[Bugfix]Sketcher/BackEdit : Backedit lost if user changed camera mode

- in current implementation, backedit feature is lost if user changes camera mode (for example from orthographic to
   perspective, or oppositely). This happens because when changing camera mode, Coin actually do not just change a
   parameter of the camera node, but delete the current camera node and add a new one to the scenegraph. Thus the
   SoFieldSensor currently used (attached to camera orientation) is just detached and sensing is left -- notice is would
   be same with a SoNodeSensor attached to camera node --. The solution is to attach the sensor at scenegraph root node
   so it isn't lost when camera mode changed. No pre-check (such as checking if camera node changed since last call) has
   been added currently because it would not actually reduce callback execution time (and even worsen it).
This commit is contained in:
0penBrain
2022-10-18 18:12:02 +02:00
committed by abdullahtahiriyo
parent ce4ba703d9
commit 525c05fae5
2 changed files with 21 additions and 12 deletions

View File

@@ -3157,13 +3157,15 @@ void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int Mo
viewer->setupEditingRoot();
cameraSensor.setData(new VPCam{this, viewer->getSoRenderManager()->getCamera()});
cameraSensor.attach(&viewer->getSoRenderManager()->getCamera()->orientation);
cameraSensor.setData(new VPRender{this, viewer->getSoRenderManager()});
cameraSensor.attach(viewer->getSoRenderManager()->getSceneGraph());
}
void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
{
delete static_cast<VPCam*>(cameraSensor.getData());
auto dataPtr = static_cast<VPRender*>(cameraSensor.getData());
dataPtr->attached = false;
delete dataPtr;
cameraSensor.detach();
viewer->removeGraphicsItem(rubberband.get());
@@ -3174,9 +3176,12 @@ void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
void ViewProviderSketch::camSensCB(void *data, SoSensor *)
{
VPCam *proxyVPCam = static_cast<VPCam*>(data);
auto vp = proxyVPCam->vp;
auto cam = proxyVPCam->cam;
VPRender *proxyVPrdr = static_cast<VPRender*>(data);
if (!proxyVPrdr->attached)
return;
auto vp = proxyVPrdr->vp;
auto cam = proxyVPrdr->renderMgr->getCamera();
auto rotSk = Base::Rotation(vp->getDocument()->getEditingTransform()); //sketch orientation
auto rotc = cam->orientation.getValue().getValue();

View File

@@ -42,8 +42,8 @@
#include <Mod/Sketcher/App/GeoList.h>
#include <Inventor/sensors/SoFieldSensor.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/sensors/SoNodeSensor.h>
#include <Inventor/SoRenderManager.h>
class TopoDS_Shape;
class TopoDS_Face;
@@ -391,11 +391,15 @@ private:
bool buttonPress = false;
};
/** @brief Private struct grouping ViewProvider and Camera node, to be used as SoFieldSensor data
/** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode sensor data
*/
struct VPCam {
struct VPRender {
ViewProviderSketch* vp;
SoCamera* cam;
SoRenderManager* renderMgr;
// we have to manage an internal flag because as sensor events are queued in Coin,
// it may happen that the callback is called while the sensor is detached,
// leading to subsequent code trying to access deleted objects (passed as sensor data)
bool attached = true;
};
public:
@@ -777,7 +781,7 @@ private:
ViewProviderParameters viewProviderParameters;
SoFieldSensor cameraSensor;
SoNodeSensor cameraSensor;
int viewOrientationFactor; // stores if sketch viewed from front or back
};