Skip to content

Commit 3a01fe4

Browse files
committed
Fem: Transform
1 parent c71de92 commit 3a01fe4

17 files changed

+846
-763
lines changed

src/Mod/Fem/App/FemConstraintTransform.cpp

+110-20
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ static const char* TransformTypes[] = {"Cylindrical", "Rectangular", nullptr};
3434

3535
ConstraintTransform::ConstraintTransform()
3636
{
37-
ADD_PROPERTY(X_rot, (0.0));
38-
ADD_PROPERTY(Y_rot, (0.0));
39-
ADD_PROPERTY(Z_rot, (0.0));
37+
// ADD_PROPERTY(X_rot, (0.0));
38+
// ADD_PROPERTY(Y_rot, (0.0));
39+
// ADD_PROPERTY(Z_rot, (0.0));
40+
ADD_PROPERTY_TYPE(RectangularTransform,
41+
(Base::Rotation(0.0, 0.0, 0.0, 1.0)),
42+
"ConstraintTransform",
43+
App::Prop_Output,
44+
"Rectangular system transform");
4045
ADD_PROPERTY_TYPE(TransformType,
4146
(1),
4247
"ConstraintTransform",
@@ -78,28 +83,113 @@ const char* ConstraintTransform::getViewProviderName() const
7883
return "FemGui::ViewProviderFemConstraintTransform";
7984
}
8085

81-
void ConstraintTransform::handleChangedPropertyType(Base::XMLReader& reader,
82-
const char* TypeName,
83-
App::Property* prop)
86+
87+
namespace
88+
{
89+
90+
Base::Rotation anglesToRotation(double xAngle, double yAngle, double zAngle)
8491
{
85-
// properties _rot had App::PropertyFloat and were changed to App::PropertyAngle
86-
if (prop == &X_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
87-
App::PropertyFloat X_rotProperty;
88-
X_rotProperty.Restore(reader);
89-
X_rot.setValue(X_rotProperty.getValue());
92+
static Base::Vector3d a(1, 0, 0);
93+
static Base::Vector3d b(0, 1, 0);
94+
static int count = 0;
95+
double xRad = xAngle * D_PI / 180.0;
96+
double yRad = yAngle * D_PI / 180.0;
97+
double zRad = zAngle * D_PI / 180.0;
98+
if (xAngle != 0) {
99+
a[1] = 0;
100+
a[2] = 0;
101+
b[1] = std::cos(xRad);
102+
b[2] = -std::sin(xRad);
103+
}
104+
if (yAngle != 0) {
105+
a[0] = std::cos(yRad);
106+
a[2] = std::sin(yRad);
107+
b[0] = 0;
108+
b[2] = 0;
109+
}
110+
if (zAngle != 0) {
111+
a[0] = std::cos(zRad);
112+
a[1] = -std::sin(zRad);
113+
b[0] = 0;
114+
b[1] = 0;
90115
}
91-
else if (prop == &Y_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
92-
App::PropertyFloat Y_rotProperty;
93-
Y_rotProperty.Restore(reader);
94-
Y_rot.setValue(Y_rotProperty.getValue());
116+
117+
++count;
118+
count %= 3;
119+
if (!count) {
120+
Base::Vector3d X = a.Normalize();
121+
Base::Vector3d Y = b.Normalize();
122+
Base::Vector3d Z = X.Cross(Y);
123+
Y = Z.Cross(X);
124+
125+
a.x = 1;
126+
a.y = 0;
127+
a.z = 0;
128+
b.x = 0;
129+
b.y = 1;
130+
b.z = 0;
131+
132+
Base::Matrix4D m;
133+
m.setCol(0, X);
134+
m.setCol(1, Y);
135+
m.setCol(2, Z);
136+
137+
return Base::Rotation(m);
95138
}
96-
else if (prop == &Z_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
97-
App::PropertyFloat Z_rotProperty;
98-
Z_rotProperty.Restore(reader);
99-
Z_rot.setValue(Z_rotProperty.getValue());
139+
return Base::Rotation();
140+
}
141+
142+
} // namespace
143+
144+
145+
void ConstraintTransform::handleChangedPropertyName(Base::XMLReader& reader,
146+
const char* typeName,
147+
const char* propName)
148+
{
149+
if (strcmp(propName, "X_rot") == 0) {
150+
double xAngle;
151+
if (strcmp(typeName, "App::PropertyFloat") == 0) {
152+
App::PropertyFloat X_rotProperty;
153+
X_rotProperty.Restore(reader);
154+
xAngle = X_rotProperty.getValue();
155+
}
156+
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
157+
App::PropertyAngle X_rotProperty;
158+
X_rotProperty.Restore(reader);
159+
xAngle = X_rotProperty.getValue();
160+
}
161+
anglesToRotation(xAngle, 0, 0);
162+
}
163+
else if (strcmp(propName, "Y_rot") == 0) {
164+
double yAngle;
165+
if (strcmp(typeName, "App::PropertyFloat") == 0) {
166+
App::PropertyFloat Y_rotProperty;
167+
Y_rotProperty.Restore(reader);
168+
yAngle = Y_rotProperty.getValue();
169+
}
170+
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
171+
App::PropertyAngle Y_rotProperty;
172+
Y_rotProperty.Restore(reader);
173+
yAngle = Y_rotProperty.getValue();
174+
}
175+
anglesToRotation(0, yAngle, 0);
176+
}
177+
else if (strcmp(propName, "Z_rot") == 0) {
178+
double zAngle;
179+
if (strcmp(typeName, "App::PropertyFloat") == 0) {
180+
App::PropertyFloat Z_rotProperty;
181+
Z_rotProperty.Restore(reader);
182+
zAngle = Z_rotProperty.getValue();
183+
}
184+
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
185+
App::PropertyAngle Z_rotProperty;
186+
Z_rotProperty.Restore(reader);
187+
zAngle = Z_rotProperty.getValue();
188+
}
189+
RectangularTransform.setValue(anglesToRotation(0, 0, zAngle));
100190
}
101191
else {
102-
Constraint::handleChangedPropertyType(reader, TypeName, prop);
192+
Constraint::handleChangedPropertyName(reader, typeName, propName);
103193
}
104194
}
105195

src/Mod/Fem/App/FemConstraintTransform.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ class FemExport ConstraintTransform: public Fem::Constraint
4242
App::PropertyLinkList NameDispl;
4343
App::PropertyVector BasePoint;
4444
App::PropertyVector Axis;
45-
App::PropertyAngle X_rot;
46-
App::PropertyAngle Y_rot;
47-
App::PropertyAngle Z_rot;
45+
// App::PropertyAngle X_rot;
46+
// App::PropertyAngle Y_rot;
47+
// App::PropertyAngle Z_rot;
48+
App::PropertyRotation RectangularTransform;
4849
App::PropertyEnumeration TransformType;
4950
// etc
5051
/* */
@@ -56,9 +57,9 @@ class FemExport ConstraintTransform: public Fem::Constraint
5657
const char* getViewProviderName() const override;
5758

5859
protected:
59-
void handleChangedPropertyType(Base::XMLReader& reader,
60-
const char* TypeName,
61-
App::Property* prop) override;
60+
void handleChangedPropertyName(Base::XMLReader& reader,
61+
const char* typeName,
62+
const char* propName) override;
6263
void onChanged(const App::Property* prop) override;
6364
};
6465

src/Mod/Fem/Gui/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ SET(FemGui_SRCS_Module
305305
ActiveAnalysisObserver.cpp
306306
ActiveAnalysisObserver.h
307307
Command.cpp
308+
FemGuiTools.cpp
309+
FemGuiTools.h
308310
FemSettings.cpp
309311
FemSettings.h
310312
Resources/Fem.qrc
@@ -364,6 +366,7 @@ SET(FemGuiSymbol_IV
364366
Resources/symbols/ConstraintSectionPrint.iv
365367
Resources/symbols/ConstraintSpring.iv
366368
Resources/symbols/ConstraintTemperature.iv
369+
Resources/symbols/ConstraintTransform.iv
367370
Resources/symbols/ConstraintTie.iv
368371
)
369372

src/Mod/Fem/Gui/FemGuiTools.cpp

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include "PreCompiled.h"
2+
3+
#ifndef _PreComp_
4+
#include <Inventor/nodes/SoCone.h>
5+
#include <Inventor/nodes/SoCube.h>
6+
#include <Inventor/nodes/SoCylinder.h>
7+
#include <Inventor/nodes/SoTranslation.h>
8+
#include <Inventor/nodes/SoSeparator.h>
9+
#include <Inventor/nodes/SoRotation.h>
10+
#endif
11+
12+
#include "FemGuiTools.h"
13+
14+
15+
namespace FemGui::GuiTools
16+
{
17+
18+
#define PLACEMENT_CHILDREN 2
19+
#define CONE_CHILDREN 2
20+
21+
void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r)
22+
{
23+
SoTranslation* trans = new SoTranslation();
24+
trans->translation.setValue(base);
25+
sep->addChild(trans);
26+
SoRotation* rot = new SoRotation();
27+
rot->rotation.setValue(r);
28+
sep->addChild(rot);
29+
}
30+
31+
void updatePlacement(const SoSeparator* sep,
32+
const int idx,
33+
const SbVec3f& base,
34+
const SbRotation& r)
35+
{
36+
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
37+
trans->translation.setValue(base);
38+
SoRotation* rot = static_cast<SoRotation*>(sep->getChild(idx + 1));
39+
rot->rotation.setValue(r);
40+
}
41+
42+
void createCone(SoSeparator* sep, const double height, const double radius)
43+
{
44+
// Adjust cone so that the tip is on base
45+
SoTranslation* trans = new SoTranslation();
46+
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
47+
sep->addChild(trans);
48+
SoCone* cone = new SoCone();
49+
cone->height.setValue(height);
50+
cone->bottomRadius.setValue(radius);
51+
sep->addChild(cone);
52+
}
53+
54+
SoSeparator* createCone(const double height, const double radius)
55+
{
56+
// Create a new cone node
57+
SoSeparator* sep = new SoSeparator();
58+
createCone(sep, height, radius);
59+
return sep;
60+
}
61+
62+
void updateCone(const SoNode* node, const int idx, const double height, const double radius)
63+
{
64+
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
65+
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
66+
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
67+
SoCone* cone = static_cast<SoCone*>(sep->getChild(idx + 1));
68+
cone->height.setValue(height);
69+
cone->bottomRadius.setValue(radius);
70+
}
71+
72+
void createCylinder(SoSeparator* sep, const double height, const double radius)
73+
{
74+
SoCylinder* cyl = new SoCylinder();
75+
cyl->height.setValue(height);
76+
cyl->radius.setValue(radius);
77+
sep->addChild(cyl);
78+
}
79+
80+
SoSeparator* createCylinder(const double height, const double radius)
81+
{
82+
// Create a new cylinder node
83+
SoSeparator* sep = new SoSeparator();
84+
createCylinder(sep, height, radius);
85+
return sep;
86+
}
87+
88+
void updateCylinder(const SoNode* node, const int idx, const double height, const double radius)
89+
{
90+
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
91+
SoCylinder* cyl = static_cast<SoCylinder*>(sep->getChild(idx));
92+
cyl->height.setValue(height);
93+
cyl->radius.setValue(radius);
94+
}
95+
96+
void createCube(SoSeparator* sep, const double width, const double length, const double height)
97+
{
98+
SoCube* cube = new SoCube();
99+
cube->width.setValue(width);
100+
cube->depth.setValue(length);
101+
cube->height.setValue(height);
102+
sep->addChild(cube);
103+
}
104+
105+
SoSeparator* createCube(const double width, const double length, const double height)
106+
{
107+
SoSeparator* sep = new SoSeparator();
108+
createCube(sep, width, length, height);
109+
return sep;
110+
}
111+
112+
void updateCube(const SoNode* node,
113+
const int idx,
114+
const double width,
115+
const double length,
116+
const double height)
117+
{
118+
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
119+
SoCube* cube = static_cast<SoCube*>(sep->getChild(idx));
120+
cube->width.setValue(width);
121+
cube->depth.setValue(length);
122+
cube->height.setValue(height);
123+
}
124+
125+
void createArrow(SoSeparator* sep, const double length, const double radius)
126+
{
127+
createCone(sep, radius, radius / 2);
128+
createPlacement(sep, SbVec3f(0, -radius / 2 - (length - radius) / 2, 0), SbRotation());
129+
createCylinder(sep, length - radius, radius / 5);
130+
}
131+
132+
SoSeparator* createArrow(const double length, const double radius)
133+
{
134+
SoSeparator* sep = new SoSeparator();
135+
createArrow(sep, length, radius);
136+
return sep;
137+
}
138+
139+
void updateArrow(const SoNode* node, const int idx, const double length, const double radius)
140+
{
141+
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
142+
updateCone(sep, idx, radius, radius / 2);
143+
updatePlacement(sep,
144+
idx + CONE_CHILDREN,
145+
SbVec3f(0, -radius / 2 - (length - radius) / 2, 0),
146+
SbRotation());
147+
updateCylinder(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, length - radius, radius / 5);
148+
}
149+
150+
void createFixed(SoSeparator* sep, const double height, const double width, const bool gap)
151+
{
152+
createCone(sep, height - width / 4, height - width / 4);
153+
createPlacement(
154+
sep,
155+
SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0),
156+
SbRotation());
157+
createCube(sep, width, width, width / 4);
158+
}
159+
160+
SoSeparator* createFixed(const double height, const double width, const bool gap)
161+
{
162+
SoSeparator* sep = new SoSeparator();
163+
createFixed(sep, height, width, gap);
164+
return sep;
165+
}
166+
167+
void updateFixed(const SoNode* node,
168+
const int idx,
169+
const double height,
170+
const double width,
171+
const bool gap)
172+
{
173+
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
174+
updateCone(sep, idx, height - width / 4, height - width / 4);
175+
updatePlacement(
176+
sep,
177+
idx + CONE_CHILDREN,
178+
SbVec3f(0, -(height - width / 4) / 2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0),
179+
SbRotation());
180+
updateCube(sep, idx + CONE_CHILDREN + PLACEMENT_CHILDREN, width, width, width / 4);
181+
}
182+
183+
} // namespace FemGui::GuiTools

0 commit comments

Comments
 (0)