App/Part: fix App::Link visibility detection in PartFeature::getTopoShape()

This commit is contained in:
Zheng, Lei
2022-09-05 12:06:06 +05:00
committed by Uwe
parent a46cc55da1
commit 32d45ac97d
3 changed files with 111 additions and 12 deletions
+61 -4
View File
@@ -2177,10 +2177,12 @@ void LinkBaseExtension::expandSubname(std::string &subname) const {
}
static bool isExcludedProperties(const char *name) {
#define CHECK_EXCLUDE_PROP(_name) if(strcmp(name,#_name)==0) return true;
CHECK_EXCLUDE_PROP(Shape);
CHECK_EXCLUDE_PROP(Proxy);
CHECK_EXCLUDE_PROP(Placement);
if (boost::equals(name, "Shape"))
return true;
if (boost::equals(name, "Proxy"))
return true;
if (boost::equals(name, "Placement"))
return true;
return false;
}
@@ -2204,6 +2206,61 @@ Property *LinkBaseExtension::extensionGetPropertyByName(const char* name) const
return nullptr;
}
std::vector<std::string> LinkBaseExtension::getHiddenSubnames(
const App::DocumentObject *obj, const char *prefix)
{
std::vector<std::string> res;
if(!obj || !obj->getNameInDocument())
return res;
PropertyLinkSubHidden *prop;
int depth=0;
while((prop=Base::freecad_dynamic_cast<PropertyLinkSubHidden>(
obj->getPropertyByName("ColoredElements"))))
{
for(auto &v : prop->getShadowSubs()) {
if(prefix && !boost::starts_with(v.first,prefix) && !boost::starts_with(v.second,prefix))
continue;
auto &s = v.second;
if(boost::ends_with(s,DocumentObject::hiddenMarker()))
res.push_back(s.substr(0,s.size()-DocumentObject::hiddenMarker().size()));
}
auto o = Base::freecad_dynamic_cast<DocumentObject>(prop->getContainer());
if(!o)
break;
o = o->getLinkedObject(false);
if(o==obj || !GetApplication().checkLinkDepth(++depth,true))
break;
obj = o;
}
return res;
}
bool LinkBaseExtension::isSubnameHidden(const App::DocumentObject *obj, const char *subname)
{
if(!obj || !obj->getNameInDocument() || !subname || !subname[0])
return false;
PropertyLinkSubHidden *prop;
int depth=0;
while((prop=Base::freecad_dynamic_cast<PropertyLinkSubHidden>(
obj->getPropertyByName("ColoredElements"))))
{
for(auto &v : prop->getShadowSubs()) {
if((boost::starts_with(v.first,subname) || boost::starts_with(v.second,subname))
&& boost::ends_with(v.second, DocumentObject::hiddenMarker()))
return true;
}
auto o = Base::freecad_dynamic_cast<DocumentObject>(prop->getContainer());
if(!o)
break;
o = o->getLinkedObject(false);
if(o==obj || !GetApplication().checkLinkDepth(++depth,true))
break;
obj = o;
}
return false;
}
bool LinkBaseExtension::isLinkMutated() const
{
return getLinkCopyOnChangeValue() != CopyOnChangeDisabled
+5
View File
@@ -304,6 +304,11 @@ public:
int getElementIndex(const char *subname, const char **psubname=nullptr) const;
void elementNameFromIndex(int idx, std::ostream &ss) const;
static std::vector<std::string> getHiddenSubnames(
const App::DocumentObject *obj, const char *prefix=0);
static bool isSubnameHidden(const App::DocumentObject *obj, const char *subname);
DocumentObject *getContainer();
const DocumentObject *getContainer() const;
+45 -8
View File
@@ -524,23 +524,60 @@ TopoDS_Shape Feature::getShape(const App::DocumentObject *obj, const char *subna
return getTopoShape(obj,subname,needSubElement,pmat,powner,resolveLink,transform,true).getShape();
}
#if 0 // remove the function as it's not used
static inline bool checkLink(const App::DocumentObject *obj) {
return obj->getExtensionByType<App::LinkBaseExtension>(obj)
|| obj->getExtensionByType<App::GeoFeatureGroupExtension>(obj);
}
#endif
static bool checkLinkVisibility(std::set<std::string> &hiddens,
bool check, const App::DocumentObject *&lastLink,
const App::DocumentObject *obj, const char *subname)
{
(void)hiddens;
(void)check;
(void)lastLink;
(void)obj;
(void)subname;
//Stub to be filled in subsequent patches;
if(!obj || !obj->getNameInDocument())
return false;
if(checkLink(obj)) {
lastLink = obj;
for(auto &s : App::LinkBaseExtension::getHiddenSubnames(obj))
hiddens.emplace(std::move(s));
}
if(!subname || !subname[0])
return true;
auto element = Data::ComplexGeoData::findElementName(subname);
std::string sub(subname,element-subname);
for(auto pos=sub.find('.');pos!=std::string::npos;pos=sub.find('.',pos+1)) {
char c = sub[pos+1];
sub[pos+1] = 0;
for(auto it=hiddens.begin();it!=hiddens.end();) {
if(!boost::starts_with(*it,CharRange(sub.c_str(),sub.c_str()+pos+1)))
it = hiddens.erase(it);
else {
if(check && it->size()==pos+1)
return false;
++it;
}
}
auto sobj = obj->getSubObject(sub.c_str());
if(!sobj || !sobj->getNameInDocument())
return false;
if(checkLink(sobj)) {
for(auto &s : App::LinkBaseExtension::getHiddenSubnames(sobj))
hiddens.insert(std::string(sub)+s);
lastLink = sobj;
}
sub[pos+1] = c;
}
std::set<std::string> res;
for(auto &s : hiddens) {
if(s.size()>sub.size())
res.insert(s.c_str()+sub.size());
}
hiddens = std::move(res);
return true;
}