Link: change sub-element linking mechanism
Previous multi-sub-element linking (e.g. Face, Edge) is supported through SubElements of type PropertyStringList, which does not support geometry element update tracking. This patch changes it to use PropertyXLink's new multi-subname capability.
This commit is contained in:
104
src/App/Link.cpp
104
src/App/Link.cpp
@@ -188,8 +188,7 @@ short LinkBaseExtension::extensionMustExecute(void) {
|
||||
}
|
||||
|
||||
App::GroupExtension *LinkBaseExtension::linkedPlainGroup() const {
|
||||
auto subs = getSubElementsProperty();
|
||||
if(subs && subs->getSize())
|
||||
if(mySubElements.size() && mySubElements[0].size())
|
||||
return 0;
|
||||
auto linked = getTrueLinkedObject(false);
|
||||
if(!linked)
|
||||
@@ -498,7 +497,7 @@ bool LinkBaseExtension::extensionGetSubObjects(std::vector<std::string> &ret, in
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(mySubElement.empty() && getSubElementsValue().empty()) {
|
||||
if(mySubElements.empty() || mySubElements[0].empty()) {
|
||||
DocumentObject *linked = getTrueLinkedObject(true);
|
||||
if(linked) {
|
||||
if(!_getElementCountValue())
|
||||
@@ -511,6 +510,8 @@ bool LinkBaseExtension::extensionGetSubObjects(std::vector<std::string> &ret, in
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(mySubElements.size()>1) {
|
||||
ret = mySubElements;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -523,13 +524,17 @@ bool LinkBaseExtension::extensionGetSubObject(DocumentObject *&ret, const char *
|
||||
auto obj = getContainer();
|
||||
if(!subname || !subname[0]) {
|
||||
ret = const_cast<DocumentObject*>(obj);
|
||||
if(pyObj && !_getElementCountValue() && _getElementListValue().empty()) {
|
||||
if(pyObj && !_getElementCountValue()
|
||||
&& _getElementListValue().empty() && mySubElements.size()<=1)
|
||||
{
|
||||
Base::Matrix4D matNext;
|
||||
if(mat) matNext = *mat;
|
||||
auto linked = getTrueLinkedObject(false,mat?&matNext:0,depth);
|
||||
if(linked && linked!=obj) {
|
||||
if(mat) *mat = matNext;
|
||||
linked->getSubObject(mySubElement.c_str(),pyObj,mat,false,depth+1);
|
||||
linked->getSubObject(
|
||||
mySubElements.empty()?0:mySubElements.front().c_str(),
|
||||
pyObj,mat,false,depth+1);
|
||||
checkGeoElementMap(obj,linked,pyObj,0);
|
||||
}
|
||||
}
|
||||
@@ -544,8 +549,6 @@ bool LinkBaseExtension::extensionGetSubObject(DocumentObject *&ret, const char *
|
||||
if(elements.size()) {
|
||||
if(idx>=(int)elements.size() || !elements[idx] || !elements[idx]->getNameInDocument())
|
||||
return true;
|
||||
if(!subname || !subname[0])
|
||||
subname = mySubElement.c_str();
|
||||
ret = elements[idx]->getSubObject(subname,pyObj,mat,true,depth+1);
|
||||
// do not resolve the link if this element is the last referenced object
|
||||
if(!subname || Data::ComplexGeoData::isMappedElement(subname) || !strchr(subname,'.'))
|
||||
@@ -576,8 +579,6 @@ bool LinkBaseExtension::extensionGetSubObject(DocumentObject *&ret, const char *
|
||||
|
||||
Base::Matrix4D matNext;
|
||||
if(mat) matNext = *mat;
|
||||
if(!subname || !subname[0])
|
||||
subname = mySubElement.c_str();
|
||||
ret = linked->getSubObject(subname,pyObj,mat?&matNext:0,false,depth+1);
|
||||
std::string postfix;
|
||||
if(ret) {
|
||||
@@ -668,15 +669,36 @@ void LinkBaseExtension::extensionOnChanged(const Property *prop) {
|
||||
}
|
||||
|
||||
void LinkBaseExtension::parseSubName() const {
|
||||
auto xlink = freecad_dynamic_cast<const PropertyXLink>(getLinkedObjectProperty());
|
||||
const char* subname = xlink?xlink->getSubName():0;
|
||||
// If user has ever linked to some sub-element, the Link shall always accept
|
||||
// sub-element linking in the future, which affects how ViewProviderLink
|
||||
// dropObjectEx() behave. So we will push an empty string later even if no
|
||||
// sub-element linking this time.
|
||||
bool hasSubElement = !mySubElements.empty();
|
||||
mySubElements.clear();
|
||||
mySubName.clear();
|
||||
mySubElement.clear();
|
||||
if(!subname || !subname[0])
|
||||
auto xlink = freecad_dynamic_cast<const PropertyXLink>(getLinkedObjectProperty());
|
||||
if(!xlink || xlink->getSubValues().empty()) {
|
||||
if(hasSubElement)
|
||||
mySubElements.emplace_back("");
|
||||
return;
|
||||
}
|
||||
const auto &subs = xlink->getSubValues();
|
||||
auto subname = subs.front().c_str();
|
||||
auto element = Data::ComplexGeoData::findElementName(subname);
|
||||
if(!element || !element[0]) {
|
||||
mySubName = subs[0];
|
||||
if(hasSubElement)
|
||||
mySubElements.emplace_back("");
|
||||
return;
|
||||
}
|
||||
mySubElements.push_back(element);
|
||||
mySubName = std::string(subname,element-subname);
|
||||
mySubElement = element;
|
||||
for(std::size_t i=1;i<subs.size();++i) {
|
||||
auto &sub = subs[i];
|
||||
element = Data::ComplexGeoData::findElementName(sub.c_str());
|
||||
if(element && element[0] && boost::starts_with(sub,mySubName))
|
||||
mySubElements.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkBaseExtension::slotChangedPlainGroup(const App::DocumentObject &obj, const App::Property &prop) {
|
||||
@@ -982,8 +1004,6 @@ void LinkBaseExtension::update(App::DocumentObject *parent, const Property *prop
|
||||
_ChildCache.setValue();
|
||||
parseSubName();
|
||||
syncElementList();
|
||||
}else if(prop == getSubElementsProperty()) {
|
||||
syncElementList();
|
||||
}else if(prop == getLinkTransformProperty()) {
|
||||
auto linkPlacement = getLinkPlacementProperty();
|
||||
auto placement = getPlacementProperty();
|
||||
@@ -1019,14 +1039,9 @@ bool LinkBaseExtension::linkTransform() const {
|
||||
}
|
||||
|
||||
void LinkBaseExtension::syncElementList() {
|
||||
const auto &subElements = getSubElementsValue();
|
||||
auto sub = getSubElementsProperty();
|
||||
auto transform = getLinkTransformProperty();
|
||||
auto link = getLinkedObjectProperty();
|
||||
auto xlink = freecad_dynamic_cast<const PropertyXLink>(link);
|
||||
std::string subname;
|
||||
if(xlink)
|
||||
subname = xlink->getSubName();
|
||||
|
||||
auto owner = getContainer();
|
||||
auto ownerID = owner?owner->getID():0;
|
||||
@@ -1038,9 +1053,6 @@ void LinkBaseExtension::syncElementList() {
|
||||
|
||||
element->myOwner = ownerID;
|
||||
|
||||
element->SubElements.setStatus(Property::Hidden,sub!=0);
|
||||
element->SubElements.setStatus(Property::Immutable,sub!=0);
|
||||
|
||||
element->LinkTransform.setStatus(Property::Hidden,transform!=0);
|
||||
element->LinkTransform.setStatus(Property::Immutable,transform!=0);
|
||||
if(transform && element->LinkTransform.getValue()!=transform->getValue())
|
||||
@@ -1048,13 +1060,16 @@ void LinkBaseExtension::syncElementList() {
|
||||
|
||||
element->LinkedObject.setStatus(Property::Hidden,link!=0);
|
||||
element->LinkedObject.setStatus(Property::Immutable,link!=0);
|
||||
if(link) {
|
||||
if(element->LinkedObject.getValue()!=link->getValue() ||
|
||||
subname != element->LinkedObject.getSubName() ||
|
||||
subElements != element->SubElements.getValue())
|
||||
if(xlink) {
|
||||
if(element->LinkedObject.getValue()!=xlink->getValue() ||
|
||||
element->LinkedObject.getSubValues()!=xlink->getSubValues())
|
||||
{
|
||||
element->setLink(-1,link->getValue(),subname.c_str(),subElements);
|
||||
element->LinkedObject.setValue(xlink->getValue(), xlink->getSubValues());
|
||||
}
|
||||
} else if(element->LinkedObject.getValue()!=link->getValue() ||
|
||||
element->LinkedObject.getSubValues().size())
|
||||
{
|
||||
element->setLink(-1,link->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1167,10 +1182,6 @@ void LinkBaseExtension::setLink(int index, DocumentObject *obj,
|
||||
// Here means we are assigning a Link
|
||||
|
||||
auto xlink = freecad_dynamic_cast<PropertyXLink>(linkProp);
|
||||
auto subElementProp = getSubElementsProperty();
|
||||
if(subElements.size() && !subElementProp)
|
||||
LINK_THROW(Base::RuntimeError,"No SubElements Property configured");
|
||||
|
||||
if(obj) {
|
||||
if(!obj->getNameInDocument())
|
||||
LINK_THROW(Base::ValueError,"Invalid document object");
|
||||
@@ -1180,18 +1191,23 @@ void LinkBaseExtension::setLink(int index, DocumentObject *obj,
|
||||
}
|
||||
}
|
||||
|
||||
if(subname && subname[0] && !xlink)
|
||||
LINK_THROW(Base::RuntimeError,"SubName link requires PropertyXLink");
|
||||
|
||||
if(subElementProp && subElements.size()) {
|
||||
subElementProp->setStatus(Property::User3, true);
|
||||
subElementProp->setValue(subElements);
|
||||
subElementProp->setStatus(Property::User3, false);
|
||||
}
|
||||
if(xlink)
|
||||
xlink->setValue(obj,subname);
|
||||
else
|
||||
if(!xlink) {
|
||||
if(subElements.size() || (subname && subname[0]))
|
||||
LINK_THROW(Base::RuntimeError,"SubName/SubElement link requires PropertyXLink");
|
||||
linkProp->setValue(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> subs;
|
||||
if(subElements.size()) {
|
||||
subs.reserve(subElements.size());
|
||||
for(const auto &s : subElements) {
|
||||
subs.emplace_back(subname?subname:"");
|
||||
subs.back() += s;
|
||||
}
|
||||
} else if(subname && subname[0])
|
||||
subs.emplace_back(subname);
|
||||
xlink->setValue(obj,std::move(subs));
|
||||
}
|
||||
|
||||
void LinkBaseExtension::detachElement(DocumentObject *obj) {
|
||||
|
||||
@@ -87,10 +87,6 @@ public:
|
||||
#define LINK_PARAM_OBJECT(...) \
|
||||
(LinkedObject, App::DocumentObject*, App::PropertyLink, 0, "Linked object", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_SUB_ELEMENT(...) \
|
||||
(SubElements, std::vector<std::string>, App::PropertyStringList, std::vector<std::string>(), \
|
||||
"Non-object Sub-element list of the linked object, e.g. Face1", ##__VA_ARGS__)
|
||||
|
||||
#define LINK_PARAM_TRANSFORM(...) \
|
||||
(LinkTransform, bool, App::PropertyBool, false, \
|
||||
"Set to false to override linked object's placement", ##__VA_ARGS__)
|
||||
@@ -145,7 +141,6 @@ public:
|
||||
LINK_PARAM(PLACEMENT)\
|
||||
LINK_PARAM(LINK_PLACEMENT)\
|
||||
LINK_PARAM(OBJECT)\
|
||||
LINK_PARAM(SUB_ELEMENT)\
|
||||
LINK_PARAM(TRANSFORM)\
|
||||
LINK_PARAM(SCALE)\
|
||||
LINK_PARAM(SCALE_VECTOR)\
|
||||
@@ -239,9 +234,10 @@ public:
|
||||
parseSubName();
|
||||
return mySubName.size()?mySubName.c_str():0;
|
||||
}
|
||||
const char *getSubElement() const {
|
||||
|
||||
const std::vector<std::string> &getSubElements() const {
|
||||
parseSubName();
|
||||
return mySubElement.size()?mySubElement.c_str():0;
|
||||
return mySubElements;
|
||||
}
|
||||
|
||||
bool extensionGetSubObject(DocumentObject *&ret, const char *subname,
|
||||
@@ -300,7 +296,7 @@ protected:
|
||||
protected:
|
||||
std::vector<Property *> props;
|
||||
std::unordered_set<const App::DocumentObject*> myHiddenElements;
|
||||
mutable std::string mySubElement;
|
||||
mutable std::vector<std::string> mySubElements;
|
||||
mutable std::string mySubName;
|
||||
|
||||
std::unordered_map<const App::DocumentObject*,
|
||||
@@ -439,7 +435,6 @@ public:
|
||||
LINK_PARAM_EXT(TRANSFORM)\
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT)\
|
||||
LINK_PARAM_EXT(PLACEMENT)\
|
||||
LINK_PARAM_EXT(SUB_ELEMENT)\
|
||||
LINK_PARAM_EXT(SHOW_ELEMENT)\
|
||||
LINK_PARAM_EXT_TYPE(COUNT,App::PropertyIntegerConstraint)\
|
||||
LINK_PARAM_EXT_ATYPE(COLORED_ELEMENTS,App::Prop_Hidden)
|
||||
@@ -475,7 +470,6 @@ public:
|
||||
LINK_PARAM_EXT(TRANSFORM) \
|
||||
LINK_PARAM_EXT(LINK_PLACEMENT)\
|
||||
LINK_PARAM_EXT(PLACEMENT)\
|
||||
LINK_PARAM_EXT(SUB_ELEMENT)
|
||||
|
||||
// defines the actual properties
|
||||
LINK_PROPS_DEFINE(LINK_PARAMS_ELEMENT)
|
||||
|
||||
@@ -267,7 +267,7 @@ StdCmdLinkMakeRelative::StdCmdLinkMakeRelative()
|
||||
: Command("Std_LinkMakeRelative")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("Link");
|
||||
sMenuText = QT_TR_NOOP("Make relative link");
|
||||
sMenuText = QT_TR_NOOP("Make sub-link");
|
||||
sToolTipText = QT_TR_NOOP("Create a sub-object or sub-element link");
|
||||
sWhatsThis = "Std_LinkMakeRelative";
|
||||
sStatusTip = sToolTipText;
|
||||
@@ -285,25 +285,46 @@ void StdCmdLinkMakeRelative::activated(int) {
|
||||
FC_ERR("no active document");
|
||||
return;
|
||||
}
|
||||
Command::openCommand("Make relative link");
|
||||
Command::openCommand("Make sub-link");
|
||||
try {
|
||||
std::vector<std::string> newNames;
|
||||
std::map<std::pair<App::DocumentObject*,std::string>,
|
||||
std::pair<App::DocumentObject*, std::vector<std::string> > > linkInfo;
|
||||
for(auto &sel : Selection().getCompleteSelection(0)) {
|
||||
std::string name = doc->getUniqueObjectName("Link");
|
||||
FCMD_DOC_CMD(doc,"addObject('App::Link','" << name << "').setLink("
|
||||
<< getObjectCmd(sel.pObject) << ",'" << sel.SubName << "')");
|
||||
auto link = doc->getObject(name.c_str());
|
||||
FCMD_OBJ_CMD(link,"LinkTransform = True");
|
||||
setLinkLabel(sel.pResolvedObject,doc->getName(),name.c_str());
|
||||
|
||||
newNames.push_back(std::move(name));
|
||||
if(!sel.pObject || !sel.pObject->getNameInDocument())
|
||||
continue;
|
||||
auto key = std::make_pair(sel.pObject,
|
||||
Data::ComplexGeoData::noElementName(sel.SubName));
|
||||
auto element = Data::ComplexGeoData::findElementName(sel.SubName);
|
||||
auto &info = linkInfo[key];
|
||||
info.first = sel.pResolvedObject;
|
||||
if(element && element[0])
|
||||
info.second.emplace_back(element);
|
||||
}
|
||||
|
||||
Selection().selStackPush();
|
||||
Selection().clearCompleteSelection();
|
||||
for(auto &name : newNames)
|
||||
Selection().addSelection(doc->getName(),name.c_str());
|
||||
Selection().selStackPush();
|
||||
|
||||
for(auto &v : linkInfo) {
|
||||
auto &key = v.first;
|
||||
auto &info = v.second;
|
||||
|
||||
std::string name = doc->getUniqueObjectName("Link");
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << '[';
|
||||
for(auto &s : info.second)
|
||||
ss << "'" << s << "',";
|
||||
ss << ']';
|
||||
FCMD_DOC_CMD(doc,"addObject('App::Link','" << name << "').setLink("
|
||||
<< getObjectCmd(key.first) << ",'" << key.second
|
||||
<< "'," << ss.str() << ")");
|
||||
auto link = doc->getObject(name.c_str());
|
||||
FCMD_OBJ_CMD(link,"LinkTransform = True");
|
||||
setLinkLabel(info.first,doc->getName(),name.c_str());
|
||||
|
||||
Selection().addSelection(doc->getName(),name.c_str());
|
||||
}
|
||||
Selection().selStackPush();
|
||||
Command::commitCommand();
|
||||
} catch (const Base::Exception& e) {
|
||||
Command::abortCommand();
|
||||
|
||||
@@ -1820,22 +1820,16 @@ void ViewProviderLink::updateDataPrivate(App::LinkBaseExtension *ext, const App:
|
||||
pcTransform->scaleFactor.setValue(v.x,v.y,v.z);
|
||||
linkView->renderDoubleSide(v.x*v.y*v.z < 0);
|
||||
}
|
||||
}else if(prop == ext->getLinkedObjectProperty() ||
|
||||
prop == ext->getSubElementsProperty())
|
||||
{
|
||||
}else if(prop == ext->getLinkedObjectProperty()) {
|
||||
|
||||
if(!prop->testStatus(App::Property::User3)) {
|
||||
std::vector<std::string> subs;
|
||||
const char *subname = ext->getSubName();
|
||||
std::string sub;
|
||||
if(subname)
|
||||
sub = subname;
|
||||
const char *subElement = ext->getSubElement();
|
||||
if(subElement) {
|
||||
hasSubElement = true;
|
||||
subs.push_back(sub+subElement);
|
||||
}else
|
||||
hasSubElement = false;
|
||||
for(const auto &s : ext->getSubElementsValue()) {
|
||||
hasSubElement = false;
|
||||
for(const auto &s : ext->getSubElements()) {
|
||||
if(s.empty()) continue;
|
||||
hasSubElement = true;
|
||||
subs.push_back(sub+s);
|
||||
@@ -2163,7 +2157,8 @@ bool ViewProviderLink::canDropObjects() const {
|
||||
}
|
||||
|
||||
bool ViewProviderLink::canDropObjectEx(App::DocumentObject *obj,
|
||||
App::DocumentObject *owner, const char *subname, const std::vector<std::string> &elements) const
|
||||
App::DocumentObject *owner, const char *subname,
|
||||
const std::vector<std::string> &subElements) const
|
||||
{
|
||||
if(pcObject == obj || pcObject == owner)
|
||||
return false;
|
||||
@@ -2180,18 +2175,19 @@ bool ViewProviderLink::canDropObjectEx(App::DocumentObject *obj,
|
||||
if(linkedVdp->getObject()==obj || linkedVdp->getObject()==owner)
|
||||
return false;
|
||||
}
|
||||
return linked->canDropObjectEx(obj,owner,subname,elements);
|
||||
return linked->canDropObjectEx(obj,owner,subname,subElements);
|
||||
}
|
||||
}
|
||||
if(obj->getDocument() != getObject()->getDocument() &&
|
||||
!freecad_dynamic_cast<App::PropertyXLink>(ext->getLinkedObjectValue()))
|
||||
!freecad_dynamic_cast<App::PropertyXLink>(ext->getLinkedObjectProperty()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ViewProviderLink::dropObjectEx(App::DocumentObject* obj,
|
||||
App::DocumentObject *owner, const char *subname, const std::vector<std::string> &elements)
|
||||
App::DocumentObject *owner, const char *subname,
|
||||
const std::vector<std::string> &subElements)
|
||||
{
|
||||
auto ext = getLinkExtension();
|
||||
if(isGroup(ext)) {
|
||||
@@ -2206,10 +2202,15 @@ std::string ViewProviderLink::dropObjectEx(App::DocumentObject* obj,
|
||||
if(!hasSubName) {
|
||||
auto linked = getLinkedView(false,ext);
|
||||
if(linked)
|
||||
return linked->dropObjectEx(obj,owner,subname,elements);
|
||||
return linked->dropObjectEx(obj,owner,subname,subElements);
|
||||
}
|
||||
if(owner)
|
||||
ext->setLink(-1,owner,subname);
|
||||
if(owner) {
|
||||
if(ext->getSubElements().size())
|
||||
ext->setLink(-1,owner,subname,subElements);
|
||||
else
|
||||
ext->setLink(-1,owner,subname);
|
||||
} else if(ext->getSubElements().size())
|
||||
ext->setLink(-1,obj,0,subElements);
|
||||
else
|
||||
ext->setLink(-1,obj,0);
|
||||
return std::string();
|
||||
|
||||
@@ -222,9 +222,9 @@ public:
|
||||
bool canDropObjects() const override;
|
||||
bool canDragAndDropObject(App::DocumentObject*) const override;
|
||||
bool canDropObjectEx(App::DocumentObject *obj, App::DocumentObject *owner,
|
||||
const char *subname, const std::vector<std::string> &elements) const override;
|
||||
const char *subname, const std::vector<std::string> &subElements) const override;
|
||||
std::string dropObjectEx(App::DocumentObject*, App::DocumentObject*,
|
||||
const char *subname, const std::vector<std::string> &elements) override;
|
||||
const char *subname, const std::vector<std::string> &subElements) override;
|
||||
|
||||
bool onDelete(const std::vector<std::string> &) override;
|
||||
bool canDelete(App::DocumentObject* obj) const override;
|
||||
|
||||
@@ -369,7 +369,10 @@ static TopoShape _getTopoShape(const App::DocumentObject *obj, const char *subna
|
||||
}
|
||||
|
||||
auto link = owner->getExtensionByType<App::LinkBaseExtension>(true);
|
||||
if(owner!=linked && (!link || !link->_ChildCache.getSize())) {
|
||||
if(owner!=linked
|
||||
&& (!link || (!link->_ChildCache.getSize()
|
||||
&& link->getSubElements().size()<=1)))
|
||||
{
|
||||
// if there is a linked object, and there is no child cache (which is used
|
||||
// for special handling of plain group), obtain shape from the linked object
|
||||
shape = Feature::getTopoShape(linked,0,false,0,0,false,false);
|
||||
@@ -405,25 +408,28 @@ static TopoShape _getTopoShape(const App::DocumentObject *obj, const char *subna
|
||||
for(auto &sub : owner->getSubObjects()) {
|
||||
if(sub.empty()) continue;
|
||||
int visible;
|
||||
if(sub[sub.size()-1] != '.')
|
||||
sub += '.';
|
||||
std::string childName;
|
||||
App::DocumentObject *parent=0;
|
||||
Base::Matrix4D mat;
|
||||
auto subObj = owner->resolve(sub.c_str(), &parent, &childName,0,0,&mat,false);
|
||||
if(!parent || !subObj)
|
||||
continue;
|
||||
if(linkStack.size()
|
||||
&& parent->getExtensionByType<App::GroupExtension>(true,false))
|
||||
{
|
||||
visible = linkStack.back()->isElementVisible(childName.c_str());
|
||||
}else
|
||||
visible = parent->isElementVisible(childName.c_str());
|
||||
App::DocumentObject *subObj=0;
|
||||
if(sub.find('.')==std::string::npos)
|
||||
visible = 1;
|
||||
else {
|
||||
subObj = owner->resolve(sub.c_str(), &parent, &childName,0,0,&mat,false);
|
||||
if(!parent || !subObj)
|
||||
continue;
|
||||
if(linkStack.size()
|
||||
&& parent->getExtensionByType<App::GroupExtension>(true,false))
|
||||
{
|
||||
visible = linkStack.back()->isElementVisible(childName.c_str());
|
||||
}else
|
||||
visible = parent->isElementVisible(childName.c_str());
|
||||
}
|
||||
if(visible==0)
|
||||
continue;
|
||||
TopoShape shape;
|
||||
if(baseShape.isNull()) {
|
||||
shape = _getTopoShape(owner,sub.c_str(),false,0,&subObj,false,false,linkStack);
|
||||
if(!subObj || baseShape.isNull()) {
|
||||
shape = _getTopoShape(owner,sub.c_str(),true,0,&subObj,false,false,linkStack);
|
||||
if(shape.isNull())
|
||||
continue;
|
||||
if(visible<0 && subObj && !subObj->Visibility.getValue())
|
||||
|
||||
Reference in New Issue
Block a user