diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 390ca047bd..2c3d5e2330 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -301,6 +301,44 @@ void SubShapeBinder::setupObject() { checkPropertyStatus(); } +App::DocumentObject *SubShapeBinder::getSubObject(const char *subname, PyObject **pyObj, + Base::Matrix4D *mat, bool transform, int depth) const +{ + auto sobj = Part::Feature::getSubObject(subname,pyObj,mat,transform,depth); + if(sobj) + return sobj; + if(Data::ComplexGeoData::findElementName(subname)==subname) + return nullptr; + + const char *dot = strchr(subname, '.'); + if(!dot) + return nullptr; + + App::GetApplication().checkLinkDepth(depth); + std::string name(subname,dot-subname); + for(auto &l : Support.getSubListValues()) { + auto obj = l.getValue(); + if(!obj || !obj->getNameInDocument()) + continue; + for(auto &sub : l.getSubValues()) { + auto sobj = obj->getSubObject(sub.c_str()); + if(!sobj || !sobj->getNameInDocument()) + continue; + if(subname[0] == '$') { + if(sobj->Label.getStrValue() != name.c_str()+1) + continue; + } else if(!boost::equals(sobj->getNameInDocument(), name)) + continue; + name = Data::ComplexGeoData::noElementName(sub.c_str()); + name += dot+1; + if(mat && transform) + *mat *= Placement.getValue().toMatrix(); + return obj->getSubObject(name.c_str(),pyObj,mat,true,depth+1); + } + } + return nullptr; +} + void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { Part::TopoShape result; std::vector shapes; diff --git a/src/Mod/PartDesign/App/ShapeBinder.h b/src/Mod/PartDesign/App/ShapeBinder.h index d5c60e0b40..8cb528a65b 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.h +++ b/src/Mod/PartDesign/App/ShapeBinder.h @@ -106,6 +106,9 @@ public: virtual bool canLinkProperties() const override {return false;} + virtual App::DocumentObject *getSubObject(const char *subname, PyObject **pyObj=0, + Base::Matrix4D *mat=0, bool transform=true, int depth=0) const override; + protected: virtual App::DocumentObjectExecReturn* execute(void) override; virtual void onChanged(const App::Property *prop) override; diff --git a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp index e630e070e1..47bddf8086 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp @@ -343,9 +343,26 @@ void ViewProviderSubShapeBinder::updatePlacement(bool transaction) { std::vector ViewProviderSubShapeBinder::claimChildren(void) const { std::vector ret; - auto self = dynamic_cast(getObject()); - if(self && self->ClaimChildren.getValue() && self->Support.getValue()) - ret.push_back(self->Support.getValue()); + auto self = Base::freecad_dynamic_cast(getObject()); + if(self && self->ClaimChildren.getValue() && self->Support.getValue()) { + std::set objSet; + for(auto &l : self->Support.getSubListValues()) { + auto obj = l.getValue(); + if(!obj) + continue; + const auto &subs = l.getSubValues(); + if(subs.empty()) { + if(objSet.insert(obj).second) + ret.push_back(obj); + continue; + } + for(auto &sub : subs) { + auto sobj = obj->getSubObject(sub.c_str()); + if(sobj && objSet.insert(sobj).second) + ret.push_back(sobj); + } + } + } return ret; }