[Bf-blender-cvs] [574a7da] id-remap: Fix several issues, add a quick and dirty new action in Outliner to remap IDs.

Bastien Montagne noreply at git.blender.org
Tue Jul 21 22:43:07 CEST 2015


Commit: 574a7da03ebc9c071384134e176aa39bc4015029
Author: Bastien Montagne
Date:   Tue Jul 21 22:26:13 2015 +0200
Branches: id-remap
https://developer.blender.org/rB574a7da03ebc9c071384134e176aa39bc4015029

Fix several issues, add a quick and dirty new action in Outliner to remap IDs.

We have to take care of Object->data aside from main foreach loop, since we can
only replace that pointer if object is **not** in Edit mode!

Also, added a "Remap" action to ID context menu of outliner. This is **very far**
from nice and pretty code/feature, but it allows to quickly test the code.

Only did very quick tests with meshes so far...

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

M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/library_query.c
M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c
M	source/blender/editors/space_outliner/outliner_tools.c

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

diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index f76694e..77f4638 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -896,23 +896,44 @@ static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int UNUS
 	ID *old_id = ((void **)user_data)[1];
 	ID *new_id = ((void **)user_data)[2];
 	ID *id = ((void **)user_data)[3];
+	int skipped = GET_INT_FROM_POINTER(((void **)user_data)[4]);
+
+	/* 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)) {
+				skipped++;
+			}
+			else {
+				ob->data = new_id;
+				DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
+			}
+		}
+	}
 
 	if (*id_p == old_id) {
 		*id_p = new_id;
 		DAG_id_tag_update_ex(bmain, id, OB_RECALC_OB | OB_RECALC_DATA);
 	}
 
+	((void **)user_data)[4] = SET_INT_IN_POINTER(skipped);
+
 	return true;
 }
 
 /** Replace all references in .blend file to \a old_id by \a new_id. */
 void BKE_libblock_remap(Main *bmain, ID *old_id, ID *new_id)
 {
-	void *user_data[4] = {(void *)bmain, (void *)old_id, (void *)new_id, NULL};
+	void *user_data[5] = {(void *)bmain, (void *)old_id, (void *)new_id, NULL, SET_INT_IN_POINTER(0)};
 	ListBase *lb_array[MAX_LIBARRAY];
+	int skipped;
 	int i;
 
 	BLI_assert(GS(old_id->name) == GS(new_id->name));
+	BLI_assert(old_id != new_id);
 
 	printf("%s: %s replaced by %s\n", __func__, old_id->name, new_id->name);
 
@@ -941,21 +962,26 @@ void BKE_libblock_remap(Main *bmain, ID *old_id, ID *new_id)
 	}
 
 	/* All ID 'users' do not actually incref it, so we just assume all uses of this ID have been cleared... */
-	if ((old_id->us > 1) && (old_id->flag & LIB_FAKEUSER)) {
-		new_id->us += old_id->us - 1;
-		if (new_id->flag & LIB_INDIRECT) {
-			new_id->flag &= ~LIB_INDIRECT;
-			new_id->flag |= LIB_EXTERN;
+	skipped = GET_INT_FROM_POINTER(((void **)user_data)[4]);
+	if (old_id->flag & LIB_FAKEUSER) {
+		BLI_assert(old_id->us - 1 - skipped >= 0);
+		if (old_id->us > 1) {
+			new_id->us += old_id->us - 1 - skipped;
+			if (new_id->flag & LIB_INDIRECT) {
+				new_id->flag &= ~LIB_INDIRECT;
+				new_id->flag |= LIB_EXTERN;
+			}
+			old_id->us = 1 + skipped;
 		}
-		old_id->us = 1;
 	}
-	else if (old_id->us > 0){
-		new_id->us += old_id->us;
+	else if (old_id->us > 0) {
+		BLI_assert(old_id->us - skipped >= 0);
+		new_id->us += old_id->us - skipped;
 		if (new_id->flag & LIB_INDIRECT) {
 			new_id->flag &= ~LIB_INDIRECT;
 			new_id->flag |= LIB_EXTERN;
 		}
-		old_id->us = 0;
+		old_id->us = skipped;
 	}
 
 	/* Full rebuild of DAG! */
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 3d5065d..6d2e2f1 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -229,7 +229,6 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 		case ID_OB:
 		{
 			Object *object = (Object *) id;
-			CALLBACK_INVOKE_ID(object->data, IDWALK_NOP);
 			CALLBACK_INVOKE(object->parent, IDWALK_NOP);
 			CALLBACK_INVOKE(object->track, IDWALK_NOP);
 			CALLBACK_INVOKE(object->proxy, IDWALK_NOP);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index d4fee5f..75b52db 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -230,7 +230,7 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
 }
 
 void item_rename_cb(bContext *C, Scene *UNUSED(scene), TreeElement *te,
-                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	ARegion *ar = CTX_wm_region(C);
 	ReportList *reports = CTX_wm_reports(C); // XXX
@@ -370,7 +370,7 @@ int common_restrict_check(bContext *C, Object *ob)
 /* Toggle Visibility ---------------------------------------- */
 
 void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te,
-                                 TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                 TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Base *base = (Base *)te->directdata;
 	Object *ob = (Object *)tselem->id;
@@ -386,7 +386,7 @@ void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te,
 }
 
 void group_toggle_visibility_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te),
-                                TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Group *group = (Group *)tselem->id;
 	restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_VIEW);
@@ -425,7 +425,7 @@ void OUTLINER_OT_visibility_toggle(wmOperatorType *ot)
 /* Toggle Selectability ---------------------------------------- */
 
 void object_toggle_selectability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
-                                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Base *base = (Base *)te->directdata;
 	
@@ -436,7 +436,7 @@ void object_toggle_selectability_cb(bContext *UNUSED(C), Scene *scene, TreeEleme
 }
 
 void group_toggle_selectability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te),
-                                   TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                   TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Group *group = (Group *)tselem->id;
 	restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_SELECT);
@@ -473,7 +473,7 @@ void OUTLINER_OT_selectability_toggle(wmOperatorType *ot)
 /* Toggle Renderability ---------------------------------------- */
 
 void object_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
-                                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                    TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Base *base = (Base *)te->directdata;
 	
@@ -484,7 +484,7 @@ void object_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeEleme
 }
 
 void group_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te),
-                                   TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+                                   TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 {
 	Group *group = (Group *)tselem->id;
 	restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_RENDER);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 54c0e4b..b256927 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -191,24 +191,24 @@ int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, boo
 
 /* outliner_edit.c ---------------------------------------------- */
 
-void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb, 
-                                  void (*operation_cb)(struct bContext *C, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *));
+void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
+                                  void (*operation_cb)(struct bContext *C, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *, void *));
 
 int common_restrict_check(struct bContext *C, struct Object *ob);
 
 int outliner_has_one_flag(struct SpaceOops *soops, ListBase *lb, short flag, const int curlevel);
 void outliner_set_flag(struct SpaceOops *soops, ListBase *lb, short flag, short set);
 
-void object_toggle_visibility_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-void object_toggle_selectability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-void object_toggle_renderability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
+void object_toggle_visibility_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void object_toggle_selectability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void object_toggle_renderability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
 
 
-void group_toggle_visibility_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-void group_toggle_selectability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-void group_toggle_renderability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
+void group_toggle_visibility_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void group_toggle_selectability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void group_toggle_renderability_cb(stru

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list