diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index b9fd563da4..805ab7f695 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -502,6 +502,35 @@ std::vector Body::getSubObjects(int reason) const { App::DocumentObject *Body::getSubObject(const char *subname, PyObject **pyObj, Base::Matrix4D *pmat, bool transform, int depth) const { + while (subname && *subname == '.') { + ++subname; // skip leading . + } + + // PartDesign::Feature now support grouping sibling features, and the user + // is free to expand/collapse at any time. To not disrupt subname path + // because of this, the body will peek the next two sub-objects reference, + // and skip the first sub-object if possible. + if (subname) { + const char* firstDot = strchr(subname, '.'); + if (firstDot) { + const char* secondDot = strchr(firstDot + 1, '.'); + if (secondDot) { + auto firstObj = Group.find(std::string(subname, firstDot).c_str()); + if (!firstObj || firstObj->isDerivedFrom(PartDesign::Feature::getClassTypeId())) { + auto secondObj = Group.find(std::string(firstDot + 1, secondDot).c_str()); + if (secondObj) { + // we support only one level of sibling grouping, so no + // recursive call to our own getSubObject() + return Part::BodyBase::getSubObject(firstDot + 1, + pyObj, + pmat, + transform, + depth + 1); + } + } + } + } + } #if 1 return Part::BodyBase::getSubObject(subname,pyObj,pmat,transform,depth); #else diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index f8ab21acd0..884b054edc 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -59,6 +59,8 @@ #endif #include +#include +#include #include #include @@ -97,6 +99,7 @@ using namespace Sketcher; using namespace Base; namespace sp = std::placeholders; +namespace bio = boost::iostreams; FC_LOG_LEVEL_INIT("Sketch", true, true) @@ -9735,10 +9738,60 @@ Part::TopoShape SketchObject::getEdge(const Part::Geometry *geo, const char *nam return shape; } -Data::IndexedName SketchObject::checkSubName(const char *sub) const -{ - // FIXME: trivial implementation needs to be replaced with full logic - (void)sub; +Data::IndexedName SketchObject::checkSubName(const char *subname) const{ + static std::vector types = { + "Edge", + "Vertex", + "edge", + "vertex", + "ExternalEdge", + "RootPoint", + "H_Axis", + "V_Axis", + "Constraint", + + // other feature from LS3 not related to TNP + "InternalEdge", + "InternalFace", + "InternalVertex", + }; + + if(!subname) return Data::IndexedName(); + const char *mappedSubname = Data::isMappedElement(subname); + + // if not a mapped name parse the indexed name directly, uppercasing "edge" and "vertex" + if(!mappedSubname) { + Data::IndexedName result(subname, types, true); + if (boost::equals(result.getType(), "edge")) + return Data::IndexedName("Edge", result.getIndex()); + if (boost::equals(result.getType(), "vertex")) + return Data::IndexedName("Vertex", result.getIndex()); + return result; + } + + bio::stream iss(mappedSubname+1, std::strlen(mappedSubname+1)); + int id = -1; + switch(mappedSubname[0]) { + case '\0': // check length != 0 + FC_ERR("invalid subname " << subname); + break; + + case 'g': // = geometry + case 'e': // = external geometry + if(!(iss>>id)) + FC_ERR("invalid subname " << subname); + break; + + // for RootPoint, H_Axis, V_Axis + default: { + const char *dot = strchr(mappedSubname,'.'); + if(dot) + mappedSubname = dot+1; + return Data::IndexedName(mappedSubname, types, false); + }} + + // TNP July '24: omitted code related to external and internal sketcher stuff implemented in LS3 + return Data::IndexedName(); } diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index b6a10acbc4..d88bca68c0 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -680,7 +680,7 @@ public: Part::TopoShape getEdge(const Part::Geometry* geo, const char* name) const; - Data::IndexedName checkSubName(const char* sub) const; + Data::IndexedName checkSubName(const char* subname) const; bool geoIdFromShapeType(const Data::IndexedName&, int& geoId, PointPos& posId) const;