Toponaming: Missing getSubObject code in PartDesign::Body and SketchObject::getSubObject

This commit is contained in:
Zheng, Lei
2024-07-04 12:56:27 -04:00
committed by bgbsww
parent 7daa22fcc7
commit bcea524177
2 changed files with 121 additions and 4 deletions

View File

@@ -502,6 +502,35 @@ std::vector<std::string> 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

View File

@@ -59,6 +59,8 @@
#endif
#include <boost/algorithm/string/predicate.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <App/Application.h>
#include <App/Document.h>
@@ -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<const char *> 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<bio::array_source> 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<int>(PointPos::none);
if((iss >> sep >> posId) && sep=='v') {
int idx = getVertexIndexGeoPos(geoId, static_cast<PointPos>(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();
}