From bcea5241772dd57f373448c1f937cda7bd73d211 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Thu, 4 Jul 2024 12:56:27 -0400 Subject: [PATCH 1/2] 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(); } From 0e5690d732521384c081f64cae90f381bfbf7eba Mon Sep 17 00:00:00 2001 From: Pesc0 Date: Thu, 11 Jul 2024 18:22:47 +0200 Subject: [PATCH 2/2] Rename variables and clean method --- src/Mod/Sketcher/App/SketchObject.cpp | 103 +++++++++----------------- src/Mod/Sketcher/App/SketchObject.h | 2 +- 2 files changed, 35 insertions(+), 70 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index fb7a6e82b7..884b054edc 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -9738,7 +9738,7 @@ Part::TopoShape SketchObject::getEdge(const Part::Geometry *geo, const char *nam return shape; } -Data::IndexedName SketchObject::checkSubName(const char *sub) const{ +Data::IndexedName SketchObject::checkSubName(const char *subname) const{ static std::vector types = { "Edge", "Vertex", @@ -9749,84 +9749,49 @@ Data::IndexedName SketchObject::checkSubName(const char *sub) const{ "H_Axis", "V_Axis", "Constraint", + + // other feature from LS3 not related to TNP "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(); + 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; } -#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); - } + 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 'e': { - auto it = externalGeoMap.find(id); - if(it!=externalGeoMap.end()) { - geoId = -it->second - 1; - geo = getGeometry(geoId); - } + + 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); }} - 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 + + // 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;