Fix collections names no longer unique when moved around
authorDalai Felinto <dfelinto@gmail.com>
Fri, 19 Jan 2018 20:44:11 +0000 (18:44 -0200)
committerDalai Felinto <dfelinto@gmail.com>
Fri, 19 Jan 2018 20:44:11 +0000 (18:44 -0200)
We were not checking for uniqueness after moving. And in some cases the new
siblings of our collection may have conflicting names.

source/blender/blenkernel/intern/collection.c
tests/python/view_layer/CMakeLists.txt
tests/python/view_layer/test_collection_rename_a.py [moved from tests/python/view_layer/test_collection_rename.py with 100% similarity]
tests/python/view_layer/test_collection_rename_b.py [new file with mode: 0644]

index d0f89eb46e5a5eaa859716dcf233d7a4d7115c8f..edd29f793ecc4f2233003c4c52f80493c353bcec 100644 (file)
@@ -314,6 +314,15 @@ void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *
        collection_rename(&scene->id, sc, name);
 }
 
+/**
+ * Make sure the collection name is still unique within its siblings.
+ */
+static void collection_name_check(const ID *owner_id, SceneCollection *sc)
+{
+       /* It's a bit of a hack, we simply try to make sure the collection name is valid. */
+       collection_rename(owner_id, sc, sc->name);
+}
+
 /**
  * Free (or release) any data used by the master collection (does not free the master collection itself).
  * Used only to clear the entire scene or group data since it's not doing re-syncing of the LayerCollection tree
@@ -589,6 +598,9 @@ bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, Scen
        BKE_layer_collection_resync(owner_id, sc_src_parent);
        BKE_layer_collection_resync(owner_id, sc_dst_parent);
 
+       /* Keep names unique. */
+       collection_name_check(owner_id, sc_src);
+
        return true;
 }
 
@@ -628,6 +640,9 @@ bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, Scen
        BKE_layer_collection_resync(owner_id, sc_src_parent);
        BKE_layer_collection_resync(owner_id, sc_dst_parent);
 
+       /* Keep names unique. */
+       collection_name_check(owner_id, sc_src);
+
        return true;
 }
 
@@ -663,6 +678,9 @@ bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, Scene
        BKE_layer_collection_resync(owner_id, sc_src_parent);
        BKE_layer_collection_resync(owner_id, sc_dst);
 
+       /* Keep names unique. */
+       collection_name_check(owner_id, sc_src);
+
        return true;
 }
 
index 69b024164874fdd8a830cb047b72592ba985fe38..e308e2e0952117694dc03cced9d79937c38c3798 100644 (file)
@@ -62,7 +62,8 @@ endmacro()
 
 VIEW_LAYER_TEST(active_collection)
 VIEW_LAYER_TEST(background_set)
-VIEW_LAYER_TEST(collection_rename)
+VIEW_LAYER_TEST(collection_rename_a)
+VIEW_LAYER_TEST(collection_rename_b)
 VIEW_LAYER_TEST(evaluation_render_settings_a)
 VIEW_LAYER_TEST(evaluation_render_settings_b)
 VIEW_LAYER_TEST(evaluation_render_settings_c)
diff --git a/tests/python/view_layer/test_collection_rename_b.py b/tests/python/view_layer/test_collection_rename_b.py
new file mode 100644 (file)
index 0000000..3787066
--- /dev/null
@@ -0,0 +1,58 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from view_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(ViewLayerTesting):
+    def setup_collections(self):
+        import bpy
+        scene = bpy.context.scene
+
+        master = scene.master_collection
+        one = master.collections[0]
+        two = master.collections.new()
+        sub = two.collections.new(one.name)
+
+        self.assertEqual(one.name, sub.name)
+
+        lookup = {
+            'master': master,
+            'one': one,
+            'two': two,
+            'sub': sub,
+        }
+        return lookup
+
+    def test_move_above(self):
+        collections = self.setup_collections()
+        collections['sub'].move_above(collections['one'])
+        self.assertNotEqual(collections['one'].name, collections['sub'].name)
+
+    def test_move_below(self):
+        collections = self.setup_collections()
+        collections['sub'].move_below(collections['one'])
+        self.assertNotEqual(collections['one'].name, collections['sub'].name)
+
+    def test_move_into(self):
+        collections = self.setup_collections()
+        collections['sub'].move_into(collections['master'])
+        self.assertNotEqual(collections['one'].name, collections['sub'].name)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    UnitTesting._extra_arguments = setup_extra_arguments(__file__)
+    unittest.main()