From 2b7e0dc3272d3a0e450037401b935c038ab63315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Mon, 5 Jun 2017 08:41:55 +0200 Subject: [PATCH] Prevent cross GeoFeatureGroup links on recompute --- src/App/Document.cpp | 1 - src/App/DocumentObject.cpp | 5 +++++ src/App/GeoFeatureGroupExtension.cpp | 14 ++++++++++++++ src/App/GeoFeatureGroupExtension.h | 6 ++++-- src/Mod/Test/Document.py | 18 +++++++++--------- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 1ca81eb978..ce9bfc0134 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -2176,7 +2176,6 @@ int Document::recompute() inObjIt->touch(); } } - } #ifdef FC_DEBUG // check if all objects are recalculated which were thouched diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index ce3510b340..2ee75cdad7 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -34,6 +34,7 @@ #include "PropertyLinks.h" #include "PropertyExpressionEngine.h" #include "DocumentObjectExtension.h" +#include "GeoFeatureGroupExtension.h" #include #include #include @@ -73,6 +74,10 @@ DocumentObject::~DocumentObject(void) App::DocumentObjectExecReturn *DocumentObject::recompute(void) { + //check if the links are valid before making the recompute + if(!GeoFeatureGroupExtension::areLinksValid(this)) + return new App::DocumentObjectExecReturn("Links between different GeoFeatureGroups are not valid", this); + // set/unset the execution bit ObjectStatusLocker exe(App::Recompute, this); return this->execute(); diff --git a/src/App/GeoFeatureGroupExtension.cpp b/src/App/GeoFeatureGroupExtension.cpp index fd53d47f40..42d2dead2c 100644 --- a/src/App/GeoFeatureGroupExtension.cpp +++ b/src/App/GeoFeatureGroupExtension.cpp @@ -305,6 +305,20 @@ void GeoFeatureGroupExtension::getCSRelevantLinks(DocumentObject* obj, std::vect vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } +bool GeoFeatureGroupExtension::areLinksValid(DocumentObject* obj) { + + //we get all linked objects. We can't use outList() as this includes the links from expressions + auto result = getObjectsFromLinks(obj); + + //no cross CS links. + auto group = obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()) ? obj : getGroupOfObject(obj); + for(auto link : result) { + if(getGroupOfObject(link) != group) + return false; + } + return true; +} + // Python feature --------------------------------------------------------- namespace App { diff --git a/src/App/GeoFeatureGroupExtension.h b/src/App/GeoFeatureGroupExtension.h index 0a6e442b87..47bc42200a 100644 --- a/src/App/GeoFeatureGroupExtension.h +++ b/src/App/GeoFeatureGroupExtension.h @@ -44,7 +44,7 @@ namespace App * also be added to the GeoFeatureGroup * - Objects can be only in a single GeoFeatureGroup. It is not allowed to have a document object in * multiple GeoFeatureGroups - * - PropertyLinks between different GeoFeatureGroups are forbidden. There are special link proeprties + * - PropertyLinks between different GeoFeatureGroups are forbidden. There are special link properties * that allow such cross-CS links. * - Expressions can cross GeoFeatureGroup borders */ @@ -109,7 +109,9 @@ public: /// obj and from obj excluding expressions and stopping the recursion at other geofeaturegroups. /// The result is the combination of CSOutList and CSInList. static void getCSRelevantLinks(App::DocumentObject* obj, std::vector& vec); - + /// Checks if the links of the given object comply with all GeoFeatureGroup requrirements, that means + /// if normal links are only withing the parent GeoFeatureGroup. + static bool areLinksValid(App::DocumentObject* obj); private: Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group); static std::vector getObjectsFromLinks(App::DocumentObject*); diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index afea2aa3c1..a09558d65d 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -297,11 +297,11 @@ class DocumentBasicCases(unittest.TestCase): self.failUnless(L7 in self.Doc.RootObjects) self.failUnless(L1 in self.Doc.RootObjects) - self.failUnless(len(self.Doc.Objects) == len(self.Doc.ToplogicalSortedObjects)) + self.failUnless(len(self.Doc.Objects) == len(self.Doc.TopologicalSortedObjects)) seqDic = {} i = 0 - for obj in self.Doc.ToplogicalSortedObjects: + for obj in self.Doc.TopologicalSortedObjects: seqDic[obj] = i print(obj) i += 1 @@ -878,13 +878,13 @@ class UndoRedoCases(unittest.TestCase): grp = prt1.Group grp.append(grp2) - #to test: check if cross CS link works - #try: - # prt1.Group=grp - #except: - # pass - #else: - # self.fail("No exception at cross geofeaturegroup links") + try: + prt1.Group=grp + self.Doc.recompute() + except: + pass + else: + self.fail("No exception at cross geofeaturegroup links") prt2.addObject(grp1) grp = grp1.Group