diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 2c1acb63d4..edd7dd6aa1 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1071,6 +1071,10 @@ SET(Inventor_CPP_SRCS Inventor/SoFCBoundingBox.cpp Inventor/SoMouseWheelEvent.cpp Inventor/SoFCTransform.cpp + Inventor/Draggers/SoTransformDragger.cpp + Inventor/Draggers/SoLinearDragger.cpp + Inventor/Draggers/SoPlanarDragger.cpp + Inventor/Draggers/SoRotationDragger.cpp SoFCColorBar.cpp SoFCColorBarNotifier.cpp SoFCColorGradient.cpp @@ -1089,7 +1093,6 @@ SET(Inventor_CPP_SRCS SoTextLabel.cpp SoDatumLabel.cpp SoTouchEvents.cpp - SoFCCSysDragger.cpp ArcEngine.cpp ) SET(Inventor_SRCS @@ -1104,6 +1107,10 @@ SET(Inventor_SRCS Inventor/SoFCBoundingBox.h Inventor/SoMouseWheelEvent.h Inventor/SoFCTransform.h + Inventor/Draggers/SoTransformDragger.h + Inventor/Draggers/SoLinearDragger.h + Inventor/Draggers/SoPlanarDragger.h + Inventor/Draggers/SoRotationDragger.h SoFCColorBar.h SoFCColorBarNotifier.h SoFCColorGradient.h @@ -1122,7 +1129,6 @@ SET(Inventor_SRCS SoTextLabel.h SoDatumLabel.h SoTouchEvents.h - SoFCCSysDragger.h ArcEngine.h ) SOURCE_GROUP("View3D\\Inventor" FILES ${Inventor_SRCS}) @@ -1428,9 +1434,12 @@ if (EIGEN3_NO_DEPRECATED_COPY) set_source_files_properties( NaviCube.cpp Inventor/SoAutoZoomTranslation.cpp + Inventor/Draggers/SoTransformDragger.cpp + Inventor/Draggers/SoLinearDragger.cpp + Inventor/Draggers/SoPlanarDragger.cpp + Inventor/Draggers/SoRotationDragger.cpp SoFCOffscreenRenderer.cpp Selection/SoFCSelectionAction.cpp - SoFCCSysDragger.cpp Quarter/QuarterWidget.cpp View3DInventorViewer.cpp PROPERTIES COMPILE_FLAGS ${EIGEN3_NO_DEPRECATED_COPY}) diff --git a/src/Gui/Inventor/Draggers/SoLinearDragger.cpp b/src/Gui/Inventor/Draggers/SoLinearDragger.cpp new file mode 100644 index 0000000000..3e27ae5167 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoLinearDragger.cpp @@ -0,0 +1,393 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "SoLinearDragger.h" + +#include "MainWindow.h" +#include "SoFCDB.h" + +#include + +using namespace Gui; + +SO_KIT_SOURCE(SoLinearDragger) + +void SoLinearDragger::initClass() +{ + SO_KIT_INIT_CLASS(SoLinearDragger, SoDragger, "Dragger"); +} + +SoLinearDragger::SoLinearDragger() +{ + SO_KIT_CONSTRUCTOR(SoLinearDragger); + +#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + this->ref(); +#endif + + SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE, geomSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(activeSwitch, SoSwitch, TRUE, translator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(activeColor, SoBaseColor, TRUE, activeSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(coneSeparator, SoSeparator, TRUE, translator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(cylinderSeparator, SoSeparator, TRUE, translator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(labelSeparator, SoSeparator, TRUE, translator, "", TRUE); + + if (SO_KIT_IS_FIRST_INSTANCE()) { + buildFirstInstance(); + } + + SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE, geomSeparator, "", TRUE); + + SO_KIT_ADD_FIELD(label, ("")); + SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); + SO_KIT_ADD_FIELD(translationIncrement, (1.0)); + SO_KIT_ADD_FIELD(translationIncrementCount, (0)); + SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); + + SO_KIT_INIT_INSTANCE(); + + // initialize default parts. + // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro + // second is unique name from buildFirstInstance(). + SoInteractionKit::setPartAsDefault("coneSeparator", "CSysDynamics_TDragger_Cone"); + SoInteractionKit::setPartAsDefault("cylinderSeparator", "CSysDynamics_TDragger_Cylinder"); + SoInteractionKit::setPartAsDefault("activeColor", "CSysDynamics_TDragger_ActiveColor"); + + SoInteractionKit::setPart("labelSeparator", buildLabelGeometry()); + + auto sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); + + + this->addStartCallback(&SoLinearDragger::startCB); + this->addMotionCallback(&SoLinearDragger::motionCB); + this->addFinishCallback(&SoLinearDragger::finishCB); + + addValueChangedCallback(&SoLinearDragger::valueChangedCB); + + fieldSensor.setFunction(&SoLinearDragger::fieldSensorCB); + fieldSensor.setData(this); + fieldSensor.setPriority(0); + + this->setUpConnections(TRUE, TRUE); +} + +SoLinearDragger::~SoLinearDragger() +{ + fieldSensor.setData(nullptr); + fieldSensor.detach(); + + this->removeStartCallback(&SoLinearDragger::startCB); + this->removeMotionCallback(&SoLinearDragger::motionCB); + this->removeFinishCallback(&SoLinearDragger::finishCB); + removeValueChangedCallback(&SoLinearDragger::valueChangedCB); +} + +void SoLinearDragger::buildFirstInstance() +{ + auto cylinderSeparator = buildCylinderGeometry(); + auto coneSeparator = buildConeGeometry(); + auto activeColor = buildActiveColor(); + + cylinderSeparator->setName("CSysDynamics_TDragger_Cylinder"); + coneSeparator->setName("CSysDynamics_TDragger_Cone"); + activeColor->setName("CSysDynamics_TDragger_ActiveColor"); + + SoFCDB::getStorage()->addChild(cylinderSeparator); + SoFCDB::getStorage()->addChild(coneSeparator); + SoFCDB::getStorage()->addChild(activeColor); +} + +SoSeparator* SoLinearDragger::buildCylinderGeometry() const +{ + auto cylinderSeparator = new SoSeparator(); + + auto cylinderLightModel = new SoLightModel(); + cylinderLightModel->model = SoLightModel::BASE_COLOR; + cylinderSeparator->addChild(cylinderLightModel); + + auto cylinderTranslation = new SoTranslation(); + cylinderTranslation->translation.setValue(0.0, cylinderHeight / 2.0, 0.0); + cylinderSeparator->addChild(cylinderTranslation); + + auto cylinder = new SoCylinder(); + cylinder->radius.setValue(cylinderRadius); + cylinder->height.setValue(cylinderHeight); + cylinderSeparator->addChild(cylinder); + + return cylinderSeparator; +} + +SoSeparator* SoLinearDragger::buildConeGeometry() const +{ + auto coneLightModel = new SoLightModel(); + coneLightModel->model = SoLightModel::BASE_COLOR; + + auto coneSeparator = new SoSeparator(); + coneSeparator->addChild(coneLightModel); + + auto pickStyle = new SoPickStyle(); + pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); + pickStyle->setOverride(TRUE); + coneSeparator->addChild(pickStyle); + + auto coneTranslation = new SoTranslation(); + coneTranslation->translation.setValue(0.0, cylinderHeight + coneHeight / 2.0, 0.0); + coneSeparator->addChild(coneTranslation); + + auto cone = new SoCone(); + cone->bottomRadius.setValue(coneBottomRadius); + cone->height.setValue(coneHeight); + coneSeparator->addChild(cone); + + return coneSeparator; +} + +SoSeparator* SoLinearDragger::buildLabelGeometry() +{ + auto labelSeparator = new SoSeparator(); + + auto labelTranslation = new SoTranslation(); + labelTranslation->translation.setValue(0.0, cylinderHeight + coneHeight * 1.5, 0.0); + labelSeparator->addChild(labelTranslation); + + auto label = new SoFrameLabel(); + label->string.connectFrom(&this->label); + label->textColor.setValue(1.0, 1.0, 1.0); + label->horAlignment = SoImage::CENTER; + label->vertAlignment = SoImage::HALF; + label->border = false; + label->backgroundUseBaseColor = true; + labelSeparator->addChild(label); + + return labelSeparator; +} + +SoBaseColor* SoLinearDragger::buildActiveColor() +{ + auto colorActive = new SoBaseColor(); + colorActive->rgb.setValue(1.0, 1.0, 0.0); + + return colorActive; +} + +void SoLinearDragger::startCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragStart(); +} + +void SoLinearDragger::motionCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->drag(); +} + +void SoLinearDragger::finishCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragFinish(); +} + +void SoLinearDragger::fieldSensorCB(void* f, SoSensor*) +{ + auto sudoThis = static_cast(f); + + if (!f) { + return; + } + + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + sudoThis->workFieldsIntoTransform(matrix); + sudoThis->setMotionMatrix(matrix); +} + +void SoLinearDragger::valueChangedCB(void*, SoDragger* d) +{ + auto sudoThis = dynamic_cast(d); + assert(sudoThis); + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + + // all this just to get the translation? + SbVec3f trans, scaleDummy; + SbRotation rotationDummy, scaleOrientationDummy; + matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy); + + sudoThis->fieldSensor.detach(); + if (sudoThis->translation.getValue() != trans) { + sudoThis->translation = trans; + } + sudoThis->fieldSensor.attach(&sudoThis->translation); +} + +void SoLinearDragger::dragStart() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + + // do an initial projection to eliminate discrepancies + // in arrow head pick. we define the arrow in the y+ direction + // and we know local space will be relative to this. so y vector + // line projection will work. + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + projector.setLine(SbLine(SbVec3f(0.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0))); + SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); + + projector.setLine(SbLine(SbVec3f(0.0, 0.0, 0.0), hitPoint)); + + SbMatrix localToWorld = getLocalToWorldMatrix(); + localToWorld.multVecMatrix(hitPoint, hitPoint); + setStartingPoint((hitPoint)); + + translationIncrementCount.setValue(0); +} + +void SoLinearDragger::drag() +{ + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + + SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); + SbVec3f startingPoint = getLocalStartingPoint(); + SbVec3f localMovement = hitPoint - startingPoint; + + // scale the increment to match local space. + float scaledIncrement = + static_cast(translationIncrement.getValue()) / autoScaleResult.getValue(); + + localMovement = roundTranslation(localMovement, scaledIncrement); + // when the movement vector is null either the appendTranslation or + // the setMotionMatrix doesn't work. either way it stops translating + // back to its initial starting point. + if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) { + setMotionMatrix(getStartMotionMatrix()); + // don't know why I need the following but if I don't have it + // it won't return to original position. + this->valueChanged(); + } + else { + setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement)); + } + + Base::Quantity quantity(static_cast(translationIncrementCount.getValue()) + * translationIncrement.getValue(), + Base::Unit::Length); + + QString message = + QStringLiteral("%1 %2").arg(QObject::tr("Translation:"), QString::fromStdString(quantity.getUserString())); + getMainWindow()->showMessage(message, 3000); +} + +void SoLinearDragger::dragFinish() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} + +SbBool SoLinearDragger::setUpConnections(SbBool onoff, SbBool doitalways) +{ + if (!doitalways && this->connectionsSetUp == onoff) { + return onoff; + } + + SbBool oldval = this->connectionsSetUp; + + if (onoff) { + inherited::setUpConnections(onoff, doitalways); + SoLinearDragger::fieldSensorCB(this, nullptr); + if (this->fieldSensor.getAttachedField() != &this->translation) { + this->fieldSensor.attach(&this->translation); + } + } + else { + if (this->fieldSensor.getAttachedField()) { + this->fieldSensor.detach(); + } + inherited::setUpConnections(onoff, doitalways); + } + this->connectionsSetUp = onoff; + return oldval; +} + +SbVec3f SoLinearDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn) +{ + // everything is transformed into local space. That means we only have + // worry about the y-value. + + int yCount = 0; + float yValue = vecIn[1]; + + if (fabs(yValue) > (incrementIn / 2.0)) { + yCount = static_cast(yValue / incrementIn); + float remainder = fmod(yValue, incrementIn); + if (remainder >= (incrementIn / 2.0)) { + yCount++; + } + } + + translationIncrementCount.setValue(yCount); + + SbVec3f out; + out[0] = 0; + out[1] = static_cast(yCount) * incrementIn; + out[2] = 0.0; + + return out; +} diff --git a/src/Gui/Inventor/Draggers/SoLinearDragger.h b/src/Gui/Inventor/Draggers/SoLinearDragger.h new file mode 100644 index 0000000000..0faca59266 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoLinearDragger.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef GUI_TDRAGGER_H +#define GUI_TDRAGGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Gui +{ +/*! @brief Translation Dragger. + * + * used for translating along axis. Set the + * translationIncrement to desired step. Use + * 'translationIncrementCount' multiplied with + * 'translationIncrement' for a full double + * precision vector scalar. + */ +class SoLinearDragger : public SoDragger +{ + SO_KIT_HEADER(SoLinearDragger); + SO_KIT_CATALOG_ENTRY_HEADER(activeSwitch); + SO_KIT_CATALOG_ENTRY_HEADER(activeColor); + SO_KIT_CATALOG_ENTRY_HEADER(translator); + SO_KIT_CATALOG_ENTRY_HEADER(cylinderSeparator); + SO_KIT_CATALOG_ENTRY_HEADER(coneSeparator); + SO_KIT_CATALOG_ENTRY_HEADER(labelSeparator); + + static constexpr float coneBottomRadius { 0.8f }; + static constexpr float coneHeight { 2.5f }; + + static constexpr float cylinderHeight { 10.0f }; + static constexpr float cylinderRadius { 0.1f }; +public: + static void initClass(); + SoLinearDragger(); + + SoSFString label; //!< set from outside and used to label + SoSFVec3f translation; //!< set from outside and used from outside for single precision. + SoSFDouble translationIncrement; //!< set from outside and used for rounding. + SoSFInt32 translationIncrementCount; //!< number of steps. used from outside. + SoSFFloat autoScaleResult; //!< set from parent dragger. + +protected: + ~SoLinearDragger() override; + SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; + + static void startCB(void *, SoDragger * d); + static void motionCB(void *, SoDragger * d); + static void finishCB(void *, SoDragger * d); + static void fieldSensorCB(void *f, SoSensor *); + static void valueChangedCB(void *, SoDragger *d); + + void dragStart(); + void drag(); + void dragFinish(); + + SoFieldSensor fieldSensor; + SbLineProjector projector; + +private: + void buildFirstInstance(); + SbVec3f roundTranslation(const SbVec3f &vecIn, float incrementIn); + SoGroup* buildGeometry(); + + SoSeparator* buildCylinderGeometry() const; + SoSeparator* buildConeGeometry() const; + SoSeparator* buildLabelGeometry(); + SoBaseColor* buildActiveColor(); + + using inherited = SoDragger; +}; + +} + +#endif /* TDRAGGER_H */ diff --git a/src/Gui/Inventor/Draggers/SoPlanarDragger.cpp b/src/Gui/Inventor/Draggers/SoPlanarDragger.cpp new file mode 100644 index 0000000000..5b9aac85cf --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoPlanarDragger.cpp @@ -0,0 +1,359 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "SoPlanarDragger.h" + +#include "MainWindow.h" +#include "SoFCDB.h" + +#include + +using namespace Gui; + +SO_KIT_SOURCE(SoPlanarDragger) + +void SoPlanarDragger::initClass() +{ + SO_KIT_INIT_CLASS(SoPlanarDragger, SoDragger, "Dragger"); +} + +SoPlanarDragger::SoPlanarDragger() +{ + SO_KIT_CONSTRUCTOR(SoPlanarDragger); +#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + this->ref(); +#endif + + SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(planarTranslator, SoSeparator, TRUE, planarTranslatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorActive, + SoSeparator, + TRUE, + planarTranslatorSwitch, + "", + TRUE); + + if (SO_KIT_IS_FIRST_INSTANCE()) { + buildFirstInstance(); + } + + SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); + SO_KIT_ADD_FIELD(translationIncrement, (1.0)); + SO_KIT_ADD_FIELD(translationIncrementXCount, (0)); + SO_KIT_ADD_FIELD(translationIncrementYCount, (0)); + SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); + + SO_KIT_INIT_INSTANCE(); + + // initialize default parts. + // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro + // second is unique name from buildFirstInstance(). + this->setPartAsDefault("planarTranslator", "CSysDynamics_TPlanarDragger_Translator"); + this->setPartAsDefault("planarTranslatorActive", + "CSysDynamics_TPlanarDragger_TranslatorActive"); + + SoSwitch* sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 0); + + this->addStartCallback(&SoPlanarDragger::startCB); + this->addMotionCallback(&SoPlanarDragger::motionCB); + this->addFinishCallback(&SoPlanarDragger::finishCB); + + addValueChangedCallback(&SoPlanarDragger::valueChangedCB); + + fieldSensor.setFunction(&SoPlanarDragger::fieldSensorCB); + fieldSensor.setData(this); + fieldSensor.setPriority(0); + + this->setUpConnections(TRUE, TRUE); +} + +SoPlanarDragger::~SoPlanarDragger() +{ + fieldSensor.setData(nullptr); + fieldSensor.detach(); + + this->removeStartCallback(&SoPlanarDragger::startCB); + this->removeMotionCallback(&SoPlanarDragger::motionCB); + this->removeFinishCallback(&SoPlanarDragger::finishCB); + removeValueChangedCallback(&SoPlanarDragger::valueChangedCB); +} + +void SoPlanarDragger::buildFirstInstance() +{ + SoGroup* geometryGroup = buildGeometry(); + + auto localTranslator = new SoSeparator(); + localTranslator->setName("CSysDynamics_TPlanarDragger_Translator"); + localTranslator->addChild(geometryGroup); + SoFCDB::getStorage()->addChild(localTranslator); + + auto localTranslatorActive = new SoSeparator(); + localTranslatorActive->setName("CSysDynamics_TPlanarDragger_TranslatorActive"); + auto colorActive = new SoBaseColor(); + colorActive->rgb.setValue(1.0, 1.0, 0.0); + localTranslatorActive->addChild(colorActive); + localTranslatorActive->addChild(geometryGroup); + SoFCDB::getStorage()->addChild(localTranslatorActive); +} + +SoGroup* SoPlanarDragger::buildGeometry() +{ + auto root = new SoGroup(); + + float cubeWidthHeight = 2.0; + float cubeDepth = 0.1f; + + auto translation = new SoTranslation(); + translation->translation.setValue(cubeWidthHeight + 0.15, cubeWidthHeight + 0.15, 0.0); + root->addChild(translation); + + auto pickStyle = new SoPickStyle(); + pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); + pickStyle->setOverride(TRUE); + root->addChild(pickStyle); + + auto lightModel = new SoLightModel(); + lightModel->model = SoLightModel::BASE_COLOR; + root->addChild(lightModel); + + auto cube = new SoCube(); + cube->width.setValue(cubeWidthHeight); + cube->height.setValue(cubeWidthHeight); + cube->depth.setValue(cubeDepth); + root->addChild(cube); + + return root; +} + +void SoPlanarDragger::startCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragStart(); +} + +void SoPlanarDragger::motionCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->drag(); +} + +void SoPlanarDragger::finishCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragFinish(); +} + +void SoPlanarDragger::fieldSensorCB(void* f, SoSensor*) +{ + auto sudoThis = static_cast(f); + + if (!f) { + return; + } + + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + sudoThis->workFieldsIntoTransform(matrix); + sudoThis->setMotionMatrix(matrix); +} + +void SoPlanarDragger::valueChangedCB(void*, SoDragger* d) +{ + auto sudoThis = dynamic_cast(d); + assert(sudoThis); + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + + // all this just to get the translation? + SbVec3f trans, scaleDummy; + SbRotation rotationDummy, scaleOrientationDummy; + matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy); + + sudoThis->fieldSensor.detach(); + if (sudoThis->translation.getValue() != trans) { + sudoThis->translation = trans; + } + sudoThis->fieldSensor.attach(&sudoThis->translation); +} + +void SoPlanarDragger::dragStart() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 1); + + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + projector.setPlane( + SbPlane(SbVec3f(0.0, 0.0, 0.0), SbVec3f(1.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0))); + SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); + + SbMatrix localToWorld = getLocalToWorldMatrix(); + localToWorld.multVecMatrix(hitPoint, hitPoint); + setStartingPoint((hitPoint)); + + translationIncrementXCount.setValue(0); + translationIncrementYCount.setValue(0); +} + +void SoPlanarDragger::drag() +{ + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + + SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); + SbVec3f startingPoint = getLocalStartingPoint(); + SbVec3f localMovement = hitPoint - startingPoint; + + // scale the increment to match local space. + float scaledIncrement = + static_cast(translationIncrement.getValue()) / autoScaleResult.getValue(); + + localMovement = roundTranslation(localMovement, scaledIncrement); + // when the movement vector is null either the appendTranslation or + // the setMotionMatrix doesn't work. either way it stops translating + // back to its initial starting point. + if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) { + setMotionMatrix(getStartMotionMatrix()); + // don't know why I need the following but if I don't have it + // it won't return to original position. + this->valueChanged(); + } + else { + setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement)); + } + + Base::Quantity quantityX(static_cast(translationIncrementXCount.getValue()) + * translationIncrement.getValue(), + Base::Unit::Length); + Base::Quantity quantityY(static_cast(translationIncrementYCount.getValue()) + * translationIncrement.getValue(), + Base::Unit::Length); + + QString message = QStringLiteral("%1 %2, %3") + .arg(QObject::tr("Translation XY:"), + QString::fromStdString(quantityX.getUserString()), + QString::fromStdString(quantityY.getUserString())); + getMainWindow()->showMessage(message, 3000); +} + +void SoPlanarDragger::dragFinish() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 0); +} + +SbBool SoPlanarDragger::setUpConnections(SbBool onoff, SbBool doitalways) +{ + if (!doitalways && this->connectionsSetUp == onoff) { + return onoff; + } + + SbBool oldval = this->connectionsSetUp; + + if (onoff) { + inherited::setUpConnections(onoff, doitalways); + SoPlanarDragger::fieldSensorCB(this, nullptr); + if (this->fieldSensor.getAttachedField() != &this->translation) { + this->fieldSensor.attach(&this->translation); + } + } + else { + if (this->fieldSensor.getAttachedField()) { + this->fieldSensor.detach(); + } + inherited::setUpConnections(onoff, doitalways); + } + this->connectionsSetUp = onoff; + return oldval; +} + +SbVec3f SoPlanarDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn) +{ + int xCount = 0; + float xValue = vecIn[0]; + + if (fabs(xValue) > (incrementIn / 2.0)) { + xCount = static_cast(xValue / incrementIn); + float remainder = fmod(xValue, incrementIn); + if (remainder >= (incrementIn / 2.0)) { + xCount++; + } + } + + translationIncrementXCount.setValue(xCount); + + int yCount = 0; + float yValue = vecIn[1]; + + if (fabs(yValue) > (incrementIn / 2.0)) { + yCount = static_cast(yValue / incrementIn); + float remainder = fmod(yValue, incrementIn); + if (remainder >= (incrementIn / 2.0)) { + yCount++; + } + } + + translationIncrementYCount.setValue(yCount); + + SbVec3f out; + out[0] = static_cast(xCount) * incrementIn; + out[1] = static_cast(yCount) * incrementIn; + out[2] = 0.0; + + return out; +} diff --git a/src/Gui/Inventor/Draggers/SoPlanarDragger.h b/src/Gui/Inventor/Draggers/SoPlanarDragger.h new file mode 100644 index 0000000000..c02a6993d6 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoPlanarDragger.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef GUI_TPLANAR_DRAGGER_H +#define GUI_TPLANAR_DRAGGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Gui +{ +/*! @brief Planar Translation Dragger. + * + * used for translating on a plane. Set the + * translationIncrement to desired step. Use + * 'translationIncrementXCount' or + * 'translationIncrementYCount' multiplied with + * 'translationIncrement' for a full double + * precision vector scalar. + * + * @author qewer33 + */ +class SoPlanarDragger : public SoDragger +{ + SO_KIT_HEADER(SoLinearDragger); + SO_KIT_CATALOG_ENTRY_HEADER(planarTranslatorSwitch); + SO_KIT_CATALOG_ENTRY_HEADER(planarTranslator); + SO_KIT_CATALOG_ENTRY_HEADER(planarTranslatorActive); +public: + static void initClass(); + SoPlanarDragger(); + SoSFVec3f translation; //!< set from outside and used from outside for single precision. + SoSFDouble translationIncrement; //!< set from outside and used for rounding. + SoSFInt32 translationIncrementXCount; //!< number of steps. used from outside. + SoSFInt32 translationIncrementYCount; //!< number of steps. used from outside. + SoSFFloat autoScaleResult; //!< set from parent dragger. + +protected: + ~SoPlanarDragger() override; + SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; + + static void startCB(void *, SoDragger * d); + static void motionCB(void *, SoDragger * d); + static void finishCB(void *, SoDragger * d); + static void fieldSensorCB(void *f, SoSensor *); + static void valueChangedCB(void *, SoDragger *d); + + void dragStart(); + void drag(); + void dragFinish(); + + SoFieldSensor fieldSensor; + SbPlaneProjector projector; + +private: + void buildFirstInstance(); + SbVec3f roundTranslation(const SbVec3f &vecIn, float incrementIn); + SoGroup* buildGeometry(); + using inherited = SoDragger; +}; + +} + +#endif /* TPLANAR_DRAGGER */ diff --git a/src/Gui/Inventor/Draggers/SoRotationDragger.cpp b/src/Gui/Inventor/Draggers/SoRotationDragger.cpp new file mode 100644 index 0000000000..3d62d3af52 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoRotationDragger.cpp @@ -0,0 +1,367 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "SoRotationDragger.h" + +#include "MainWindow.h" +#include "SoFCDB.h" + +#include + +using namespace Gui; + +SO_KIT_SOURCE(SoRotationDragger) + +void SoRotationDragger::initClass() +{ + SO_KIT_INIT_CLASS(SoRotationDragger, SoDragger, "Dragger"); +} + +SoRotationDragger::SoRotationDragger() +{ + SO_KIT_CONSTRUCTOR(SoRotationDragger); +#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + this->ref(); +#endif + + SO_KIT_ADD_CATALOG_ENTRY(rotatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(rotator, SoSeparator, TRUE, rotatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(rotatorActive, SoSeparator, TRUE, rotatorSwitch, "", TRUE); + + arcRadius = 8.0; + + if (SO_KIT_IS_FIRST_INSTANCE()) { + buildFirstInstance(); + } + + SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0)); + SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0)); + SO_KIT_ADD_FIELD(rotationIncrementCount, (0)); + + SO_KIT_INIT_INSTANCE(); + + // initialize default parts. + // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro + // second is unique name from buildFirstInstance(). + this->setPartAsDefault("rotator", "CSysDynamics_RDragger_Rotator"); + this->setPartAsDefault("rotatorActive", "CSysDynamics_RDragger_RotatorActive"); + + SoSwitch* sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 0); + + this->addStartCallback(&SoRotationDragger::startCB); + this->addMotionCallback(&SoRotationDragger::motionCB); + this->addFinishCallback(&SoRotationDragger::finishCB); + + addValueChangedCallback(&SoRotationDragger::valueChangedCB); + + fieldSensor.setFunction(&SoRotationDragger::fieldSensorCB); + fieldSensor.setData(this); + fieldSensor.setPriority(0); + + this->setUpConnections(TRUE, TRUE); +} + +SoRotationDragger::~SoRotationDragger() +{ + fieldSensor.setData(nullptr); + fieldSensor.detach(); + + this->removeStartCallback(&SoRotationDragger::startCB); + this->removeMotionCallback(&SoRotationDragger::motionCB); + this->removeFinishCallback(&SoRotationDragger::finishCB); + removeValueChangedCallback(&SoRotationDragger::valueChangedCB); +} + +void SoRotationDragger::buildFirstInstance() +{ + SoGroup* geometryGroup = buildGeometry(); + + auto localRotator = new SoSeparator(); + localRotator->setName("CSysDynamics_RDragger_Rotator"); + localRotator->addChild(geometryGroup); + SoFCDB::getStorage()->addChild(localRotator); + + auto localRotatorActive = new SoSeparator(); + localRotatorActive->setName("CSysDynamics_RDragger_RotatorActive"); + auto colorActive = new SoBaseColor(); + colorActive->rgb.setValue(1.0, 1.0, 0.0); + localRotatorActive->addChild(colorActive); + localRotatorActive->addChild(geometryGroup); + SoFCDB::getStorage()->addChild(localRotatorActive); +} + +SoGroup* SoRotationDragger::buildGeometry() +{ + auto root = new SoGroup(); + + // arc + auto coordinates = new SoCoordinate3(); + + unsigned int segments = 15; + + float angleIncrement = (std::numbers::pi_v / 2.f) / static_cast(segments); + SbRotation rotation(SbVec3f(0.0, 0.0, 1.0), angleIncrement); + SbVec3f point(arcRadius, 0.0, 0.0); + for (unsigned int index = 0; index <= segments; ++index) { + coordinates->point.set1Value(index, point); + rotation.multVec(point, point); + } + root->addChild(coordinates); + + auto drawStyle = new SoDrawStyle(); + drawStyle->lineWidth = 4.0; + root->addChild(drawStyle); + + auto lightModel = new SoLightModel(); + lightModel->model = SoLightModel::BASE_COLOR; + root->addChild(lightModel); + + auto lineSet = new SoLineSet(); + lineSet->numVertices.setValue(segments + 1); + root->addChild(lineSet); + + auto pickStyle = new SoPickStyle(); + pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); + pickStyle->setOverride(TRUE); + root->addChild(pickStyle); + + // sphere. + SbVec3f origin(1.0, 1.0, 0.0); + origin.normalize(); + origin *= arcRadius; + auto sphereTranslation = new SoTranslation(); + sphereTranslation->translation.setValue(origin); + root->addChild(sphereTranslation); + + auto sphere = new SoSphere(); + sphere->radius.setValue(0.8F); + root->addChild(sphere); + + return root; +} + +void SoRotationDragger::startCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragStart(); +} + +void SoRotationDragger::motionCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->drag(); +} + +void SoRotationDragger::finishCB(void*, SoDragger* d) +{ + auto sudoThis = static_cast(d); + assert(sudoThis); + sudoThis->dragFinish(); +} + +void SoRotationDragger::fieldSensorCB(void* f, SoSensor*) +{ + auto sudoThis = static_cast(f); + + if (!f) { + return; + } + + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + sudoThis->workFieldsIntoTransform(matrix); + sudoThis->setMotionMatrix(matrix); +} + +void SoRotationDragger::valueChangedCB(void*, SoDragger* d) +{ + auto sudoThis = dynamic_cast(d); + assert(sudoThis); + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + + // all this just to get the translation? + SbVec3f translationDummy, scaleDummy; + SbRotation localRotation, scaleOrientationDummy; + matrix.getTransform(translationDummy, localRotation, scaleDummy, scaleOrientationDummy); + + sudoThis->fieldSensor.detach(); + if (sudoThis->rotation.getValue() != localRotation) { + sudoThis->rotation = localRotation; + } + sudoThis->fieldSensor.attach(&sudoThis->rotation); +} + +void SoRotationDragger::dragStart() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 1); + + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + projector.setPlane(SbPlane(SbVec3f(0.0, 0.0, 1.0), 0.0)); + + SbVec3f hitPoint; + if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) { + return; + } + hitPoint.normalize(); + + SbMatrix localToWorld = getLocalToWorldMatrix(); + localToWorld.multVecMatrix(hitPoint, hitPoint); + setStartingPoint((hitPoint)); + + rotationIncrementCount.setValue(0); +} + +void SoRotationDragger::drag() +{ + projector.setViewVolume(this->getViewVolume()); + projector.setWorkingSpace(this->getLocalToWorldMatrix()); + + SbVec3f hitPoint; + if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) { + return; + } + hitPoint.normalize(); + + SbVec3f startingPoint = getLocalStartingPoint(); + startingPoint.normalize(); + + SbRotation localRotation(startingPoint, hitPoint); + // getting some slop from this. grab vector and put it absolute. + SbVec3f tempVec; + float tempRadians; + localRotation.getValue(tempVec, tempRadians); + tempVec[0] = 0.0; + tempVec[1] = 0.0; + tempVec.normalize(); + if (tempVec[2] < 0.0) { + tempRadians *= -1.0; + tempVec.negate(); + } + int incrementCount = roundIncrement(tempRadians); + rotationIncrementCount.setValue(incrementCount); + localRotation = + SbRotation(tempVec, incrementCount * static_cast(rotationIncrement.getValue())); + + // same problem as described in tDragger::drag. + if (localRotation.equals(SbRotation(SbVec3f(0.0, 0.0, 1.0), 0.0), 0.00001f)) { + setMotionMatrix(getStartMotionMatrix()); + this->valueChanged(); + } + else { + setMotionMatrix( + appendRotation(getStartMotionMatrix(), localRotation, SbVec3f(0.0, 0.0, 0.0))); + } + + Base::Quantity quantity( + static_cast(rotationIncrementCount.getValue()) + * (180.0 / std::numbers::pi)* rotationIncrement.getValue(), + Base::Unit::Angle); + + QString message = + QStringLiteral("%1 %2").arg(QObject::tr("Rotation:"), QString::fromStdString(quantity.getUserString())); + getMainWindow()->showMessage(message, 3000); +} + +void SoRotationDragger::dragFinish() +{ + SoSwitch* sw; + sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, 0); +} + +SbBool SoRotationDragger::setUpConnections(SbBool onoff, SbBool doitalways) +{ + if (!doitalways && this->connectionsSetUp == onoff) { + return onoff; + } + + SbBool oldval = this->connectionsSetUp; + + if (onoff) { + inherited::setUpConnections(onoff, doitalways); + SoRotationDragger::fieldSensorCB(this, nullptr); + if (this->fieldSensor.getAttachedField() != &this->rotation) { + this->fieldSensor.attach(&this->rotation); + } + } + else { + if (this->fieldSensor.getAttachedField()) { + this->fieldSensor.detach(); + } + inherited::setUpConnections(onoff, doitalways); + } + this->connectionsSetUp = onoff; + return oldval; +} + +int SoRotationDragger::roundIncrement(const float& radiansIn) +{ + int rCount = 0; + + auto increment = static_cast(rotationIncrement.getValue()); + if (fabs(radiansIn) > (increment / 2.0)) { + rCount = static_cast(radiansIn / increment); + float remainder = fmod(radiansIn, increment); + if (remainder >= (increment / 2.0)) { + rCount++; + } + } + + return rCount; +} diff --git a/src/Gui/Inventor/Draggers/SoRotationDragger.h b/src/Gui/Inventor/Draggers/SoRotationDragger.h new file mode 100644 index 0000000000..6cbc611038 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoRotationDragger.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef GUI_RDRAGGER_H +#define GUI_RDRAGGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Gui +{ +/*! @brief Rotation Dragger. + * + * used for rotating around an axis. Set the rotation + * increment to desired step. Use rotationIncrementCount + * multiplied with rotationIncrement for full double + * precision vector scalar. + */ +class SoRotationDragger : public SoDragger +{ + SO_KIT_HEADER(SoRotationDragger); + SO_KIT_CATALOG_ENTRY_HEADER(rotatorSwitch); + SO_KIT_CATALOG_ENTRY_HEADER(rotator); + SO_KIT_CATALOG_ENTRY_HEADER(rotatorActive); +public: + static void initClass(); + SoRotationDragger(); + SoSFRotation rotation; //!< set from outside and used from outside for single precision. + SoSFDouble rotationIncrement; //!< set from outside and used for rounding. + SoSFInt32 rotationIncrementCount; //!< number of steps. used from outside. + SoSFColor color; //!< set from outside. non-active color. + +protected: + ~SoRotationDragger() override; + SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; + + static void startCB(void *, SoDragger * d); + static void motionCB(void *, SoDragger * d); + static void finishCB(void *, SoDragger * d); + static void fieldSensorCB(void *f, SoSensor *); + static void valueChangedCB(void *, SoDragger *d); + + void dragStart(); + void drag(); + void dragFinish(); + + SoFieldSensor fieldSensor; + SbPlaneProjector projector; + float arcRadius; + +private: + void buildFirstInstance(); + int roundIncrement(const float &radiansIn); + SoGroup* buildGeometry(); + using inherited = SoDragger; +}; + +} + +#endif /* GUI_RDRAGGER_H */ diff --git a/src/Gui/Inventor/Draggers/SoTransformDragger.cpp b/src/Gui/Inventor/Draggers/SoTransformDragger.cpp new file mode 100644 index 0000000000..8ac9ef5f74 --- /dev/null +++ b/src/Gui/Inventor/Draggers/SoTransformDragger.cpp @@ -0,0 +1,889 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include "SoTransformDragger.h" +#include "SoLinearDragger.h" +#include "SoPlanarDragger.h" +#include "SoRotationDragger.h" + +#include + + +/* + GENERAL NOTE ON COIN3D CUSTOM DRAGGERS + * You basically have two choices for creating custom dragger geometry. + * 1) create an .iv file and set environment variable to the file path. This + * comes with install headaches. + * 2) create an .iv file and run through a mock compiler that generates a header + * file to include in the project. I would have gone this way but after installing + * inventor-demo(ubuntu), the mock compiler tool was there only in source and make + * didn't do anything. Didn't want to put any time into something I didn't like anyway. + * + * static SbList * defaultdraggerparts = NULL; is a global definition + * in SoInteractionKit that contains the geometry. There doesn't appear to be anyway + * to add to this other than readDefaultParts, that takes a file. So maybe a temp file? + * + * naming appears to be central to the core. It looks like as long as an object + * is alive SoNode::getByName() will find it. So maybe just create my own little + * container of objects to keep the default geometry alive....This appears to be + * working and I like this solution. + * + * SoInteractionKit warns about these + * names all being the same scope and do NOT have to be unique. Need to make names + * descriptive to avoid collisions. + + * this is point of the SoGroup accessed from SoFCDB::getStorage(). +*/ + +using namespace Gui; + +SO_KIT_SOURCE(SoTransformDragger) + +void SoTransformDragger::initClass() +{ + SoLinearDragger::initClass(); + SoPlanarDragger::initClass(); + SoRotationDragger::initClass(); + SO_KIT_INIT_CLASS(SoTransformDragger, SoDragger, "Dragger"); +} + +SoTransformDragger::SoTransformDragger() + : axisScale(1.0f, 1.0f, 1.0f) +{ + SO_KIT_CONSTRUCTOR(SoTransformDragger); + +#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) + this->ref(); +#endif + + SO_KIT_ADD_CATALOG_ENTRY(annotation, So3DAnnotation, TRUE, geomSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(scaleNode, SoScale, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(pickStyle, SoPickStyle, TRUE, annotation, "", TRUE); + // Translator + + SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSeparator, SoSeparator, TRUE, xTranslatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSeparator, SoSeparator, TRUE, yTranslatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSeparator, SoSeparator, TRUE, zTranslatorSwitch, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xTranslatorColor, SoBaseColor, TRUE, xTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yTranslatorColor, SoBaseColor, TRUE, yTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zTranslatorColor, SoBaseColor, TRUE, zTranslatorSeparator, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xTranslatorRotation, SoRotation, TRUE, xTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yTranslatorRotation, SoRotation, TRUE, yTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zTranslatorRotation, SoRotation, TRUE, zTranslatorSeparator, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xTranslatorDragger, SoLinearDragger, TRUE, xTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yTranslatorDragger, SoLinearDragger, TRUE, yTranslatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zTranslatorDragger, SoLinearDragger, TRUE, zTranslatorSeparator, "", TRUE); + + // Planar Translator + + SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSeparator, + SoSeparator, + TRUE, + xyPlanarTranslatorSwitch, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSeparator, + SoSeparator, + TRUE, + yzPlanarTranslatorSwitch, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSeparator, + SoSeparator, + TRUE, + zxPlanarTranslatorSwitch, + "", + TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorColor, + SoBaseColor, + TRUE, + xyPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorColor, + SoBaseColor, + TRUE, + yzPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorColor, + SoBaseColor, + TRUE, + zxPlanarTranslatorSeparator, + "", + TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorRotation, + SoRotation, + TRUE, + xyPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorRotation, + SoRotation, + TRUE, + yzPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorRotation, + SoRotation, + TRUE, + zxPlanarTranslatorSeparator, + "", + TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorDragger, + SoPlanarDragger, + TRUE, + xyPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorDragger, + SoPlanarDragger, + TRUE, + yzPlanarTranslatorSeparator, + "", + TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorDragger, + SoPlanarDragger, + TRUE, + zxPlanarTranslatorSeparator, + "", + TRUE); + + // Rotator + + SO_KIT_ADD_CATALOG_ENTRY(xRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xRotatorSeparator, SoSeparator, TRUE, xRotatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yRotatorSeparator, SoSeparator, TRUE, yRotatorSwitch, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zRotatorSeparator, SoSeparator, TRUE, zRotatorSwitch, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xRotatorColor, SoBaseColor, TRUE, xRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yRotatorColor, SoBaseColor, TRUE, yRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zRotatorColor, SoBaseColor, TRUE, zRotatorSeparator, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xRotatorRotation, SoRotation, TRUE, xRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yRotatorRotation, SoRotation, TRUE, yRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zRotatorRotation, SoRotation, TRUE, zRotatorSeparator, "", TRUE); + + SO_KIT_ADD_CATALOG_ENTRY(xRotatorDragger, SoRotationDragger, TRUE, xRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(yRotatorDragger, SoRotationDragger, TRUE, yRotatorSeparator, "", TRUE); + SO_KIT_ADD_CATALOG_ENTRY(zRotatorDragger, SoRotationDragger, TRUE, zRotatorSeparator, "", TRUE); + + // Other + SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); + SO_KIT_ADD_FIELD(translationIncrement, (1.0)); + SO_KIT_ADD_FIELD(translationIncrementCountX, (0)); + SO_KIT_ADD_FIELD(translationIncrementCountY, (0)); + SO_KIT_ADD_FIELD(translationIncrementCountZ, (0)); + + SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0)); + SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0)); + SO_KIT_ADD_FIELD(rotationIncrementCountX, (0)); + SO_KIT_ADD_FIELD(rotationIncrementCountY, (0)); + SO_KIT_ADD_FIELD(rotationIncrementCountZ, (0)); + + SO_KIT_ADD_FIELD(draggerSize, (1.0)); + SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); + + SO_KIT_ADD_FIELD(xAxisLabel, ("X")); + SO_KIT_ADD_FIELD(yAxisLabel, ("Y")); + SO_KIT_ADD_FIELD(zAxisLabel, ("Z")); + + SO_KIT_INIT_INSTANCE(); + + // Colors + setAxisColors(SbColor(1.0, 0, 0).getPackedValue(0.0f), + SbColor(0, 1.0, 0).getPackedValue(0.0f), + SbColor(0, 0, 1.0).getPackedValue(0.0f)); + + // Translator + SoLinearDragger* tDragger; + tDragger = SO_GET_ANY_PART(this, "xTranslatorDragger", SoLinearDragger); + tDragger->translationIncrement.connectFrom(&this->translationIncrement); + tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + tDragger->label.connectFrom(&xAxisLabel); + translationIncrementCountX.connectFrom(&tDragger->translationIncrementCount); + tDragger = SO_GET_ANY_PART(this, "yTranslatorDragger", SoLinearDragger); + tDragger->translationIncrement.connectFrom(&this->translationIncrement); + tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + tDragger->label.connectFrom(&yAxisLabel); + translationIncrementCountY.connectFrom(&tDragger->translationIncrementCount); + tDragger = SO_GET_ANY_PART(this, "zTranslatorDragger", SoLinearDragger); + tDragger->translationIncrement.connectFrom(&this->translationIncrement); + tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + tDragger->label.connectFrom(&zAxisLabel); + translationIncrementCountZ.connectFrom(&tDragger->translationIncrementCount); + // Planar Translator + SoPlanarDragger* tPlanarDragger; + tPlanarDragger = SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", SoPlanarDragger); + tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); + tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + translationIncrementCountX.appendConnection(&tPlanarDragger->translationIncrementXCount); + translationIncrementCountY.appendConnection(&tPlanarDragger->translationIncrementYCount); + tPlanarDragger = SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", SoPlanarDragger); + tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); + tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + translationIncrementCountZ.appendConnection(&tPlanarDragger->translationIncrementXCount); + translationIncrementCountY.appendConnection(&tPlanarDragger->translationIncrementYCount); + tPlanarDragger = SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", SoPlanarDragger); + tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); + tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); + translationIncrementCountX.appendConnection(&tPlanarDragger->translationIncrementXCount); + translationIncrementCountZ.appendConnection(&tPlanarDragger->translationIncrementYCount); + // Rotator + SoRotationDragger* rDragger; + rDragger = SO_GET_ANY_PART(this, "xRotatorDragger", SoRotationDragger); + rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); + rotationIncrementCountX.connectFrom(&rDragger->rotationIncrementCount); + rDragger = SO_GET_ANY_PART(this, "yRotatorDragger", SoRotationDragger); + rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); + rotationIncrementCountY.connectFrom(&rDragger->rotationIncrementCount); + rDragger = SO_GET_ANY_PART(this, "zRotatorDragger", SoRotationDragger); + rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); + rotationIncrementCountZ.connectFrom(&rDragger->rotationIncrementCount); + + // Switches + + // Translator + SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + // Planar Translator + sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + // Rotator + sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); + + // Rotations + + SoRotation* localRotation; + SbRotation tempRotation; + auto angle = static_cast(std::numbers::pi / 2.0); + // Translator + localRotation = SO_GET_ANY_PART(this, "xTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbVec3f(0.0, 0.0, -1.0), angle); + localRotation = SO_GET_ANY_PART(this, "yTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbRotation::identity()); + localRotation = SO_GET_ANY_PART(this, "zTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbVec3f(1.0, 0.0, 0.0), angle); + // Planar Translator + localRotation = SO_GET_ANY_PART(this, "xyPlanarTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbRotation::identity()); + localRotation = SO_GET_ANY_PART(this, "yzPlanarTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbVec3f(0.0, -1.0, 0.0), angle); + localRotation = SO_GET_ANY_PART(this, "zxPlanarTranslatorRotation", SoRotation); + localRotation->rotation.setValue(SbVec3f(1.0, 0.0, 0.0), angle); + // Rotator + localRotation = SO_GET_ANY_PART(this, "xRotatorRotation", SoRotation); + tempRotation = SbRotation(SbVec3f(1.0, 0.0, 0.0), angle); + tempRotation *= SbRotation(SbVec3f(0.0, 0.0, 1.0), angle); + localRotation->rotation.setValue(tempRotation); + localRotation = SO_GET_ANY_PART(this, "yRotatorRotation", SoRotation); + tempRotation = SbRotation(SbVec3f(0.0, -1.0, 0.0), angle); + tempRotation *= SbRotation(SbVec3f(0.0, 0.0, -1.0), angle); + localRotation->rotation.setValue(tempRotation); + localRotation = SO_GET_ANY_PART(this, "zRotatorRotation", SoRotation); + localRotation->rotation.setValue(SbRotation::identity()); + + // this is for non-autoscale mode. this will be disconnected for autoscale + // and won't be used. see setUpAutoScale. + auto scaleEngine = new SoComposeVec3f(); // uses coin ref scheme. + scaleEngine->x.connectFrom(&draggerSize); + scaleEngine->y.connectFrom(&draggerSize); + scaleEngine->z.connectFrom(&draggerSize); + SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); + localScaleNode->scaleFactor.connectFrom(&scaleEngine->vector); + autoScaleResult.connectFrom(&draggerSize); + + SoPickStyle* localPickStyle = SO_GET_ANY_PART(this, "pickStyle", SoPickStyle); + localPickStyle->style = SoPickStyle::SHAPE_ON_TOP; + + addValueChangedCallback(&SoTransformDragger::valueChangedCB); + + translationSensor.setFunction(&SoTransformDragger::translationSensorCB); + translationSensor.setData(this); + translationSensor.setPriority(0); + + rotationSensor.setFunction(&SoTransformDragger::rotationSensorCB); + rotationSensor.setData(this); + rotationSensor.setPriority(0); + + cameraSensor.setFunction(&SoTransformDragger::cameraCB); + cameraSensor.setData(this); + + idleSensor.setFunction(&SoTransformDragger::idleCB); + idleSensor.setData(this); + + this->addFinishCallback(&SoTransformDragger::finishDragCB, this); + + this->setUpConnections(TRUE, TRUE); +} + +SoTransformDragger::~SoTransformDragger() +{ + translationSensor.setData(nullptr); + translationSensor.detach(); + rotationSensor.setData(nullptr); + rotationSensor.detach(); + cameraSensor.setData(nullptr); + cameraSensor.detach(); + idleSensor.setData(nullptr); + idleSensor.unschedule(); + + removeValueChangedCallback(&SoTransformDragger::valueChangedCB); + removeFinishCallback(&SoTransformDragger::finishDragCB, this); +} + + +SbBool SoTransformDragger::setUpConnections(SbBool onoff, SbBool doitalways) +{ + if (!doitalways && (connectionsSetUp == onoff)) { + return onoff; + } + + SoLinearDragger* tDraggerX = SO_GET_ANY_PART(this, "xTranslatorDragger", SoLinearDragger); + SoLinearDragger* tDraggerY = SO_GET_ANY_PART(this, "yTranslatorDragger", SoLinearDragger); + SoLinearDragger* tDraggerZ = SO_GET_ANY_PART(this, "zTranslatorDragger", SoLinearDragger); + SoPlanarDragger* tPlanarDraggerXZ = + SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", SoPlanarDragger); + SoPlanarDragger* tPlanarDraggerYZ = + SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", SoPlanarDragger); + SoPlanarDragger* tPlanarDraggerZX = + SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", SoPlanarDragger); + SoRotationDragger* rDraggerX = SO_GET_ANY_PART(this, "xRotatorDragger", SoRotationDragger); + SoRotationDragger* rDraggerY = SO_GET_ANY_PART(this, "yRotatorDragger", SoRotationDragger); + SoRotationDragger* rDraggerZ = SO_GET_ANY_PART(this, "zRotatorDragger", SoRotationDragger); + + if (onoff) { + inherited::setUpConnections(onoff, doitalways); + + registerChildDragger(tDraggerX); + registerChildDragger(tDraggerY); + registerChildDragger(tDraggerZ); + registerChildDragger(tPlanarDraggerXZ); + registerChildDragger(tPlanarDraggerYZ); + registerChildDragger(tPlanarDraggerZX); + registerChildDragger(rDraggerX); + registerChildDragger(rDraggerY); + registerChildDragger(rDraggerZ); + + translationSensorCB(this, nullptr); + if (this->translationSensor.getAttachedField() != &this->translation) { + this->translationSensor.attach(&this->translation); + } + + rotationSensorCB(this, nullptr); + if (this->rotationSensor.getAttachedField() != &this->rotation) { + this->rotationSensor.attach(&this->rotation); + } + } + else { + unregisterChildDragger(tDraggerX); + unregisterChildDragger(tDraggerY); + unregisterChildDragger(tDraggerZ); + unregisterChildDragger(tPlanarDraggerXZ); + unregisterChildDragger(tPlanarDraggerYZ); + unregisterChildDragger(tPlanarDraggerZX); + unregisterChildDragger(rDraggerX); + unregisterChildDragger(rDraggerY); + unregisterChildDragger(rDraggerZ); + + inherited::setUpConnections(onoff, doitalways); + + if (this->translationSensor.getAttachedField()) { + this->translationSensor.detach(); + } + + if (this->rotationSensor.getAttachedField()) { + this->rotationSensor.detach(); + } + } + return !(this->connectionsSetUp = onoff); +} + +void SoTransformDragger::translationSensorCB(void* f, SoSensor*) +{ + auto sudoThis = static_cast(f); + if (!f) { + return; + } + + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + sudoThis->workFieldsIntoTransform(matrix); + sudoThis->setMotionMatrix(matrix); +} + +void SoTransformDragger::rotationSensorCB(void* f, SoSensor*) +{ + auto sudoThis = static_cast(f); + if (!f) { + return; + } + + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + sudoThis->workFieldsIntoTransform(matrix); + sudoThis->setMotionMatrix(matrix); +} + +void SoTransformDragger::valueChangedCB(void*, SoDragger* d) +{ + auto sudoThis = dynamic_cast(d); + assert(sudoThis); + SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft + + // all this just to get the translation? + SbVec3f localTranslation, scaleDummy; + SbRotation localRotation, scaleOrientationDummy; + matrix.getTransform(localTranslation, localRotation, scaleDummy, scaleOrientationDummy); + + sudoThis->translationSensor.detach(); + if (sudoThis->translation.getValue() != localTranslation) { + sudoThis->translation = localTranslation; + } + sudoThis->translationSensor.attach(&sudoThis->translation); + + sudoThis->rotationSensor.detach(); + if (sudoThis->rotation.getValue() != localRotation) { + sudoThis->rotation = localRotation; + } + sudoThis->rotationSensor.attach(&sudoThis->rotation); +} + +void SoTransformDragger::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. + if (cameraIn->getTypeId() == SoOrthographicCamera::getClassTypeId()) { + auto localCamera = dynamic_cast(cameraIn); + assert(localCamera); + cameraSensor.attach(&localCamera->height); + SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); + localScaleNode->scaleFactor.disconnect(); + autoScaleResult.disconnect(&draggerSize); + cameraCB(this, nullptr); + } + else if (cameraIn->getTypeId() == SoPerspectiveCamera::getClassTypeId()) { + auto localCamera = dynamic_cast(cameraIn); + assert(localCamera); + cameraSensor.attach(&localCamera->position); + SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); + localScaleNode->scaleFactor.disconnect(); + autoScaleResult.disconnect(&draggerSize); + cameraCB(this, nullptr); + } +} + +void SoTransformDragger::cameraCB(void* data, SoSensor*) +{ + auto sudoThis = static_cast(data); + if (!sudoThis) { + return; + } + if (!sudoThis->idleSensor.isScheduled()) { + sudoThis->idleSensor.schedule(); + } +} + +void SoTransformDragger::GLRender(SoGLRenderAction* action) +{ + if (!scaleInited) { + scaleInited = true; + updateDraggerCache(action->getCurPath()); + updateAxisScale(); + } + + inherited::GLRender(action); +} + +void SoTransformDragger::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 SoTransformDragger::handleEvent(SoHandleEventAction* action) +{ + this->ref(); + + inherited::handleEvent(action); + updateAxisScale(); + + this->unref(); +} + +void SoTransformDragger::idleCB(void* data, SoSensor*) +{ + auto sudoThis = static_cast(data); + if (!data) { + return; + } + SoField* field = sudoThis->cameraSensor.getAttachedField(); + if (field) { + auto 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); + 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); + } +} + +void SoTransformDragger::finishDragCB(void* data, SoDragger*) +{ + auto sudoThis = static_cast(data); + assert(sudoThis); + + // 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) { + auto camera = static_cast(field->getContainer()); + if (camera->getTypeId() == SoPerspectiveCamera::getClassTypeId()) { + cameraCB(sudoThis, nullptr); + } + } +} + +void SoTransformDragger::clearIncrementCounts() +{ + translationIncrementCountX.setValue(0); + translationIncrementCountY.setValue(0); + translationIncrementCountZ.setValue(0); + rotationIncrementCountX.setValue(0); + rotationIncrementCountY.setValue(0); + rotationIncrementCountZ.setValue(0); +} + +void SoTransformDragger::setAxisColors(unsigned long x, unsigned long y, unsigned long z) +{ + SbColor colorX; + SbColor colorY; + SbColor colorZ; + + float t = 0.0f; + colorX.setPackedValue(x, t); + colorY.setPackedValue(y, t); + colorZ.setPackedValue(z, t); + + SoBaseColor* color; + + // Translator + color = SO_GET_ANY_PART(this, "xTranslatorColor", SoBaseColor); + color->rgb.setValue(colorX[0], colorX[1], colorX[2]); + color = SO_GET_ANY_PART(this, "yTranslatorColor", SoBaseColor); + color->rgb.setValue(colorY[0], colorY[1], colorY[2]); + color = SO_GET_ANY_PART(this, "zTranslatorColor", SoBaseColor); + color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); + // Planar Translator + color = SO_GET_ANY_PART(this, "xyPlanarTranslatorColor", SoBaseColor); + color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); + color = SO_GET_ANY_PART(this, "yzPlanarTranslatorColor", SoBaseColor); + color->rgb.setValue(colorX[0], colorX[1], colorX[2]); + color = SO_GET_ANY_PART(this, "zxPlanarTranslatorColor", SoBaseColor); + color->rgb.setValue(colorY[0], colorY[1], colorY[2]); + // Rotator + color = SO_GET_ANY_PART(this, "xRotatorColor", SoBaseColor); + color->rgb.setValue(colorX[0], colorX[1], colorX[2]); + color = SO_GET_ANY_PART(this, "yRotatorColor", SoBaseColor); + color->rgb.setValue(colorY[0], colorY[1], colorY[2]); + color = SO_GET_ANY_PART(this, "zRotatorColor", SoBaseColor); + color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); +} + +// Visibility API Functions + +// Translator +void SoTransformDragger::showTranslationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showTranslationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showTranslationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} + +void SoTransformDragger::hideTranslationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hideTranslationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hideTranslationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} + +bool SoTransformDragger::isShownTranslationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownTranslationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownTranslationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} + +bool SoTransformDragger::isHiddenTranslationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenTranslationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenTranslationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} + +// Planar Translator +void SoTransformDragger::showPlanarTranslationXY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showPlanarTranslationYZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showPlanarTranslationZX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} + +void SoTransformDragger::hidePlanarTranslationXY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hidePlanarTranslationYZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hidePlanarTranslationZX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} + +bool SoTransformDragger::isShownPlanarTranslationXY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownPlanarTranslationYZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownPlanarTranslationZX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} + +bool SoTransformDragger::isHiddenPlanarTranslationXY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenPlanarTranslationYZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenPlanarTranslationZX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} + +// Rotator +void SoTransformDragger::showRotationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showRotationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} +void SoTransformDragger::showRotationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); +} + +void SoTransformDragger::hideRotationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hideRotationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} +void SoTransformDragger::hideRotationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); + SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); +} + +bool SoTransformDragger::isShownRotationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownRotationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} +bool SoTransformDragger::isShownRotationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_ALL); +} + +bool SoTransformDragger::isHiddenRotationX() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenRotationY() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} +bool SoTransformDragger::isHiddenRotationZ() +{ + SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); + return (sw->whichChild.getValue() == SO_SWITCH_NONE); +} diff --git a/src/Gui/SoFCCSysDragger.h b/src/Gui/Inventor/Draggers/SoTransformDragger.h similarity index 65% rename from src/Gui/SoFCCSysDragger.h rename to src/Gui/Inventor/Draggers/SoTransformDragger.h index 99c7a77ac6..0258fc2154 100644 --- a/src/Gui/SoFCCSysDragger.h +++ b/src/Gui/Inventor/Draggers/SoTransformDragger.h @@ -20,8 +20,8 @@ * * ***************************************************************************/ -#ifndef CSYSDRAGGER_H -#define CSYSDRAGGER_H +#ifndef GUI_TRANSFORM_DRAGGER_H +#define GUI_TRANSFORM_DRAGGER_H #include #include @@ -30,9 +30,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -41,165 +38,6 @@ class SoCamera; namespace Gui { -/*! @brief Translation Dragger. - * - * used for translating along axis. Set the - * translationIncrement to desired step. Use - * 'translationIncrementCount' multiplied with - * 'translationIncrement' for a full double - * precision vector scalar. - */ -class TDragger : public SoDragger -{ - SO_KIT_HEADER(TDragger); - SO_KIT_CATALOG_ENTRY_HEADER(activeSwitch); - SO_KIT_CATALOG_ENTRY_HEADER(activeColor); - SO_KIT_CATALOG_ENTRY_HEADER(translator); - SO_KIT_CATALOG_ENTRY_HEADER(cylinderSeparator); - SO_KIT_CATALOG_ENTRY_HEADER(coneSeparator); - SO_KIT_CATALOG_ENTRY_HEADER(labelSeparator); - - static constexpr float coneBottomRadius { 0.8f }; - static constexpr float coneHeight { 2.5f }; - - static constexpr float cylinderHeight { 10.0f }; - static constexpr float cylinderRadius { 0.1f }; -public: - static void initClass(); - TDragger(); - - SoSFString label; //!< set from outside and used to label - SoSFVec3f translation; //!< set from outside and used from outside for single precision. - SoSFDouble translationIncrement; //!< set from outside and used for rounding. - SoSFInt32 translationIncrementCount; //!< number of steps. used from outside. - SoSFFloat autoScaleResult; //!< set from parent dragger. - -protected: - ~TDragger() override; - SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; - - static void startCB(void *, SoDragger * d); - static void motionCB(void *, SoDragger * d); - static void finishCB(void *, SoDragger * d); - static void fieldSensorCB(void *f, SoSensor *); - static void valueChangedCB(void *, SoDragger *d); - - void dragStart(); - void drag(); - void dragFinish(); - - SoFieldSensor fieldSensor; - SbLineProjector projector; - -private: - void buildFirstInstance(); - SbVec3f roundTranslation(const SbVec3f &vecIn, float incrementIn); - SoGroup* buildGeometry(); - - SoSeparator* buildCylinderGeometry() const; - SoSeparator* buildConeGeometry() const; - SoSeparator* buildLabelGeometry(); - SoBaseColor* buildActiveColor(); - - using inherited = SoDragger; -}; - -/*! @brief Planar Translation Dragger. - * - * used for translating on a plane. Set the - * translationIncrement to desired step. Use - * 'translationIncrementXCount' or - * 'translationIncrementYCount' multiplied with - * 'translationIncrement' for a full double - * precision vector scalar. - * - * @author qewer33 - */ -class TPlanarDragger : public SoDragger -{ - SO_KIT_HEADER(TDragger); - SO_KIT_CATALOG_ENTRY_HEADER(planarTranslatorSwitch); - SO_KIT_CATALOG_ENTRY_HEADER(planarTranslator); - SO_KIT_CATALOG_ENTRY_HEADER(planarTranslatorActive); -public: - static void initClass(); - TPlanarDragger(); - SoSFVec3f translation; //!< set from outside and used from outside for single precision. - SoSFDouble translationIncrement; //!< set from outside and used for rounding. - SoSFInt32 translationIncrementXCount; //!< number of steps. used from outside. - SoSFInt32 translationIncrementYCount; //!< number of steps. used from outside. - SoSFFloat autoScaleResult; //!< set from parent dragger. - -protected: - ~TPlanarDragger() override; - SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; - - static void startCB(void *, SoDragger * d); - static void motionCB(void *, SoDragger * d); - static void finishCB(void *, SoDragger * d); - static void fieldSensorCB(void *f, SoSensor *); - static void valueChangedCB(void *, SoDragger *d); - - void dragStart(); - void drag(); - void dragFinish(); - - SoFieldSensor fieldSensor; - SbPlaneProjector projector; - -private: - void buildFirstInstance(); - SbVec3f roundTranslation(const SbVec3f &vecIn, float incrementIn); - SoGroup* buildGeometry(); - using inherited = SoDragger; -}; - -/*! @brief Rotation Dragger. - * - * used for rotating around an axis. Set the rotation - * increment to desired step. Use rotationIncrementCount - * multiplied with rotationIncrement for full double - * precision vector scalar. - */ -class RDragger : public SoDragger -{ - SO_KIT_HEADER(RDragger); - SO_KIT_CATALOG_ENTRY_HEADER(rotatorSwitch); - SO_KIT_CATALOG_ENTRY_HEADER(rotator); - SO_KIT_CATALOG_ENTRY_HEADER(rotatorActive); -public: - static void initClass(); - RDragger(); - SoSFRotation rotation; //!< set from outside and used from outside for single precision. - SoSFDouble rotationIncrement; //!< set from outside and used for rounding. - SoSFInt32 rotationIncrementCount; //!< number of steps. used from outside. - SoSFColor color; //!< set from outside. non-active color. - -protected: - ~RDragger() override; - SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; - - static void startCB(void *, SoDragger * d); - static void motionCB(void *, SoDragger * d); - static void finishCB(void *, SoDragger * d); - static void fieldSensorCB(void *f, SoSensor *); - static void valueChangedCB(void *, SoDragger *d); - - void dragStart(); - void drag(); - void dragFinish(); - - SoFieldSensor fieldSensor; - SbPlaneProjector projector; - float arcRadius; - -private: - void buildFirstInstance(); - int roundIncrement(const float &radiansIn); - SoGroup* buildGeometry(); - using inherited = SoDragger; -}; - /*! @brief Coordinate System Dragger * * used to transform objects in 3d space. Set initial: @@ -212,9 +50,9 @@ private: * For autoscale you set the field scale & call setupAutoScale with * the viewer camera. @see setUpAutoScale @see scale. */ -class GuiExport SoFCCSysDragger : public SoDragger +class GuiExport SoTransformDragger : public SoDragger { - SO_KIT_HEADER(SoFCCSysDragger); + SO_KIT_HEADER(SoTransformDragger); SO_KIT_CATALOG_ENTRY_HEADER(annotation); SO_KIT_CATALOG_ENTRY_HEADER(scaleNode); SO_KIT_CATALOG_ENTRY_HEADER(pickStyle); @@ -268,8 +106,8 @@ class GuiExport SoFCCSysDragger : public SoDragger SO_KIT_CATALOG_ENTRY_HEADER(zRotatorDragger); public: static void initClass(); - SoFCCSysDragger(); - ~SoFCCSysDragger() override; + SoTransformDragger(); + ~SoTransformDragger() override; SoSFVec3f translation; //!< initial translation and reflects single precision movement. SoSFDouble translationIncrement; //!< set from outside used for rounding. @@ -377,4 +215,4 @@ private: } -#endif // CSYSDRAGGER_H +#endif /* GUI_TRANSFORM_DRAGGER_H */ diff --git a/src/Gui/SoFCCSysDragger.cpp b/src/Gui/SoFCCSysDragger.cpp deleted file mode 100644 index 21142b5def..0000000000 --- a/src/Gui/SoFCCSysDragger.cpp +++ /dev/null @@ -1,1826 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2015 Thomas Anderson * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include - -#include "SoFCCSysDragger.h" -#include "Inventor/So3DAnnotation.h" - -#include "MainWindow.h" -#include "SoFCDB.h" - -#include - - -/* - GENERAL NOTE ON COIN3D CUSTOM DRAGGERS - * You basically have two choices for creating custom dragger geometry. - * 1) create an .iv file and set environment variable to the file path. This - * comes with install headaches. - * 2) create an .iv file and run through a mock compiler that generates a header - * file to include in the project. I would have gone this way but after installing - * inventor-demo(ubuntu), the mock compiler tool was there only in source and make - * didn't do anything. Didn't want to put any time into something I didn't like anyway. - * - * static SbList * defaultdraggerparts = NULL; is a global definition - * in SoInteractionKit that contains the geometry. There doesn't appear to be anyway - * to add to this other than readDefaultParts, that takes a file. So maybe a temp file? - * - * naming appears to be central to the core. It looks like as long as an object - * is alive SoNode::getByName() will find it. So maybe just create my own little - * container of objects to keep the default geometry alive....This appears to be - * working and I like this solution. - * - * SoInteractionKit warns about these - * names all being the same scope and do NOT have to be unique. Need to make names - * descriptive to avoid collisions. - - * this is point of the SoGroup accessed from SoFCDB::getStorage(). -*/ - -using namespace Gui; - -SO_KIT_SOURCE(TDragger) - -void TDragger::initClass() -{ - SO_KIT_INIT_CLASS(TDragger, SoDragger, "Dragger"); -} - -TDragger::TDragger() -{ - SO_KIT_CONSTRUCTOR(TDragger); - -#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - this->ref(); -#endif - - SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE, geomSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(activeSwitch, SoSwitch, TRUE, translator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(activeColor, SoBaseColor, TRUE, activeSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(coneSeparator, SoSeparator, TRUE, translator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(cylinderSeparator, SoSeparator, TRUE, translator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(labelSeparator, SoSeparator, TRUE, translator, "", TRUE); - - if (SO_KIT_IS_FIRST_INSTANCE()) { - buildFirstInstance(); - } - - SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE, geomSeparator, "", TRUE); - - SO_KIT_ADD_FIELD(label, ("")); - SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); - SO_KIT_ADD_FIELD(translationIncrement, (1.0)); - SO_KIT_ADD_FIELD(translationIncrementCount, (0)); - SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); - - SO_KIT_INIT_INSTANCE(); - - // initialize default parts. - // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro - // second is unique name from buildFirstInstance(). - SoInteractionKit::setPartAsDefault("coneSeparator", "CSysDynamics_TDragger_Cone"); - SoInteractionKit::setPartAsDefault("cylinderSeparator", "CSysDynamics_TDragger_Cylinder"); - SoInteractionKit::setPartAsDefault("activeColor", "CSysDynamics_TDragger_ActiveColor"); - - SoInteractionKit::setPart("labelSeparator", buildLabelGeometry()); - - auto sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); - - - this->addStartCallback(&TDragger::startCB); - this->addMotionCallback(&TDragger::motionCB); - this->addFinishCallback(&TDragger::finishCB); - - addValueChangedCallback(&TDragger::valueChangedCB); - - fieldSensor.setFunction(&TDragger::fieldSensorCB); - fieldSensor.setData(this); - fieldSensor.setPriority(0); - - this->setUpConnections(TRUE, TRUE); -} - -TDragger::~TDragger() -{ - fieldSensor.setData(nullptr); - fieldSensor.detach(); - - this->removeStartCallback(&TDragger::startCB); - this->removeMotionCallback(&TDragger::motionCB); - this->removeFinishCallback(&TDragger::finishCB); - removeValueChangedCallback(&TDragger::valueChangedCB); -} - -void TDragger::buildFirstInstance() -{ - auto cylinderSeparator = buildCylinderGeometry(); - auto coneSeparator = buildConeGeometry(); - auto activeColor = buildActiveColor(); - - cylinderSeparator->setName("CSysDynamics_TDragger_Cylinder"); - coneSeparator->setName("CSysDynamics_TDragger_Cone"); - activeColor->setName("CSysDynamics_TDragger_ActiveColor"); - - SoFCDB::getStorage()->addChild(cylinderSeparator); - SoFCDB::getStorage()->addChild(coneSeparator); - SoFCDB::getStorage()->addChild(activeColor); -} - -SoSeparator* TDragger::buildCylinderGeometry() const -{ - auto cylinderSeparator = new SoSeparator(); - - auto cylinderLightModel = new SoLightModel(); - cylinderLightModel->model = SoLightModel::BASE_COLOR; - cylinderSeparator->addChild(cylinderLightModel); - - auto cylinderTranslation = new SoTranslation(); - cylinderTranslation->translation.setValue(0.0, cylinderHeight / 2.0, 0.0); - cylinderSeparator->addChild(cylinderTranslation); - - auto cylinder = new SoCylinder(); - cylinder->radius.setValue(cylinderRadius); - cylinder->height.setValue(cylinderHeight); - cylinderSeparator->addChild(cylinder); - - return cylinderSeparator; -} - -SoSeparator* TDragger::buildConeGeometry() const -{ - auto coneLightModel = new SoLightModel(); - coneLightModel->model = SoLightModel::BASE_COLOR; - - auto coneSeparator = new SoSeparator(); - coneSeparator->addChild(coneLightModel); - - auto pickStyle = new SoPickStyle(); - pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); - pickStyle->setOverride(TRUE); - coneSeparator->addChild(pickStyle); - - auto coneTranslation = new SoTranslation(); - coneTranslation->translation.setValue(0.0, cylinderHeight + coneHeight / 2.0, 0.0); - coneSeparator->addChild(coneTranslation); - - auto cone = new SoCone(); - cone->bottomRadius.setValue(coneBottomRadius); - cone->height.setValue(coneHeight); - coneSeparator->addChild(cone); - - return coneSeparator; -} - -SoSeparator* TDragger::buildLabelGeometry() -{ - auto labelSeparator = new SoSeparator(); - - auto labelTranslation = new SoTranslation(); - labelTranslation->translation.setValue(0.0, cylinderHeight + coneHeight * 1.5, 0.0); - labelSeparator->addChild(labelTranslation); - - auto label = new SoFrameLabel(); - label->string.connectFrom(&this->label); - label->textColor.setValue(1.0, 1.0, 1.0); - label->horAlignment = SoImage::CENTER; - label->vertAlignment = SoImage::HALF; - label->border = false; - label->backgroundUseBaseColor = true; - labelSeparator->addChild(label); - - return labelSeparator; -} - -SoBaseColor* TDragger::buildActiveColor() -{ - auto colorActive = new SoBaseColor(); - colorActive->rgb.setValue(1.0, 1.0, 0.0); - - return colorActive; -} - -void TDragger::startCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragStart(); -} - -void TDragger::motionCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->drag(); -} - -void TDragger::finishCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragFinish(); -} - -void TDragger::fieldSensorCB(void* f, SoSensor*) -{ - auto sudoThis = static_cast(f); - - if (!f) { - return; - } - - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - sudoThis->workFieldsIntoTransform(matrix); - sudoThis->setMotionMatrix(matrix); -} - -void TDragger::valueChangedCB(void*, SoDragger* d) -{ - auto sudoThis = dynamic_cast(d); - assert(sudoThis); - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - - // all this just to get the translation? - SbVec3f trans, scaleDummy; - SbRotation rotationDummy, scaleOrientationDummy; - matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy); - - sudoThis->fieldSensor.detach(); - if (sudoThis->translation.getValue() != trans) { - sudoThis->translation = trans; - } - sudoThis->fieldSensor.attach(&sudoThis->translation); -} - -void TDragger::dragStart() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - - // do an initial projection to eliminate discrepancies - // in arrow head pick. we define the arrow in the y+ direction - // and we know local space will be relative to this. so y vector - // line projection will work. - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - projector.setLine(SbLine(SbVec3f(0.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0))); - SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); - - projector.setLine(SbLine(SbVec3f(0.0, 0.0, 0.0), hitPoint)); - - SbMatrix localToWorld = getLocalToWorldMatrix(); - localToWorld.multVecMatrix(hitPoint, hitPoint); - setStartingPoint((hitPoint)); - - translationIncrementCount.setValue(0); -} - -void TDragger::drag() -{ - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - - SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); - SbVec3f startingPoint = getLocalStartingPoint(); - SbVec3f localMovement = hitPoint - startingPoint; - - // scale the increment to match local space. - float scaledIncrement = - static_cast(translationIncrement.getValue()) / autoScaleResult.getValue(); - - localMovement = roundTranslation(localMovement, scaledIncrement); - // when the movement vector is null either the appendTranslation or - // the setMotionMatrix doesn't work. either way it stops translating - // back to its initial starting point. - if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) { - setMotionMatrix(getStartMotionMatrix()); - // don't know why I need the following but if I don't have it - // it won't return to original position. - this->valueChanged(); - } - else { - setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement)); - } - - Base::Quantity quantity(static_cast(translationIncrementCount.getValue()) - * translationIncrement.getValue(), - Base::Unit::Length); - - QString message = - QStringLiteral("%1 %2").arg(QObject::tr("Translation:"), QString::fromStdString(quantity.getUserString())); - getMainWindow()->showMessage(message, 3000); -} - -void TDragger::dragFinish() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "activeSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} - -SbBool TDragger::setUpConnections(SbBool onoff, SbBool doitalways) -{ - if (!doitalways && this->connectionsSetUp == onoff) { - return onoff; - } - - SbBool oldval = this->connectionsSetUp; - - if (onoff) { - inherited::setUpConnections(onoff, doitalways); - TDragger::fieldSensorCB(this, nullptr); - if (this->fieldSensor.getAttachedField() != &this->translation) { - this->fieldSensor.attach(&this->translation); - } - } - else { - if (this->fieldSensor.getAttachedField()) { - this->fieldSensor.detach(); - } - inherited::setUpConnections(onoff, doitalways); - } - this->connectionsSetUp = onoff; - return oldval; -} - -SbVec3f TDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn) -{ - // everything is transformed into local space. That means we only have - // worry about the y-value. - - int yCount = 0; - float yValue = vecIn[1]; - - if (fabs(yValue) > (incrementIn / 2.0)) { - yCount = static_cast(yValue / incrementIn); - float remainder = fmod(yValue, incrementIn); - if (remainder >= (incrementIn / 2.0)) { - yCount++; - } - } - - translationIncrementCount.setValue(yCount); - - SbVec3f out; - out[0] = 0; - out[1] = static_cast(yCount) * incrementIn; - out[2] = 0.0; - - return out; -} - - -SO_KIT_SOURCE(TPlanarDragger) - -void TPlanarDragger::initClass() -{ - SO_KIT_INIT_CLASS(TPlanarDragger, SoDragger, "Dragger"); -} - -TPlanarDragger::TPlanarDragger() -{ - SO_KIT_CONSTRUCTOR(TPlanarDragger); -#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - this->ref(); -#endif - - SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(planarTranslator, SoSeparator, TRUE, planarTranslatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorActive, - SoSeparator, - TRUE, - planarTranslatorSwitch, - "", - TRUE); - - if (SO_KIT_IS_FIRST_INSTANCE()) { - buildFirstInstance(); - } - - SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); - SO_KIT_ADD_FIELD(translationIncrement, (1.0)); - SO_KIT_ADD_FIELD(translationIncrementXCount, (0)); - SO_KIT_ADD_FIELD(translationIncrementYCount, (0)); - SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); - - SO_KIT_INIT_INSTANCE(); - - // initialize default parts. - // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro - // second is unique name from buildFirstInstance(). - this->setPartAsDefault("planarTranslator", "CSysDynamics_TPlanarDragger_Translator"); - this->setPartAsDefault("planarTranslatorActive", - "CSysDynamics_TPlanarDragger_TranslatorActive"); - - SoSwitch* sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 0); - - this->addStartCallback(&TPlanarDragger::startCB); - this->addMotionCallback(&TPlanarDragger::motionCB); - this->addFinishCallback(&TPlanarDragger::finishCB); - - addValueChangedCallback(&TPlanarDragger::valueChangedCB); - - fieldSensor.setFunction(&TPlanarDragger::fieldSensorCB); - fieldSensor.setData(this); - fieldSensor.setPriority(0); - - this->setUpConnections(TRUE, TRUE); -} - -TPlanarDragger::~TPlanarDragger() -{ - fieldSensor.setData(nullptr); - fieldSensor.detach(); - - this->removeStartCallback(&TPlanarDragger::startCB); - this->removeMotionCallback(&TPlanarDragger::motionCB); - this->removeFinishCallback(&TPlanarDragger::finishCB); - removeValueChangedCallback(&TPlanarDragger::valueChangedCB); -} - -void TPlanarDragger::buildFirstInstance() -{ - SoGroup* geometryGroup = buildGeometry(); - - auto localTranslator = new SoSeparator(); - localTranslator->setName("CSysDynamics_TPlanarDragger_Translator"); - localTranslator->addChild(geometryGroup); - SoFCDB::getStorage()->addChild(localTranslator); - - auto localTranslatorActive = new SoSeparator(); - localTranslatorActive->setName("CSysDynamics_TPlanarDragger_TranslatorActive"); - auto colorActive = new SoBaseColor(); - colorActive->rgb.setValue(1.0, 1.0, 0.0); - localTranslatorActive->addChild(colorActive); - localTranslatorActive->addChild(geometryGroup); - SoFCDB::getStorage()->addChild(localTranslatorActive); -} - -SoGroup* TPlanarDragger::buildGeometry() -{ - auto root = new SoGroup(); - - float cubeWidthHeight = 2.0; - float cubeDepth = 0.1f; - - auto translation = new SoTranslation(); - translation->translation.setValue(cubeWidthHeight + 0.15, cubeWidthHeight + 0.15, 0.0); - root->addChild(translation); - - auto pickStyle = new SoPickStyle(); - pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); - pickStyle->setOverride(TRUE); - root->addChild(pickStyle); - - auto lightModel = new SoLightModel(); - lightModel->model = SoLightModel::BASE_COLOR; - root->addChild(lightModel); - - auto cube = new SoCube(); - cube->width.setValue(cubeWidthHeight); - cube->height.setValue(cubeWidthHeight); - cube->depth.setValue(cubeDepth); - root->addChild(cube); - - return root; -} - -void TPlanarDragger::startCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragStart(); -} - -void TPlanarDragger::motionCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->drag(); -} - -void TPlanarDragger::finishCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragFinish(); -} - -void TPlanarDragger::fieldSensorCB(void* f, SoSensor*) -{ - auto sudoThis = static_cast(f); - - if (!f) { - return; - } - - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - sudoThis->workFieldsIntoTransform(matrix); - sudoThis->setMotionMatrix(matrix); -} - -void TPlanarDragger::valueChangedCB(void*, SoDragger* d) -{ - auto sudoThis = dynamic_cast(d); - assert(sudoThis); - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - - // all this just to get the translation? - SbVec3f trans, scaleDummy; - SbRotation rotationDummy, scaleOrientationDummy; - matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy); - - sudoThis->fieldSensor.detach(); - if (sudoThis->translation.getValue() != trans) { - sudoThis->translation = trans; - } - sudoThis->fieldSensor.attach(&sudoThis->translation); -} - -void TPlanarDragger::dragStart() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 1); - - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - projector.setPlane( - SbPlane(SbVec3f(0.0, 0.0, 0.0), SbVec3f(1.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0))); - SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); - - SbMatrix localToWorld = getLocalToWorldMatrix(); - localToWorld.multVecMatrix(hitPoint, hitPoint); - setStartingPoint((hitPoint)); - - translationIncrementXCount.setValue(0); - translationIncrementYCount.setValue(0); -} - -void TPlanarDragger::drag() -{ - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - - SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition()); - SbVec3f startingPoint = getLocalStartingPoint(); - SbVec3f localMovement = hitPoint - startingPoint; - - // scale the increment to match local space. - float scaledIncrement = - static_cast(translationIncrement.getValue()) / autoScaleResult.getValue(); - - localMovement = roundTranslation(localMovement, scaledIncrement); - // when the movement vector is null either the appendTranslation or - // the setMotionMatrix doesn't work. either way it stops translating - // back to its initial starting point. - if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) { - setMotionMatrix(getStartMotionMatrix()); - // don't know why I need the following but if I don't have it - // it won't return to original position. - this->valueChanged(); - } - else { - setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement)); - } - - Base::Quantity quantityX(static_cast(translationIncrementXCount.getValue()) - * translationIncrement.getValue(), - Base::Unit::Length); - Base::Quantity quantityY(static_cast(translationIncrementYCount.getValue()) - * translationIncrement.getValue(), - Base::Unit::Length); - - QString message = QStringLiteral("%1 %2, %3") - .arg(QObject::tr("Translation XY:"), - QString::fromStdString(quantityX.getUserString()), - QString::fromStdString(quantityY.getUserString())); - getMainWindow()->showMessage(message, 3000); -} - -void TPlanarDragger::dragFinish() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 0); -} - -SbBool TPlanarDragger::setUpConnections(SbBool onoff, SbBool doitalways) -{ - if (!doitalways && this->connectionsSetUp == onoff) { - return onoff; - } - - SbBool oldval = this->connectionsSetUp; - - if (onoff) { - inherited::setUpConnections(onoff, doitalways); - TPlanarDragger::fieldSensorCB(this, nullptr); - if (this->fieldSensor.getAttachedField() != &this->translation) { - this->fieldSensor.attach(&this->translation); - } - } - else { - if (this->fieldSensor.getAttachedField()) { - this->fieldSensor.detach(); - } - inherited::setUpConnections(onoff, doitalways); - } - this->connectionsSetUp = onoff; - return oldval; -} - -SbVec3f TPlanarDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn) -{ - int xCount = 0; - float xValue = vecIn[0]; - - if (fabs(xValue) > (incrementIn / 2.0)) { - xCount = static_cast(xValue / incrementIn); - float remainder = fmod(xValue, incrementIn); - if (remainder >= (incrementIn / 2.0)) { - xCount++; - } - } - - translationIncrementXCount.setValue(xCount); - - int yCount = 0; - float yValue = vecIn[1]; - - if (fabs(yValue) > (incrementIn / 2.0)) { - yCount = static_cast(yValue / incrementIn); - float remainder = fmod(yValue, incrementIn); - if (remainder >= (incrementIn / 2.0)) { - yCount++; - } - } - - translationIncrementYCount.setValue(yCount); - - SbVec3f out; - out[0] = static_cast(xCount) * incrementIn; - out[1] = static_cast(yCount) * incrementIn; - out[2] = 0.0; - - return out; -} - - -SO_KIT_SOURCE(RDragger) - -void RDragger::initClass() -{ - SO_KIT_INIT_CLASS(RDragger, SoDragger, "Dragger"); -} - -RDragger::RDragger() -{ - SO_KIT_CONSTRUCTOR(RDragger); -#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - this->ref(); -#endif - - SO_KIT_ADD_CATALOG_ENTRY(rotatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(rotator, SoSeparator, TRUE, rotatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(rotatorActive, SoSeparator, TRUE, rotatorSwitch, "", TRUE); - - arcRadius = 8.0; - - if (SO_KIT_IS_FIRST_INSTANCE()) { - buildFirstInstance(); - } - - SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0)); - SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0)); - SO_KIT_ADD_FIELD(rotationIncrementCount, (0)); - - SO_KIT_INIT_INSTANCE(); - - // initialize default parts. - // first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro - // second is unique name from buildFirstInstance(). - this->setPartAsDefault("rotator", "CSysDynamics_RDragger_Rotator"); - this->setPartAsDefault("rotatorActive", "CSysDynamics_RDragger_RotatorActive"); - - SoSwitch* sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 0); - - this->addStartCallback(&RDragger::startCB); - this->addMotionCallback(&RDragger::motionCB); - this->addFinishCallback(&RDragger::finishCB); - - addValueChangedCallback(&RDragger::valueChangedCB); - - fieldSensor.setFunction(&RDragger::fieldSensorCB); - fieldSensor.setData(this); - fieldSensor.setPriority(0); - - this->setUpConnections(TRUE, TRUE); -} - -RDragger::~RDragger() -{ - fieldSensor.setData(nullptr); - fieldSensor.detach(); - - this->removeStartCallback(&RDragger::startCB); - this->removeMotionCallback(&RDragger::motionCB); - this->removeFinishCallback(&RDragger::finishCB); - removeValueChangedCallback(&RDragger::valueChangedCB); -} - -void RDragger::buildFirstInstance() -{ - SoGroup* geometryGroup = buildGeometry(); - - auto localRotator = new SoSeparator(); - localRotator->setName("CSysDynamics_RDragger_Rotator"); - localRotator->addChild(geometryGroup); - SoFCDB::getStorage()->addChild(localRotator); - - auto localRotatorActive = new SoSeparator(); - localRotatorActive->setName("CSysDynamics_RDragger_RotatorActive"); - auto colorActive = new SoBaseColor(); - colorActive->rgb.setValue(1.0, 1.0, 0.0); - localRotatorActive->addChild(colorActive); - localRotatorActive->addChild(geometryGroup); - SoFCDB::getStorage()->addChild(localRotatorActive); -} - -SoGroup* RDragger::buildGeometry() -{ - auto root = new SoGroup(); - - // arc - auto coordinates = new SoCoordinate3(); - - unsigned int segments = 15; - - float angleIncrement = (std::numbers::pi_v / 2.f) / static_cast(segments); - SbRotation rotation(SbVec3f(0.0, 0.0, 1.0), angleIncrement); - SbVec3f point(arcRadius, 0.0, 0.0); - for (unsigned int index = 0; index <= segments; ++index) { - coordinates->point.set1Value(index, point); - rotation.multVec(point, point); - } - root->addChild(coordinates); - - auto drawStyle = new SoDrawStyle(); - drawStyle->lineWidth = 4.0; - root->addChild(drawStyle); - - auto lightModel = new SoLightModel(); - lightModel->model = SoLightModel::BASE_COLOR; - root->addChild(lightModel); - - auto lineSet = new SoLineSet(); - lineSet->numVertices.setValue(segments + 1); - root->addChild(lineSet); - - auto pickStyle = new SoPickStyle(); - pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP); - pickStyle->setOverride(TRUE); - root->addChild(pickStyle); - - // sphere. - SbVec3f origin(1.0, 1.0, 0.0); - origin.normalize(); - origin *= arcRadius; - auto sphereTranslation = new SoTranslation(); - sphereTranslation->translation.setValue(origin); - root->addChild(sphereTranslation); - - auto sphere = new SoSphere(); - sphere->radius.setValue(0.8F); - root->addChild(sphere); - - return root; -} - -void RDragger::startCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragStart(); -} - -void RDragger::motionCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->drag(); -} - -void RDragger::finishCB(void*, SoDragger* d) -{ - auto sudoThis = static_cast(d); - assert(sudoThis); - sudoThis->dragFinish(); -} - -void RDragger::fieldSensorCB(void* f, SoSensor*) -{ - auto sudoThis = static_cast(f); - - if (!f) { - return; - } - - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - sudoThis->workFieldsIntoTransform(matrix); - sudoThis->setMotionMatrix(matrix); -} - -void RDragger::valueChangedCB(void*, SoDragger* d) -{ - auto sudoThis = dynamic_cast(d); - assert(sudoThis); - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - - // all this just to get the translation? - SbVec3f translationDummy, scaleDummy; - SbRotation localRotation, scaleOrientationDummy; - matrix.getTransform(translationDummy, localRotation, scaleDummy, scaleOrientationDummy); - - sudoThis->fieldSensor.detach(); - if (sudoThis->rotation.getValue() != localRotation) { - sudoThis->rotation = localRotation; - } - sudoThis->fieldSensor.attach(&sudoThis->rotation); -} - -void RDragger::dragStart() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 1); - - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - projector.setPlane(SbPlane(SbVec3f(0.0, 0.0, 1.0), 0.0)); - - SbVec3f hitPoint; - if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) { - return; - } - hitPoint.normalize(); - - SbMatrix localToWorld = getLocalToWorldMatrix(); - localToWorld.multVecMatrix(hitPoint, hitPoint); - setStartingPoint((hitPoint)); - - rotationIncrementCount.setValue(0); -} - -void RDragger::drag() -{ - projector.setViewVolume(this->getViewVolume()); - projector.setWorkingSpace(this->getLocalToWorldMatrix()); - - SbVec3f hitPoint; - if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) { - return; - } - hitPoint.normalize(); - - SbVec3f startingPoint = getLocalStartingPoint(); - startingPoint.normalize(); - - SbRotation localRotation(startingPoint, hitPoint); - // getting some slop from this. grab vector and put it absolute. - SbVec3f tempVec; - float tempRadians; - localRotation.getValue(tempVec, tempRadians); - tempVec[0] = 0.0; - tempVec[1] = 0.0; - tempVec.normalize(); - if (tempVec[2] < 0.0) { - tempRadians *= -1.0; - tempVec.negate(); - } - int incrementCount = roundIncrement(tempRadians); - rotationIncrementCount.setValue(incrementCount); - localRotation = - SbRotation(tempVec, incrementCount * static_cast(rotationIncrement.getValue())); - - // same problem as described in tDragger::drag. - if (localRotation.equals(SbRotation(SbVec3f(0.0, 0.0, 1.0), 0.0), 0.00001f)) { - setMotionMatrix(getStartMotionMatrix()); - this->valueChanged(); - } - else { - setMotionMatrix( - appendRotation(getStartMotionMatrix(), localRotation, SbVec3f(0.0, 0.0, 0.0))); - } - - Base::Quantity quantity( - static_cast(rotationIncrementCount.getValue()) - * (180.0 / std::numbers::pi)* rotationIncrement.getValue(), - Base::Unit::Angle); - - QString message = - QStringLiteral("%1 %2").arg(QObject::tr("Rotation:"), QString::fromStdString(quantity.getUserString())); - getMainWindow()->showMessage(message, 3000); -} - -void RDragger::dragFinish() -{ - SoSwitch* sw; - sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, 0); -} - -SbBool RDragger::setUpConnections(SbBool onoff, SbBool doitalways) -{ - if (!doitalways && this->connectionsSetUp == onoff) { - return onoff; - } - - SbBool oldval = this->connectionsSetUp; - - if (onoff) { - inherited::setUpConnections(onoff, doitalways); - RDragger::fieldSensorCB(this, nullptr); - if (this->fieldSensor.getAttachedField() != &this->rotation) { - this->fieldSensor.attach(&this->rotation); - } - } - else { - if (this->fieldSensor.getAttachedField()) { - this->fieldSensor.detach(); - } - inherited::setUpConnections(onoff, doitalways); - } - this->connectionsSetUp = onoff; - return oldval; -} - -int RDragger::roundIncrement(const float& radiansIn) -{ - int rCount = 0; - - auto increment = static_cast(rotationIncrement.getValue()); - if (fabs(radiansIn) > (increment / 2.0)) { - rCount = static_cast(radiansIn / increment); - float remainder = fmod(radiansIn, increment); - if (remainder >= (increment / 2.0)) { - rCount++; - } - } - - return rCount; -} - - -SO_KIT_SOURCE(SoFCCSysDragger) - -void SoFCCSysDragger::initClass() -{ - TDragger::initClass(); - TPlanarDragger::initClass(); - RDragger::initClass(); - SO_KIT_INIT_CLASS(SoFCCSysDragger, SoDragger, "Dragger"); -} - -SoFCCSysDragger::SoFCCSysDragger() - : axisScale(1.0f, 1.0f, 1.0f) -{ - SO_KIT_CONSTRUCTOR(SoFCCSysDragger); - -#if defined(Q_OS_MACOS) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - this->ref(); -#endif - - SO_KIT_ADD_CATALOG_ENTRY(annotation, So3DAnnotation, TRUE, geomSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(scaleNode, SoScale, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(pickStyle, SoPickStyle, TRUE, annotation, "", TRUE); - // Translator - - SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xTranslatorSeparator, SoSeparator, TRUE, xTranslatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yTranslatorSeparator, SoSeparator, TRUE, yTranslatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zTranslatorSeparator, SoSeparator, TRUE, zTranslatorSwitch, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xTranslatorColor, SoBaseColor, TRUE, xTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yTranslatorColor, SoBaseColor, TRUE, yTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zTranslatorColor, SoBaseColor, TRUE, zTranslatorSeparator, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xTranslatorRotation, SoRotation, TRUE, xTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yTranslatorRotation, SoRotation, TRUE, yTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zTranslatorRotation, SoRotation, TRUE, zTranslatorSeparator, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xTranslatorDragger, TDragger, TRUE, xTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yTranslatorDragger, TDragger, TRUE, yTranslatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zTranslatorDragger, TDragger, TRUE, zTranslatorSeparator, "", TRUE); - - // Planar Translator - - SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSeparator, - SoSeparator, - TRUE, - xyPlanarTranslatorSwitch, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSeparator, - SoSeparator, - TRUE, - yzPlanarTranslatorSwitch, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSeparator, - SoSeparator, - TRUE, - zxPlanarTranslatorSwitch, - "", - TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorColor, - SoBaseColor, - TRUE, - xyPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorColor, - SoBaseColor, - TRUE, - yzPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorColor, - SoBaseColor, - TRUE, - zxPlanarTranslatorSeparator, - "", - TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorRotation, - SoRotation, - TRUE, - xyPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorRotation, - SoRotation, - TRUE, - yzPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorRotation, - SoRotation, - TRUE, - zxPlanarTranslatorSeparator, - "", - TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorDragger, - TPlanarDragger, - TRUE, - xyPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorDragger, - TPlanarDragger, - TRUE, - yzPlanarTranslatorSeparator, - "", - TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorDragger, - TPlanarDragger, - TRUE, - zxPlanarTranslatorSeparator, - "", - TRUE); - - // Rotator - - SO_KIT_ADD_CATALOG_ENTRY(xRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zRotatorSwitch, SoSwitch, TRUE, annotation, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xRotatorSeparator, SoSeparator, TRUE, xRotatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yRotatorSeparator, SoSeparator, TRUE, yRotatorSwitch, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zRotatorSeparator, SoSeparator, TRUE, zRotatorSwitch, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xRotatorColor, SoBaseColor, TRUE, xRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yRotatorColor, SoBaseColor, TRUE, yRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zRotatorColor, SoBaseColor, TRUE, zRotatorSeparator, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xRotatorRotation, SoRotation, TRUE, xRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yRotatorRotation, SoRotation, TRUE, yRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zRotatorRotation, SoRotation, TRUE, zRotatorSeparator, "", TRUE); - - SO_KIT_ADD_CATALOG_ENTRY(xRotatorDragger, RDragger, TRUE, xRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(yRotatorDragger, RDragger, TRUE, yRotatorSeparator, "", TRUE); - SO_KIT_ADD_CATALOG_ENTRY(zRotatorDragger, RDragger, TRUE, zRotatorSeparator, "", TRUE); - - // Other - SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0)); - SO_KIT_ADD_FIELD(translationIncrement, (1.0)); - SO_KIT_ADD_FIELD(translationIncrementCountX, (0)); - SO_KIT_ADD_FIELD(translationIncrementCountY, (0)); - SO_KIT_ADD_FIELD(translationIncrementCountZ, (0)); - - SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0)); - SO_KIT_ADD_FIELD(rotationIncrement, (std::numbers::pi / 8.0)); - SO_KIT_ADD_FIELD(rotationIncrementCountX, (0)); - SO_KIT_ADD_FIELD(rotationIncrementCountY, (0)); - SO_KIT_ADD_FIELD(rotationIncrementCountZ, (0)); - - SO_KIT_ADD_FIELD(draggerSize, (1.0)); - SO_KIT_ADD_FIELD(autoScaleResult, (1.0)); - - SO_KIT_ADD_FIELD(xAxisLabel, ("X")); - SO_KIT_ADD_FIELD(yAxisLabel, ("Y")); - SO_KIT_ADD_FIELD(zAxisLabel, ("Z")); - - SO_KIT_INIT_INSTANCE(); - - // Colors - setAxisColors(SbColor(1.0, 0, 0).getPackedValue(0.0f), - SbColor(0, 1.0, 0).getPackedValue(0.0f), - SbColor(0, 0, 1.0).getPackedValue(0.0f)); - - // Translator - TDragger* tDragger; - tDragger = SO_GET_ANY_PART(this, "xTranslatorDragger", TDragger); - tDragger->translationIncrement.connectFrom(&this->translationIncrement); - tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - tDragger->label.connectFrom(&xAxisLabel); - translationIncrementCountX.connectFrom(&tDragger->translationIncrementCount); - tDragger = SO_GET_ANY_PART(this, "yTranslatorDragger", TDragger); - tDragger->translationIncrement.connectFrom(&this->translationIncrement); - tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - tDragger->label.connectFrom(&yAxisLabel); - translationIncrementCountY.connectFrom(&tDragger->translationIncrementCount); - tDragger = SO_GET_ANY_PART(this, "zTranslatorDragger", TDragger); - tDragger->translationIncrement.connectFrom(&this->translationIncrement); - tDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - tDragger->label.connectFrom(&zAxisLabel); - translationIncrementCountZ.connectFrom(&tDragger->translationIncrementCount); - // Planar Translator - TPlanarDragger* tPlanarDragger; - tPlanarDragger = SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", TPlanarDragger); - tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); - tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - translationIncrementCountX.appendConnection(&tPlanarDragger->translationIncrementXCount); - translationIncrementCountY.appendConnection(&tPlanarDragger->translationIncrementYCount); - tPlanarDragger = SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", TPlanarDragger); - tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); - tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - translationIncrementCountZ.appendConnection(&tPlanarDragger->translationIncrementXCount); - translationIncrementCountY.appendConnection(&tPlanarDragger->translationIncrementYCount); - tPlanarDragger = SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", TPlanarDragger); - tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement); - tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult); - translationIncrementCountX.appendConnection(&tPlanarDragger->translationIncrementXCount); - translationIncrementCountZ.appendConnection(&tPlanarDragger->translationIncrementYCount); - // Rotator - RDragger* rDragger; - rDragger = SO_GET_ANY_PART(this, "xRotatorDragger", RDragger); - rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); - rotationIncrementCountX.connectFrom(&rDragger->rotationIncrementCount); - rDragger = SO_GET_ANY_PART(this, "yRotatorDragger", RDragger); - rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); - rotationIncrementCountY.connectFrom(&rDragger->rotationIncrementCount); - rDragger = SO_GET_ANY_PART(this, "zRotatorDragger", RDragger); - rDragger->rotationIncrement.connectFrom(&this->rotationIncrement); - rotationIncrementCountZ.connectFrom(&rDragger->rotationIncrementCount); - - // Switches - - // Translator - SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - // Planar Translator - sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - // Rotator - sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); - - // Rotations - - SoRotation* localRotation; - SbRotation tempRotation; - auto angle = static_cast(std::numbers::pi / 2.0); - // Translator - localRotation = SO_GET_ANY_PART(this, "xTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbVec3f(0.0, 0.0, -1.0), angle); - localRotation = SO_GET_ANY_PART(this, "yTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbRotation::identity()); - localRotation = SO_GET_ANY_PART(this, "zTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbVec3f(1.0, 0.0, 0.0), angle); - // Planar Translator - localRotation = SO_GET_ANY_PART(this, "xyPlanarTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbRotation::identity()); - localRotation = SO_GET_ANY_PART(this, "yzPlanarTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbVec3f(0.0, -1.0, 0.0), angle); - localRotation = SO_GET_ANY_PART(this, "zxPlanarTranslatorRotation", SoRotation); - localRotation->rotation.setValue(SbVec3f(1.0, 0.0, 0.0), angle); - // Rotator - localRotation = SO_GET_ANY_PART(this, "xRotatorRotation", SoRotation); - tempRotation = SbRotation(SbVec3f(1.0, 0.0, 0.0), angle); - tempRotation *= SbRotation(SbVec3f(0.0, 0.0, 1.0), angle); - localRotation->rotation.setValue(tempRotation); - localRotation = SO_GET_ANY_PART(this, "yRotatorRotation", SoRotation); - tempRotation = SbRotation(SbVec3f(0.0, -1.0, 0.0), angle); - tempRotation *= SbRotation(SbVec3f(0.0, 0.0, -1.0), angle); - localRotation->rotation.setValue(tempRotation); - localRotation = SO_GET_ANY_PART(this, "zRotatorRotation", SoRotation); - localRotation->rotation.setValue(SbRotation::identity()); - - // this is for non-autoscale mode. this will be disconnected for autoscale - // and won't be used. see setUpAutoScale. - auto scaleEngine = new SoComposeVec3f(); // uses coin ref scheme. - scaleEngine->x.connectFrom(&draggerSize); - scaleEngine->y.connectFrom(&draggerSize); - scaleEngine->z.connectFrom(&draggerSize); - SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); - localScaleNode->scaleFactor.connectFrom(&scaleEngine->vector); - autoScaleResult.connectFrom(&draggerSize); - - SoPickStyle* localPickStyle = SO_GET_ANY_PART(this, "pickStyle", SoPickStyle); - localPickStyle->style = SoPickStyle::SHAPE_ON_TOP; - - addValueChangedCallback(&SoFCCSysDragger::valueChangedCB); - - translationSensor.setFunction(&SoFCCSysDragger::translationSensorCB); - translationSensor.setData(this); - translationSensor.setPriority(0); - - rotationSensor.setFunction(&SoFCCSysDragger::rotationSensorCB); - rotationSensor.setData(this); - rotationSensor.setPriority(0); - - cameraSensor.setFunction(&SoFCCSysDragger::cameraCB); - cameraSensor.setData(this); - - idleSensor.setFunction(&SoFCCSysDragger::idleCB); - idleSensor.setData(this); - - this->addFinishCallback(&SoFCCSysDragger::finishDragCB, this); - - this->setUpConnections(TRUE, TRUE); -} - -SoFCCSysDragger::~SoFCCSysDragger() -{ - translationSensor.setData(nullptr); - translationSensor.detach(); - rotationSensor.setData(nullptr); - rotationSensor.detach(); - cameraSensor.setData(nullptr); - cameraSensor.detach(); - idleSensor.setData(nullptr); - idleSensor.unschedule(); - - removeValueChangedCallback(&SoFCCSysDragger::valueChangedCB); - removeFinishCallback(&SoFCCSysDragger::finishDragCB, this); -} - - -SbBool SoFCCSysDragger::setUpConnections(SbBool onoff, SbBool doitalways) -{ - if (!doitalways && (connectionsSetUp == onoff)) { - return onoff; - } - - TDragger* tDraggerX = SO_GET_ANY_PART(this, "xTranslatorDragger", TDragger); - TDragger* tDraggerY = SO_GET_ANY_PART(this, "yTranslatorDragger", TDragger); - TDragger* tDraggerZ = SO_GET_ANY_PART(this, "zTranslatorDragger", TDragger); - TPlanarDragger* tPlanarDraggerXZ = - SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", TPlanarDragger); - TPlanarDragger* tPlanarDraggerYZ = - SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", TPlanarDragger); - TPlanarDragger* tPlanarDraggerZX = - SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", TPlanarDragger); - RDragger* rDraggerX = SO_GET_ANY_PART(this, "xRotatorDragger", RDragger); - RDragger* rDraggerY = SO_GET_ANY_PART(this, "yRotatorDragger", RDragger); - RDragger* rDraggerZ = SO_GET_ANY_PART(this, "zRotatorDragger", RDragger); - - if (onoff) { - inherited::setUpConnections(onoff, doitalways); - - registerChildDragger(tDraggerX); - registerChildDragger(tDraggerY); - registerChildDragger(tDraggerZ); - registerChildDragger(tPlanarDraggerXZ); - registerChildDragger(tPlanarDraggerYZ); - registerChildDragger(tPlanarDraggerZX); - registerChildDragger(rDraggerX); - registerChildDragger(rDraggerY); - registerChildDragger(rDraggerZ); - - translationSensorCB(this, nullptr); - if (this->translationSensor.getAttachedField() != &this->translation) { - this->translationSensor.attach(&this->translation); - } - - rotationSensorCB(this, nullptr); - if (this->rotationSensor.getAttachedField() != &this->rotation) { - this->rotationSensor.attach(&this->rotation); - } - } - else { - unregisterChildDragger(tDraggerX); - unregisterChildDragger(tDraggerY); - unregisterChildDragger(tDraggerZ); - unregisterChildDragger(tPlanarDraggerXZ); - unregisterChildDragger(tPlanarDraggerYZ); - unregisterChildDragger(tPlanarDraggerZX); - unregisterChildDragger(rDraggerX); - unregisterChildDragger(rDraggerY); - unregisterChildDragger(rDraggerZ); - - inherited::setUpConnections(onoff, doitalways); - - if (this->translationSensor.getAttachedField()) { - this->translationSensor.detach(); - } - - if (this->rotationSensor.getAttachedField()) { - this->rotationSensor.detach(); - } - } - return !(this->connectionsSetUp = onoff); -} - -void SoFCCSysDragger::translationSensorCB(void* f, SoSensor*) -{ - auto sudoThis = static_cast(f); - if (!f) { - return; - } - - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - sudoThis->workFieldsIntoTransform(matrix); - sudoThis->setMotionMatrix(matrix); -} - -void SoFCCSysDragger::rotationSensorCB(void* f, SoSensor*) -{ - auto sudoThis = static_cast(f); - if (!f) { - return; - } - - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - sudoThis->workFieldsIntoTransform(matrix); - sudoThis->setMotionMatrix(matrix); -} - -void SoFCCSysDragger::valueChangedCB(void*, SoDragger* d) -{ - auto sudoThis = dynamic_cast(d); - assert(sudoThis); - SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft - - // all this just to get the translation? - SbVec3f localTranslation, scaleDummy; - SbRotation localRotation, scaleOrientationDummy; - matrix.getTransform(localTranslation, localRotation, scaleDummy, scaleOrientationDummy); - - sudoThis->translationSensor.detach(); - if (sudoThis->translation.getValue() != localTranslation) { - sudoThis->translation = localTranslation; - } - sudoThis->translationSensor.attach(&sudoThis->translation); - - sudoThis->rotationSensor.detach(); - if (sudoThis->rotation.getValue() != localRotation) { - sudoThis->rotation = localRotation; - } - sudoThis->rotationSensor.attach(&sudoThis->rotation); -} - -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. - if (cameraIn->getTypeId() == SoOrthographicCamera::getClassTypeId()) { - auto localCamera = dynamic_cast(cameraIn); - assert(localCamera); - cameraSensor.attach(&localCamera->height); - SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); - localScaleNode->scaleFactor.disconnect(); - autoScaleResult.disconnect(&draggerSize); - cameraCB(this, nullptr); - } - else if (cameraIn->getTypeId() == SoPerspectiveCamera::getClassTypeId()) { - auto localCamera = dynamic_cast(cameraIn); - assert(localCamera); - cameraSensor.attach(&localCamera->position); - SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale); - localScaleNode->scaleFactor.disconnect(); - autoScaleResult.disconnect(&draggerSize); - cameraCB(this, nullptr); - } -} - -void SoFCCSysDragger::cameraCB(void* data, SoSensor*) -{ - auto sudoThis = static_cast(data); - if (!sudoThis) { - return; - } - if (!sudoThis->idleSensor.isScheduled()) { - 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*) -{ - auto sudoThis = static_cast(data); - if (!data) { - return; - } - SoField* field = sudoThis->cameraSensor.getAttachedField(); - if (field) { - auto 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); - 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); - } -} - -void SoFCCSysDragger::finishDragCB(void* data, SoDragger*) -{ - auto sudoThis = static_cast(data); - assert(sudoThis); - - // 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) { - auto camera = static_cast(field->getContainer()); - if (camera->getTypeId() == SoPerspectiveCamera::getClassTypeId()) { - cameraCB(sudoThis, nullptr); - } - } -} - -void SoFCCSysDragger::clearIncrementCounts() -{ - translationIncrementCountX.setValue(0); - translationIncrementCountY.setValue(0); - translationIncrementCountZ.setValue(0); - rotationIncrementCountX.setValue(0); - rotationIncrementCountY.setValue(0); - rotationIncrementCountZ.setValue(0); -} - -void SoFCCSysDragger::setAxisColors(unsigned long x, unsigned long y, unsigned long z) -{ - SbColor colorX; - SbColor colorY; - SbColor colorZ; - - float t = 0.0f; - colorX.setPackedValue(x, t); - colorY.setPackedValue(y, t); - colorZ.setPackedValue(z, t); - - SoBaseColor* color; - - // Translator - color = SO_GET_ANY_PART(this, "xTranslatorColor", SoBaseColor); - color->rgb.setValue(colorX[0], colorX[1], colorX[2]); - color = SO_GET_ANY_PART(this, "yTranslatorColor", SoBaseColor); - color->rgb.setValue(colorY[0], colorY[1], colorY[2]); - color = SO_GET_ANY_PART(this, "zTranslatorColor", SoBaseColor); - color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); - // Planar Translator - color = SO_GET_ANY_PART(this, "xyPlanarTranslatorColor", SoBaseColor); - color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); - color = SO_GET_ANY_PART(this, "yzPlanarTranslatorColor", SoBaseColor); - color->rgb.setValue(colorX[0], colorX[1], colorX[2]); - color = SO_GET_ANY_PART(this, "zxPlanarTranslatorColor", SoBaseColor); - color->rgb.setValue(colorY[0], colorY[1], colorY[2]); - // Rotator - color = SO_GET_ANY_PART(this, "xRotatorColor", SoBaseColor); - color->rgb.setValue(colorX[0], colorX[1], colorX[2]); - color = SO_GET_ANY_PART(this, "yRotatorColor", SoBaseColor); - color->rgb.setValue(colorY[0], colorY[1], colorY[2]); - color = SO_GET_ANY_PART(this, "zRotatorColor", SoBaseColor); - color->rgb.setValue(colorZ[0], colorZ[1], colorZ[2]); -} - -// Visibility API Functions - -// Translator -void SoFCCSysDragger::showTranslationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showTranslationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showTranslationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} - -void SoFCCSysDragger::hideTranslationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hideTranslationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hideTranslationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} - -bool SoFCCSysDragger::isShownTranslationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownTranslationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownTranslationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} - -bool SoFCCSysDragger::isHiddenTranslationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenTranslationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenTranslationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} - -// Planar Translator -void SoFCCSysDragger::showPlanarTranslationXY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showPlanarTranslationYZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showPlanarTranslationZX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} - -void SoFCCSysDragger::hidePlanarTranslationXY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hidePlanarTranslationYZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hidePlanarTranslationZX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} - -bool SoFCCSysDragger::isShownPlanarTranslationXY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownPlanarTranslationYZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownPlanarTranslationZX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} - -bool SoFCCSysDragger::isHiddenPlanarTranslationXY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenPlanarTranslationYZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenPlanarTranslationZX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} - -// Rotator -void SoFCCSysDragger::showRotationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showRotationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} -void SoFCCSysDragger::showRotationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL); -} - -void SoFCCSysDragger::hideRotationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hideRotationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} -void SoFCCSysDragger::hideRotationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); - SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE); -} - -bool SoFCCSysDragger::isShownRotationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownRotationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} -bool SoFCCSysDragger::isShownRotationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_ALL); -} - -bool SoFCCSysDragger::isHiddenRotationX() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenRotationY() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} -bool SoFCCSysDragger::isHiddenRotationZ() -{ - SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch); - return (sw->whichChild.getValue() == SO_SWITCH_NONE); -} diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 54041e8a84..29e80fbe31 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -50,6 +50,7 @@ #include "SoFCDB.h" #include "Camera.h" #include "Flag.h" +#include "Inventor/Draggers/SoTransformDragger.h" #include "Navigation/GestureNavigationStyle.h" #include "Navigation/NavigationStyle.h" #include "SelectionObject.h" @@ -57,7 +58,6 @@ #include "SoFCColorBar.h" #include "SoFCColorGradient.h" #include "SoFCColorLegend.h" -#include "SoFCCSysDragger.h" #include "SoFCInteractiveElement.h" #include "SoFCSelection.h" #include "SoFCSelectionAction.h" @@ -142,7 +142,7 @@ void Gui::SoFCDB::init() SoFCTransform ::initClass(); SoAutoZoomTranslation ::initClass(); MarkerBitmaps ::initClass(); - SoFCCSysDragger ::initClass(); + SoTransformDragger ::initClass(); SmSwitchboard ::initClass(); SoFCSeparator ::initClass(); SoFCSelectionRoot ::initClass(); diff --git a/src/Gui/SoFCDB.h b/src/Gui/SoFCDB.h index d9ecb349eb..8306474e68 100644 --- a/src/Gui/SoFCDB.h +++ b/src/Gui/SoFCDB.h @@ -54,7 +54,7 @@ public: static bool writeToX3DOM(SoNode* node, std::string& buffer); // Write to Inventor, VRML, X3D or XHTML (based on X3DOM) file static bool writeToFile(SoNode* node, const char* filename, bool binary); - /*! container for app lifetime storage. See SoFCCSysDragger for details + /*! container for app lifetime storage. See SoTransformDragger for details * on why this is needed. */ static SoGroup* getStorage(); diff --git a/src/Gui/TaskCSysDragger.cpp b/src/Gui/TaskCSysDragger.cpp index 77c74be9f0..4bfc6f542a 100644 --- a/src/Gui/TaskCSysDragger.cpp +++ b/src/Gui/TaskCSysDragger.cpp @@ -41,8 +41,8 @@ #include "Application.h" #include "BitmapFactory.h" #include "Command.h" +#include "Inventor/Draggers/SoTransformDragger.h" #include "QuantitySpinBox.h" -#include "SoFCCSysDragger.h" #include "ViewProviderDragger.h" #include "TaskView/TaskView.h" @@ -81,7 +81,7 @@ void alignGridLayoutColumns(const std::list& layouts, unsigned col } // namespace TaskTransform::TaskTransform(Gui::ViewProviderDragger* vp, - Gui::SoFCCSysDragger* dragger, + Gui::SoTransformDragger* dragger, QWidget* parent, App::SubObjectPlacementProvider* subObjectPlacemenProvider, App::CenterOfMassProvider* centerOfMassProvider) @@ -708,7 +708,7 @@ void TaskTransform::onRotationChange(QuantitySpinBox* changed) resetReferencePlacement(); } -TaskCSysDragger::TaskCSysDragger(ViewProviderDragger* vp, SoFCCSysDragger* dragger) +TaskCSysDragger::TaskCSysDragger(ViewProviderDragger* vp, SoTransformDragger* dragger) : vp(vp) { transform = new TaskTransform(vp, dragger); diff --git a/src/Gui/TaskCSysDragger.h b/src/Gui/TaskCSysDragger.h index 0f7fed2cca..a2d0fbdd25 100644 --- a/src/Gui/TaskCSysDragger.h +++ b/src/Gui/TaskCSysDragger.h @@ -41,7 +41,7 @@ namespace Attacher namespace Gui { class QuantitySpinBox; -class SoFCCSysDragger; +class SoTransformDragger; class ViewProviderDragger; class Ui_TaskCSysDragger; @@ -67,7 +67,7 @@ public: Q_ENUM(PositionMode) TaskTransform(Gui::ViewProviderDragger* vp, - Gui::SoFCCSysDragger* dragger, + Gui::SoTransformDragger* dragger, QWidget* parent = nullptr, App::SubObjectPlacementProvider* subObjectPlacementProvider = Base::provideService(), @@ -134,7 +134,7 @@ private: const App::SubObjectPlacementProvider* subObjectPlacementProvider; const App::CenterOfMassProvider *centerOfMassProvider; - CoinPtr dragger; + CoinPtr dragger; Ui_TaskCSysDragger *ui; @@ -155,7 +155,7 @@ class TaskCSysDragger: public Gui::TaskView::TaskDialog Q_OBJECT public: - TaskCSysDragger(ViewProviderDragger* vp, SoFCCSysDragger* dragger); + TaskCSysDragger(ViewProviderDragger* vp, SoTransformDragger* dragger); ~TaskCSysDragger() override = default; QDialogButtonBox::StandardButtons getStandardButtons() const override diff --git a/src/Gui/ViewProviderDragger.cpp b/src/Gui/ViewProviderDragger.cpp index 1b001ec006..9c7756558f 100644 --- a/src/Gui/ViewProviderDragger.cpp +++ b/src/Gui/ViewProviderDragger.cpp @@ -42,7 +42,7 @@ #include "BitmapFactory.h" #include "Control.h" #include "Document.h" -#include "SoFCCSysDragger.h" +#include "Inventor/Draggers/SoTransformDragger.h" #include "Inventor/SoFCPlacementIndicatorKit.h" #include "SoFCUnifiedSelection.h" #include "TaskCSysDragger.h" @@ -109,7 +109,7 @@ void ViewProviderDragger::onChanged(const App::Property* property) TaskView::TaskDialog* ViewProviderDragger::getTransformDialog() { - return new TaskCSysDragger(this, csysDragger); + return new TaskCSysDragger(this, transformDragger); } bool ViewProviderDragger::doubleClicked() @@ -179,17 +179,17 @@ bool ViewProviderDragger::setEdit(int ModNum) return true; } - assert(!csysDragger); + assert(!transformDragger); - csysDragger = new SoFCCSysDragger(); - csysDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(), + transformDragger = new SoTransformDragger(); + transformDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(), Gui::ViewParams::instance()->getAxisYColor(), Gui::ViewParams::instance()->getAxisZColor()); - csysDragger->draggerSize.setValue(ViewParams::instance()->getDraggerScale()); + transformDragger->draggerSize.setValue(ViewParams::instance()->getDraggerScale()); - csysDragger->addStartCallback(dragStartCallback, this); - csysDragger->addFinishCallback(dragFinishCallback, this); - csysDragger->addMotionCallback(dragMotionCallback, this); + transformDragger->addStartCallback(dragStartCallback, this); + transformDragger->addFinishCallback(dragFinishCallback, this); + transformDragger->addMotionCallback(dragMotionCallback, this); Gui::Control().showDialog(getTransformDialog()); @@ -202,7 +202,7 @@ void ViewProviderDragger::unsetEdit(int ModNum) { Q_UNUSED(ModNum); - csysDragger.reset(); + transformDragger.reset(); Gui::Control().closeDialog(); } @@ -211,14 +211,14 @@ void ViewProviderDragger::setEditViewer(Gui::View3DInventorViewer* viewer, int M { Q_UNUSED(ModNum); - if (csysDragger && viewer) { - csysDragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); + if (transformDragger && viewer) { + transformDragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); auto originPlacement = App::GeoFeature::getGlobalPlacement(getObject()) * getObjectPlacement().inverse(); auto mat = originPlacement.toMatrix(); viewer->getDocument()->setEditingTransform(mat); - viewer->setupEditingRoot(csysDragger, &mat); + viewer->setupEditingRoot(transformDragger, &mat); } } @@ -231,7 +231,7 @@ void ViewProviderDragger::dragStartCallback(void* data, [[maybe_unused]] SoDragg auto vp = static_cast(data); vp->draggerPlacement = vp->getDraggerPlacement(); - vp->csysDragger->clearIncrementCounts(); + vp->transformDragger->clearIncrementCounts(); } void ViewProviderDragger::dragFinishCallback(void* data, [[maybe_unused]] SoDragger* d) @@ -240,7 +240,7 @@ void ViewProviderDragger::dragFinishCallback(void* data, [[maybe_unused]] SoDrag auto vp = static_cast(data); vp->draggerPlacement = vp->getDraggerPlacement(); - vp->csysDragger->clearIncrementCounts(); + vp->transformDragger->clearIncrementCounts(); vp->updatePlacementFromDragger(); } @@ -282,10 +282,10 @@ Base::Placement ViewProviderDragger::getObjectPlacement() const Base::Placement ViewProviderDragger::getDraggerPlacement() const { - const double translationStep = csysDragger->translationIncrement.getValue(); - const int xSteps = csysDragger->translationIncrementCountX.getValue(); - const int ySteps = csysDragger->translationIncrementCountY.getValue(); - const int zSteps = csysDragger->translationIncrementCountZ.getValue(); + const double translationStep = transformDragger->translationIncrement.getValue(); + const int xSteps = transformDragger->translationIncrementCountX.getValue(); + const int ySteps = transformDragger->translationIncrementCountY.getValue(); + const int zSteps = transformDragger->translationIncrementCountZ.getValue(); const auto rotation = draggerPlacement.getRotation(); const auto xBase = rotation.multVec(Base::Vector3d(1, 0, 0)); @@ -297,10 +297,10 @@ Base::Placement ViewProviderDragger::getDraggerPlacement() const yBase * (translationStep * ySteps) + zBase * (translationStep * zSteps); - const double rotationStep = csysDragger->rotationIncrement.getValue(); - const int xRotationSteps = csysDragger->rotationIncrementCountX.getValue(); - const int yRotationSteps = csysDragger->rotationIncrementCountY.getValue(); - const int zRotationSteps = csysDragger->rotationIncrementCountZ.getValue(); + const double rotationStep = transformDragger->rotationIncrement.getValue(); + const int xRotationSteps = transformDragger->rotationIncrementCountX.getValue(); + const int yRotationSteps = transformDragger->rotationIncrementCountY.getValue(); + const int zRotationSteps = transformDragger->rotationIncrementCountZ.getValue(); auto newRotation = rotation; newRotation = newRotation * Base::Rotation(Base::Vector3d(1, 0, 0), xRotationSteps * rotationStep); @@ -320,11 +320,11 @@ Base::Placement ViewProviderDragger::getOriginalDraggerPlacement() const void ViewProviderDragger::setDraggerPlacement(const Base::Placement& placement) { - csysDragger->translation.setValue(Base::convertTo(placement.getPosition())); - csysDragger->rotation.setValue(Base::convertTo(placement.getRotation())); + transformDragger->translation.setValue(Base::convertTo(placement.getPosition())); + transformDragger->rotation.setValue(Base::convertTo(placement.getRotation())); draggerPlacement = placement; - csysDragger->clearIncrementCounts(); + transformDragger->clearIncrementCounts(); } void ViewProviderDragger::attach(App::DocumentObject* pcObject) @@ -343,7 +343,7 @@ void ViewProviderDragger::attach(App::DocumentObject* pcObject) void ViewProviderDragger::updateDraggerPosition() { - if (!csysDragger) { + if (!transformDragger) { return; } diff --git a/src/Gui/ViewProviderDragger.h b/src/Gui/ViewProviderDragger.h index ad1b18d1f7..7641e08dfd 100644 --- a/src/Gui/ViewProviderDragger.h +++ b/src/Gui/ViewProviderDragger.h @@ -25,7 +25,7 @@ #define GUI_VIEWPROVIDER_DRAGGER_H #include "ViewProviderDocumentObject.h" -#include "SoFCCSysDragger.h" +#include "Inventor/Draggers/SoTransformDragger.h" #include #include @@ -113,7 +113,7 @@ protected: */ virtual TaskView::TaskDialog* getTransformDialog(); - CoinPtr csysDragger = nullptr; + CoinPtr transformDragger = nullptr; ViewProvider *forwardedViewProvider = nullptr; CoinPtr pcPlacement; diff --git a/src/Gui/ViewProviderLink.cpp b/src/Gui/ViewProviderLink.cpp index 8a4cb8a5ee..3744c75654 100644 --- a/src/Gui/ViewProviderLink.cpp +++ b/src/Gui/ViewProviderLink.cpp @@ -71,9 +71,9 @@ #include "Application.h" #include "BitmapFactory.h" #include "Control.h" +#include "Inventor/Draggers/SoTransformDragger.h" #include "LinkViewPy.h" #include "Selection.h" -#include "SoFCCSysDragger.h" #include "SoFCUnifiedSelection.h" #include "TaskCSysDragger.h" #include "TaskElementColors.h" @@ -2793,9 +2793,9 @@ ViewProvider *ViewProviderLink::startEditing(int mode) { } if (auto result = inherited::startEditing(mode)) { - csysDragger->addStartCallback(dragStartCallback, this); - csysDragger->addFinishCallback(dragFinishCallback, this); - csysDragger->addMotionCallback(dragMotionCallback, this); + transformDragger->addStartCallback(dragStartCallback, this); + transformDragger->addFinishCallback(dragFinishCallback, this); + transformDragger->addMotionCallback(dragMotionCallback, this); setDraggerPlacement(dragCtx->initialPlacement); @@ -2879,7 +2879,7 @@ void ViewProviderLink::unsetEditViewer(Gui::View3DInventorViewer* viewer) } bool ViewProviderLink::callDraggerProxy(const char* fname) { - if (!csysDragger) { + if (!transformDragger) { return false; } diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp index 5927cefb49..9b6b1c2ecd 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp @@ -54,9 +54,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -267,7 +267,7 @@ void ViewProviderAssembly::setDragger() { // Create the dragger coin object assert(!asmDragger); - asmDragger = new Gui::SoFCCSysDragger(); + asmDragger = new Gui::SoTransformDragger(); asmDragger->setAxisColors(Gui::ViewParams::instance()->getAxisXColor(), Gui::ViewParams::instance()->getAxisYColor(), Gui::ViewParams::instance()->getAxisZColor()); @@ -1144,7 +1144,7 @@ Base::Placement ViewProviderAssembly::getDraggerPlacement() Base::convertTo(asmDragger->rotation.getValue())}; } -Gui::SoFCCSysDragger* ViewProviderAssembly::getDragger() +Gui::SoTransformDragger* ViewProviderAssembly::getDragger() { return asmDragger; } diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.h b/src/Mod/Assembly/Gui/ViewProviderAssembly.h index fc7defe8e2..3f99972dc4 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.h +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.h @@ -38,7 +38,7 @@ class SoFieldSensor; namespace Gui { -class SoFCCSysDragger; +class SoTransformDragger; class View3DInventorViewer; } // namespace Gui @@ -194,7 +194,7 @@ public: bool getDraggerVisibility(); void setDraggerPlacement(Base::Placement plc); Base::Placement getDraggerPlacement(); - Gui::SoFCCSysDragger* getDragger(); + Gui::SoTransformDragger* getDragger(); static Base::Vector3d getCenterOfBoundingBox(const std::vector& movingObjs); @@ -222,7 +222,7 @@ public: std::vector> objectMasses; std::vector docsToMove; - Gui::SoFCCSysDragger* asmDragger = nullptr; + Gui::SoTransformDragger* asmDragger = nullptr; SoSwitch* asmDraggerSwitch = nullptr; SoFieldSensor* translationSensor = nullptr; SoFieldSensor* rotationSensor = nullptr; diff --git a/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml b/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml index 9ede675da9..34db07a03d 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml +++ b/src/Mod/Assembly/Gui/ViewProviderAssemblyPy.xml @@ -28,7 +28,7 @@ Return the assembly dragger coin object. - getDragger() -> SoFCCSysDragger + getDragger() -> SoTransformDragger Returns: dragger coin object of the assembly diff --git a/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp b/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp index 47551d257a..463be2e9ea 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssemblyPyImp.cpp @@ -97,7 +97,7 @@ PyObject* ViewProviderAssemblyPy::getDragger(PyObject* args) if (!PyArg_ParseTuple(args, "")) { return nullptr; } - Gui::SoFCCSysDragger* asmDragger = getViewProviderAssemblyPtr()->getDragger(); + Gui::SoTransformDragger* asmDragger = getViewProviderAssemblyPtr()->getDragger(); return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDragger *", asmDragger, 0); }