diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index bf585c598e..55feb77d9e 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -60,76 +60,21 @@ using namespace Gui; bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName) { - // TODO review this function (2015-09-04, Fat-Zer) - PartDesign::Body *body; - App::DocumentObject* originGroupObject = nullptr; - - if ( support ) { - body = PartDesign::Body::findBodyOf (support); - } else { - body = PartDesignGui::getBody (false); - } - - if ( body ) { // Search for Part of the body - originGroupObject = App::OriginGroupExtension::getGroupOfObject ( body ) ; - } else if ( support ) { // if no body search part for support - originGroupObject = App::OriginGroupExtension::getGroupOfObject ( support ) ; - } else { // fallback to active part - originGroupObject = PartDesignGui::getActivePart ( ); - } - - App::OriginGroupExtension* originGroup = nullptr; - if(originGroupObject) - originGroup = originGroupObject->getExtensionByType(); + PartDesign::Body *body = getBody(); + App::OriginGroupExtension* originGroup = getOriginGroupExtension(body); // Don't allow selection in other document - if ( support && pDoc != support->getDocument() ) { + if (support && pDoc != support->getDocument()) { return false; } // Enable selection from origin of current part/ - if ( pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()) ) { - bool fits = false; - if ( type.testFlag(AllowSelection::FACE) && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) { - fits = true; - } else if ( type.testFlag(AllowSelection::EDGE) && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) { - fits = true; - } - - if (fits) { // check that it is actually belongs to the chosen body or part - try { // here are some throwers - if (body) { - if (body->getOrigin ()->hasObject (pObj) ) { - return true; - } - } else if (originGroup ) { - if ( originGroup->getOrigin ()->hasObject (pObj) ) { - return true; - } - } - } - catch (const Base::Exception&) { - } - } - return false; // The Plane/Axis doesn't fits our needs + if (pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId())) { + return allowOrigin(body, originGroup, pObj); } if (pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) { - - if (!body) { // Allow selecting Part::Datum features from the active Body - return false; - } else if (!type.testFlag(AllowSelection::OTHERBODY) && !body->hasObject(pObj)) { - return false; - } - - if (type.testFlag(AllowSelection::FACE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId()))) - return true; - if (type.testFlag(AllowSelection::EDGE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId()))) - return true; - if (type.testFlag(AllowSelection::POINT) && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId()))) - return true; - - return false; + return allowDatum(body, pObj); } // The flag was used to be set. So, this block will never be treated and doesn't make really sense anyway @@ -151,51 +96,172 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c } if (pObj && pObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - std::string subName(sSubName); - if (type.testFlag(AllowSelection::EDGE) && subName.compare(0, 4, "Edge") == 0) { - const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); - TopoDS_Shape sh = shape.getSubShape(subName.c_str()); - const TopoDS_Edge& edgeShape = TopoDS::Edge(sh); - if (!edgeShape.IsNull()) { - if (type.testFlag(AllowSelection::PLANAR)) { - BRepAdaptor_Curve adapt(edgeShape); - if (adapt.GetType() == GeomAbs_Line) - return true; - } else { - return true; - } - } - } - if (type.testFlag(AllowSelection::FACE) && subName.compare(0, 4, "Face") == 0) { - const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); - TopoDS_Shape sh = shape.getSubShape(subName.c_str()); - const TopoDS_Face& face = TopoDS::Face(sh); - if (!face.IsNull()) { - if (type.testFlag(AllowSelection::PLANAR)) { - BRepAdaptor_Surface adapt(face); - if (adapt.GetType() == GeomAbs_Plane) - return true; - } else { - return true; - } - } - } - if (type.testFlag(AllowSelection::POINT) && subName.compare(0, 6, "Vertex") == 0) { - return true; - } - if (type.testFlag(AllowSelection::CIRCLE) && subName.compare(0, 4, "Edge") == 0) { - 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 allowPartFeature(pObj, sSubName); } + return false; } +PartDesign::Body* ReferenceSelection::getBody() const +{ + PartDesign::Body *body; + if (support) { + body = PartDesign::Body::findBodyOf (support); + } + else { + body = PartDesignGui::getBody(false); + } + + return body; +} + +App::OriginGroupExtension* ReferenceSelection::getOriginGroupExtension(PartDesign::Body *body) const +{ + App::DocumentObject* originGroupObject = nullptr; + + if (body) { // Search for Part of the body + originGroupObject = App::OriginGroupExtension::getGroupOfObject(body); + } + else if (support) { // if no body search part for support + originGroupObject = App::OriginGroupExtension::getGroupOfObject(support); + } + else { // fallback to active part + originGroupObject = PartDesignGui::getActivePart(); + } + + App::OriginGroupExtension* originGroup = nullptr; + if (originGroupObject) + originGroup = originGroupObject->getExtensionByType(); + + return originGroup; +} + +bool ReferenceSelection::allowOrigin(PartDesign::Body *body, App::OriginGroupExtension* originGroup, App::DocumentObject* pObj) const +{ + bool fits = false; + if (type.testFlag(AllowSelection::FACE) && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { + fits = true; + } + else if (type.testFlag(AllowSelection::EDGE) && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId())) { + fits = true; + } + + if (fits) { // check that it actually belongs to the chosen body or part + try { // here are some throwers + if (body) { + if (body->getOrigin ()->hasObject (pObj) ) { + return true; + } + } + else if (originGroup ) { + if (originGroup->getOrigin()->hasObject(pObj)) { + return true; + } + } + } + catch (const Base::Exception&) { + } + } + return false; // The Plane/Axis doesn't fits our needs +} + +bool ReferenceSelection::allowDatum(PartDesign::Body *body, App::DocumentObject* pObj) const +{ + if (!body) { // Allow selecting Part::Datum features from the active Body + return false; + } + else if (!type.testFlag(AllowSelection::OTHERBODY) && !body->hasObject(pObj)) { + return false; + } + + if (type.testFlag(AllowSelection::FACE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId()))) + return true; + if (type.testFlag(AllowSelection::EDGE) && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId()))) + return true; + if (type.testFlag(AllowSelection::POINT) && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId()))) + return true; + + return false; +} + +bool ReferenceSelection::allowPartFeature(App::DocumentObject* pObj, const char* sSubName) const +{ + std::string subName(sSubName); + if (type.testFlag(AllowSelection::POINT) && subName.compare(0, 6, "Vertex") == 0) { + return true; + } + + if (type.testFlag(AllowSelection::EDGE) && subName.compare(0, 4, "Edge") == 0) { + if (isEdge(pObj, sSubName)) + return true; + } + + if (type.testFlag(AllowSelection::CIRCLE) && subName.compare(0, 4, "Edge") == 0) { + if (isCircle(pObj, sSubName)) + return true; + } + + if (type.testFlag(AllowSelection::FACE) && subName.compare(0, 4, "Face") == 0) { + if (isFace(pObj, sSubName)) + return true; + } + + return false; +} + +bool ReferenceSelection::isEdge(App::DocumentObject* pObj, const char* sSubName) const +{ + const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sSubName); + const TopoDS_Edge& edgeShape = TopoDS::Edge(sh); + if (!edgeShape.IsNull()) { + if (type.testFlag(AllowSelection::PLANAR)) { + BRepAdaptor_Curve adapt(edgeShape); + if (adapt.GetType() == GeomAbs_Line) + return true; + } + else { + return true; + } + } + + return false; +} + +bool ReferenceSelection::isFace(App::DocumentObject* pObj, const char* sSubName) const +{ + const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sSubName); + const TopoDS_Face& face = TopoDS::Face(sh); + if (!face.IsNull()) { + if (type.testFlag(AllowSelection::PLANAR)) { + BRepAdaptor_Surface adapt(face); + if (adapt.GetType() == GeomAbs_Plane) + return true; + } + else { + return true; + } + } + + return false; +} + +bool ReferenceSelection::isCircle(App::DocumentObject* pObj, const char* sSubName) const +{ + const Part::TopoShape &shape = static_cast(pObj)->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sSubName); + const TopoDS_Edge& edgeShape = TopoDS::Edge(sh); + BRepAdaptor_Curve adapt(edgeShape); + if (adapt.GetType() == GeomAbs_Circle) { + return true; + } + + return false; +} + +// ---------------------------------------------------------------------------- + bool NoDependentsSelection::allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* /*sSubName*/) { if (support && support->testIfLinkDAGCompatible(pObj)) { diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.h b/src/Mod/PartDesign/Gui/ReferenceSelection.h index 1c274412e3..ce662c9c77 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.h +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.h @@ -27,6 +27,12 @@ #include #include +namespace App { +class OriginGroupExtension; +} +namespace PartDesign { +class Body; +} namespace PartDesignGui { class ReferenceSelection : public Gui::SelectionFilterGate @@ -47,6 +53,16 @@ public: * Optionally restrict the selection to planar edges/faces */ bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName); + +private: + PartDesign::Body* getBody() const; + App::OriginGroupExtension* getOriginGroupExtension(PartDesign::Body *body) const; + bool allowOrigin(PartDesign::Body *body, App::OriginGroupExtension* originGroup, App::DocumentObject* pObj) const; + bool allowDatum(PartDesign::Body *body, App::DocumentObject* pObj) const; + bool allowPartFeature(App::DocumentObject* pObj, const char* sSubName) const; + bool isEdge(App::DocumentObject* pObj, const char* sSubName) const; + bool isFace(App::DocumentObject* pObj, const char* sSubName) const; + bool isCircle(App::DocumentObject* pObj, const char* sSubName) const; }; class NoDependentsSelection : public Gui::SelectionFilterGate