[Bf-blender-cvs] [32ea612] id-remap: Moar cleanup, some fixes towards sanier handling of remap & indirect data...

Bastien Montagne noreply at git.blender.org
Fri Sep 18 18:10:40 CEST 2015


Commit: 32ea612fcc55117359ae7b2f2551f76b21cb6b6b
Author: Bastien Montagne
Date:   Fri Sep 18 18:09:13 2015 +0200
Branches: id-remap
https://developer.blender.org/rB32ea612fcc55117359ae7b2f2551f76b21cb6b6b

Moar cleanup, some fixes towards sanier handling of remap & indirect data...

Proxy are still not correctly handled here though.

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

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/editors/space_outliner/outliner_tools.c
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 85ce132..172ebdf 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -58,8 +58,10 @@ void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void  BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
 
 /* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */
-void BKE_libblock_remap_locked(struct Main *bmain, struct ID *old_id, struct ID *new_id) ATTR_NONNULL();
-void BKE_libblock_remap(struct Main *bmain, struct ID *old_id, struct ID *new_id) ATTR_NONNULL();
+void BKE_libblock_remap_locked(
+        struct Main *bmain, struct ID *old_id, struct ID *new_id, const bool skip_indirect_usage) ATTR_NONNULL();
+void BKE_libblock_remap(
+        struct Main *bmain, struct ID *old_id, struct ID *new_id, const bool skip_indirect_usage) ATTR_NONNULL();
 
 void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
 void id_lib_extern(struct ID *id);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 9b1df04..a3e5fca 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1015,8 +1015,13 @@ typedef struct IDRemap {
 	ID *new_id;
 	ID *id;  /* The ID in which we are replacing old_id by new_id usages. */
 	int skipped;  /* Number of usecase that could not be remapped (e.g.: obdata when in edit mode). */
+	int flag;
 } IDRemap;
 
+enum {
+	ID_REMAP_SKIP_INDIRECT_USAGE  = 1 << 0,
+};
+
 static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int UNUSED(cb_flag))
 {
 	IDRemap *id_remap_data = user_data;
@@ -1024,35 +1029,25 @@ static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int UNUS
 	ID *old_id = id_remap_data->old_id;
 	ID *new_id = id_remap_data->new_id;
 	ID *id = id_remap_data->id;
-
-	/* Special hack in case it's Object->data, this is *not* covered by foreach_ID_link.
-	 * Here we simply do nothing in case we are in edit mode, otherwise we replace the ID! */
-	if (GS(id->name) == ID_OB) {
-		Object *ob = (Object *)id;
-
-		if (ob->data == old_id) {
-			if (BKE_object_is_in_editmode(ob)) {
-				id_remap_data->skipped++;
-			}
-			else {
-				ob->data = new_id;
-				DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
-			}
-		}
-	}
+	const bool skip_indirect_usage = ((id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) && id->lib);
 
 	if (*id_p == old_id) {
-		*id_p = new_id;
-		DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
+		if (skip_indirect_usage) {
+			id_remap_data->skipped++;
+		}
+		else {
+			*id_p = new_id;
+			DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
+		}
 	}
 
 	return true;
 }
 
 /** Replace all references in .blend file to \a old_id by \a new_id. */
-void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id)
+void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id, const bool skip_indirect_usage)
 {
-	IDRemap id_remap_data = {(void *)bmain, (void *)old_id, (void *)new_id, NULL, 0};
+	IDRemap id_remap_data = {(void *)bmain, (void *)old_id, (void *)new_id, NULL};
 	ListBase *lb_array[MAX_LIBARRAY];
 	int skipped;
 	int i;
@@ -1062,17 +1057,41 @@ void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id)
 
 	printf("%s: %s (%p) replaced by %s (%p)\n", __func__, old_id->name, old_id, new_id->name, new_id);
 
+	if (skip_indirect_usage) {
+		id_remap_data.flag |= ID_REMAP_SKIP_INDIRECT_USAGE;
+	}
+
 	i = set_listbasepointers(bmain, lb_array);
 
 	/* Note that this is a very 'bruteforce' approach, maybe we could use some depsgraph to only process
 	 * objects actually using given old_id... But for now this will do. */
 
 	while (i--) {
-		ID *id;
-		for (id = lb_array[i]->first; id; id = id->next) {
-			printf("\tchecking id %s (%p)\n", id->name, id);
+		ID *id = lb_array[i]->first;
+		const bool is_obj = id ? (GS(id->name) == ID_OB) : false;
+
+		for (; id; id = id->next) {
+			/* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for
+			 * the user count handling... */
+			printf("\tchecking id %s (%p, %p)\n", id->name, id, id->lib);
 			id_remap_data.id = id;
 			BKE_library_foreach_ID_link(id, foreach_libblock_remap_callback, (void *)&id_remap_data, IDWALK_NOP);
+
+			/* Special hack in case it's Object->data, this is *not* covered by foreach_ID_link.
+			 * Here we simply do nothing in case we are in edit mode, otherwise we replace the ID! */
+			if (is_obj) {
+				Object *ob = (Object *)id;
+
+				if (ob->data == old_id) {
+					if (id->lib || BKE_object_is_in_editmode(ob)) {
+						id_remap_data.skipped++;
+					}
+					else {
+						ob->data = new_id;
+						DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
+					}
+				}
+			}
 		}
 	}
 
@@ -1104,11 +1123,11 @@ void BKE_libblock_remap_locked(Main *bmain, ID *old_id, ID *new_id)
 	DAG_relations_tag_update(bmain);
 }
 
-void BKE_libblock_remap(Main *bmain, ID *old_id, ID *new_id)
+void BKE_libblock_remap(Main *bmain, ID *old_id, ID *new_id, const bool skip_indirect_usage)
 {
 	BKE_main_lock(bmain);
 
-	BKE_libblock_remap_locked(bmain, old_id, new_id);
+	BKE_libblock_remap_locked(bmain, old_id, new_id, skip_indirect_usage);
 
 	BKE_main_unlock(bmain);
 }
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 284b102..7da5fd2 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -1345,7 +1345,7 @@ static void remap_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUS
 	ID *new_id = user_data;
 
 	if (tselem->id && (tselem->id != new_id) && (GS(tselem->id->name) == GS(new_id->name))) {
-		BKE_libblock_remap(CTX_data_main(C), tselem->id, new_id);
+		BKE_libblock_remap(CTX_data_main(C), tselem->id, new_id, true);
 	}
 }
 
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index f74dfe2..d361139 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -336,7 +336,7 @@ static void rna_ID_user_clear(ID *id)
 static void rna_ID_user_remap(ID *id, Main *bmain, ID *new_id)
 {
 	if (GS(id->name) == GS(new_id->name)) {
-		BKE_libblock_remap(bmain, id, new_id);
+		BKE_libblock_remap(bmain, id, new_id, true);  /* Now, do not allow remapping data in linked data from here... */
 	}
 }
 
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 9931b1d..7594cac 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2662,7 +2662,7 @@ static void wm_link_do(
 	BlendHandle *bh;
 	Library *lib;
 
-	const int flag = lapp_data->flag;
+	const short flag = lapp_data->flag;
 
 	BLI_bitmap *done_items = BLI_BITMAP_NEW(lapp_data->num_items, __func__);
 	char (*libname)[FILE_MAX];
@@ -3003,7 +3003,7 @@ static int wm_lib_relocate_exec(bContext *C, wmOperator *op)
 		PropertyRNA *prop;
 		WMLinkAppendData lapp_data;
 		char path[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
-		int flag = 0;
+		short flag = 0;
 
 		if (RNA_boolean_get(op->ptr, "relative_path")) {
 			flag |= FILE_RELPATH;
@@ -3147,7 +3147,7 @@ static int wm_lib_relocate_exec(bContext *C, wmOperator *op)
 				BLI_assert(old_id);
 				if (new_id) {
 					printf("before remap, old_id users: %d, new_id users: %d\n", old_id->us, new_id->us);
-					BKE_libblock_remap_locked(bmain, old_id, new_id);
+					BKE_libblock_remap_locked(bmain, old_id, new_id, true);
 					printf("after remap, old_id users: %d, new_id users: %d\n", old_id->us, new_id->us);
 				}
 			}




More information about the Bf-blender-cvs mailing list