[Bf-blender-cvs] [a508d49] id-remap: Better handling of missing datablocks in reload case.

Bastien Montagne noreply at git.blender.org
Mon Sep 21 21:58:52 CEST 2015


Commit: a508d49e330d2e26bbecaf68aff7d57d83abd17b
Author: Bastien Montagne
Date:   Mon Sep 21 21:57:54 2015 +0200
Branches: id-remap
https://developer.blender.org/rBa508d49e330d2e26bbecaf68aff7d57d83abd17b

Better handling of missing datablocks in reload case.

We need to generate a placeholder for those here... Also, enhances handling
of direct/indirect flags & co.

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

M	source/blender/blenloader/BLO_readfile.h
M	source/blender/blenloader/intern/readfile.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index e65c4dd..68e0278 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -243,12 +243,14 @@ struct ID *BLO_library_link_named_part(
  * \param flag Options for linking, used for instancing.
  * \param scene The scene in which to instanciate objects/groups (if NULL, no instanciation is done).
  * \param v3d The active View3D (only to define active layers for instanced objects & groups, can be NULL).
+ * \param use_placeholders If true, generate a placeholder (empty ID) if not found in current lib file.
+ * \param force_indirect If true, force loaded ID to be tagged as LIB_INDIRECT (used in reload context only).
  * \return the appended ID when found.
  */
 struct ID *BLO_library_link_named_part_ex(
         struct Main *mainl, BlendHandle **bh,
         const char *idname, const int idcode, const short flag,
-        struct Scene *scene, struct View3D *v3d);
+        struct Scene *scene, struct View3D *v3d, const bool use_placeholders, const bool force_indirect);
 
 /**
  * Finalize linking from a given .blend file (library).
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 22e6a66..97e2d39 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9584,7 +9584,9 @@ static ID *create_placeholder(Main *mainvar, const short idcode, const char *nam
 
 /* returns true if the item was found
  * but it may already have already been appended/linked */
-static ID *link_named_part(Main *mainl, FileData *fd, const char *idname, const short idcode)
+static ID *link_named_part(
+        Main *mainl, FileData *fd, const char *idname, const short idcode,
+        const bool use_placeholders, const bool force_indirect)
 {
 	BHead *bhead = find_bhead_from_code_name(fd, idcode, idname);
 	ID *id;
@@ -9593,7 +9595,7 @@ static ID *link_named_part(Main *mainl, FileData *fd, const char *idname, const
 		id = is_yet_read(fd, mainl, bhead);
 		if (id == NULL) {
 			/* not read yet */
-			read_libblock(fd, mainl, bhead, LIB_TESTEXT, &id);
+			read_libblock(fd, mainl, bhead, force_indirect ? LIB_TESTIND : LIB_TESTEXT, &id);
 
 			if (id) {
 				/* sort by name in list */
@@ -9606,18 +9608,22 @@ static ID *link_named_part(Main *mainl, FileData *fd, const char *idname, const
 			if (G.debug)
 				printf("append: already linked\n");
 			oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
-			if (id->flag & LIB_INDIRECT) {
-				id->flag -= LIB_INDIRECT;
+			if (!force_indirect && (id->flag & LIB_INDIRECT)) {
+				id->flag &= ~LIB_INDIRECT;
 				id->flag |= LIB_EXTERN;
 			}
 		}
 	}
+	else if (use_placeholders) {
+		/* XXX flag part is weak! */
+		id = create_placeholder(mainl, idcode, idname, force_indirect ? LIB_INDIRECT : LIB_EXTERN);
+	}
 	else {
 		id = NULL;
 	}
 	
 	/* if we found the id but the id is NULL, this is really bad */
-	BLI_assert((bhead != NULL) == (id != NULL));
+	BLI_assert(!((bhead != NULL) && (id == NULL)));
 	
 	return id;
 }
@@ -9645,9 +9651,9 @@ void BLO_library_link_all(Main *mainl, BlendHandle *bh)
 
 static ID *link_named_part_ex(
         Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag,
-		Scene *scene, View3D *v3d)
+		Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
 {
-	ID *id = link_named_part(mainl, fd, idname, idcode);
+	ID *id = link_named_part(mainl, fd, idname, idcode, use_placeholders, force_indirect);
 
 	if (id && (GS(id->name) == ID_OB)) {	/* loose object: give a base */
 		if (scene) {
@@ -9688,15 +9694,15 @@ static ID *link_named_part_ex(
 ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const char *idname, const int idcode)
 {
 	FileData *fd = (FileData*)(*bh);
-	return link_named_part(mainl, fd, idname, idcode);
+	return link_named_part(mainl, fd, idname, idcode, false, false);
 }
 
 ID *BLO_library_link_named_part_ex(
         Main *mainl, BlendHandle **bh, const char *idname, const int idcode, const short flag,
-        Scene *scene, View3D *v3d)
+        Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
 {
 	FileData *fd = (FileData*)(*bh);
-	return link_named_part_ex(mainl, fd, idname, idcode, flag, scene, v3d);
+	return link_named_part_ex(mainl, fd, idname, idcode, flag, scene, v3d, use_placeholders, force_indirect);
 }
 
 static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 712c477..139dc07 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2677,7 +2677,8 @@ static WMLinkAppendDataItem *wm_link_append_data_item_add(
 }
 
 static void wm_link_do(
-        WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d)
+        WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d,
+        const bool use_placeholders, const bool force_indirect)
 {
 	Main *mainl;
 	BlendHandle *bh;
@@ -2738,7 +2739,9 @@ static void wm_link_do(
 
 				BLI_BITMAP_ENABLE(done_items, item_idx);
 
-				if ((new_id = BLO_library_link_named_part_ex(mainl, &bh, item->name, idcode, flag, scene, v3d))) {
+				new_id = BLO_library_link_named_part_ex(
+				             mainl, &bh, item->name, idcode, flag, scene, v3d, use_placeholders, force_indirect);
+				if (new_id) {
 					/* If the link is sucessful, clear item's libs 'todo' flags.
 					 * This avoids trying to link same item with other libraries to come. */
 					BLI_BITMAP_SET_ALL(item->libraries, false, lapp_data->num_libraries);
@@ -2886,7 +2889,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 	/* XXX We'd need re-entrant locking on Main for this to work... */
 	/* BKE_main_lock(bmain); */
 
-	wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C));
+	wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C), false, false);
 
 	/* BKE_main_unlock(bmain); */
 
@@ -3087,7 +3090,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, const bool reloa
 			BKE_main_unlock(bmain);
 
 			/* We do not want any instanciation here! */
-			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL);
+			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL, true, true);
 
 			BKE_main_lock(bmain);
 
@@ -3107,6 +3110,8 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, const bool reloa
 				ID *old_id = item->customdata;
 				ID *new_id = item->new_id;
 
+				/* Since we asked for placeholders in case of missing IDs, we expect to always get a valid one. */
+				BLI_assert(new_id);
 				if (new_id) {
 					printf("before remap, old_id users: %d (%p), new_id users: %d (%p)\n", old_id->us, old_id->lib, new_id->us, new_id->lib);
 					/* Note that here, we also want to replace indirect usages. */
@@ -3230,7 +3235,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, const bool reloa
 			BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, true);
 
 			/* We do not want any instanciation here! */
-			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL);
+			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL, false, false);
 
 			for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
 				WMLinkAppendDataItem *item = itemlink->link;




More information about the Bf-blender-cvs mailing list