diff --git a/src/Gui/ViewProvider.cpp b/src/Gui/ViewProvider.cpp index d7eee8216..dc2976085 100644 --- a/src/Gui/ViewProvider.cpp +++ b/src/Gui/ViewProvider.cpp @@ -32,6 +32,8 @@ # include # include # include +# include +# include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... @@ -379,16 +381,32 @@ PyObject* ViewProvider::getPyObject() SoPickedPoint* ViewProvider::getPointOnRay(const SbVec2s& pos, const View3DInventorViewer* viewer) const { - // for convenience make a pick ray action to get the (potentially) picked entity in the provider + //first get the path to this node and calculate the current transformation + SoSearchAction sa; + sa.setNode(pcRoot); + sa.setSearchingAll(true); + sa.apply(viewer->getSoRenderManager()->getSceneGraph()); + SoGetMatrixAction gm(viewer->getSoRenderManager()->getViewportRegion()); + gm.apply(sa.getPath()); + + SoTransform* trans = new SoTransform; + trans->setMatrix(gm.getMatrix()); + trans->ref(); + + // build a temporary scenegraph only keeping this viewproviders nodes and the accumulated + // transformation SoSeparator* root = new SoSeparator; root->ref(); root->addChild(viewer->getSoRenderManager()->getCamera()); + root->addChild(trans); root->addChild(pcRoot); + //get the picked point SoRayPickAction rp(viewer->getSoRenderManager()->getViewportRegion()); rp.setPoint(pos); rp.apply(root); root->unref(); + trans->unref(); SoPickedPoint* pick = rp.getPickedPoint(); return (pick ? new SoPickedPoint(*pick) : 0); @@ -398,9 +416,33 @@ SoPickedPoint* ViewProvider::getPointOnRay(const SbVec3f& pos,const SbVec3f& dir { // Note: There seems to be a bug with setRay() which causes SoRayPickAction // to fail to get intersections between the ray and a line + + //first get the path to this node and calculate the current setTransformation + SoSearchAction sa; + sa.setNode(pcRoot); + sa.setSearchingAll(true); + sa.apply(viewer->getSoRenderManager()->getSceneGraph()); + SoGetMatrixAction gm(viewer->getSoRenderManager()->getViewportRegion()); + gm.apply(sa.getPath()); + + // build a temporary scenegraph only keeping this viewproviders nodes and the accumulated + // transformation + SoTransform* trans = new SoTransform; + trans->ref(); + trans->setMatrix(gm.getMatrix()); + + SoSeparator* root = new SoSeparator; + root->ref(); + root->addChild(viewer->getSoRenderManager()->getCamera()); + root->addChild(trans); + root->addChild(pcRoot); + + //get the picked point SoRayPickAction rp(viewer->getSoRenderManager()->getViewportRegion()); rp.setRay(pos,dir); - rp.apply(pcRoot); + rp.apply(root); + root->unref(); + trans->unref(); // returns a copy of the point SoPickedPoint* pick = rp.getPickedPoint(); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index bae6159f2..8834ec5e7 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -99,6 +99,7 @@ #include #include +#include #include #include @@ -492,7 +493,7 @@ void ViewProviderSketch::getCoordsOnSketchPlane(double &u, double &v,const SbVec Base::Vector3d R0(0,0,0),RN(0,0,1),RX(1,0,0),RY(0,1,0); // move to position of Sketch - Base::Placement Plz = getSketchObject()->Placement.getValue(); + Base::Placement Plz = getPlacement(); R0 = Plz.getPosition() ; Base::Rotation tmp(Plz.getRotation()); tmp.multVec(RN,RN); @@ -1869,7 +1870,7 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s &startPos, const SbVec2s & Sketcher::SketchObject *sketchObject = getSketchObject(); App::Document *doc = sketchObject->getDocument(); - Base::Placement Plm = sketchObject->Placement.getValue(); + Base::Placement Plm = getPlacement(); int intGeoCount = sketchObject->getHighestCurveIndex() + 1; int extGeoCount = sketchObject->getExternalGeometryCount(); @@ -3950,7 +3951,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) Base::Vector3d RN(0,0,1); // move to position of Sketch - Base::Placement Plz = getSketchObject()->Placement.getValue(); + Base::Placement Plz = getPlacement(); Base::Rotation tmp(Plz.getRotation()); tmp.multVec(RN,RN); Plz.setRotation(tmp); @@ -4145,7 +4146,7 @@ void ViewProviderSketch::onChanged(const App::Property *prop) } void ViewProviderSketch::attach(App::DocumentObject *pcFeat) -{ +{ ViewProviderPart::attach(pcFeat); } @@ -4156,6 +4157,19 @@ void ViewProviderSketch::setupContextMenu(QMenu *menu, QObject *receiver, const bool ViewProviderSketch::setEdit(int ModNum) { + //find the Part object the feature belongs to, TODO: use GRAPH methods + App::DocumentObject* search = getSketchObject(); + for(Part::BodyBase* b : getSketchObject()->getDocument()->getObjectsOfType()) { + if(b->hasFeature(getSketchObject())) { + search = b; + } + } + for(App::Part* p : getSketchObject()->getDocument()->getObjectsOfType()) { + if(p->hasObject(search)) { + parentPart = p; + } + } + // always change to sketcher WB, remember where we come from oldWb = Gui::Command::assureWorkbench("SketcherWorkbench"); @@ -4592,7 +4606,7 @@ void ViewProviderSketch::unsetEdit(int ModNum) void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum) { - Base::Placement plm = getSketchObject()->Placement.getValue(); + Base::Placement plm = getPlacement(); Base::Rotation tmp(plm.getRotation()); SbRotation rot((float)tmp[0],(float)tmp[1],(float)tmp[2],(float)tmp[3]); @@ -4877,3 +4891,14 @@ bool ViewProviderSketch::onDelete(const std::vector &subList) // if not in edit delete the whole object return PartGui::ViewProviderPart::onDelete(subList); } + +Base::Placement ViewProviderSketch::getPlacement() { + //TODO: use GRAPH placement handling, as this function right now only works with one parent + //part object + Base::Placement Plz = getSketchObject()->Placement.getValue(); + if(parentPart) + return parentPart->Placement.getValue()*Plz; + + return Plz; +} + diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 3a718277d..7238770c0 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -28,8 +28,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -345,6 +347,9 @@ protected: void removeSelectPoint(int SelectPoint); void clearSelectPoints(void); + // handle stacked placements of App::Parts + Base::Placement getPlacement(); + // modes while sketching SketchMode Mode; @@ -381,8 +386,11 @@ protected: double xInit,yInit; bool relative; - Gui::Rubberband* rubberband; std::string oldWb; + int antiAliasing; + + Gui::Rubberband* rubberband; + App::Part* parentPart = nullptr; }; } // namespace PartGui