From ba0825f60591fdf0af81a2432843ee5027e800d6 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Mon, 22 Apr 2024 00:10:06 -0300 Subject: [PATCH] Fem: Constraint symbol scaling based on shape size - fixes #7030 --- src/Mod/Fem/App/FemConstraint.cpp | 48 +++++++--------------- src/Mod/Fem/App/FemConstraint.h | 39 ++---------------- src/Mod/Fem/App/FemConstraintTransform.cpp | 2 +- 3 files changed, 19 insertions(+), 70 deletions(-) diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index d42b342f20fb..8609d1e72227 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -131,22 +132,14 @@ App::DocumentObjectExecReturn* Constraint::execute() } } -// OvG: Provide the ability to determine how big to draw constraint arrows etc. -unsigned int Constraint::calcSizeFactor(double lparam) const +// Provide the ability to determine how big to draw constraint arrows etc. +// Try to get symbol size equal to 1/5 of the characteristic length of +// the object. Typical symbol size is 5, so use 1/25 of the characteristic length. +double Constraint::calcSizeFactor(double characLen) const { - return (static_cast(round(log(lparam) * log(lparam) * log(lparam) / 10)) > 1) - ? (static_cast(round(log(lparam) * log(lparam) * log(lparam) / 10))) - : 1; -} - -unsigned int Constraint::calcSizeFactor(double lvparam, double luparam) const -{ - return calcSizeFactor((lvparam + luparam) / 2.0); -} - -unsigned int Constraint::calcSizeFactor() const -{ - return 1; + double l = characLen / 25.0; + l = ((round(l)) > 1) ? round(l) : l; + return (l > Precision::Confusion() ? l : 1); } float Constraint::getScaleFactor() const @@ -272,7 +265,7 @@ void Constraint::handleChangedPropertyType(Base::XMLReader& reader, bool Constraint::getPoints(std::vector& points, std::vector& normals, - int* scale) const + double* scale) const { std::vector Objects = References.getValues(); std::vector SubElements = References.getSubValues(); @@ -294,42 +287,35 @@ bool Constraint::getPoints(std::vector& points, } setSubShapeLocation(feat, sh); + // Scale by bounding box of the object + Bnd_Box box; + BRepBndLib::Add(toposhape.getShape(), box); + double l = sqrt(box.SquareExtent() / 3.0); + *scale = this->calcSizeFactor(l); if (sh.ShapeType() == TopAbs_VERTEX) { const TopoDS_Vertex& vertex = TopoDS::Vertex(sh); gp_Pnt p = BRep_Tool::Pnt(vertex); points.emplace_back(p.X(), p.Y(), p.Z()); normals.push_back(NormalDirection.getValue()); - // OvG: Scale by whole object mass in case of a vertex - GProp_GProps props; - BRepGProp::VolumeProperties(toposhape.getShape(), props); - double lx = props.Mass(); - // OvG: setup draw scale for constraint - *scale = this->calcSizeFactor(sqrt(lx) * 0.5); } else if (sh.ShapeType() == TopAbs_EDGE) { BRepAdaptor_Curve curve(TopoDS::Edge(sh)); double fp = curve.FirstParameter(); double lp = curve.LastParameter(); - GProp_GProps props; - BRepGProp::LinearProperties(TopoDS::Edge(sh), props); - double l = props.Mass(); // Create points with 10 units distance, but at least one at the beginning and end of // the edge int steps; // OvG: Increase 10 units distance proportionately to l for larger objects. if (l >= 30) { - *scale = this->calcSizeFactor(l); // OvG: setup draw scale for constraint steps = static_cast(round(l / (10 * (*scale)))); steps = steps < 3 ? 3 : steps; } else if (l >= 20) { steps = static_cast(round(l / 10)); - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { steps = 1; - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps @@ -407,19 +393,16 @@ bool Constraint::getPoints(std::vector& points, // OvG: Increase 10 units distance proportionately to lv for larger objects. int stepsv; if (lv >= 30) { - *scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint stepsv = static_cast(round(lv / (10 * (*scale)))); stepsv = stepsv < 3 ? 3 : stepsv; } else if (lv >= 20.0) { stepsv = static_cast(round(lv / 10)); - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { // Minimum of three arrows to ensure (as much as possible) that at // least one is displayed stepsv = 2; - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps @@ -427,17 +410,14 @@ bool Constraint::getPoints(std::vector& points, int stepsu; // OvG: Increase 10 units distance proportionately to lu for larger objects. if (lu >= 30) { - *scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint stepsu = static_cast(round(lu / (10 * (*scale)))); stepsu = stepsu < 3 ? 3 : stepsu; } else if (lu >= 20.0) { stepsu = static_cast(round(lu / 10)); - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } else { stepsu = 2; - *scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint } // OvG: Place upper limit on number of steps diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index f56cb34bbb61..1c86166a89ce 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -123,43 +123,12 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible App::DocumentObjectExecReturn* execute() override; /** - * @brief Calculates scale factor based on length of edge. + * @brief Calculates scale factor based on characteristic length of shape. * * @details * Used to calculate the scale factor returned by @ref getPoints when the - * scale factor is calculated for a face. - * - * @note - * This method does a really crazy calculation that I didn't dare to try - * to understand. - */ - unsigned int calcSizeFactor(double lparam) const; - - /** - * @brief Calculates scale factor based on size of face. - * - * @details - * Used to calculate the scale factor returned by @ref getPoints when the - * scale factor is calculated for a edge. - * - * @note - * This method does a really crazy calculation that I didn't dare to try - * to understand. - */ - unsigned int calcSizeFactor(double lvparam, double luparam) const; - - /** - * @brief Returns default scale factor of 1. - * - * @details - * This is just used to make code more understandable. Other versions - * (overloads) of this function do useful calculations based on faces or - * edges. Used by @ref getPoints if no useful shape information is - * available. - * - * @return always the integer 1 */ - unsigned int calcSizeFactor() const; + double calcSizeFactor(double characLen) const; const char* getViewProviderName() const override { @@ -227,7 +196,7 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible */ bool getPoints(std::vector& points, std::vector& normals, - int* scale) const; + double* scale) const; /** * @brief Extract properties of cylindrical face. @@ -263,7 +232,7 @@ class FemExport Constraint: public App::DocumentObject, public App::Suppressible /** * @brief Symbol size factor determined from the size of the shape. */ - int sizeFactor; + double sizeFactor; void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop); boost::signals2::connection connDocChangedObject; diff --git a/src/Mod/Fem/App/FemConstraintTransform.cpp b/src/Mod/Fem/App/FemConstraintTransform.cpp index dc2856caa69c..163f190c60f1 100644 --- a/src/Mod/Fem/App/FemConstraintTransform.cpp +++ b/src/Mod/Fem/App/FemConstraintTransform.cpp @@ -110,7 +110,7 @@ void ConstraintTransform::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - int scale = 1; // OvG: Enforce use of scale + double scale = 1; // OvG: Enforce use of scale if (getPoints(points, normals, &scale)) { std::string transform_type = TransformType.getValueAsString(); if (transform_type == "Cylindrical") {