diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 9ad7024b87..00b7b41b1c 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -15,7 +15,7 @@ ENDIF(DOCDIR) add_definitions(-DBOOST_${Boost_VERSION}) #if you want to use the old DAG structure uncomment this line -add_definitions(-DUSE_OLD_DAG) +#add_definitions(-DUSE_OLD_DAG) #write relevant cmake variables to a file for later access with python. Exportet are all variables #starting with BUILD. As the variable only exists if the user set it to ON a dict is useless, we diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 367f4f46a9..1ca81eb978 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -2199,8 +2199,8 @@ std::vector Document::topologicalSort() const ret.reserve(d->objectArray.size()); map < App::DocumentObject*,int > countMap; - for (auto objectIt : d->objectArray) - countMap[objectIt] = objectIt->getInList().size(); + for (auto objectIt : d->objectMap) + countMap[objectIt.second] = objectIt.second->getInList().size(); auto rootObjeIt = find_if(countMap.begin(), countMap.end(), [](pair < App::DocumentObject*, int > count)->bool { return count.second == 0; @@ -2213,7 +2213,13 @@ std::vector Document::topologicalSort() const while (rootObjeIt != countMap.end()){ rootObjeIt->second = rootObjeIt->second - 1; - for (auto outListIt : rootObjeIt->first->getOutList()){ + + //we need outlist with unique entries, as inlist also has unique entries + auto out = rootObjeIt->first->getOutList(); + std::sort(out.begin(), out.end()); + out.erase(std::unique(out.begin(), out.end()), out.end()); + + for (auto outListIt : out) { auto outListMapIt = countMap.find(outListIt); outListMapIt->second = outListMapIt->second - 1; } diff --git a/src/App/DocumentPy.xml b/src/App/DocumentPy.xml index 3752239688..4d4dfb0d0a 100644 --- a/src/App/DocumentPy.xml +++ b/src/App/DocumentPy.xml @@ -151,7 +151,7 @@ Both parameters are optional. - + The list of object of this document in topological sorted order diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index e3d2303df4..506c31cfc0 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -516,7 +516,7 @@ Py::List DocumentPy::getObjects(void) const return res; } -Py::List DocumentPy::getToplogicalSortedObjects(void) const +Py::List DocumentPy::getTopologicalSortedObjects(void) const { std::vector objs = getDocumentPtr()->topologicalSort(); Py::List res; diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index 679315f013..728ad59344 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -75,11 +75,13 @@ void PropertyLink::setValue(App::DocumentObject * lValue) { aboutToSetValue(); #ifndef USE_OLD_DAG - // maintain the back link in the DocumentObject class - if(_pcLink) - _pcLink->_removeBackLink(static_cast(getContainer())); - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); + // maintain the back link in the DocumentObject class if it is from a document object + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + if(_pcLink) + _pcLink->_removeBackLink(static_cast(getContainer())); + if(lValue) + lValue->_addBackLink(static_cast(getContainer())); + } #endif _pcLink=lValue; hasSetValue(); @@ -208,10 +210,12 @@ void PropertyLinkList::setValue(DocumentObject* lValue) { #ifndef USE_OLD_DAG //maintain the back link in the DocumentObject class - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + if(lValue) + lValue->_addBackLink(static_cast(getContainer())); + } #endif if (lValue){ @@ -232,10 +236,12 @@ void PropertyLinkList::setValues(const std::vector& lValue) aboutToSetValue(); #ifndef USE_OLD_DAG //maintain the back link in the DocumentObject class - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + for(auto *obj : lValue) + obj->_addBackLink(static_cast(getContainer())); + } #endif _lValueList = lValue; hasSetValue(); @@ -391,10 +397,12 @@ void PropertyLinkSub::setValue(App::DocumentObject * lValue, const std::vector_removeBackLink(static_cast(getContainer())); - if (lValue) - lValue->_addBackLink(static_cast(getContainer())); + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + if (_pcLinkSub) + _pcLinkSub->_removeBackLink(static_cast(getContainer())); + if (lValue) + lValue->_addBackLink(static_cast(getContainer())); + } #endif _pcLinkSub=lValue; _cSubList = SubList; @@ -587,10 +595,12 @@ void PropertyLinkSubList::setValue(DocumentObject* lValue,const char* SubName) { #ifndef USE_OLD_DAG //maintain backlinks - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - if (lValue) - lValue->_addBackLink(static_cast(getContainer())); + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + if (lValue) + lValue->_addBackLink(static_cast(getContainer())); + } #endif if (lValue) { @@ -615,15 +625,19 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c throw Base::ValueError("PropertyLinkSubList::setValues: size of subelements list != size of objects list"); #ifndef USE_OLD_DAG - //maintain backlinks. _lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + //maintain backlinks. + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + for(auto *obj : lValue) + obj->_addBackLink(static_cast(getContainer())); + } #endif aboutToSetValue(); @@ -641,15 +655,19 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c throw Base::ValueError("PropertyLinkSubList::setValues: size of subelements list != size of objects list"); #ifndef USE_OLD_DAG - //maintain backlinks. _lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + //maintain backlinks. + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + for(auto *obj : lValue) + obj->_addBackLink(static_cast(getContainer())); + } #endif aboutToSetValue(); @@ -660,16 +678,20 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c void PropertyLinkSubList::setValue(DocumentObject* lValue, const std::vector &SubList) { -#ifndef USE_OLD_DAG - //maintain backlinks. _lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); +#ifndef USE_OLD_DAG + //maintain backlinks. + if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(static_cast(getContainer())); + + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + if(lValue) + lValue->_addBackLink(static_cast(getContainer())); + } #endif aboutToSetValue();