Specialized viewproviders for datum features, create points from intersection of edges and faces

This commit is contained in:
jrheinlaender 2013-04-27 20:40:52 +04:30 committed by Stefan Tröger
parent 8682b5f490
commit 1c1531278c
10 changed files with 457 additions and 174 deletions

View File

@ -180,8 +180,20 @@ const bool Body::isAfterTip(const App::DocumentObject *f) {
const bool Body::isSolidFeature(const App::DocumentObject* f) const bool Body::isSolidFeature(const App::DocumentObject* f)
{ {
return (f->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) && if (f == NULL)
!f->getTypeId().isDerivedFrom(PartDesign::Datum::getClassTypeId())); return false;
return (f->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()));
}
const bool Body::isAllowed(const App::DocumentObject* f)
{
if (f == NULL)
return false;
return (f->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) ||
f->getTypeId().isDerivedFrom(PartDesign::Datum::getClassTypeId()) ||
f->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId()));
} }
Body* Body::findBodyOf(const App::DocumentObject* f) Body* Body::findBodyOf(const App::DocumentObject* f)

View File

@ -90,11 +90,17 @@ public:
/** /**
* Return true if the given feature is a solid feature allowed in a Body. Currently this is only valid * Return true if the given feature is a solid feature allowed in a Body. Currently this is only valid
* for features derived from PartDesign::Feature with the exception of PartDesign::Datum features * for features derived from PartDesign::Feature
* Return false if the given feature is a Sketch or a PartDesign::Datum feature * Return false if the given feature is a Sketch or a PartDesign::Datum feature
*/ */
static const bool isSolidFeature(const App::DocumentObject* f); static const bool isSolidFeature(const App::DocumentObject* f);
/**
* Return true if the given feature is allowed in a Body. Currently allowed are
* all features derived from PartDesign::Feature and PartDesign::Datum and sketches
*/
static const bool isAllowed(const App::DocumentObject* f);
/// Return the body which this feature belongs too, or NULL /// Return the body which this feature belongs too, or NULL
static Body* findBodyOf(const App::DocumentObject* f); static Body* findBodyOf(const App::DocumentObject* f);

View File

@ -32,14 +32,13 @@ int BodyPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
PyObject* BodyPy::addFeature(PyObject *args) PyObject* BodyPy::addFeature(PyObject *args)
{ {
PyObject* featurePy; PyObject* featurePy;
if (!PyArg_ParseTuple(args, "O!", &(Part::PartFeaturePy::Type), &featurePy)) if (!PyArg_ParseTuple(args, "O!", &(App::DocumentObjectPy::Type), &featurePy))
return 0; return 0;
Part::Feature* feature = static_cast<Part::PartFeaturePy*>(featurePy)->getFeaturePtr(); App::DocumentObject* feature = static_cast<App::DocumentObjectPy*>(featurePy)->getDocumentObjectPtr();
if (!feature->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) && if (!Body::isAllowed(feature)) {
!feature->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { PyErr_SetString(PyExc_SystemError, "Only PartDesign features, datum features and sketches can be inserted into a Body");
PyErr_SetString(PyExc_SystemError, "Only PartDesign features and sketches can be inserted into a Body");
return 0; return 0;
} }
Body* body = this->getBodyPtr(); Body* body = this->getBodyPtr();
@ -57,10 +56,10 @@ PyObject* BodyPy::addFeature(PyObject *args)
PyObject* BodyPy::removeFeature(PyObject *args) PyObject* BodyPy::removeFeature(PyObject *args)
{ {
PyObject* featurePy; PyObject* featurePy;
if (!PyArg_ParseTuple(args, "O!", &(Part::PartFeaturePy::Type), &featurePy)) if (!PyArg_ParseTuple(args, "O!", &(App::DocumentObjectPy::Type), &featurePy))
return 0; return 0;
Part::Feature* feature = static_cast<Part::PartFeaturePy*>(featurePy)->getFeaturePtr(); App::DocumentObject* feature = static_cast<App::DocumentObjectPy*>(featurePy)->getDocumentObjectPtr();
Body* body = this->getBodyPtr(); Body* body = this->getBodyPtr();
try { try {

View File

@ -30,23 +30,34 @@
# include <BRepBuilderAPI_MakeVertex.hxx> # include <BRepBuilderAPI_MakeVertex.hxx>
# include <BRepBuilderAPI_MakeWire.hxx> # include <BRepBuilderAPI_MakeWire.hxx>
# include <BRepBuilderAPI_GTransform.hxx> # include <BRepBuilderAPI_GTransform.hxx>
# include <BRep_Tool.hxx>
# include <gp_GTrsf.hxx> # include <gp_GTrsf.hxx>
# include <Geom_Plane.hxx> # include <Geom_Plane.hxx>
# include <Geom2d_Line.hxx> # include <Geom2d_Line.hxx>
# include <Handle_Geom_Curve.hxx>
# include <Handle_Geom_Surface.hxx>
# include <Handle_Geom_Plane.hxx> # include <Handle_Geom_Plane.hxx>
# include <Handle_Geom2d_Line.hxx> # include <Handle_Geom2d_Line.hxx>
# include <GeomAPI_IntCS.hxx>
# include <GeomAPI_IntSS.hxx>
# include <GeomAPI_ExtremaCurveCurve.hxx>
# include <Precision.hxx> # include <Precision.hxx>
# include <Standard_Real.hxx> # include <Standard_Real.hxx>
# include <TopoDS.hxx> # include <TopoDS.hxx>
# include <TopoDS_Vertex.hxx> # include <TopoDS_Vertex.hxx>
# include <TopoDS_Edge.hxx>
# include <TopoDS_Face.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Standard_Version.hxx> # include <Standard_Version.hxx>
#endif #endif
#include <QObject>
#include <App/Plane.h> #include <App/Plane.h>
#include "DatumFeature.h" #include "DatumFeature.h"
#include <Base/Tools.h> #include <Base/Tools.h>
#include <Base/Exception.h> #include <Base/Exception.h>
#include <Base/Console.h>
#include "Mod/Part/App/PrimitiveFeature.h" #include "Mod/Part/App/PrimitiveFeature.h"
#ifndef M_PI #ifndef M_PI
@ -55,7 +66,7 @@
using namespace PartDesign; using namespace PartDesign;
PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, PartDesign::Feature) PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, App::DocumentObject)
Datum::Datum(void) Datum::Datum(void)
{ {
@ -68,12 +79,11 @@ Datum::~Datum()
{ {
} }
short Datum::mustExecute(void) const
App::DocumentObjectExecReturn *Datum::execute(void)
{ {
if (References.isTouched() || References.touch();
Values.isTouched()) return StdReturn;
return 1;
return Feature::mustExecute();
} }
void Datum::onChanged(const App::Property* prop) void Datum::onChanged(const App::Property* prop)
@ -88,16 +98,22 @@ void Datum::onChanged(const App::Property* prop)
refTypes.insert(getRefType(refs[r], refnames[r])); refTypes.insert(getRefType(refs[r], refnames[r]));
} }
PartDesign::Feature::onChanged(prop); App::DocumentObject::onChanged(prop);
}
void Datum::onDocumentRestored()
{
// This seems to be the only way to make the ViewProvider display the datum feature
References.touch();
App::DocumentObject::onDocumentRestored();
} }
// Note: We don't distinguish between e.g. datum lines and edges here // Note: We don't distinguish between e.g. datum lines and edges here
// These values are just markers so it doesn't matter that they are Part features #define PLANE QObject::tr("DPLANE")
#define PLANE Part::Plane::getClassTypeId() #define LINE QObject::tr("DLINE")
#define LINE Part::Line::getClassTypeId() #define POINT QObject::tr("DPOINT")
#define POINT Part::Vertex::getClassTypeId()
const Base::Type Datum::getRefType(const App::DocumentObject* obj, const std::string& subname) const QString Datum::getRefType(const App::DocumentObject* obj, const std::string& subname)
{ {
Base::Type type = obj->getTypeId(); Base::Type type = obj->getTypeId();
@ -122,15 +138,15 @@ const Base::Type Datum::getRefType(const App::DocumentObject* obj, const std::st
// ================================ Initialize the hints ===================== // ================================ Initialize the hints =====================
std::map<std::multiset<Base::Type>, std::set<Base::Type> > Point::hints = std::map<std::multiset<Base::Type>, std::set<Base::Type> >(); std::map<std::multiset<QString>, std::set<QString> > Point::hints = std::map<std::multiset<QString>, std::set<QString> >();
void Point::initHints() void Point::initHints()
{ {
std::set<Base::Type> DONE; std::set<QString> DONE;
DONE.insert(PartDesign::Point::getClassTypeId()); DONE.insert(QObject::tr("Point"));
std::multiset<Base::Type> key; std::multiset<QString> key;
std::set<Base::Type> value; std::set<QString> value;
key.insert(POINT); key.insert(POINT);
hints[key] = DONE; // POINT -> DONE. Point from another point or vertex hints[key] = DONE; // POINT -> DONE. Point from another point or vertex
@ -166,15 +182,15 @@ void Point::initHints()
hints[key] = value; hints[key] = value;
} }
std::map<std::multiset<Base::Type>, std::set<Base::Type> > Line::hints = std::map<std::multiset<Base::Type>, std::set<Base::Type> >(); std::map<std::multiset<QString>, std::set<QString> > Line::hints = std::map<std::multiset<QString>, std::set<QString> >();
void Line::initHints() void Line::initHints()
{ {
std::set<Base::Type> DONE; std::set<QString> DONE;
DONE.insert(PartDesign::Line::getClassTypeId()); DONE.insert(QObject::tr("Line"));
std::multiset<Base::Type> key; std::multiset<QString> key;
std::set<Base::Type> value; std::set<QString> value;
key.insert(LINE); key.insert(LINE);
hints[key] = DONE; // LINE -> DONE. Line from another line or edge hints[key] = DONE; // LINE -> DONE. Line from another line or edge
@ -201,15 +217,15 @@ void Line::initHints()
hints[key] = value; hints[key] = value;
} }
std::map<std::multiset<Base::Type>, std::set<Base::Type> > Plane::hints = std::map<std::multiset<Base::Type>, std::set<Base::Type> >(); std::map<std::multiset<QString>, std::set<QString> > Plane::hints = std::map<std::multiset<QString>, std::set<QString> >();
void Plane::initHints() void Plane::initHints()
{ {
std::set<Base::Type> DONE; std::set<QString> DONE;
DONE.insert(PartDesign::Plane::getClassTypeId()); DONE.insert(QObject::tr("Plane"));
std::multiset<Base::Type> key; std::multiset<QString> key;
std::set<Base::Type> value; std::set<QString> value;
key.insert(PLANE); key.insert(PLANE);
hints[key] = DONE; // PLANE -> DONE. Plane from another plane or face hints[key] = DONE; // PLANE -> DONE. Plane from another plane or face
@ -247,71 +263,138 @@ PROPERTY_SOURCE(PartDesign::Point, PartDesign::Datum)
Point::Point() Point::Point()
{ {
ADD_PROPERTY_TYPE(_Point,(Base::Vector3d(0,0,1)),"DatumPoint",
App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Coordinates of the datum point");
} }
Point::~Point() Point::~Point()
{ {
} }
short Point::mustExecute() const void Point::onChanged(const App::Property* prop)
{ {
return PartDesign::Datum::mustExecute(); Datum::onChanged(prop);
}
App::DocumentObjectExecReturn *Point::execute(void) if (prop == &References) {
{ std::set<QString> hint = getHint();
std::set<Base::Type> hint = getHint(); if (!((hint.size() == 1) && (hint.find(QObject::tr("Point")) != hint.end())))
if (!((hint.size() == 1) && (hint.find(PartDesign::Point::getClassTypeId()) != hint.end()))) return; // incomplete references
return App::DocumentObject::StdReturn; // incomplete references
// Extract the shapes of the references // Extract the geometry of the references
std::vector<TopoDS_Shape> shapes;
std::vector<App::DocumentObject*> refs = References.getValues(); std::vector<App::DocumentObject*> refs = References.getValues();
std::vector<std::string> refnames = References.getSubValues(); std::vector<std::string> refnames = References.getSubValues();
Base::Vector3f* point = NULL;
Handle_Geom_Curve c1 = NULL;
Handle_Geom_Curve c2 = NULL;
Handle_Geom_Surface s1 = NULL;
Handle_Geom_Surface s2 = NULL;
Handle_Geom_Surface s3 = NULL;
for (int i = 0; i < refs.size(); i++) { for (int i = 0; i < refs.size(); i++) {
if (!refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) {
return new App::DocumentObjectExecReturn("PartDesign::Point: Invalid reference type"); PartDesign::Point* p = static_cast<PartDesign::Point*>(refs[i]);
point = new Base::Vector3f (p->_Point.getValue());
} else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) {
PartDesign::Line* l = static_cast<PartDesign::Line*>(refs[i]);
//point = new Base::Vector3f (p->_Point.getValue());
} else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) {
PartDesign::Plane* p = static_cast<PartDesign::Plane*>(refs[i]);
//point = new Base::Vector3f (p->_Point.getValue());
} else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
App::Plane* p = static_cast<App::Plane*>(refs[i]);
//point = new Base::Vector3f (p->_Point.getValue());
} else if (refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
Part::Feature* feature = static_cast<Part::Feature*>(refs[i]); Part::Feature* feature = static_cast<Part::Feature*>(refs[i]);
const TopoDS_Shape& sh = feature->Shape.getValue(); const TopoDS_Shape& sh = feature->Shape.getValue();
if (sh.IsNull()) if (sh.IsNull())
return new App::DocumentObjectExecReturn("PartDesign::Point: Reference has NULL shape"); return; // "PartDesign::Point: Reference has NULL shape"
if (refnames[i].empty()) {
// Datum feature or App::Plane
shapes.push_back(sh);
} else {
// Get subshape // Get subshape
TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str()); TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str());
if (subshape.IsNull()) if (subshape.IsNull())
return new App::DocumentObjectExecReturn("PartDesign::Point: Reference has NULL subshape"); return; // "PartDesign::Point: Reference has NULL subshape";
shapes.push_back(subshape);
if (subshape.ShapeType() == TopAbs_VERTEX) {
TopoDS_Vertex v = TopoDS::Vertex(subshape);
gp_Pnt p = BRep_Tool::Pnt(v);
point = new Base::Vector3f(p.X(), p.Y(), p.Z());
} else if (subshape.ShapeType() == TopAbs_EDGE) {
TopoDS_Edge e = TopoDS::Edge(subshape);
Standard_Real first, last;
if (c1.IsNull())
c1 = BRep_Tool::Curve(e, first, last);
else
c2 = BRep_Tool::Curve(e, first, last);
} else if (subshape.ShapeType() == TopAbs_FACE) {
TopoDS_Face f = TopoDS::Face(subshape);
if (s1.IsNull())
s1 = BRep_Tool::Surface(f);
else if (s2.IsNull())
s2 = BRep_Tool::Surface(f);
else
s3 = BRep_Tool::Surface(f);
}
} else {
return; //"PartDesign::Point: Invalid reference type"
} }
} }
// Find the point if (point != NULL) {
gp_Pnt point(0,0,0); // Point from vertex or other point. Nothing to be done
} else if (!c1.IsNull()) {
if (!c2.IsNull()) {
// Point from intersection of two curves
GeomAPI_ExtremaCurveCurve intersector(c1, c2);
if ((intersector.LowerDistance() > Precision::Confusion()) || (intersector.NbExtrema() == 0))
return; // No intersection
// Note: We don't check for multiple intersection points
gp_Pnt p, p2;
intersector.Points(1, p, p2);
point = new Base::Vector3f(p.X(), p.Y(), p.Z());
} else if (!s1.IsNull()) {
GeomAPI_IntCS intersector(c1, s1);
if (!intersector.IsDone() || (intersector.NbPoints() == 0))
return;
if (intersector.NbPoints() > 1)
Base::Console().Warning("More than one intersection point for datum point from curve and surface");
if (shapes.size() == 1) { gp_Pnt p = intersector.Point(1);
// Point from vertex or other point point = new Base::Vector3f(p.X(), p.Y(), p.Z());
if (shapes[0].ShapeType() != TopAbs_VERTEX) } else
return new App::DocumentObjectExecReturn("PartDesign::Point::execute(): Internal error, unexpected ShapeType"); return;
TopoDS_Vertex v = TopoDS::Vertex(shapes[0]); } else if (!s1.IsNull() && !s2.IsNull() && !s3.IsNull()) {
//point.X = v. GeomAPI_IntSS intersectorSS(s1, s2, Precision::Confusion());
if (!intersectorSS.IsDone() || (intersectorSS.NbLines() == 0))
return;
if (intersectorSS.NbLines() > 1)
Base::Console().Warning("More than one intersection line for datum point from surfaces");
Handle_Geom_Curve line = intersectorSS.Line(1);
GeomAPI_IntCS intersector(line, s3);
if (!intersector.IsDone() || (intersector.NbPoints() == 0))
return;
if (intersector.NbPoints() > 1)
Base::Console().Warning("More than one intersection point for datum point from surfaces");
gp_Pnt p = intersector.Point(1);
point = new Base::Vector3f(p.X(), p.Y(), p.Z());
} else {
return;
} }
BRepBuilderAPI_MakeVertex MakeVertex(point); _Point.setValue(*point);
const TopoDS_Vertex& vertex = MakeVertex.Vertex(); _Point.touch(); // This triggers ViewProvider::updateData()
this->Shape.setValue(vertex); delete point;
}
return App::DocumentObject::StdReturn;
} }
const std::set<Base::Type> Point::getHint() const std::set<QString> Point::getHint()
{ {
if (hints.find(refTypes) != hints.end()) if (hints.find(refTypes) != hints.end())
return hints[refTypes]; return hints[refTypes];
else else
return std::set<Base::Type>(); return std::set<QString>();
} }
@ -325,33 +408,22 @@ Line::~Line()
{ {
} }
short Line::mustExecute() const void Line::onChanged(const App::Property *prop)
{
return PartDesign::Datum::mustExecute();
}
App::DocumentObjectExecReturn *Line::execute(void)
{ {
gp_Pnt point1(0,0,0); gp_Pnt point1(0,0,0);
gp_Pnt point2(10,10,10); gp_Pnt point2(10,10,10);
BRepBuilderAPI_MakeEdge mkEdge(point1, point2); return;
if (!mkEdge.IsDone())
return new App::DocumentObjectExecReturn("Failed to create edge");
const TopoDS_Edge& edge = mkEdge.Edge();
this->Shape.setValue(edge);
return App::DocumentObject::StdReturn;
} }
const std::set<Base::Type> Line::getHint() const std::set<QString> Line::getHint()
{ {
if (hints.find(refTypes) != hints.end()) if (hints.find(refTypes) != hints.end())
return hints[refTypes]; return hints[refTypes];
else else
return std::set<Base::Type>(); return std::set<QString>();
} }
@ -361,39 +433,25 @@ Plane::Plane()
{ {
} }
short Plane::mustExecute() const void Plane::onChanged(const App::Property *prop)
{
return PartDesign::Datum::mustExecute();
}
App::DocumentObjectExecReturn *Plane::execute(void)
{ {
double O = 10.0; //this->Offset.getValue(); double O = 10.0; //this->Offset.getValue();
double A = 45.0; //this->Angle.getValue(); double A = 45.0; //this->Angle.getValue();
if (fabs(A) > 360.0) if (fabs(A) > 360.0)
return new App::DocumentObjectExecReturn("Angle too large (please use -360.0 .. +360.0)"); return; // "Angle too large (please use -360.0 .. +360.0)"
gp_Pnt pnt(0.0,0.0,0.0); gp_Pnt pnt(0.0,0.0,0.0);
gp_Dir dir(0.0,0.0,1.0); gp_Dir dir(0.0,0.0,1.0);
Handle_Geom_Plane aPlane = new Geom_Plane(pnt, dir);
BRepBuilderAPI_MakeFace mkFace(aPlane, 0.0, 100.0, 0.0, 100.0
#if OCC_VERSION_HEX >= 0x060502
, Precision::Confusion()
#endif
);
TopoDS_Shape ResultShape = mkFace.Shape(); return;
this->Shape.setValue(ResultShape);
return App::DocumentObject::StdReturn;
} }
const std::set<Base::Type> Plane::getHint() const std::set<QString> Plane::getHint()
{ {
if (hints.find(refTypes) != hints.end()) if (hints.find(refTypes) != hints.end())
return hints[refTypes]; return hints[refTypes];
else else
return std::set<Base::Type>(); return std::set<QString>();
} }

View File

@ -24,14 +24,14 @@
#ifndef PARTDESIGN_DATUMFEATURE_H #ifndef PARTDESIGN_DATUMFEATURE_H
#define PARTDESIGN_DATUMFEATURE_H #define PARTDESIGN_DATUMFEATURE_H
//#include <App/PropertyUnits.h> #include <QString>
#include <App/PropertyLinks.h> #include <App/PropertyLinks.h>
#include "Feature.h" #include "Feature.h"
namespace PartDesign namespace PartDesign
{ {
class PartDesignExport Datum : public PartDesign::Feature class PartDesignExport Datum : public App::DocumentObject
{ {
PROPERTY_HEADER(PartDesign::Datum); PROPERTY_HEADER(PartDesign::Datum);
@ -44,26 +44,24 @@ public:
/// The values defining the datum object, e.g. the offset from a Reference plane /// The values defining the datum object, e.g. the offset from a Reference plane
App::PropertyFloatList Values; App::PropertyFloatList Values;
/** @name methods override feature */
//@{
/// recalculate the feature /// recalculate the feature
App::DocumentObjectExecReturn *execute(void) = 0; App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider /// returns the type name of the view provider
const char* getViewProviderName(void) const { const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderDatum"; return "PartDesignGui::ViewProviderDatum";
} }
//@}
virtual const std::set<Base::Type> getHint() = 0; virtual const std::set<QString> getHint() = 0;
protected: protected:
void onChanged (const App::Property* prop); void onChanged (const App::Property* prop);
void onDocumentRestored();
protected: protected:
std::multiset<Base::Type> refTypes; std::multiset<QString> refTypes;
static const Base::Type getRefType(const App::DocumentObject* obj, const std::string& subname); static const QString getRefType(const App::DocumentObject* obj, const std::string& subname);
}; };
@ -72,22 +70,24 @@ class PartDesignExport Point : public PartDesign::Datum
PROPERTY_HEADER(PartDesign::Point); PROPERTY_HEADER(PartDesign::Point);
public: public:
App::PropertyVector _Point;
Point(); Point();
virtual ~Point(); virtual ~Point();
/** @name methods override feature */ const char* getViewProviderName(void) const {
//@{ return "PartDesignGui::ViewProviderDatumPoint";
/// recalculate the Feature }
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
//@}
static void initHints(); static void initHints();
const std::set<Base::Type> getHint(); const std::set<QString> getHint();
protected:
virtual void onChanged(const App::Property* prop);
private: private:
// Hints on what further references are required/possible on this feature for a given set of references // Hints on what further references are required/possible on this feature for a given set of references
static std::map<std::multiset<Base::Type>, std::set<Base::Type> > hints; static std::map<std::multiset<QString>, std::set<QString> > hints;
}; };
class PartDesignExport Line : public PartDesign::Datum class PartDesignExport Line : public PartDesign::Datum
@ -98,19 +98,19 @@ public:
Line(); Line();
virtual ~Line(); virtual ~Line();
/** @name methods override feature */ const char* getViewProviderName(void) const {
//@{ return "PartDesignGui::ViewProviderDatumLine";
/// recalculate the Feature }
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
//@}
static void initHints(); static void initHints();
const std::set<Base::Type> getHint(); const std::set<QString> getHint();
protected:
virtual void onChanged(const App::Property* prop);
private: private:
// Hints on what further references are required/possible on this feature for a given set of references // Hints on what further references are required/possible on this feature for a given set of references
static std::map<std::multiset<Base::Type>, std::set<Base::Type> > hints; static std::map<std::multiset<QString>, std::set<QString> > hints;
}; };
class PartDesignExport Plane : public PartDesign::Datum class PartDesignExport Plane : public PartDesign::Datum
@ -120,19 +120,19 @@ class PartDesignExport Plane : public PartDesign::Datum
public: public:
Plane(); Plane();
/** @name methods override feature */ const char* getViewProviderName(void) const {
//@{ return "PartDesignGui::ViewProviderDatumPlane";
/// recalculate the feature }
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
//@}
static void initHints(); static void initHints();
const std::set<Base::Type> getHint(); const std::set<QString> getHint();
protected:
virtual void onChanged(const App::Property* prop);
private: private:
// Hints on what further references are required/possible on this feature for a given set of references // Hints on what further references are required/possible on this feature for a given set of references
static std::map<std::multiset<Base::Type>, std::set<Base::Type> > hints; static std::map<std::multiset<QString>, std::set<QString> > hints;
}; };
} //namespace PartDesign } //namespace PartDesign

View File

@ -121,6 +121,9 @@ PyMODINIT_FUNC initPartDesignGui()
PartDesignGui::ViewProviderScaled ::init(); PartDesignGui::ViewProviderScaled ::init();
PartDesignGui::ViewProviderMultiTransform::init(); PartDesignGui::ViewProviderMultiTransform::init();
PartDesignGui::ViewProviderDatum ::init(); PartDesignGui::ViewProviderDatum ::init();
PartDesignGui::ViewProviderDatumPoint ::init();
PartDesignGui::ViewProviderDatumLine ::init();
PartDesignGui::ViewProviderDatumPlane ::init();
// add resources and reloads the translators // add resources and reloads the translators
loadPartDesignResource(); loadPartDesignResource();

View File

@ -611,20 +611,16 @@ void CmdPartDesignNewSketch::activated(int iMsg)
firstValidPlane = planes.begin(); firstValidPlane = planes.begin();
} }
//TODO: Allow user to choose front or back of the plane // TODO: Allow user to choose front or back of the plane
App::Plane* plane = static_cast<App::Plane*>(*firstValidPlane); App::Plane* plane = static_cast<App::Plane*>(*firstValidPlane);
Base::Vector3d p = plane->Placement.getValue().getPosition();
Base::Rotation r = plane->Placement.getValue().getRotation();
std::string FeatName = getUniqueObjectName("Sketch"); std::string FeatName = getUniqueObjectName("Sketch");
std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + ", ['front'])"; std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + ", ['front'])";
openCommand("Create a new Sketch"); openCommand("Create a new Sketch");
doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str());
//doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))", updateActive(); // Make sure the Support's Placement property is updated
// FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]);
doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
pcActiveBody->getNameInDocument(), FeatName.c_str()); pcActiveBody->getNameInDocument(), FeatName.c_str());
//doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str());

View File

@ -168,16 +168,16 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
updateUI(); updateUI();
} }
const QString makeRefText(std::set<Base::Type> hint) const QString makeRefText(std::set<QString> hint)
{ {
QString result; QString result;
for (std::set<Base::Type>::const_iterator t = hint.begin(); t != hint.end(); t++) { for (std::set<QString>::const_iterator t = hint.begin(); t != hint.end(); t++) {
QString tText; QString tText;
if (((*t) == Part::Plane::getClassTypeId()) || ((*t) == PartDesign::Plane::getClassTypeId())) if (((*t) == QObject::tr("DPLANE")) || ((*t) == QObject::tr("Plane")))
tText = QObject::tr("Plane"); tText = QObject::tr("Plane");
else if (((*t) == Part::Line::getClassTypeId()) || ((*t) == PartDesign::Line::getClassTypeId())) else if (((*t) == QObject::tr("DLINE")) || ((*t) == QObject::tr("Line")))
tText = QObject::tr("Line"); tText = QObject::tr("Line");
else if (((*t) == Part::Vertex::getClassTypeId()) || ((*t) == PartDesign::Point::getClassTypeId())) else if (((*t) == QObject::tr("DPOINT")) || ((*t) == QObject::tr("Point")))
tText = QObject::tr("Point"); tText = QObject::tr("Point");
result += QString::fromAscii(result.size() == 0 ? "" : "/") + tText; result += QString::fromAscii(result.size() == 0 ? "" : "/") + tText;
} }
@ -200,8 +200,8 @@ void TaskDatumParameters::updateUI()
} }
// Get hints for further required references // Get hints for further required references
std::set<Base::Type> hint = pcDatum->getHint(); std::set<QString> hint = pcDatum->getHint();
if (hint == std::set<Base::Type>()) { if (hint == std::set<QString>()) {
QMessageBox::warning(this, tr("Illegal selection"), tr("This feature cannot be created with this combination of references")); QMessageBox::warning(this, tr("Illegal selection"), tr("This feature cannot be created with this combination of references"));
if (refs.size() == 1) { if (refs.size() == 1) {
onButtonRef1(true); onButtonRef1(true);

View File

@ -27,6 +27,15 @@
# include <QMessageBox> # include <QMessageBox>
# include <QAction> # include <QAction>
# include <QMenu> # include <QMenu>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoVertexProperty.h>
# include <TopoDS_Vertex.hxx>
# include <TopoDS.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
#endif #endif
#include "ViewProviderDatum.h" #include "ViewProviderDatum.h"
@ -34,22 +43,26 @@
#include "Workbench.h" #include "Workbench.h"
#include <Mod/PartDesign/App/DatumFeature.h> #include <Mod/PartDesign/App/DatumFeature.h>
#include <Gui/Control.h> #include <Gui/Control.h>
#include <Gui/Command.h>
using namespace PartDesignGui; using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,PartDesignGui::ViewProvider) PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject)
ViewProviderDatum::ViewProviderDatum() ViewProviderDatum::ViewProviderDatum()
{ {
pShapeSep = new SoSeparator();
pShapeSep->ref();
} }
ViewProviderDatum::~ViewProviderDatum() ViewProviderDatum::~ViewProviderDatum()
{ {
pShapeSep->unref();
} }
void ViewProviderDatum::attach(App::DocumentObject *obj) void ViewProviderDatum::attach(App::DocumentObject *obj)
{ {
ViewProvider::attach(obj); ViewProviderDocumentObject::attach(obj);
PartDesign::Datum* pcDatum = static_cast<PartDesign::Datum*>(getObject()); PartDesign::Datum* pcDatum = static_cast<PartDesign::Datum*>(getObject());
if (pcDatum->getTypeId() == PartDesign::Plane::getClassTypeId()) if (pcDatum->getTypeId() == PartDesign::Plane::getClassTypeId())
@ -58,6 +71,42 @@ void ViewProviderDatum::attach(App::DocumentObject *obj)
datumType = QObject::tr("Line"); datumType = QObject::tr("Line");
else if (pcDatum->getTypeId() == PartDesign::Point::getClassTypeId()) else if (pcDatum->getTypeId() == PartDesign::Point::getClassTypeId())
datumType = QObject::tr("Point"); datumType = QObject::tr("Point");
SoSeparator* sep = new SoSeparator();
SoShapeHints* hints = new SoShapeHints();
hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE);
hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE);
SoBaseColor* color = new SoBaseColor();
color->rgb.setValue(0.9, 0.9, 0.2);
sep->addChild(hints);
sep->addChild(color);
sep->addChild(pShapeSep);
addDisplayMaskMode(sep, "Base");
}
std::vector<std::string> ViewProviderDatum::getDisplayModes(void) const
{
// add modes
std::vector<std::string> StrList;
StrList.push_back("Base");
return StrList;
}
void ViewProviderDatum::setDisplayMode(const char* ModeName)
{
if (strcmp(ModeName, "Base") == 0)
setDisplayMaskMode("Base");
ViewProviderDocumentObject::setDisplayMode(ModeName);
}
void ViewProviderDatum::onChanged(const App::Property* prop)
{
/*if (prop == &Shape) {
updateData(prop);
}
else {*/
ViewProviderDocumentObject::onChanged(prop);
//}
} }
void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
@ -65,11 +114,14 @@ void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const c
QAction* act; QAction* act;
act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member); act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member);
act->setData(QVariant((int)ViewProvider::Default)); act->setData(QVariant((int)ViewProvider::Default));
PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); Gui::ViewProviderGeometryObject::setupContextMenu(menu, receiver, member);
} }
bool ViewProviderDatum::setEdit(int ModNum) bool ViewProviderDatum::setEdit(int ModNum)
{ {
if (!ViewProvider::setEdit(ModNum))
return false;
if (ModNum == ViewProvider::Default ) { if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this datum feature the // When double-clicking on the item for this datum feature the
// object unsets and sets its edit mode without closing // object unsets and sets its edit mode without closing
@ -94,6 +146,9 @@ bool ViewProviderDatum::setEdit(int ModNum)
// clear the selection (convenience) // clear the selection (convenience)
Gui::Selection().clearSelection(); Gui::Selection().clearSelection();
// always change to PartDesign WB, remember where we come from
oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench");
// start the edit dialog // start the edit dialog
if (datumDlg) if (datumDlg)
Gui::Control().showDialog(datumDlg); Gui::Control().showDialog(datumDlg);
@ -103,19 +158,126 @@ bool ViewProviderDatum::setEdit(int ModNum)
return true; return true;
} }
else { else {
return ViewProviderPart::setEdit(ModNum); return ViewProvider::setEdit(ModNum);
} }
} }
void ViewProviderDatum::unsetEdit(int ModNum) void ViewProviderDatum::unsetEdit(int ModNum)
{ {
// return to the WB we were in before editing the PartDesign feature
Gui::Command::assureWorkbench(oldWb.c_str());
if (ModNum == ViewProvider::Default) { if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog // when pressing ESC make sure to close the dialog
Gui::Control().closeDialog(); Gui::Control().closeDialog();
} }
else { else {
PartGui::ViewProviderPart::unsetEdit(ModNum); Gui::ViewProviderGeometryObject::unsetEdit(ModNum);
} }
} }
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumPoint,PartDesignGui::ViewProviderDatum)
ViewProviderDatumPoint::ViewProviderDatumPoint()
{
SoMarkerSet* points = new SoMarkerSet();
points->markerIndex = SoMarkerSet::DIAMOND_FILLED_9_9;
points->numPoints = 1;
pShapeSep->addChild(points);
}
ViewProviderDatumPoint::~ViewProviderDatumPoint()
{
}
void ViewProviderDatumPoint::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
PartDesign::Point* pcDatum = static_cast<PartDesign::Point*>(this->getObject());
if (strcmp(prop->getName(),"_Point") == 0) {
Base::Vector3f p = pcDatum->_Point.getValue();
SoMFVec3f v;
v.set1Value(0, p.x, p.y, p.z);
SoVertexProperty* vprop = new SoVertexProperty();
vprop->vertex = v;
SoMarkerSet* points = static_cast<SoMarkerSet*>(pShapeSep->getChild(0));
points->vertexProperty = vprop;
}
ViewProviderDatum::updateData(prop);
}
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumLine,PartDesignGui::ViewProviderDatum)
ViewProviderDatumLine::ViewProviderDatumLine()
{
/*
SoMarkerSet* points = new SoMarkerSet();
points->markerIndex = SoMarkerSet::DIAMOND_FILLED_9_9;
points->numPoints = 1;
pShapeSep->addChild(points);
*/
}
ViewProviderDatumLine::~ViewProviderDatumLine()
{
}
void ViewProviderDatumLine::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
PartDesign::Line* pcDatum = static_cast<PartDesign::Line*>(this->getObject());
/*
if (strcmp(prop->getName(),"_Point") == 0) {
Base::Vector3f p = pcDatum->_Point.getValue();
SoMFVec3f v;
v.set1Value(0, p.x, p.y, p.z);
SoVertexProperty* vprop = new SoVertexProperty();
vprop->vertex = v;
SoMarkerSet* points = static_cast<SoMarkerSet*>(pShapeSep->getChild(0));
points->vertexProperty = vprop;
}*/
ViewProviderDatum::updateData(prop);
}
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumPlane,PartDesignGui::ViewProviderDatum)
ViewProviderDatumPlane::ViewProviderDatumPlane()
{
/*
SoMarkerSet* points = new SoMarkerSet();
points->markerIndex = SoMarkerSet::DIAMOND_FILLED_9_9;
points->numPoints = 1;
pShapeSep->addChild(points);
*/
}
ViewProviderDatumPlane::~ViewProviderDatumPlane()
{
}
void ViewProviderDatumPlane::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
PartDesign::Plane* pcDatum = static_cast<PartDesign::Plane*>(this->getObject());
/*
if (strcmp(prop->getName(),"_Point") == 0) {
Base::Vector3f p = pcDatum->_Point.getValue();
SoMFVec3f v;
v.set1Value(0, p.x, p.y, p.z);
SoVertexProperty* vprop = new SoVertexProperty();
vprop->vertex = v;
SoMarkerSet* points = static_cast<SoMarkerSet*>(pShapeSep->getChild(0));
points->vertexProperty = vprop;
}*/
ViewProviderDatum::updateData(prop);
}

View File

@ -24,11 +24,11 @@
#ifndef PARTGUI_ViewProviderDatum_H #ifndef PARTGUI_ViewProviderDatum_H
#define PARTGUI_ViewProviderDatum_H #define PARTGUI_ViewProviderDatum_H
#include "ViewProvider.h" #include "Gui/ViewProviderGeometryObject.h"
namespace PartDesignGui { namespace PartDesignGui {
class PartDesignGuiExport ViewProviderDatum : public ViewProvider class PartDesignGuiExport ViewProviderDatum : public Gui::ViewProviderGeometryObject
{ {
PROPERTY_HEADER(PartDesignGui::ViewProviderDatum); PROPERTY_HEADER(PartDesignGui::ViewProviderDatum);
@ -42,14 +42,61 @@ public:
void setupContextMenu(QMenu*, QObject*, const char*); void setupContextMenu(QMenu*, QObject*, const char*);
virtual void attach(App::DocumentObject *); virtual void attach(App::DocumentObject *);
virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); }
std::vector<std::string> getDisplayModes(void) const;
void setDisplayMode(const char* ModeName);
/// The datum type (Plane, Line or Point) /// The datum type (Plane, Line or Point)
QString datumType; QString datumType;
protected: protected:
void onChanged(const App::Property* prop);
virtual bool setEdit(int ModNum); virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum); virtual void unsetEdit(int ModNum);
protected:
SoSeparator* pShapeSep;
std::string oldWb;
};
class PartDesignGuiExport ViewProviderDatumPoint : public PartDesignGui::ViewProviderDatum
{
PROPERTY_HEADER(PartDesignGui::ViewProviderDatumPoint);
public:
/// Constructor
ViewProviderDatumPoint();
virtual ~ViewProviderDatumPoint();
virtual void updateData(const App::Property*);
};
class PartDesignGuiExport ViewProviderDatumLine : public PartDesignGui::ViewProviderDatum
{
PROPERTY_HEADER(PartDesignGui::ViewProviderDatumLine);
public:
/// Constructor
ViewProviderDatumLine();
virtual ~ViewProviderDatumLine();
virtual void updateData(const App::Property*);
};
class PartDesignGuiExport ViewProviderDatumPlane : public PartDesignGui::ViewProviderDatum
{
PROPERTY_HEADER(PartDesignGui::ViewProviderDatumPlane);
public:
/// Constructor
ViewProviderDatumPlane();
virtual ~ViewProviderDatumPlane();
virtual void updateData(const App::Property*);
}; };