diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index d740137b0c3..83d3b2066b4 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 ad0ce3fef9b..250ad6794fe 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 ff98d95cc09..78253268173 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 e551518ac53..d24b80e0d0a 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 00000000000..72bd046d758 --- /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 00000000000..49600f2e73e --- /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 00000000000..11358d680a1 --- /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()