Fixed problems with loading of FEM constraint objects
This commit is contained in:
@@ -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<App::DocumentObject*> 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<Base::Vector3f> &points, std::vector<Base::Vector3f> &normals) const
|
||||
const bool Constraint::getPoints(std::vector<Base::Vector3f> &points, std::vector<Base::Vector3f> &normals) const
|
||||
{
|
||||
std::vector<App::DocumentObject*> Objects = References.getValues();
|
||||
std::vector<std::string> SubElements = References.getSubValues();
|
||||
@@ -141,6 +136,8 @@ void Constraint::getPoints(std::vector<Base::Vector3f> &points, std::vector<Base
|
||||
App::DocumentObject* obj = Objects[i];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(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<Base::Vector3f> &points, std::vector<Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const
|
||||
const bool Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const
|
||||
{
|
||||
std::vector<App::DocumentObject*> Objects = References.getValues();
|
||||
std::vector<std::string> SubElements = References.getSubValues();
|
||||
if (Objects.empty())
|
||||
return;
|
||||
return false;
|
||||
App::DocumentObject* obj = Objects[0];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(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,
|
||||
|
||||
@@ -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<Base::Vector3f>& points, std::vector<Base::Vector3f>& normals) const;
|
||||
void getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const;
|
||||
const bool getPoints(std::vector<Base::Vector3f>& points, std::vector<Base::Vector3f>& 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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -75,9 +75,10 @@ void ConstraintFixed::onChanged(const App::Property* prop)
|
||||
if (prop == &References) {
|
||||
std::vector<Base::Vector3f> points;
|
||||
std::vector<Base::Vector3f> 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,10 @@ void ConstraintForce::onChanged(const App::Property* prop)
|
||||
if (prop == &References) {
|
||||
std::vector<Base::Vector3f> points;
|
||||
std::vector<Base::Vector3f> 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<std::string> names = Direction.getSubValues();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
# include <Inventor/nodes/SoCone.h>
|
||||
# include <Inventor/nodes/SoCube.h>
|
||||
# include <Inventor/nodes/SoShapeHints.h>
|
||||
# include <Inventor/nodes/SoComplexity.h>
|
||||
#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();
|
||||
|
||||
@@ -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<std::string> 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);
|
||||
|
||||
|
||||
@@ -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<Fem::ConstraintBearing*>(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<Fem::ConstraintBearing*>(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();
|
||||
|
||||
@@ -112,6 +112,9 @@ void ViewProviderFemConstraintFixed::updateData(const App::Property* prop)
|
||||
|
||||
Fem::ConstraintFixed* pcConstraint = static_cast<Fem::ConstraintFixed*>(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<Base::Vector3f>& points = pcConstraint->Points.getValues();
|
||||
const std::vector<Base::Vector3f>& normals = pcConstraint->Normals.getValues();
|
||||
std::vector<Base::Vector3f>::const_iterator n = normals.begin();
|
||||
/*
|
||||
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
|
||||
cp->matrix.setNum(points.size());
|
||||
int idx = 0;
|
||||
*/
|
||||
|
||||
for (std::vector<Base::Vector3f>::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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ void ViewProviderFemConstraintForce::updateData(const App::Property* prop)
|
||||
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(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();
|
||||
|
||||
@@ -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<SoSeparator*>(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<SoSeparator*>(pShapeSep->getChild(5));
|
||||
updateArrow(sep, 0, dia/2, dia/8);
|
||||
}
|
||||
|
||||
@@ -152,11 +152,11 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
|
||||
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
|
||||
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2);
|
||||
sep = static_cast<SoSeparator*>(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<SoSeparator*>(sep->getChild(2));
|
||||
updateArrow(subsep, 0, dia/2, dia/8);
|
||||
sep = static_cast<SoSeparator*>(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<SoSeparator*>(sep->getChild(2));
|
||||
updateArrow(subsep, 0, dia/2, dia/8);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user