From f1d6c78cbe3c17a0b219e0f7b1443ec53463b80a Mon Sep 17 00:00:00 2001 From: David Osterberg Date: Sun, 14 Feb 2021 08:48:31 +0100 Subject: [PATCH] PartDesign: Allow use of circle edge as axis in ProfileBased --- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 17 ++++++++++++----- src/Mod/PartDesign/Gui/ReferenceSelection.cpp | 13 +++++++++++-- src/Mod/PartDesign/Gui/ReferenceSelection.h | 10 ++++++---- src/Mod/PartDesign/Gui/TaskHelixParameters.cpp | 2 +- .../PartDesign/Gui/TaskRevolutionParameters.cpp | 2 +- .../Gui/TaskSketchBasedParameters.cpp | 5 ++--- .../PartDesign/Gui/TaskSketchBasedParameters.h | 2 +- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 3a5498548824..01141a2a8017 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -46,6 +46,7 @@ # include # include # include +# include # include # include # include @@ -1129,12 +1130,18 @@ void ProfileBased::getAxis(const App::DocumentObject *pcReferenceAxis, const std if (refEdge.IsNull()) throw Base::ValueError("Failed to extract rotation edge"); BRepAdaptor_Curve adapt(refEdge); - if (adapt.GetType() != GeomAbs_Line) - throw Base::TypeError("Rotation edge must be a straight line"); - - gp_Pnt b = adapt.Line().Location(); + gp_Pnt b; + gp_Dir d; + if (adapt.GetType() == GeomAbs_Line) { + b = adapt.Line().Location(); + d = adapt.Line().Direction(); + } else if (adapt.GetType() == GeomAbs_Circle) { + b = adapt.Circle().Location(); + d = adapt.Circle().Axis().Direction(); + } else { + throw Base::TypeError("Rotation edge must be a straight line, circle or arc of circle"); + } base = Base::Vector3d(b.X(), b.Y(), b.Z()); - gp_Dir d = adapt.Line().Direction(); dir = Base::Vector3d(d.X(), d.Y(), d.Z()); // Check that axis is co-planar with sketch plane! // Check that axis is perpendicular with sketch plane! diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index 431bb690d9a4..7bace9f3e53c 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -77,7 +77,7 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c } else { // fallback to active part originGroupObject = PartDesignGui::getActivePart ( ); } - + App::OriginGroupExtension* originGroup = nullptr; if(originGroupObject) originGroup = originGroupObject->getExtensionByType(); @@ -172,6 +172,15 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c if (point && subName.size() > 6 && subName.substr(0,6) == "Vertex") { return true; } + if (circle && subName.size() > 4 && subName.substr(0,4) == "Edge") { + const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(subName.c_str()); + const TopoDS_Edge& edgeShape = TopoDS::Edge(sh); + BRepAdaptor_Curve adapt(edgeShape); + if (adapt.GetType() == GeomAbs_Circle) { + return true; + } + } return false; } @@ -212,7 +221,7 @@ bool getReferencedSelection(const App::DocumentObject* thisObj, const Gui::Selec std::string subname = msg.pSubName; //check if the selection is an external reference and ask the user what to do - //of course only if thisObj is in a body, as otherwise the old workflow would not + //of course only if thisObj is in a body, as otherwise the old workflow would not //be supported PartDesign::Body* body = PartDesignGui::getBodyFor(thisObj, false); bool originfeature = selObj->isDerivedFrom(App::OriginFeature::getClassTypeId()); diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.h b/src/Mod/PartDesign/Gui/ReferenceSelection.h index 11cf85f29d63..42490a75cebf 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.h +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.h @@ -42,14 +42,16 @@ class ReferenceSelection : public Gui::SelectionFilterGate bool allowOtherBody; // Allow whole object selection bool whole; + // Allow picking circular edges (incl arcs) + bool circle; public: ReferenceSelection(const App::DocumentObject* support_, - const bool edge_, const bool plane_, const bool planar_, - const bool point_ = false, bool whole_ = false) + const bool edge_, const bool plane_, const bool planar_, + const bool point_ = false, bool whole_ = false, bool circle_ = false) : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), - support(support_), edge(edge_), plane(plane_), - planar(planar_), point(point_), allowOtherBody(true), whole(whole_) + support(support_), edge(edge_), plane(plane_), + planar(planar_), point(point_), allowOtherBody(true), whole(whole_), circle(circle_) { } /** diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp index 8c9f24eea25e..b23fef1b6fd0 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp @@ -361,7 +361,7 @@ void TaskHelixParameters::onAxisChanged(int num) App::PropertyLinkSub &lnk = *(axesInList[num]); if (lnk.getValue() == 0) { // enter reference selection mode - TaskSketchBasedParameters::onSelectReference(true, true, false, true); + TaskSketchBasedParameters::onSelectReference(true, true, false, true, true); return; } else { if (!pcHelix->getDocument()->isIn(lnk.getValue())){ diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp index 7da3ea44a4fb..27029e5f022c 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp @@ -276,7 +276,7 @@ void TaskRevolutionParameters::onAxisChanged(int num) App::PropertyLinkSub &lnk = *(axesInList[num]); if (lnk.getValue() == 0) { // enter reference selection mode - TaskSketchBasedParameters::onSelectReference(true, true, false, true); + TaskSketchBasedParameters::onSelectReference(true, true, false, true, true); } else { if (!pcRevolution->getDocument()->isIn(lnk.getValue())){ Base::Console().Error("Object was deleted\n"); diff --git a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp index 07980efdf6d8..696efbbb5664 100644 --- a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.cpp @@ -92,7 +92,6 @@ const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChan return refStr; } - void TaskSketchBasedParameters::startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base) { Gui::Document* doc = vp->getDocument(); @@ -113,7 +112,7 @@ void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* pr } } -void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar) { +void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar, const bool circle) { // Note: Even if there is no solid, App::Plane and Part::Datum can still be selected PartDesign::ProfileBased* pcSketchBased = dynamic_cast(vp->getObject()); @@ -125,7 +124,7 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool startReferenceSelection(pcSketchBased, prevSolid); Gui::Selection().clearSelection(); Gui::Selection().addSelectionGate - (new ReferenceSelection(prevSolid, edge, face, planar)); + (new ReferenceSelection(prevSolid, edge, face, planar, false, false, circle)); } else { Gui::Selection().rmvSelectionGate(); finishReferenceSelection(pcSketchBased, prevSolid); diff --git a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h index 351e485230bc..539848a43571 100644 --- a/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h +++ b/src/Mod/PartDesign/Gui/TaskSketchBasedParameters.h @@ -53,7 +53,7 @@ class TaskSketchBasedParameters : public PartDesignGui::TaskFeatureParameters, const QString onAddSelection(const Gui::SelectionChanges& msg); virtual void startReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base); virtual void finishReferenceSelection(App::DocumentObject* profile, App::DocumentObject* base); - void onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar); + void onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar, const bool circle = false); void exitSelectionMode(); QVariant setUpToFace(const QString& text); /// Try to find the name of a feature with the given label.