[Bf-blender-cvs] [2f9a0dfe64] blender2.8: Fix T50714: Collections: Adding object to scene without an existing collection

Dalai Felinto noreply at git.blender.org
Fri Feb 24 10:14:47 CET 2017


Commit: 2f9a0dfe6429661f1d4bdf28398504df7fe98beb
Author: Dalai Felinto
Date:   Thu Feb 23 12:35:14 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB2f9a0dfe6429661f1d4bdf28398504df7fe98beb

Fix T50714: Collections: Adding object to scene without an existing collection

This was causing blender to segfault.

We now add create a new collection and link to the layer before adding
the new object

(also included unittests, and requires updated lib/tests)

===================================================================

M	release/scripts/modules/bpy_extras/object_utils.py
M	source/blender/blenkernel/intern/object.c
M	tests/python/render_layer/CMakeLists.txt
M	tests/python/render_layer/render_layer_common.py
A	tests/python/render_layer/test_object_add_no_collection_cylinder.py
A	tests/python/render_layer/test_object_add_no_collection_empty.py
A	tests/python/render_layer/test_object_add_no_collection_torus.py

===================================================================

diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index d740137b0c..83d3b2066b 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -121,7 +121,14 @@ def object_data_add(context, obdata, operator=None, name=None):
     """
     scene = context.scene
     layer = context.render_layer
-    scene_collection = context.scene_collection
+    layer_collection = context.layer_collection
+
+    if not layer_collection:
+        # when there is no collection linked to this render_layer create one
+        scene_collection = scene.master_collection.collections.new("")
+        layer_collection = layer.collections.link(scene_collection)
+    else:
+        scene_collection = layer_collection.collection
 
     bpy.ops.object.select_all(action='DESELECT')
 
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ad0ce3fef9..250ad6794f 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -692,6 +692,14 @@ Object *BKE_object_add(
 	ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
 
 	lc = BKE_layer_collection_active(sl);
+
+	if (lc == NULL) {
+		BLI_assert(BLI_listbase_count_ex(&sl->layer_collections, 1) == 0);
+		/* when there is no collection linked to this SceneLayer, create one */
+		SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+		lc = BKE_collection_link(sl, sc);
+	}
+
 	BKE_collection_object_add(scene, lc->scene_collection, ob);
 
 	base = BKE_scene_layer_base_find(sl, ob);
diff --git a/tests/python/render_layer/CMakeLists.txt b/tests/python/render_layer/CMakeLists.txt
index ff98d95cc0..7825326817 100644
--- a/tests/python/render_layer/CMakeLists.txt
+++ b/tests/python/render_layer/CMakeLists.txt
@@ -67,6 +67,9 @@ RENDER_LAYER_TEST(operator_context)
 RENDER_LAYER_TEST(object_add_cylinder)
 RENDER_LAYER_TEST(object_add_empty)
 RENDER_LAYER_TEST(object_add_torus)
+RENDER_LAYER_TEST(object_add_no_collection_cylinder)
+RENDER_LAYER_TEST(object_add_no_collection_empty)
+RENDER_LAYER_TEST(object_add_no_collection_torus)
 RENDER_LAYER_TEST(object_copy)
 RENDER_LAYER_TEST(evaluation_visibility_a)
 RENDER_LAYER_TEST(evaluation_visibility_b)
diff --git a/tests/python/render_layer/render_layer_common.py b/tests/python/render_layer/render_layer_common.py
index e551518ac5..d24b80e0d0 100644
--- a/tests/python/render_layer/render_layer_common.py
+++ b/tests/python/render_layer/render_layer_common.py
@@ -309,3 +309,30 @@ class RenderLayerTesting(unittest.TestCase):
                 ),
                 "Scene dump files differ")
 
+    def do_object_add_no_collection(self, add_mode):
+        """
+        Test for adding objects when no collection
+        exists in render layer
+        """
+        import bpy
+
+        # empty layer of collections
+
+        layer = bpy.context.render_layer
+        while layer.collections:
+            layer.collections.unlink(layer.collections[0])
+
+        # add new objects
+        if add_mode == 'EMPTY':
+            bpy.ops.object.add() # 'Empty'
+
+        elif add_mode == 'CYLINDER':
+            bpy.ops.mesh.primitive_cylinder_add() # 'Cylinder'
+
+        elif add_mode == 'TORUS':
+            bpy.ops.mesh.primitive_torus_add() # 'Torus'
+
+        self.assertEqual(len(layer.collections), 1, "New collection not created")
+        collection = layer.collections[0]
+        self.assertEqual(len(collection.objects), 1, "New collection is empty")
+
diff --git a/tests/python/render_layer/test_object_add_no_collection_cylinder.py b/tests/python/render_layer/test_object_add_no_collection_cylinder.py
new file mode 100644
index 0000000000..72bd046d75
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_cylinder.py
@@ -0,0 +1,40 @@
+# ./blender.bin --background -noaudio --python tests/python/render_layer/test_scene_copy.py -- --testdir="/data/lib/tests/"
+
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+
+import os, sys
+sys.path.append(os.path.dirname(__file__))
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+    def test_object_add_cylinder(self):
+        """
+        See if new objects are added to the correct collection
+        bpy.ops.mesh.primitive_cylinder_add()
+        """
+        import os
+        self.do_object_add_no_collection('CYLINDER')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    import sys
+
+    extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+    sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+    UnitTesting._extra_arguments = extra_arguments
+    unittest.main()
diff --git a/tests/python/render_layer/test_object_add_no_collection_empty.py b/tests/python/render_layer/test_object_add_no_collection_empty.py
new file mode 100644
index 0000000000..49600f2e73
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_empty.py
@@ -0,0 +1,39 @@
+# ./blender.bin --background -noaudio --python tests/python/render_layer/test_scene_copy.py -- --testdir="/data/lib/tests/"
+
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+
+import os, sys
+sys.path.append(os.path.dirname(__file__))
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+    def test_syncing_object_add_empty(self):
+        """
+        See if new objects are added to the correct collection
+        bpy.ops.object.add()
+        """
+        self.do_object_add_no_collection('EMPTY')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    import sys
+
+    extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+    sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+    UnitTesting._extra_arguments = extra_arguments
+    unittest.main()
diff --git a/tests/python/render_layer/test_object_add_no_collection_torus.py b/tests/python/render_layer/test_object_add_no_collection_torus.py
new file mode 100644
index 0000000000..11358d680a
--- /dev/null
+++ b/tests/python/render_layer/test_object_add_no_collection_torus.py
@@ -0,0 +1,39 @@
+# ./blender.bin --background -noaudio --python tests/python/render_layer/test_scene_copy.py -- --testdir="/data/lib/tests/"
+
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+
+import os, sys
+sys.path.append(os.path.dirname(__file__))
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+    def test_syncing_object_add_torus(self):
+        """
+        See if new objects are added to the correct collection
+        bpy.ops.mesh.primitive_torus_add()
+        """
+        self.do_object_add_no_collection('TORUS')
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    import sys
+
+    extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+    sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+    UnitTesting._extra_arguments = extra_arguments
+    unittest.main()




More information about the Bf-blender-cvs mailing list