App: fix endless-loop when recursively determining placement of an object

This commit is contained in:
wmayer
2022-11-17 15:46:06 +01:00
parent c8074a972e
commit 07711bb8a8
2 changed files with 22 additions and 11 deletions

View File

@@ -103,25 +103,35 @@ DocumentObject* GeoFeatureGroupExtension::getGroupOfObject(const DocumentObject*
return nullptr;
}
Base::Placement GeoFeatureGroupExtension::globalGroupPlacement() {
if(getExtendedObject()->isRecomputing())
Base::Placement GeoFeatureGroupExtension::globalGroupPlacement()
{
if (getExtendedObject()->isRecomputing()) {
throw Base::RuntimeError("Global placement cannot be calculated on recompute");
}
return recursiveGroupPlacement(this);
std::unordered_set<GeoFeatureGroupExtension*> history;
history.insert(this);
return recursiveGroupPlacement(this, history);
}
Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGroupExtension* group) {
Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGroupExtension* group,
std::unordered_set<GeoFeatureGroupExtension*>& history)
{
history.insert(this);
auto inList = group->getExtendedObject()->getInList();
for(auto* link : inList) {
for (auto* link : inList) {
auto parent = link->getExtensionByType<GeoFeatureGroupExtension>(true);
if(parent && parent->hasObject(group->getExtendedObject()))
return recursiveGroupPlacement(parent) * group->placement().getValue();
if (parent && parent->hasObject(group->getExtendedObject())) {
// Cyclic dependencies detected
if (history.count(parent) > 0) {
break;
}
return recursiveGroupPlacement(parent, history) * group->placement().getValue();
}
}
return group->placement().getValue();
}

View File

@@ -25,6 +25,7 @@
#ifndef APP_GeoFeatureGroup_H
#define APP_GeoFeatureGroup_H
#include <unordered_set>
#include "DocumentObject.h"
#include "GroupExtension.h"
#include "PropertyGeo.h"
@@ -120,7 +121,7 @@ public:
static void getInvalidLinkObjects(const App::DocumentObject* obj, std::vector<App::DocumentObject*>& vec);
private:
Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group);
Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group, std::unordered_set<GeoFeatureGroupExtension*>& history);
static std::vector<App::DocumentObject*> getScopedObjectsFromLinks(const App::DocumentObject*, LinkScope scope = LinkScope::Local);
static std::vector<App::DocumentObject*> getScopedObjectsFromLink(App::Property*, LinkScope scope = LinkScope::Local);