App/Part: fix App::Link visibility detection in PartFeature::getTopoShape()
This commit is contained in:
+61
-4
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user