From 776c0bd72091a49afe165fb666833daf5c6544cb Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 9 Oct 2016 22:16:21 +0200 Subject: [PATCH] fix crash when creating a second view and closing the first view while the dragger task panel is open --- src/Gui/SoFCCSysDragger.cpp | 39 ++++++++++++++++++++++--------------- src/Gui/SoFCCSysDragger.h | 1 - 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/Gui/SoFCCSysDragger.cpp b/src/Gui/SoFCCSysDragger.cpp index 52e69a5b5836..9eedb61916c2 100644 --- a/src/Gui/SoFCCSysDragger.cpp +++ b/src/Gui/SoFCCSysDragger.cpp @@ -910,7 +910,6 @@ void SoFCCSysDragger::setUpAutoScale(SoCamera *cameraIn) //note: sofieldsensor checks if the current sensor is already attached //and takes appropriate action. So it is safe to attach to a field without //checking current attachment state. - camera = cameraIn; if (cameraIn->getTypeId() == SoOrthographicCamera::getClassTypeId()) { SoOrthographicCamera *localCamera = dynamic_cast(cameraIn); @@ -943,28 +942,36 @@ void SoFCCSysDragger::cameraCB(void *data, SoSensor *) void SoFCCSysDragger::idleCB(void *data, SoSensor *) { SoFCCSysDragger *sudoThis = reinterpret_cast(data); - assert(sudoThis->camera); - - SbMatrix localToWorld = sudoThis->getLocalToWorldMatrix(); - SbVec3f origin; - localToWorld.multVecMatrix(SbVec3f(0.0, 0.0, 0.0), origin); - - SbViewVolume viewVolume = sudoThis->camera->getViewVolume(); - float radius = sudoThis->draggerSize.getValue() / 2.0; - float localScale = viewVolume.getWorldToScreenScale(origin, radius); - SbVec3f scaleVector(localScale, localScale, localScale); - SoScale *localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale); - localScaleNode->scaleFactor.setValue(scaleVector); - sudoThis->autoScaleResult.setValue(localScale); + SoField* field = sudoThis->cameraSensor.getAttachedField(); + if (field) + { + SoCamera* camera = static_cast(field->getContainer()); + SbMatrix localToWorld = sudoThis->getLocalToWorldMatrix(); + SbVec3f origin; + localToWorld.multVecMatrix(SbVec3f(0.0, 0.0, 0.0), origin); + + SbViewVolume viewVolume = camera->getViewVolume(); + float radius = sudoThis->draggerSize.getValue() / 2.0; + float localScale = viewVolume.getWorldToScreenScale(origin, radius); + SbVec3f scaleVector(localScale, localScale, localScale); + SoScale *localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale); + localScaleNode->scaleFactor.setValue(scaleVector); + sudoThis->autoScaleResult.setValue(localScale); + } } void SoFCCSysDragger::finishDragCB(void *data, SoDragger *) { SoFCCSysDragger *sudoThis = reinterpret_cast(data); - if (sudoThis->camera) + // note: when creating a second view of the document and then closing + // the first viewer it deletes the camera. However, the attached field + // of the cameraSensor will be detached automatically. + SoField* field = sudoThis->cameraSensor.getAttachedField(); + if (field) { - if (sudoThis->camera->getTypeId() == SoPerspectiveCamera::getClassTypeId()) + SoCamera* camera = static_cast(field->getContainer()); + if (camera->getTypeId() == SoPerspectiveCamera::getClassTypeId()) cameraCB(sudoThis, nullptr); } } diff --git a/src/Gui/SoFCCSysDragger.h b/src/Gui/SoFCCSysDragger.h index 8d33c3e5cf1d..d21ee310d544 100644 --- a/src/Gui/SoFCCSysDragger.h +++ b/src/Gui/SoFCCSysDragger.h @@ -207,7 +207,6 @@ class GuiExport SoFCCSysDragger : public SoDragger SoIdleSensor idleSensor; //!< might be overkill, but want to make sure of performance. void setUpAutoScale(SoCamera *cameraIn); //!< used to setup the auto scaling of dragger. - SoCamera *camera = nullptr; //!< don't assign directly! use setUpAutoScale. //! @name Visibility Functions //@{