From 7d4d5eddf5cca698a78c8774fecfa5c826c422d7 Mon Sep 17 00:00:00 2001 From: marioalexis84 <53127171+marioalexis84@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:49:13 -0300 Subject: [PATCH] Fem: Constraint symbol scaling (#13274) * Fem: Constraint symbols rescaling * Fem: Add constraint symbol .iv files * Fem: Fix contact constraint symbol rescaling * Fem: Fix displacement constraint symbol rescaling * Fem: Fix fixed constraint symbol rescaling * Fem: Fix force constraint symbol rescaling * Fem: Fix heat flux constraint symbol rescaling * Fem: Fix plane rotation constraint symbol rescaling * Fem: Fix pressure constraint symbol rescaling * Fem: Fix spring constraint symbol rescaling * Fem: Fix temperature constraint symbol rescaling * Fem: Add tie constraint symbol --- src/Mod/Fem/App/FemConstraint.cpp | 62 +++-- src/Mod/Fem/App/FemConstraint.h | 21 +- src/Mod/Fem/App/FemConstraintPressure.cpp | 9 - src/Mod/Fem/App/FemConstraintPressure.h | 1 - src/Mod/Fem/Gui/CMakeLists.txt | 17 +- .../Resources/symbols/ConstraintContact.iv | 19 ++ .../symbols/ConstraintDisplacement.iv | 93 +++++++ .../Gui/Resources/symbols/ConstraintFixed.iv | 32 +++ .../Gui/Resources/symbols/ConstraintForce.iv | 26 ++ .../Resources/symbols/ConstraintHeatFlux.iv | 48 ++++ .../symbols/ConstraintPlaneRotation.iv | 18 ++ .../Resources/symbols/ConstraintPressure.iv | 30 +++ .../Gui/Resources/symbols/ConstraintSpring.iv | 28 +++ .../symbols/ConstraintTemperature.iv | 39 +++ .../Gui/Resources/symbols/ConstraintTie.iv | 18 ++ src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp | 104 +++++++- src/Mod/Fem/Gui/ViewProviderFemConstraint.h | 58 ++++- .../Gui/ViewProviderFemConstraintContact.cpp | 74 +----- .../ViewProviderFemConstraintDisplacement.cpp | 233 +++--------------- .../Gui/ViewProviderFemConstraintFixed.cpp | 63 +---- .../Gui/ViewProviderFemConstraintForce.cpp | 145 +++-------- .../Fem/Gui/ViewProviderFemConstraintForce.h | 3 + .../Gui/ViewProviderFemConstraintHeatflux.cpp | 106 +------- ...ViewProviderFemConstraintPlaneRotation.cpp | 98 +------- .../Gui/ViewProviderFemConstraintPressure.cpp | 102 +++----- .../Gui/ViewProviderFemConstraintPressure.h | 3 + .../Fem/Gui/ViewProviderFemConstraintPy.xml | 26 ++ .../Gui/ViewProviderFemConstraintPyImp.cpp | 55 ++++- .../Gui/ViewProviderFemConstraintSpring.cpp | 67 +---- .../ViewProviderFemConstraintTemperature.cpp | 95 +------ .../view_base_femconstraint.py | 20 +- .../femviewprovider/view_constraint_tie.py | 7 + 32 files changed, 768 insertions(+), 952 deletions(-) create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index 6034569f68..d42b342f20 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -74,9 +74,12 @@ using Adaptor3d_HSurface = Adaptor3d_Surface; using BRepAdaptor_HSurface = BRepAdaptor_Surface; #endif +static const App::PropertyFloatConstraint::Constraints scaleConstraint = {0.0, DBL_MAX, 0.1}; + PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject) Constraint::Constraint() + : sizeFactor {1} { ADD_PROPERTY_TYPE(References, (nullptr, nullptr), @@ -90,10 +93,9 @@ Constraint::Constraint() "Normal direction pointing outside of solid"); ADD_PROPERTY_TYPE(Scale, (1), - "Base", - App::PropertyType(App::Prop_Output), - "Scale used for drawing constraints"); // OvG: Add scale parameter inherited - // by all derived constraints + "Constraint", + App::PropertyType(App::Prop_None), + "Scale used for drawing constraints"); ADD_PROPERTY_TYPE(Points, (Base::Vector3d()), "Constraint", @@ -105,6 +107,8 @@ Constraint::Constraint() App::PropertyType(App::Prop_ReadOnly | App::Prop_Output | App::Prop_Hidden), "Normals where symbols are drawn"); + Scale.setConstraints(&scaleConstraint); + Points.setValues(std::vector()); Normals.setValues(std::vector()); @@ -128,23 +132,28 @@ App::DocumentObjectExecReturn* Constraint::execute() } // OvG: Provide the ability to determine how big to draw constraint arrows etc. -int Constraint::calcDrawScaleFactor(double lparam) const +unsigned int Constraint::calcSizeFactor(double lparam) const { return (static_cast(round(log(lparam) * log(lparam) * log(lparam) / 10)) > 1) ? (static_cast(round(log(lparam) * log(lparam) * log(lparam) / 10))) : 1; } -int Constraint::calcDrawScaleFactor(double lvparam, double luparam) const +unsigned int Constraint::calcSizeFactor(double lvparam, double luparam) const { - return calcDrawScaleFactor((lvparam + luparam) / 2.0); + return calcSizeFactor((lvparam + luparam) / 2.0); } -int Constraint::calcDrawScaleFactor() const +unsigned int Constraint::calcSizeFactor() const { return 1; } +float Constraint::getScaleFactor() const +{ + return Scale.getValue() * sizeFactor; +} + void setSubShapeLocation(const Part::Feature* feat, TopoDS_Shape& sh) { // subshape placement is not necessarily the same as the @@ -200,11 +209,9 @@ void Constraint::onChanged(const App::Property* prop) std::vector points; std::vector normals; - int scale = 1; - if (getPoints(points, normals, &scale)) { + if (getPoints(points, normals, &sizeFactor)) { Points.setValues(points); Normals.setValues(normals); - Scale.setValue(scale); Points.touch(); } } @@ -250,6 +257,19 @@ void Constraint::onDocumentRestored() App::DocumentObject::onDocumentRestored(); } +void Constraint::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) +{ + // Old integer Scale is equal to sizeFactor, now Scale*sizeFactor is used to scale the symbol + if (prop == &Scale && strcmp(TypeName, "App::PropertyInteger") == 0) { + Scale.setValue(1.0f); + } + else { + App::DocumentObject::handleChangedPropertyType(reader, TypeName, prop); + } +} + bool Constraint::getPoints(std::vector& points, std::vector& normals, int* scale) const @@ -285,7 +305,7 @@ bool Constraint::getPoints(std::vector& points, BRepGProp::VolumeProperties(toposhape.getShape(), props); double lx = props.Mass(); // OvG: setup draw scale for constraint - *scale = this->calcDrawScaleFactor(sqrt(lx) * 0.5); + *scale = this->calcSizeFactor(sqrt(lx) * 0.5); } else if (sh.ShapeType() == TopAbs_EDGE) { BRepAdaptor_Curve curve(TopoDS::Edge(sh)); @@ -299,17 +319,17 @@ bool Constraint::getPoints(std::vector& points, int steps; // OvG: Increase 10 units distance proportionately to l for larger objects. if (l >= 30) { - *scale = this->calcDrawScaleFactor(l); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(l); // OvG: setup draw scale for constraint steps = static_cast(round(l / (10 * (*scale)))); steps = steps < 3 ? 3 : steps; } else if (l >= 20) { steps = static_cast(round(l / 10)); - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { steps = 1; - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps @@ -387,19 +407,19 @@ bool Constraint::getPoints(std::vector& points, // OvG: Increase 10 units distance proportionately to lv for larger objects. int stepsv; if (lv >= 30) { - *scale = this->calcDrawScaleFactor(lv, lu); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint stepsv = static_cast(round(lv / (10 * (*scale)))); stepsv = stepsv < 3 ? 3 : stepsv; } else if (lv >= 20.0) { stepsv = static_cast(round(lv / 10)); - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { // Minimum of three arrows to ensure (as much as possible) that at // least one is displayed stepsv = 2; - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps @@ -407,17 +427,17 @@ bool Constraint::getPoints(std::vector& points, int stepsu; // OvG: Increase 10 units distance proportionately to lu for larger objects. if (lu >= 30) { - *scale = this->calcDrawScaleFactor(lv, lu); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint stepsu = static_cast(round(lu / (10 * (*scale)))); stepsu = stepsu < 3 ? 3 : stepsu; } else if (lu >= 20.0) { stepsu = static_cast(round(lu / 10)); - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { stepsu = 2; - *scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint + *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index 6ebc3ff374..f56cb34bbb 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -101,7 +101,7 @@ public: * View Provider but it's always 1. It isn't updated when @ref References * changes. */ - App::PropertyInteger Scale; + App::PropertyFloatConstraint Scale; // Read-only (calculated values). These trigger changes in the ViewProvider App::PropertyVectorList Points; @@ -133,7 +133,7 @@ public: * This method does a really crazy calculation that I didn't dare to try * to understand. */ - int calcDrawScaleFactor(double lparam) const; + unsigned int calcSizeFactor(double lparam) const; /** * @brief Calculates scale factor based on size of face. @@ -146,7 +146,7 @@ public: * This method does a really crazy calculation that I didn't dare to try * to understand. */ - int calcDrawScaleFactor(double lvparam, double luparam) const; + unsigned int calcSizeFactor(double lvparam, double luparam) const; /** * @brief Returns default scale factor of 1. @@ -159,13 +159,18 @@ public: * * @return always the integer 1 */ - int calcDrawScaleFactor() const; + unsigned int calcSizeFactor() const; const char* getViewProviderName() const override { return "FemGui::ViewProviderFemConstraint"; } + /** + * @brief Returns Scale * sizeFactor. + */ + float getScaleFactor() const; + protected: /** * @brief Updates NormalDirection if References change. @@ -182,6 +187,9 @@ protected: void onDocumentRestored() override; void onSettingDocument() override; void unsetupObject() override; + void handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) override; /** * @brief Returns data based on References relevant for rendering widgets. @@ -252,6 +260,11 @@ protected: const Base::Vector3d getDirection(const App::PropertyLinkSub& direction); private: + /** + * @brief Symbol size factor determined from the size of the shape. + */ + int sizeFactor; + void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop); boost::signals2::connection connDocChangedObject; }; diff --git a/src/Mod/Fem/App/FemConstraintPressure.cpp b/src/Mod/Fem/App/FemConstraintPressure.cpp index 427617139b..78b0f6c2f4 100644 --- a/src/Mod/Fem/App/FemConstraintPressure.cpp +++ b/src/Mod/Fem/App/FemConstraintPressure.cpp @@ -63,12 +63,3 @@ void ConstraintPressure::handleChangedPropertyType(Base::XMLReader& reader, Constraint::handleChangedPropertyType(reader, TypeName, prop); } } - -void ConstraintPressure::onChanged(const App::Property* prop) -{ - Constraint::onChanged(prop); - - if (prop == &Reversed) { - Points.touch(); - } -} diff --git a/src/Mod/Fem/App/FemConstraintPressure.h b/src/Mod/Fem/App/FemConstraintPressure.h index 5568bcdc3f..c2389de792 100644 --- a/src/Mod/Fem/App/FemConstraintPressure.h +++ b/src/Mod/Fem/App/FemConstraintPressure.h @@ -50,7 +50,6 @@ protected: void handleChangedPropertyType(Base::XMLReader& reader, const char* TypeName, App::Property* prop) override; - void onChanged(const App::Property* prop) override; }; } // namespace Fem diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index 2334876e01..1d07f4e4f3 100755 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -346,12 +346,27 @@ SET(FemGuiIcon_SVG Resources/icons/FemWorkbench.svg ) -add_library(FemGui SHARED ${FemGui_SRCS} ${FemGuiIcon_SVG}) +SET(FemGuiSymbol_IV + Resources/symbols/ConstraintContact.iv + Resources/symbols/ConstraintDisplacement.iv + Resources/symbols/ConstraintFixed.iv + Resources/symbols/ConstraintForce.iv + Resources/symbols/ConstraintHeatFlux.iv + Resources/symbols/ConstraintPlaneRotation.iv + Resources/symbols/ConstraintPressure.iv + Resources/symbols/ConstraintSpring.iv + Resources/symbols/ConstraintTemperature.iv + Resources/symbols/ConstraintTie.iv +) + +add_library(FemGui SHARED ${FemGui_SRCS} ${FemGuiIcon_SVG} ${FemGuiSymbol_IV}) target_link_libraries(FemGui ${FemGui_LIBS} ${VTK_LIBRARIES}) fc_copy_sources(FemGui "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Fem" ${FemGuiIcon_SVG}) +fc_copy_sources(FemGui "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Fem" ${FemGuiSymbol_IV}) INSTALL(FILES ${FemGuiIcon_SVG} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Fem/Resources/icons") +INSTALL(FILES ${FemGuiSymbol_IV} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Fem/Resources/symbols") # Python modules ui files, they are copied as they are, thus the need not to be added to Fem.qrc # see https://forum.freecad.org/viewtopic.php?f=10&t=25833 diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv new file mode 100644 index 0000000000..2a6455cdd6 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv @@ -0,0 +1,19 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.0625 0 + + } + Cube { + width 0.375 + height 0.125 + depth 0.75 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv new file mode 100644 index 0000000000..8c94b9a89b --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv @@ -0,0 +1,93 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + DEF X_DISPLACEMENT Switch { + + Separator { + + Rotation { + rotation 0 0 1 1.5707964 + + } + DEF DISPLACEMENT Separator { + + Translation { + translation 0 -2 0 + + } + Cone { + bottomRadius 0.3 + height 4 + + } + } + } + } + DEF Y_DISPLACEMENT Switch { + + Separator { + + Rotation { + rotation 0 0 1 3.1415927 + + } + USE DISPLACEMENT + } + } + DEF Z_DISPLACEMENT Switch { + + Separator { + + Rotation { + rotation -1 0 0 1.5707964 + + } + USE DISPLACEMENT + } + } + DEF X_ROTATION Switch { + + Separator { + + Rotation { + rotation 0 0 1 1.5707964 + + } + DEF ROTATION Separator { + + Cylinder { + radius 2 + height 0.15 + + } + } + } + } + DEF Y_ROTATION Switch { + + Separator { + + Rotation { + rotation 0 0 1 0 + + } + USE ROTATION + } + } + DEF Z_ROTATION Switch { + + Separator { + + Rotation { + rotation 1 0 0 1.5707964 + + } + USE ROTATION + } + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv new file mode 100644 index 0000000000..a0494da316 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv @@ -0,0 +1,32 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Rotation { + rotation 1 0 0 3.1415927 + + } + Translation { + translation 0 -0.25 0 + + } + Cone { + bottomRadius 0.5 + height 0.5 + + } + Translation { + translation 0 -0.525 0 + + } + Cube { + width 2 + height 0.5 + depth 2 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv new file mode 100644 index 0000000000..5ac7254065 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv @@ -0,0 +1,26 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 3.3333334 0 + } + Cone { + bottomRadius 0.66666669 + height 1.3333334 + + } + Translation { + translation 0 -2 0 + + } + Cylinder { + radius 0.26666668 + height 2.6666667 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv new file mode 100644 index 0000000000..5c91f02dd6 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv @@ -0,0 +1,48 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.225 0 + + } + Sphere { + radius 0.225 + + } + Translation { + translation 0 0.5625 0 + + } + Cylinder { + radius 0.1125 + height 0.75 + + } + Translation { + translation 0 0.5625 0 + + } + Material { + diffuseColor 1 1 1 + + } + Cylinder { + radius 0.1125 + height 0.375 + + } + Translation { + translation 0 -0.5625 0 + + } + Cylinder { + radius 0.3 + height 0.075 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv new file mode 100644 index 0000000000..d5ec896cd3 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv @@ -0,0 +1,18 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.125 0 + + } + Cylinder { + radius 1.25 + height 0.25 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv new file mode 100644 index 0000000000..137c2325e6 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv @@ -0,0 +1,30 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Rotation { + rotation 1 0 0 3.1415927 + + } + Translation { + translation 0 -0.66666669 0 + } + Cone { + bottomRadius 0.66666669 + height 1.3333334 + + } + Translation { + translation 0 -2 0 + + } + Cylinder { + radius 0.26666668 + height 2.6666667 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv new file mode 100644 index 0000000000..943232eca9 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv @@ -0,0 +1,28 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.5 0 + + } + Cube { + width 1 + height 1 + depth 1 + + } + Translation { + translation 0 1 0 + + } + Cylinder { + radius 0.25 + height 1 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv new file mode 100644 index 0000000000..e821eacdae --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv @@ -0,0 +1,39 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.225 0 + + } + Sphere { + radius 0.225 + + } + Translation { + translation 0 0.5625 0 + + } + Cylinder { + radius 0.1125 + height 0.75 + + } + Translation { + translation 0 0.5625 0 + + } + Material { + diffuseColor 1 1 1 + + } + Cylinder { + radius 0.1125 + height 0.375 + + } + } +} diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv new file mode 100644 index 0000000000..62d491599b --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv @@ -0,0 +1,18 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + + Translation { + translation 0 0.0625 0 + + } + Cylinder { + radius 0.375 + height 0.125 + + } + } +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp index 8000d55004..a1a5dae78f 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -40,10 +41,12 @@ #include #endif +#include "App/Application.h" #include "Gui/Command.h" #include "Gui/Control.h" #include "Gui/Document.h" #include "Gui/MainWindow.h" +#include "Mod/Fem/App/FemConstraint.h" #include "TaskFemConstraint.h" #include "ViewProviderFemConstraint.h" @@ -56,6 +59,13 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraint, Gui::ViewProviderGeometryObje ViewProviderFemConstraint::ViewProviderFemConstraint() + : rotateSymbol(true) + , pSymbol(nullptr) + , pExtraSymbol(nullptr) + , ivFile(nullptr) + , wizardWidget(nullptr) + , wizardSubLayout(nullptr) + , constraintDialog(nullptr) { ADD_PROPERTY(TextColor, (0.0f, 0.0f, 0.0f)); ADD_PROPERTY(FaceColor, (1.0f, 0.0f, 0.2f)); @@ -69,22 +79,19 @@ ViewProviderFemConstraint::ViewProviderFemConstraint() pLabel->ref(); pTextColor = new SoBaseColor(); pTextColor->ref(); + pShapeSep = new SoSeparator(); + pShapeSep->ref(); + pMultCopy = new SoMultipleCopy(); + pMultCopy->ref(); pMaterials = new SoBaseColor(); pMaterials->ref(); pMaterials->rgb.setValue(1.0f, 0.0f, 0.2f); - pShapeSep = new SoSeparator(); - pShapeSep->ref(); - TextColor.touch(); FontSize.touch(); FaceColor.touch(); - wizardWidget = nullptr; - wizardSubLayout = nullptr; - constraintDialog = nullptr; - Gui::ViewProviderSuppressibleExtension::initExtension(this); } @@ -94,6 +101,7 @@ ViewProviderFemConstraint::~ViewProviderFemConstraint() pLabel->unref(); pTextColor->unref(); pMaterials->unref(); + pMultCopy->unref(); pShapeSep->unref(); } @@ -115,6 +123,41 @@ void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) addDisplayMaskMode(sep, "Base"); } +std::string ViewProviderFemConstraint::resourceSymbolDir = + App::Application::getResourceDir() + "Mod/Fem/Resources/symbols/"; + +void ViewProviderFemConstraint::loadSymbol(const char* fileName) +{ + ivFile = fileName; + SoInput in; + if (!in.openFile(ivFile)) { + std::stringstream str; + str << "Error opening symbol file " << fileName; + throw Base::ImportError(str.str()); + } + SoSeparator* nodes = SoDB::readAll(&in); + if (!nodes) { + std::stringstream str; + str << "Error reading symbol file " << fileName; + throw Base::ImportError(str.str()); + } + + nodes->ref(); + pSymbol = dynamic_cast(nodes->getChild(0)); + pShapeSep->addChild(pMultCopy); + if (pSymbol) { + pMultCopy->addChild(pSymbol); + } + if (nodes->getNumChildren() == 2) { + pExtraSymbol = dynamic_cast(nodes->getChild(1)); + if (pExtraSymbol) { + pShapeSep->addChild(pExtraSymbol); + } + } + pMultCopy->matrix.setNum(0); + nodes->unref(); +} + std::vector ViewProviderFemConstraint::getDisplayModes() const { // add modes @@ -148,7 +191,7 @@ void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver, void ViewProviderFemConstraint::onChanged(const App::Property* prop) { - if (prop == &Mirror || prop == &DistFactor) { + if (prop == &Mirror) { updateData(prop); } else if (prop == &TextColor) { @@ -167,6 +210,51 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop) } } +void ViewProviderFemConstraint::updateData(const App::Property* prop) +{ + auto pcConstraint = static_cast(this->getObject()); + + if (prop == &pcConstraint->Points || prop == &pcConstraint->Normals + || prop == &pcConstraint->Scale) { + updateSymbol(); + } + else { + ViewProviderGeometryObject::updateData(prop); + } +} + +void ViewProviderFemConstraint::updateSymbol() +{ + auto obj = static_cast(this->getObject()); + const std::vector& points = obj->Points.getValue(); + const std::vector& normals = obj->Normals.getValue(); + pMultCopy->matrix.setNum(points.size()); + SbMatrix* mat = pMultCopy->matrix.startEditing(); + + for (size_t i = 0; i < points.size(); ++i) { + transformSymbol(points[i], normals[i], mat[i]); + } + + pMultCopy->matrix.finishEditing(); +} + +void ViewProviderFemConstraint::transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const +{ + auto obj = static_cast(this->getObject()); + SbVec3f axisY(0, 1, 0); + float s = obj->getScaleFactor(); + SbVec3f scale(s, s, s); + SbVec3f norm = rotateSymbol ? SbVec3f(normal.x, normal.y, normal.z) : axisY; + SbRotation rot(axisY, norm); + SbVec3f tra(static_cast(point.x), + static_cast(point.y), + static_cast(point.z)); + mat.setTransform(tra, rot, scale); +} + + // OvG: Visibility automation show parts and hide meshes on activation of a constraint std::string ViewProviderFemConstraint::gethideMeshShowPartStr(const std::string showConstr) { diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h index 73c572629d..c3e5beb323 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h @@ -34,12 +34,12 @@ #include +class SbRotation; class SoFontStyle; class SoText2; class SoBaseColor; -class SoTranslation; -class SbRotation; class SoMaterial; +class SoMultipleCopy; namespace FemGui { @@ -64,10 +64,7 @@ public: App::PropertyBool Mirror; void attach(App::DocumentObject*) override; - void updateData(const App::Property* prop) override - { - Gui::ViewProviderGeometryObject::updateData(prop); - } + void updateData(const App::Property* prop) override; std::vector getDisplayModes() const override; void setDisplayMode(const char* ModeName) override; @@ -80,10 +77,19 @@ public: virtual void highlightReferences(const bool /* on */) {} - SoSeparator* getSymbolSeparator() const - { - return pShapeSep; - } + SoSeparator* getSymbolSeparator() const; + SoSeparator* getExtraSymbolSeparator() const; + // Apply rotation on copies of the constraint symbol + void setRotateSymbol(bool rotate); + bool getRotateSymbol() const; + + /** Load constraint symbol from Open Inventor file + * The file structure should be as follows: + * A separator containing a separator with the symbol used in multiple + * copies at points on the surface and an optional separator with a symbol + * excluded from multiple copies. + */ + void loadSymbol(const char* fileName); static std::string gethideMeshShowPartStr(); static std::string gethideMeshShowPartStr(const std::string showConstr); @@ -93,6 +99,10 @@ protected: bool setEdit(int ModNum) override; void unsetEdit(int ModNum) override; + void updateSymbol(); + virtual void + transformSymbol(const Base::Vector3d& point, const Base::Vector3d& normal, SbMatrix& mat) const; + static void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r); static void updatePlacement(const SoSeparator* sep, const int idx, @@ -159,9 +169,16 @@ private: SoText2* pLabel; SoBaseColor* pTextColor; SoBaseColor* pMaterials; + bool rotateSymbol; protected: SoSeparator* pShapeSep; + SoSeparator* pSymbol; + SoSeparator* pExtraSymbol; + SoMultipleCopy* pMultCopy; + const char* ivFile; + + static std::string resourceSymbolDir; // Shaft design wizard integration protected: @@ -174,6 +191,27 @@ protected: static QObject* findChildByName(const QObject* parent, const QString& name); }; + +inline SoSeparator* ViewProviderFemConstraint::getSymbolSeparator() const +{ + return pSymbol; +} + +inline SoSeparator* ViewProviderFemConstraint::getExtraSymbolSeparator() const +{ + return pExtraSymbol; +} + +inline bool ViewProviderFemConstraint::getRotateSymbol() const +{ + return rotateSymbol; +} + +inline void ViewProviderFemConstraint::setRotateSymbol(bool rotate) +{ + rotateSymbol = rotate; +} + using ViewProviderFemConstraintPython = Gui::ViewProviderPythonFeatureT; diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintContact.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintContact.cpp index 44dd3cff81..34c0ef18ee 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintContact.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintContact.cpp @@ -26,11 +26,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include -#include -#include #endif #include "Mod/Fem/App/FemConstraintContact.h" @@ -46,6 +41,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintContact, FemGui::ViewProviderFe ViewProviderFemConstraintContact::ViewProviderFemConstraintContact() { sPixmap = "FEM_ConstraintContact"; + loadSymbol((resourceSymbolDir + "ConstraintContact.iv").c_str()); // Note change "Contact" in line above to new constraint name, make sure it is the same as in // taskFem* cpp file ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f)); @@ -93,75 +89,7 @@ bool ViewProviderFemConstraintContact::setEdit(int ModNum) } } -#define HEIGHT (0.5) -#define LENGTH (1.5) -#define WIDTH (0.5) - -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - -// so disable - void ViewProviderFemConstraintContact::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintContact* pcConstraint = static_cast(this->getObject()); - float scaledlength = - LENGTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - - // Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - for (const auto& point : points) { - // Define base and normal directions - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); // normal - - /// Visual indication - // define separator - SoSeparator* sep = new SoSeparator(); - - // first move to correct position - SoTranslation* trans = new SoTranslation(); - SbVec3f newPos = base + scaledheight * dir * 0.12f; - trans->translation.setValue(newPos); - sep->addChild(trans); - - // adjust orientation - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir)); - sep->addChild(rot); - - // define color of shape - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB - // myMaterial->diffuseColor.set1Value(1,SbColor(0,0,1));//possible to adjust sides - // separately - sep->addChild(myMaterial); - - // draw a cube - SoCube* cbe = new SoCube(); - cbe->depth.setValue(scaledlength * 0.5); - cbe->height.setValue(scaledheight * 0.25); - cbe->width.setValue(scaledwidth * 0.75); - sep->addChild(cbe); - // translate position - SoTranslation* trans2 = new SoTranslation(); - trans2->translation.setValue(SbVec3f(0, 0, 0)); - sep->addChild(trans2); - - pShapeSep->addChild(sep); - n++; - } - } - // Gets called whenever a property of the attached object changes ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintDisplacement.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintDisplacement.cpp index 0a4a8449ad..26976e0b5e 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintDisplacement.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintDisplacement.cpp @@ -26,10 +26,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include #include +#include #endif #include "Mod/Fem/App/FemConstraintDisplacement.h" @@ -46,7 +44,11 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintDisplacement, ViewProviderFemConstraintDisplacement::ViewProviderFemConstraintDisplacement() { sPixmap = "FEM_ConstraintDisplacement"; + loadSymbol((resourceSymbolDir + "ConstraintDisplacement.iv").c_str()); ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f)); + + // do not rotate symbol according to boundary normal + setRotateSymbol(false); } ViewProviderFemConstraintDisplacement::~ViewProviderFemConstraintDisplacement() = default; @@ -92,211 +94,36 @@ bool ViewProviderFemConstraintDisplacement::setEdit(int ModNum) } } -#define HEIGHT (4) -#define WIDTH (0.3) -// #define USE_MULTIPLE_COPY -// OvG: MULTICOPY fails to update scaled display on initial drawing - so disable - void ViewProviderFemConstraintDisplacement::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes Fem::ConstraintDisplacement* pcConstraint = static_cast(this->getObject()); - // OvG: Calculate scaled values once only - float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - bool xFree = pcConstraint->xFree.getValue(); - bool yFree = pcConstraint->yFree.getValue(); - bool zFree = pcConstraint->zFree.getValue(); - bool rotxFree = pcConstraint->rotxFree.getValue(); - bool rotyFree = pcConstraint->rotyFree.getValue(); - bool rotzFree = pcConstraint->rotzFree.getValue(); -#ifdef USE_MULTIPLE_COPY - // OvG: always need access to cp for scaling - SoMultipleCopy* cpx = new SoMultipleCopy(); - SoMultipleCopy* cpy = new SoMultipleCopy(); - SoMultipleCopy* cpz = new SoMultipleCopy(); - SoMultipleCopy* cprotx = new SoMultipleCopy(); - SoMultipleCopy* cproty = new SoMultipleCopy(); - SoMultipleCopy* cprotz = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cpx->matrix.setNum(0); - cpx->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling - - cpy->matrix.setNum(0); - cpy->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling - - cpz->matrix.setNum(0); - cpz->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling - - cprotx->matrix.setNum(0); - cprotx->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling - - cproty->matrix.setNum(0); - cproty->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling - - cprotz->matrix.setNum(0); - cprotz->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling - - pShapeSep->addChild(cpx); - pShapeSep->addChild(cpy); - pShapeSep->addChild(cpz); - pShapeSep->addChild(cprotx); - pShapeSep->addChild(cproty); - pShapeSep->addChild(cprotz; + if (prop == &pcConstraint->xFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(0)); + sw->whichChild.setValue((pcConstraint->xFree.getValue() ? -1 : 0)); } -#endif - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - -#ifdef USE_MULTIPLE_COPY - cpx = static_cast(pShapeSep->getChild(0)); - cpx->matrix.setNum(points.size()); - SbMatrix* matricesx = cpx->matrix.startEditing(); - - cpy = static_cast(pShapeSep->getChild(1)); - cpy->matrix.setNum(points.size()); - SbMatrix* matricesy = cpy->matrix.startEditing(); - - cpz = static_cast(pShapeSep->getChild(2)); - cpz->matrix.setNum(points.size()); - SbMatrix* matricesz = cpz->matrix.startEditing(); - - cprotx = static_cast(pShapeSep->getChild(3)); - cprotx->matrix.setNum(points.size()); - SbMatrix* matricesrotx = cprotx->matrix.startEditing(); - - cproty = static_cast(pShapeSep->getChild(4)); - cproty->matrix.setNum(points.size()); - SbMatrix* matricesroty = cproty->matrix.startEditing(); - - cprotz = static_cast(pShapeSep->getChild(5)); - cprotz->matrix.setNum(points.size()); - SbMatrix* matricesrotz = cprotz->matrix.startEditing(); - - int idx = 0; - int idy = 0; - int idz = 0; - int idrotx = 0; - int idroty = 0; - int idrotz = 0; -#else - // Note: Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); -#endif - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f dirx(1, 0, 0); // OvG: Make relevant to global axes - SbVec3f diry(0, 1, 0); // OvG: Make relevant to global axes - SbVec3f dirz(0, 0, 1); // OvG: Make relevant to global axes - SbRotation rotx(SbVec3f(0, -1, 0), dirx); // OvG Tri-cones - SbRotation roty(SbVec3f(0, -1, 0), diry); - SbRotation rotz(SbVec3f(0, -1, 0), dirz); -#ifdef USE_MULTIPLE_COPY - SbMatrix mx; - SbMatrix my; - SbMatrix mz; - // OvG: Translation indication - if (!xFree) { - SbMatrix mx; - mx.setTransform(base, rotx, SbVec3f(1, 1, 1)); - matricesx[idx] = mx; - idx++; - } - if (!yFree) { - SbMatrix my; - my.setTransform(base, roty, SbVec3f(1, 1, 1)); - matricesy[idy] = my; - idy++; - } - if (!zFree) { - SbMatrix mz; - mz.setTransform(base, rotz, SbVec3f(1, 1, 1)); - matricesz[idz] = mz; - idz++; - } - - // OvG: Rotation indication - if (!rotxFree) { - SbMatrix mrotx; - mrotx.setTransform(base, rotx, SbVec3f(1, 1, 1)); - matricesrotx[idrotx] = mrotx; - idrotx++; - } - if (!rotyFree) { - SbMatrix mroty; - mroty.setTransform(base, roty, SbVec3f(1, 1, 1)); - matricesroty[idroty] = mroty; - idroty++; - } - if (!rotzFree) { - SbMatrix mrotz; - mrotz.setTransform(base, rotz, SbVec3f(1, 1, 1)); - matricesrotz[idrotz] = mrotz; - idrotz++; - } -#else - // OvG: Translation indication - if (!xFree) { - SoSeparator* sepx = new SoSeparator(); - createPlacement(sepx, base, rotx); - createDisplacement(sepx, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepx); - } - if (!yFree) { - SoSeparator* sepy = new SoSeparator(); - createPlacement(sepy, base, roty); - createDisplacement(sepy, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepy); - } - if (!zFree) { - SoSeparator* sepz = new SoSeparator(); - createPlacement(sepz, base, rotz); - createDisplacement(sepz, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepz); - } - - // OvG: Rotation indication - if (!rotxFree) { - SoSeparator* sepx = new SoSeparator(); - createPlacement(sepx, base, rotx); - createRotation(sepx, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepx); - } - if (!rotyFree) { - SoSeparator* sepy = new SoSeparator(); - createPlacement(sepy, base, roty); - createRotation(sepy, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepy); - } - if (!rotzFree) { - SoSeparator* sepz = new SoSeparator(); - createPlacement(sepz, base, rotz); - createRotation(sepz, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sepz); - } -#endif - n++; - } -#ifdef USE_MULTIPLE_COPY - cpx->matrix.finishEditing(); - cpy->matrix.finishEditing(); - cpz->matrix.finishEditing(); - cprotx->matrix.finishEditing(); - cproty->matrix.finishEditing(); - cprotz->matrix.finishEditing(); -#endif + else if (prop == &pcConstraint->yFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(1)); + sw->whichChild.setValue((pcConstraint->yFree.getValue() ? -1 : 0)); + } + else if (prop == &pcConstraint->zFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(2)); + sw->whichChild.setValue((pcConstraint->zFree.getValue() ? -1 : 0)); + } + else if (prop == &pcConstraint->rotxFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(3)); + sw->whichChild.setValue((pcConstraint->rotxFree.getValue() ? -1 : 0)); + } + else if (prop == &pcConstraint->rotyFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(4)); + sw->whichChild.setValue((pcConstraint->rotyFree.getValue() ? -1 : 0)); + } + else if (prop == &pcConstraint->rotzFree) { + auto sw = static_cast(getSymbolSeparator()->getChild(5)); + sw->whichChild.setValue((pcConstraint->rotzFree.getValue() ? -1 : 0)); + } + else { + ViewProviderFemConstraint::updateData(prop); } - - // Gets called whenever a property of the attached object changes - ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp index 3a3ebcaa11..fe3b54322b 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp @@ -46,6 +46,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemC ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed() { sPixmap = "FEM_ConstraintFixed"; + loadSymbol((resourceSymbolDir + "ConstraintFixed.iv").c_str()); } ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed() = default; @@ -108,69 +109,7 @@ bool ViewProviderFemConstraintFixed::setEdit(int ModNum) } } -#define WIDTH (2) -#define HEIGHT (1) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - -// so disable - void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); - float scaledwidth = - WIDTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - -#ifdef USE_MULTIPLE_COPY - // OvG: always need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); // OvG: Scaling - pShapeSep->addChild(cp); - } -#endif - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Note: Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); -#endif - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); - SbRotation rot(SbVec3f(0, -1, 0), dir); -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1, 1, 1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sep); -#endif - n++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp index d6614dbbc0..98b6ca6013 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp @@ -24,11 +24,9 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include #include -#include -#include -#include #include #endif @@ -47,6 +45,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemC ViewProviderFemConstraintForce::ViewProviderFemConstraintForce() { sPixmap = "FEM_ConstraintForce"; + loadSymbol((resourceSymbolDir + "ConstraintForce.iv").c_str()); } ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce() = default; @@ -109,117 +108,41 @@ bool ViewProviderFemConstraintForce::setEdit(int ModNum) } } -#define ARROWLENGTH (4) -#define ARROWHEADRADIUS (ARROWLENGTH / 3.0f) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so -// disable - void ViewProviderFemConstraintForce::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); - float scaledheadradius = - ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); + auto pcConstraint = static_cast(this->getObject()); -#ifdef USE_MULTIPLE_COPY - // OvG: need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling - pShapeSep->addChild(cp); + if (prop == &pcConstraint->Reversed || prop == &pcConstraint->DirectionVector) { + updateSymbol(); } -#endif - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Redraw all arrows - Gui::coinRemoveAllChildren(pShapeSep); -#endif - // This should always point outside of the solid - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - - // Get default direction (on first call to method) - Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); - if (forceDirection.Length() < Precision::Confusion()) { - forceDirection = normal; - } - - SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); - SbRotation rot(SbVec3f(0, 1, 0), dir); - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - if (forceDirection.GetAngle(normal) - < M_PI_2) { // Move arrow so it doesn't disappear inside the solid - base = base + dir * scaledlength; // OvG: Scaling - } -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1, 1, 1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling - pShapeSep->addChild(sep); -#endif - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif + else { + ViewProviderFemConstraint::updateData(prop); } - else if (prop == &pcConstraint->DirectionVector) { - // Note: "Reversed" also triggers "DirectionVector" - // Re-orient all arrows - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); - if (forceDirection.Length() < Precision::Confusion()) { - forceDirection = normal; - } - - SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); - SbRotation rot(SbVec3f(0, 1, 0), dir); - - const std::vector& points = pcConstraint->Points.getValues(); - -#ifdef USE_MULTIPLE_COPY - SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); -#endif - int idx = 0; - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - if (forceDirection.GetAngle(normal) < M_PI_2) { - base = base + dir * scaledlength; // OvG: Scaling - } -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1, 1, 1)); - matrices[idx] = m; -#else - SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); - updatePlacement(sep, 0, base, rot); - updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling -#endif - idx++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - - ViewProviderFemConstraint::updateData(prop); +} + +void ViewProviderFemConstraintForce::transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const +{ + auto obj = static_cast(this->getObject()); + bool rev = obj->Reversed.getValue(); + float s = obj->getScaleFactor(); + // Symbol length from .iv file + float symLen = 4.0f; + // Place each symbol outside the boundary + Base::Vector3d dir = (rev ? -1.0 : 1.0) * obj->DirectionVector.getValue(); + float symTraY = dir.Dot(normal) < 0 ? -1 * symLen : 0.0f; + float rotAngle = rev ? F_PI : 0.0f; + SbMatrix mat0, mat1; + mat0.setTransform(SbVec3f(0, symTraY, 0), + SbRotation(SbVec3f(0, 0, 1), rotAngle), + SbVec3f(1, 1, 1), + SbRotation(SbVec3f(0, 0, 1), 0), + SbVec3f(0, symLen / 2.0f, 0)); + + mat1.setTransform(SbVec3f(point.x, point.y, point.z), + SbRotation(SbVec3f(0, 1, 0), SbVec3f(dir.x, dir.y, dir.z)), + SbVec3f(s, s, s)); + + mat = mat0 * mat1; } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h index 8008780a93..440e29e65a 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h @@ -44,6 +44,9 @@ public: protected: bool setEdit(int ModNum) override; + void transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const override; private: /// Direction of the force diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintHeatflux.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintHeatflux.cpp index f876fc5e82..39c32de510 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintHeatflux.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintHeatflux.cpp @@ -26,12 +26,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include -#include -#include -#include #endif #include "Mod/Fem/App/FemConstraintHeatflux.h" @@ -49,7 +43,9 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintHeatflux, ViewProviderFemConstraintHeatflux::ViewProviderFemConstraintHeatflux() { sPixmap = "FEM_ConstraintHeatflux"; - ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f)); + loadSymbol((resourceSymbolDir + "ConstraintHeatFlux.iv").c_str()); + + FaceColor.setValue(1.0f, 0.0f, 0.0f); } ViewProviderFemConstraintHeatflux::~ViewProviderFemConstraintHeatflux() = default; @@ -94,103 +90,7 @@ bool ViewProviderFemConstraintHeatflux::setEdit(int ModNum) } } -#define HEIGHT (1.5) -#define RADIUS (0.3) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - -// so disable - void ViewProviderFemConstraintHeatflux::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintHeatflux* pcConstraint = - static_cast(this->getObject()); - float scaledradius = - RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - // float ambienttemp = pcConstraint->AmbientTemp.getValue(); - // //float facetemp = pcConstraint->FaceTemp.getValue(); - // float filmcoef = pcConstraint->FilmCoef.getValue(); - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - - // Note: Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - for (const auto& point : points) { - // Define base and normal directions - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); // normal - - /// Temperature indication - // define separator - SoSeparator* sep = new SoSeparator(); - - /// draw a temp gauge,with sphere and a cylinder - // first move to correct position - SoTranslation* trans = new SoTranslation(); - SbVec3f newPos = base + scaledradius * dir * 0.7f; - trans->translation.setValue(newPos); - sep->addChild(trans); - - // adjust orientation - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir)); - sep->addChild(rot); - - // define color of shape - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(0.65f, 0.1f, 0.25f)); // RGB - // myMaterial->diffuseColor.set1Value(1,SbColor(.1,.1,.1));//possible to adjust sides - // separately - sep->addChild(myMaterial); - - // draw a sphere - SoSphere* sph = new SoSphere(); - sph->radius.setValue(scaledradius * 0.75); - sep->addChild(sph); - // translate position - SoTranslation* trans2 = new SoTranslation(); - trans2->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0)); - sep->addChild(trans2); - // draw a cylinder - SoCylinder* cyl = new SoCylinder(); - cyl->height.setValue(scaledheight * 0.5); - cyl->radius.setValue(scaledradius * 0.375); - sep->addChild(cyl); - // translate position - SoTranslation* trans3 = new SoTranslation(); - trans3->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0)); - sep->addChild(trans3); - // define color of shape - SoMaterial* myMaterial2 = new SoMaterial; - myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB - sep->addChild(myMaterial2); - // draw a cylinder - SoCylinder* cyl2 = new SoCylinder(); - cyl2->height.setValue(scaledheight * 0.25); - cyl2->radius.setValue(scaledradius * 0.375); - sep->addChild(cyl2); - // translate position - SoTranslation* trans4 = new SoTranslation(); - trans4->translation.setValue(SbVec3f(0, -scaledheight * 0.375, 0)); - sep->addChild(trans4); - // draw a cylinder - SoCylinder* cyl3 = new SoCylinder(); - cyl3->height.setValue(scaledheight * 0.05); - cyl3->radius.setValue(scaledradius * 1); - sep->addChild(cyl3); - - pShapeSep->addChild(sep); - - n++; - } - } - // Gets called whenever a property of the attached object changes ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPlaneRotation.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPlaneRotation.cpp index ea2cf874ae..e90917713f 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPlaneRotation.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPlaneRotation.cpp @@ -26,12 +26,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include -#include -#include -#include #endif #include "Mod/Fem/App/FemConstraintPlaneRotation.h" @@ -48,6 +42,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPlaneRotation, FemGui::ViewProv ViewProviderFemConstraintPlaneRotation::ViewProviderFemConstraintPlaneRotation() { sPixmap = "FEM_ConstraintPlaneRotation"; + loadSymbol((resourceSymbolDir + "ConstraintPlaneRotation.iv").c_str()); // Note change "planerotation" in line above to new constraint name, make sure it is the same as // in taskFem* cpp file ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f)); @@ -96,98 +91,7 @@ bool ViewProviderFemConstraintPlaneRotation::setEdit(int ModNum) } } -#define HEIGHT (0.5) -#define RADIUS (5) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - -// so disable - void ViewProviderFemConstraintPlaneRotation::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintPlaneRotation* pcConstraint = - static_cast(this->getObject()); - float scaledradius = - RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - - // Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - for (const auto& point : points) { - // Define base and normal directions - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); // normal - - /* Note: - * This next part draws a temperature gauge in 3D to indicate the constraint visually. - * This serves as an example. Change or remove as needs be. - * It is possible to draw almost any basic 3D shape. See inventor's documentation - * This gets drawn at every point. - * */ - - /// Visual indication - // define separator - SoSeparator* sep = new SoSeparator(); - - /// draw a temp gauge,with sphere and a cylinder - // first move to correct position - SoTranslation* trans = new SoTranslation(); - SbVec3f newPos = base + scaledradius * dir * 0.08f; - trans->translation.setValue(newPos); - sep->addChild(trans); - - // adjust orientation - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(SbRotation(SbVec3f(1, 0, 0), dir)); - sep->addChild(rot); - - // define color of shape - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(0, 1, 0)); // RGB - // myMaterial->diffuseColor.set1Value(1,SbColor(0,0,1));//possible to adjust sides - // separately - sep->addChild(myMaterial); - - // draw a sphere - // SoSphere* sph = new SoSphere(); - // sph->radius.setValue(scaledradius*0.75); - // sep->addChild(sph); - // translate position - // SoTranslation* trans2 = new SoTranslation(); - // trans2->translation.setValue(SbVec3f(0,scaledheight*0.375,0)); - // sep->addChild(trans2); - // draw a cylinder - SoCylinder* cyl = new SoCylinder(); - cyl->height.setValue(scaledheight * 0.5); - cyl->radius.setValue(scaledradius * 0.375); - sep->addChild(cyl); - // translate position - // SoTranslation* trans3 = new SoTranslation(); - // trans3->translation.setValue(SbVec3f(0,scaledheight*0.05,0)); - // sep->addChild(trans3); - // define color of shape - SoMaterial* myMaterial2 = new SoMaterial; - myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB - sep->addChild(myMaterial2); - // draw a cylinder - // SoCylinder* cyl2 = new SoCylinder(); - // cyl2->height.setValue(scaledheight*0.25); - // cyl2->radius.setValue(scaledradius*0.375); - // sep->addChild(cyl2); - - pShapeSep->addChild(sep); - - n++; - } - } - // Gets called whenever a property of the attached object changes ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp index 089edd28af..8f674a8e6a 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp @@ -24,10 +24,9 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include #include -#include -#include #endif #include "Mod/Fem/App/FemConstraintPressure.h" @@ -45,6 +44,8 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPressure, ViewProviderFemConstraintPressure::ViewProviderFemConstraintPressure() { sPixmap = "FEM_ConstraintPressure"; + loadSymbol((resourceSymbolDir + "ConstraintPressure.iv").c_str()); + ADD_PROPERTY(FaceColor, (0.0f, 0.2f, 0.8f)); } @@ -90,78 +91,37 @@ bool ViewProviderFemConstraintPressure::setEdit(int ModNum) } } -#define ARROWLENGTH (4) -#define ARROWHEADRADIUS (ARROWLENGTH / 3.0f) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so -// disable - void ViewProviderFemConstraintPressure::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintPressure* pcConstraint = - static_cast(this->getObject()); - float scaledheadradius = - ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); + auto pcConstraint = static_cast(this->getObject()); -#ifdef USE_MULTIPLE_COPY - // OvG: always need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling - pShapeSep->addChild(cp); + if (prop == &pcConstraint->Reversed) { + updateSymbol(); } -#endif - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); // OvG: Use top cp - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Redraw all arrows - Gui::coinRemoveAllChildren(pShapeSep); -#endif - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); - double rev; - if (pcConstraint->Reversed.getValue()) { - base = base + dir * scaledlength; // OvG: Scaling - rev = 1; - } - else { - rev = -1; - } - SbRotation rot(SbVec3f(0, rev, 0), dir); -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1, 1, 1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling - pShapeSep->addChild(sep); -#endif - n++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif + else { + ViewProviderFemConstraint::updateData(prop); } - - ViewProviderFemConstraint::updateData(prop); +} + +void ViewProviderFemConstraintPressure::transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const +{ + auto obj = static_cast(this->getObject()); + float rotAngle = obj->Reversed.getValue() ? F_PI : 0.0f; + float s = obj->getScaleFactor(); + // Symbol length from .iv file + float symLen = 4.0f; + SbMatrix mat0, mat1; + mat0.setTransform(SbVec3f(0, 0, 0), + SbRotation(SbVec3f(0, 0, 1), rotAngle), + SbVec3f(1, 1, 1), + SbRotation(SbVec3f(0, 0, 1), 0), + SbVec3f(0, symLen / 2.0f, 0)); + + mat1.setTransform(SbVec3f(point.x, point.y, point.z), + SbRotation(SbVec3f(0, 1, 0), SbVec3f(normal.x, normal.y, normal.z)), + SbVec3f(s, s, s)); + + mat = mat0 * mat1; } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.h index 6b1c9ebcc3..2f328bdda3 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.h @@ -41,6 +41,9 @@ public: protected: bool setEdit(int ModNum) override; + void transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const override; }; } // namespace FemGui diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPy.xml b/src/Mod/Fem/Gui/ViewProviderFemConstraintPy.xml index 3192cf5853..c679c82b89 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPy.xml +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPy.xml @@ -13,11 +13,37 @@ This is the ViewProviderFemConstraint class + + + loadSymbol(filename) -> None + +Load constraint symbol from Open Inventor file. +The file structure should be as follows: +A separator containing a separator with the symbol used in +multiple copies at points on the surface and an optional +separator with a symbol excluded from multiple copies. + +filename : str + Open Inventor file. + + A pivy SoSeparator with the nodes of the constraint symbols + + + A pivy SoSeparator with the nodes of the constraint extra symbols + + + + + + Apply rotation on copies of the constraint symbol + + + diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPyImp.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPyImp.cpp index 8117daf4c8..e6d28673ed 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPyImp.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPyImp.cpp @@ -43,23 +43,68 @@ std::string ViewProviderFemConstraintPy::representation() const return str.str(); } +PyObject* ViewProviderFemConstraintPy::loadSymbol(PyObject* args) +{ + const char* name; + if (!PyArg_ParseTuple(args, "s", &name)) { + return nullptr; + } + + getViewProviderFemConstraintPtr()->loadSymbol(name); + + Py_Return; +} Py::Object ViewProviderFemConstraintPy::getSymbolNode() const { try { SoSeparator* sep = getViewProviderFemConstraintPtr()->getSymbolSeparator(); - PyObject* Ptr = - Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1); + if (sep) { + PyObject* Ptr = + Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1); + sep->ref(); - sep->ref(); - - return Py::Object(Ptr, true); + return Py::Object(Ptr, true); + } + else { + return Py::None(); + } } catch (const Base::Exception& e) { throw Py::RuntimeError(e.what()); } } +Py::Object ViewProviderFemConstraintPy::getExtraSymbolNode() const +{ + try { + SoSeparator* sep = getViewProviderFemConstraintPtr()->getExtraSymbolSeparator(); + if (sep) { + PyObject* Ptr = + Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1); + sep->ref(); + + return Py::Object(Ptr, true); + } + else { + return Py::None(); + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } +} + +Py::Boolean ViewProviderFemConstraintPy::getRotateSymbol() const +{ + return Py::Boolean(getViewProviderFemConstraintPtr()->getRotateSymbol()); +} + +void ViewProviderFemConstraintPy::setRotateSymbol(Py::Boolean arg) +{ + getViewProviderFemConstraintPtr()->setRotateSymbol((arg)); +} + PyObject* ViewProviderFemConstraintPy::getCustomAttributes(const char* /*attr*/) const { return nullptr; diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintSpring.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintSpring.cpp index 33fca41ec0..43c6924661 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintSpring.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintSpring.cpp @@ -24,10 +24,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include -#include #endif #include "Mod/Fem/App/FemConstraintSpring.h" @@ -45,6 +41,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintSpring, ViewProviderFemConstraintSpring::ViewProviderFemConstraintSpring() { sPixmap = "FEM_ConstraintSpring"; + loadSymbol((resourceSymbolDir + "ConstraintSpring.iv").c_str()); ADD_PROPERTY(FaceColor, (0.0f, 0.2f, 0.8f)); } @@ -91,69 +88,7 @@ bool ViewProviderFemConstraintSpring::setEdit(int ModNum) } } -#define WIDTH (1) -#define LENGTH (2) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so -// disable - void ViewProviderFemConstraintSpring::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintSpring* pcConstraint = static_cast(this->getObject()); - float scaledwidth = - WIDTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledlength = LENGTH * pcConstraint->Scale.getValue(); - -#ifdef USE_MULTIPLE_COPY - // OvG: always need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createSpring(scaledlength, scaledwidth)); // OvG: Scaling - pShapeSep->addChild(cp); - } -#endif - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); // OvG: Use top cp - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Redraw all cylinders - Gui::coinRemoveAllChildren(pShapeSep); -#endif - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); - SbRotation rot(SbVec3f(0, -1.0, 0), dir); -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1, 1, 1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createSpring(sep, scaledlength, scaledwidth); // OvG: Scaling - pShapeSep->addChild(sep); -#endif - n++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintTemperature.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintTemperature.cpp index bc538feb68..53430c262e 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintTemperature.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintTemperature.cpp @@ -26,12 +26,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include -#include -#include -#include #endif #include "Mod/Fem/App/FemConstraintTemperature.h" @@ -48,7 +42,9 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintTemperature, ViewProviderFemConstraintTemperature::ViewProviderFemConstraintTemperature() { sPixmap = "FEM_ConstraintTemperature"; - ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f)); + loadSymbol((resourceSymbolDir + "ConstraintTemperature.iv").c_str()); + + FaceColor.setValue(1.0f, 0.0f, 0.0f); } ViewProviderFemConstraintTemperature::~ViewProviderFemConstraintTemperature() = default; @@ -94,92 +90,7 @@ bool ViewProviderFemConstraintTemperature::setEdit(int ModNum) } } -#define HEIGHT (1.5) -#define RADIUS (0.3) -// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - -// so disable - void ViewProviderFemConstraintTemperature::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintTemperature* pcConstraint = - static_cast(this->getObject()); - float scaledradius = - RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - // float temperature = pcConstraint->temperature.getValue(); - - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; - } - std::vector::const_iterator n = normals.begin(); - - // Note: Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - for (const auto& point : points) { - // Define base and normal directions - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); // normal - - /// Temperature indication - // define separator - SoSeparator* sep = new SoSeparator(); - - /// draw a temp gauge,with sphere and a cylinder - // first move to correct position - SoTranslation* trans = new SoTranslation(); - SbVec3f newPos = base + scaledradius * dir * 0.7f; - trans->translation.setValue(newPos); - sep->addChild(trans); - - // adjust orientation - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir)); - sep->addChild(rot); - - // define color of shape - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB - // myMaterial->diffuseColor.set1Value(1,SbColor(.1,.1,.1));//possible to adjust sides - // separately - sep->addChild(myMaterial); - - // draw a sphere - SoSphere* sph = new SoSphere(); - sph->radius.setValue(scaledradius * 0.75); - sep->addChild(sph); - // translate position - SoTranslation* trans2 = new SoTranslation(); - trans2->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0)); - sep->addChild(trans2); - // draw a cylinder - SoCylinder* cyl = new SoCylinder(); - cyl->height.setValue(scaledheight * 0.5); - cyl->radius.setValue(scaledradius * 0.375); - sep->addChild(cyl); - // translate position - SoTranslation* trans3 = new SoTranslation(); - trans3->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0)); - sep->addChild(trans3); - // define color of shape - SoMaterial* myMaterial2 = new SoMaterial; - myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB - sep->addChild(myMaterial2); - // draw a cylinder - SoCylinder* cyl2 = new SoCylinder(); - cyl2->height.setValue(scaledheight * 0.25); - cyl2->radius.setValue(scaledradius * 0.375); - sep->addChild(cyl2); - - pShapeSep->addChild(sep); - - n++; - } - } - // Gets called whenever a property of the attached object changes ViewProviderFemConstraint::updateData(prop); } diff --git a/src/Mod/Fem/femviewprovider/view_base_femconstraint.py b/src/Mod/Fem/femviewprovider/view_base_femconstraint.py index 49e551c767..f0dbc0a262 100644 --- a/src/Mod/Fem/femviewprovider/view_base_femconstraint.py +++ b/src/Mod/Fem/femviewprovider/view_base_femconstraint.py @@ -32,25 +32,15 @@ __url__ = "https://www.freecad.org" from pivy import coin +from FreeCAD import getResourceDir from femviewprovider import view_base_femobject class VPBaseFemConstraint(view_base_femobject.VPBaseFemObject): """Proxy View Provider for Pythons base constraint.""" + resource_symbol_dir = getResourceDir() + "Mod/Fem/Resources/symbols/" + def attach(self, vobj): - default = coin.SoGroup() - vobj.addDisplayMode(default, "Default") - self.Object = vobj.Object # used on various places, claim childreens, get icon, etc. - # self.ViewObject = vobj # not used ATM - - def getDisplayModes(self, obj): - "Return a list of display modes." - modes = ["Default"] - return modes - - def getDefaultDisplayMode(self): - return "Default" - - def setDisplayMode(self, mode): - return mode + # used on various places, claim childreens, get icon, etc. + self.Object = vobj.Object diff --git a/src/Mod/Fem/femviewprovider/view_constraint_tie.py b/src/Mod/Fem/femviewprovider/view_constraint_tie.py index 56b32ff9b5..874b779b52 100644 --- a/src/Mod/Fem/femviewprovider/view_constraint_tie.py +++ b/src/Mod/Fem/femviewprovider/view_constraint_tie.py @@ -38,6 +38,9 @@ class VPConstraintTie(view_base_femconstraint.VPBaseFemConstraint): A View Provider for the ConstraintTie object """ + def __init__(self, vobj): + super().__init__(vobj) + def setEdit(self, vobj, mode=0): view_base_femconstraint.VPBaseFemConstraint.setEdit( self, @@ -45,3 +48,7 @@ class VPConstraintTie(view_base_femconstraint.VPBaseFemConstraint): mode, task_constraint_tie._TaskPanel ) + + def attach(self, vobj): + super().attach(vobj) + vobj.loadSymbol(self.resource_symbol_dir + "ConstraintTie.iv")