Skip to content

Commit 863cb80

Browse files
committed
Fem: Constraint symbol scaling based on shape size - fixes FreeCAD#7030
1 parent 1e42992 commit 863cb80

File tree

3 files changed

+19
-70
lines changed

3 files changed

+19
-70
lines changed

src/Mod/Fem/App/FemConstraint.cpp

+14-34
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <BRepAdaptor_CompCurve.hxx>
2929
#include <BRepAdaptor_Curve.hxx>
3030
#include <BRepAdaptor_Surface.hxx>
31+
#include <BRepBndLib.hxx>
3132
#include <BRepClass_FaceClassifier.hxx>
3233
#include <BRepGProp.hxx>
3334
#include <BRepGProp_Face.hxx>
@@ -131,22 +132,14 @@ App::DocumentObjectExecReturn* Constraint::execute()
131132
}
132133
}
133134

134-
// OvG: Provide the ability to determine how big to draw constraint arrows etc.
135-
unsigned int Constraint::calcSizeFactor(double lparam) const
135+
// Provide the ability to determine how big to draw constraint arrows etc.
136+
// Try to get symbol size equal to 1/5 of the characteristic length of
137+
// the object. Typical symbol size is 5, so use 1/25 of the characteristic length.
138+
double Constraint::calcSizeFactor(double characLen) const
136139
{
137-
return (static_cast<int>(round(log(lparam) * log(lparam) * log(lparam) / 10)) > 1)
138-
? (static_cast<int>(round(log(lparam) * log(lparam) * log(lparam) / 10)))
139-
: 1;
140-
}
141-
142-
unsigned int Constraint::calcSizeFactor(double lvparam, double luparam) const
143-
{
144-
return calcSizeFactor((lvparam + luparam) / 2.0);
145-
}
146-
147-
unsigned int Constraint::calcSizeFactor() const
148-
{
149-
return 1;
140+
double l = characLen / 25.0;
141+
l = ((round(l)) > 1) ? round(l) : l;
142+
return (l > Precision::Confusion() ? l : 1);
150143
}
151144

152145
float Constraint::getScaleFactor() const
@@ -272,7 +265,7 @@ void Constraint::handleChangedPropertyType(Base::XMLReader& reader,
272265

273266
bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
274267
std::vector<Base::Vector3d>& normals,
275-
int* scale) const
268+
double* scale) const
276269
{
277270
std::vector<App::DocumentObject*> Objects = References.getValues();
278271
std::vector<std::string> SubElements = References.getSubValues();
@@ -294,42 +287,35 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
294287
}
295288

296289
setSubShapeLocation(feat, sh);
290+
// Scale by bounding box of the object
291+
Bnd_Box box;
292+
BRepBndLib::Add(toposhape.getShape(), box);
293+
double l = sqrt(box.SquareExtent() / 3.0);
294+
*scale = this->calcSizeFactor(l);
297295

298296
if (sh.ShapeType() == TopAbs_VERTEX) {
299297
const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
300298
gp_Pnt p = BRep_Tool::Pnt(vertex);
301299
points.emplace_back(p.X(), p.Y(), p.Z());
302300
normals.push_back(NormalDirection.getValue());
303-
// OvG: Scale by whole object mass in case of a vertex
304-
GProp_GProps props;
305-
BRepGProp::VolumeProperties(toposhape.getShape(), props);
306-
double lx = props.Mass();
307-
// OvG: setup draw scale for constraint
308-
*scale = this->calcSizeFactor(sqrt(lx) * 0.5);
309301
}
310302
else if (sh.ShapeType() == TopAbs_EDGE) {
311303
BRepAdaptor_Curve curve(TopoDS::Edge(sh));
312304
double fp = curve.FirstParameter();
313305
double lp = curve.LastParameter();
314-
GProp_GProps props;
315-
BRepGProp::LinearProperties(TopoDS::Edge(sh), props);
316-
double l = props.Mass();
317306
// Create points with 10 units distance, but at least one at the beginning and end of
318307
// the edge
319308
int steps;
320309
// OvG: Increase 10 units distance proportionately to l for larger objects.
321310
if (l >= 30) {
322-
*scale = this->calcSizeFactor(l); // OvG: setup draw scale for constraint
323311
steps = static_cast<int>(round(l / (10 * (*scale))));
324312
steps = steps < 3 ? 3 : steps;
325313
}
326314
else if (l >= 20) {
327315
steps = static_cast<int>(round(l / 10));
328-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
329316
}
330317
else {
331318
steps = 1;
332-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
333319
}
334320

335321
// OvG: Place upper limit on number of steps
@@ -407,37 +393,31 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
407393
// OvG: Increase 10 units distance proportionately to lv for larger objects.
408394
int stepsv;
409395
if (lv >= 30) {
410-
*scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint
411396
stepsv = static_cast<int>(round(lv / (10 * (*scale))));
412397
stepsv = stepsv < 3 ? 3 : stepsv;
413398
}
414399
else if (lv >= 20.0) {
415400
stepsv = static_cast<int>(round(lv / 10));
416-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
417401
}
418402
else {
419403
// Minimum of three arrows to ensure (as much as possible) that at
420404
// least one is displayed
421405
stepsv = 2;
422-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
423406
}
424407

425408
// OvG: Place upper limit on number of steps
426409
stepsv = stepsv > CONSTRAINTSTEPLIMIT ? CONSTRAINTSTEPLIMIT : stepsv;
427410
int stepsu;
428411
// OvG: Increase 10 units distance proportionately to lu for larger objects.
429412
if (lu >= 30) {
430-
*scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint
431413
stepsu = static_cast<int>(round(lu / (10 * (*scale))));
432414
stepsu = stepsu < 3 ? 3 : stepsu;
433415
}
434416
else if (lu >= 20.0) {
435417
stepsu = static_cast<int>(round(lu / 10));
436-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
437418
}
438419
else {
439420
stepsu = 2;
440-
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
441421
}
442422

443423
// OvG: Place upper limit on number of steps

src/Mod/Fem/App/FemConstraint.h

+4-35
Original file line numberDiff line numberDiff line change
@@ -123,43 +123,12 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible
123123
App::DocumentObjectExecReturn* execute() override;
124124

125125
/**
126-
* @brief Calculates scale factor based on length of edge.
126+
* @brief Calculates scale factor based on characteristic length of shape.
127127
*
128128
* @details
129129
* Used to calculate the scale factor returned by @ref getPoints when the
130-
* scale factor is calculated for a face.
131-
*
132-
* @note
133-
* This method does a really crazy calculation that I didn't dare to try
134-
* to understand.
135-
*/
136-
unsigned int calcSizeFactor(double lparam) const;
137-
138-
/**
139-
* @brief Calculates scale factor based on size of face.
140-
*
141-
* @details
142-
* Used to calculate the scale factor returned by @ref getPoints when the
143-
* scale factor is calculated for a edge.
144-
*
145-
* @note
146-
* This method does a really crazy calculation that I didn't dare to try
147-
* to understand.
148-
*/
149-
unsigned int calcSizeFactor(double lvparam, double luparam) const;
150-
151-
/**
152-
* @brief Returns default scale factor of 1.
153-
*
154-
* @details
155-
* This is just used to make code more understandable. Other versions
156-
* (overloads) of this function do useful calculations based on faces or
157-
* edges. Used by @ref getPoints if no useful shape information is
158-
* available.
159-
*
160-
* @return always the integer 1
161130
*/
162-
unsigned int calcSizeFactor() const;
131+
double calcSizeFactor(double characLen) const;
163132

164133
const char* getViewProviderName() const override
165134
{
@@ -227,7 +196,7 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible
227196
*/
228197
bool getPoints(std::vector<Base::Vector3d>& points,
229198
std::vector<Base::Vector3d>& normals,
230-
int* scale) const;
199+
double* scale) const;
231200

232201
/**
233202
* @brief Extract properties of cylindrical face.
@@ -263,7 +232,7 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible
263232
/**
264233
* @brief Symbol size factor determined from the size of the shape.
265234
*/
266-
int sizeFactor;
235+
double sizeFactor;
267236

268237
void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop);
269238
boost::signals2::connection connDocChangedObject;

src/Mod/Fem/App/FemConstraintTransform.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ void ConstraintTransform::onChanged(const App::Property* prop)
110110
if (prop == &References) {
111111
std::vector<Base::Vector3d> points;
112112
std::vector<Base::Vector3d> normals;
113-
int scale = 1; // OvG: Enforce use of scale
113+
double scale = 1; // OvG: Enforce use of scale
114114
if (getPoints(points, normals, &scale)) {
115115
std::string transform_type = TransformType.getValueAsString();
116116
if (transform_type == "Cylindrical") {

0 commit comments

Comments
 (0)