[Bf-blender-cvs] [7484c6c5ee6] blender2.8: Fix non-instanced groups in no-collection file creating collections

Dalai Felinto noreply at git.blender.org
Tue Oct 24 14:28:13 CEST 2017


Commit: 7484c6c5ee68c313e72394f7538d1c7386c0ced7
Author: Dalai Felinto
Date:   Tue Oct 24 10:21:24 2017 -0200
Branches: blender2.8
https://developer.blender.org/rB7484c6c5ee68c313e72394f7538d1c7386c0ced7

Fix non-instanced groups in no-collection file creating collections

This is a corner-case, but one that is too easy to reproduce:

* Unlink all the collections of active view layer.
* Link a group without "Instancing" it.

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

M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenloader/intern/readfile.c

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

diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 0e0290414a4..66a5e67583c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -386,6 +386,8 @@ LayerCollection *BKE_layer_collection_get_active_ensure(Scene *scene, SceneLayer
 		/* 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);
+		/* New collection has to be the active one. */
+		BLI_assert(lc == BKE_layer_collection_get_active(sl));
 	}
 
 	return lc;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c0580660e2b..ce7914b0f37 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -252,6 +252,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
 static void direct_link_modifiers(FileData *fd, ListBase *lb);
 static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
 static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
+static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *sl, const short flag);
 
 /* this function ensures that reports are printed,
  * in the case of libraray linking errors this is important!
@@ -10142,15 +10143,16 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
 }
 
 static void give_base_to_objects(
-        Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc, Library *lib, const short flag)
+        Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *lib, const short flag)
 {
 	Object *ob;
 	Base *base;
+	SceneCollection *scene_collection = NULL;
 	const bool is_link = (flag & FILE_LINK) != 0;
 
 	BLI_assert(scene);
 
-	/* give all objects which are LIB_TAG_INDIRECT a base, or for a group when *lib has been set */
+	/* Give all objects which are LIB_TAG_INDIRECT a base, or for a group when *lib has been set. */
 	for (ob = mainvar->object.first; ob; ob = ob->id.next) {
 		if ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0) {
 			bool do_it = false;
@@ -10167,8 +10169,12 @@ static void give_base_to_objects(
 			if (do_it) {
 				CLAMP_MIN(ob->id.us, 0);
 
-				BKE_collection_object_add(scene, sc, ob);
-				base = BKE_scene_layer_base_find(sl, ob);
+				if (scene_collection == NULL) {
+					scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION);
+				}
+
+				BKE_collection_object_add(scene, scene_collection, ob);
+				base = BKE_scene_layer_base_find(scene_layer, ob);
 				BKE_scene_object_base_flag_sync_from_base(base);
 
 				if (flag & FILE_AUTOSELECT) {
@@ -10178,10 +10184,9 @@ static void give_base_to_objects(
 						base->flag |= BASE_SELECTED;
 						BKE_scene_base_flag_sync_from_base(base);
 					}
-					/* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
+					/* Do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level. */
 				}
 
-
 				ob->id.tag &= ~LIB_TAG_INDIRECT;
 				ob->id.tag |= LIB_TAG_EXTERN;
 			}
@@ -10190,25 +10195,28 @@ static void give_base_to_objects(
 }
 
 static void give_base_to_groups(
-        Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc,
-        Library *UNUSED(lib), const short UNUSED(flag))
+        Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *UNUSED(lib), const short UNUSED(flag))
 {
 	Group *group;
 	Base *base;
 	Object *ob;
+	SceneCollection *scene_collection;
+
+	/* If the group is empty this function is not even called, so it's safe to ensure a collection at this point. */
+	scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION);
 
-	/* give all objects which are tagged a base */
+	/* Give all objects which are tagged a base. */
 	for (group = mainvar->group.first; group; group = group->id.next) {
 		if (group->id.tag & LIB_TAG_DOIT) {
-			/* any indirect group should not have been tagged */
+			/* Any indirect group should not have been tagged. */
 			BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0);
 
-			/* BKE_object_add(...) messes with the selection */
+			/* BKE_object_add(...) messes with the selection. */
 			ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2);
 			ob->type = OB_EMPTY;
 
-			BKE_collection_object_add(scene, sc, ob);
-			base = BKE_scene_layer_base_find(sl, ob);
+			BKE_collection_object_add(scene, scene_collection, ob);
+			base = BKE_scene_layer_base_find(scene_layer, ob);
 
 			if (base->flag & BASE_SELECTABLED) {
 				base->flag |= BASE_SELECTED;
@@ -10216,9 +10224,9 @@ static void give_base_to_groups(
 
 			BKE_scene_object_base_flag_sync_from_base(base);
 			DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
-			sl->basact = base;
+			scene_layer->basact = base;
 
-			/* assign the group */
+			/* Assign the group. */
 			ob->dup_group = group;
 			ob->transflag |= OB_DUPLIGROUP;
 			copy_v3_v3(ob->loc, scene->cursor);
@@ -10593,11 +10601,10 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
 	 * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
 	 * here we handle indirect ones and other possible edge-cases. */
 	if (scene) {
-		SceneCollection *sc = get_scene_collection_active_or_create(scene, sl, FILE_ACTIVE_COLLECTION);
-		give_base_to_objects(mainvar, scene, sl, sc, curlib, flag);
+		give_base_to_objects(mainvar, scene, sl, curlib, flag);
 
 		if (flag & FILE_GROUP_INSTANCE) {
-			give_base_to_groups(mainvar, scene, sl, sc, curlib, flag);
+			give_base_to_groups(mainvar, scene, sl, curlib, flag);
 		}
 	}
 	else {



More information about the Bf-blender-cvs mailing list