From 517443fb595b3beca0aba034e993d950e159ba0f Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Fri, 22 Feb 2013 16:16:03 +0430 Subject: [PATCH] Fixed problems with loading of FEM constraint objects --- src/Mod/Fem/App/FemConstraint.cpp | 34 +++++++++++-------- src/Mod/Fem/App/FemConstraint.h | 5 ++- src/Mod/Fem/App/FemConstraintBearing.cpp | 10 +++--- src/Mod/Fem/App/FemConstraintFixed.cpp | 9 ++--- src/Mod/Fem/App/FemConstraintForce.cpp | 7 ++-- src/Mod/Fem/Gui/TaskFemConstraint.h | 6 ++-- src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp | 2 ++ src/Mod/Fem/Gui/ViewProviderFemConstraint.h | 6 ++-- .../Gui/ViewProviderFemConstraintBearing.cpp | 8 +++-- .../Gui/ViewProviderFemConstraintFixed.cpp | 16 ++++++++- .../Gui/ViewProviderFemConstraintForce.cpp | 2 ++ .../Fem/Gui/ViewProviderFemConstraintGear.cpp | 4 +-- .../Gui/ViewProviderFemConstraintPulley.cpp | 4 +-- 13 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index 008c0ec2a3..98d7fc92f1 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -78,9 +78,8 @@ App::DocumentObjectExecReturn *Constraint::execute(void) void Constraint::onChanged(const App::Property* prop) { - //Base::Console().Error("Constraint::onChanged()\n"); + Base::Console().Error("Constraint::onChanged() %s\n", prop->getName()); if (prop == &References) { - Base::Console().Error("References\n"); // 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 std::vector Objects = References.getValues(); @@ -108,28 +107,24 @@ void Constraint::onChanged(const App::Property* prop) normal.Normalize(); NormalDirection.setValue(normal.X(), normal.Y(), normal.Z()); // One face is enough... - DocumentObject::onChanged(prop); + App::DocumentObject::onChanged(prop); return; } } } } - DocumentObject::onChanged(prop); + App::DocumentObject::onChanged(prop); } void Constraint::onDocumentRestored() { - Base::Console().Error("onDocumentRestored\n"); + // This seems to be the only way to make the ViewProvider display the constraint + References.touch(); + App::DocumentObject::onDocumentRestored(); } - -void Constraint::onSettingDocument() -{ - Base::Console().Error("onSettingDocument\n"); -} - -void Constraint::getPoints(std::vector &points, std::vector &normals) const +const bool Constraint::getPoints(std::vector &points, std::vector &normals) const { std::vector Objects = References.getValues(); std::vector SubElements = References.getSubValues(); @@ -141,6 +136,8 @@ void Constraint::getPoints(std::vector &points, std::vector(obj); const Part::TopoShape& toposhape = feat->Shape.getShape(); + if (toposhape.isNull()) + return false; sh = toposhape.getSubShape(SubElements[i].c_str()); if (sh.ShapeType() == TopAbs_VERTEX) { @@ -219,17 +216,22 @@ void Constraint::getPoints(std::vector &points, std::vector Objects = References.getValues(); std::vector SubElements = References.getSubValues(); if (Objects.empty()) - return; + return false; App::DocumentObject* obj = Objects[0]; Part::Feature* feat = static_cast(obj); - TopoDS_Shape sh = feat->Shape.getShape().getSubShape(SubElements[0].c_str()); + 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); @@ -243,6 +245,8 @@ void Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, base = Base::Vector3f(b.X(), b.Y(), b.Z()); gp_Dir dir = cyl.Axis().Direction(); axis = Base::Vector3f(dir.X(), dir.Y(), dir.Z()); + + return true; } Base::Vector3f Constraint::getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis, diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index 02c0bfd9d5..1814183278 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -55,12 +55,11 @@ public: protected: virtual void onChanged(const App::Property* prop); virtual void onDocumentRestored(); - virtual void onSettingDocument(); protected: /// Calculate the points where symbols should be drawn - void getPoints(std::vector& points, std::vector& normals) const; - void getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const; + const bool getPoints(std::vector& points, std::vector& normals) const; + const bool getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const; Base::Vector3f getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis, const App::PropertyLinkSub &location, const float& dist); diff --git a/src/Mod/Fem/App/FemConstraintBearing.cpp b/src/Mod/Fem/App/FemConstraintBearing.cpp index 3ecf7ea4c4..51aa790d0d 100644 --- a/src/Mod/Fem/App/FemConstraintBearing.cpp +++ b/src/Mod/Fem/App/FemConstraintBearing.cpp @@ -58,11 +58,13 @@ ConstraintBearing::ConstraintBearing() App::DocumentObjectExecReturn *ConstraintBearing::execute(void) { + Base::Console().Error("ConstraintBearing: execute()\n"); return Constraint::execute(); } void ConstraintBearing::onChanged(const App::Property* prop) { + Base::Console().Error("ConstraintBearing: onChanged %s\n", prop->getName()); // Note: If we call this at the end, then the symbol ist not oriented correctly initially // because the NormalDirection has not been calculated yet Constraint::onChanged(prop); @@ -71,7 +73,8 @@ void ConstraintBearing::onChanged(const App::Property* prop) // Find data of cylinder float radius, height; Base::Vector3f base, axis; - getCylinder(radius, height, base, axis); + if (!getCylinder(radius, height, base, axis)) + return; Radius.setValue(radius); Axis.setValue(axis); Height.setValue(height); @@ -80,7 +83,6 @@ void ConstraintBearing::onChanged(const App::Property* prop) if (Location.getValue() != NULL) { base = getBasePoint(base, axis, Location, Dist.getValue()); } - Base::Console().Error("Basepoint2: %f, %f, %f\n", base.x, base.y, base.z); BasePoint.setValue(base); BasePoint.touch(); // This triggers ViewProvider::updateData() } else if ((prop == &Location) || (prop == &Dist)) { @@ -107,9 +109,9 @@ void ConstraintBearing::onChanged(const App::Property* prop) float radius, height; Base::Vector3f base, axis; - getCylinder(radius, height, base, axis); + if (!getCylinder(radius, height, base, axis)) + return; base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue()); - Base::Console().Error("Basepoint: %f, %f, %f\n", base.x, base.y, base.z); BasePoint.setValue(base); BasePoint.touch(); } diff --git a/src/Mod/Fem/App/FemConstraintFixed.cpp b/src/Mod/Fem/App/FemConstraintFixed.cpp index 1cde0061fa..762b63d891 100644 --- a/src/Mod/Fem/App/FemConstraintFixed.cpp +++ b/src/Mod/Fem/App/FemConstraintFixed.cpp @@ -75,9 +75,10 @@ void ConstraintFixed::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - getPoints(points, normals); - Points.setValues(points); - Normals.setValues(normals); - Points.touch(); // This triggers ViewProvider::updateData() + if (getPoints(points, normals)) { + Points.setValues(points); + Normals.setValues(normals); + Points.touch(); // This triggers ViewProvider::updateData() + } } } diff --git a/src/Mod/Fem/App/FemConstraintForce.cpp b/src/Mod/Fem/App/FemConstraintForce.cpp index 2fa97b7778..034acaae96 100644 --- a/src/Mod/Fem/App/FemConstraintForce.cpp +++ b/src/Mod/Fem/App/FemConstraintForce.cpp @@ -70,9 +70,10 @@ void ConstraintForce::onChanged(const App::Property* prop) if (prop == &References) { std::vector points; std::vector normals; - getPoints(points, normals); - Points.setValues(points); // We don't use the normals because all arrows should have the same direction - Points.touch(); // This triggers ViewProvider::updateData() + if (getPoints(points, normals)) { + Points.setValues(points); // We don't use the normals because all arrows should have the same direction + Points.touch(); // This triggers ViewProvider::updateData() + } } else if (prop == &Direction) { App::DocumentObject* obj = Direction.getValue(); std::vector names = Direction.getSubValues(); diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.h b/src/Mod/Fem/Gui/TaskFemConstraint.h index f4d7ee0bde..ada7965734 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.h +++ b/src/Mod/Fem/Gui/TaskFemConstraint.h @@ -56,11 +56,11 @@ protected Q_SLOTS: void onButtonReference(const bool pressed = true); protected: - virtual void changeEvent(QEvent *e) {} + virtual void changeEvent(QEvent *e) { TaskBox::changeEvent(e); } const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const; private: - virtual void onSelectionChanged(const Gui::SelectionChanges& msg) {} + virtual void onSelectionChanged(const Gui::SelectionChanges&) {} protected: QWidget* proxy; @@ -74,11 +74,13 @@ class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog Q_OBJECT public: + /* /// is called the TaskView when the dialog is opened virtual void open() {} /// is called by the framework if an button is clicked which has no accept or reject role virtual void clicked(int) {} /// is called by the framework if the dialog is accepted (Ok) + */ virtual bool accept(); /// is called by the framework if the dialog is rejected (Cancel) virtual bool reject(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp index 4bb6dabe31..778b59b3af 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp @@ -36,6 +36,7 @@ # include # include # include +# include #endif #include "ViewProviderFemConstraint.h" @@ -94,6 +95,7 @@ ViewProviderFemConstraint::~ViewProviderFemConstraint() void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) { + Base::Console().Error("VP FemConstraint attach %s\n", pcObject->getNameInDocument()); ViewProviderDocumentObject::attach(pcObject); SoPickStyle* ps = new SoPickStyle(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h index 09ca86eaf6..015f8d38c4 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h @@ -64,7 +64,7 @@ public: App::PropertyBool Mirror; void attach(App::DocumentObject *); - virtual void updateData(const App::Property*) {} + virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); } std::vector getDisplayModes(void) const; void setDisplayMode(const char* ModeName); @@ -73,7 +73,7 @@ public: protected: void onChanged(const App::Property* prop); - virtual bool setEdit(int ModNum) {} + virtual bool setEdit(int ModNum) { return Gui::ViewProviderGeometryObject::setEdit(ModNum); } virtual void unsetEdit(int ModNum); static void createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r); @@ -90,7 +90,7 @@ protected: 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 createFixed(SoSeparator* sep, const double height, const double width, const bool gap); + 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); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp index bf6a7cf412..f19849181f 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp @@ -97,13 +97,17 @@ bool ViewProviderFemConstraintBearing::setEdit(int ModNum) void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) { - // Gets called whenever a property of the attached object changes - Fem::ConstraintBearing* pcConstraint = static_cast(this->getObject()); if (this->getObject() != NULL) Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); else Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName()); + // Gets called whenever a property of the attached object changes + Fem::ConstraintBearing* pcConstraint = static_cast(this->getObject()); + + if (strcmp(prop->getName(),"References") == 0) + Base::Console().Error("\n"); // enable a breakpoint here + if (strcmp(prop->getName(),"BasePoint") == 0) { // Remove and recreate the symbol pShapeSep->removeAllChildren(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp index 74727e5ac3..88fdf84cb7 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp @@ -112,6 +112,9 @@ void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); + /* + // This has a HUGE performance penalty as opposed to separate nodes for every symbol + // The problem seems to be SoCone if (pShapeSep->getNumChildren() == 0) { // Set up the nodes SoMultipleCopy* cp = new SoMultipleCopy(); @@ -120,26 +123,37 @@ void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) cp->addChild((SoNode*)createFixed(HEIGHT, WIDTH)); pShapeSep->addChild(cp); } + */ if (strcmp(prop->getName(),"Points") == 0) { // Note: Points and Normals are always updated together + pShapeSep->removeAllChildren(); const std::vector& points = pcConstraint->Points.getValues(); const std::vector& normals = pcConstraint->Normals.getValues(); std::vector::const_iterator n = normals.begin(); + /* SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); cp->matrix.setNum(points.size()); int idx = 0; + */ 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); SbRotation rot(SbVec3f(0,-1,0), dir); + /* SbMatrix m; m.setTransform(base, rot, SbVec3f(1,1,1)); cp->matrix.set1Value(idx, m); + idx++ + */ + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, base, rot); + createFixed(sep, HEIGHT, WIDTH); + pShapeSep->addChild(sep); + n++; - idx++; } } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp index b29a65f9a5..8003f45e8b 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp @@ -111,6 +111,8 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop) Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); /* + // This has a HUGE performance penalty as opposed to separate nodes for every symbol + // The problem seems to be SoCone if (pShapeSep->getNumChildren() == 0) { // Set up the nodes SoMultipleCopy* cp = new SoMultipleCopy(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp index 16ff06f50a..e30aecb78c 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp @@ -123,7 +123,7 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop) createPlacement(pShapeSep, b, rot); pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); - createPlacement(pShapeSep, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0))); + createPlacement(pShapeSep, SbVec3f(-dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(0,0,1))); pShapeSep->addChild(createArrow(dia/2, dia/8)); } } else if (strcmp(prop->getName(),"Diameter") == 0) { @@ -144,7 +144,7 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop) updatePlacement(pShapeSep, 0, b, rot); const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); - updatePlacement(pShapeSep, 3, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0))); + updatePlacement(pShapeSep, 3, SbVec3f(-dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(0,0,1))); sep = static_cast(pShapeSep->getChild(5)); updateArrow(sep, 0, dia/2, dia/8); } diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp index abdd3ec3e3..df47623648 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp @@ -152,11 +152,11 @@ 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); sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, 0, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,sin(angle)))); + updatePlacement(sep, 0, SbVec3f(dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(sin(angle),0,cos(angle)))); const SoSeparator* subsep = static_cast(sep->getChild(2)); updateArrow(subsep, 0, dia/2, dia/8); sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, 0, SbVec3f(0,0,-dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,-sin(angle)))); + updatePlacement(sep, 0, SbVec3f(-dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(angle),0,cos(angle)))); subsep = static_cast(sep->getChild(2)); updateArrow(subsep, 0, dia/2, dia/8); }