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:
-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);