diff --git a/src/App/Part.cpp b/src/App/Part.cpp index f66a32d0fc..c56bee1c84 100644 --- a/src/App/Part.cpp +++ b/src/App/Part.cpp @@ -67,19 +67,38 @@ Part::~Part(void) { } -App::Part *Part::getPartOfObject (const DocumentObject* obj) { - +static App::Part *_getPartOfObject(const DocumentObject *obj, + std::set *objset) +{ // as a Part is a geofeaturegroup it must directly link to all // objects it contains, even if they are in additional groups etc. - auto list = obj->getInList(); - for (auto obj : list) { - if(obj->isDerivedFrom(App::Part::getClassTypeId())) - return static_cast(obj); + // But we still must call 'hasObject()' to exclude link brought in by + // expressions. + for (auto inObj : obj->getInList()) { + if (objset && !objset->insert(inObj).second) + continue; + auto group = inObj->getExtensionByType(true); + if(group && group->hasObject(obj)) { + if(inObj->isDerivedFrom(App::Part::getClassTypeId())) + return static_cast(inObj); + else if (objset) + return _getPartOfObject(inObj, objset); + // Only one parent geofeature group per object, so break + break; + } } return nullptr; } +App::Part *Part::getPartOfObject (const DocumentObject* obj, bool recursive) { + if (!recursive) + return _getPartOfObject(obj, nullptr); + std::set objset; + objset.insert(obj); + return _getPartOfObject(obj, &objset); +} + PyObject *Part::getPyObject() { diff --git a/src/App/Part.h b/src/App/Part.h index bd509d898a..8c7667fbd0 100644 --- a/src/App/Part.h +++ b/src/App/Part.h @@ -88,8 +88,9 @@ public: * Returns the part which contains this object. * In case this object does not belong to any Part, 0 is returned. * @param obj the object to search for + * @param recursive: whether to recursively find any grand parent Part container */ - static App::Part* getPartOfObject (const DocumentObject* obj); + static App::Part* getPartOfObject (const DocumentObject* obj, bool recursive=true); virtual PyObject *getPyObject(void) override; };