Fixed problems with loading of FEM constraint objects

This commit is contained in:
jrheinlaender
2013-02-22 16:16:03 +04:30
parent d48542cf56
commit 517443fb59
13 changed files with 72 additions and 41 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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()
}
}
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();

View File

@@ -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++;
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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);
}