diff --git a/src/App/DocumentPy.xml b/src/App/DocumentPy.xml
index f5afe30b74..da2ce190d7 100644
--- a/src/App/DocumentPy.xml
+++ b/src/App/DocumentPy.xml
@@ -102,7 +102,7 @@
- Recompute the document
+ Recompute the document and returns the amount of recomputed features
diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp
index a57ce47bde..88296ce9d4 100644
--- a/src/App/DocumentPyImp.cpp
+++ b/src/App/DocumentPyImp.cpp
@@ -384,8 +384,8 @@ PyObject* DocumentPy::recompute(PyObject * args)
{
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
return NULL; // NULL triggers exception
- getDocumentPtr()->recompute();
- Py_Return;
+ int objectCount = getDocumentPtr()->recompute();
+ return Py::new_reference_to(Py::Int(objectCount));
}
PyObject* DocumentPy::getObject(PyObject *args)
diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py
index 5fdc3ae951..ae15e84ec7 100644
--- a/src/Mod/Test/Document.py
+++ b/src/Mod/Test/Document.py
@@ -263,7 +263,85 @@ class DocumentBasicCases(unittest.TestCase):
self.Doc.removeObject(obj.Name)
del obj
+
+ def testRecompute(self):
+
+ # sequence to test recompute behaviour
+ # L1---\ L7
+ # / \ \ |
+ # L2 L3 \ L8
+ # / \ / \ /
+ # L4 L5 L6
+
+ L1 = self.Doc.addObject("App::FeatureTest","Label_1")
+ L2 = self.Doc.addObject("App::FeatureTest","Label_2")
+ L3 = self.Doc.addObject("App::FeatureTest","Label_3")
+ L4 = self.Doc.addObject("App::FeatureTest","Label_4")
+ L5 = self.Doc.addObject("App::FeatureTest","Label_5")
+ L6 = self.Doc.addObject("App::FeatureTest","Label_6")
+ L7 = self.Doc.addObject("App::FeatureTest","Label_7")
+ L8 = self.Doc.addObject("App::FeatureTest","Label_8")
+ L1.LinkList = [L2,L3,L6]
+ L2.Link = L4
+ L2.LinkList = [L5]
+ L3.LinkList = [L5,L6]
+ L7.Link = L8 #make second root
+
+ self.failUnless(L7 in self.Doc.RootObjects)
+ self.failUnless(L1 in self.Doc.RootObjects)
+
+ self.failUnless(len(self.Doc.Objects) == len(self.Doc.ToplogicalSortedObjects))
+
+ seqDic = {}
+ i = 0
+ for obj in self.Doc.ToplogicalSortedObjects:
+ seqDic[obj] = i
+ print obj
+ i += 1
+
+ self.failUnless(seqDic[L2] > seqDic[L1])
+ self.failUnless(seqDic[L3] > seqDic[L1])
+ self.failUnless(seqDic[L5] > seqDic[L2])
+ self.failUnless(seqDic[L5] > seqDic[L3])
+ self.failUnless(seqDic[L5] > seqDic[L1])
+
+
+ self.failUnless((0, 0, 0, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ self.failUnless(self.Doc.recompute()==4)
+ self.failUnless((1, 1, 1, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L5.touch()
+ self.failUnless((1, 1, 1, 0, 0, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ self.failUnless(self.Doc.recompute()==4)
+ self.failUnless((2, 2, 2, 0, 1, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L4.touch()
+ self.failUnless(self.Doc.recompute()==3)
+ self.failUnless((3, 3, 2, 1, 1, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L5.touch()
+ self.failUnless(self.Doc.recompute()==4)
+ self.failUnless((4, 4, 3, 1, 2, 0)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L6.touch()
+ self.failUnless(self.Doc.recompute()==3)
+ self.failUnless((5, 4, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L2.touch()
+ self.failUnless(self.Doc.recompute()==2)
+ self.failUnless((6, 5, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L1.touch()
+ self.failUnless(self.Doc.recompute()==1)
+ self.failUnless((7, 5, 4, 1, 2, 1)==(L1.ExecCount,L2.ExecCount,L3.ExecCount,L4.ExecCount,L5.ExecCount,L6.ExecCount))
+ L6.Link = L1 # create a circular dependency
+ self.failUnless(self.Doc.recompute()==-1)
+ L6.Link = None # resolve the circular dependency
+ self.failUnless(self.Doc.recompute()==3)
+ self.Doc.removeObject(L1.Name)
+ self.Doc.removeObject(L2.Name)
+ self.Doc.removeObject(L3.Name)
+ self.Doc.removeObject(L4.Name)
+ self.Doc.removeObject(L5.Name)
+ self.Doc.removeObject(L6.Name)
+ self.Doc.removeObject(L7.Name)
+ self.Doc.removeObject(L8.Name)
+
def tearDown(self):
#closing doc
FreeCAD.closeDocument("CreateTest")