Allow add/remove multiple objects in a group
This commit is contained in:
@@ -119,47 +119,61 @@ Base::Placement GeoFeatureGroupExtension::recursiveGroupPlacement(GeoFeatureGrou
|
||||
return group->placement().getValue();
|
||||
}
|
||||
|
||||
std::vector<DocumentObject*> GeoFeatureGroupExtension::addObject(App::DocumentObject* object) {
|
||||
std::vector<DocumentObject*> GeoFeatureGroupExtension::addObjects(std::vector<App::DocumentObject*> objects) {
|
||||
|
||||
if(!allowObject(object))
|
||||
return std::vector<DocumentObject*>();
|
||||
|
||||
//cross CoordinateSystem links are not allowed, so we need to move the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
links.push_back(object);
|
||||
|
||||
auto ret = links;
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
for( auto obj : links) {
|
||||
//only one geofeaturegroup per object.
|
||||
auto *group = App::GeoFeatureGroupExtension::getGroupOfObject(obj);
|
||||
if(group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
std::vector<DocumentObject*> ret;
|
||||
|
||||
for(auto object : objects) {
|
||||
|
||||
if (!hasObject(obj))
|
||||
grp.push_back(obj);
|
||||
else
|
||||
ret.erase(std::remove(ret.begin(), ret.end(), obj), ret.end());
|
||||
if(!allowObject(object))
|
||||
continue;
|
||||
|
||||
//cross CoordinateSystem links are not allowed, so we need to move the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
links.push_back(object);
|
||||
|
||||
for( auto obj : links) {
|
||||
//only one geofeaturegroup per object.
|
||||
auto *group = App::GeoFeatureGroupExtension::getGroupOfObject(obj);
|
||||
if(group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
|
||||
if (!hasObject(obj)) {
|
||||
grp.push_back(obj);
|
||||
ret.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Group.setValues(grp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<DocumentObject*> GeoFeatureGroupExtension::removeObject(App::DocumentObject* object) {
|
||||
|
||||
//cross CoordinateSystem links are not allowed, so we need to remove the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
links.push_back(object);
|
||||
std::vector<DocumentObject*> GeoFeatureGroupExtension::removeObjects(std::vector<App::DocumentObject*> objects) {
|
||||
|
||||
//remove all links out of group
|
||||
std::vector<DocumentObject*> removed;
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
for(auto link : links)
|
||||
grp.erase(std::remove(grp.begin(), grp.end(), link), grp.end());
|
||||
|
||||
Group.setValues(grp);
|
||||
return links;
|
||||
for(auto object : objects) {
|
||||
//cross CoordinateSystem links are not allowed, so we need to remove the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
links.push_back(object);
|
||||
|
||||
//remove all links out of group
|
||||
for(auto link : links) {
|
||||
auto end = std::remove(grp.begin(), grp.end(), link);
|
||||
if(end != grp.end()) {
|
||||
grp.erase(end, grp.end());
|
||||
removed.push_back(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!removed.empty())
|
||||
Group.setValues(grp);
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > GeoFeatureGroupExtension::getObjectsFromLinks(DocumentObject* obj) {
|
||||
|
||||
@@ -96,8 +96,8 @@ public:
|
||||
!obj->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId());
|
||||
}
|
||||
|
||||
virtual std::vector<DocumentObject*> addObject(DocumentObject* obj) override;
|
||||
virtual std::vector<DocumentObject*> removeObject(DocumentObject* obj) override;
|
||||
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
|
||||
/// including their linkes (recursively) except GeoFeatureGroups, where the recursion stops. Expressions
|
||||
|
||||
@@ -62,35 +62,46 @@ DocumentObject* GroupExtension::addObject(const char* sType, const char* pObject
|
||||
|
||||
std::vector<DocumentObject*> GroupExtension::addObject(DocumentObject* obj)
|
||||
{
|
||||
if(!allowObject(obj))
|
||||
return std::vector<DocumentObject*>();
|
||||
std::vector<DocumentObject*> vec = {obj};
|
||||
return addObjects(vec);
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > GroupExtension::addObjects(std::vector< DocumentObject* > objs) {
|
||||
|
||||
if (hasObject(obj))
|
||||
return std::vector<DocumentObject*>();
|
||||
std::vector<DocumentObject*> added;
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
for(auto obj : objs) {
|
||||
|
||||
if(!allowObject(obj))
|
||||
continue;
|
||||
|
||||
//only one group per object. Note that it is allowed to be in a group and geofeaturegroup. However,
|
||||
//getGroupOfObject() returns only normal groups, no GeoFeatureGroups. Hence this works.
|
||||
auto *group = App::GroupExtension::getGroupOfObject(obj);
|
||||
if(group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
|
||||
//if we are on a geofeaturegroup we need to ensure the object is too
|
||||
auto geogrp = GeoFeatureGroupExtension::getGroupOfObject(getExtendedObject());
|
||||
auto objgrp = GeoFeatureGroupExtension::getGroupOfObject(obj);
|
||||
if( geogrp != objgrp ) {
|
||||
//what to doo depends on if we are in geofeature group or not
|
||||
if(geogrp)
|
||||
geogrp->getExtensionByType<GeoFeatureGroupExtension>()->addObject(obj);
|
||||
else
|
||||
objgrp->getExtensionByType<GeoFeatureGroupExtension>()->removeObject(obj);
|
||||
if (hasObject(obj))
|
||||
continue;
|
||||
|
||||
//only one group per object. Note that it is allowed to be in a group and geofeaturegroup. However,
|
||||
//getGroupOfObject() returns only normal groups, no GeoFeatureGroups. Hence this works.
|
||||
auto *group = App::GroupExtension::getGroupOfObject(obj);
|
||||
if(group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
|
||||
//if we are in a geofeaturegroup we need to ensure the object is too
|
||||
auto geogrp = GeoFeatureGroupExtension::getGroupOfObject(getExtendedObject());
|
||||
auto objgrp = GeoFeatureGroupExtension::getGroupOfObject(obj);
|
||||
if( geogrp != objgrp ) {
|
||||
//what to doo depends on if we are in geofeature group or not
|
||||
if(geogrp)
|
||||
geogrp->getExtensionByType<GeoFeatureGroupExtension>()->addObject(obj);
|
||||
else
|
||||
objgrp->getExtensionByType<GeoFeatureGroupExtension>()->removeObject(obj);
|
||||
}
|
||||
|
||||
grp.push_back(obj);
|
||||
added.push_back(obj);
|
||||
}
|
||||
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
grp.push_back(obj);
|
||||
Group.setValues(grp);
|
||||
|
||||
std::vector<DocumentObject*> vec = {obj};
|
||||
return vec;
|
||||
return added;
|
||||
}
|
||||
|
||||
void GroupExtension::addObjects(const std::vector<App::DocumentObject*>& objs)
|
||||
@@ -118,18 +129,34 @@ void GroupExtension::addObjects(const std::vector<App::DocumentObject*>& objs)
|
||||
|
||||
std::vector<DocumentObject*> GroupExtension::removeObject(DocumentObject* obj)
|
||||
{
|
||||
const std::vector<DocumentObject*> & grp = Group.getValues();
|
||||
std::vector<DocumentObject*> newGrp;
|
||||
std::vector<DocumentObject*> vec = {obj};
|
||||
return removeObjects(vec);
|
||||
}
|
||||
|
||||
std::remove_copy (grp.begin(), grp.end(), std::back_inserter (newGrp), obj);
|
||||
std::vector< DocumentObject* > GroupExtension::removeObjects(std::vector< DocumentObject* > objs) {
|
||||
|
||||
const std::vector<DocumentObject*> & grp = Group.getValues();
|
||||
std::vector<DocumentObject*> newGrp = grp;
|
||||
std::vector<DocumentObject*> removed;
|
||||
|
||||
std::vector<DocumentObject*>::iterator end = newGrp.end();
|
||||
for(auto obj : objs) {
|
||||
auto res = std::remove(newGrp.begin(), end, obj);
|
||||
if(res != end) {
|
||||
end = res;
|
||||
removed.push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
newGrp.erase(end, newGrp.end());
|
||||
if (grp.size() != newGrp.size()) {
|
||||
Group.setValues (newGrp);
|
||||
}
|
||||
|
||||
std::vector<DocumentObject*> vec = {obj};
|
||||
return vec;
|
||||
return removed;
|
||||
}
|
||||
|
||||
|
||||
void GroupExtension::removeObjectsFromDocument()
|
||||
{
|
||||
const std::vector<DocumentObject*> & grp = Group.getValues();
|
||||
|
||||
@@ -53,9 +53,9 @@ public:
|
||||
/* Adds the object \a obj to this group. Returns all objects that have been added.
|
||||
*/
|
||||
virtual std::vector<DocumentObject*> addObject(DocumentObject* obj);
|
||||
/* Adds an array of object \a objs to this group.
|
||||
/* Adds the objects \a objs to this group. Returns all objects that have been added.
|
||||
*/
|
||||
virtual void addObjects(const std::vector<App::DocumentObject*>& objs);
|
||||
virtual std::vector<DocumentObject*> addObjects(std::vector<DocumentObject*> obj);
|
||||
/*override this function if you want only special objects
|
||||
*/
|
||||
virtual bool allowObject(DocumentObject* ) {return true;}
|
||||
@@ -63,6 +63,9 @@ public:
|
||||
/** Removes an object from this group. Returns all objects that have been removed.
|
||||
*/
|
||||
virtual std::vector<DocumentObject*> removeObject(DocumentObject* obj);
|
||||
/** Removes objects from this group. Returns all objects that have been removed.
|
||||
*/
|
||||
virtual std::vector<DocumentObject*> removeObjects(std::vector<DocumentObject*> obj);
|
||||
/** Removes all children objects from this group and the document.
|
||||
*/
|
||||
virtual void removeObjectsFromDocument();
|
||||
|
||||
@@ -18,15 +18,25 @@
|
||||
<UserDocu>Create and add an object with given type and name to the group</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="addObject">
|
||||
<Documentation>
|
||||
<UserDocu>Add an object to the group</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeObject">
|
||||
<Documentation>
|
||||
<UserDocu>Remove an object from the group</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="addObject">
|
||||
<Documentation>
|
||||
<UserDocu>Add an object to the group</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="addObjects">
|
||||
<Documentation>
|
||||
<UserDocu>Adds multiple objects to the group. Expects a list.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeObject">
|
||||
<Documentation>
|
||||
<UserDocu>Remove an object from the group</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeObjects">
|
||||
<Documentation>
|
||||
<UserDocu>Remove multiple objects from the group. Expects a list.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeObjectsFromDocument">
|
||||
<Documentation>
|
||||
|
||||
@@ -94,6 +94,43 @@ PyObject* GroupExtensionPy::addObject(PyObject *args)
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
|
||||
PyObject* GroupExtensionPy::addObjects(PyObject *args) {
|
||||
|
||||
PyObject *object;
|
||||
if (!PyArg_ParseTuple(args, "O", &object)) // convert args: Python->C
|
||||
return NULL; // NULL triggers exception
|
||||
|
||||
if (PyTuple_Check(object) || PyList_Check(object)) {
|
||||
Py::Sequence list(object);
|
||||
Py::Sequence::size_type size = list.size();
|
||||
std::vector<DocumentObject*> values;
|
||||
values.resize(size);
|
||||
|
||||
for (Py::Sequence::size_type i = 0; i < size; i++) {
|
||||
Py::Object item = list[i];
|
||||
if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) {
|
||||
std::string error = std::string("type in list must be 'DocumentObject', not ");
|
||||
error += (*item)->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
}
|
||||
|
||||
values[i] = static_cast<DocumentObjectPy*>(*item)->getDocumentObjectPtr();
|
||||
}
|
||||
|
||||
GroupExtension* grp = getGroupExtensionPtr();
|
||||
auto vec = grp->addObjects(values);
|
||||
Py::List result;
|
||||
for (App::DocumentObject* obj : vec)
|
||||
result.append(Py::asObject(obj->getPyObject()));
|
||||
|
||||
return Py::new_reference_to(result);
|
||||
}
|
||||
|
||||
std::string error = std::string("type must be list of 'DocumentObject', not ");
|
||||
error += object->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
};
|
||||
|
||||
PyObject* GroupExtensionPy::removeObject(PyObject *args)
|
||||
{
|
||||
PyObject *object;
|
||||
@@ -120,6 +157,43 @@ PyObject* GroupExtensionPy::removeObject(PyObject *args)
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
|
||||
PyObject* GroupExtensionPy::removeObjects(PyObject *args) {
|
||||
|
||||
PyObject *object;
|
||||
if (!PyArg_ParseTuple(args, "O", &object)) // convert args: Python->C
|
||||
return NULL; // NULL triggers exception
|
||||
|
||||
if (PyTuple_Check(object) || PyList_Check(object)) {
|
||||
Py::Sequence list(object);
|
||||
Py::Sequence::size_type size = list.size();
|
||||
std::vector<DocumentObject*> values;
|
||||
values.resize(size);
|
||||
|
||||
for (Py::Sequence::size_type i = 0; i < size; i++) {
|
||||
Py::Object item = list[i];
|
||||
if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) {
|
||||
std::string error = std::string("type in list must be 'DocumentObject', not ");
|
||||
error += (*item)->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
}
|
||||
|
||||
values[i] = static_cast<DocumentObjectPy*>(*item)->getDocumentObjectPtr();
|
||||
}
|
||||
|
||||
GroupExtension* grp = getGroupExtensionPtr();
|
||||
auto vec = grp->removeObjects(values);
|
||||
Py::List result;
|
||||
for (App::DocumentObject* obj : vec)
|
||||
result.append(Py::asObject(obj->getPyObject()));
|
||||
|
||||
return Py::new_reference_to(result);
|
||||
}
|
||||
|
||||
std::string error = std::string("type must be list of 'DocumentObject', not ");
|
||||
error += object->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
};
|
||||
|
||||
PyObject* GroupExtensionPy::removeObjectsFromDocument(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
|
||||
|
||||
@@ -184,9 +184,12 @@ void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > OriginGroupExtension::addObject(DocumentObject* obj) {
|
||||
relinkToOrigin(obj);
|
||||
return App::GeoFeatureGroupExtension::addObject(obj);
|
||||
std::vector< DocumentObject* > OriginGroupExtension::addObjects(std::vector<DocumentObject*> objs) {
|
||||
|
||||
for(auto obj : objs)
|
||||
relinkToOrigin(obj);
|
||||
|
||||
return App::GeoFeatureGroupExtension::addObjects(objs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
//changes all links of obj to a origin to point to this groupes origin
|
||||
void relinkToOrigin(App::DocumentObject* obj);
|
||||
|
||||
virtual std::vector<DocumentObject*> addObject(DocumentObject* obj) override;
|
||||
virtual std::vector<DocumentObject*> addObjects(std::vector<DocumentObject*> obj) override;
|
||||
|
||||
protected:
|
||||
/// Checks integrity of the Origin
|
||||
|
||||
Reference in New Issue
Block a user