[Bf-blender-cvs] [7547c6a] master: ID-Remap, step two: add some user-level tools.

Bastien Montagne noreply at git.blender.org
Wed Jun 22 18:11:53 CEST 2016


Commit: 7547c6a250cd6f36c9894605b822380a1261febf
Author: Bastien Montagne
Date:   Wed Jun 22 18:05:55 2016 +0200
Branches: master
https://developer.blender.org/rB7547c6a250cd6f36c9894605b822380a1261febf

ID-Remap, step two: add some user-level tools.

This commit adds operators and Outliner menu entries to reload or relocate a library,
and to delete or replace a datablock.

RNA ID API is also extended to allow ID deletion and remapping from python.

Review task: D2027 (https://developer.blender.org/D2027).
Reviewed by campbellbarton, thanks a bunch.

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

M	source/blender/blenloader/BLO_readfile.h
M	source/blender/blenloader/intern/readfile.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
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/windowmanager/intern/wm_files_link.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/wm_files.h

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

diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index bf47682..c85cf12 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -100,7 +100,8 @@ struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, con
 struct ID *BLO_library_link_named_part_ex(
         struct Main *mainl, BlendHandle **bh,
         const short idcode, const char *name, const short flag,
-        struct Scene *scene, struct View3D *v3d);
+        struct Scene *scene, struct View3D *v3d,
+        const bool use_placeholders, const bool force_indirect);
 void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d);
 
 void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d8768f1..8e69408 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -113,6 +113,7 @@
 
 #include "BKE_action.h"
 #include "BKE_armature.h"
+#include "BKE_blender_version.h"
 #include "BKE_brush.h"
 #include "BKE_cloth.h"
 #include "BKE_constraint.h"
@@ -8287,6 +8288,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	blo_do_versions_260(fd, lib, main);
 	blo_do_versions_270(fd, lib, main);
 
+	main->versionfile = BLENDER_VERSION;
+	main->subversionfile = BLENDER_SUBVERSION;
+
 	/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
 	/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
 
@@ -9707,13 +9711,13 @@ static void give_base_to_groups(
 	}
 }
 
-static ID *create_placeholder(Main *mainvar, const char *idname, const short tag)
+static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const short tag)
 {
-	const short idcode = GS(idname);
 	ListBase *lb = which_libbase(mainvar, idcode);
 	ID *ph_id = BKE_libblock_alloc_notest(idcode);
 
-	memcpy(ph_id->name, idname, sizeof(ph_id->name));
+	*((short *)ph_id->name) = idcode;
+	BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
 	BKE_libblock_init_empty(ph_id);
 	ph_id->lib = mainvar->curlib;
 	ph_id->tag = tag | LIB_TAG_MISSING;
@@ -9728,7 +9732,9 @@ static ID *create_placeholder(Main *mainvar, const char *idname, const short tag
 
 /* 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 short idcode, const char *name)
+static ID *link_named_part(
+        Main *mainl, FileData *fd, const short idcode, const char *name,
+        const bool use_placeholders, const bool force_indirect)
 {
 	BHead *bhead = find_bhead_from_code_name(fd, idcode, name);
 	ID *id;
@@ -9739,7 +9745,7 @@ static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const
 		id = is_yet_read(fd, mainl, bhead);
 		if (id == NULL) {
 			/* not read yet */
-			read_libblock(fd, mainl, bhead, LIB_TAG_TESTEXT, &id);
+			read_libblock(fd, mainl, bhead, force_indirect ? LIB_TAG_TESTIND : LIB_TAG_TESTEXT, &id);
 
 			if (id) {
 				/* sort by name in list */
@@ -9752,18 +9758,22 @@ static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const
 			if (G.debug)
 				printf("append: already linked\n");
 			oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
-			if (id->tag & LIB_TAG_INDIRECT) {
+			if (!force_indirect && (id->tag & LIB_TAG_INDIRECT)) {
 				id->tag &= ~LIB_TAG_INDIRECT;
 				id->tag |= LIB_TAG_EXTERN;
 			}
 		}
 	}
+	else if (use_placeholders) {
+		/* XXX flag part is weak! */
+		id = create_placeholder(mainl, idcode, name, force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_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;
 }
@@ -9835,9 +9845,9 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
 
 static ID *link_named_part_ex(
         Main *mainl, FileData *fd, const short idcode, const char *name, const short flag,
-		Scene *scene, View3D *v3d)
+		Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
 {
-	ID *id = link_named_part(mainl, fd, idcode, name);
+	ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect);
 
 	if (id && (GS(id->name) == ID_OB)) {	/* loose object: give a base */
 		link_object_postprocess(id, scene, v3d, flag);
@@ -9863,7 +9873,7 @@ static ID *link_named_part_ex(
 ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcode, const char *name)
 {
 	FileData *fd = (FileData*)(*bh);
-	return link_named_part(mainl, fd, idcode, name);
+	return link_named_part(mainl, fd, idcode, name, false, false);
 }
 
 /**
@@ -9877,15 +9887,18 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod
  * \param flag Options for linking, used for instantiating.
  * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done).
  * \param v3d The active View3D (only to define active layers for instantiated 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_TAG_INDIRECT (used in reload context only).
  * \return the linked ID when found.
  */
 ID *BLO_library_link_named_part_ex(
         Main *mainl, BlendHandle **bh,
         const short idcode, const char *name, 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, idcode, name, flag, scene, v3d);
+	return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d, use_placeholders, force_indirect);
 }
 
 static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -9925,7 +9938,7 @@ static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *i
 
 		/* Generate a placeholder for this ID (simplified version of read_libblock actually...). */
 		if (r_id) {
-			*r_id = is_valid ? create_placeholder(mainvar, id->name, id->tag) : NULL;
+			*r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) : NULL;
 		}
 	}
 }
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 8cee696..687869a 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -29,17 +29,23 @@
  *  \ingroup spoutliner
  */
 
+#include <string.h>
+
 #include "MEM_guardedalloc.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_group_types.h"
+#include "DNA_ID.h"
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
 #include "DNA_material_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
+#include "BLI_path_util.h"
 #include "BLI_mempool.h"
+#include "BLI_stack.h"
+#include "BLI_string.h"
 
 #include "BLT_translation.h"
 
@@ -47,7 +53,9 @@
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
+#include "BKE_idcode.h"
 #include "BKE_library.h"
+#include "BKE_library_remap.h"
 #include "BKE_main.h"
 #include "BKE_outliner_treehash.h"
 #include "BKE_report.h"
@@ -55,6 +63,8 @@
 #include "BKE_material.h"
 #include "BKE_group.h"
 
+#include "../blenloader/BLO_readfile.h"
+
 #include "ED_object.h"
 #include "ED_outliner.h"
 #include "ED_screen.h"
@@ -70,6 +80,9 @@
 
 #include "RNA_access.h"
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "GPU_material.h"
 
 #include "outliner_intern.h"
 
@@ -291,64 +304,294 @@ void OUTLINER_OT_item_rename(wmOperatorType *ot)
 	ot->poll = ED_operator_outliner_active;
 }
 
-/* Library delete --------------------------------------------------- */
+/* ID delete --------------------------------------------------- */
 
-static void lib_delete(bContext *C, TreeElement *te, TreeStoreElem *tselem, ReportList *reports)
+static void id_delete(bContext *C, TreeElement *te, TreeStoreElem *tselem)
 {
-	Library *lib = (Library *)tselem->id;
-	ListBase *lbarray[MAX_LIBARRAY];
-	int a;
+	Main *bmain = CTX_data_main(C);
+	ID *id = tselem->id;
 
-	BLI_assert(te->idcode == ID_LI && lib != NULL);
+	BLI_assert(te->idcode != 0 && id != NULL);
+	BLI_assert(te->idcode != ID_LI || ((Library *)id)->parent == NULL);
 	UNUSED_VARS_NDEBUG(te);
 
-	/* We simply set all ID from given lib (including lib itself) to zero user count.
-	 * It is not possible to do a proper cleanup without a save/reload in current master. */
-	a = set_listbasepointers(CTX_data_main(C), lbarray);
-	while (a--) {
-		ListBase *lb = lbarray[a];
-		ID *id;
-
-		for (id = lb->first; id; id = id->next) {
-			if (id->lib == lib) {
-				id_fake_user_clear(id);
-				id->us = 0;
+	BKE_libblock_delete(bmain, id);
+
+	WM_event_add_notifier(C, NC_WINDOW, NULL);
+}
+
+void id_delete_cb(
+        bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem,
+        void *UNUSED(user_data))
+{
+	id_delete(C, te, tselem);
+}
+
+static int outliner_id_delete_invoke_do(bContext *C, ReportList *reports, TreeElement *te, const float mval[2])
+{
+	if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+		TreeStoreElem *tselem = TREESTORE(te);
+
+		if (te->idcode != 0 && tselem->id) {
+			if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) {
+				BKE_reportf(reports, RPT_ERROR_INVALID_INPUT,
+				            "Cannot delete indirectly linked library '%s'", ((Library *)tselem->id)->filepath);
+				return OPERATOR_CANCELLED;
+			}
+			id_delete(C, te, tselem);
+			return OPERATOR_FINISHED;
+		}
+	}
+	else {
+		for (te = te->subtree.first; te; te = te->next) {
+			int ret;
+			if ((ret = outliner_id_delete_invoke_do(C, reports, te, mval))) {
+				return ret;
 			}
 		}
 	}
 
-	BKE_reportf(reports, RPT_WARNING,
-	            "Please save and reload .b

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list