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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
ID *BLO_library_link_named_part_ex(
|
||||
Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag)
|
||||
{
|
||||
FileData *fd = (FileData *)(*bh);
|
||||
return link_named_part_ex(mainl, fd, idcode, name, flag);
|
||||
return link_named_part(mainl, fd, idcode, name, params->flag);
|
||||
}
|
||||
|
||||
/* common routine to append/link something from a library */
|
||||
|
||||
static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath)
|
||||
/**
|
||||
* Checks if the \a idcode needs to be tagged with #LIB_TAG_DOIT when linking/appending.
|
||||
*/
|
||||
static bool library_link_idcode_needs_tag_check(const short idcode, const int 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user