Gui: moved dragger classes to separate folder and files

* renamed SoFCCSysDragger to SoTransformDragger
* moved TDragger, RDragger and TPlanarDragger to separate files and also renamed them to be more descriptive
This commit is contained in:
captain0xff
2025-04-11 19:05:06 +05:30
committed by Kacper Donat
parent 3fa260f869
commit d2ff41dbd7
21 changed files with 2361 additions and 2050 deletions

View File

@@ -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})

View File

@@ -0,0 +1,393 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <cassert>
#include <numbers>
#include <Inventor/SbRotation.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/engines/SoComposeVec3f.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoFontStyle.h>
#endif
#include <Base/Quantity.h>
#include "SoLinearDragger.h"
#include "MainWindow.h"
#include "SoFCDB.h"
#include <SoTextLabel.h>
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<SoLinearDragger*>(d);
assert(sudoThis);
sudoThis->dragStart();
}
void SoLinearDragger::motionCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoLinearDragger*>(d);
assert(sudoThis);
sudoThis->drag();
}
void SoLinearDragger::finishCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoLinearDragger*>(d);
assert(sudoThis);
sudoThis->dragFinish();
}
void SoLinearDragger::fieldSensorCB(void* f, SoSensor*)
{
auto sudoThis = static_cast<SoLinearDragger*>(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<SoLinearDragger*>(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<float>(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<double>(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<int>(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<float>(yCount) * incrementIn;
out[2] = 0.0;
return out;
}

View File

@@ -0,0 +1,104 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <Inventor/draggers/SoDragger.h>
#include <Inventor/fields/SoSFColor.h>
#include <Inventor/fields/SoSFDouble.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/fields/SoSFInt32.h>
#include <Inventor/fields/SoSFRotation.h>
#include <Inventor/fields/SoSFString.h>
#include <Inventor/projectors/SbLineProjector.h>
#include <Inventor/projectors/SbPlaneProjector.h>
#include <Inventor/nodes/SoBaseColor.h>
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 */

View File

@@ -0,0 +1,359 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <cassert>
#include <numbers>
#include <Inventor/SbRotation.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/engines/SoComposeVec3f.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoFontStyle.h>
#endif
#include <Base/Quantity.h>
#include "SoPlanarDragger.h"
#include "MainWindow.h"
#include "SoFCDB.h"
#include <SoTextLabel.h>
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<SoPlanarDragger*>(d);
assert(sudoThis);
sudoThis->dragStart();
}
void SoPlanarDragger::motionCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoPlanarDragger*>(d);
assert(sudoThis);
sudoThis->drag();
}
void SoPlanarDragger::finishCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoPlanarDragger*>(d);
assert(sudoThis);
sudoThis->dragFinish();
}
void SoPlanarDragger::fieldSensorCB(void* f, SoSensor*)
{
auto sudoThis = static_cast<SoPlanarDragger*>(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<SoPlanarDragger*>(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<float>(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<double>(translationIncrementXCount.getValue())
* translationIncrement.getValue(),
Base::Unit::Length);
Base::Quantity quantityY(static_cast<double>(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<int>(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<int>(yValue / incrementIn);
float remainder = fmod(yValue, incrementIn);
if (remainder >= (incrementIn / 2.0)) {
yCount++;
}
}
translationIncrementYCount.setValue(yCount);
SbVec3f out;
out[0] = static_cast<float>(xCount) * incrementIn;
out[1] = static_cast<float>(yCount) * incrementIn;
out[2] = 0.0;
return out;
}

View File

@@ -0,0 +1,91 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <Inventor/draggers/SoDragger.h>
#include <Inventor/fields/SoSFColor.h>
#include <Inventor/fields/SoSFDouble.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/fields/SoSFInt32.h>
#include <Inventor/fields/SoSFRotation.h>
#include <Inventor/fields/SoSFString.h>
#include <Inventor/projectors/SbLineProjector.h>
#include <Inventor/projectors/SbPlaneProjector.h>
#include <Inventor/nodes/SoBaseColor.h>
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 */

View File

@@ -0,0 +1,367 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <cassert>
#include <numbers>
#include <Inventor/SbRotation.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/engines/SoComposeVec3f.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoFontStyle.h>
#endif
#include <Base/Quantity.h>
#include "SoRotationDragger.h"
#include "MainWindow.h"
#include "SoFCDB.h"
#include <SoTextLabel.h>
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<float> / 2.f) / static_cast<float>(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<SoRotationDragger*>(d);
assert(sudoThis);
sudoThis->dragStart();
}
void SoRotationDragger::motionCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoRotationDragger*>(d);
assert(sudoThis);
sudoThis->drag();
}
void SoRotationDragger::finishCB(void*, SoDragger* d)
{
auto sudoThis = static_cast<SoRotationDragger*>(d);
assert(sudoThis);
sudoThis->dragFinish();
}
void SoRotationDragger::fieldSensorCB(void* f, SoSensor*)
{
auto sudoThis = static_cast<SoRotationDragger*>(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<SoRotationDragger*>(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<float>(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<double>(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<float>(rotationIncrement.getValue());
if (fabs(radiansIn) > (increment / 2.0)) {
rCount = static_cast<int>(radiansIn / increment);
float remainder = fmod(radiansIn, increment);
if (remainder >= (increment / 2.0)) {
rCount++;
}
}
return rCount;
}

View File

@@ -0,0 +1,87 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <Inventor/draggers/SoDragger.h>
#include <Inventor/fields/SoSFColor.h>
#include <Inventor/fields/SoSFDouble.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/fields/SoSFInt32.h>
#include <Inventor/fields/SoSFRotation.h>
#include <Inventor/fields/SoSFString.h>
#include <Inventor/projectors/SbLineProjector.h>
#include <Inventor/projectors/SbPlaneProjector.h>
#include <Inventor/nodes/SoBaseColor.h>
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 */

View File

@@ -0,0 +1,889 @@
/***************************************************************************
* Copyright (c) 2015 Thomas Anderson <blobfish[at]gmx.com> *
* *
* 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 <cassert>
#include <numbers>
#include <Inventor/SbRotation.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/engines/SoComposeVec3f.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoFontStyle.h>
#endif
#include <Base/Quantity.h>
#include "SoTransformDragger.h"
#include "SoLinearDragger.h"
#include "SoPlanarDragger.h"
#include "SoRotationDragger.h"
#include <SoTextLabel.h>
/*
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 <SoNode*> * 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<float>(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<SoTransformDragger*>(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<SoTransformDragger*>(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<SoTransformDragger*>(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<SoOrthographicCamera*>(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<SoPerspectiveCamera*>(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<SoTransformDragger*>(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<SoTransformDragger*>(data);
if (!data) {
return;
}
SoField* field = sudoThis->cameraSensor.getAttachedField();
if (field) {
auto camera = static_cast<SoCamera*>(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<SoTransformDragger*>(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<SoCamera*>(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);
}

View File

@@ -20,8 +20,8 @@
* *
***************************************************************************/
#ifndef CSYSDRAGGER_H
#define CSYSDRAGGER_H
#ifndef GUI_TRANSFORM_DRAGGER_H
#define GUI_TRANSFORM_DRAGGER_H
#include <Inventor/draggers/SoDragger.h>
#include <Inventor/fields/SoSFColor.h>
@@ -30,9 +30,6 @@
#include <Inventor/fields/SoSFInt32.h>
#include <Inventor/fields/SoSFRotation.h>
#include <Inventor/fields/SoSFString.h>
#include <Inventor/projectors/SbLineProjector.h>
#include <Inventor/projectors/SbPlaneProjector.h>
#include <Inventor/sensors/SoFieldSensor.h>
#include <Inventor/sensors/SoIdleSensor.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <FCGlobal.h>
@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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();

View File

@@ -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();

View File

@@ -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<QGridLayout*>& 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);

View File

@@ -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<App::SubObjectPlacementProvider>(),
@@ -134,7 +134,7 @@ private:
const App::SubObjectPlacementProvider* subObjectPlacementProvider;
const App::CenterOfMassProvider *centerOfMassProvider;
CoinPtr<SoFCCSysDragger> dragger;
CoinPtr<SoTransformDragger> 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

View File

@@ -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<ViewProviderDragger*>(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<ViewProviderDragger*>(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<SbVec3f>(placement.getPosition()));
csysDragger->rotation.setValue(Base::convertTo<SbRotation>(placement.getRotation()));
transformDragger->translation.setValue(Base::convertTo<SbVec3f>(placement.getPosition()));
transformDragger->rotation.setValue(Base::convertTo<SbRotation>(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;
}

View File

@@ -25,7 +25,7 @@
#define GUI_VIEWPROVIDER_DRAGGER_H
#include "ViewProviderDocumentObject.h"
#include "SoFCCSysDragger.h"
#include "Inventor/Draggers/SoTransformDragger.h"
#include <Base/Placement.h>
#include <App/PropertyGeo.h>
@@ -113,7 +113,7 @@ protected:
*/
virtual TaskView::TaskDialog* getTransformDialog();
CoinPtr<SoFCCSysDragger> csysDragger = nullptr;
CoinPtr<SoTransformDragger> transformDragger = nullptr;
ViewProvider *forwardedViewProvider = nullptr;
CoinPtr<SoSwitch> pcPlacement;

View File

@@ -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;
}

View File

@@ -54,9 +54,9 @@
#include <Gui/BitmapFactory.h>
#include <Gui/CommandT.h>
#include <Gui/Control.h>
#include <Gui/Inventor/Draggers/SoTransformDragger.h>
#include <Gui/MDIView.h>
#include <Gui/MainWindow.h>
#include <Gui/SoFCCSysDragger.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/ViewParams.h>
@@ -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<Base::Rotation>(asmDragger->rotation.getValue())};
}
Gui::SoFCCSysDragger* ViewProviderAssembly::getDragger()
Gui::SoTransformDragger* ViewProviderAssembly::getDragger()
{
return asmDragger;
}

View File

@@ -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<MovingObject>& movingObjs);
@@ -222,7 +222,7 @@ public:
std::vector<std::pair<App::DocumentObject*, double>> objectMasses;
std::vector<MovingObject> docsToMove;
Gui::SoFCCSysDragger* asmDragger = nullptr;
Gui::SoTransformDragger* asmDragger = nullptr;
SoSwitch* asmDraggerSwitch = nullptr;
SoFieldSensor* translationSensor = nullptr;
SoFieldSensor* rotationSensor = nullptr;

View File

@@ -28,7 +28,7 @@
<UserDocu>
Return the assembly dragger coin object.
getDragger() -> SoFCCSysDragger
getDragger() -> SoTransformDragger
Returns: dragger coin object of the assembly
</UserDocu>

View File

@@ -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);
}