[Bf-blender-cvs] [e7c3c46e890] blender2.8: Fix make single user crash

Dalai Felinto noreply at git.blender.org
Wed Mar 14 12:15:42 CET 2018


Commit: e7c3c46e8902a214c12f2cba70790646a6fcfda6
Author: Dalai Felinto
Date:   Tue Mar 13 16:10:20 2018 -0300
Branches: blender2.8
https://developer.blender.org/rBe7c3c46e8902a214c12f2cba70790646a6fcfda6

Fix make single user crash

How to reproduce the crash:
* Factory startup
* 'u'key (make single user)

It comes with a simple unittest to reproduce the original issue.

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

M	source/blender/editors/object/object_relations.c
M	tests/python/view_layer/CMakeLists.txt
A	tests/python/view_layer/test_make_single_user.py

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

diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 5e7e0fb68a3..00c5fdf3cc7 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1632,33 +1632,30 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
 
 static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups)
 {
-	if (!ID_IS_LINKED(ob) && ob->id.us > 1) {
-		/* base gets copy of object */
-		Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
+	/* base gets copy of object */
+	Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
 
-		if (copy_groups) {
-			if (ob->flag & OB_FROMGROUP) {
-				obn->flag |= OB_FROMGROUP;
-			}
-		}
-		else {
-			/* copy already clears */
+	if (copy_groups) {
+		if (ob->flag & OB_FROMGROUP) {
+			obn->flag |= OB_FROMGROUP;
 		}
-		/* remap gpencil parenting */
+	}
+	else {
+		/* copy already clears */
+	}
+	/* remap gpencil parenting */
 
-		if (scene->gpd) {
-			bGPdata *gpd = scene->gpd;
-			for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
-				if (gpl->parent == ob) {
-					gpl->parent = obn;
-				}
+	if (scene->gpd) {
+		bGPdata *gpd = scene->gpd;
+		for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+			if (gpl->parent == ob) {
+				gpl->parent = obn;
 			}
 		}
-
-		id_us_min(&ob->id);
-		return obn;
 	}
-	return NULL;
+
+	id_us_min(&ob->id);
+	return obn;
 }
 
 static void libblock_relink_scene_collection(SceneCollection *sc)
@@ -1678,7 +1675,9 @@ static void single_object_users_scene_collection(Main *bmain, Scene *scene, Scen
 		Object *ob = link->data;
 		/* an object may be in more than one collection */
 		if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
-			link->data = single_object_users_object(bmain, scene, link->data, copy_groups);
+			if (!ID_IS_LINKED(ob) && ob->id.us > 1) {
+				link->data = single_object_users_object(bmain, scene, link->data, copy_groups);
+			}
 		}
 	}
 
diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt
index 77a56fb47f9..9cb33420ac5 100644
--- a/tests/python/view_layer/CMakeLists.txt
+++ b/tests/python/view_layer/CMakeLists.txt
@@ -108,6 +108,7 @@ VIEW_LAYER_TEST(object_link_a)
 VIEW_LAYER_TEST(object_link_b)
 VIEW_LAYER_TEST(object_link_c)
 VIEW_LAYER_TEST(operator_context)
+VIEW_LAYER_TEST(make_single_user)
 VIEW_LAYER_TEST(move_above_below_scene_collection_a)
 VIEW_LAYER_TEST(move_above_below_scene_collection_b)
 VIEW_LAYER_TEST(move_above_below_scene_collection_c)
diff --git a/tests/python/view_layer/test_make_single_user.py b/tests/python/view_layer/test_make_single_user.py
new file mode 100644
index 00000000000..2a8a479bab2
--- /dev/null
+++ b/tests/python/view_layer/test_make_single_user.py
@@ -0,0 +1,54 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from view_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(ViewLayerTesting):
+    def test_make_single_user(self):
+        """
+        Really basic test, just to check for crashes on basic files.
+        """
+        import bpy
+        scene = bpy.context.scene
+        master_collection = scene.master_collection
+        view_layer = bpy.context.view_layer
+        ob = bpy.context.object
+
+        # clean up the scene a bit
+        for o in (o for o in view_layer.objects if o != ob):
+            view_layer.collections[0].collection.objects.unlink(o)
+
+        for v in (v for v in scene.view_layers if v != view_layer):
+            scene.view_layers.remove(v)
+
+        while master_collection.collections:
+            master_collection.collections.remove(
+                    master_collection.collections[0])
+
+        view_layer.collections.link(master_collection)
+        ob.select_set('SELECT')
+
+        # update depsgraph
+        scene.update()
+
+        # test itself
+        bpy.ops.object.make_single_user(object=True)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    UnitTesting._extra_arguments = setup_extra_arguments(__file__)
+    unittest.main()



More information about the Bf-blender-cvs mailing list