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:
authorCampbell Barton <ideasman42@gmail.com>2020-09-08 08:32:43 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-09-08 09:14:33 +0300
commite467c54d58c88316d959f2481dc7484037a4c0be (patch)
tree4cdf31ed7bac3efeef7f75075920cb23adfaee16
parent48690d967a7731367cda01ab8dca64e7f4c3f6b5 (diff)
Refactor: move library linking arguments into a parameter struct
Move arguments to BLO_library_link_{begin/named_part/end} into a single parameter struct, to ensure arguments always match. This allows is to skip tagging ID's LIB_TAG_DOIT when it's not needed, previously it was always cleared just in case it was needed. This also makes it possible to remove BLO_library_link_named_part_ex which was only used when tagging was needed.
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c13
-rw-r--r--source/blender/blenloader/BLO_readfile.h60
-rw-r--r--source/blender/blenloader/intern/readfile.c164
-rw-r--r--source/blender/python/intern/bpy_library_load.c9
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c10
5 files changed, 168 insertions, 88 deletions
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index e950e94655a..9f5e038fb82 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -93,9 +93,12 @@ bool BKE_copybuffer_read(Main *bmain_dst,
return false;
}
/* Here appending/linking starts. */
- Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname);
+ const int flag = 0;
+ struct LibraryLink_Params liblink_params;
+ BLO_library_link_params_init(&liblink_params, bmain_dst, flag);
+ Main *mainl = BLO_library_link_begin(&bh, libname, &liblink_params);
BLO_library_link_copypaste(mainl, bh, id_types_mask);
- BLO_library_link_end(mainl, &bh, 0, NULL, NULL, NULL, NULL);
+ BLO_library_link_end(mainl, &bh, &liblink_params);
/* Mark all library linked objects to be updated. */
BKE_main_lib_objects_recalc_all(bmain_dst);
IMB_colormanagement_check_file_config(bmain_dst);
@@ -144,11 +147,13 @@ int BKE_copybuffer_paste(bContext *C,
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
/* here appending/linking starts */
- mainl = BLO_library_link_begin(bmain, &bh, libname);
+ struct LibraryLink_Params liblink_params;
+ BLO_library_link_params_init_with_context(&liblink_params, bmain, flag, scene, view_layer, v3d);
+ mainl = BLO_library_link_begin(&bh, libname, &liblink_params);
const int num_pasted = BLO_library_link_copypaste(mainl, bh, id_types_mask);
- BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d);
+ BLO_library_link_end(mainl, &bh, &liblink_params);
/* 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 c9e837eb3b5..c83d8e037c8 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -138,6 +138,10 @@ void BLO_blendhandle_close(BlendHandle *bh);
bool BLO_has_bfile_extension(const char *str);
bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name);
+/* -------------------------------------------------------------------- */
+/** \name BLO Blend File Linking API
+ * \{ */
+
/* Options controlling behavior of append/link code.
* Note: merged with 'user-level' options from operators etc. in 16 lower bits
* (see eFileSel_Params_Flag in DNA_space_types.h). */
@@ -146,25 +150,63 @@ typedef enum BLO_LibLinkFlags {
BLO_LIBLINK_USE_PLACEHOLDERS = 1 << 16,
/* Force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). */
BLO_LIBLINK_FORCE_INDIRECT = 1 << 17,
+ /**
+ * When set, tag ID types that pass the internal check #library_link_idcode_needs_tag_check
+ *
+ * Currently this is only used to instantiate objects in the scene.
+ * Set this from #BLO_library_link_params_init_with_context so callers
+ * don't need to remember to set this flag.
+ */
+ BLO_LIBLINK_NEEDS_ID_TAG_DOIT = 1 << 18,
} BLO_LinkFlags;
-struct Main *BLO_library_link_begin(struct Main *mainvar, BlendHandle **bh, const char *filepath);
+/**
+ * Struct for passing arguments to
+ * #BLO_library_link_begin, #BLO_library_link_named_part & #BLO_library_link_end.
+ * Wrap these in parameters since it's important both functions receive matching values.
+ */
+struct LibraryLink_Params {
+ /** The current main database, e.g. #G_MAIN or `CTX_data_main(C)`. */
+ struct Main *bmain;
+ /** Options for linking, used for instantiating. */
+ int flag;
+ /** Context for instancing objects (optional, no instantiation will be performed when NULL). */
+ struct {
+ /** The scene in which to instantiate objects/collections. */
+ struct Scene *scene;
+ /** The scene layer in which to instantiate objects/collections. */
+ struct ViewLayer *view_layer;
+ /** The active 3D viewport (only used to define local-view). */
+ const struct View3D *v3d;
+ } context;
+};
+
+void BLO_library_link_params_init(struct LibraryLink_Params *params,
+ struct Main *bmain,
+ const int flag);
+void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params,
+ struct Main *bmain,
+ const int flag,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d);
+
+struct Main *BLO_library_link_begin(BlendHandle **bh,
+ const char *filepath,
+ const struct LibraryLink_Params *params);
struct ID *BLO_library_link_named_part(struct Main *mainl,
BlendHandle **bh,
const short idcode,
- const char *name);
-struct ID *BLO_library_link_named_part_ex(
- struct Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag);
+ const char *name,
+ const struct LibraryLink_Params *params);
void BLO_library_link_end(struct Main *mainl,
BlendHandle **bh,
- int flag,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer,
- const struct View3D *v3d);
+ const struct LibraryLink_Params *params);
int BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh, const uint64_t id_types_mask);
+/** \} */
+
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
/* internal function but we need to expose it */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 84cb898a426..35534963433 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -262,6 +262,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(BlendDataReader *reader, ListBase *lb, Object *ob);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
+static bool library_link_idcode_needs_tag_check(const short idcode, const int flag);
#ifdef USE_COLLECTION_COMPAT_28
static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc);
@@ -10469,6 +10470,14 @@ static ID *link_named_part(
/* if we found the id but the id is NULL, this is really bad */
BLI_assert(!((bhead != NULL) && (id == NULL)));
+ /* Tag as loose object (or data associated with objects)
+ * needing to be instantiated in #LibraryLink_Params.scene. */
+ if ((id != NULL) && (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT)) {
+ if (library_link_idcode_needs_tag_check(idcode, flag)) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+ }
+
return id;
}
@@ -10514,23 +10523,6 @@ int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const uint64_t id_t
return num_directly_linked;
}
-static ID *link_named_part_ex(
- Main *mainl, FileData *fd, const short idcode, const char *name, const int flag)
-{
- ID *id = link_named_part(mainl, fd, idcode, name, flag);
-
- if (id && (GS(id->name) == ID_OB)) {
- /* Tag as loose object needing to be instantiated somewhere... */
- id->tag |= LIB_TAG_DOIT;
- }
- else if (id && (GS(id->name) == ID_GR)) {
- /* tag as needing to be instantiated or linked */
- id->tag |= LIB_TAG_DOIT;
- }
-
- return id;
-}
-
/**
* Link a named data-block from an external blend file.
*
@@ -10543,41 +10535,53 @@ static ID *link_named_part_ex(
ID *BLO_library_link_named_part(Main *mainl,
BlendHandle **bh,
const short idcode,
- const char *name)
+ const char *name,
+ const struct LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
- return link_named_part(mainl, fd, idcode, name, 0);
+ return link_named_part(mainl, fd, idcode, name, params->flag);
}
+/* common routine to append/link something from a library */
+
/**
- * Link a named data-block from an external blend file.
- * Optionally instantiate the object/collection 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.
- * \param idcode: The kind of data-block to link.
- * \param name: The name of the data-block (without the 2 char ID prefix).
- * \param flag: Options for linking, used for instantiating.
- * \return the linked ID when found.
+ * Checks if the \a idcode needs to be tagged with #LIB_TAG_DOIT when linking/appending.
*/
-ID *BLO_library_link_named_part_ex(
- Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag)
+static bool library_link_idcode_needs_tag_check(const short idcode, const int flag)
{
- FileData *fd = (FileData *)(*bh);
- return link_named_part_ex(mainl, fd, idcode, name, flag);
+ if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
+ /* Always true because of #add_loose_objects_to_scene & #add_collections_to_scene. */
+ if (ELEM(idcode, ID_OB, ID_GR)) {
+ return true;
+ }
+ }
+ return false;
}
-/* common routine to append/link something from a library */
+/**
+ * Clears #LIB_TAG_DOIT based on the result of #library_link_idcode_needs_tag_check.
+ */
+static void library_link_clear_tag(Main *mainvar, const int flag)
+{
+ for (int i = 0; i < MAX_LIBARRAY; i++) {
+ const short idcode = BKE_idtype_idcode_from_index(i);
+ BLI_assert(idcode != -1);
+ if (library_link_idcode_needs_tag_check(idcode, flag)) {
+ BKE_main_id_tag_idcode(mainvar, idcode, LIB_TAG_DOIT, false);
+ }
+ }
+}
-static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath)
+static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath, const int flag)
{
Main *mainl;
(*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
- /* clear for objects and collections instantiating tag */
- BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false);
- BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false);
+ if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
+ /* Clear for objects and collections instantiating tag. */
+ library_link_clear_tag(mainvar, flag);
+ }
/* make mains */
blo_split_main((*fd)->mainlist, mainvar);
@@ -10595,19 +10599,49 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa
return mainl;
}
+void BLO_library_link_params_init(struct LibraryLink_Params *params,
+ struct Main *bmain,
+ const int flag)
+{
+ memset(params, 0, sizeof(*params));
+ params->bmain = bmain;
+ params->flag = flag;
+}
+
+void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params,
+ struct Main *bmain,
+ const int flag,
+ /* Context arguments. */
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ const struct View3D *v3d)
+{
+ BLO_library_link_params_init(params, bmain, flag);
+ if (scene != NULL) {
+ /* Tagging is needed for instancing. */
+ params->flag |= BLO_LIBLINK_NEEDS_ID_TAG_DOIT;
+
+ params->context.scene = scene;
+ params->context.view_layer = view_layer;
+ params->context.v3d = v3d;
+ }
+}
+
/**
* Initialize the #BlendHandle for linking library data.
*
- * \param mainvar: The current main database, e.g. #G_MAIN or #CTX_data_main(C).
* \param bh: A blender file handle as returned by
* #BLO_blendhandle_from_file or #BLO_blendhandle_from_memory.
* \param filepath: Used for relative linking, copied to the `lib->filepath`.
- * \return the library #Main, to be passed to #BLO_library_link_named_part_ex as \a mainl.
+ * \param params: Settings for linking that don't change from beginning to end of linking.
+ * \return the library #Main, to be passed to #BLO_library_link_named_part as \a mainl.
*/
-Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepath)
+Main *BLO_library_link_begin(BlendHandle **bh,
+ const char *filepath,
+ const struct LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
- return library_link_begin(mainvar, &fd, filepath);
+ return library_link_begin(params->bmain, &fd, filepath, params->flag);
}
static void split_main_newid(Main *mainptr, Main *main_newid)
@@ -10642,8 +10676,8 @@ static void split_main_newid(Main *mainptr, Main *main_newid)
*/
static void library_link_end(Main *mainl,
FileData **fd,
- const short flag,
Main *bmain,
+ const int flag,
Scene *scene,
ViewLayer *view_layer,
const View3D *v3d)
@@ -10720,19 +10754,18 @@ static void library_link_end(Main *mainl,
/* Give a base to loose objects and collections.
* Only directly linked objects & collections are instantiated by
- * #BLO_library_link_named_part_ex & co,
+ * #BLO_library_link_named_part & co,
* here we handle indirect ones and other possible edge-cases. */
- if (scene) {
- add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
- add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
- }
- else {
- /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */
- }
+ if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
+ /* Should always be true. */
+ if (scene != NULL) {
+ add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
+ add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
+ }
- /* Clear objects and collections instantiating tag. */
- BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false);
- BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false);
+ /* Clear objects and collections instantiating tag. */
+ library_link_clear_tag(mainvar, flag);
+ }
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
@@ -10748,25 +10781,18 @@ static void library_link_end(Main *mainl,
*
* \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 instantiating.
- * \param bmain: The main database in which to instantiate objects/collections
- * \param scene: The scene in which to instantiate objects/collections
- * (if NULL, no instantiation is done).
- * \param view_layer: The scene layer in which to instantiate objects/collections
- * (if NULL, no instantiation is done).
- * \param v3d: The active 3D viewport
- * (only to define local-view for instantiated objects & groups, can be NULL).
+ * \param params: Settings for linking that don't change from beginning to end of linking.
*/
-void BLO_library_link_end(Main *mainl,
- BlendHandle **bh,
- int flag,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer,
- const View3D *v3d)
+void BLO_library_link_end(Main *mainl, BlendHandle **bh, const struct LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
- library_link_end(mainl, &fd, flag, bmain, scene, view_layer, v3d);
+ library_link_end(mainl,
+ &fd,
+ params->bmain,
+ params->flag,
+ params->context.scene,
+ params->context.view_layer,
+ params->context.v3d);
*bh = (BlendHandle *)fd;
}
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index bdad4d03ae7..a3750d348f5 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -327,7 +327,10 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
/* here appending/linking starts */
- mainl = BLO_library_link_begin(bmain, &(self->blo_handle), self->relpath);
+ struct LibraryLink_Params liblink_params;
+ BLO_library_link_params_init(&liblink_params, bmain, self->flag);
+
+ mainl = BLO_library_link_begin(&(self->blo_handle), self->relpath, &liblink_params);
{
int idcode_step = 0, idcode;
@@ -350,7 +353,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
if (item_idname) {
ID *id = BLO_library_link_named_part(
- mainl, &(self->blo_handle), idcode, item_idname);
+ mainl, &(self->blo_handle), idcode, item_idname, &liblink_params);
if (id) {
#ifdef USE_RNA_DATABLOCKS
/* swap name for pointer to the id */
@@ -394,7 +397,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
}
Library *lib = mainl->curlib; /* newly added lib, assign before append end */
- BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL);
+ BLO_library_link_end(mainl, &(self->blo_handle), &liblink_params);
BLO_blendhandle_close(self->blo_handle);
self->blo_handle = NULL;
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 6ccc5d79962..8c14055696c 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -250,7 +250,11 @@ static void wm_link_do(WMLinkAppendData *lapp_data,
}
/* here appending/linking starts */
- mainl = BLO_library_link_begin(bmain, &bh, libname);
+ struct LibraryLink_Params liblink_params;
+ BLO_library_link_params_init_with_context(
+ &liblink_params, bmain, flag, scene, view_layer, v3d);
+
+ mainl = BLO_library_link_begin(&bh, libname, &liblink_params);
lib = mainl->curlib;
BLI_assert(lib);
UNUSED_VARS_NDEBUG(lib);
@@ -276,7 +280,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data,
continue;
}
- new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag);
+ new_id = BLO_library_link_named_part(mainl, &bh, item->idcode, item->name, &liblink_params);
if (new_id) {
/* If the link is successful, clear item's libs 'todo' flags.
@@ -286,7 +290,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data,
}
}
- BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d);
+ BLO_library_link_end(mainl, &bh, &liblink_params);
BLO_blendhandle_close(bh);
}
}