From bcea5241772dd57f373448c1f937cda7bd73d211 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Thu, 4 Jul 2024 12:56:27 -0400 Subject: [PATCH] Toponaming: Missing getSubObject code in PartDesign::Body and SketchObject::getSubObject --- src/Mod/PartDesign/App/Body.cpp | 29 ++++++++ src/Mod/Sketcher/App/SketchObject.cpp | 96 +++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 4 deletions(-) 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..fb7a6e82b7 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,95 @@ 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 *sub) const{ + static std::vector types = { + "Edge", + "Vertex", + "edge", + "vertex", + "ExternalEdge", + "RootPoint", + "H_Axis", + "V_Axis", + "Constraint", + "InternalEdge", + "InternalFace", + "InternalVertex", + }; + + if(!sub) return Data::IndexedName(); + const char *subname = Data::isMappedElement(sub); + if(!subname) { + Data::IndexedName res(sub, types, true); + if (boost::equals(res.getType(), "edge")) + return Data::IndexedName("Edge", res.getIndex()); + else if (boost::starts_with(res.getType(), "vertex")) + return Data::IndexedName("Vertex", res.getIndex()); + return res; + } + if(!subname[0]) { + FC_ERR("invalid subname " << sub); + return Data::IndexedName(); + } + bio::stream iss(subname+1, std::strlen(subname+1)); + int id = -1; + bool valid = false; + switch(subname[0]) { + case 'g': + case 'e': + if(iss>>id) + valid = true; + break; + default: { + // for RootPoint,H_Axis,V_Axis + const char *dot = strchr(subname,'.'); + if(dot) + subname = dot+1; + return Data::IndexedName(subname, types, false); + }} + if(!valid) { + FC_ERR("invalid subname " << sub); + // return sub; + return Data::IndexedName(); + } + +#ifdef FUTURE_TNP_CODE_FROM_LS3 + int geoId; + const Part::Geometry *geo = 0; + switch(subname[0]) { + case 'g': { + auto it = geoMap.find(id); + if(it!=geoMap.end()) { + geoId = it->second; + geo = getGeometry(geoId); + } + break; + } case 'e': { + auto it = externalGeoMap.find(id); + if(it!=externalGeoMap.end()) { + geoId = -it->second - 1; + geo = getGeometry(geoId); + } + break; + }} + if(geo && GeometryFacade::getId(geo) == id) { + char sep; + int posId = static_cast(PointPos::none); + if((iss >> sep >> posId) && sep=='v') { + int idx = getVertexIndexGeoPos(geoId, static_cast(posId)); + if(idx < 0) { + FC_ERR("invalid subname " << sub); + // return sub; + return Data::IndexedName(); + } + return Data::IndexedName::fromConst("Vertex", idx+1); + }else if(geoId>=0) + return Data::IndexedName::fromConst("Edge", geoId+1); + else + return Data::IndexedName::fromConst("ExternalEdge", -geoId-2); + } + FC_ERR("cannot find subname " << sub); +#endif return Data::IndexedName(); }