Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-10-12 16:07:07 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-10-12 16:07:07 +0300
commit2e8fcac15db50713ae3552e535be91ba331ad4bc (patch)
treef67ee95800317f02d719e41d8559df4cfa32c3ab
parentd24bafa0d5b0f1f833145524b7073a513a272b17 (diff)
Cleanup & rework of BLO_linking code.
This commits does mostly two things: * Get rid of bContext parameter: I can see no real good reason to pass such a high-level data to such low-level code... It also makes it more difficult to call when you do not have a context available. * Cleanup the instantiating part. Last point is the most risky - previous code was sometimes quite confusing and hard to follow, from tests nothing behaves differently in new code, but some hidden corner case may show up. Anyway, no change in behavior is expected from this commit, if it happens please file a bugreport!
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenloader/BLO_readfile.h8
-rw-r--r--source/blender/blenloader/intern/readfile.c213
-rw-r--r--source/blender/python/intern/bpy_library.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c6
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp2
6 files changed, 104 insertions, 129 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index e0f2219d5f8..f1300697b85 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -1073,7 +1073,7 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports)
BLO_library_link_all(mainl, bh);
- BLO_library_link_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 eda76ec8402..c203f651680 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;
@@ -97,9 +98,10 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha
struct Main *BLO_library_link_begin(struct Main *mainvar, BlendHandle **bh, const char *filepath);
struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, const char *idname, const int idcode);
struct ID *BLO_library_link_named_part_ex(
- const struct bContext *C, struct Main *mainl, BlendHandle **bh,
- const char *idname, const int idcode, const short flag);
-void BLO_library_link_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag);
+ struct Main *mainl, BlendHandle **bh,
+ const char *idname, const int idcode, const short flag,
+ struct Scene *scene, struct View3D *v3d);
+void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d);
void BLO_library_link_all(struct Main *mainl, BlendHandle *bh);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 721878db733..470d45f1fea 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9536,93 +9536,77 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
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;
@@ -9694,33 +9678,33 @@ void BLO_library_link_all(Main *mainl, BlendHandle *bh)
}
}
-
-static ID *link_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag)
+static ID *link_named_part_ex(
+ Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag,
+ Scene *scene, View3D *v3d)
{
ID *id = link_named_part(mainl, fd, idname, idcode);
if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */
- Scene *scene = CTX_data_scene(C); /* can be NULL */
if (scene) {
Base *base;
Object *ob;
-
- base= MEM_callocN(sizeof(Base), "app_nam_part");
+
+ base = MEM_callocN(sizeof(Base), "app_nam_part");
BLI_addtail(&scene->base, base);
-
+
ob = (Object *)id;
-
+
/* link at active layer (view3d if available in context, else scene one */
- if ((flag & FILE_ACTIVELAY)) {
- View3D *v3d = CTX_wm_view3d(C);
+ if (flag & FILE_ACTIVELAY) {
ob->lay = BKE_screen_view3d_layer_active(v3d, scene);
}
-
+
ob->mode = OB_MODE_OBJECT;
base->lay = ob->lay;
base->object = ob;
+ base->flag = ob->flag;
ob->id.us++;
-
+
if (flag & FILE_AUTOSELECT) {
base->flag |= SELECT;
base->object->flag = base->flag;
@@ -9729,11 +9713,11 @@ static ID *link_named_part_ex(const bContext *C, Main *mainl, FileData *fd, cons
}
}
else if (id && (GS(id->name) == ID_GR)) {
- /* tag as needing to be instanced */
+ /* tag as needing to be instantiated */
if (flag & FILE_GROUP_INSTANCE)
id->flag |= LIB_DOIT;
}
-
+
return id;
}
@@ -9756,20 +9740,21 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const char *idnam
* Link a named datablock from an external blend file.
* Optionally instantiate the object/group in the scene when the flags are set.
*
- * \param C The context, when NULL instantiating 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 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).
* \return the appended ID when found.
*/
ID *BLO_library_link_named_part_ex(
- const bContext *C, Main *mainl, BlendHandle **bh,
- const char *idname, const int idcode, const short flag)
+ Main *mainl, BlendHandle **bh, const char *idname, const int idcode, const short flag,
+ Scene *scene, View3D *v3d)
{
FileData *fd = (FileData*)(*bh);
- return link_named_part_ex(C, mainl, fd, idname, idcode, flag);
+ return link_named_part_ex(mainl, fd, idname, idcode, flag, scene, v3d);
}
static void link_id_part(FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -9825,71 +9810,58 @@ Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepa
return library_link_begin(mainvar, &fd, filepath);
}
-
-/* Context == NULL signifies not to do any scene manipulation */
-static void library_link_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
+/* scene and v3d may be NULL. */
+static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, View3D *v3d)
{
Main *mainvar;
Library *curlib;
-
+
/* expander now is callback function */
BLO_main_expander(expand_doit_library);
-
+
/* make main consistent */
BLO_expand_main(*fd, mainl);
-
+
/* do this when expand found other libs */
read_libraries(*fd, (*fd)->mainlist);
-
+
curlib = mainl->curlib;
-
+
/* make the lib path relative if required */
if (flag & FILE_RELPATH) {
/* use the full path, this could have been read by other library even */
BLI_strncpy(curlib->name, curlib->filepath, sizeof(curlib->name));
-
+
/* uses current .blend file as reference */
BLI_path_rel(curlib->name, G.main->name);
}
-
+
blo_join_main((*fd)->mainlist);
mainvar = (*fd)->mainlist->first;
MEM_freeN((*fd)->mainlist);
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
-
+
lib_link_all(*fd, mainvar);
lib_verify_nodetree(mainvar, false);
fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */
-
- if (C) {
- Scene *scene = CTX_data_scene(C);
-
- /* give a base to loose objects. If group append, do it for objects too */
- if (scene) {
- const bool is_link = (flag & FILE_LINK) != 0;
- if (idcode == ID_SCE) {
- /* don't instance anything when linking in scenes, assume the scene its self instances the data */
- }
- else {
- give_base_to_objects(mainvar, scene, curlib, idcode, is_link, flag & FILE_ACTIVELAY);
-
- if (flag & FILE_GROUP_INSTANCE) {
- give_base_to_groups(mainvar, scene);
- }
- }
- }
- else {
- printf("library_append_end, scene is NULL (objects wont get bases)\n");
+
+ /* Give a base to loose objects. If group append, do it for objects too.
+ * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
+ * here we handle indirect ones and other possible edge-cases. */
+ if (scene) {
+ give_base_to_objects(mainvar, scene, v3d, curlib, flag);
+
+ if (flag & FILE_GROUP_INSTANCE) {
+ give_base_to_groups(mainvar, scene, v3d, curlib, flag);
}
}
+ else {
+ /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */
+ }
/* clear group instantiating tag */
BKE_main_id_tag_listbase(&(mainvar->group), false);
-
- /* has been removed... erm, why? s..ton) */
- /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
- /* 20041208: put back. It only linked direct, not indirect objects (ton) */
-
+
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
blo_freefiledata(*fd);
@@ -9898,19 +9870,20 @@ static void library_link_end(const bContext *C, Main *mainl, FileData **fd, int
}
/**
- * Finalize the linking process (among other things, ensures remaining needed intantiation is done).
+ * Finalize linking from a given .blend file (library).
+ * Optionally instance the indirect object/group in the scene when the flags are set.
* \note Do not use \a bh after calling this function, it may frees it.
*
- * \param C The context, when NULL instantiating 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 idcode The kind of datablock that has been linked.
- * \param flag Options for for instantiating.
+ * \param bh The blender file handle (WARNING! may be freed by this function!).
+ * \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).
*/
-void BLO_library_link_end(const bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag)
+void BLO_library_link_end(Main *mainl, BlendHandle **bh, short flag, Scene *scene, View3D *v3d)
{
FileData *fd = (FileData*)(*bh);
- library_link_end(C, mainl, &fd, idcode, flag);
+ library_link_end(mainl, &fd, flag, scene, v3d);
*bh = (BlendHandle*)fd;
}
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 74f5dc2bfc8..fb9fecb878f 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -405,7 +405,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
}
else {
Library *lib = mainl->curlib; /* newly added lib, assign before append end */
- BLO_library_link_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
+ BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL);
BLO_blendhandle_close(self->blo_handle);
self->blo_handle = NULL;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 70d7fdbdfd9..aed147344e0 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2656,7 +2656,7 @@ static void wm_link_append_do_libgroup(
}
if (name) {
- BLO_library_link_named_part_ex(C, mainl, &bh, name, idcode, flag);
+ BLO_library_link_named_part_ex(mainl, &bh, name, idcode, flag, CTX_data_scene(C), CTX_wm_view3d(C));
}
else {
if (is_first_run) {
@@ -2680,7 +2680,7 @@ static void wm_link_append_do_libgroup(
curr_idcode = BKE_idcode_from_name(group);
if ((idcode == curr_idcode) && (BLI_path_cmp(curr_libname, libname) == 0)) {
- BLO_library_link_named_part_ex(C, mainl, &bh, name, idcode, flag);
+ BLO_library_link_named_part_ex(mainl, &bh, name, idcode, flag, CTX_data_scene(C), CTX_wm_view3d(C));
}
else if (is_first_run) {
BLI_join_dirfile(path, sizeof(path), curr_libname, group);
@@ -2692,7 +2692,7 @@ static void wm_link_append_do_libgroup(
}
RNA_END;
}
- BLO_library_link_end(C, mainl, &bh, idcode, flag);
+ BLO_library_link_end(mainl, &bh, flag, CTX_data_scene(C), CTX_wm_view3d(C));
BLO_blendhandle_close(bh);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index e0319c5a749..4adfcb50d61 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -918,7 +918,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
load_datablocks(main_tmp, bpy_openlib, path, ID_AC);
}
- BLO_library_link_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
+ BLO_library_link_end(main_tmp, &bpy_openlib, flag, NULL, NULL);
BLO_blendhandle_close(bpy_openlib);