From 36fccfdd08abca7f5ae27520221af57d7a93cd4a Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Tue, 30 Aug 2022 16:18:38 +0200 Subject: [PATCH] Sketcher/BackEdit: Add camera sensor to VP that detects side and redraw if side changed --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 32 ++++++++++++++++++++- src/Mod/Sketcher/Gui/ViewProviderSketch.h | 14 +++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index a1ae8b5fa4..e08d0d3178 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -283,7 +283,8 @@ ViewProviderSketch::ViewProviderSketch() listener(nullptr), editCoinManager(nullptr), pObserver(std::make_unique(*this)), - sketchHandler(nullptr) + sketchHandler(nullptr), + viewOrientationFactor(1) { PartGui::ViewProviderAttachExtension::initExtension(this); @@ -312,6 +313,8 @@ ViewProviderSketch::ViewProviderSketch() //rubberband selection rubberband = std::make_unique(); + cameraSensor.setFunction(&ViewProviderSketch::camSensCB); + } ViewProviderSketch::~ViewProviderSketch() @@ -3112,16 +3115,43 @@ void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int Mo rubberband->setViewer(viewer); viewer->setupEditingRoot(); + + cameraSensor.setData(new VPCam{this, viewer->getSoRenderManager()->getCamera()}); + cameraSensor.attach(&viewer->getSoRenderManager()->getCamera()->orientation); } void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer) { + delete static_cast(cameraSensor.getData()); + cameraSensor.detach(); + viewer->removeGraphicsItem(rubberband.get()); viewer->setEditing(false); SoNode* root = viewer->getSceneGraph(); static_cast(root)->selectionRole.setValue(true); } +void ViewProviderSketch::camSensCB(void *data, SoSensor *) +{ + VPCam *proxyVPCam = static_cast(data); + auto vp = proxyVPCam->vp; + auto cam = proxyVPCam->cam; + + auto rotSk = Base::Rotation(vp->getDocument()->getEditingTransform()); //sketch orientation + auto rotc = cam->orientation.getValue().getValue(); + auto rotCam = Base::Rotation(rotc[0], rotc[1], rotc[2], rotc[3]); // camera orientation (needed because float to double conversion) + + // Is camera in the same hemisphere as positive sketch normal ? + auto orientation = (rotCam.invert()*rotSk).multVec(Base::Vector3d(0,0,1)); + auto tmpFactor = orientation.z<0?-1:1; + + if (tmpFactor != vp->viewOrientationFactor) { // redraw only if viewing side changed + Base::Console().Log("Switching side, now %s, redrawing\n", tmpFactor < 0 ? "back" : "front"); + vp->viewOrientationFactor = tmpFactor; + vp->draw(); + } +} + int ViewProviderSketch::getPreselectPoint() const { if (isInEditMode()) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index e8a19f6b18..f688003d67 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -42,6 +42,9 @@ #include +#include +#include + class TopoDS_Shape; class TopoDS_Face; class SoSeparator; @@ -388,6 +391,13 @@ private: bool buttonPress = false; }; + /** @brief Private struct grouping ViewProvider and Camera node, to be used as SoFieldSensor data + */ + struct VPCam { + ViewProviderSketch* vp; + SoCamera* cam; + }; + public: /// constructor ViewProviderSketch(); @@ -551,6 +561,7 @@ protected: void unsetEdit(int ModNum) override; void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override; void unsetEditViewer(Gui::View3DInventorViewer*) override; + static void camSensCB(void *data, SoSensor *); // camera sensor callback //@} /** @name miscelanea editing functions */ @@ -763,6 +774,9 @@ private: std::unique_ptr sketchHandler; ViewProviderParameters viewProviderParameters; + + SoFieldSensor cameraSensor; + int viewOrientationFactor; // stores if sketch viewed from front or back }; } // namespace PartGui