[Bf-blender-cvs] [49156ee] lib-link-rework-temp: Serious rework (again) of append/link code, to make it more generic.

Bastien Montagne noreply at git.blender.org
Thu Sep 17 20:58:33 CEST 2015


Commit: 49156ee77b97a229365dbc51e1da9a29d290ea4b
Author: Bastien Montagne
Date:   Thu Sep 17 20:45:51 2015 +0200
Branches: lib-link-rework-temp
https://developer.blender.org/rB49156ee77b97a229365dbc51e1da9a29d290ea4b

Serious rework (again) of append/link code, to make it more generic.

Making the code in WM area more generic (will be used by relocate libs feature too in future).
And multi-append/link shall no more close & re-open lib files for each and every idcode!

Also, serious cleanup of BLO_append_... API (renamed BLO_link_..., since it links and never appends!),
main real changes there are removing the bContext arg in favor of scene/v3d (a bit more verbose, but does
not requires a valid context anymore to be able to instanciate ob/groups!). And logic behind instanciating
or not has been simplified, previous code was really obscure and sometimes redondant, from quick tests
it still works as expected.

This is temp branch for until 2.76 is over, shall be merged in master asap then.

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

M	source/blender/blenkernel/intern/blender.c
M	source/blender/blenloader/BLO_readfile.h
M	source/blender/blenloader/intern/readfile.c
M	source/blender/python/intern/bpy_library.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/gameengine/Converter/KX_BlenderSceneConverter.cpp

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

diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 0923ac7..7faa89d 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -1068,11 +1068,11 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports)
 	BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, true);
 	
 	/* here appending/linking starts */
-	mainl = BLO_library_append_begin(bmain, &bh, libname);
+	mainl = BLO_library_link_begin(bmain, &bh, libname);
 	
-	BLO_library_append_all(mainl, bh);
+	BLO_library_link_all(mainl, bh);
 
-	BLO_library_append_end(C, mainl, &bh, 0, 0);
+	BLO_library_link_end(mainl, &bh, 0, scene, CTX_wm_view3d(C));
 	
 	/* mark all library linked objects to be updated */
 	BKE_main_lib_objects_recalc_all(bmain);
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 77bdb99..e65c4dd 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -44,6 +44,7 @@ struct MemFile;
 struct ReportList;
 struct Scene;
 struct UserDef;
+struct View3D;
 struct bContext;
 struct BHead;
 struct FileData;
@@ -213,13 +214,13 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha
  * \param filepath Used for relative linking, copied to the lib->name
  * \return the library Main, to be passed to BLO_library_append_named_part as mainl.
  */
-struct Main *BLO_library_append_begin(
+struct Main *BLO_library_link_begin(
         struct Main *mainvar, BlendHandle **bh,
         const char *filepath);
 
 
 /**
- * Link/Append a named datablock from an external blend file.
+ * Link a named datablock from an external blend file.
  *
  * \param mainl The main database to link from (not the active one).
  * \param bh The blender file handle.
@@ -227,29 +228,41 @@ struct Main *BLO_library_append_begin(
  * \param idcode The kind of datablock to link.
  * \return the appended ID when found.
  */
-struct ID *BLO_library_append_named_part(
+struct ID *BLO_library_link_named_part(
         struct Main *mainl, BlendHandle **bh,
         const char *idname, const int idcode);
 
 /**
- * Link/Append a named datablock from an external blend file.
- * optionally instance the object in the scene when the flags are set.
+ * Link a named datablock from an external blend file.
+ * optionally instance the object/group in the scene when the flags are set.
  *
- * \param C The context, when NULL instancing object in the scene isn't done.
  * \param mainl The main database to link from (not the active one).
  * \param bh The blender file handle.
  * \param idname The name of the datablock (without the 2 char ID prefix)
  * \param idcode The kind of datablock to link.
  * \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).
  * \return the appended ID when found.
  */
-struct ID *BLO_library_append_named_part_ex(
-        const struct bContext *C, struct Main *mainl, BlendHandle **bh,
-        const char *idname, const int idcode, const short flag);
+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);
 
-void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag);
+/**
+ * Finalize linking from a given .blend file (library).
+ * Optionally instance the indirect object/group in the scene when the flags are set.
+ *
+ * \param mainl The main database to link from (not the active one).
+ * \param bh The blender file handle (WARNING! may be freed by this function!).
+ * \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).
+ */
+void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d);
 
-void BLO_library_append_all(struct Main *mainl, BlendHandle *bh);
+void BLO_library_link_all(struct Main *mainl, BlendHandle *bh);
 
 void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
 
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 55cadae..dbb0b76 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9461,101 +9461,86 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
 {
 	Scene *sce;
 	
-	for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
-		if (BKE_scene_base_find(sce, ob))
-			return 1;
+	for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
+		if (BKE_scene_base_find(sce, ob)) {
+			return true;
+		}
 	}
 	
-	return 0;
+	return false;
 }
 
-static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const bool is_link, const short active_lay)
+static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Library *lib, const short flag)
 {
 	Object *ob;
 	Base *base;
-	const bool is_group_append = (is_link == false && idcode == ID_GR);
+	const unsigned int active_lay = (flag & FILE_ACTIVELAY) ? BKE_screen_view3d_layer_active(v3d, scene) : 0;
+	const bool is_link = (flag & FILE_LINK) != 0;
+
+	BLI_assert(scene);
 
 	/* give all objects which are LIB_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.flag & LIB_INDIRECT) {
-			/* IF below is quite confusing!
-			 * if we are appending, but this object wasnt just added along with a group,
-			 * then this is already used indirectly in the scene somewhere else and we didnt just append it.
-			 *
-			 * (ob->id.flag & LIB_PRE_EXISTING)==0 means that this is a newly appended object - Campbell */
-			if (is_group_append==0 || (ob->id.flag & LIB_PRE_EXISTING)==0) {
-				bool do_it = false;
-				
-				if (ob->id.us == 0) {
-					do_it = true;
-				}
-				else if (idcode==ID_GR) {
-					if ((is_link == false) && (ob->id.lib == lib)) {
-						if ((ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) {
-							do_it = true;
-						}
-					}
-				}
-				else {
-					/* when appending, make sure any indirectly loaded objects
-					 * get a base else they cant be accessed at all [#27437] */
-					if ((is_link == false) && (ob->id.lib == lib)) {
-						/* we may be appending from a scene where we already
-						 *  have a linked object which is not in any scene [#27616] */
-						if ((ob->id.flag & LIB_PRE_EXISTING)==0) {
-							if (object_in_any_scene(mainvar, ob)==0) {
-								do_it = true;
-							}
-						}
-					}
-				}
-				
-				if (do_it) {
-					base = MEM_callocN(sizeof(Base), "add_ext_base");
-					BLI_addtail(&sce->base, base);
-					
-					if (active_lay) ob->lay = sce->lay;
-					
-					base->lay = ob->lay;
-					base->object = ob;
-					base->flag = ob->flag;
+		if ((ob->id.flag & LIB_INDIRECT) && (ob->id.flag & LIB_PRE_EXISTING) == 0) {
+			bool do_it = false;
 
-					CLAMP_MIN(ob->id.us, 0);
-					ob->id.us += 1;
-					
-					ob->id.flag -= LIB_INDIRECT;
-					ob->id.flag |= LIB_EXTERN;
+			if (ob->id.us == 0) {
+				do_it = true;
+			}
+			else if (!is_link && (ob->id.lib == lib) && (object_in_any_scene(mainvar, ob) == 0)) {
+				/* When appending, make sure any indirectly loaded objects get a base, else they cant be accessed at all
+				 * (see T27437). */
+				do_it = true;
+			}
+
+			if (do_it) {
+				base = MEM_callocN(sizeof(Base), __func__);
+				BLI_addtail(&scene->base, base);
+
+				if (active_lay) {
+					ob->lay = active_lay;
 				}
+
+				base->lay = ob->lay;
+				base->object = ob;
+				base->flag = ob->flag;
+
+				CLAMP_MIN(ob->id.us, 0);
+				ob->id.us += 1;
+
+				ob->id.flag &= ~LIB_INDIRECT;
+				ob->id.flag |= LIB_EXTERN;
 			}
 		}
 	}
 }
 
-static void give_base_to_groups(Main *mainvar, Scene *scene)
+static void give_base_to_groups(
+        Main *mainvar, Scene *scene, View3D *v3d, Library *UNUSED(lib), const short UNUSED(flag))
 {
 	Group *group;
-	
+	Base *base;
+	Object *ob;
+	const unsigned int active_lay = BKE_screen_view3d_layer_active(v3d, scene);
+
 	/* give all objects which are tagged a base */
 	for (group = mainvar->group.first; group; group = group->id.next) {
 		if (group->id.flag & LIB_DOIT) {
-			Base *base;
-			Object *ob;
-
 			/* any indirect group should not have been tagged */
-			BLI_assert((group->id.flag & LIB_INDIRECT)==0);
-			
+			BLI_assert((group->id.flag & LIB_INDIRECT) == 0);
+
 			/* BKE_object_add(...) messes with the selection */
 			ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2);
 			ob->type = OB_EMPTY;
-			ob->lay = scene->lay;
-			
+			ob->lay = active_lay;
+
 			/* assign the base */
 			base = BKE_scene_base_add(scene, ob);
 			base->flag |= SELECT;
-			base->object->flag= base->flag;
+			base->object->flag = base->flag;
 			DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 			scene->basact = base;
-			
+
 			/* assign the group */
 			ob->dup_group = group;
 			ob->transflag |= OB_DUPLIGROUP;
@@ -9566,7 +9551,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
 
 /* returns true if the item was found
  * but it may already have already been appended/linked */
-static ID *append_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)
 {
 	BHead *bhead = find_bhead_from_code_name(fd, idcode, idname);
 	ID *id;
@@ -9605,7 +9590,7 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons
 }
 
 /* simple reader for copy/paste buffers */
-void BLO_library_append_all(Main *mainl, BlendHandle *bh)
+void BLO_library_link_all(Main *mainl, BlendHandle *bh)
 {
 	FileData *

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list