Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_group.h1
-rw-r--r--source/blender/blenkernel/intern/group.c37
2 files changed, 38 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index f528fe8c7f9..820e1ea1494 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -50,6 +50,7 @@ bool BKE_group_object_add(struct Group *group, struct Object *ob, struc
bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
+bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
bool BKE_group_is_animated(struct Group *group, struct Object *parent);
void BKE_group_tag_recalc(struct Group *group);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 1f9cf2e11b7..96eb95968f3 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -219,6 +219,43 @@ static int group_object_unlink_internal(Group *group, Object *ob)
return removed;
}
+static bool group_object_cyclic_check_internal(Object *object, Group *group) {
+
+ if (object->dup_group) {
+ Group *dup_group = object->dup_group;
+ if ((dup_group->id.flag & LIB_DOIT) == 0) {
+ /* Cycle already exists in groups, let's prevent further crappyness */
+ return true;
+ }
+ /* flag the object to identify cyclic dependencies in further dupli groups */
+ dup_group->id.flag &= ~LIB_DOIT;
+
+ if (dup_group == group)
+ return true;
+ else {
+ GroupObject *gob;
+ for (gob = dup_group->gobject.first; gob; gob = gob->next) {
+ if (group_object_cyclic_check_internal(gob->ob, group)) {
+ return true;
+ }
+ }
+ }
+
+ /* un-flag the object, it's allowed to have the same group multiple times in parallel */
+ dup_group->id.flag |= LIB_DOIT;
+ }
+
+ return false;
+}
+
+bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
+{
+ /* first flag all groups */
+ BKE_main_id_tag_listbase(&bmain->group, true);
+
+ return group_object_cyclic_check_internal(object, group);
+}
+
bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
{
if (group_object_unlink_internal(group, object)) {