From bb1a3a532f79e39107c43169fef74f5dbb05ee08 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Tue, 30 Apr 2013 17:55:45 +0430 Subject: [PATCH] Miscellaneous fixes --- src/Mod/Part/App/Part2DObject.cpp | 11 +- src/Mod/PartDesign/App/DatumFeature.cpp | 311 +++++++++++++++++-- src/Mod/PartDesign/Gui/Command.cpp | 25 +- src/Mod/PartDesign/Gui/ViewProviderDatum.cpp | 1 + src/Mod/PartDesign/Gui/Workbench.cpp | 2 + src/Mod/Sketcher/App/PreCompiled.h | 2 + src/Mod/Sketcher/App/SketchObject.cpp | 15 +- 7 files changed, 323 insertions(+), 44 deletions(-) diff --git a/src/Mod/Part/App/Part2DObject.cpp b/src/Mod/Part/App/Part2DObject.cpp index 16f754a3a..b70c337bb 100644 --- a/src/Mod/Part/App/Part2DObject.cpp +++ b/src/Mod/Part/App/Part2DObject.cpp @@ -111,16 +111,7 @@ void Part2DObject::positionBySupport(void) Place.getRotation().multVec(Base::Vector3d(0,0,1),dir); Base::Vector3d pos = Place.getPosition(); plane = gp_Pln(gp_Pnt(pos.x, pos.y, pos.z), gp_Dir(dir.x, dir.y, dir.z)); - }/* else if (support->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { - Place = static_cast(support)->Placement.getValue(); - Base::Vector3d pos = Place.getPosition(); - Base::Vector3d dir; - Place.getRotation().multVec(Base::Vector3d(0,0,1),dir); - const std::vector &sub = Support.getSubValues(); - if (!sub.empty()) - Reverse = (sub[0] == "back"); - plane = gp_Pln(gp_Pnt(pos.x, pos.y, pos.z), gp_Dir(dir.x, dir.y, dir.z)); - }*/ else { + } else { Part::Feature *part = static_cast(support); if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) return; diff --git a/src/Mod/PartDesign/App/DatumFeature.cpp b/src/Mod/PartDesign/App/DatumFeature.cpp index bb6861f11..ce951ffa2 100644 --- a/src/Mod/PartDesign/App/DatumFeature.cpp +++ b/src/Mod/PartDesign/App/DatumFeature.cpp @@ -32,6 +32,9 @@ # include # include # include +# include +# include +# include # include # include # include @@ -56,8 +59,8 @@ #include #include "DatumFeature.h" #include -#include #include +#include #include "Mod/Part/App/PrimitiveFeature.h" #ifndef M_PI @@ -66,7 +69,7 @@ using namespace PartDesign; -PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, App::DocumentObject) +PROPERTY_SOURCE_ABSTRACT(PartDesign::Datum, App::GeoFeature) Datum::Datum(void) { @@ -98,14 +101,14 @@ void Datum::onChanged(const App::Property* prop) refTypes.insert(getRefType(refs[r], refnames[r])); } - App::DocumentObject::onChanged(prop); + App::GeoFeature::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(); + App::GeoFeature::onDocumentRestored(); } // Note: We don't distinguish between e.g. datum lines and edges here @@ -263,7 +266,7 @@ PROPERTY_SOURCE(PartDesign::Point, PartDesign::Datum) Point::Point() { - ADD_PROPERTY_TYPE(_Point,(Base::Vector3d(0,0,1)),"DatumPoint", + ADD_PROPERTY_TYPE(_Point,(Base::Vector3d(0,0,0)),"DatumPoint", App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), "Coordinates of the datum point"); } @@ -284,7 +287,7 @@ void Point::onChanged(const App::Property* prop) // Extract the geometry of the references std::vector refs = References.getValues(); std::vector refnames = References.getSubValues(); - Base::Vector3f* point = NULL; + Base::Vector3d* point = NULL; Handle_Geom_Curve c1 = NULL; Handle_Geom_Curve c2 = NULL; Handle_Geom_Surface s1 = NULL; @@ -297,13 +300,40 @@ void Point::onChanged(const App::Property* prop) point = new Base::Vector3d (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()); + Base::Vector3d base = l->_Base.getValue(); + Base::Vector3d dir = l->_Direction.getValue(); + if (c1.IsNull()) + c1 = new Geom_Line(gp_Pnt(base.x, base.y, base.z), gp_Dir(dir.x, dir.y, dir.z)); + else + c2 = new Geom_Line(gp_Pnt(base.x, base.y, base.z), gp_Dir(dir.x, dir.y, dir.z)); } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { PartDesign::Plane* p = static_cast(refs[i]); - //point = new Base::Vector3f (p->_Point.getValue()); + Base::Vector3d base = p->_Base.getValue(); + Base::Vector3d normal = p->_Normal.getValue(); + if (s1.IsNull()) + s1 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); + else if (s2.IsNull()) + s2 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); + else + s3 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); } else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { App::Plane* p = static_cast(refs[i]); - //point = new Base::Vector3f (p->_Point.getValue()); + // Note: We only handle the three base planes here + gp_Pnt base(0,0,0); + gp_Dir normal; + if (strcmp(p->getNameInDocument(), "BaseplaneXY") == 0) + normal = gp_Dir(0,0,1); + else if (strcmp(p->getNameInDocument(), "BaseplaneYZ") == 0) + normal = gp_Dir(1,0,0); + else if (strcmp(p->getNameInDocument(), "BaseplaneXZ") == 0) + normal = gp_Dir(0,1,0); + + if (s1.IsNull()) + s1 = new Geom_Plane(base, normal); + else if (s2.IsNull()) + s2 = new Geom_Plane(base, normal); + else + s3 = new Geom_Plane(base, normal); } else if (refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { Part::Feature* feature = static_cast(refs[i]); const TopoDS_Shape& sh = feature->Shape.getValue(); @@ -317,7 +347,7 @@ void Point::onChanged(const App::Property* prop) 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()); + point = new Base::Vector3d(p.X(), p.Y(), p.Z()); } else if (subshape.ShapeType() == TopAbs_EDGE) { TopoDS_Edge e = TopoDS::Edge(subshape); Standard_Real first, last; @@ -337,7 +367,7 @@ void Point::onChanged(const App::Property* prop) } else { return; //"PartDesign::Point: Invalid reference type" } - } + } if (point != NULL) { // Point from vertex or other point. Nothing to be done @@ -350,7 +380,7 @@ void Point::onChanged(const App::Property* prop) // 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()); + point = new Base::Vector3d(p.X(), p.Y(), p.Z()); } else if (!s1.IsNull()) { GeomAPI_IntCS intersector(c1, s1); if (!intersector.IsDone() || (intersector.NbPoints() == 0)) @@ -359,7 +389,7 @@ void Point::onChanged(const App::Property* prop) 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()); + point = new Base::Vector3d(p.X(), p.Y(), p.Z()); } else return; } else if (!s1.IsNull() && !s2.IsNull() && !s3.IsNull()) { @@ -377,7 +407,7 @@ void Point::onChanged(const App::Property* prop) 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()); + point = new Base::Vector3d(p.X(), p.Y(), p.Z()); } else { return; } @@ -402,6 +432,12 @@ PROPERTY_SOURCE(PartDesign::Line, PartDesign::Datum) Line::Line() { + ADD_PROPERTY_TYPE(_Base,(Base::Vector3d(0,0,0)),"DatumLine", + App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Coordinates of the line base point"); + ADD_PROPERTY_TYPE(_Direction,(Base::Vector3d(1,1,1)),"DatumLine", + App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Coordinates of the line direction"); } Line::~Line() @@ -410,11 +446,129 @@ Line::~Line() void Line::onChanged(const App::Property *prop) { - gp_Pnt point1(0,0,0); + Datum::onChanged(prop); - gp_Pnt point2(10,10,10); + if (prop == &References) { + std::set hint = getHint(); + if (!((hint.size() == 1) && (hint.find(QObject::tr("Line")) != hint.end()))) + return; // incomplete references - return; + // Extract the geometry of the references + std::vector refs = References.getValues(); + std::vector refnames = References.getSubValues(); + Base::Vector3d* base = NULL; + Base::Vector3d* direction = NULL; + Base::Vector3d* p1 = NULL; + Base::Vector3d* p2 = NULL; + gp_Lin* line = NULL; + Handle_Geom_Surface s1 = NULL; + Handle_Geom_Surface s2 = NULL; + + for (int i = 0; i < refs.size(); i++) { + if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) { + PartDesign::Point* p = static_cast(refs[i]); + if (p1 == NULL) + p1 = new Base::Vector3d (p->_Point.getValue()); + else + p2 = new Base::Vector3d (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + PartDesign::Line* l = static_cast(refs[i]); + base = new Base::Vector3d (l->_Base.getValue()); + direction = new Base::Vector3d (l->_Direction.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + PartDesign::Plane* p = static_cast(refs[i]); + Base::Vector3d base = p->_Base.getValue(); + Base::Vector3d normal = p->_Normal.getValue(); + if (s1.IsNull()) + s1 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); + else + s2 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z)); + } else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + App::Plane* p = static_cast(refs[i]); + // Note: We only handle the three base planes here + gp_Pnt base(0,0,0); + gp_Dir normal; + if (strcmp(p->getNameInDocument(), "BaseplaneXY") == 0) + normal = gp_Dir(0,0,1); + else if (strcmp(p->getNameInDocument(), "BaseplaneYZ") == 0) + normal = gp_Dir(1,0,0); + else if (strcmp(p->getNameInDocument(), "BaseplaneXZ") == 0) + normal = gp_Dir(0,1,0); + + if (s1.IsNull()) + s1 = new Geom_Plane(base, normal); + else + s2 = new Geom_Plane(base, normal); + } 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::Line: Reference has NULL shape" + // Get subshape + TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str()); + if (subshape.IsNull()) + return; // "PartDesign::Line: Reference has NULL subshape"; + + if (subshape.ShapeType() == TopAbs_VERTEX) { + TopoDS_Vertex v = TopoDS::Vertex(subshape); + gp_Pnt p = BRep_Tool::Pnt(v); + if (p1 == NULL) + p1 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + else + p2 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + } else if (subshape.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge e = TopoDS::Edge(subshape); + BRepAdaptor_Curve adapt(e); + if (adapt.GetType() != GeomAbs_Line) + return; // Non-linear edge + line = new gp_Lin(adapt.Line()); + } else if (subshape.ShapeType() == TopAbs_FACE) { + TopoDS_Face f = TopoDS::Face(subshape); + if (s1.IsNull()) + s1 = BRep_Tool::Surface(f); + else + s2 = BRep_Tool::Surface(f); + } + } else { + return; //"PartDesign::Point: Invalid reference type" + } + } + + if ((base != NULL) && (direction != NULL)) { + // Line from other datum line. Nothing to be done + } else if ((p1 != NULL) && (p2 != NULL)) { + // Line from two points + base = new Base::Vector3d(*p1); + direction = new Base::Vector3d(*p2 - *p1); + } else if (line != NULL) { + // Line from gp_lin + base = new Base::Vector3d(line->Location().X(), line->Location().Y(), line->Location().Z()); + direction = new Base::Vector3d(line->Direction().X(), line->Direction().Y(), line->Direction().Z()); + } else if (!s1.IsNull() && !s2.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_Line l = Handle_Geom_Line::DownCast(intersectorSS.Line(1)); + if (l.IsNull()) + return; // non-linear intersection curve + gp_Lin lin = l->Lin(); + base = new Base::Vector3d(lin.Location().X(), lin.Location().Y(), lin.Location().Z()); + direction = new Base::Vector3d(lin.Direction().X(), lin.Direction().Y(), lin.Direction().Z()); + } else { + return; + } + + _Base.setValue(*base); + _Direction.setValue(*direction); + _Base.touch(); // This triggers ViewProvider::updateData() + delete base; + delete direction; + if (p1 != NULL) delete p1; + if (p2 != NULL) delete p2; + if (line != NULL) delete line; + } } @@ -431,20 +585,129 @@ PROPERTY_SOURCE(PartDesign::Plane, PartDesign::Datum) Plane::Plane() { +ADD_PROPERTY_TYPE(_Base,(Base::Vector3d(0,0,0)),"DatumPlane", + App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Coordinates of the plane base point"); +ADD_PROPERTY_TYPE(_Normal,(Base::Vector3d(1,1,1)),"DatumPlane", + App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Coordinates of the plane normal"); } void Plane::onChanged(const App::Property *prop) { - double O = 10.0; //this->Offset.getValue(); - double A = 45.0; //this->Angle.getValue(); + Datum::onChanged(prop); - if (fabs(A) > 360.0) - return; // "Angle too large (please use -360.0 .. +360.0)" + if (prop == &References) { + std::set hint = getHint(); + if (!((hint.size() == 1) && (hint.find(QObject::tr("Plane")) != hint.end()))) + return; // incomplete references - gp_Pnt pnt(0.0,0.0,0.0); - gp_Dir dir(0.0,0.0,1.0); + // Extract the geometry of the references + std::vector refs = References.getValues(); + std::vector refnames = References.getSubValues(); + Base::Vector3d* p1 = NULL; + Base::Vector3d* p2 = NULL; + Base::Vector3d* p3 = NULL; + Base::Vector3d* normal = NULL; + gp_Lin* line = NULL; - return; + for (int i = 0; i < refs.size(); i++) { + if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) { + PartDesign::Point* p = static_cast(refs[i]); + if (p1 == NULL) + p1 = new Base::Vector3d (p->_Point.getValue()); + else if (p2 == NULL) + p2 = new Base::Vector3d (p->_Point.getValue()); + else + p3 = new Base::Vector3d (p->_Point.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { + PartDesign::Line* l = static_cast(refs[i]); + Base::Vector3d base = l->_Base.getValue(); + Base::Vector3d dir = l->_Direction.getValue(); + line = new gp_Lin(gp_Pnt(base.x, base.y, base.z), gp_Dir(dir.x, dir.y, dir.z)); + } else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + PartDesign::Plane* p = static_cast(refs[i]); + p1 = new Base::Vector3d(p->_Base.getValue()); + normal = new Base::Vector3d(p->_Normal.getValue()); + } else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + App::Plane* p = static_cast(refs[i]); + // Note: We only handle the three base planes here + p1 = new Base::Vector3d(0,0,0); + normal = new Base::Vector3d; + if (strcmp(p->getNameInDocument(), "BaseplaneXY") == 0) + *normal = Base::Vector3d(0,0,1); + else if (strcmp(p->getNameInDocument(), "BaseplaneYZ") == 0) + *normal = Base::Vector3d(1,0,0); + else if (strcmp(p->getNameInDocument(), "BaseplaneXZ") == 0) + *normal = Base::Vector3d(0,1,0); + } 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::Plane: Reference has NULL shape" + // Get subshape + TopoDS_Shape subshape = feature->Shape.getShape().getSubShape(refnames[i].c_str()); + if (subshape.IsNull()) + return; // "PartDesign::Plane: Reference has NULL subshape"; + + if (subshape.ShapeType() == TopAbs_VERTEX) { + TopoDS_Vertex v = TopoDS::Vertex(subshape); + gp_Pnt p = BRep_Tool::Pnt(v); + if (p1 == NULL) + p1 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + else if (p2 == NULL) + p2 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + else + p3 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + } else if (subshape.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge e = TopoDS::Edge(subshape); + BRepAdaptor_Curve adapt(e); + if (adapt.GetType() != GeomAbs_Line) + return; // Non-linear edge + line = new gp_Lin(adapt.Line()); + } else if (subshape.ShapeType() == TopAbs_FACE) { + TopoDS_Face f = TopoDS::Face(subshape); + BRepAdaptor_Surface adapt(f); + if (adapt.GetType() != GeomAbs_Plane) + return; // Non-planar face + gp_Pnt b = adapt.Plane().Location(); + gp_Dir d = adapt.Plane().Axis().Direction(); + p1 = new Base::Vector3d(b.X(), b.Y(), b.Z()); + normal = new Base::Vector3d(d.X(), d.Y(), d.Z()); + } + } else { + return; //"PartDesign::Plane: Invalid reference type" + } + } + + if ((p1 != NULL) && (normal != NULL)) { + // plane from other plane. Nothing to be done + } else if ((p1 != NULL) && (p2 != NULL) && (p3 != NULL)) { + // Plane from three points + Base::Vector3d vec1 = *p2 - *p1; + Base::Vector3d vec2 = *p3 - *p1; + normal = new Base::Vector3d(vec1 % vec2); + } else if ((line != NULL) && (p1 != NULL)) { + // Plane from point and line + p2 = new Base::Vector3d(line->Location().X(), line->Location().Y(), line->Location().Z()); + gp_Pnt p(line->Location().X() + line->Direction().X(), line->Location().Y() + line->Direction().Y(), line->Location().Z() + line->Direction().Z()); + p3 = new Base::Vector3d(p.X(), p.Y(), p.Z()); + Base::Vector3d vec1 = *p2 - *p1; + Base::Vector3d vec2 = *p3 - *p1; + normal = new Base::Vector3d(vec1 % vec2); + } else { + return; + } + + _Base.setValue(*p1); + _Normal.setValue(*normal); + _Base.touch(); // This triggers ViewProvider::updateData() + delete p1; + delete normal; + if (p2 != NULL) delete p2; + if (p3 != NULL) delete p3; + if (line != NULL) delete line; + } } diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 5277285ed..7081d2f23 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -216,19 +216,27 @@ const QString getReferenceString(Gui::Command* cmd) if(!pcActiveBody) return QString::fromAscii(""); Gui::SelectionFilter GeometryFilter("SELECT Part::Feature SUBELEMENT Face COUNT 1"); + Gui::SelectionFilter DatumFilter ("SELECT PartDesign::Plane COUNT 1"); Gui::SelectionFilter EdgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1"); + Gui::SelectionFilter LineFilter ("SELECT PartDesign::Line COUNT 1"); Gui::SelectionFilter VertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 1"); + Gui::SelectionFilter PointFilter ("SELECT PartDesign::Point COUNT 1"); Gui::SelectionFilter PlaneFilter ("SELECT App::Plane COUNT 1"); - Gui::SelectionFilter PlaneFilter2 ("SELECT PartDesign::Plane COUNT 1"); + if (EdgeFilter.match()) GeometryFilter = EdgeFilter; else if (VertexFilter.match()) GeometryFilter = VertexFilter; - if (PlaneFilter2.match()) - PlaneFilter = PlaneFilter2; - if (GeometryFilter.match() || PlaneFilter.match()) { + if (LineFilter.match()) + DatumFilter = LineFilter; + else if (PointFilter.match()) + DatumFilter = PointFilter; + else if (PlaneFilter.match()) + DatumFilter = PlaneFilter; + + if (GeometryFilter.match() || DatumFilter.match()) { // get the selected object if (GeometryFilter.match()) { Part::Feature *part = static_cast(GeometryFilter.Result[0][0].getObject()); @@ -257,7 +265,7 @@ const QString getReferenceString(Gui::Command* cmd) return referenceString; } else { - Part::Feature *part = static_cast(PlaneFilter.Result[0][0].getObject()); + Part::Feature *part = static_cast(DatumFilter.Result[0][0].getObject()); return QString::fromAscii("[(App.activeDocument().") + QString::fromAscii(part->getNameInDocument()) + QString::fromAscii(",'')]"); } @@ -296,9 +304,8 @@ const QString getReferenceString(Gui::Command* cmd) if (!body->hasFeature(*r)) { status.push_back(PartDesignGui::FeaturePickDialog::otherBody); continue; - } else { - if (body->isAfterTip(*r)) - status.push_back(PartDesignGui::FeaturePickDialog::afterTip); + } else if (body->isAfterTip(*r)) { + status.push_back(PartDesignGui::FeaturePickDialog::afterTip); continue; } @@ -311,7 +318,7 @@ const QString getReferenceString(Gui::Command* cmd) if (validRefs == 0) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid references in this document"), - QObject::tr("Please select a face, edge or vertex")); + QObject::tr("Please select a datum feature, or a face, edge or vertex")); return QString::fromAscii(""); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp index 2f57d4574..46773c7cf 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include using namespace PartDesignGui; diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 81157b44e..bdba81f42 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include using namespace PartDesignGui; @@ -261,6 +262,7 @@ void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) con if (strcmp(recipient,"Tree") == 0) { if (Gui::Selection().countObjectsOfType(PartDesign::Feature::getClassTypeId()) + + Gui::Selection().countObjectsOfType(PartDesign::Datum::getClassTypeId()) + Gui::Selection().countObjectsOfType(Part::Part2DObject::getClassTypeId()) > 0 ) *item << "PartDesign_MoveTip"; } diff --git a/src/Mod/Sketcher/App/PreCompiled.h b/src/Mod/Sketcher/App/PreCompiled.h index 0ea5baa48..017e51666 100644 --- a/src/Mod/Sketcher/App/PreCompiled.h +++ b/src/Mod/Sketcher/App/PreCompiled.h @@ -30,10 +30,12 @@ #ifdef FC_OS_WIN32 # define SketcherExport __declspec(dllexport) # define PartExport __declspec(dllimport) +# define PartDesignExport __declspec(dllimport) # define MeshExport __declspec(dllimport) #else // for Linux # define SketcherExport # define PartExport +# define PartDesignExport # define MeshExport #endif diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 95af4568d..7e75f2a34 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -57,6 +57,7 @@ #include #include +#include #include "SketchObject.h" #include "SketchObjectPy.h" @@ -114,7 +115,19 @@ SketchObject::~SketchObject() App::DocumentObjectExecReturn *SketchObject::execute(void) { try { - this->positionBySupport(); + App::DocumentObject* support = Support.getValue(); + if (support == NULL) + throw Base::Exception("Sketch support has been deleted"); + + if (support->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { + // We don't want to handle this case in Part::Part2DObject because then Part would depend on PartDesign + PartDesign::Plane* plane = static_cast(support); + Base::Vector3d pos = plane->_Base.getValue(); + Base::Vector3d normal = plane->_Normal.getValue(); + this->Placement.setValue(Base::Placement(pos, Base::Rotation(Base::Vector3d(0,0,1), normal))); + } else { + this->positionBySupport(); + } } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what());