Make InList hadling and topological sort more robust. fixes #0002871

This commit is contained in:
Stefan Tröger
2017-06-04 14:44:48 +02:00
committed by wmayer
parent 03b63d3a40
commit ab85c6e784
5 changed files with 83 additions and 55 deletions

View File

@@ -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

View File

@@ -2199,8 +2199,8 @@ std::vector<App::DocumentObject*> 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<App::DocumentObject*> 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;
}

View File

@@ -151,7 +151,7 @@ Both parameters are optional.</UserDocu>
</Documentation>
<Parameter Name="Objects" Type="List" />
</Attribute>
<Attribute Name="ToplogicalSortedObjects" ReadOnly="true">
<Attribute Name="TopologicalSortedObjects" ReadOnly="true">
<Documentation>
<UserDocu>The list of object of this document in topological sorted order</UserDocu>
</Documentation>

View File

@@ -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<DocumentObject*> objs = getDocumentPtr()->topologicalSort();
Py::List res;

View File

@@ -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<DocumentObject*>(getContainer()));
if(lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(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<DocumentObject*>(getContainer()));
if(lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(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<DocumentObject*>(getContainer()));
if(lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(getContainer()));
if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
for(auto *obj : _lValueList)
obj->_removeBackLink(static_cast<DocumentObject*>(getContainer()));
if(lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(getContainer()));
}
#endif
if (lValue){
@@ -232,10 +236,12 @@ void PropertyLinkList::setValues(const std::vector<DocumentObject*>& lValue)
aboutToSetValue();
#ifndef USE_OLD_DAG
//maintain the back link in the DocumentObject class
for(auto *obj : _lValueList)
obj->_removeBackLink(static_cast<DocumentObject*>(getContainer()));
for(auto *obj : lValue)
obj->_addBackLink(static_cast<DocumentObject*>(getContainer()));
if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
for(auto *obj : _lValueList)
obj->_removeBackLink(static_cast<DocumentObject*>(getContainer()));
for(auto *obj : lValue)
obj->_addBackLink(static_cast<DocumentObject*>(getContainer()));
}
#endif
_lValueList = lValue;
hasSetValue();
@@ -391,10 +397,12 @@ void PropertyLinkSub::setValue(App::DocumentObject * lValue, const std::vector<s
{
aboutToSetValue();
#ifndef USE_OLD_DAG
if (_pcLinkSub)
_pcLinkSub->_removeBackLink(static_cast<App::DocumentObject*>(getContainer()));
if (lValue)
lValue->_addBackLink(static_cast<App::DocumentObject*>(getContainer()));
if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
if (_pcLinkSub)
_pcLinkSub->_removeBackLink(static_cast<App::DocumentObject*>(getContainer()));
if (lValue)
lValue->_addBackLink(static_cast<App::DocumentObject*>(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<DocumentObject*>(getContainer()));
if (lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(getContainer()));
if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
for(auto *obj : _lValueList)
obj->_removeBackLink(static_cast<DocumentObject*>(getContainer()));
if (lValue)
lValue->_addBackLink(static_cast<DocumentObject*>(getContainer()));
}
#endif
if (lValue) {
@@ -615,15 +625,19 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& 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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(getContainer()));
}
#endif
aboutToSetValue();
@@ -641,15 +655,19 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& 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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(getContainer()));
}
#endif
aboutToSetValue();
@@ -660,16 +678,20 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,c
void PropertyLinkSubList::setValue(DocumentObject* lValue, const std::vector<string> &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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(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<DocumentObject*>(getContainer()));
}
#endif
aboutToSetValue();