Use Face or 3D direction for View and ProjGroup

- use current 3D window direction as starting
  direction for DrawViewPart and ProjectionGroup
- if a Face is selected, use Face normal as
  starting direction.
This commit is contained in:
wandererfan
2018-08-20 20:01:48 -04:00
committed by wmayer
parent 233ed49b23
commit aa8feb79d0
16 changed files with 544 additions and 893 deletions

View File

@@ -36,6 +36,14 @@
#endif
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Dir.hxx>
#include <gp_Ax2.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepLProp_SLProps.hxx>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
@@ -51,6 +59,11 @@
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Gui/MainWindow.h>
#include <Gui/MDIView.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Inventor/SbVec3f.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/Part2DObject.h>
@@ -67,6 +80,7 @@
#include "DrawGuiUtil.h"
using namespace TechDrawGui;
using namespace TechDraw;
//===========================================================================
// validate helper routines
@@ -187,3 +201,87 @@ void DrawGuiUtil::dumpPointF(const char* text, const QPointF& p)
Base::Console().Message("DUMP - dumpPointF - %s\n",text);
Base::Console().Message("Point: (%.3f, %.3f)\n",p.x(),p.y());
}
std::pair<Base::Vector3d,Base::Vector3d> DrawGuiUtil::get3DDirAndRot()
{
std::pair<Base::Vector3d,Base::Vector3d> result;
Base::Vector3d viewDir(0.0,-1.0,0.0); //default to front
Base::Vector3d viewUp(0.0,0.0,1.0); //default to top
Base::Vector3d viewRight(1.0,0.0,0.0); //default to right
std::list<Gui::MDIView*> mdis = Gui::Application::Instance->activeDocument()->getMDIViews();
Gui::View3DInventor *view;
Gui::View3DInventorViewer *viewer = nullptr;
for (auto& m: mdis) { //find the 3D viewer
view = dynamic_cast<Gui::View3DInventor*>(m);
if (view) {
viewer = view->getViewer();
break;
}
}
if (!viewer) {
Base::Console().Log("LOG - DrawGuiUtil could not find a 3D viewer\n");
return std::make_pair( viewDir, viewRight);
}
SbVec3f dvec = viewer->getViewDirection();
SbVec3f upvec = viewer->getUpDirection();
viewDir = Base::Vector3d(dvec[0], dvec[1], dvec[2]);
viewUp = Base::Vector3d(upvec[0],upvec[1],upvec[2]);
Base::Vector3d dirXup = viewDir.Cross(viewUp); //dir X up should give local Right
viewDir = viewDir * (-1.0); // Inventor dir is opposite TD projection dir
result = std::make_pair(viewDir,dirXup);
return result;
}
std::pair<Base::Vector3d,Base::Vector3d> DrawGuiUtil::getProjDirFromFace(Part::Feature* obj, std::string faceName)
{
std::pair<Base::Vector3d,Base::Vector3d> d3Dirs = get3DDirAndRot();
Base::Vector3d d3Up = (d3Dirs.first).Cross(d3Dirs.second);
std::pair<Base::Vector3d,Base::Vector3d> dirs;
dirs.first = Base::Vector3d(0.0,0.0,1.0); //set a default
dirs.second = Base::Vector3d(1.0,0.0,0.0);
Base::Vector3d projDir, rotVec;
projDir = d3Dirs.first;
rotVec = d3Dirs.second;
if (DrawUtil::getGeomTypeFromName(faceName) != "Face") {
Base::Console().Warning("getProjDirFromFace(%s) is not a Face\n",faceName.c_str());
return dirs;
}
Part::TopoShape ts = obj->Shape.getShape();
ts.setPlacement(obj->globalPlacement());
TopoDS_Shape subShape = ts.getSubShape(faceName.c_str());
const TopoDS_Face& face = TopoDS::Face(subShape);
TopAbs_Orientation orient = face.Orientation();
BRepAdaptor_Surface adapt(face);
double u1 = adapt.FirstUParameter();
double u2 = adapt.LastUParameter();
double v1 = adapt.FirstVParameter();
double v2 = adapt.LastVParameter();
double uMid = (u1+u2)/2.0;
double vMid = (v1+v2)/2.0;
BRepLProp_SLProps props(adapt,uMid,vMid,2,Precision::Confusion());
if (props.IsNormalDefined()) {
gp_Dir vec = props.Normal();
projDir = Base::Vector3d(vec.X(),vec.Y(),vec.Z());
rotVec = projDir.Cross(d3Up);
if (orient != TopAbs_FORWARD) {
projDir = projDir * (-1.0);
}
}
else {
Base::Console().Log("Selected Face has no normal at midpoint\n");
}
dirs = std::make_pair(projDir,rotVec);
return dirs;
}