Sketcher/BackEdit: Add camera sensor to VP that detects side and redraw if side changed

This commit is contained in:
0penBrain
2022-08-30 16:18:38 +02:00
committed by wwmayer
parent 028517323c
commit 36fccfdd08
2 changed files with 45 additions and 1 deletions

View File

@@ -283,7 +283,8 @@ ViewProviderSketch::ViewProviderSketch()
listener(nullptr),
editCoinManager(nullptr),
pObserver(std::make_unique<ViewProviderSketch::ParameterObserver>(*this)),
sketchHandler(nullptr)
sketchHandler(nullptr),
viewOrientationFactor(1)
{
PartGui::ViewProviderAttachExtension::initExtension(this);
@@ -312,6 +313,8 @@ ViewProviderSketch::ViewProviderSketch()
//rubberband selection
rubberband = std::make_unique<Gui::Rubberband>();
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<VPCam*>(cameraSensor.getData());
cameraSensor.detach();
viewer->removeGraphicsItem(rubberband.get());
viewer->setEditing(false);
SoNode* root = viewer->getSceneGraph();
static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionRole.setValue(true);
}
void ViewProviderSketch::camSensCB(void *data, SoSensor *)
{
VPCam *proxyVPCam = static_cast<VPCam*>(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())

View File

@@ -42,6 +42,9 @@
#include <Mod/Sketcher/App/GeoList.h>
#include <Inventor/sensors/SoFieldSensor.h>
#include <Inventor/nodes/SoCamera.h>
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<DrawSketchHandler> sketchHandler;
ViewProviderParameters viewProviderParameters;
SoFieldSensor cameraSensor;
int viewOrientationFactor; // stores if sketch viewed from front or back
};
} // namespace PartGui