From 047b184df4d7430112d389d45afb58d04248be03 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Tue, 28 May 2024 00:29:05 -0300 Subject: [PATCH 1/4] Fem: Cleanup ViewProviderFemConstraint class --- src/Mod/Fem/Gui/CMakeLists.txt | 2 + src/Mod/Fem/Gui/FemGuiTools.cpp | 206 +++++++++++ src/Mod/Fem/Gui/FemGuiTools.h | 74 ++++ src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp | 347 +----------------- src/Mod/Fem/Gui/ViewProviderFemConstraint.h | 62 +--- .../Gui/ViewProviderFemConstraintBearing.cpp | 16 +- ...ViewProviderFemConstraintFluidBoundary.cpp | 19 +- .../Fem/Gui/ViewProviderFemConstraintGear.cpp | 34 +- .../Gui/ViewProviderFemConstraintPulley.cpp | 151 ++++---- 9 files changed, 407 insertions(+), 504 deletions(-) create mode 100644 src/Mod/Fem/Gui/FemGuiTools.cpp create mode 100644 src/Mod/Fem/Gui/FemGuiTools.h diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index 0cfad23eb6..63afa186a2 100755 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -305,6 +305,8 @@ SET(FemGui_SRCS_Module ActiveAnalysisObserver.cpp ActiveAnalysisObserver.h Command.cpp + FemGuiTools.cpp + FemGuiTools.h FemSettings.cpp FemSettings.h Resources/Fem.qrc diff --git a/src/Mod/Fem/Gui/FemGuiTools.cpp b/src/Mod/Fem/Gui/FemGuiTools.cpp new file mode 100644 index 0000000000..cf6d66ec62 --- /dev/null +++ b/src/Mod/Fem/Gui/FemGuiTools.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#include +#include +#include +#include +#include +#include +#endif + +#include "FemGuiTools.h" + + +namespace FemGui::GuiTools +{ + +#define PLACEMENT_CHILDREN 2 +#define CONE_CHILDREN 2 + +void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r) +{ + SoTranslation* trans = new SoTranslation(); + trans->translation.setValue(base); + sep->addChild(trans); + SoRotation* rot = new SoRotation(); + rot->rotation.setValue(r); + sep->addChild(rot); +} + +void updatePlacement(const SoSeparator* sep, + const int idx, + const SbVec3f& base, + const SbRotation& r) +{ + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(base); + SoRotation* rot = static_cast(sep->getChild(idx + 1)); + rot->rotation.setValue(r); +} + +void createCone(SoSeparator* sep, const double height, const double radius) +{ + // Adjust cone so that the tip is on base + SoTranslation* trans = new SoTranslation(); + trans->translation.setValue(SbVec3f(0, -height / 2, 0)); + sep->addChild(trans); + SoCone* cone = new SoCone(); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); + sep->addChild(cone); +} + +SoSeparator* createCone(const double height, const double radius) +{ + // Create a new cone node + SoSeparator* sep = new SoSeparator(); + createCone(sep, height, radius); + return sep; +} + +void updateCone(const SoNode* node, const int idx, const double height, const double radius) +{ + const SoSeparator* sep = static_cast(node); + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(SbVec3f(0, -height / 2, 0)); + SoCone* cone = static_cast(sep->getChild(idx + 1)); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); +} + +void createCylinder(SoSeparator* sep, const double height, const double radius) +{ + SoCylinder* cyl = new SoCylinder(); + cyl->height.setValue(height); + cyl->radius.setValue(radius); + sep->addChild(cyl); +} + +SoSeparator* createCylinder(const double height, const double radius) +{ + // Create a new cylinder node + SoSeparator* sep = new SoSeparator(); + createCylinder(sep, height, radius); + return sep; +} + +void updateCylinder(const SoNode* node, const int idx, const double height, const double radius) +{ + const SoSeparator* sep = static_cast(node); + SoCylinder* cyl = static_cast(sep->getChild(idx)); + cyl->height.setValue(height); + cyl->radius.setValue(radius); +} + +void createCube(SoSeparator* sep, const double width, const double length, const double height) +{ + SoCube* cube = new SoCube(); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); + sep->addChild(cube); +} + +SoSeparator* createCube(const double width, const double length, const double height) +{ + SoSeparator* sep = new SoSeparator(); + createCube(sep, width, length, height); + return sep; +} + +void updateCube(const SoNode* node, + const int idx, + const double width, + const double length, + const double height) +{ + const SoSeparator* sep = static_cast(node); + SoCube* cube = static_cast(sep->getChild(idx)); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); +} + +void createArrow(SoSeparator* sep, const double length, const double radius) +{ + createCone(sep, radius, radius / 2); + createPlacement(sep, SbVec3f(0, -radius / 2 - (length - radius) / 2, 0), SbRotation()); + createCylinder(sep, length - radius, radius / 5); +} + +SoSeparator* createArrow(const double length, const double radius) +{ + SoSeparator* sep = new SoSeparator(); + createArrow(sep, length, radius); + return sep; +} + +void updateArrow(const SoNode* node, const int idx, const double length, const double radius) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, radius, radius / 2); + updatePlacement(sep, + idx + CONE_CHILDREN, + SbVec3f(0, -radius / 2 - (length - radius) / 2, 0), + SbRotation()); + updateCylinder(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, length - radius, radius / 5); +} + +void createFixed(SoSeparator* sep, const double height, const double width, const bool gap) +{ + createCone(sep, height - width / 4, height - width / 4); + createPlacement( + sep, + SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0), + SbRotation()); + createCube(sep, width, width, width / 4); +} + +SoSeparator* createFixed(const double height, const double width, const bool gap) +{ + SoSeparator* sep = new SoSeparator(); + createFixed(sep, height, width, gap); + return sep; +} + +void updateFixed(const SoNode* node, + const int idx, + const double height, + const double width, + const bool gap) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, height - width / 4, height - width / 4); + updatePlacement( + sep, + idx + CONE_CHILDREN, + SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0), + SbRotation()); + updateCube(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, width, width, width / 4); +} + +} // namespace FemGui::GuiTools diff --git a/src/Mod/Fem/Gui/FemGuiTools.h b/src/Mod/Fem/Gui/FemGuiTools.h new file mode 100644 index 0000000000..59d61421c1 --- /dev/null +++ b/src/Mod/Fem/Gui/FemGuiTools.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef FEM_GUI_TOOLS_H +#define FEM_GUI_TOOLS_H + +#include +#include + + +class SoNode; +class SoSeparator; + +namespace FemGui +{ + +namespace GuiTools +{ + +void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r); +void updatePlacement(const SoSeparator* sep, + const int idx, + const SbVec3f& base, + const SbRotation& r); +void createCone(SoSeparator* sep, const double height, const double radius); +SoSeparator* createCone(const double height, const double radius); +void updateCone(const SoNode* node, const int idx, const double height, const double radius); +void createCylinder(SoSeparator* sep, const double height, const double radius); +SoSeparator* createCylinder(const double height, const double radius); +void updateCylinder(const SoNode* node, const int idx, const double height, const double radius); +void createCube(SoSeparator* sep, const double width, const double length, const double height); +SoSeparator* createCube(const double width, const double length, const double height); +void updateCube(const SoNode* node, + const int idx, + const double width, + const double length, + const double height); +void createArrow(SoSeparator* sep, const double length, const double radius); +SoSeparator* createArrow(const double length, const double radius); +void updateArrow(const SoNode* node, const int idx, const double length, const double radius); +void createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false); +SoSeparator* createFixed(const double height, const double width, const bool gap = false); +void updateFixed(const SoNode* node, + const int idx, + const double height, + const double width, + const bool gap = false); + +} // namespace GuiTools + +} // namespace FemGui + + +#endif // FEM_GUI_TOOLS_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp index cf567600c3..a9310215a4 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (c) 2013 Jan Rheinländer * * * + * Copyright (c) 2024 Mario Passaglia * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,17 +25,12 @@ #include "PreCompiled.h" #ifndef _PreComp_ -#include -#include -#include #include #include #include -#include #include #include #include -#include #include #include #include @@ -318,348 +314,7 @@ PyObject* ViewProviderFemConstraint::getPyObject() pyViewObject->IncRef(); return pyViewObject; } -/* -// Create a local coordinate system with the z-axis given in dir -void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x) -{ - // Find the y axis in an arbitrary direction, normal to z - // Conditions: - // y1 * z1 + y2 * z2 + y3 * z3 = |y| |z| cos(90°) = 0 - // |y| = sqrt(y1^2 + y2^2 + y3^2) = 1 - float z1, z2, z3; - z.getValue(z1, z2, z3); - float y1, y2, y3; - if (fabs(z1) > Precision::Confusion()) { - // Choose: y3 = 0 - // Solution: - // y1 * z1 + y2 * z2 = 0 - // y1 = - z2/z1 y2 - // sqrt(z2^2/z1^2 y2^2 + y2^2) = 1 - // y2^2 ( 1 + z2^2/z1^2)) = +-1 -> choose +1 otherwise no solution - // y2 = +- sqrt(1 / (1 + z2^2/z1^2)) - y3 = 0; - y2 = sqrt(1 / (1 + z2*z2 / (z1*z1))); - y1 = -z2/z1 * y2; - // Note: result might be (0, 1, 0) - } else if (fabs(z2) > Precision::Confusion()) { - // Given: z1 = 0 - // Choose: y1 = 0 - // Solution: - // y2 * z2 + y3 * z3 = 0 - // y2 = - z3/z2 y3 - // sqrt(z3^2/z2^2 y3^3 + y3^2) = 1 - // y3^2 (1 + z3^2/z2^2)) = +1 - // y3 = +- sqrt(1 / (1 + z3^2/z2^2)) - y1 = 0; - y3 = sqrt(1 / (1 + z3*z3 / (z2*z2))); - y2 = -z3/z2 * y3; - // Note: result might be (0, 0, 1) - } else if (fabs(z3) > Precision::Confusion()) { - // Given: z1 = z2 = 0 - // Choose the remaining possible axis - y1 = 1; - y2 = 0; - y3 = 0; - } - y = SbVec3f(y1, y2, y3); - x = y.cross(z); -} -*/ -#define PLACEMENT_CHILDREN 2 - -void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, - const SbVec3f& base, - const SbRotation& r) -{ - SoTranslation* trans = new SoTranslation(); - trans->translation.setValue(base); - sep->addChild(trans); - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(r); - sep->addChild(rot); -} - -void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, - const int idx, - const SbVec3f& base, - const SbRotation& r) -{ - SoTranslation* trans = static_cast(sep->getChild(idx)); - trans->translation.setValue(base); - SoRotation* rot = static_cast(sep->getChild(idx + 1)); - rot->rotation.setValue(r); -} - -#define CONE_CHILDREN 2 - -void ViewProviderFemConstraint::createCone(SoSeparator* sep, - const double height, - const double radius) -{ - // Adjust cone so that the tip is on base - SoTranslation* trans = new SoTranslation(); - trans->translation.setValue(SbVec3f(0, -height / 2, 0)); - sep->addChild(trans); - SoCone* cone = new SoCone(); - cone->height.setValue(height); - cone->bottomRadius.setValue(radius); - sep->addChild(cone); -} - -SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius) -{ - // Create a new cone node - SoSeparator* sep = new SoSeparator(); - createCone(sep, height, radius); - return sep; -} - -void ViewProviderFemConstraint::updateCone(const SoNode* node, - const int idx, - const double height, - const double radius) -{ - const SoSeparator* sep = static_cast(node); - SoTranslation* trans = static_cast(sep->getChild(idx)); - trans->translation.setValue(SbVec3f(0, -height / 2, 0)); - SoCone* cone = static_cast(sep->getChild(idx + 1)); - cone->height.setValue(height); - cone->bottomRadius.setValue(radius); -} - -#define CYLINDER_CHILDREN 1 - -void ViewProviderFemConstraint::createCylinder(SoSeparator* sep, - const double height, - const double radius) -{ - SoCylinder* cyl = new SoCylinder(); - cyl->height.setValue(height); - cyl->radius.setValue(radius); - sep->addChild(cyl); -} - -SoSeparator* ViewProviderFemConstraint::createCylinder(const double height, const double radius) -{ - // Create a new cylinder node - SoSeparator* sep = new SoSeparator(); - createCylinder(sep, height, radius); - return sep; -} - -void ViewProviderFemConstraint::updateCylinder(const SoNode* node, - const int idx, - const double height, - const double radius) -{ - const SoSeparator* sep = static_cast(node); - SoCylinder* cyl = static_cast(sep->getChild(idx)); - cyl->height.setValue(height); - cyl->radius.setValue(radius); -} - -#define CUBE_CHILDREN 1 - -void ViewProviderFemConstraint::createCube(SoSeparator* sep, - const double width, - const double length, - const double height) -{ - SoCube* cube = new SoCube(); - cube->width.setValue(width); - cube->depth.setValue(length); - cube->height.setValue(height); - sep->addChild(cube); -} - -SoSeparator* -ViewProviderFemConstraint::createCube(const double width, const double length, const double height) -{ - SoSeparator* sep = new SoSeparator(); - createCube(sep, width, length, height); - return sep; -} - -void ViewProviderFemConstraint::updateCube(const SoNode* node, - const int idx, - const double width, - const double length, - const double height) -{ - const SoSeparator* sep = static_cast(node); - SoCube* cube = static_cast(sep->getChild(idx)); - cube->width.setValue(width); - cube->depth.setValue(length); - cube->height.setValue(height); -} - -#define ARROW_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN) - -void ViewProviderFemConstraint::createArrow(SoSeparator* sep, - const double length, - const double radius) -{ - createCone(sep, radius, radius / 2); - createPlacement(sep, SbVec3f(0, -radius / 2 - (length - radius) / 2, 0), SbRotation()); - createCylinder(sep, length - radius, radius / 5); -} - -SoSeparator* ViewProviderFemConstraint::createArrow(const double length, const double radius) -{ - SoSeparator* sep = new SoSeparator(); - createArrow(sep, length, radius); - return sep; -} - -void ViewProviderFemConstraint::updateArrow(const SoNode* node, - const int idx, - const double length, - const double radius) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, radius, radius / 2); - updatePlacement(sep, - idx + CONE_CHILDREN, - SbVec3f(0, -radius / 2 - (length - radius) / 2, 0), - SbRotation()); - updateCylinder(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, length - radius, radius / 5); -} - -#define SPRING_CHILDREN (CUBE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN) - -void ViewProviderFemConstraint::createSpring(SoSeparator* sep, - const double length, - const double width) -{ - createCube(sep, width, width, length / 2); - createPlacement(sep, SbVec3f(0, -length / 2, 0), SbRotation()); - createCylinder(sep, length / 2, width / 4); -} - -SoSeparator* ViewProviderFemConstraint::createSpring(const double length, const double width) -{ - SoSeparator* sep = new SoSeparator(); - createSpring(sep, length, width); - return sep; -} - -void ViewProviderFemConstraint::updateSpring(const SoNode* node, - const int idx, - const double length, - const double width) -{ - const SoSeparator* sep = static_cast(node); - updateCube(sep, idx, width, width, length / 2); - updatePlacement(sep, idx + CUBE_CHILDREN, SbVec3f(0, -length / 2, 0), SbRotation()); - updateCylinder(sep, idx + CUBE_CHILDREN + PLACEMENT_CHILDREN, length / 2, width / 4); -} - -#define FIXED_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CUBE_CHILDREN) - -void ViewProviderFemConstraint::createFixed(SoSeparator* sep, - const double height, - const double width, - const bool gap) -{ - createCone(sep, height - width / 4, height - width / 4); - createPlacement( - sep, - SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0), - SbRotation()); - createCube(sep, width, width, width / 4); -} - -SoSeparator* -ViewProviderFemConstraint::createFixed(const double height, const double width, const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createFixed(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateFixed(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, height - width / 4, height - width / 4); - updatePlacement( - sep, - idx + CONE_CHILDREN, - SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0), - SbRotation()); - updateCube(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, width, width, width / 4); -} - -void ViewProviderFemConstraint::createDisplacement(SoSeparator* sep, - const double height, - const double width, - const bool gap) -{ - createCone(sep, height, width); - createPlacement(sep, - SbVec3f(0, -(height) / 2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0), - SbRotation()); -} - -SoSeparator* ViewProviderFemConstraint::createDisplacement(const double height, - const double width, - const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createDisplacement(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateDisplacement(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, height, width); - updatePlacement(sep, - idx + CONE_CHILDREN, - SbVec3f(0, -(height) / 2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0), - SbRotation()); -} - -void ViewProviderFemConstraint::createRotation(SoSeparator* sep, - const double height, - const double width, - const bool gap) -{ - createCylinder(sep, width / 2, height / 2); - createPlacement(sep, - SbVec3f(0, -(height)*2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0), - SbRotation()); -} - -SoSeparator* -ViewProviderFemConstraint::createRotation(const double height, const double width, const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createRotation(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateRotation(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCylinder(sep, idx, height / 2, width / 2); - updatePlacement(sep, - idx + CYLINDER_CHILDREN, - SbVec3f(0, -(height)*2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0), - SbRotation()); -} QObject* ViewProviderFemConstraint::findChildByName(const QObject* parent, const QString& name) { diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h index e887981291..e9537c6793 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h @@ -1,6 +1,7 @@ /*************************************************************************** * Copyright (c) 2013 Jan Rheinländer * * * + * Copyright (c) 2024 Mario Passaglia * * * * This file is part of the FreeCAD CAx development system. * * * @@ -98,67 +99,6 @@ protected: transformSymbol(const Base::Vector3d& point, const Base::Vector3d& normal, SbMatrix& mat) const; virtual void transformExtraSymbol() const; - static void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r); - static void updatePlacement(const SoSeparator* sep, - const int idx, - const SbVec3f& base, - const SbRotation& r); - static void createCone(SoSeparator* sep, const double height, const double radius); - static SoSeparator* createCone(const double height, const double radius); - static void - updateCone(const SoNode* node, const int idx, const double height, const double radius); - static void createCylinder(SoSeparator* sep, const double height, const double radius); - static SoSeparator* createCylinder(const double height, const double radius); - static void - updateCylinder(const SoNode* node, const int idx, const double height, const double radius); - static void - createCube(SoSeparator* sep, const double width, const double length, const double height); - static SoSeparator* createCube(const double width, const double length, const double height); - static void updateCube(const SoNode* node, - const int idx, - const double width, - const double length, - const double height); - static void createArrow(SoSeparator* sep, const double length, const double radius); - static SoSeparator* createArrow(const double length, const double radius); - static void - updateArrow(const SoNode* node, const int idx, const double length, const double radius); - static void createSpring(SoSeparator* sep, const double length, const double width); - static SoSeparator* createSpring(const double length, const double width); - static void - updateSpring(const SoNode* node, const int idx, const double length, const double width); - static void - createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false); - static SoSeparator* - createFixed(const double height, const double width, const bool gap = false); - static void updateFixed(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap = false); - static void createDisplacement(SoSeparator* sep, - const double height, - const double width, - const bool gap = false); - static SoSeparator* - createDisplacement(const double height, const double width, const bool gap = false); - static void updateDisplacement(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap = false); - static void createRotation(SoSeparator* sep, - const double height, - const double width, - const bool gap = false); - static SoSeparator* - createRotation(const double height, const double width, const bool gap = false); - static void updateRotation(const SoNode* node, - const int idx, - const double height, - const double width, - const bool gap = false); - private: bool rotateSymbol; diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp index 4da4bbcfe9..02550bdc7e 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp @@ -31,6 +31,7 @@ #endif #include "Gui/Control.h" +#include "FemGuiTools.h" #include "TaskFemConstraintBearing.h" #include "ViewProviderFemConstraintBearing.h" #include @@ -131,9 +132,10 @@ void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) SbVec3f dir(normal.x, normal.y, normal.z); SbRotation rot(SbVec3f(0, -1, 0), dir); - createPlacement(pShapeSep, b, rot); - pShapeSep->addChild( - createFixed(radius / 2, radius / 2 * 1.5, pcConstraint->AxialFree.getValue())); + GuiTools::createPlacement(pShapeSep, b, rot); + pShapeSep->addChild(GuiTools::createFixed(radius / 2, + radius / 2 * 1.5, + pcConstraint->AxialFree.getValue())); } else if (prop == &pcConstraint->AxialFree) { if (pShapeSep->getNumChildren() > 0) { @@ -147,9 +149,13 @@ void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) SbVec3f dir(normal.x, normal.y, normal.z); SbRotation rot(SbVec3f(0, -1, 0), dir); - updatePlacement(pShapeSep, 0, b, rot); + GuiTools::updatePlacement(pShapeSep, 0, b, rot); const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateFixed(sep, 0, radius / 2, radius / 2 * 1.5, pcConstraint->AxialFree.getValue()); + GuiTools::updateFixed(sep, + 0, + radius / 2, + radius / 2 * 1.5, + pcConstraint->AxialFree.getValue()); } } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp index 2c18ed9ad2..f31a7c6fec 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFluidBoundary.cpp @@ -35,6 +35,7 @@ #include "Gui/Control.h" #include +#include "FemGuiTools.h" #include "TaskFemConstraintFluidBoundary.h" #include "ViewProviderFemConstraintFluidBoundary.h" @@ -157,7 +158,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro if (pShapeSep->getNumChildren() == 0) { // Set up the nodes cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling + cp->addChild( + (SoNode*)GuiTools::createArrow(scaledlength, scaledheadradius)); // OvG: Scaling pShapeSep->addChild(cp); } #endif @@ -199,8 +201,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro idx++; #else SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling + GuiTools::createPlacement(sep, base, rot); + GuiTools::createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling pShapeSep->addChild(sep); #endif } @@ -243,8 +245,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro matrices[idx] = m; #else SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); - updatePlacement(sep, 0, base, rot); - updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling + GuiTools::updatePlacement(sep, 0, base, rot); + GuiTools::updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling #endif idx++; } @@ -261,7 +263,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro if (pShapeSep->getNumChildren() == 0) { // Set up the nodes cp->matrix.setNum(0); - cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); // OvG: Scaling + cp->addChild( + (SoNode*)GuiTools::createFixed(scaledheight, scaledwidth)); // OvG: Scaling pShapeSep->addChild(cp); } #endif @@ -295,8 +298,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro idx++; #else SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling + GuiTools::createPlacement(sep, base, rot); + GuiTools::createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling pShapeSep->addChild(sep); #endif n++; diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp index e0f860f73f..25773e78bd 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp @@ -36,6 +36,7 @@ #include #include +#include "FemGuiTools.h" #include "TaskFemConstraintGear.h" #include "ViewProviderFemConstraintGear.h" @@ -139,12 +140,13 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop) // Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y, // direction.z); - createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax)); - pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2)); - createPlacement(pShapeSep, - SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), - SbRotation(ax, dir)); - pShapeSep->addChild(createArrow(dia / 2, dia / 8)); + GuiTools::createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax)); + pShapeSep->addChild( + GuiTools::createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2)); + GuiTools::createPlacement(pShapeSep, + SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), + SbRotation(ax, dir)); + pShapeSep->addChild(GuiTools::createArrow(dia / 2, dia / 8)); } } else if (prop == &pcConstraint->Diameter) { @@ -166,13 +168,13 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop) SbVec3f dir(direction.x, direction.y, direction.z); const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2); - updatePlacement(pShapeSep, - 3, - SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), - SbRotation(ax, dir)); + GuiTools::updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2); + GuiTools::updatePlacement(pShapeSep, + 3, + SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), + SbRotation(ax, dir)); sep = static_cast(pShapeSep->getChild(5)); - updateArrow(sep, 0, dia / 2, dia / 8); + GuiTools::updateArrow(sep, 0, dia / 2, dia / 8); } } else if ((prop == &pcConstraint->DirectionVector) || (prop == &pcConstraint->ForceAngle)) { @@ -203,10 +205,10 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop) directions!) */ - updatePlacement(pShapeSep, - 3, - SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), - SbRotation(ax, dir)); + GuiTools::updatePlacement(pShapeSep, + 3, + SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)), + SbRotation(ax, dir)); } } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp index dc206ebc22..5892a50f52 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp @@ -32,6 +32,7 @@ #endif #include "Gui/Control.h" +#include "FemGuiTools.h" #include "TaskFemConstraintPulley.h" #include "ViewProviderFemConstraintPulley.h" #include @@ -138,32 +139,34 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) SbVec3f b(base.x, base.y, base.z); SbVec3f ax(axis.x, axis.y, axis.z); - createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax)); // child 0 and 1 - pShapeSep->addChild( - createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2)); // child 2 + GuiTools::createPlacement(pShapeSep, + b, + SbRotation(SbVec3f(0, 1, 0), ax)); // child 0 and 1 + pShapeSep->addChild(GuiTools::createCylinder(pcConstraint->Height.getValue() * 0.8, + dia / 2)); // child 2 SoSeparator* sep = new SoSeparator(); - createPlacement(sep, - SbVec3f(dia / 2 * sin(forceAngle + beltAngle), - 0, - dia / 2 * cos(forceAngle + beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(sin(forceAngle + beltAngle + M_PI_2), - 0, - cos(forceAngle + beltAngle + M_PI_2)))); - createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation()); - sep->addChild(createArrow(dia / 8 + dia / 2 * rat1, dia / 8)); + GuiTools::createPlacement(sep, + SbVec3f(dia / 2 * sin(forceAngle + beltAngle), + 0, + dia / 2 * cos(forceAngle + beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(sin(forceAngle + beltAngle + M_PI_2), + 0, + cos(forceAngle + beltAngle + M_PI_2)))); + GuiTools::createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation()); + sep->addChild(GuiTools::createArrow(dia / 8 + dia / 2 * rat1, dia / 8)); pShapeSep->addChild(sep); // child 3 sep = new SoSeparator(); - createPlacement(sep, - SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), - 0, - -dia / 2 * cos(forceAngle - beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), - 0, - -cos(forceAngle - beltAngle - M_PI_2)))); - createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation()); - sep->addChild(createArrow(dia / 8 + dia / 2 * rat2, dia / 8)); + GuiTools::createPlacement(sep, + SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), + 0, + -dia / 2 * cos(forceAngle - beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), + 0, + -cos(forceAngle - beltAngle - M_PI_2)))); + GuiTools::createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation()); + sep->addChild(GuiTools::createArrow(dia / 8 + dia / 2 * rat2, dia / 8)); pShapeSep->addChild(sep); // child 4 } } @@ -186,33 +189,39 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) } const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2); + GuiTools::updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2); sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, - 0, - SbVec3f(dia / 2 * sin(forceAngle + beltAngle), - 0, - dia / 2 * cos(forceAngle + beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(sin(forceAngle + beltAngle + M_PI_2), - 0, - cos(forceAngle + beltAngle + M_PI_2)))); - updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation()); + GuiTools::updatePlacement(sep, + 0, + SbVec3f(dia / 2 * sin(forceAngle + beltAngle), + 0, + dia / 2 * cos(forceAngle + beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(sin(forceAngle + beltAngle + M_PI_2), + 0, + cos(forceAngle + beltAngle + M_PI_2)))); + GuiTools::updatePlacement(sep, + 2, + SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), + SbRotation()); const SoSeparator* subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8); + GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8); sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, - 0, - SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), - 0, - -dia / 2 * cos(forceAngle - beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), - 0, - -cos(forceAngle - beltAngle - M_PI_2)))); - updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation()); + GuiTools::updatePlacement(sep, + 0, + SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), + 0, + -dia / 2 * cos(forceAngle - beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), + 0, + -cos(forceAngle - beltAngle - M_PI_2)))); + GuiTools::updatePlacement(sep, + 2, + SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), + SbRotation()); subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8); + GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8); } } else if ((prop == &pcConstraint->ForceAngle) || (prop == &pcConstraint->BeltAngle)) { @@ -226,25 +235,25 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) double beltAngle = pcConstraint->BeltAngle.getValue(); const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, - 0, - SbVec3f(dia / 2 * sin(forceAngle + beltAngle), - 0, - dia / 2 * cos(forceAngle + beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(sin(forceAngle + beltAngle + M_PI_2), - 0, - cos(forceAngle + beltAngle + M_PI_2)))); + GuiTools::updatePlacement(sep, + 0, + SbVec3f(dia / 2 * sin(forceAngle + beltAngle), + 0, + dia / 2 * cos(forceAngle + beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(sin(forceAngle + beltAngle + M_PI_2), + 0, + cos(forceAngle + beltAngle + M_PI_2)))); sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, - 0, - SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), - 0, - -dia / 2 * cos(forceAngle - beltAngle)), - SbRotation(SbVec3f(0, 1, 0), - SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), - 0, - -cos(forceAngle - beltAngle - M_PI_2)))); + GuiTools::updatePlacement(sep, + 0, + SbVec3f(-dia / 2 * sin(forceAngle - beltAngle), + 0, + -dia / 2 * cos(forceAngle - beltAngle)), + SbRotation(SbVec3f(0, 1, 0), + SbVec3f(-sin(forceAngle - beltAngle - M_PI_2), + 0, + -cos(forceAngle - beltAngle - M_PI_2)))); } } else if ((prop == &pcConstraint->BeltForce1) || (prop == &pcConstraint->BeltForce2)) { @@ -263,13 +272,19 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) } const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation()); + GuiTools::updatePlacement(sep, + 2, + SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), + SbRotation()); const SoSeparator* subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8); + GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8); sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation()); + GuiTools::updatePlacement(sep, + 2, + SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), + SbRotation()); subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8); + GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8); } } From 25febcd7afe9d681f532dcdf46e4e19d4ee19859 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Wed, 29 May 2024 00:36:04 -0300 Subject: [PATCH 2/4] Fem: Move functions to Tools class --- src/Mod/Fem/App/FemConstraint.cpp | 93 +++++------------------- src/Mod/Fem/App/FemConstraint.h | 10 --- src/Mod/Fem/App/FemConstraintBearing.cpp | 27 +++++-- src/Mod/Fem/App/FemTools.cpp | 76 +++++++++++++++++++ src/Mod/Fem/App/FemTools.h | 31 +++++++- 5 files changed, 144 insertions(+), 93 deletions(-) diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index 8609d1e722..2ea98ec940 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -147,18 +147,6 @@ 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 - // feature placement. - Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation()); - Base::Placement shPla {matrix}; - Base::Placement featlPlaInv = feat->Placement.getValue().inverse(); - Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla; - - sh.Location(Part::Tools::fromPlacement(shGlobalPla)); -} - constexpr int CONSTRAINTSTEPLIMIT = 50; void Constraint::onChanged(const App::Property* prop) @@ -177,26 +165,20 @@ void Constraint::onChanged(const App::Property* prop) for (std::size_t i = 0; i < Objects.size(); i++) { App::DocumentObject* obj = Objects[i]; Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (!toposhape.getShape().IsNull()) { - sh = toposhape.getSubShape(SubElements[i].c_str(), !execute); - - if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) { - setSubShapeLocation(feat, sh); - - // Get face normal in center point - TopoDS_Face face = TopoDS::Face(sh); - BRepGProp_Face props(face); - gp_Vec normal; - gp_Pnt center; - double u1, u2, v1, v2; - props.Bounds(u1, u2, v1, v2); - props.Normal((u1 + u2) / 2.0, (v1 + v2) / 2.0, center, normal); - normal.Normalize(); - NormalDirection.setValue(normal.X(), normal.Y(), normal.Z()); - // One face is enough... - break; - } + sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), !execute); + if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) { + // Get face normal in center point + TopoDS_Face face = TopoDS::Face(sh); + BRepGProp_Face props(face); + gp_Vec normal; + gp_Pnt center; + double u1, u2, v1, v2; + props.Bounds(u1, u2, v1, v2); + props.Normal((u1 + u2) / 2.0, (v1 + v2) / 2.0, center, normal); + normal.Normalize(); + NormalDirection.setValue(normal.X(), normal.Y(), normal.Z()); + // One face is enough... + break; } } @@ -274,22 +256,15 @@ bool Constraint::getPoints(std::vector& points, TopoDS_Shape sh; for (std::size_t i = 0; i < Objects.size(); i++) { - App::DocumentObject* obj = Objects[i]; - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (toposhape.isNull()) { - return false; - } - - sh = toposhape.getSubShape(SubElements[i].c_str(), true); + Part::Feature* feat = static_cast(Objects[i]); + sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), true); if (sh.IsNull()) { return false; } - setSubShapeLocation(feat, sh); // Scale by bounding box of the object Bnd_Box box; - BRepBndLib::Add(toposhape.getShape(), box); + BRepBndLib::Add(feat->Shape.getShape().getShape(), box); double l = sqrt(box.SquareExtent() / 3.0); *scale = this->calcSizeFactor(l); @@ -471,40 +446,6 @@ bool Constraint::getPoints(std::vector& points, return true; } -bool Constraint::getCylinder(double& radius, - double& height, - Base::Vector3d& base, - Base::Vector3d& axis) const -{ - std::vector Objects = References.getValues(); - std::vector SubElements = References.getSubValues(); - if (Objects.empty()) { - return false; - } - App::DocumentObject* obj = Objects[0]; - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (toposhape.isNull()) { - return false; - } - TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str()); - - TopoDS_Face face = TopoDS::Face(sh); - BRepAdaptor_Surface surface(face); - gp_Cylinder cyl = surface.Cylinder(); - gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter()); - gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter()); - height = start.Distance(end); - radius = cyl.Radius(); - - gp_Pnt b = cyl.Location(); - base = Base::Vector3d(b.X(), b.Y(), b.Z()); - gp_Dir dir = cyl.Axis().Direction(); - axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z()); - - return true; -} - Base::Vector3d Constraint::getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, const App::PropertyLinkSub& location, diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index 1c86166a89..1e70cf1b06 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -198,16 +198,6 @@ protected: std::vector& normals, double* scale) const; - /** - * @brief Extract properties of cylindrical face. - * - * @note - * This method is very specific and doesn't require access to member - * variables. It should be rewritten at a different place. - */ - bool - getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const; - /** * @brief Calculate point of cylindrical face where to render widget. * diff --git a/src/Mod/Fem/App/FemConstraintBearing.cpp b/src/Mod/Fem/App/FemConstraintBearing.cpp index 69a06a86c0..fb87cff984 100644 --- a/src/Mod/Fem/App/FemConstraintBearing.cpp +++ b/src/Mod/Fem/App/FemConstraintBearing.cpp @@ -32,7 +32,7 @@ #include #include "FemConstraintBearing.h" - +#include "FemTools.h" using namespace Fem; @@ -74,9 +74,17 @@ void ConstraintBearing::onChanged(const App::Property* prop) if (prop == &References) { // Find data of cylinder + std::vector ref = References.getValues(); + std::vector subRef = References.getSubValues(); + if (ref.empty()) { + return; + } + + Part::Feature* feat = static_cast(ref.front()); + TopoDS_Shape sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true); double radius, height; Base::Vector3d base, axis; - if (!getCylinder(radius, height, base, axis)) { + if (!Tools::getCylinderParams(sh, base, axis, height, radius)) { return; } Radius.setValue(radius); @@ -113,12 +121,19 @@ void ConstraintBearing::onChanged(const App::Property* prop) } } - double radius, height; - Base::Vector3d base, axis; - if (!getCylinder(radius, height, base, axis)) { + std::vector ref = References.getValues(); + std::vector subRef = References.getSubValues(); + if (ref.empty()) { + return; + } + + feat = static_cast(ref.front()); + sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true); + double radius, height; + Base::Vector3d base, axis; + if (!Tools::getCylinderParams(sh, base, axis, height, radius)) { return; } - base = getBasePoint(base + axis * height / 2, axis, Location, Dist.getValue()); BasePoint.setValue(base); BasePoint.touch(); } diff --git a/src/Mod/Fem/App/FemTools.cpp b/src/Mod/Fem/App/FemTools.cpp index 585e62c559..3739f2c42e 100644 --- a/src/Mod/Fem/App/FemTools.cpp +++ b/src/Mod/Fem/App/FemTools.cpp @@ -27,16 +27,19 @@ #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -44,6 +47,8 @@ #endif #include +#include +#include #include "FemTools.h" @@ -322,3 +327,74 @@ std::string Fem::Tools::checkIfBinaryExists(std::string prefSection, } return ""; } + +Base::Placement Fem::Tools::getSubShapeGlobalLocation(const Part::Feature* feat, + const TopoDS_Shape& sh) +{ + Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation()); + Base::Placement shPla {matrix}; + Base::Placement featlPlaInv = feat->Placement.getValue().inverse(); + Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla; + + return shGlobalPla; +} + +void Fem::Tools::setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh) +{ + Base::Placement pla = getSubShapeGlobalLocation(feat, sh); + sh.Location(Part::Tools::fromPlacement(pla)); +} + + +TopoDS_Shape +Fem::Tools::getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent) +{ + TopoDS_Shape sh; + const Part::TopoShape& toposhape = feat->Shape.getShape(); + if (toposhape.isNull()) { + return sh; + } + + sh = toposhape.getSubShape(subName, silent); + if (sh.IsNull()) { + return sh; + } + + setSubShapeGlobalLocation(feat, sh); + + return sh; +} + +bool Fem::Tools::getCylinderParams(const TopoDS_Shape& sh, + Base::Vector3d& base, + Base::Vector3d& axis, + double& height, + double& radius) +{ + TopoDS_Face face = TopoDS::Face(sh); + BRepAdaptor_Surface surface(face); + if (!(surface.GetType() == GeomAbs_Cylinder)) { + return false; + } + + gp_Cylinder cyl = surface.Cylinder(); + gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter()); + gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter()); + + Handle(Geom_Curve) handle = new Geom_Line(cyl.Axis()); + GeomAPI_ProjectPointOnCurve proj(start, handle); + gp_XYZ startProj = proj.NearestPoint().XYZ(); + proj.Perform(end); + gp_XYZ endProj = proj.NearestPoint().XYZ(); + + gp_XYZ ax(endProj - startProj); + gp_XYZ center = (startProj + endProj) / 2.0; + gp_Dir dir(ax); + + height = ax.Modulus(); + radius = cyl.Radius(); + base = Base::Vector3d(center.X(), center.Y(), center.Z()); + axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z()); + + return true; +} diff --git a/src/Mod/Fem/App/FemTools.h b/src/Mod/Fem/App/FemTools.h index d5397df0df..fd6388b1cc 100644 --- a/src/Mod/Fem/App/FemTools.h +++ b/src/Mod/Fem/App/FemTools.h @@ -24,14 +24,22 @@ #ifndef FEM_TOOLS_H #define FEM_TOOLS_H +#include #include #include #include +#include -class TopoDS_Shape; class TopoDS_Edge; class TopoDS_Face; +namespace Part +{ + +class Feature; + +} + namespace Fem { @@ -75,6 +83,27 @@ public: static std::string checkIfBinaryExists(std::string prefSection, std::string prefBinaryPath, std::string prefBinaryName); + + /*! + Subshape placement is not necessarily the same as the + feature placement + */ + static Base::Placement getSubShapeGlobalLocation(const Part::Feature* feat, + const TopoDS_Shape& sh); + static void setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh); + /*! + Get subshape from Part Feature. The subShape is returned with global location + */ + static TopoDS_Shape + getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent); + /*! + Get cylinder parameters. Base is located at the center of the cylinder + */ + static bool getCylinderParams(const TopoDS_Shape& sh, + Base::Vector3d& base, + Base::Vector3d& axis, + double& height, + double& radius); }; } // namespace Fem From d228d507550112e96370698937f53aeb97373409 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Tue, 28 May 2024 00:37:08 -0300 Subject: [PATCH 3/4] Fem: Update constraint transform --- src/Mod/Fem/App/FemConstraintTransform.cpp | 187 +++++++++--- src/Mod/Fem/App/FemConstraintTransform.h | 13 +- src/Mod/Fem/Gui/CMakeLists.txt | 1 + src/Mod/Fem/Gui/Command.cpp | 3 - .../Resources/symbols/ConstraintTransform.iv | 120 ++++++++ .../Fem/Gui/TaskFemConstraintTransform.cpp | 205 +++++++------ src/Mod/Fem/Gui/TaskFemConstraintTransform.h | 11 +- src/Mod/Fem/Gui/TaskFemConstraintTransform.ui | 139 +++++---- .../ViewProviderFemConstraintTransform.cpp | 276 +++++------------- .../Gui/ViewProviderFemConstraintTransform.h | 4 + .../constraint_transform_beam_hinged.py | 6 - .../constraint_transform_torque.py | 3 - .../calculix/write_constraint_transform.py | 10 +- .../constraint_transform_beam_hinged.inp | 4 +- .../calculix/constraint_transform_torque.inp | 2 +- src/Mod/Fem/femtools/geomtools.py | 49 ---- 16 files changed, 535 insertions(+), 498 deletions(-) create mode 100644 src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv diff --git a/src/Mod/Fem/App/FemConstraintTransform.cpp b/src/Mod/Fem/App/FemConstraintTransform.cpp index 163f190c60..462202649d 100644 --- a/src/Mod/Fem/App/FemConstraintTransform.cpp +++ b/src/Mod/Fem/App/FemConstraintTransform.cpp @@ -23,8 +23,10 @@ #include "PreCompiled.h" -#include "FemConstraintTransform.h" +#include +#include "FemConstraintTransform.h" +#include "FemTools.h" using namespace Fem; @@ -34,9 +36,11 @@ static const char* TransformTypes[] = {"Cylindrical", "Rectangular", nullptr}; ConstraintTransform::ConstraintTransform() { - ADD_PROPERTY(X_rot, (0.0)); - ADD_PROPERTY(Y_rot, (0.0)); - ADD_PROPERTY(Z_rot, (0.0)); + ADD_PROPERTY_TYPE(Rotation, + (Base::Rotation(0.0, 0.0, 0.0, 1.0)), + "ConstraintTransform", + App::Prop_Output, + "Rectangular system transform"); ADD_PROPERTY_TYPE(TransformType, (1), "ConstraintTransform", @@ -78,54 +82,141 @@ const char* ConstraintTransform::getViewProviderName() const return "FemGui::ViewProviderFemConstraintTransform"; } -void ConstraintTransform::handleChangedPropertyType(Base::XMLReader& reader, - const char* TypeName, - App::Property* prop) -{ - // properties _rot had App::PropertyFloat and were changed to App::PropertyAngle - if (prop == &X_rot && strcmp(TypeName, "App::PropertyFloat") == 0) { - App::PropertyFloat X_rotProperty; - X_rotProperty.Restore(reader); - X_rot.setValue(X_rotProperty.getValue()); - } - else if (prop == &Y_rot && strcmp(TypeName, "App::PropertyFloat") == 0) { - App::PropertyFloat Y_rotProperty; - Y_rotProperty.Restore(reader); - Y_rot.setValue(Y_rotProperty.getValue()); - } - else if (prop == &Z_rot && strcmp(TypeName, "App::PropertyFloat") == 0) { - App::PropertyFloat Z_rotProperty; - Z_rotProperty.Restore(reader); - Z_rot.setValue(Z_rotProperty.getValue()); - } - else { - Constraint::handleChangedPropertyType(reader, TypeName, prop); - } -} - void ConstraintTransform::onChanged(const App::Property* prop) { - Constraint::onChanged(prop); - if (prop == &References) { - std::vector points; - std::vector normals; - double scale = 1; // OvG: Enforce use of scale - if (getPoints(points, normals, &scale)) { - std::string transform_type = TransformType.getValueAsString(); - if (transform_type == "Cylindrical") { - // Find data of cylinder - double radius, height; - Base::Vector3d base, axis; - if (!getCylinder(radius, height, base, axis)) { - return; - } - Axis.setValue(axis); - // Update base point - base = base + axis * height / 2; - BasePoint.setValue(base); - BasePoint.touch(); // This triggers ViewProvider::updateData() + std::string transform_type = TransformType.getValueAsString(); + if (transform_type == "Cylindrical") { + // Extract geometry from References + std::vector ref = References.getValues(); + std::vector subRef = References.getSubValues(); + if (ref.empty()) { + return; } + + Part::Feature* feat = static_cast(ref.front()); + TopoDS_Shape sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true); + + Base::Vector3d axis, base; + double height, radius; + if (!Tools::getCylinderParams(sh, base, axis, height, radius)) { + return; + } + + BasePoint.setValue(base); + Axis.setValue(axis); } } + + Constraint::onChanged(prop); +} + +namespace +{ + +Base::Rotation anglesToRotation(double xAngle, double yAngle, double zAngle) +{ + static Base::Vector3d a(1, 0, 0); + static Base::Vector3d b(0, 1, 0); + static int count = 0; + double xRad = xAngle * D_PI / 180.0; + double yRad = yAngle * D_PI / 180.0; + double zRad = zAngle * D_PI / 180.0; + if (xAngle != 0) { + a[1] = 0; + a[2] = 0; + b[1] = std::cos(xRad); + b[2] = -std::sin(xRad); + } + if (yAngle != 0) { + a[0] = std::cos(yRad); + a[2] = std::sin(yRad); + b[0] = 0; + b[2] = 0; + } + if (zAngle != 0) { + a[0] = std::cos(zRad); + a[1] = -std::sin(zRad); + b[0] = 0; + b[1] = 0; + } + + ++count; + count %= 3; + if (!count) { + Base::Vector3d X = a.Normalize(); + Base::Vector3d Y = b.Normalize(); + Base::Vector3d Z = X.Cross(Y); + Z.Normalize(); + Y = Z.Cross(X); + + a.x = 1; + a.y = 0; + a.z = 0; + b.x = 0; + b.y = 1; + b.z = 0; + + Base::Matrix4D m; + m.setCol(0, X); + m.setCol(1, Y); + m.setCol(2, Z); + + return Base::Rotation(m); + } + return Base::Rotation(); +} + +} // namespace + + +void ConstraintTransform::handleChangedPropertyName(Base::XMLReader& reader, + const char* typeName, + const char* propName) +{ + if (strcmp(propName, "X_rot") == 0) { + double xAngle; + if (strcmp(typeName, "App::PropertyFloat") == 0) { + App::PropertyFloat X_rotProperty; + X_rotProperty.Restore(reader); + xAngle = X_rotProperty.getValue(); + } + else if (strcmp(typeName, "App::PropertyAngle") == 0) { + App::PropertyAngle X_rotProperty; + X_rotProperty.Restore(reader); + xAngle = X_rotProperty.getValue(); + } + anglesToRotation(xAngle, 0, 0); + } + else if (strcmp(propName, "Y_rot") == 0) { + double yAngle; + if (strcmp(typeName, "App::PropertyFloat") == 0) { + App::PropertyFloat Y_rotProperty; + Y_rotProperty.Restore(reader); + yAngle = Y_rotProperty.getValue(); + } + else if (strcmp(typeName, "App::PropertyAngle") == 0) { + App::PropertyAngle Y_rotProperty; + Y_rotProperty.Restore(reader); + yAngle = Y_rotProperty.getValue(); + } + anglesToRotation(0, yAngle, 0); + } + else if (strcmp(propName, "Z_rot") == 0) { + double zAngle; + if (strcmp(typeName, "App::PropertyFloat") == 0) { + App::PropertyFloat Z_rotProperty; + Z_rotProperty.Restore(reader); + zAngle = Z_rotProperty.getValue(); + } + else if (strcmp(typeName, "App::PropertyAngle") == 0) { + App::PropertyAngle Z_rotProperty; + Z_rotProperty.Restore(reader); + zAngle = Z_rotProperty.getValue(); + } + Rotation.setValue(anglesToRotation(0, 0, zAngle)); + } + else { + Constraint::handleChangedPropertyName(reader, typeName, propName); + } } diff --git a/src/Mod/Fem/App/FemConstraintTransform.h b/src/Mod/Fem/App/FemConstraintTransform.h index 3c77fc948c..ecbdbb99cf 100644 --- a/src/Mod/Fem/App/FemConstraintTransform.h +++ b/src/Mod/Fem/App/FemConstraintTransform.h @@ -42,12 +42,9 @@ public: App::PropertyLinkList NameDispl; App::PropertyVector BasePoint; App::PropertyVector Axis; - App::PropertyAngle X_rot; - App::PropertyAngle Y_rot; - App::PropertyAngle Z_rot; + + App::PropertyRotation Rotation; App::PropertyEnumeration TransformType; - // etc - /* */ /// recalculate the object App::DocumentObjectExecReturn* execute() override; @@ -56,9 +53,9 @@ public: const char* getViewProviderName() const override; protected: - void handleChangedPropertyType(Base::XMLReader& reader, - const char* TypeName, - App::Property* prop) override; + void handleChangedPropertyName(Base::XMLReader& reader, + const char* typeName, + const char* propName) override; void onChanged(const App::Property* prop) override; }; diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index 63afa186a2..6fede03fac 100755 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -366,6 +366,7 @@ SET(FemGuiSymbol_IV Resources/symbols/ConstraintSectionPrint.iv Resources/symbols/ConstraintSpring.iv Resources/symbols/ConstraintTemperature.iv + Resources/symbols/ConstraintTransform.iv Resources/symbols/ConstraintTie.iv ) diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 5cd5b29be7..2c0d734b2e 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -1002,9 +1002,6 @@ void CmdFemConstraintTransform::activated(int) doCommand(Doc, "App.activeDocument().addObject(\"Fem::ConstraintTransform\",\"%s\")", FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.X_rot = 0.0", FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.Y_rot = 0.0", FeatName.c_str()); - doCommand(Doc, "App.activeDocument().%s.Z_rot = 0.0", FeatName.c_str()); doCommand(Doc, "App.activeDocument().%s.Scale = 1", FeatName.c_str()); doCommand(Doc, "App.activeDocument().%s.addObject(App.activeDocument().%s)", diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv new file mode 100644 index 0000000000..f001b5daa1 --- /dev/null +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv @@ -0,0 +1,120 @@ +#Inventor V2.1 ascii + + +Separator { + + Separator { + DEF REC_TRANSFORM Switch { + Separator { + + BaseColor { + rgb 0.0 1.0 0.0 + + } + DEF AXIS Separator { + + Translation { + translation 0 2.5 0 + + } + Cone { + bottomRadius 0.4 + height 1.0 + + } + Translation { + translation 0 -1.5 0 + + } + Cylinder { + radius 0.15 + height 2.0 + + } + } + Separator { + + BaseColor { + rgb 1.0 0.0 0.0 + + } + Rotation { + rotation 0 0 1 -1.5707964 + + } + USE AXIS + } + + Separator { + + BaseColor { + rgb 0.0 0.0 1.0 + + } + Rotation { + rotation 1 0 0 1.5707964 + + } + USE AXIS + } + } + Separator { + + BaseColor { + rgb 1.0 0.0 0.0 + + } + Translation { + translation 0 2.5 0 + + } + Cone { + bottomRadius 0.4 + height 1.0 + + } + Translation { + translation 0 -1.5 0 + + } + Cylinder { + radius 0.15 + height 2.0 + + } + } + + } +} + Separator { + + Switch { + + Separator { + + BaseColor { + rgb 0.0 0.0 1.0 + + } + Translation { + translation 0 12.0 0 + + } + Cone { + bottomRadius 0.4 + height 1.0 + + } + Translation { + translation 0 -12.5 0 + + } + Cylinder { + radius 0.15 + height 24.0 + + } + } + } + } +} diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp b/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp index 08a0b49824..b669dee265 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp @@ -88,18 +88,22 @@ TaskFemConstraintTransform::TaskFemConstraintTransform( connect(ui->rb_rect, &QRadioButton::clicked, this, &TaskFemConstraintTransform::Rect); connect(ui->rb_cylin, &QRadioButton::clicked, this, &TaskFemConstraintTransform::Cyl); - connect(ui->sp_X, + connect(ui->spb_rot_axis_x, + qOverload(&DoubleSpinBox::valueChanged), + this, + &TaskFemConstraintTransform::xAxisChanged); + connect(ui->spb_rot_axis_y, + qOverload(&DoubleSpinBox::valueChanged), + this, + &TaskFemConstraintTransform::yAxisChanged); + connect(ui->spb_rot_axis_z, + qOverload(&DoubleSpinBox::valueChanged), + this, + &TaskFemConstraintTransform::zAxisChanged); + connect(ui->qsb_rot_angle, qOverload(&QuantitySpinBox::valueChanged), this, - &TaskFemConstraintTransform::x_Changed); - connect(ui->sp_Y, - qOverload(&QuantitySpinBox::valueChanged), - this, - &TaskFemConstraintTransform::y_Changed); - connect(ui->sp_Z, - qOverload(&QuantitySpinBox::valueChanged), - this, - &TaskFemConstraintTransform::z_Changed); + &TaskFemConstraintTransform::angleChanged); // Get the feature data Fem::ConstraintTransform* pcConstraint = @@ -109,9 +113,33 @@ TaskFemConstraintTransform::TaskFemConstraintTransform( std::vector SubElements = pcConstraint->References.getSubValues(); // Fill data into dialog elements - ui->sp_X->setValue(pcConstraint->X_rot.getQuantityValue()); - ui->sp_Y->setValue(pcConstraint->Y_rot.getQuantityValue()); - ui->sp_Z->setValue(pcConstraint->Z_rot.getQuantityValue()); + Base::Vector3d axis; + double angle; + pcConstraint->Rotation.getValue().getValue(axis, angle); + ui->spb_rot_axis_x->setValue(axis.x); + ui->spb_rot_axis_y->setValue(axis.y); + ui->spb_rot_axis_z->setValue(axis.z); + Base::Quantity rotAngle(angle, QString::fromUtf8("rad")); + ui->qsb_rot_angle->setValue(rotAngle.getValueAs(Base::Quantity::Degree)); + + ui->spb_rot_axis_x->bind( + App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.x"))); + ui->spb_rot_axis_y->bind( + App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.y"))); + ui->spb_rot_axis_z->bind( + App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.z"))); + ui->qsb_rot_angle->bind( + App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Angle"))); + + ui->spb_rot_axis_x->setMinimum(-FLOAT_MAX); + ui->spb_rot_axis_x->setMaximum(FLOAT_MAX); + ui->spb_rot_axis_y->setMinimum(-FLOAT_MAX); + ui->spb_rot_axis_y->setMaximum(FLOAT_MAX); + ui->spb_rot_axis_z->setMinimum(-FLOAT_MAX); + ui->spb_rot_axis_z->setMaximum(FLOAT_MAX); + ui->qsb_rot_angle->setMinimum(-FLOAT_MAX); + ui->qsb_rot_angle->setMaximum(FLOAT_MAX); + std::string transform_type = pcConstraint->TransformType.getValueAsString(); if (transform_type == "Rectangular") { ui->sw_transform->setCurrentIndex(0); @@ -167,11 +195,6 @@ TaskFemConstraintTransform::TaskFemConstraintTransform( this, &TaskFemConstraintTransform::removeFromSelection); - // Bind input fields to properties - ui->sp_X->bind(pcConstraint->X_rot); - ui->sp_Y->bind(pcConstraint->Y_rot); - ui->sp_Z->bind(pcConstraint->Z_rot); - updateUI(); if ((p == 0) && (!Objects.empty())) { @@ -199,43 +222,40 @@ void TaskFemConstraintTransform::updateUI() } } -void TaskFemConstraintTransform::x_Changed(int i) +void TaskFemConstraintTransform::xAxisChanged(double x) { + (void)x; + Base::Rotation rot = getRotation(); Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); - double x = i; - pcConstraint->X_rot.setValue(x); - std::string name = ConstraintView->getObject()->getNameInDocument(); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.X_rot = %f", name.c_str(), x); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - pcConstraint->References.setValues(Objects, SubElements); + pcConstraint->Rotation.setValue(rot); } -void TaskFemConstraintTransform::y_Changed(int i) +void TaskFemConstraintTransform::yAxisChanged(double y) { + (void)y; + Base::Rotation rot = getRotation(); Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); - double y = i; - pcConstraint->Y_rot.setValue(y); - std::string name = ConstraintView->getObject()->getNameInDocument(); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Y_rot = %f", name.c_str(), y); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - pcConstraint->References.setValues(Objects, SubElements); + pcConstraint->Rotation.setValue(rot); } -void TaskFemConstraintTransform::z_Changed(int i) +void TaskFemConstraintTransform::zAxisChanged(double z) { + (void)z; + Base::Rotation rot = getRotation(); Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); - double z = i; - pcConstraint->Z_rot.setValue(z); - std::string name = ConstraintView->getObject()->getNameInDocument(); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Z_rot = %f", name.c_str(), z); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - pcConstraint->References.setValues(Objects, SubElements); + pcConstraint->Rotation.setValue(rot); +} + +void TaskFemConstraintTransform::angleChanged(double a) +{ + (void)a; + Base::Rotation rot = getRotation(); + Fem::ConstraintTransform* pcConstraint = + static_cast(ConstraintView->getObject()); + pcConstraint->Rotation.setValue(rot); } void TaskFemConstraintTransform::Rect() @@ -258,9 +278,6 @@ void TaskFemConstraintTransform::Rect() void TaskFemConstraintTransform::Cyl() { ui->sw_transform->setCurrentIndex(1); - ui->sp_X->setValue(0); - ui->sp_Y->setValue(0); - ui->sp_Z->setValue(0); std::string name = ConstraintView->getObject()->getNameInDocument(); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.TransformType = %s", @@ -391,35 +408,15 @@ void TaskFemConstraintTransform::addToSelection() updateUI(); if (ui->rb_rect->isChecked()) { Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - double n = normal.x; - double m = normal.y; - double l = normal.z; - // about Z-axis - double about_z; - double mag_norm_z = sqrt(n * n + m * m); // normal vector mapped onto XY plane - if (mag_norm_z == 0) { - about_z = 0; - } - else { - about_z = (-1 * (acos(m / mag_norm_z) * 180 / M_PI) + 180); - } - if (n > 0) { - about_z = about_z * (-1); - } - // rotation to ZY plane - double m_p = n * sin(about_z * M_PI / 180) + m * cos(about_z * M_PI / 180); - double l_p = l; - // about X-axis - double about_x; - double mag_norm_x = sqrt(m_p * m_p + l_p * l_p); - if (mag_norm_x == 0) { - about_x = 0; - } - else { - about_x = -(acos(l_p / mag_norm_x) * 180 / M_PI); // rotation to the Z axis - } - ui->sp_X->setValue(round(about_x)); - ui->sp_Z->setValue(round(about_z)); + Base::Rotation rot(Base::Vector3d(0, 0, 1), normal); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + ui->spb_rot_axis_x->setValue(axis.x); + ui->spb_rot_axis_y->setValue(axis.y); + ui->spb_rot_axis_z->setValue(axis.z); + Base::Quantity rotAngle(angle, QString::fromUtf8("rad")); + ui->qsb_rot_angle->setValue(rotAngle.getValueAs(Base::Quantity::Degree)); } } @@ -475,9 +472,10 @@ void TaskFemConstraintTransform::removeFromSelection() } pcConstraint->References.setValues(Objects, SubElements); updateUI(); - ui->sp_X->setValue(0); - ui->sp_Y->setValue(0); - ui->sp_Z->setValue(0); + ui->spb_rot_axis_x->setValue(0); + ui->spb_rot_axis_y->setValue(0); + ui->spb_rot_axis_z->setValue(1); + ui->qsb_rot_angle->setValue(0); } const std::string TaskFemConstraintTransform::getReferences() const @@ -490,6 +488,16 @@ const std::string TaskFemConstraintTransform::getReferences() const return TaskFemConstraint::getReferences(items); } +Base::Rotation TaskFemConstraintTransform::getRotation() const +{ + double x = ui->spb_rot_axis_x->value(); + double y = ui->spb_rot_axis_y->value(); + double z = ui->spb_rot_axis_z->value(); + double angle = ui->qsb_rot_angle->value().getValueAs(Base::Quantity::Radian); + + return Base::Rotation(Base::Vector3d(x, y, z), angle); +} + void TaskFemConstraintTransform::onReferenceDeleted() { TaskFemConstraintTransform::removeFromSelection(); @@ -535,19 +543,6 @@ else:\n\ + showConstr + ".NameDispl = []\n"; } -std::string TaskFemConstraintTransform::get_X_rot() const -{ - return ui->sp_X->value().getSafeUserString().toStdString(); -} -std::string TaskFemConstraintTransform::get_Y_rot() const -{ - return ui->sp_Y->value().getSafeUserString().toStdString(); -} -std::string TaskFemConstraintTransform::get_Z_rot() const -{ - return ui->sp_Z->value().getSafeUserString().toStdString(); -} - std::string TaskFemConstraintTransform::get_transform_type() const { std::string transform; @@ -607,27 +602,29 @@ bool TaskDlgFemConstraintTransform::accept() static_cast(parameter); try { - Gui::Command::doCommand(Gui::Command::Doc, - "App.ActiveDocument.%s.X_rot = \"%s\"", - name.c_str(), - parameters->get_X_rot().c_str()); - Gui::Command::doCommand(Gui::Command::Doc, - "App.ActiveDocument.%s.Y_rot = \"%s\"", - name.c_str(), - parameters->get_Y_rot().c_str()); - Gui::Command::doCommand(Gui::Command::Doc, - "App.ActiveDocument.%s.Z_rot = \"%s\"", - name.c_str(), - parameters->get_Z_rot().c_str()); + Base::Rotation rot = parameters->getRotation(); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + Gui::Command::doCommand( + Gui::Command::Doc, + "App.ActiveDocument.%s.Rotation = App.Rotation(App.Vector(%f,% f, %f), Radian=%f)", + name.c_str(), + axis.x, + axis.y, + axis.z, + angle); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.TransformType = %s", name.c_str(), parameters->get_transform_type().c_str()); - std::string scale = parameters->getScale(); // OvG: determine modified scale + + std::string scale = parameters->getScale(); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Scale = %s", name.c_str(), - scale.c_str()); // OvG: implement modified scale + scale.c_str()); } catch (const Base::Exception& e) { QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.h b/src/Mod/Fem/Gui/TaskFemConstraintTransform.h index a570128e9d..d6e087c5a5 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintTransform.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.h @@ -47,9 +47,7 @@ public: QWidget* parent = nullptr); ~TaskFemConstraintTransform() override; const std::string getReferences() const override; - std::string get_X_rot() const; - std::string get_Y_rot() const; - std::string get_Z_rot() const; + Base::Rotation getRotation() const; std::string get_transform_type() const; static std::string getSurfaceReferences(const std::string showConstr); @@ -59,9 +57,10 @@ private Q_SLOTS: void Cyl(); void addToSelection(); void removeFromSelection(); - void x_Changed(int x); - void y_Changed(int y); - void z_Changed(int z); + void xAxisChanged(double x); + void yAxisChanged(double y); + void zAxisChanged(double z); + void angleChanged(double a); protected: bool event(QEvent* e) override; diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui b/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui index a4792249f6..9adc553c4d 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui @@ -105,76 +105,84 @@ - - - - - Rotation about X-Axis + + + System Rotation + + + + + + X: + + + + + + + false + + + 0.10000000000000 - - - - - deg + + + + + Y: + + + + + + + false - - -360.000000000000000 - - - 360.000000000000000 + + 0.10000000000000 - - - - - - - - - Rotation about Y-Axis + + + + + Z: + + + + + + + false + + + 0.10000000000000 - - - - - deg - - - -360.000000000000000 - - - 360.000000000000000 - - - - - - - - - - - Rotation about Z-Axis - - - - - - - deg - - - -360.000000000000000 - - - 360.000000000000000 - - - - + + + + + Angle: + + + + + + + deg + + + -360.000000000000000 + + + 360.000000000000000 + + + + + @@ -222,6 +230,11 @@ QWidget
Gui/QuantitySpinBox.h
+ + Gui::DoubleSpinBox + QWidget +
Gui/SpinBox.h
+
diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp index ad903451f9..f891d5789d 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp @@ -27,10 +27,12 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include -#include +#include #include -#include +#include +#include #endif #include "Mod/Fem/App/FemConstraintTransform.h" @@ -46,6 +48,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintTransform, FemGui::ViewProvider ViewProviderFemConstraintTransform::ViewProviderFemConstraintTransform() { sPixmap = "FEM_ConstraintTransform"; + loadSymbol((resourceSymbolDir + "ConstraintTransform.iv").c_str()); } ViewProviderFemConstraintTransform::~ViewProviderFemConstraintTransform() = default; @@ -91,215 +94,82 @@ bool ViewProviderFemConstraintTransform::setEdit(int ModNum) } } -#define HEIGHTAXIS (20) -#define RADIUSAXIS (0.8) -#define ARROWLENGTH (3) -#define ARROWHEADRADIUS (ARROWLENGTH / 3) -#define LENGTHDISC (0.25) -#define RADIUSDISC (0.8) - void ViewProviderFemConstraintTransform::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintTransform* pcConstraint = - static_cast(this->getObject()); - float scaledradiusaxis = - RADIUSAXIS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledheightaxis = HEIGHTAXIS * pcConstraint->Scale.getValue(); - float scaledheadradiusA = - ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only - float scaledlengthA = ARROWLENGTH * pcConstraint->Scale.getValue(); - std::string transform_type = pcConstraint->TransformType.getValueAsString(); - if (transform_type == "Rectangular") { + auto obj = static_cast(this->getObject()); - if (prop == &pcConstraint->Points) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) { - return; + if (prop == &obj->Rotation) { + updateSymbol(); + } + else if (prop == &obj->TransformType || prop == &obj->References) { + std::string transType = obj->TransformType.getValueAsString(); + auto sw = static_cast(getSymbolSeparator()->getChild(0)); + auto swExtra = static_cast(getExtraSymbolSeparator()->getChild(0)); + + if (transType == "Rectangular") { + sw->whichChild.setValue(0); + swExtra->whichChild.setValue(-1); + } + else if (transType == "Cylindrical") { + sw->whichChild.setValue(1); + if (obj->References.getSize()) { + swExtra->whichChild.setValue(0); } - std::vector::const_iterator n = normals.begin(); - - // Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f basex(point.x, point.y, point.z); - SbVec3f basey(point.x, point.y, point.z); - - double x_axis_x = 1; - double x_axis_y = 0; - double x_axis_z = 0; - - double y_axis_x = 0; - double y_axis_y = 1; - double y_axis_z = 0; - - double z_axis_x = 0; - double z_axis_y = 0; - double z_axis_z = 1; - - double rot_x = (pcConstraint->X_rot.getValue() * (M_PI / 180)); - double rot_y = (pcConstraint->Y_rot.getValue() * (M_PI / 180)); - double rot_z = (pcConstraint->Z_rot.getValue() * (M_PI / 180)); - - double x_axis_x_p; - double x_axis_y_p; - double x_axis_z_p; - - double y_axis_x_p; - double y_axis_y_p; - double y_axis_z_p; - - double z_axis_x_p; - double z_axis_y_p; - double z_axis_z_p; - - if (rot_x != 0) { - x_axis_z_p = x_axis_z * cos(rot_x) - x_axis_y * sin(rot_x); - x_axis_y_p = x_axis_y * cos(rot_x) + x_axis_z * sin(rot_x); - x_axis_z = x_axis_z_p; - x_axis_y = x_axis_y_p; - - y_axis_z_p = y_axis_z * cos(rot_x) - y_axis_y * sin(rot_x); - y_axis_y_p = y_axis_y * cos(rot_x) + y_axis_z * sin(rot_x); - y_axis_z = y_axis_z_p; - y_axis_y = y_axis_y_p; - - z_axis_z_p = z_axis_z * cos(rot_x) - z_axis_y * sin(rot_x); - z_axis_y_p = z_axis_y * cos(rot_x) + z_axis_z * sin(rot_x); - z_axis_z = z_axis_z_p; - z_axis_y = z_axis_y_p; - } - if (rot_y != 0) { - x_axis_z_p = x_axis_z * cos(rot_y) + x_axis_x * sin(rot_y); - x_axis_x_p = x_axis_x * cos(rot_y) - x_axis_z * sin(rot_y); - x_axis_z = x_axis_z_p; - x_axis_x = x_axis_x_p; - - y_axis_z_p = y_axis_z * cos(rot_y) + y_axis_x * sin(rot_y); - y_axis_x_p = y_axis_x * cos(rot_y) - y_axis_z * sin(rot_y); - y_axis_z = y_axis_z_p; - y_axis_x = y_axis_x_p; - - z_axis_z_p = z_axis_z * cos(rot_y) + z_axis_x * sin(rot_y); - z_axis_x_p = z_axis_x * cos(rot_y) - z_axis_z * sin(rot_y); - z_axis_z = z_axis_z_p; - z_axis_x = z_axis_x_p; - } - if (rot_z != 0) { - x_axis_x_p = x_axis_x * cos(rot_z) + x_axis_y * sin(rot_z); - x_axis_y_p = x_axis_y * cos(rot_z) - x_axis_x * sin(rot_z); - x_axis_x = x_axis_x_p; - x_axis_y = x_axis_y_p; - - y_axis_x_p = y_axis_x * cos(rot_z) + y_axis_y * sin(rot_z); - y_axis_y_p = y_axis_y * cos(rot_z) - y_axis_x * sin(rot_z); - y_axis_x = y_axis_x_p; - y_axis_y = y_axis_y_p; - - z_axis_x_p = z_axis_x * cos(rot_z) + z_axis_y * sin(rot_z); - z_axis_y_p = z_axis_y * cos(rot_z) - z_axis_x * sin(rot_z); - z_axis_x = z_axis_x_p; - z_axis_y = z_axis_y_p; - } - - SbVec3f dirz(z_axis_x, z_axis_y, z_axis_z); - SbRotation rot(SbVec3f(0, 1, 0), dirz); - - SbVec3f dirx(x_axis_x, x_axis_y, x_axis_z); - SbRotation rotx(SbVec3f(0, 1, 0), dirx); - - SbVec3f diry(y_axis_x, y_axis_y, y_axis_z); - SbRotation roty(SbVec3f(0, 1, 0), diry); - - base = base + dirz * scaledlengthA * 0.75f; - basex = basex + dirx * scaledlengthA * 0.65f; - basey = basey + diry * scaledlengthA * 0.65f; - - SoSeparator* sep = new SoSeparator(); - - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(0, 0, 1)); // RGB - sep->addChild(myMaterial); - - createPlacement(sep, base, rot); - createArrow(sep, scaledlengthA * 0.75, scaledheadradiusA * 0.9); // OvG: Scaling - pShapeSep->addChild(sep); - - SoSeparator* sepx = new SoSeparator(); - - SoMaterial* myMaterialx = new SoMaterial; - myMaterialx->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB - sepx->addChild(myMaterialx); - - createPlacement(sepx, basex, rotx); - createArrow(sepx, scaledlengthA * 0.65, scaledheadradiusA * 0.65); // OvG: Scaling - pShapeSep->addChild(sepx); - - SoSeparator* sepy = new SoSeparator(); - - SoMaterial* myMaterialy = new SoMaterial; - myMaterialy->diffuseColor.set1Value(0, SbColor(0, 1, 0)); // RGB - sepy->addChild(myMaterialy); - - createPlacement(sepy, basey, roty); - createArrow(sepy, scaledlengthA * 0.65, scaledheadradiusA * 0.65); // OvG: Scaling - pShapeSep->addChild(sepy); - - n++; + else { + swExtra->whichChild.setValue(-1); } } + updateSymbol(); } - else if (transform_type == "Cylindrical") { - - // Points and Normals are always updated together - Gui::coinRemoveAllChildren(pShapeSep); - - 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(); - - if (!points.empty()) { - Base::Vector3d base = pcConstraint->BasePoint.getValue(); - Base::Vector3d axis = pcConstraint->Axis.getValue(); - - SbVec3f b(base.x, base.y, base.z); - SbVec3f ax(axis.x, axis.y, axis.z); - SbRotation rots(SbVec3f(0, -1, 0), ax); - - b = b - ax * scaledheightaxis / 2; - SoSeparator* sepAx = new SoSeparator(); - SoMaterial* myMaterial = new SoMaterial; - myMaterial->diffuseColor.set1Value(0, SbColor(0, 0, 1)); // RGB - sepAx->addChild(myMaterial); - createPlacement(sepAx, b, rots); - createArrow(sepAx, scaledheightaxis, scaledradiusaxis); - pShapeSep->addChild(sepAx); - } - - for (const auto& point : points) { - SbVec3f base(point.x, point.y, point.z); - SbVec3f dir(n->x, n->y, n->z); - base = base + dir * scaledlengthA; // OvG: Scaling - SbRotation rot(SbVec3f(0, 1, 0), dir); - - SoSeparator* sep = new SoSeparator(); - SoMaterial* myMaterials = new SoMaterial; - myMaterials->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB - sep->addChild(myMaterials); - createPlacement(sep, base, rot); - createArrow(sep, scaledlengthA, scaledheadradiusA); // OvG: Scaling - pShapeSep->addChild(sep); - n++; - } + else if (prop == &obj->BasePoint || prop == &obj->Axis) { + updateSymbol(); } - // Gets called whenever a property of the attached object changes ViewProviderFemConstraint::updateData(prop); } + +void ViewProviderFemConstraintTransform::transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const +{ + auto obj = static_cast(this->getObject()); + + std::string transType = obj->TransformType.getValueAsString(); + if (transType == "Rectangular") { + Base::Rotation rot = obj->Rotation.getValue(); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + float s = obj->getScaleFactor(); + + mat.setTransform(SbVec3f(point.x, point.y, point.z), + SbRotation(SbVec3f(axis.x, axis.y, axis.z), angle), + SbVec3f(s, s, s)); + } + else if (transType == "Cylindrical") { + float s = obj->getScaleFactor(); + + mat.setTransform(SbVec3f(point.x, point.y, point.z), + SbRotation(SbVec3f(0, 1, 0), SbVec3f(normal.x, normal.y, normal.z)), + SbVec3f(s, s, s)); + } +} + +void ViewProviderFemConstraintTransform::transformExtraSymbol() const +{ + auto obj = static_cast(this->getObject()); + std::string transType = obj->TransformType.getValueAsString(); + if (transType == "Cylindrical") { + SoTransform* trans = getExtraSymbolTransform(); + Base::Vector3d point = obj->BasePoint.getValue(); + Base::Vector3d axis = obj->Axis.getValue(); + float s = obj->getScaleFactor(); + + SbMatrix mat; + mat.setTransform(SbVec3f(point.x, point.y, point.z), + SbRotation(SbVec3f(0, 1, 0), SbVec3f(axis.x, axis.y, axis.z)), + SbVec3f(s, s, s)); + + trans->setMatrix(mat); + } +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h index 42beaeb1b0..5b356473f2 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h @@ -43,6 +43,10 @@ public: protected: bool setEdit(int ModNum) override; + void transformSymbol(const Base::Vector3d& point, + const Base::Vector3d& normal, + SbMatrix& mat) const override; + void transformExtraSymbol() const override; }; } // namespace FemGui diff --git a/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py b/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py index 04fcbac1ad..ab1bc43824 100644 --- a/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py +++ b/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py @@ -160,17 +160,11 @@ def setup(doc=None, solvertype="ccxtools"): con_transform1 = ObjectsFem.makeConstraintTransform(doc, name="FemConstraintTransform1") con_transform1.References = [(geom_obj, "Face4")] con_transform1.TransformType = "Cylindrical" - con_transform1.X_rot = 0.0 - con_transform1.Y_rot = 0.0 - con_transform1.Z_rot = 0.0 analysis.addObject(con_transform1) con_transform2 = ObjectsFem.makeConstraintTransform(doc, name="FemConstraintTransform2") con_transform2.References = [(geom_obj, "Face5")] con_transform2.TransformType = "Cylindrical" - con_transform2.X_rot = 0.0 - con_transform2.Y_rot = 0.0 - con_transform2.Z_rot = 0.0 analysis.addObject(con_transform2) # mesh diff --git a/src/Mod/Fem/femexamples/constraint_transform_torque.py b/src/Mod/Fem/femexamples/constraint_transform_torque.py index 209d34f973..312cdbeb46 100644 --- a/src/Mod/Fem/femexamples/constraint_transform_torque.py +++ b/src/Mod/Fem/femexamples/constraint_transform_torque.py @@ -156,9 +156,6 @@ def setup(doc=None, solvertype="ccxtools"): con_transform = ObjectsFem.makeConstraintTransform(doc, name="ConstraintTransform") con_transform.References = [(geom_obj, "Face1")] con_transform.TransformType = "Cylindrical" - con_transform.X_rot = 0.0 - con_transform.Y_rot = 0.0 - con_transform.Z_rot = 0.0 analysis.addObject(con_transform) # mesh diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_transform.py b/src/Mod/Fem/femsolver/calculix/write_constraint_transform.py index 6b012dd7d4..949d8384d9 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_transform.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_transform.py @@ -26,6 +26,8 @@ __author__ = "Bernd Hahnebach" __url__ = "https://www.freecad.org" +import FreeCAD + from femtools import geomtools @@ -75,11 +77,15 @@ def write_constraint(f, femobj, trans_obj, ccxwriter): if trans_obj.TransformType == "Rectangular": trans_name = "Rect" trans_type = "R" - coords = geomtools.get_rectangular_coords(trans_obj) + x = trans_obj.Rotation * FreeCAD.Vector(1, 0, 0) + y = trans_obj.Rotation * FreeCAD.Vector(0, 1, 0) + coords = list(x) + list(y) elif trans_obj.TransformType == "Cylindrical": trans_name = "Cylin" trans_type = "C" - coords = geomtools.get_cylindrical_coords(trans_obj) + base = trans_obj.BasePoint + axis = trans_obj.Axis + coords = list(base) + list(base + axis) f.write("*TRANSFORM, NSET={}{}, TYPE={}\n".format( trans_name, trans_obj.Name, diff --git a/src/Mod/Fem/femtest/data/calculix/constraint_transform_beam_hinged.inp b/src/Mod/Fem/femtest/data/calculix/constraint_transform_beam_hinged.inp index 3f39638f93..1725927172 100644 --- a/src/Mod/Fem/femtest/data/calculix/constraint_transform_beam_hinged.inp +++ b/src/Mod/Fem/femtest/data/calculix/constraint_transform_beam_hinged.inp @@ -3635,10 +3635,10 @@ Evolumes ** Transform Constraints ** FemConstraintTransform1 *TRANSFORM, NSET=CylinFemConstraintTransform1, TYPE=C -10,27,10,10,7,10 +10,5,10,10,6,10 ** FemConstraintTransform2 *TRANSFORM, NSET=CylinFemConstraintTransform2, TYPE=C -190,27,10,190,7,10 +190,5,10,190,6,10 *********************************************************** ** At least one step is needed to run an CalculiX analysis of FreeCAD diff --git a/src/Mod/Fem/femtest/data/calculix/constraint_transform_torque.inp b/src/Mod/Fem/femtest/data/calculix/constraint_transform_torque.inp index b5747c0145..a4f0b4dc22 100644 --- a/src/Mod/Fem/femtest/data/calculix/constraint_transform_torque.inp +++ b/src/Mod/Fem/femtest/data/calculix/constraint_transform_torque.inp @@ -10979,7 +10979,7 @@ Evolumes ** Transform Constraints ** ConstraintTransform *TRANSFORM, NSET=CylinConstraintTransform, TYPE=C -0,0,-35,0,0,-15 +0,0,25,0,0,24 *********************************************************** ** At least one step is needed to run an CalculiX analysis of FreeCAD diff --git a/src/Mod/Fem/femtools/geomtools.py b/src/Mod/Fem/femtools/geomtools.py index 34ddf29a27..bd3f502df7 100644 --- a/src/Mod/Fem/femtools/geomtools.py +++ b/src/Mod/Fem/femtools/geomtools.py @@ -187,52 +187,3 @@ def get_element( return part.Shape.Solids[index] # Solid else: return part.Shape.getElement(element) # Face, Edge, Vertex - - -# ************************************************************************************************ -def get_rectangular_coords( - obj -): - from math import cos, sin, radians - A = [1, 0, 0] - B = [0, 1, 0] - a_x = A[0] - a_y = A[1] - a_z = A[2] - b_x = B[0] - b_y = B[1] - b_z = B[2] - x_rot = radians(obj.X_rot) - y_rot = radians(obj.Y_rot) - z_rot = radians(obj.Z_rot) - if obj.X_rot != 0: - a_y = A[1] * cos(x_rot) + A[2] * sin(x_rot) - a_z = A[2] * cos(x_rot) - A[1] * sin(x_rot) - b_y = B[1] * cos(x_rot) + B[2] * sin(x_rot) - b_z = B[2] * cos(x_rot) - B[1] * sin(x_rot) - if obj.Y_rot != 0: - a_x = A[0] * cos(y_rot) - A[2] * sin(y_rot) - a_z = A[2] * cos(y_rot) + A[0] * sin(y_rot) - b_x = B[0] * cos(y_rot) - B[2] * sin(y_rot) - b_z = B[2] * cos(y_rot) + B[0] * sin(z_rot) - if obj.Z_rot != 0: - a_x = A[0] * cos(z_rot) + A[1] * sin(z_rot) - a_y = A[1] * cos(z_rot) - A[0] * sin(z_rot) - b_x = B[0] * cos(z_rot) + B[1] * sin(z_rot) - b_y = B[1] * cos(z_rot) - B[0] * sin(z_rot) - return (a_x, a_y, a_z, b_x, b_y, b_z) - - -# ************************************************************************************************ -def get_cylindrical_coords( - obj -): - vec = obj.Axis - base = obj.BasePoint - a_x = base[0] + 10 * vec[0] - a_y = base[1] + 10 * vec[1] - a_z = base[2] + 10 * vec[2] - b_x = base[0] - 10 * vec[0] - b_y = base[1] - 10 * vec[1] - b_z = base[2] - 10 * vec[2] - return (a_x, a_y, a_z, b_x, b_y, b_z) From 5f30e51894dead267867f642c5570eb96eac1474 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Wed, 5 Jun 2024 13:12:13 -0300 Subject: [PATCH 4/4] Fem: Add license to constraints symbol files --- .../Resources/symbols/ConstraintContact.iv | 23 +++++++++++++++++++ .../symbols/ConstraintDisplacement.iv | 23 +++++++++++++++++++ .../Gui/Resources/symbols/ConstraintFixed.iv | 23 +++++++++++++++++++ .../Gui/Resources/symbols/ConstraintForce.iv | 23 +++++++++++++++++++ .../Resources/symbols/ConstraintHeatFlux.iv | 23 +++++++++++++++++++ .../symbols/ConstraintPlaneRotation.iv | 23 +++++++++++++++++++ .../Resources/symbols/ConstraintPressure.iv | 23 +++++++++++++++++++ .../Resources/symbols/ConstraintRigidBody.iv | 23 +++++++++++++++++++ .../symbols/ConstraintSectionPrint.iv | 23 +++++++++++++++++++ .../Gui/Resources/symbols/ConstraintSpring.iv | 23 +++++++++++++++++++ .../symbols/ConstraintTemperature.iv | 23 +++++++++++++++++++ .../Gui/Resources/symbols/ConstraintTie.iv | 23 +++++++++++++++++++ .../Resources/symbols/ConstraintTransform.iv | 23 +++++++++++++++++++ 13 files changed, 299 insertions(+) diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv index 2a6455cdd6..1723f4b380 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintContact.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv index 8c94b9a89b..e4895f7dcc 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintDisplacement.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv index a0494da316..9af3c94e85 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintFixed.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv index 5ac7254065..90df0a45b3 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintForce.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv index 6ba000fa45..0e52b83855 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintHeatFlux.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv index d5ec896cd3..de74787542 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPlaneRotation.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv index 137c2325e6..8cfe3300e8 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintPressure.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv index 4e75700a9d..fd4da8d21f 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintSectionPrint.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSectionPrint.iv index ddcb93fae9..9fab479a3c 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintSectionPrint.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSectionPrint.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv index 943232eca9..cb7640d3a5 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintSpring.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv index cb6691cc0a..29269a2443 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTemperature.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv index 62d491599b..1dff7e5f43 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTie.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator { diff --git a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv index f001b5daa1..13a0715d32 100644 --- a/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv +++ b/src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv @@ -1,5 +1,28 @@ #Inventor V2.1 ascii +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + Separator {