From b81485d72dc4d128b412e0ad109fe677dc5d8800 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 5 Oct 2019 10:24:05 +0800 Subject: [PATCH] Gui: improve scale handling in SoFCCSysDragger Because of the scale transformion in Link, the dragger may have undesired behavior. This patch checks scaling factor in scenegraph transformation, and auto scale the dragger axis accordingly. --- src/Gui/SoFCCSysDragger.cpp | 45 +++++++++++++++++++++++++++++++++++- src/Gui/SoFCCSysDragger.h | 11 +++++++++ src/Gui/ViewProviderLink.cpp | 10 +------- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/Gui/SoFCCSysDragger.cpp b/src/Gui/SoFCCSysDragger.cpp index f4c836469d..72d2b053ba 100644 --- a/src/Gui/SoFCCSysDragger.cpp +++ b/src/Gui/SoFCCSysDragger.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -638,6 +639,8 @@ void SoFCCSysDragger::initClass() } SoFCCSysDragger::SoFCCSysDragger() + :axisScale(1.0f,1.0f,1.0f) + ,scaleInited(false) { SO_KIT_CONSTRUCTOR(SoFCCSysDragger); @@ -939,6 +942,44 @@ void SoFCCSysDragger::cameraCB(void *data, SoSensor *) sudoThis->idleSensor.schedule(); } +void SoFCCSysDragger::GLRender(SoGLRenderAction * action) +{ + if(!scaleInited) { + scaleInited = true; + updateDraggerCache(action->getCurPath()); + updateAxisScale(); + } + + inherited::GLRender(action); +} + +void SoFCCSysDragger::updateAxisScale() { + SbMatrix localToWorld = getLocalToWorldMatrix(); + SbVec3f origin; + localToWorld.multVecMatrix(SbVec3f(0.0, 0.0, 0.0), origin); + SbVec3f vx,vy,vz; + localToWorld.multVecMatrix(SbVec3f(1.0f, 0.0f, 0.0f), vx); + localToWorld.multVecMatrix(SbVec3f(0.0f, 1.0f, 0.0f), vy); + localToWorld.multVecMatrix(SbVec3f(0.0f, 0.0f, 1.0f), vz); + float x = std::max((vx-origin).length(),1e-7f); + float y = std::max((vy-origin).length(),1e-7f); + float z = std::max((vz-origin).length(),1e-7f); + if(!axisScale.equals(SbVec3f(x,y,z),1e-7f)) { + axisScale.setValue(x,y,z); + idleCB(this,&idleSensor); + } +} + +void SoFCCSysDragger::handleEvent(SoHandleEventAction * action) +{ + this->ref(); + + inherited::handleEvent(action); + updateAxisScale(); + + this->unref(); +} + void SoFCCSysDragger::idleCB(void *data, SoSensor *) { SoFCCSysDragger *sudoThis = reinterpret_cast(data); @@ -953,7 +994,9 @@ void SoFCCSysDragger::idleCB(void *data, SoSensor *) SbViewVolume viewVolume = camera->getViewVolume(); float radius = sudoThis->draggerSize.getValue() / 2.0; float localScale = viewVolume.getWorldToScreenScale(origin, radius); - SbVec3f scaleVector(localScale, localScale, localScale); + float sx,sy,sz; + sudoThis->axisScale.getValue(sx,sy,sz); + SbVec3f scaleVector(localScale/sx, localScale/sy, localScale/sz); SoScale *localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale); localScaleNode->scaleFactor.setValue(scaleVector); sudoThis->autoScaleResult.setValue(localScale); diff --git a/src/Gui/SoFCCSysDragger.h b/src/Gui/SoFCCSysDragger.h index f78e68388c..c49c87c032 100644 --- a/src/Gui/SoFCCSysDragger.h +++ b/src/Gui/SoFCCSysDragger.h @@ -239,8 +239,11 @@ public: bool isHiddenRotationZ(); //!< is x rotation dragger hidden. //@} + virtual void GLRender(SoGLRenderAction * action); + protected: virtual SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; + virtual void handleEvent(SoHandleEventAction * action) override; static void translationSensorCB(void *f, SoSensor *); static void rotationSensorCB(void *f, SoSensor *); @@ -255,6 +258,14 @@ protected: SoFieldSensor cameraSensor; private: + // Used to compensate for axis scale in world transformation when doing + // auto scale. + SbVec3f axisScale; + + bool scaleInited; + + void updateAxisScale(); + typedef SoDragger inherited; }; diff --git a/src/Gui/ViewProviderLink.cpp b/src/Gui/ViewProviderLink.cpp index da105122d7..c5f3208a31 100644 --- a/src/Gui/ViewProviderLink.cpp +++ b/src/Gui/ViewProviderLink.cpp @@ -2572,15 +2572,7 @@ void ViewProviderLink::setEditViewer(Gui::View3DInventorViewer* viewer, int ModN viewer->setupEditingRoot(group,&dragCtx->preTransform); }else{ SoFCCSysDragger* dragger = static_cast(pcDragger.get()); - auto doc = Application::Instance->editDocument(); - if(doc) { - Base::Vector3d v0, v1(1,0,0); - doc->getEditingTransform().multVec(v0,v0); - doc->getEditingTransform().multVec(v1,v1); - // Compensate for possible scaling - dragger->draggerSize.setValue(0.05f / (v1-v0).Length()); - } else - dragger->draggerSize.setValue(0.05f); + dragger->draggerSize.setValue(0.05f); dragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); viewer->setupEditingRoot(pcDragger,&dragCtx->preTransform);