diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index afa7f05da..fb6632772 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -180,8 +180,20 @@ const bool Body::isAfterTip(const App::DocumentObject *f) { const bool Body::isSolidFeature(const App::DocumentObject* f) { - return (f->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) && - !f->getTypeId().isDerivedFrom(PartDesign::Datum::getClassTypeId())); + if (f == NULL) + 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) diff --git a/src/Mod/PartDesign/App/Body.h b/src/Mod/PartDesign/App/Body.h index 3ce3d159b..18b58d84e 100644 --- a/src/Mod/PartDesign/App/Body.h +++ b/src/Mod/PartDesign/App/Body.h @@ -90,11 +90,17 @@ public: /** * 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 */ 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 static Body* findBodyOf(const App::DocumentObject* f); diff --git a/src/Mod/PartDesign/App/BodyPyImp.cpp b/src/Mod/PartDesign/App/BodyPyImp.cpp index 8bc88ca60..f66754810 100644 --- a/src/Mod/PartDesign/App/BodyPyImp.cpp +++ b/src/Mod/PartDesign/App/BodyPyImp.cpp @@ -32,14 +32,13 @@ int BodyPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) PyObject* BodyPy::addFeature(PyObject *args) { PyObject* featurePy; - if (!PyArg_ParseTuple(args, "O!", &(Part::PartFeaturePy::Type), &featurePy)) + if (!PyArg_ParseTuple(args, "O!", &(App::DocumentObjectPy::Type), &featurePy)) return 0; - Part::Feature* feature = static_cast(featurePy)->getFeaturePtr(); + App::DocumentObject* feature = static_cast(featurePy)->getDocumentObjectPtr(); - if (!feature->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) && - !feature->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { - PyErr_SetString(PyExc_SystemError, "Only PartDesign features and sketches can be inserted into a Body"); + if (!Body::isAllowed(feature)) { + PyErr_SetString(PyExc_SystemError, "Only PartDesign features, datum features and sketches can be inserted into a Body"); return 0; } Body* body = this->getBodyPtr(); @@ -57,10 +56,10 @@ PyObject* BodyPy::addFeature(PyObject *args) PyObject* BodyPy::removeFeature(PyObject *args) { PyObject* featurePy; - if (!PyArg_ParseTuple(args, "O!", &(Part::PartFeaturePy::Type), &featurePy)) + if (!PyArg_ParseTuple(args, "O!", &(App::DocumentObjectPy::Type), &featurePy)) return 0; - Part::Feature* feature = static_cast(featurePy)->getFeaturePtr(); + App::DocumentObject* feature = static_cast(featurePy)->getDocumentObjectPtr(); Body* body = this->getBodyPtr(); try { diff --git a/src/Mod/PartDesign/App/DatumFeature.cpp b/src/Mod/PartDesign/App/DatumFeature.cpp index 75a95ca53..416c4f913 100644 --- a/src/Mod/PartDesign/App/DatumFeature.cpp +++ b/src/Mod/PartDesign/App/DatumFeature.cpp @@ -30,23 +30,34 @@ # include # include # include +# include # include # include # include +# include +# include # include # include +# include +# include +# include # include # include # include # include +# include +# include +# include +# include # include #endif - +#include #include #include "DatumFeature.h" #include #include +#include #include "Mod/Part/App/PrimitiveFeature.h" #ifndef M_PI @@ -55,7 +66,7 @@ using namespace PartDesign; -PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, PartDesign::Feature) +PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, App::DocumentObject) Datum::Datum(void) { @@ -68,12 +79,11 @@ Datum::~Datum() { } -short Datum::mustExecute(void) const + +App::DocumentObjectExecReturn *Datum::execute(void) { - if (References.isTouched() || - Values.isTouched()) - return 1; - return Feature::mustExecute(); + References.touch(); + return StdReturn; } 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])); } - 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 -// These values are just markers so it doesn't matter that they are Part features -#define PLANE Part::Plane::getClassTypeId() -#define LINE Part::Line::getClassTypeId() -#define POINT Part::Vertex::getClassTypeId() +#define PLANE QObject::tr("DPLANE") +#define LINE QObject::tr("DLINE") +#define POINT QObject::tr("DPOINT") -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(); @@ -122,15 +138,15 @@ const Base::Type Datum::getRefType(const App::DocumentObject* obj, const std::st // ================================ Initialize the hints ===================== -std::map, std::set > Point::hints = std::map, std::set >(); +std::map, std::set > Point::hints = std::map, std::set >(); void Point::initHints() { - std::set DONE; - DONE.insert(PartDesign::Point::getClassTypeId()); + std::set DONE; + DONE.insert(QObject::tr("Point")); - std::multiset key; - std::set value; + std::multiset key; + std::set value; key.insert(POINT); hints[key] = DONE; // POINT -> DONE. Point from another point or vertex @@ -166,15 +182,15 @@ void Point::initHints() hints[key] = value; } -std::map, std::set > Line::hints = std::map, std::set >(); +std::map, std::set > Line::hints = std::map, std::set >(); void Line::initHints() { - std::set DONE; - DONE.insert(PartDesign::Line::getClassTypeId()); + std::set DONE; + DONE.insert(QObject::tr("Line")); - std::multiset key; - std::set value; + std::multiset key; + std::set value; key.insert(LINE); hints[key] = DONE; // LINE -> DONE. Line from another line or edge @@ -201,15 +217,15 @@ void Line::initHints() hints[key] = value; } -std::map, std::set > Plane::hints = std::map, std::set >(); +std::map, std::set > Plane::hints = std::map, std::set >(); void Plane::initHints() { - std::set DONE; - DONE.insert(PartDesign::Plane::getClassTypeId()); + std::set DONE; + DONE.insert(QObject::tr("Plane")); - std::multiset key; - std::set value; + std::multiset key; + std::set value; key.insert(PLANE); hints[key] = DONE; // PLANE -> DONE. Plane from another plane or face @@ -247,71 +263,138 @@ PROPERTY_SOURCE(PartDesign::Point, PartDesign::Datum) 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() { } -short Point::mustExecute() const +void Point::onChanged(const App::Property* prop) { - return PartDesign::Datum::mustExecute(); -} + Datum::onChanged(prop); -App::DocumentObjectExecReturn *Point::execute(void) -{ - std::set hint = getHint(); - if (!((hint.size() == 1) && (hint.find(PartDesign::Point::getClassTypeId()) != hint.end()))) - return App::DocumentObject::StdReturn; // incomplete references + if (prop == &References) { + std::set hint = getHint(); + if (!((hint.size() == 1) && (hint.find(QObject::tr("Point")) != hint.end()))) + return; // incomplete references - // Extract the shapes of the references - std::vector shapes; - std::vector refs = References.getValues(); - std::vector refnames = References.getSubValues(); - for (int i = 0; i < refs.size(); i++) { - if (!refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - return new App::DocumentObjectExecReturn("PartDesign::Point: Invalid reference type"); - Part::Feature* feature = static_cast(refs[i]); - const TopoDS_Shape& sh = feature->Shape.getValue(); - if (sh.IsNull()) - return new App::DocumentObjectExecReturn("PartDesign::Point: Reference has NULL shape"); - if (refnames[i].empty()) { - // Datum feature or App::Plane - shapes.push_back(sh); - } else { - // Get subshape - TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str()); - if (subshape.IsNull()) - return new App::DocumentObjectExecReturn("PartDesign::Point: Reference has NULL subshape"); - shapes.push_back(subshape); + // Extract the geometry of the references + std::vector refs = References.getValues(); + std::vector 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++) { + if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) { + PartDesign::Point* p = static_cast(refs[i]); + point = new Base::Vector3f (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + PartDesign::Line* l = static_cast(refs[i]); + //point = new Base::Vector3f (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + PartDesign::Plane* p = static_cast(refs[i]); + //point = new Base::Vector3f (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + App::Plane* p = static_cast(refs[i]); + //point = new Base::Vector3f (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* feature = static_cast(refs[i]); + const TopoDS_Shape& sh = feature->Shape.getValue(); + if (sh.IsNull()) + return; // "PartDesign::Point: Reference has NULL shape" + // Get subshape + TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str()); + if (subshape.IsNull()) + return; // "PartDesign::Point: Reference has NULL 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" + } } + + if (point != NULL) { + // 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"); + + gp_Pnt p = intersector.Point(1); + point = new Base::Vector3f(p.X(), p.Y(), p.Z()); + } else + return; + } else if (!s1.IsNull() && !s2.IsNull() && !s3.IsNull()) { + 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; + } + + _Point.setValue(*point); + _Point.touch(); // This triggers ViewProvider::updateData() + delete point; } - - // Find the point - gp_Pnt point(0,0,0); - - if (shapes.size() == 1) { - // Point from vertex or other point - if (shapes[0].ShapeType() != TopAbs_VERTEX) - return new App::DocumentObjectExecReturn("PartDesign::Point::execute(): Internal error, unexpected ShapeType"); - TopoDS_Vertex v = TopoDS::Vertex(shapes[0]); - //point.X = v. - } - - BRepBuilderAPI_MakeVertex MakeVertex(point); - const TopoDS_Vertex& vertex = MakeVertex.Vertex(); - this->Shape.setValue(vertex); - - return App::DocumentObject::StdReturn; } -const std::set Point::getHint() +const std::set Point::getHint() { if (hints.find(refTypes) != hints.end()) return hints[refTypes]; else - return std::set(); + return std::set(); } @@ -325,33 +408,22 @@ Line::~Line() { } -short Line::mustExecute() const -{ - return PartDesign::Datum::mustExecute(); -} - -App::DocumentObjectExecReturn *Line::execute(void) +void Line::onChanged(const App::Property *prop) { gp_Pnt point1(0,0,0); gp_Pnt point2(10,10,10); - BRepBuilderAPI_MakeEdge mkEdge(point1, point2); - 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; + return; } -const std::set Line::getHint() +const std::set Line::getHint() { if (hints.find(refTypes) != hints.end()) return hints[refTypes]; else - return std::set(); + return std::set(); } @@ -361,39 +433,25 @@ Plane::Plane() { } -short Plane::mustExecute() const -{ - return PartDesign::Datum::mustExecute(); -} - -App::DocumentObjectExecReturn *Plane::execute(void) +void Plane::onChanged(const App::Property *prop) { double O = 10.0; //this->Offset.getValue(); double A = 45.0; //this->Angle.getValue(); 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_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(); - this->Shape.setValue(ResultShape); - - return App::DocumentObject::StdReturn; + return; } -const std::set Plane::getHint() +const std::set Plane::getHint() { if (hints.find(refTypes) != hints.end()) return hints[refTypes]; else - return std::set(); + return std::set(); } diff --git a/src/Mod/PartDesign/App/DatumFeature.h b/src/Mod/PartDesign/App/DatumFeature.h index 7e4f6d7a8..99a4bbf75 100644 --- a/src/Mod/PartDesign/App/DatumFeature.h +++ b/src/Mod/PartDesign/App/DatumFeature.h @@ -24,14 +24,14 @@ #ifndef PARTDESIGN_DATUMFEATURE_H #define PARTDESIGN_DATUMFEATURE_H -//#include +#include #include #include "Feature.h" namespace PartDesign { -class PartDesignExport Datum : public PartDesign::Feature +class PartDesignExport Datum : public App::DocumentObject { PROPERTY_HEADER(PartDesign::Datum); @@ -44,26 +44,24 @@ public: /// The values defining the datum object, e.g. the offset from a Reference plane App::PropertyFloatList Values; - /** @name methods override feature */ - //@{ /// recalculate the feature - App::DocumentObjectExecReturn *execute(void) = 0; - short mustExecute() const; + App::DocumentObjectExecReturn *execute(void); + /// returns the type name of the view provider const char* getViewProviderName(void) const { return "PartDesignGui::ViewProviderDatum"; } - //@} - virtual const std::set getHint() = 0; + virtual const std::set getHint() = 0; protected: void onChanged (const App::Property* prop); + void onDocumentRestored(); protected: - std::multiset refTypes; + std::multiset 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); public: + App::PropertyVector _Point; + Point(); virtual ~Point(); - /** @name methods override feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute(void); - short mustExecute() const; - //@} + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderDatumPoint"; + } static void initHints(); - const std::set getHint(); + const std::set getHint(); + +protected: + virtual void onChanged(const App::Property* prop); private: // Hints on what further references are required/possible on this feature for a given set of references - static std::map, std::set > hints; + static std::map, std::set > hints; }; class PartDesignExport Line : public PartDesign::Datum @@ -98,19 +98,19 @@ public: Line(); virtual ~Line(); - /** @name methods override feature */ - //@{ - /// recalculate the Feature - App::DocumentObjectExecReturn *execute(void); - short mustExecute() const; - //@} + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderDatumLine"; + } static void initHints(); - const std::set getHint(); + const std::set getHint(); + +protected: + virtual void onChanged(const App::Property* prop); private: // Hints on what further references are required/possible on this feature for a given set of references - static std::map, std::set > hints; + static std::map, std::set > hints; }; class PartDesignExport Plane : public PartDesign::Datum @@ -120,19 +120,19 @@ class PartDesignExport Plane : public PartDesign::Datum public: Plane(); - /** @name methods override feature */ - //@{ - /// recalculate the feature - App::DocumentObjectExecReturn *execute(void); - short mustExecute() const; - //@} + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderDatumPlane"; + } static void initHints(); - const std::set getHint(); + const std::set getHint(); + +protected: + virtual void onChanged(const App::Property* prop); private: // Hints on what further references are required/possible on this feature for a given set of references - static std::map, std::set > hints; + static std::map, std::set > hints; }; } //namespace PartDesign diff --git a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp index bec1ad5d8..2b26c6afe 100644 --- a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp +++ b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp @@ -121,6 +121,9 @@ PyMODINIT_FUNC initPartDesignGui() PartDesignGui::ViewProviderScaled ::init(); PartDesignGui::ViewProviderMultiTransform::init(); PartDesignGui::ViewProviderDatum ::init(); + PartDesignGui::ViewProviderDatumPoint ::init(); + PartDesignGui::ViewProviderDatumLine ::init(); + PartDesignGui::ViewProviderDatumPlane ::init(); // add resources and reloads the translators loadPartDesignResource(); diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 766860f16..5277285ed 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -611,20 +611,16 @@ void CmdPartDesignNewSketch::activated(int iMsg) firstValidPlane = planes.begin(); } - //TODO: Allow user to choose front or back of the plane - - App::Plane* plane = static_cast(*firstValidPlane); - Base::Vector3d p = plane->Placement.getValue().getPosition(); - Base::Rotation r = plane->Placement.getValue().getRotation(); + // TODO: Allow user to choose front or back of the plane + App::Plane* plane = static_cast(*firstValidPlane); std::string FeatName = getUniqueObjectName("Sketch"); std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + ", ['front'])"; openCommand("Create a new Sketch"); 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.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))", - // FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]); + updateActive(); // Make sure the Support's Placement property is updated doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", pcActiveBody->getNameInDocument(), FeatName.c_str()); //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp index 46e114f56..0adfb5f1a 100644 --- a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp @@ -168,16 +168,16 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p updateUI(); } -const QString makeRefText(std::set hint) +const QString makeRefText(std::set hint) { QString result; - for (std::set::const_iterator t = hint.begin(); t != hint.end(); t++) { + for (std::set::const_iterator t = hint.begin(); t != hint.end(); t++) { QString tText; - if (((*t) == Part::Plane::getClassTypeId()) || ((*t) == PartDesign::Plane::getClassTypeId())) + if (((*t) == QObject::tr("DPLANE")) || ((*t) == 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"); - else if (((*t) == Part::Vertex::getClassTypeId()) || ((*t) == PartDesign::Point::getClassTypeId())) + else if (((*t) == QObject::tr("DPOINT")) || ((*t) == QObject::tr("Point"))) tText = QObject::tr("Point"); result += QString::fromAscii(result.size() == 0 ? "" : "/") + tText; } @@ -200,8 +200,8 @@ void TaskDatumParameters::updateUI() } // Get hints for further required references - std::set hint = pcDatum->getHint(); - if (hint == std::set()) { + std::set hint = pcDatum->getHint(); + if (hint == std::set()) { QMessageBox::warning(this, tr("Illegal selection"), tr("This feature cannot be created with this combination of references")); if (refs.size() == 1) { onButtonRef1(true); diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp index 327507569..2bbfd9c63 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -27,6 +27,15 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif #include "ViewProviderDatum.h" @@ -34,22 +43,26 @@ #include "Workbench.h" #include #include +#include using namespace PartDesignGui; -PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,PartDesignGui::ViewProvider) +PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject) ViewProviderDatum::ViewProviderDatum() { + pShapeSep = new SoSeparator(); + pShapeSep->ref(); } ViewProviderDatum::~ViewProviderDatum() { + pShapeSep->unref(); } void ViewProviderDatum::attach(App::DocumentObject *obj) { - ViewProvider::attach(obj); + ViewProviderDocumentObject::attach(obj); PartDesign::Datum* pcDatum = static_cast(getObject()); if (pcDatum->getTypeId() == PartDesign::Plane::getClassTypeId()) @@ -58,6 +71,42 @@ void ViewProviderDatum::attach(App::DocumentObject *obj) datumType = QObject::tr("Line"); else if (pcDatum->getTypeId() == PartDesign::Point::getClassTypeId()) 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 ViewProviderDatum::getDisplayModes(void) const +{ + // add modes + std::vector 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) @@ -65,11 +114,14 @@ void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const c QAction* act; act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member); act->setData(QVariant((int)ViewProvider::Default)); - PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); + Gui::ViewProviderGeometryObject::setupContextMenu(menu, receiver, member); } bool ViewProviderDatum::setEdit(int ModNum) { + if (!ViewProvider::setEdit(ModNum)) + return false; + if (ModNum == ViewProvider::Default ) { // When double-clicking on the item for this datum feature the // object unsets and sets its edit mode without closing @@ -94,6 +146,9 @@ bool ViewProviderDatum::setEdit(int ModNum) // clear the selection (convenience) Gui::Selection().clearSelection(); + // always change to PartDesign WB, remember where we come from + oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench"); + // start the edit dialog if (datumDlg) Gui::Control().showDialog(datumDlg); @@ -103,19 +158,126 @@ bool ViewProviderDatum::setEdit(int ModNum) return true; } else { - return ViewProviderPart::setEdit(ModNum); + return ViewProvider::setEdit(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) { // when pressing ESC make sure to close the dialog Gui::Control().closeDialog(); } 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(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(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(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(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(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(pShapeSep->getChild(0)); + points->vertexProperty = vprop; + }*/ + + ViewProviderDatum::updateData(prop); +} + diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.h b/src/Mod/PartDesign/Gui/ViewProviderDatum.h index acb4a89b3..bde60f4e7 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.h @@ -24,11 +24,11 @@ #ifndef PARTGUI_ViewProviderDatum_H #define PARTGUI_ViewProviderDatum_H -#include "ViewProvider.h" +#include "Gui/ViewProviderGeometryObject.h" namespace PartDesignGui { -class PartDesignGuiExport ViewProviderDatum : public ViewProvider +class PartDesignGuiExport ViewProviderDatum : public Gui::ViewProviderGeometryObject { PROPERTY_HEADER(PartDesignGui::ViewProviderDatum); @@ -42,14 +42,61 @@ public: void setupContextMenu(QMenu*, QObject*, const char*); virtual void attach(App::DocumentObject *); + virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); } + std::vector getDisplayModes(void) const; + void setDisplayMode(const char* ModeName); /// The datum type (Plane, Line or Point) QString datumType; protected: + void onChanged(const App::Property* prop); virtual bool setEdit(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*); + };