diff --git a/src/Gui/InventorAll.h b/src/Gui/InventorAll.h index abfafa0450..c3d00ac0ff 100644 --- a/src/Gui/InventorAll.h +++ b/src/Gui/InventorAll.h @@ -132,6 +132,7 @@ #include #include #include +#include #include #include diff --git a/src/Mod/Measure/App/MeasureDistance.cpp b/src/Mod/Measure/App/MeasureDistance.cpp index 59bbdc15ae..da1effe52c 100644 --- a/src/Mod/Measure/App/MeasureDistance.cpp +++ b/src/Mod/Measure/App/MeasureDistance.cpp @@ -51,6 +51,16 @@ MeasureDistance::MeasureDistance() "Distance between the two elements"); Distance.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceX,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in X direction"); + DistanceX.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceY,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in Y direction"); + DistanceY.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceZ,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in Z direction"); + DistanceZ.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(Position1,(Base::Vector3d(0.0,0.0,0.0)),"Measurement", App::Prop_Hidden, "Position1"); ADD_PROPERTY_TYPE(Position2,(Base::Vector3d(0.0,1.0,0.0)),"Measurement", App::Prop_Hidden, "Position2"); @@ -196,7 +206,11 @@ App::DocumentObjectExecReturn *MeasureDistance::execute() return new App::DocumentObjectExecReturn("Could not get extrema"); } + gp_Pnt delta = measure.PointOnShape2(1).XYZ() - measure.PointOnShape1(1).XYZ(); Distance.setValue(measure.Value()); + DistanceX.setValue(fabs(delta.X())); + DistanceY.setValue(fabs(delta.Y())); + DistanceZ.setValue(fabs(delta.Z())); gp_Pnt p1 = measure.PointOnShape1(1); Position1.setValue(p1.X(), p1.Y(), p1.Z()); @@ -238,6 +252,16 @@ MeasureDistanceDetached::MeasureDistanceDetached() "Distance between the two elements"); Distance.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceX,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in X direction"); + DistanceX.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceY,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in Y direction"); + DistanceY.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(DistanceZ,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Distance in Z direction"); + DistanceZ.setUnit(Base::Unit::Length); + ADD_PROPERTY_TYPE(Position1,(Base::Vector3d(0.0,0.0,0.0)),"Measurement", App::Prop_None, "Position1"); ADD_PROPERTY_TYPE(Position2,(Base::Vector3d(0.0,1.0,0.0)),"Measurement", App::Prop_None, "Position2"); } @@ -268,6 +292,9 @@ void MeasureDistanceDetached::recalculateDistance() { auto delta = Position1.getValue() - Position2.getValue(); Distance.setValue(delta.Length()); + DistanceX.setValue(fabs(delta.x)); + DistanceY.setValue(fabs(delta.y)); + DistanceZ.setValue(fabs(delta.z)); } void MeasureDistanceDetached::onChanged(const App::Property* prop) diff --git a/src/Mod/Measure/App/MeasureDistance.h b/src/Mod/Measure/App/MeasureDistance.h index b05a642336..d36332e616 100644 --- a/src/Mod/Measure/App/MeasureDistance.h +++ b/src/Mod/Measure/App/MeasureDistance.h @@ -63,6 +63,9 @@ public: App::PropertyLinkSub Element1; App::PropertyLinkSub Element2; App::PropertyDistance Distance; + App::PropertyDistance DistanceX; + App::PropertyDistance DistanceY; + App::PropertyDistance DistanceZ; // Position properties for the viewprovider App::PropertyVector Position1; @@ -106,6 +109,9 @@ public: ~MeasureDistanceDetached() override; App::PropertyDistance Distance; + App::PropertyDistance DistanceX; + App::PropertyDistance DistanceY; + App::PropertyDistance DistanceZ; App::PropertyVector Position1; App::PropertyVector Position2; diff --git a/src/Mod/Measure/Gui/AppMeasureGui.cpp b/src/Mod/Measure/Gui/AppMeasureGui.cpp index 5ca94d8627..3bc562ba74 100644 --- a/src/Mod/Measure/Gui/AppMeasureGui.cpp +++ b/src/Mod/Measure/Gui/AppMeasureGui.cpp @@ -93,6 +93,8 @@ PyMOD_INIT_FUNC(MeasureGui) // instantiating the commands CreateMeasureCommands(); + MeasureGui::DimensionLinear::initClass(); + MeasureGui::ViewProviderMeasureGroup ::init(); MeasureGui::ViewProviderMeasureBase ::init(); MeasureGui::ViewProviderMeasure ::init(); diff --git a/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp b/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp index ce7697bdc9..fcbf87944b 100644 --- a/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp +++ b/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp @@ -84,6 +84,10 @@ ViewProviderMeasureBase::ViewProviderMeasureBase() ADD_PROPERTY_TYPE(FontSize, (Preferences::defaultFontSize()), agroup, App::Prop_None, "Size of measurement text"); //NOLINTEND + pGlobalSeparator = new SoSeparator(); + pGlobalSeparator->ref(); + getRoot()->insertChild(pGlobalSeparator, 0); + // setupAnnoSceneGraph() - sets up the annotation scene graph pLabel = new Gui::SoFrameLabel(); pLabel->ref(); @@ -175,6 +179,7 @@ ViewProviderMeasureBase::ViewProviderMeasureBase() ViewProviderMeasureBase::~ViewProviderMeasureBase() { _mVisibilityChangedConnection.disconnect(); + pGlobalSeparator->unref(); pLabel->unref(); pColor->unref(); pDragger->unref(); diff --git a/src/Mod/Measure/Gui/ViewProviderMeasureBase.h b/src/Mod/Measure/Gui/ViewProviderMeasureBase.h index 979e06eacb..3a1d69f48f 100644 --- a/src/Mod/Measure/Gui/ViewProviderMeasureBase.h +++ b/src/Mod/Measure/Gui/ViewProviderMeasureBase.h @@ -135,6 +135,7 @@ protected: // TODO: getters & setters and move variables to private? bool _mShowTree = true; + SoSeparator* pGlobalSeparator; // Separator in the global coordinate space Gui::SoFrameLabel * pLabel; SoTranslate2Dragger* pDragger; SoTransform* pDraggerOrientation; diff --git a/src/Mod/Measure/Gui/ViewProviderMeasureDistance.cpp b/src/Mod/Measure/Gui/ViewProviderMeasureDistance.cpp index bf2e8edc4f..5940f61492 100644 --- a/src/Mod/Measure/Gui/ViewProviderMeasureDistance.cpp +++ b/src/Mod/Measure/Gui/ViewProviderMeasureDistance.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) 2023 David Friedli * + * Copyright (c) 2013 Thomas Anderson * * Copyright (c) 2008 Werner Mayer * * * * This file is part of FreeCAD. * @@ -23,20 +24,29 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif #include @@ -60,6 +70,166 @@ using namespace Measure; PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureDistance, MeasureGui::ViewProviderMeasureBase) +SO_KIT_SOURCE(MeasureGui::DimensionLinear) + +void MeasureGui::DimensionLinear::initClass() +{ + SO_KIT_INIT_CLASS(DimensionLinear, SoSeparatorKit, "SeparatorKit"); +} + +MeasureGui::DimensionLinear::DimensionLinear() +{ + SO_KIT_CONSTRUCTOR(MeasureGui::DimensionLinear); + + SO_KIT_ADD_CATALOG_ENTRY(transformation, SoTransform, true, topSeparator, "", true); + SO_KIT_ADD_CATALOG_ENTRY(annotate, SoAnnotation, true, topSeparator, "", true); + SO_KIT_ADD_CATALOG_ENTRY(leftArrow, SoShapeKit, true, topSeparator, "", true); + SO_KIT_ADD_CATALOG_ENTRY(rightArrow, SoShapeKit, true, topSeparator, "", true); + SO_KIT_ADD_CATALOG_ENTRY(line, SoShapeKit, true, annotate, "", true); + SO_KIT_ADD_CATALOG_ENTRY(textSep, SoSeparator, true, annotate, "", true); + + SO_KIT_INIT_INSTANCE(); + + SO_NODE_ADD_FIELD(rotate, (1.0, 0.0, 0.0, 0.0)); // position orientation of the dimension. + SO_NODE_ADD_FIELD(length, (1.0)); // turns into dimension length + SO_NODE_ADD_FIELD(origin, (0.0, 0.0, 0.0)); // static + SO_NODE_ADD_FIELD(text, ("test")); // dimension text + SO_NODE_ADD_FIELD(dColor, (1.0, 0.0, 0.0)); // dimension color. + SO_NODE_ADD_FIELD(backgroundColor, (1.0, 1.0, 1.0)); + SO_NODE_ADD_FIELD(showArrows, (false)); // display dimension arrows + SO_NODE_ADD_FIELD(fontSize, (12.0)); // size of the dimension font +} + +MeasureGui::DimensionLinear::~DimensionLinear() +{} + +SbBool MeasureGui::DimensionLinear::affectsState() const +{ + return false; +} + +void MeasureGui::DimensionLinear::setupDimension() +{ + // make unpickable + SoPickStyle* ps = static_cast(getPart("pickStyle", true)); + if (ps) { + ps->style = SoPickStyle::UNPICKABLE; + } + + // transformation + SoTransform* trans = static_cast(getPart("transformation", true)); + trans->translation.connectFrom(&point1); + // build engine for vector subtraction and length. + SoCalculator* hyp = new SoCalculator(); + hyp->A.connectFrom(&point1); + hyp->B.connectFrom(&point2); + hyp->expression.set1Value(0, "oA = B-A"); + hyp->expression.set1Value(1, "oB = normalize(oA)"); + hyp->expression.set1Value(2, "oa = length(oA)"); + length.connectFrom(&hyp->oa); + + // build engine for rotation. + SoComposeRotationFromTo* rotationEngine = new SoComposeRotationFromTo(); + rotationEngine->from.setValue(SbVec3f(1.0, 0.0, 0.0)); + rotationEngine->to.connectFrom(&hyp->oB); + trans->rotation.connectFrom(&rotationEngine->rotation); + + // color + SoMaterial* material = new SoMaterial; + material->diffuseColor.connectFrom(&dColor); + + // dimension arrows + float dimLength = (point2.getValue() - point1.getValue()).length(); + float coneHeight = dimLength * 0.06; + float coneRadius = coneHeight * 0.5; + + SoComposeVec3f* vec = new SoComposeVec3f; + vec->x.connectFrom(&length); + vec->y.setValue(0.0); + vec->z.setValue(0.0); + + // NOTE: showArrows is only respected at setup stage and cannot be changed later + if (showArrows.getValue()) { + SoCone* cone = new SoCone(); + cone->bottomRadius.setValue(coneRadius); + cone->height.setValue(coneHeight); + + char lStr[100]; + char rStr[100]; + snprintf(lStr, sizeof(lStr), "translation %.6f 0.0 0.0", coneHeight * 0.5); + snprintf(rStr, sizeof(rStr), "translation 0.0 -%.6f 0.0", coneHeight * 0.5); + + setPart("leftArrow.shape", cone); + set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963"); + set("leftArrow.transform", lStr); + setPart("rightArrow.shape", cone); + set("rightArrow.transform", "rotation 0.0 0.0 -1.0 1.5707963"); // no constant for PI. + // have use local here to do the offset because the main is wired up to length of dimension. + set("rightArrow.localTransform", rStr); + + SoTransform* transform = static_cast(getPart("rightArrow.transform", false)); + if (!transform) { + return; // what to do here? + } + transform->translation.connectFrom(&vec->vector); + + setPart("leftArrow.material", material); + setPart("rightArrow.material", material); + } + + // line + SoConcatenate* catEngine = new SoConcatenate(SoMFVec3f::getClassTypeId()); + // don't know how to get around having this dummy origin. cat engine wants to connectfrom? + catEngine->input[0]->connectFrom(&origin); + catEngine->input[1]->connectFrom(&vec->vector); + + SoVertexProperty* lineVerts = new SoVertexProperty; + lineVerts->vertex.connectFrom(catEngine->output); + + int lineVertexMap[] = {0, 1}; + int lineVertexMapSize(sizeof(lineVertexMap) / sizeof(int)); + SoIndexedLineSet* line = new SoIndexedLineSet; + line->vertexProperty = lineVerts; + line->coordIndex.setValues(0, lineVertexMapSize, lineVertexMap); + + setPart("line.shape", line); + setPart("line.material", material); + + // text + SoSeparator* textSep = static_cast(getPart("textSep", true)); + if (!textSep) { + return; + } + + textSep->addChild(material); + + SoCalculator* textVecCalc = new SoCalculator(); + textVecCalc->A.connectFrom(&vec->vector); + textVecCalc->B.set1Value(0, 0.0, 0.250, 0.0); + textVecCalc->expression.set1Value(0, "oA = (A / 2) + B"); + + SoTransform* textTransform = new SoTransform(); + textTransform->translation.connectFrom(&textVecCalc->oA); + textSep->addChild(textTransform); + + SoFont* fontNode = new SoFont(); + fontNode->name.setValue("Helvetica : Bold"); + fontNode->size.connectFrom(&fontSize); + textSep->addChild(fontNode); + + auto textNode = new SoFrameLabel(); + textNode->justification = SoText2::CENTER; + textNode->string.connectFrom(&text); + textNode->textColor.connectFrom(&dColor); + textNode->backgroundColor.connectFrom(&backgroundColor); + textSep->addChild(textNode); + + // this prevents the 2d text from screwing up the bounding box for a viewall + SoResetTransform* rTrans = new SoResetTransform; + rTrans->whatToReset = SoResetTransform::BBOX; + textSep->addChild(rTrans); +} + SbMatrix ViewProviderMeasureDistance::getMatrix() { if (!pcObject) { @@ -127,6 +297,8 @@ ViewProviderMeasureDistance::ViewProviderMeasureDistance() { sPixmap = "Measurement-Distance"; + ADD_PROPERTY_TYPE(ShowDelta, (false), "Appearance", App::Prop_None, "Display the X, Y and Z components of the distance"); + // vert indexes used to create the annotation lines const size_t lineCount(3); static const int32_t lines[lineCount] = @@ -161,10 +333,10 @@ ViewProviderMeasureDistance::ViewProviderMeasureDistance() engineCat->input[3]->connectFrom(&engineCoords->oD); engineCat->input[4]->connectFrom(&pLabelTranslation->translation); - pCoords->point.connectFrom(engineCat->output); + pCoords->point.connectFrom(engineCat->output); pCoords->point.setNum(engineCat->output->getNumConnections()); - pLines = new SoIndexedLineSet(); + pLines = new SoIndexedLineSet(); pLines->ref(); pLines->coordIndex.setNum(lineCount); pLines->coordIndex.setValues(0, lineCount, lines); @@ -186,12 +358,70 @@ ViewProviderMeasureDistance::ViewProviderMeasureDistance() ViewParams::instance()->getMarkerSize()); points->numPoints=2; pLineSeparator->addChild(points); + + + // Delta Dimensions + auto decomposedPosition1 = new SoDecomposeVec3f(); + decomposedPosition1->vector.connectFrom(&fieldPosition1); + auto decomposedPosition2 = new SoDecomposeVec3f(); + decomposedPosition2->vector.connectFrom(&fieldPosition2); + + // Create intermediate points + auto composeVecDelta1 = new SoComposeVec3f(); + composeVecDelta1->x.connectFrom(&decomposedPosition2->x); + composeVecDelta1->y.connectFrom(&decomposedPosition1->y); + composeVecDelta1->z.connectFrom(&decomposedPosition1->z); + + auto composeVecDelta2 = new SoComposeVec3f(); + composeVecDelta2->x.connectFrom(&decomposedPosition2->x); + composeVecDelta2->y.connectFrom(&decomposedPosition2->y); + composeVecDelta2->z.connectFrom(&decomposedPosition1->z); + + // Set axis colors + SbColor colorX; + SbColor colorY; + SbColor colorZ; + + float t = 0.0f; + colorX.setPackedValue(ViewParams::instance()->getAxisXColor(), t); + colorY.setPackedValue(ViewParams::instance()->getAxisYColor(), t); + colorZ.setPackedValue(ViewParams::instance()->getAxisZColor(), t); + + auto dimDeltaX = new MeasureGui::DimensionLinear(); + dimDeltaX->point1.connectFrom(&fieldPosition1); + dimDeltaX->point2.connectFrom(&composeVecDelta1->vector); + dimDeltaX->setupDimension(); + dimDeltaX->dColor.setValue(colorX); + + auto dimDeltaY = new MeasureGui::DimensionLinear(); + dimDeltaY->point1.connectFrom(&composeVecDelta1->vector); + dimDeltaY->point2.connectFrom(&composeVecDelta2->vector); + dimDeltaY->setupDimension(); + dimDeltaY->dColor.setValue(colorY); + + auto dimDeltaZ = new MeasureGui::DimensionLinear(); + dimDeltaZ->point2.connectFrom(&composeVecDelta2->vector); + dimDeltaZ->point1.connectFrom(&fieldPosition2); + dimDeltaZ->setupDimension(); + dimDeltaZ->dColor.setValue(colorZ); + + pDeltaDimensionSwitch = new SoSwitch(); + pDeltaDimensionSwitch->ref(); + pGlobalSeparator->addChild(pDeltaDimensionSwitch); + + pDeltaDimensionSwitch->addChild(dimDeltaX); + pDeltaDimensionSwitch->addChild(dimDeltaY); + pDeltaDimensionSwitch->addChild(dimDeltaZ); + + // This should already be touched in ViewProviderMeasureBase + FontSize.touch(); } ViewProviderMeasureDistance::~ViewProviderMeasureDistance() { pCoords->unref(); pLines->unref(); + pDeltaDimensionSwitch->unref(); } @@ -212,12 +442,28 @@ void ViewProviderMeasureDistance::redrawAnnotation() auto vec1 = prop1->getValue(); auto vec2 = prop2->getValue(); + fieldPosition1.setValue(SbVec3f(vec1.x, vec1.y, vec1.z)); + fieldPosition2.setValue(SbVec3f(vec2.x, vec2.y, vec2.z)); + // Set the distance fieldDistance = (vec2 - vec1).Length(); auto propDistance = dynamic_cast(pcObject->getPropertyByName("Distance")); setLabelValue(propDistance->getQuantityValue().getUserString()); + // Set delta distance + auto propDistanceX = static_cast(getMeasureObject()->getPropertyByName("DistanceX")); + static_cast(pDeltaDimensionSwitch->getChild(0)) + ->text.setValue("Δx: " + propDistanceX->getQuantityValue().getUserString().toUtf8()); + + auto propDistanceY = static_cast(getMeasureObject()->getPropertyByName("DistanceY")); + static_cast(pDeltaDimensionSwitch->getChild(1)) + ->text.setValue("Δy: " + propDistanceY->getQuantityValue().getUserString().toUtf8()); + + auto propDistanceZ = static_cast(getMeasureObject()->getPropertyByName("DistanceZ")); + static_cast(pDeltaDimensionSwitch->getChild(2)) + ->text.setValue("Δz: " + propDistanceZ->getQuantityValue().getUserString().toUtf8()); + // Set matrix SbMatrix matrix = getMatrix(); pcTransform->setMatrix(matrix); @@ -226,6 +472,25 @@ void ViewProviderMeasureDistance::redrawAnnotation() updateView(); } +void ViewProviderMeasureDistance::onChanged(const App::Property* prop) { + + if (prop == &ShowDelta) { + pDeltaDimensionSwitch->whichChild.setValue(ShowDelta.getValue() ? SO_SWITCH_ALL : SO_SWITCH_NONE); + } else if (prop == &FontSize) { + static_cast(pDeltaDimensionSwitch->getChild(0))->fontSize.setValue(FontSize.getValue()); + static_cast(pDeltaDimensionSwitch->getChild(1))->fontSize.setValue(FontSize.getValue()); + static_cast(pDeltaDimensionSwitch->getChild(2))->fontSize.setValue(FontSize.getValue()); + } else if (prop == &TextBackgroundColor) { + auto bColor = TextBackgroundColor.getValue(); + static_cast(pDeltaDimensionSwitch->getChild(0))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g); + static_cast(pDeltaDimensionSwitch->getChild(1))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g); + static_cast(pDeltaDimensionSwitch->getChild(2))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g); + } + + + ViewProviderMeasureBase::onChanged(prop); +} + void ViewProviderMeasureDistance::positionAnno(const Measure::MeasureBase* measureObject) { (void)measureObject; diff --git a/src/Mod/Measure/Gui/ViewProviderMeasureDistance.h b/src/Mod/Measure/Gui/ViewProviderMeasureDistance.h index 945f6c7f78..cd46aa1679 100644 --- a/src/Mod/Measure/Gui/ViewProviderMeasureDistance.h +++ b/src/Mod/Measure/Gui/ViewProviderMeasureDistance.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) 2023 David Friedli * + * Copyright (c) 2013 Thomas Anderson * * * * This file is part of FreeCAD. * * * @@ -28,6 +29,17 @@ #include #include "ViewProviderMeasureBase.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + class SoCoordinate3; class SoIndexedLineSet; @@ -35,6 +47,41 @@ class SoIndexedLineSet; namespace MeasureGui { +class DimensionLinear: public SoSeparatorKit +{ + SO_KIT_HEADER(DimensionLinear); + + SO_KIT_CATALOG_ENTRY_HEADER(transformation); + SO_KIT_CATALOG_ENTRY_HEADER(annotate); + SO_KIT_CATALOG_ENTRY_HEADER(leftArrow); + SO_KIT_CATALOG_ENTRY_HEADER(rightArrow); + SO_KIT_CATALOG_ENTRY_HEADER(line); + SO_KIT_CATALOG_ENTRY_HEADER(textSep); + +public: + DimensionLinear(); + static void initClass(); + SbBool affectsState() const override; + void setupDimension(); + + SoSFVec3f point1; + SoSFVec3f point2; + SoSFString text; + SoSFColor dColor; + SoSFColor backgroundColor; + SoSFBool showArrows; + SoSFFloat fontSize; + +protected: + SoSFRotation rotate; + SoSFFloat length; + SoSFVec3f origin; + +private: + ~DimensionLinear() override; +}; + + class MeasureGuiExport ViewProviderMeasureDistance : public MeasureGui::ViewProviderMeasureBase { @@ -45,17 +92,25 @@ public: ViewProviderMeasureDistance(); ~ViewProviderMeasureDistance() override; + App::PropertyBool ShowDelta; + void redrawAnnotation() override; void positionAnno(const Measure::MeasureBase* measureObject) override; protected: Base::Vector3d getTextDirection(Base::Vector3d elementDirection, double tolerance = defaultTolerance) override; + void onChanged(const App::Property* prop) override; private: - SoCoordinate3 * pCoords; - SoIndexedLineSet * pLines; + SoCoordinate3* pCoords; + SoIndexedLineSet* pLines; + SoSwitch* pDeltaDimensionSwitch; + + SoSFVec3f fieldPosition1; + SoSFVec3f fieldPosition2; + + SoSFFloat fieldDistance; - SoSFFloat fieldDistance; SbMatrix getMatrix(); };