GeoFeatureGroup: Make link collection non-DAG save
This commit is contained in:
@@ -130,7 +130,8 @@ std::vector<DocumentObject*> GeoFeatureGroupExtension::addObjects(std::vector<Ap
|
||||
continue;
|
||||
|
||||
//cross CoordinateSystem links are not allowed, so we need to move the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
std::vector<App::DocumentObject*> links;
|
||||
getCSRelevantLinks(object, links);
|
||||
links.push_back(object);
|
||||
|
||||
for( auto obj : links) {
|
||||
@@ -157,7 +158,8 @@ std::vector<DocumentObject*> GeoFeatureGroupExtension::removeObjects(std::vector
|
||||
|
||||
for(auto object : objects) {
|
||||
//cross CoordinateSystem links are not allowed, so we need to remove the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
std::vector< DocumentObject* > links;
|
||||
getCSRelevantLinks(object, links);
|
||||
links.push_back(object);
|
||||
|
||||
//remove all links out of group
|
||||
@@ -206,14 +208,14 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getObjectsFromLinks(Doc
|
||||
}
|
||||
|
||||
|
||||
std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSOutList(App::DocumentObject* obj) {
|
||||
void GeoFeatureGroupExtension::getCSOutList(App::DocumentObject* obj, std::vector< DocumentObject* >& vec) {
|
||||
|
||||
if(!obj)
|
||||
return std::vector< App::DocumentObject* >();
|
||||
return;
|
||||
|
||||
//if the object is a geofeaturegroup than all dependencies belong to that CS, we don't want them
|
||||
if(obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()))
|
||||
return std::vector< App::DocumentObject* >();
|
||||
return;
|
||||
|
||||
//we get all linked objects. We can't use outList() as this includes the links from expressions
|
||||
auto result = getObjectsFromLinks(obj);
|
||||
@@ -224,37 +226,43 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSOutList(App::Docum
|
||||
obj->isDerivedFrom(App::Origin::getClassTypeId()));
|
||||
}), result.end());
|
||||
|
||||
//collect all dependencies of those objects
|
||||
std::vector< App::DocumentObject* > links;
|
||||
//collect all dependencies of those objects and store them in the result vector
|
||||
for(App::DocumentObject *obj : result) {
|
||||
auto vec = getCSOutList(obj);
|
||||
links.insert(links.end(), vec.begin(), vec.end());
|
||||
|
||||
//prevent infinite recursion
|
||||
if(std::find(vec.begin(), vec.end(), obj) != vec.end())
|
||||
throw Base::Exception("Graph is not DAG");
|
||||
|
||||
vec.push_back(obj);
|
||||
std::vector< DocumentObject* > links;
|
||||
getCSOutList(obj, links);
|
||||
vec.insert(vec.end(), links.begin(), links.end());
|
||||
}
|
||||
|
||||
if (!links.empty()) {
|
||||
result.insert(result.end(), links.begin(), links.end());
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
}
|
||||
|
||||
return result;
|
||||
//post process the vector
|
||||
std::sort(vec.begin(), vec.end());
|
||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSInList(DocumentObject* obj) {
|
||||
void GeoFeatureGroupExtension::getCSInList(DocumentObject* obj, std::vector< DocumentObject* >& vec) {
|
||||
|
||||
if(!obj)
|
||||
return std::vector< App::DocumentObject* >();
|
||||
return;
|
||||
|
||||
//we get all objects that link to it
|
||||
std::vector< App::DocumentObject* > result;
|
||||
|
||||
//search the inlist for objects that have non-expression links to us
|
||||
for(App::DocumentObject* parent : obj->getInList()) {
|
||||
|
||||
|
||||
//not interested in other groups (and here we mean all groups, normal ones and geofeaturegroup)
|
||||
if(parent->hasExtension(App::GroupExtension::getExtensionClassTypeId()))
|
||||
continue;
|
||||
|
||||
//prevent infinite recursion
|
||||
if(std::find(vec.begin(), vec.end(), parent) != vec.end())
|
||||
throw Base::Exception("Graph is not DAG");
|
||||
|
||||
//check if the link is real or if it is a expression one (could also be both, so it is not
|
||||
//enough to check the expressions)
|
||||
auto res = getObjectsFromLinks(parent);
|
||||
@@ -262,46 +270,39 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSInList(DocumentObj
|
||||
result.push_back(parent);
|
||||
}
|
||||
|
||||
//clear all douplicates
|
||||
//clear all duplicates
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
|
||||
//collect all links to those objects
|
||||
std::vector< App::DocumentObject* > links;
|
||||
for(App::DocumentObject *obj : result) {
|
||||
auto vec = getCSInList(obj);
|
||||
links.insert(links.end(), vec.begin(), vec.end());
|
||||
vec.push_back(obj);
|
||||
getCSInList(obj, vec);
|
||||
}
|
||||
|
||||
if (!links.empty()) {
|
||||
result.insert(result.end(), links.begin(), links.end());
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
}
|
||||
std::sort(vec.begin(), vec.end());
|
||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > GeoFeatureGroupExtension::getCSRelevantLinks(DocumentObject* obj) {
|
||||
void GeoFeatureGroupExtension::getCSRelevantLinks(DocumentObject* obj, std::vector< DocumentObject* >& vec ) {
|
||||
|
||||
//we need to get the outlist of all inlist objects and ourself. This is needed to handle things
|
||||
//get all out links
|
||||
getCSOutList(obj, vec);
|
||||
|
||||
//we need to get the outlist of all inlist objects. This is needed to handle things
|
||||
//like Booleans: the boolean is our parent, than there is a second object under it which relates
|
||||
//to obj and needs to be handled.
|
||||
auto in = getCSInList(obj);
|
||||
in.push_back(obj); //there may be nothing in inlist
|
||||
std::vector<App::DocumentObject*> result;
|
||||
for(auto o : in) {
|
||||
|
||||
auto out = getCSOutList(o);
|
||||
result.insert(result.end(), out.begin(), out.end());
|
||||
std::vector< DocumentObject* > in;
|
||||
getCSInList(obj, in);
|
||||
for(auto o : in) {
|
||||
vec.push_back(o);
|
||||
getCSOutList(o, vec);
|
||||
}
|
||||
|
||||
//there will be many douplicates and also the passed obj in
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
result.erase(std::remove(result.begin(), result.end(), obj), result.end());
|
||||
|
||||
return result;
|
||||
//post process
|
||||
std::sort(vec.begin(), vec.end());
|
||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||
}
|
||||
|
||||
// Python feature ---------------------------------------------------------
|
||||
|
||||
@@ -73,8 +73,6 @@ public:
|
||||
* In case this object is not part of any geoFeatureGroup 0 is returned.
|
||||
* Unlike DocumentObjectGroup::getGroupOfObject serches only for GeoFeatureGroups
|
||||
* @param obj the object to search for
|
||||
* @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject()
|
||||
* default is true
|
||||
*/
|
||||
static DocumentObject* getGroupOfObject(const DocumentObject* obj);
|
||||
|
||||
@@ -99,18 +97,18 @@ public:
|
||||
virtual std::vector< DocumentObject* > addObjects(std::vector< DocumentObject* > obj) override;
|
||||
virtual std::vector< DocumentObject* > removeObjects(std::vector< DocumentObject* > obj) override;
|
||||
|
||||
/// returns GeoFeatureGroup relevant objects that are linked from the given one. That meas all linked objects
|
||||
/// Collects GeoFeatureGroup relevant objects that are linked from the given one. That meas all linked objects
|
||||
/// including their linkes (recursively) except GeoFeatureGroups, where the recursion stops. Expressions
|
||||
/// links are ignored.
|
||||
static std::vector<App::DocumentObject*> getCSOutList(App::DocumentObject* obj);
|
||||
///returns GeoFeatureGroup relevant objects that link to the given one. That meas all objects
|
||||
/// links are ignored. A exception is thrown when there are dependency loops.
|
||||
static void getCSOutList(App::DocumentObject* obj, std::vector<App::DocumentObject*>& vec);
|
||||
/// Collects GeoFeatureGroup relevant objects that link to the given one. That meas all objects
|
||||
/// including their parents (recursively) except GeoFeatureGroups, where the recursion stops. Expression
|
||||
/// links are ignored
|
||||
static std::vector<App::DocumentObject*> getCSInList(App::DocumentObject* obj);
|
||||
/// Returns all links that are relevant for the coordinate system, meaning all recursive links to
|
||||
/// links are ignored. A exception is thrown when there are dependency loops.
|
||||
static void getCSInList(App::DocumentObject* obj, std::vector<App::DocumentObject*>& vec);
|
||||
/// Collects all links that are relevant for the coordinate system, meaning all recursive links to
|
||||
/// obj and from obj excluding expressions and stopping the recursion at other geofeaturegroups.
|
||||
/// The result is the combination of CSOutList and CSInList.
|
||||
static std::vector<App::DocumentObject*> getCSRelevantLinks(App::DocumentObject* obj);
|
||||
static void getCSRelevantLinks(App::DocumentObject* obj, std::vector<App::DocumentObject*>& vec);
|
||||
|
||||
private:
|
||||
Base::Placement recursiveGroupPlacement(GeoFeatureGroupExtension* group);
|
||||
|
||||
@@ -104,29 +104,6 @@ std::vector< DocumentObject* > GroupExtension::addObjects(std::vector< DocumentO
|
||||
return added;
|
||||
}
|
||||
|
||||
void GroupExtension::addObjects(const std::vector<App::DocumentObject*>& objs)
|
||||
{
|
||||
bool objectAdded = false;
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
for (auto obj : objs) {
|
||||
if (allowObject(obj)) {
|
||||
|
||||
//only one group per object
|
||||
auto *group = App::GroupExtension::getGroupOfObject(obj);
|
||||
if (group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
|
||||
if (std::find(grp.begin(), grp.end(), obj) == grp.end()) {
|
||||
grp.push_back(obj);
|
||||
objectAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (objectAdded)
|
||||
Group.setValues(grp);
|
||||
}
|
||||
|
||||
std::vector<DocumentObject*> GroupExtension::removeObject(DocumentObject* obj)
|
||||
{
|
||||
std::vector<DocumentObject*> vec = {obj};
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
* Returns the origin group which contains this object.
|
||||
* In case this object is not part of any geoFeatureGroup 0 is returned.
|
||||
* @param obj the object to search for
|
||||
* @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject()
|
||||
* default is true
|
||||
*/
|
||||
static DocumentObject* getGroupOfObject (const DocumentObject* obj);
|
||||
|
||||
|
||||
@@ -88,8 +88,6 @@ public:
|
||||
* Returns the part which contains this object.
|
||||
* In case this object is not belongs to any Part 0 is returned.
|
||||
* @param obj the object to search for
|
||||
* @param indirect if true return if the part that so-called geoHas the object, @see geoHasObject()
|
||||
* default is true
|
||||
*/
|
||||
static App::Part* getPartOfObject (const DocumentObject* obj);
|
||||
|
||||
|
||||
@@ -108,7 +108,8 @@ void ensureCorrectGroups(PropertyContainer* container, App::DocumentObject* obje
|
||||
if(cont->isRestoring() || object->isRestoring())
|
||||
return;
|
||||
|
||||
auto objs = GeoFeatureGroupExtension::getCSRelevantLinks(object);
|
||||
std::vector< DocumentObject* > objs;
|
||||
GeoFeatureGroupExtension::getCSRelevantLinks(object, objs);
|
||||
objs.push_back(object);
|
||||
|
||||
for(auto obj : objs) {
|
||||
|
||||
@@ -2097,8 +2097,8 @@ bool SketchObject::isCarbonCopyAllowed(App::Document *pDoc, App::DocumentObject
|
||||
//App::DocumentObject *support = this->Support.getValue();
|
||||
Part::BodyBase* body_this = Part::BodyBase::findBodyOf(this);
|
||||
Part::BodyBase* body_obj = Part::BodyBase::findBodyOf(pObj);
|
||||
App::Part* part_this = App::Part::getPartOfObject(this, true);
|
||||
App::Part* part_obj = App::Part::getPartOfObject(pObj, true);
|
||||
App::Part* part_this = App::Part::getPartOfObject(this);
|
||||
App::Part* part_obj = App::Part::getPartOfObject(pObj);
|
||||
if (part_this == part_obj){ //either in the same part, or in the root of document
|
||||
if (body_this != NULL) {
|
||||
if ((body_this != body_obj) && !this->allowOtherBody) {
|
||||
|
||||
@@ -5819,9 +5819,9 @@ bool ViewProviderSketch::onDelete(const std::vector<std::string> &subList)
|
||||
return PartGui::ViewProviderPart::onDelete(subList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ViewProviderSketch::showRestoreInformationLayer() {
|
||||
|
||||
visibleInformationChanged = true ;
|
||||
draw(false,false);
|
||||
draw(false,false);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user