Gui: Fix invalid scene graph mutation in EditableDatumLabel.
`EditableDatumLabel` uses `activate`/`deactivate` methods for showing or hiding its widgets in the scene. However, `activate`/`deactivate` methods can end up being called as part of a scene graph / Coin action (`SoAction`) handler, in the context of `SoFCUnifiedSelection`, and this ended up in a Coin warning and eventual crash due to the scene graph being manipulated (nodes being removed), which Coin has checks for in debug mode: ``` Coin error in SoGroup::removeChild(): tried to remove non-existent child 0x5555579c5290 (Annotation) ``` Fix this issue by using a `SoSwitch` node instead and by controling the child visibility using it instead.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
# include <Inventor/nodes/SoAnnotation.h>
|
||||
# include <Inventor/nodes/SoOrthographicCamera.h>
|
||||
# include <Inventor/nodes/SoTransform.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
#endif // _PreComp_
|
||||
|
||||
#include <Gui/Application.h>
|
||||
@@ -60,13 +61,17 @@ EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
|
||||
, function(Function::Positioning)
|
||||
{
|
||||
// NOLINTBEGIN
|
||||
root = new SoAnnotation;
|
||||
root = new SoSwitch;
|
||||
root->ref();
|
||||
root->renderCaching = SoSeparator::OFF;
|
||||
|
||||
annotation = new SoAnnotation;
|
||||
annotation->ref();
|
||||
annotation->renderCaching = SoSeparator::OFF;
|
||||
root->addChild(annotation);
|
||||
|
||||
transform = new SoTransform();
|
||||
transform->ref();
|
||||
root->addChild(transform);
|
||||
annotation->addChild(transform);
|
||||
|
||||
label = new SoDatumLabel();
|
||||
label->ref();
|
||||
@@ -82,16 +87,19 @@ EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
|
||||
if (autoDistance) {
|
||||
setLabelRecommendedDistance();
|
||||
}
|
||||
root->addChild(label);
|
||||
annotation->addChild(label);
|
||||
|
||||
setPlacement(plc);
|
||||
// NOLINTEND
|
||||
|
||||
static_cast<SoSeparator*>(viewer->getSceneGraph())->addChild(root); // NOLINT
|
||||
}
|
||||
|
||||
EditableDatumLabel::~EditableDatumLabel()
|
||||
{
|
||||
deactivate();
|
||||
transform->unref();
|
||||
annotation->unref();
|
||||
root->unref();
|
||||
label->unref();
|
||||
}
|
||||
@@ -102,7 +110,7 @@ void EditableDatumLabel::activate()
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<SoSeparator*>(viewer->getSceneGraph())->addChild(root); // NOLINT
|
||||
root->whichChild = 0;
|
||||
|
||||
//track camera movements to update spinbox position.
|
||||
auto info = new NodeData{ this };
|
||||
@@ -129,9 +137,7 @@ void EditableDatumLabel::deactivate()
|
||||
cameraSensor = nullptr;
|
||||
}
|
||||
|
||||
if (viewer) {
|
||||
static_cast<SoSeparator*>(viewer->getSceneGraph())->removeChild(root); // NOLINT
|
||||
}
|
||||
root->whichChild = SO_SWITCH_NONE;
|
||||
}
|
||||
|
||||
void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool visibleToMouse)
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
class SoNodeSensor;
|
||||
class SoTransform;
|
||||
class SoAnnotation;
|
||||
class SoSwitch;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
@@ -97,7 +99,8 @@ private:
|
||||
SbVec3f getTextCenterPoint() const;
|
||||
|
||||
private:
|
||||
SoSeparator* root;
|
||||
SoSwitch* root;
|
||||
SoAnnotation* annotation;
|
||||
SoTransform* transform;
|
||||
QPointer<View3DInventorViewer> viewer;
|
||||
QuantitySpinBox* spinBox;
|
||||
|
||||
Reference in New Issue
Block a user