From 80a791021b25d5b3732b94865c54288784338ad7 Mon Sep 17 00:00:00 2001 From: vginkeo Date: Mon, 1 Feb 2016 10:52:37 +0200 Subject: [PATCH] FEM: Constraint view sizing and scaling of indicators for force, pressure and fixed constraints and limit on steps. --- src/Mod/Fem/App/FemConstraint.cpp | 73 +++++++++++++++++-- src/Mod/Fem/App/FemConstraint.h | 10 ++- src/Mod/Fem/App/FemConstraintFixed.cpp | 4 +- src/Mod/Fem/App/FemConstraintForce.cpp | 5 +- src/Mod/Fem/App/FemConstraintPressure.cpp | 4 +- src/Mod/Fem/Gui/Command.cpp | 9 ++- src/Mod/Fem/Gui/TaskFemConstraint.cpp | 10 +++ src/Mod/Fem/Gui/TaskFemConstraint.h | 1 + src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp | 4 + src/Mod/Fem/Gui/TaskFemConstraintForce.cpp | 14 +++- src/Mod/Fem/Gui/TaskFemConstraintPressure.cpp | 17 ++++- .../Gui/ViewProviderFemConstraintFixed.cpp | 13 ++-- .../Gui/ViewProviderFemConstraintForce.cpp | 19 +++-- .../Gui/ViewProviderFemConstraintPressure.cpp | 32 ++++++-- 14 files changed, 182 insertions(+), 33 deletions(-) diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index 48ad96a6e..e6eb67e16 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -57,6 +57,7 @@ #include #include #include +#include //OvG: Required for log10 using namespace Fem; @@ -71,6 +72,7 @@ Constraint::Constraint() { ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3d(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid"); + ADD_PROPERTY_TYPE(Scale,(1),"Base",App::PropertyType(App::Prop_Output),"Scale used for drawing constraints"); //OvG: Add scale parameter inherited by all derived constraints } Constraint::~Constraint() @@ -80,12 +82,29 @@ Constraint::~Constraint() App::DocumentObjectExecReturn *Constraint::execute(void) { References.touch(); + Scale.touch(); return StdReturn; } +//OvG: Provide the ability to determine how big to draw constraint arrows etc. +int Constraint::calcDrawScaleFactor(double lparam) const +{ + return ((int)round(log(lparam)*log(lparam)*log(lparam)/10)>1)?((int)round(log(lparam)*log(lparam)*log(lparam)/10)):1; +} + +int Constraint::calcDrawScaleFactor(double lvparam, double luparam) const +{ + return calcDrawScaleFactor((lvparam+luparam)/2.0); +} + +int Constraint::calcDrawScaleFactor() const +{ + return 1; +} +#define CONSTRAINTSTEPLIMIT 50 + void Constraint::onChanged(const App::Property* prop) { - //Base::Console().Error("Constraint::onChanged() %s\n", prop->getName()); if (prop == &References) { // If References are changed, recalculate the normal direction. If no useful reference is found, // use z axis or previous value. If several faces are selected, only the first one is used @@ -131,7 +150,7 @@ void Constraint::onDocumentRestored() App::DocumentObject::onDocumentRestored(); } -const bool Constraint::getPoints(std::vector &points, std::vector &normals) const +const bool Constraint::getPoints(std::vector &points, std::vector &normals, int * scale) const { std::vector Objects = References.getValues(); std::vector SubElements = References.getSubValues(); @@ -152,6 +171,11 @@ const bool Constraint::getPoints(std::vector &points, std::vecto gp_Pnt p = BRep_Tool::Pnt(vertex); points.push_back(Base::Vector3d(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._Shape, props); + double lx = props.Mass(); + *scale = this->calcDrawScaleFactor(sqrt(lx)); //OvG: setup draw scale for constraint } else if (sh.ShapeType() == TopAbs_EDGE) { BRepAdaptor_Curve curve(TopoDS::Edge(sh)); double fp = curve.FirstParameter(); @@ -161,10 +185,23 @@ const bool Constraint::getPoints(std::vector &points, std::vecto double l = props.Mass(); // Create points with 10 units distance, but at least one at the beginning and end of the edge int steps; - if (l >= 20) + if (l >= 100) //OvG: Increase 10 units distance proportionately to l for larger objects. + { + *scale = this->calcDrawScaleFactor(l); //OvG: setup draw scale for constraint + steps = (int)round(l / (10*( *scale))); + steps = steps<3?3:steps; + } + else if (l >= 20) + { steps = (int)round(l / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } else + { steps = 1; + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + steps = steps>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:steps; //OvG: Place upper limit on number of steps double step = (lp - fp) / steps; for (int i = 0; i < steps + 1; i++) { gp_Pnt p = curve.Value(i * step); @@ -195,15 +232,41 @@ const bool Constraint::getPoints(std::vector &points, std::vecto isoc.Load(GeomAbs_IsoV, ulp); double lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; int stepsv; - if (lv >= 20.0) + if (lv >= 100) //OvG: Increase 10 units distance proportionately to lv for larger objects. + { + *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint + stepsv = (int)round(lv / (10*( *scale))); + stepsv = stepsv<3?3:stepsv; + } + else if (lv >= 20.0) + { stepsv = (int)round(lv / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } else + { stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + stepsv = stepsv>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsv; //OvG: Place upper limit on number of steps int stepsu; - if (lu >= 20.0) + if (lu >= 100) //OvG: Increase 10 units distance proportionately to lu for larger objects. + { + *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint + stepsu = (int)round(lu / (10*( *scale))); + stepsu = stepsu<3?3:stepsu; + } + else if (lu >= 20.0) + { stepsu = (int)round(lu / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } else + { stepsu = 2; + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + stepsu = stepsu>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsu; //OvG: Place upper limit on number of steps double stepv = (vlp - vfp) / stepsv; double stepu = (ulp - ufp) / stepsu; // Create points and normals diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index a0ba40911..facc0c665 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -44,6 +44,9 @@ public: App::PropertyLinkSubList References; // Read-only (calculated values). These trigger changes in the ViewProvider App::PropertyVector NormalDirection; + + //OvG: Scale + App::PropertyInteger Scale; /// recalculate the object virtual App::DocumentObjectExecReturn *execute(void); @@ -52,6 +55,11 @@ public: virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemConstraint"; } + + //OvG: Allow automatic determination of scaling of constraint drawings, e.g. arrow length and size + int calcDrawScaleFactor(double lparam) const; + int calcDrawScaleFactor(double lvparam, double luparam) const; + int calcDrawScaleFactor() const; protected: virtual void onChanged(const App::Property* prop); @@ -59,7 +67,7 @@ protected: protected: /// Calculate the points where symbols should be drawn - const bool getPoints(std::vector& points, std::vector& normals) const; + const bool getPoints(std::vector& points, std::vector& normals, int * scale) const; //OvG: added scale parameter const bool getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const; Base::Vector3d getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, const App::PropertyLinkSub &location, const double& dist); diff --git a/src/Mod/Fem/App/FemConstraintFixed.cpp b/src/Mod/Fem/App/FemConstraintFixed.cpp index dcd5ab33b..afb984694 100644 --- a/src/Mod/Fem/App/FemConstraintFixed.cpp +++ b/src/Mod/Fem/App/FemConstraintFixed.cpp @@ -75,9 +75,11 @@ void ConstraintFixed::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - if (getPoints(points, normals)) { + int scale = 1; //OvG: Enforce use of scale + if (getPoints(points, normals, &scale)) { Points.setValues(points); Normals.setValues(normals); + Scale.setValue(scale); //OvG: Scale Points.touch(); // This triggers ViewProvider::updateData() } } diff --git a/src/Mod/Fem/App/FemConstraintForce.cpp b/src/Mod/Fem/App/FemConstraintForce.cpp index 3a30b1192..a0a91e3d3 100644 --- a/src/Mod/Fem/App/FemConstraintForce.cpp +++ b/src/Mod/Fem/App/FemConstraintForce.cpp @@ -70,8 +70,11 @@ void ConstraintForce::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - if (getPoints(points, normals)) { + int scale = 1; //OvG: Enforce use of scale + if (getPoints(points, normals, &scale)) { Points.setValues(points); // We don't use the normals because all arrows should have the same direction + Scale.setValue(scale); //OvG Scale + Points.touch(); } } else if (prop == &Direction) { Base::Vector3d direction = getDirection(Direction); diff --git a/src/Mod/Fem/App/FemConstraintPressure.cpp b/src/Mod/Fem/App/FemConstraintPressure.cpp index 9d1cafc67..ebdecdecd 100644 --- a/src/Mod/Fem/App/FemConstraintPressure.cpp +++ b/src/Mod/Fem/App/FemConstraintPressure.cpp @@ -70,9 +70,11 @@ void ConstraintPressure::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - if (getPoints(points, normals)) { + int scale = Scale.getValue(); + if (getPoints(points, normals, &scale)) { Points.setValues(points); Normals.setValues(normals); + Scale.setValue(scale); Points.touch(); } } else if (prop == &Reversed) { diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 20fd1b66b..71867b5b3 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -315,6 +315,7 @@ void CmdFemConstraintFixed::activated(int iMsg) openCommand("Make FEM constraint fixed geometry"); doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintFixed\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); updateActive(); @@ -353,7 +354,9 @@ void CmdFemConstraintForce::activated(int iMsg) openCommand("Make FEM constraint force on geometry"); doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintForce\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Force = 0.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Force = 1.0",FeatName.c_str()); //OvG: set default not equal to 0 + doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); updateActive(); @@ -392,7 +395,9 @@ void CmdFemConstraintPressure::activated(int iMsg) openCommand("Make FEM constraint pressure on face"); doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPressure\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Pressure = 0.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Pressure = 1000.0",FeatName.c_str()); //OvG: set default not equal to 0 + doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); updateActive(); diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.cpp b/src/Mod/Fem/Gui/TaskFemConstraint.cpp index d0dfe5419..000b3bd1d 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraint.cpp @@ -56,6 +56,8 @@ #include +# include //OvG conversion between string and int etc. + using namespace FemGui; using namespace Gui; @@ -113,6 +115,14 @@ const std::string TaskFemConstraint::getReferences(const std::vector(ConstraintView->getObject()); + result = boost::lexical_cast(pcConstraint->Scale.getValue()); + return result; +} + void TaskFemConstraint::onReferenceDeleted(const int row) { Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); std::vector Objects = pcConstraint->References.getValues(); diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.h b/src/Mod/Fem/Gui/TaskFemConstraint.h index 4ba739272..275c38f76 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.h +++ b/src/Mod/Fem/Gui/TaskFemConstraint.h @@ -42,6 +42,7 @@ public: virtual const std::string getReferences(void) const {return std::string();} const std::string getReferences(const std::vector& items) const; + const std::string getScale() const; protected Q_SLOTS: void onReferenceDeleted(const int row); diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp index 985a73d4f..3a2627087 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp @@ -215,6 +215,10 @@ TaskDlgFemConstraintFixed::TaskDlgFemConstraintFixed(ViewProviderFemConstraintFi bool TaskDlgFemConstraintFixed::accept() { + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintFixed* parameterFixed = static_cast(parameter); + std::string scale = parameterFixed->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale return TaskDlgFemConstraint::accept(); } diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp index e58841bc6..1e83b2b1d 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp @@ -352,10 +352,19 @@ bool TaskDlgFemConstraintForce::accept() try { //Gui::Command::openCommand("FEM force constraint changed"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterForce->getForce()); + if (parameterForce->getForce()<=0) + { + QMessageBox::warning(parameter, tr("Input error"), tr("Please specify a force greater than 0")); + return false; + } + else + { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterForce->getForce()); + } std::string dirname = parameterForce->getDirectionName().data(); std::string dirobj = parameterForce->getDirectionObject().data(); + std::string scale = "1"; if (!dirname.empty()) { QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); @@ -367,6 +376,9 @@ bool TaskDlgFemConstraintForce::accept() } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterForce->getReverse() ? "True" : "False"); + + scale = parameterForce->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale } catch (const Base::Exception& e) { QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); diff --git a/src/Mod/Fem/Gui/TaskFemConstraintPressure.cpp b/src/Mod/Fem/Gui/TaskFemConstraintPressure.cpp index 995372dea..cc276b2c8 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintPressure.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintPressure.cpp @@ -249,12 +249,25 @@ bool TaskDlgFemConstraintPressure::accept() { std::string name = ConstraintView->getObject()->getNameInDocument(); const TaskFemConstraintPressure* parameterPressure = static_cast(parameter); + std::string scale = "1"; try { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Pressure = %f", - name.c_str(), parameterPressure->getPressure()); + if (parameterPressure->getPressure()<=0) + { + QMessageBox::warning(parameter, tr("Input error"), tr("Please specify a pressure greater than 0")); + return false; + } + else + { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Pressure = %f", + name.c_str(), parameterPressure->getPressure()); + } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterPressure->getReverse() ? "True" : "False"); + + scale = parameterPressure->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", + name.c_str(), scale.c_str()); //OvG: implement modified scale } catch (const Base::Exception& e) { QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp index 792a235b4..7d2080876 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp @@ -107,19 +107,22 @@ bool ViewProviderFemConstraintFixed::setEdit(int ModNum) #define HEIGHT 4 #define WIDTH (1.5*HEIGHT) -#define USE_MULTIPLE_COPY +//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - so disable void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) { // Gets called whenever a property of the attached object changes Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); + float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); #ifdef USE_MULTIPLE_COPY + //OvG: always need access to cp for scaling + SoMultipleCopy* cp = new SoMultipleCopy(); if (pShapeSep->getNumChildren() == 0) { // Set up the nodes - SoMultipleCopy* cp = new SoMultipleCopy(); cp->matrix.setNum(0); - cp->addChild((SoNode*)createFixed(HEIGHT, WIDTH)); + cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); //OvG: Scaling pShapeSep->addChild(cp); } #endif @@ -132,7 +135,7 @@ void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) std::vector::const_iterator n = normals.begin(); #ifdef USE_MULTIPLE_COPY - SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp = static_cast(pShapeSep->getChild(0)); cp->matrix.setNum(points.size()); SbMatrix* matrices = cp->matrix.startEditing(); int idx = 0; @@ -153,7 +156,7 @@ void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) #else SoSeparator* sep = new SoSeparator(); createPlacement(sep, base, rot); - createFixed(sep, HEIGHT, WIDTH); + createFixed(sep, scaledheight, scaledwidth); //OvG: Scaling pShapeSep->addChild(sep); #endif n++; diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp index 208005846..ba8ffb4df 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp @@ -107,19 +107,22 @@ bool ViewProviderFemConstraintForce::setEdit(int ModNum) #define ARROWLENGTH 9 #define ARROWHEADRADIUS (ARROWLENGTH/3) -#define USE_MULTIPLE_COPY +//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so disable void ViewProviderFemConstraintForce::updateData(const App::Property* prop) { // Gets called whenever a property of the attached object changes Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); + float scaledheadradius = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); #ifdef USE_MULTIPLE_COPY + //OvG: need access to cp for scaling + SoMultipleCopy* cp = new SoMultipleCopy(); if (pShapeSep->getNumChildren() == 0) { // Set up the nodes - SoMultipleCopy* cp = new SoMultipleCopy(); cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(ARROWLENGTH, ARROWHEADRADIUS)); + cp->addChild((SoNode*)createArrow(scaledlength , scaledheadradius)); //OvG: Scaling pShapeSep->addChild(cp); } #endif @@ -128,7 +131,7 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) const std::vector& points = pcConstraint->Points.getValues(); #ifdef USE_MULTIPLE_COPY - SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp = static_cast(pShapeSep->getChild(0)); cp->matrix.setNum(points.size()); SbMatrix* matrices = cp->matrix.startEditing(); int idx = 0; @@ -150,7 +153,7 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { SbVec3f base(p->x, p->y, p->z); if (forceDirection.GetAngle(normal) < M_PI_2) // Move arrow so it doesn't disappear inside the solid - base = base + dir * ARROWLENGTH; + base = base + dir * scaledlength; //OvG: Scaling #ifdef USE_MULTIPLE_COPY SbMatrix m; m.setTransform(base, rot, SbVec3f(1,1,1)); @@ -159,7 +162,7 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) #else SoSeparator* sep = new SoSeparator(); createPlacement(sep, base, rot); - createArrow(sep, ARROWLENGTH, ARROWHEADRADIUS); + createArrow(sep, scaledlength, scaledheadradius); //OvG: Scaling pShapeSep->addChild(sep); #endif } @@ -189,7 +192,7 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { SbVec3f base(p->x, p->y, p->z); if (forceDirection.GetAngle(normal) < M_PI_2) - base = base + dir * ARROWLENGTH; + base = base + dir * scaledlength; //OvG: Scaling #ifdef USE_MULTIPLE_COPY SbMatrix m; m.setTransform(base, rot, SbVec3f(1,1,1)); @@ -197,7 +200,7 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) #else SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); updatePlacement(sep, 0, base, rot); - updateArrow(sep, 2, ARROWLENGTH, ARROWHEADRADIUS); + updateArrow(sep, 2, scaledlength, scaledheadradius); //OvG: Scaling #endif idx++; } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp index f586ef25a..b87a2c3b5 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPressure.cpp @@ -89,21 +89,27 @@ bool ViewProviderFemConstraintPressure::setEdit(int ModNum) } } -#define ARROWLENGTH 5 -#define ARROWHEADRADIUS 3 +#define ARROWLENGTH (6) +#define ARROWHEADRADIUS (ARROWLENGTH/3) +//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so disable void ViewProviderFemConstraintPressure::updateData(const App::Property* prop) { // Gets called whenever a property of the attached object changes Fem::ConstraintPressure* pcConstraint = static_cast(this->getObject()); + float scaledheadradius = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); +#ifdef USE_MULTIPLE_COPY + //OvG: always need access to cp for scaling + SoMultipleCopy* cp = new SoMultipleCopy(); if (pShapeSep->getNumChildren() == 0) { // Set up the nodes - SoMultipleCopy* cp = new SoMultipleCopy(); cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(ARROWLENGTH, ARROWHEADRADIUS)); + cp->addChild((SoNode*)createArrow(scaledlength , scaledheadradius)); //OvG: Scaling pShapeSep->addChild(cp); } +#endif if (strcmp(prop->getName(),"Points") == 0) { const std::vector& points = pcConstraint->Points.getValues(); @@ -113,29 +119,43 @@ void ViewProviderFemConstraintPressure::updateData(const App::Property* prop) } std::vector::const_iterator n = normals.begin(); - SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); +#ifdef USE_MULTIPLE_COPY + cp = static_cast(pShapeSep->getChild(0)); //OvG: Use top cp cp->matrix.setNum(points.size()); SbMatrix* matrices = cp->matrix.startEditing(); int idx = 0; +#else + // Redraw all arrows + pShapeSep->removeAllChildren(); +#endif for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { SbVec3f base(p->x, p->y, p->z); SbVec3f dir(n->x, n->y, n->z); double rev; if (pcConstraint->Reversed.getValue()) { - base = base + dir * ARROWLENGTH; + base = base + dir * scaledlength; //OvG: Scaling rev = 1; } else { rev = -1; } SbRotation rot(SbVec3f(0, rev, 0), dir); +#ifdef USE_MULTIPLE_COPY SbMatrix m; m.setTransform(base, rot, SbVec3f(1,1,1)); matrices[idx] = m; idx++; +#else + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, base, rot); + createArrow(sep, scaledlength , scaledheadradius); //OvG: Scaling + pShapeSep->addChild(sep); +#endif n++; } +#ifdef USE_MULTIPLE_COPY cp->matrix.finishEditing(); +#endif } ViewProviderFemConstraint::updateData(prop);