Refactor: Modernize BlendfileLinkAppendContext and related link/append BKE code.
Mainly remove usages of BLI memarena and bitmap, and use owninh C++ containers instead. And replace pointers by references in some of the internal functions parameters. Pull Request: https://projects.blender.org/blender/blender/pulls/128041
This commit is contained in:
committed by
Bastien Montagne
parent
37458329e2
commit
e44fc3df06
@@ -14,6 +14,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
@@ -25,16 +26,15 @@
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
@@ -71,9 +71,9 @@ static CLG_LogRef LOG = {"bke.blendfile_link_append"};
|
||||
|
||||
struct BlendfileLinkAppendContextItem {
|
||||
/** Name of the ID (without the heading two-chars IDcode). */
|
||||
char *name;
|
||||
std::string name;
|
||||
/** All libraries (from #BlendfileLinkAppendContext.libraries) to try to load this ID from. */
|
||||
BLI_bitmap *libraries;
|
||||
blender::BitVector<> libraries;
|
||||
/** ID type. */
|
||||
short idcode;
|
||||
|
||||
@@ -103,7 +103,7 @@ struct BlendfileLinkAppendContextItem {
|
||||
|
||||
/* A blendfile library entry in the `libraries` list of #BlendfileLinkAppendContext. */
|
||||
struct BlendfileLinkAppendContextLibrary {
|
||||
char *path; /* Absolute .blend file path. */
|
||||
std::string path; /* Absolute .blend file path. */
|
||||
BlendHandle *blo_handle; /* Blend file handle, if any. */
|
||||
bool blo_handle_is_owned; /* Whether the blend file handle is owned, or borrowed. */
|
||||
/* The blendfile report associated with the `blo_handle`, if owned. */
|
||||
@@ -112,14 +112,12 @@ struct BlendfileLinkAppendContextLibrary {
|
||||
|
||||
struct BlendfileLinkAppendContext {
|
||||
/** List of library paths to search IDs in. */
|
||||
blender::Vector<BlendfileLinkAppendContextLibrary *> libraries;
|
||||
blender::Vector<BlendfileLinkAppendContextLibrary> libraries;
|
||||
/**
|
||||
* List of all ID to try to link from #libraries. This is a linked list because iterators must
|
||||
* not be invalidated when adding more items.
|
||||
*/
|
||||
std::list<BlendfileLinkAppendContextItem *> items;
|
||||
int num_libraries = 0;
|
||||
int num_items = 0;
|
||||
std::list<BlendfileLinkAppendContextItem> items;
|
||||
/** Linking/appending parameters. Including `bmain`, `scene`, `viewlayer` and `view3d`. */
|
||||
LibraryLink_Params *params = nullptr;
|
||||
|
||||
@@ -132,9 +130,6 @@ struct BlendfileLinkAppendContext {
|
||||
/** Embedded blendfile and its size, if needed. */
|
||||
const void *blendfile_mem = nullptr;
|
||||
size_t blendfile_memsize = 0;
|
||||
|
||||
/** Internal 'private' data */
|
||||
MemArena *memarena = nullptr;
|
||||
};
|
||||
|
||||
struct BlendfileLinkAppendContextCallBack {
|
||||
@@ -191,59 +186,56 @@ enum {
|
||||
};
|
||||
|
||||
static BlendHandle *link_append_context_library_blohandle_ensure(
|
||||
BlendfileLinkAppendContext *lapp_context,
|
||||
BlendfileLinkAppendContextLibrary *lib_context,
|
||||
BlendfileLinkAppendContext &lapp_context,
|
||||
BlendfileLinkAppendContextLibrary &lib_context,
|
||||
ReportList *reports)
|
||||
{
|
||||
if (reports != nullptr) {
|
||||
lib_context->bf_reports.reports = reports;
|
||||
lib_context.bf_reports.reports = reports;
|
||||
}
|
||||
|
||||
const char *libname = lib_context->path;
|
||||
BlendHandle *blo_handle = lib_context->blo_handle;
|
||||
const blender::StringRefNull libname = lib_context.path;
|
||||
BlendHandle *blo_handle = lib_context.blo_handle;
|
||||
if (blo_handle == nullptr) {
|
||||
if (STREQ(libname, BLO_EMBEDDED_STARTUP_BLEND)) {
|
||||
blo_handle = BLO_blendhandle_from_memory(lapp_context->blendfile_mem,
|
||||
int(lapp_context->blendfile_memsize),
|
||||
&lib_context->bf_reports);
|
||||
if (libname == BLO_EMBEDDED_STARTUP_BLEND) {
|
||||
blo_handle = BLO_blendhandle_from_memory(lapp_context.blendfile_mem,
|
||||
int(lapp_context.blendfile_memsize),
|
||||
&lib_context.bf_reports);
|
||||
}
|
||||
else {
|
||||
blo_handle = BLO_blendhandle_from_file(libname, &lib_context->bf_reports);
|
||||
blo_handle = BLO_blendhandle_from_file(libname.c_str(), &lib_context.bf_reports);
|
||||
}
|
||||
lib_context->blo_handle = blo_handle;
|
||||
lib_context->blo_handle_is_owned = true;
|
||||
lib_context.blo_handle = blo_handle;
|
||||
lib_context.blo_handle_is_owned = true;
|
||||
}
|
||||
|
||||
return blo_handle;
|
||||
}
|
||||
|
||||
static void link_append_context_library_blohandle_release(
|
||||
BlendfileLinkAppendContext * /*lapp_context*/, BlendfileLinkAppendContextLibrary *lib_context)
|
||||
BlendfileLinkAppendContext & /*lapp_context*/, BlendfileLinkAppendContextLibrary &lib_context)
|
||||
{
|
||||
if (lib_context->blo_handle_is_owned && lib_context->blo_handle != nullptr) {
|
||||
BLO_blendhandle_close(lib_context->blo_handle);
|
||||
lib_context->blo_handle = nullptr;
|
||||
if (lib_context.blo_handle_is_owned && lib_context.blo_handle != nullptr) {
|
||||
BLO_blendhandle_close(lib_context.blo_handle);
|
||||
lib_context.blo_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BlendfileLinkAppendContext *BKE_blendfile_link_append_context_new(LibraryLink_Params *params)
|
||||
{
|
||||
BlendfileLinkAppendContext *lapp_context = MEM_new<BlendfileLinkAppendContext>(__func__);
|
||||
lapp_context->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
||||
lapp_context->params = params;
|
||||
return lapp_context;
|
||||
}
|
||||
|
||||
void BKE_blendfile_link_append_context_free(BlendfileLinkAppendContext *lapp_context)
|
||||
{
|
||||
for (BlendfileLinkAppendContextLibrary *lib_context : lapp_context->libraries) {
|
||||
link_append_context_library_blohandle_release(lapp_context, lib_context);
|
||||
for (BlendfileLinkAppendContextLibrary &lib_context : lapp_context->libraries) {
|
||||
link_append_context_library_blohandle_release(*lapp_context, lib_context);
|
||||
}
|
||||
|
||||
BLI_assert(lapp_context->library_weak_reference_mapping == nullptr);
|
||||
|
||||
BLI_memarena_free(lapp_context->memarena);
|
||||
|
||||
MEM_delete(lapp_context);
|
||||
}
|
||||
|
||||
@@ -282,24 +274,15 @@ void BKE_blendfile_link_append_context_library_add(BlendfileLinkAppendContext *l
|
||||
{
|
||||
BLI_assert(lapp_context->items.empty());
|
||||
|
||||
static_assert(std::is_trivial_v<BlendfileLinkAppendContextLibrary>);
|
||||
BlendfileLinkAppendContextLibrary *lib_context =
|
||||
static_cast<BlendfileLinkAppendContextLibrary *>(
|
||||
BLI_memarena_calloc(lapp_context->memarena, sizeof(*lib_context)));
|
||||
BlendfileLinkAppendContextLibrary lib_context = {};
|
||||
|
||||
const size_t libname_size = strlen(libname) + 1;
|
||||
char *libpath = static_cast<char *>(BLI_memarena_alloc(lapp_context->memarena, libname_size));
|
||||
memcpy(libpath, libname, libname_size);
|
||||
|
||||
lib_context->path = libpath;
|
||||
lib_context->blo_handle = blo_handle;
|
||||
lib_context.path = libname;
|
||||
lib_context.blo_handle = blo_handle;
|
||||
/* Always steal the ownership on the blendfile handle, as it may be freed by readfile code in
|
||||
* case of endianness conversion. */
|
||||
lib_context->blo_handle_is_owned = true;
|
||||
lib_context.blo_handle_is_owned = true;
|
||||
|
||||
lapp_context->libraries.append(lib_context);
|
||||
|
||||
lapp_context->num_libraries++;
|
||||
}
|
||||
|
||||
BlendfileLinkAppendContextItem *BKE_blendfile_link_append_context_item_add(
|
||||
@@ -308,23 +291,19 @@ BlendfileLinkAppendContextItem *BKE_blendfile_link_append_context_item_add(
|
||||
const short idcode,
|
||||
void *userdata)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
BLI_memarena_calloc(lapp_context->memarena, sizeof(*item)));
|
||||
const size_t idname_size = strlen(idname) + 1;
|
||||
BlendfileLinkAppendContextItem item = {};
|
||||
|
||||
item->name = static_cast<char *>(BLI_memarena_alloc(lapp_context->memarena, idname_size));
|
||||
memcpy(item->name, idname, idname_size);
|
||||
item->idcode = idcode;
|
||||
item->libraries = BLI_BITMAP_NEW_MEMARENA(lapp_context->memarena, lapp_context->num_libraries);
|
||||
item.name = idname;
|
||||
item.idcode = idcode;
|
||||
item.libraries = blender::BitVector<>(lapp_context->libraries.size(), false);
|
||||
|
||||
item->new_id = nullptr;
|
||||
item->action = LINK_APPEND_ACT_UNSET;
|
||||
item->userdata = userdata;
|
||||
item.new_id = nullptr;
|
||||
item.action = LINK_APPEND_ACT_UNSET;
|
||||
item.userdata = userdata;
|
||||
|
||||
lapp_context->items.push_back(item);
|
||||
lapp_context->num_items++;
|
||||
|
||||
return item;
|
||||
return &lapp_context->items.back();
|
||||
}
|
||||
|
||||
int BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
||||
@@ -337,9 +316,9 @@ int BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
||||
int id_code_iter = 0;
|
||||
short id_code;
|
||||
|
||||
BlendfileLinkAppendContextLibrary *lib_context = lapp_context->libraries[library_index];
|
||||
BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[library_index];
|
||||
BlendHandle *blo_handle = link_append_context_library_blohandle_ensure(
|
||||
lapp_context, lib_context, reports);
|
||||
*lapp_context, lib_context, reports);
|
||||
|
||||
if (blo_handle == nullptr) {
|
||||
return BLENDFILE_LINK_APPEND_INVALID;
|
||||
@@ -382,12 +361,12 @@ void BKE_blendfile_link_append_context_item_library_index_enable(
|
||||
BlendfileLinkAppendContextItem *item,
|
||||
const int library_index)
|
||||
{
|
||||
BLI_BITMAP_ENABLE(item->libraries, library_index);
|
||||
item->libraries[library_index].set();
|
||||
}
|
||||
|
||||
bool BKE_blendfile_link_append_context_is_empty(BlendfileLinkAppendContext *lapp_context)
|
||||
{
|
||||
return lapp_context->num_items == 0;
|
||||
return lapp_context->items.empty();
|
||||
}
|
||||
|
||||
void *BKE_blendfile_link_append_context_item_userdata_get(
|
||||
@@ -434,19 +413,19 @@ void BKE_blendfile_link_append_context_item_foreach(
|
||||
BlendfileLinkAppendContextItem *item)> callback_function,
|
||||
const eBlendfileLinkAppendForeachItemFlag flag)
|
||||
{
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
if ((flag & BKE_BLENDFILE_LINK_APPEND_FOREACH_ITEM_FLAG_DO_DIRECT) == 0 &&
|
||||
(item->tag & LINK_APPEND_TAG_INDIRECT) == 0)
|
||||
(item.tag & LINK_APPEND_TAG_INDIRECT) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((flag & BKE_BLENDFILE_LINK_APPEND_FOREACH_ITEM_FLAG_DO_INDIRECT) == 0 &&
|
||||
(item->tag & LINK_APPEND_TAG_INDIRECT) != 0)
|
||||
(item.tag & LINK_APPEND_TAG_INDIRECT) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callback_function(lapp_context, item)) {
|
||||
if (!callback_function(lapp_context, &item)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -611,8 +590,8 @@ static void loose_data_instantiate_obdata_preprocess(
|
||||
|
||||
/* First pass on obdata to enable their instantiation by default, then do a second pass on
|
||||
* objects to clear it for any obdata already in use. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -629,19 +608,19 @@ static void loose_data_instantiate_obdata_preprocess(
|
||||
|
||||
id->tag |= ID_TAG_DOIT;
|
||||
}
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr || GS(id->name) != ID_OB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object *ob = (Object *)id;
|
||||
Object *new_ob = (Object *)id->newid;
|
||||
Object *ob = reinterpret_cast<Object *>(id);
|
||||
Object *new_ob = reinterpret_cast<Object *>(id->newid);
|
||||
if (ob->data != nullptr) {
|
||||
((ID *)(ob->data))->tag &= ~ID_TAG_DOIT;
|
||||
(static_cast<ID *>(ob->data))->tag &= ~ID_TAG_DOIT;
|
||||
}
|
||||
if (new_ob != nullptr && new_ob->data != nullptr) {
|
||||
((ID *)(new_ob->data))->tag &= ~ID_TAG_DOIT;
|
||||
(static_cast<ID *>(new_ob->data))->tag &= ~ID_TAG_DOIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -682,8 +661,8 @@ static void loose_data_instantiate_collection_process(
|
||||
* non-instantiated objects in them.
|
||||
* NOTE: Also avoid view-layer-instantiating of collections children of other instantiated
|
||||
* collections. This is why we need two passes here. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr || GS(id->name) != ID_GR) {
|
||||
continue;
|
||||
}
|
||||
@@ -705,7 +684,7 @@ static void loose_data_instantiate_collection_process(
|
||||
const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain,
|
||||
collection);
|
||||
/* Always consider adding collections directly selected by the user. */
|
||||
bool do_add_collection = (item->tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
|
||||
bool do_add_collection = (item.tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
|
||||
!collection_is_instantiated;
|
||||
/* In linking case, do not enforce instantiating non-directly linked collections/objects.
|
||||
* This avoids cluttering the view-layers, user can instantiate themselves specific collections
|
||||
@@ -726,13 +705,13 @@ static void loose_data_instantiate_collection_process(
|
||||
|
||||
/* Second loop to actually instantiate collections tagged as such in first loop, unless some of
|
||||
* their ancestor is also instantiated in case this is not an empty-instantiation. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr || GS(id->name) != ID_GR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Collection *collection = (Collection *)id;
|
||||
Collection *collection = reinterpret_cast<Collection *>(id);
|
||||
bool do_add_collection = (id->tag & ID_TAG_DOIT) != 0;
|
||||
|
||||
if (!do_add_collection) {
|
||||
@@ -747,7 +726,7 @@ static void loose_data_instantiate_collection_process(
|
||||
}
|
||||
/* When instantiated as empty, do not add indirectly linked (i.e. non-user-selected)
|
||||
* collections. */
|
||||
if (do_instantiate_as_empty && (item->tag & LINK_APPEND_TAG_INDIRECT) != 0) {
|
||||
if (do_instantiate_as_empty && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -814,8 +793,8 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
|
||||
|
||||
/* NOTE: For objects we only view_layer-instantiate duplicated objects that are not yet used
|
||||
* anywhere. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr || GS(id->name) != ID_OB) {
|
||||
continue;
|
||||
}
|
||||
@@ -827,7 +806,7 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
|
||||
* make them directly linked. Think for now keeping them indirectly linked is more important.
|
||||
* Ref. #93757.
|
||||
*/
|
||||
if (is_linking && (item->tag & LINK_APPEND_TAG_INDIRECT) != 0) {
|
||||
if (is_linking && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -866,8 +845,8 @@ static void loose_data_instantiate_obdata_process(LooseDataInstantiateContext *i
|
||||
* if you want it do it at the editor level. */
|
||||
const bool object_set_active = false;
|
||||
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -911,12 +890,12 @@ static void loose_data_instantiate_object_rigidbody_postprocess(
|
||||
Main *bmain = lapp_context->params->bmain;
|
||||
|
||||
/* Add rigid body objects and constraints to current RB world(s). */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, item);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
|
||||
if (id == nullptr || GS(id->name) != ID_OB) {
|
||||
continue;
|
||||
}
|
||||
BKE_rigidbody_ensure_local_object(bmain, (Object *)id);
|
||||
BKE_rigidbody_ensure_local_object(bmain, reinterpret_cast<Object *>(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -947,19 +926,19 @@ static void loose_data_instantiate(LooseDataInstantiateContext *instantiate_cont
|
||||
loose_data_instantiate_object_rigidbody_postprocess(instantiate_context);
|
||||
}
|
||||
|
||||
static void new_id_to_item_mapping_add(BlendfileLinkAppendContext *lapp_context,
|
||||
static void new_id_to_item_mapping_add(BlendfileLinkAppendContext &lapp_context,
|
||||
ID *id,
|
||||
BlendfileLinkAppendContextItem *item)
|
||||
BlendfileLinkAppendContextItem &item)
|
||||
{
|
||||
lapp_context->new_id_to_item.add(id, item);
|
||||
lapp_context.new_id_to_item.add(id, &item);
|
||||
}
|
||||
|
||||
/* Generate a mapping between newly linked IDs and their items, and tag linked IDs used as
|
||||
* liboverride references as already existing. */
|
||||
static void new_id_to_item_mapping_create(BlendfileLinkAppendContext *lapp_context)
|
||||
static void new_id_to_item_mapping_create(BlendfileLinkAppendContext &lapp_context)
|
||||
{
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -1045,7 +1024,7 @@ static int foreach_libblock_append_add_dependencies_callback(LibraryIDLinkCallba
|
||||
*/
|
||||
item->tag |= LINK_APPEND_TAG_INDIRECT;
|
||||
item->action = LINK_APPEND_ACT_UNSET;
|
||||
new_id_to_item_mapping_add(data->lapp_context, id, item);
|
||||
new_id_to_item_mapping_add(*data->lapp_context, id, *item);
|
||||
|
||||
if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
|
||||
data->is_liboverride_dependency_only)
|
||||
@@ -1139,21 +1118,21 @@ static int foreach_libblock_append_finalize_action_callback(LibraryIDLinkCallbac
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_context,
|
||||
static void blendfile_append_define_actions(BlendfileLinkAppendContext &lapp_context,
|
||||
ReportList *reports)
|
||||
{
|
||||
Main *bmain = lapp_context->params->bmain;
|
||||
Main *bmain = lapp_context.params->bmain;
|
||||
|
||||
const bool do_recursive = (lapp_context->params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
|
||||
const bool do_reuse_local_id = (lapp_context->params->flag &
|
||||
BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) != 0;
|
||||
const bool do_recursive = (lapp_context.params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
|
||||
const bool do_reuse_local_id = (lapp_context.params->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) !=
|
||||
0;
|
||||
|
||||
/* In case of non-recursive appending, gather a set of all 'original' libraries (i.e. libraries
|
||||
* containing data that was explicitly selected by the user). */
|
||||
blender::Set<Library *> direct_libraries;
|
||||
if (!do_recursive) {
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -1166,12 +1145,12 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
* NOTE: Since items are appended, this list will grow and these IDs will be processed later,
|
||||
* leading to a flatten recursive processing of all the linked dependencies.
|
||||
*/
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
BLI_assert(item->reusable_local_id == nullptr);
|
||||
BLI_assert(item.reusable_local_id == nullptr);
|
||||
|
||||
/* NOTE: handling of reusable local ID info is needed, even if their usage is not requested
|
||||
* for that append operation:
|
||||
@@ -1179,19 +1158,19 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
* if requested.
|
||||
* - Existing appended data may need to get this 'reuse' weak reference cleared, e.g. if a
|
||||
* new version of it is made local. */
|
||||
item->reusable_local_id = BKE_idtype_idcode_append_is_reusable(GS(id->name)) ?
|
||||
BKE_main_library_weak_reference_search_item(
|
||||
lapp_context->library_weak_reference_mapping,
|
||||
id->lib->filepath,
|
||||
id->name) :
|
||||
nullptr;
|
||||
item.reusable_local_id = BKE_idtype_idcode_append_is_reusable(GS(id->name)) ?
|
||||
BKE_main_library_weak_reference_search_item(
|
||||
lapp_context.library_weak_reference_mapping,
|
||||
id->lib->filepath,
|
||||
id->name) :
|
||||
nullptr;
|
||||
|
||||
BlendfileLinkAppendContextCallBack cb_data{};
|
||||
cb_data.lapp_context = lapp_context;
|
||||
cb_data.item = item;
|
||||
cb_data.lapp_context = &lapp_context;
|
||||
cb_data.item = &item;
|
||||
cb_data.reports = reports;
|
||||
cb_data.is_liboverride_dependency = (item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
|
||||
cb_data.is_liboverride_dependency_only = (item->tag &
|
||||
cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
|
||||
cb_data.is_liboverride_dependency_only = (item.tag &
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0;
|
||||
BKE_library_foreach_ID_link(
|
||||
bmain, id, foreach_libblock_append_add_dependencies_callback, &cb_data, IDWALK_NOP);
|
||||
@@ -1200,27 +1179,27 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
/* At this point, linked IDs that should remain linked can already be defined as such:
|
||||
* - In case of non-recursive appending, IDs from other libraries.
|
||||
* - IDs only used as liboverride references. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
/* These tags should have been set in above loop, here they can be check for validity (they
|
||||
* are mutually exclusive). */
|
||||
BLI_assert(
|
||||
(item->tag &
|
||||
(item.tag &
|
||||
(LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY | LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY)) !=
|
||||
(LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY | LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY));
|
||||
|
||||
ID *id = item->new_id;
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
/* IDs exclusively used as liboverride reference should not be made local at all. */
|
||||
if ((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
|
||||
if ((item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
|
||||
CLOG_INFO(
|
||||
&LOG,
|
||||
3,
|
||||
"Appended ID '%s' is only used as a liboverride linked dependency, keeping it linked.",
|
||||
id->name);
|
||||
item->action = LINK_APPEND_ACT_KEEP_LINKED;
|
||||
item->reusable_local_id = nullptr;
|
||||
item.action = LINK_APPEND_ACT_KEEP_LINKED;
|
||||
item.reusable_local_id = nullptr;
|
||||
}
|
||||
/* In non-recursive append case, only IDs from the same libraries as the directly appended
|
||||
* ones are made local. All dependencies from other libraries are kept linked. */
|
||||
@@ -1230,8 +1209,8 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
"Appended ID '%s' belongs to another library and recursive append is disabled, "
|
||||
"keeping it linked.",
|
||||
id->name);
|
||||
item->action = LINK_APPEND_ACT_KEEP_LINKED;
|
||||
item->reusable_local_id = nullptr;
|
||||
item.action = LINK_APPEND_ACT_KEEP_LINKED;
|
||||
item.reusable_local_id = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1247,28 +1226,27 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
* before the user IDs) could avoid a lot of iterations. */
|
||||
for (bool keep_looping = do_reuse_local_id; keep_looping;) {
|
||||
keep_looping = false;
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!item->reusable_local_id) {
|
||||
if (!item.reusable_local_id) {
|
||||
continue;
|
||||
}
|
||||
BlendfileLinkAppendContextCallBack cb_data{};
|
||||
cb_data.lapp_context = lapp_context;
|
||||
cb_data.item = item;
|
||||
cb_data.lapp_context = &lapp_context;
|
||||
cb_data.item = &item;
|
||||
cb_data.reports = reports;
|
||||
cb_data.is_liboverride_dependency = (item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) !=
|
||||
0;
|
||||
cb_data.is_liboverride_dependency_only = (item->tag &
|
||||
cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
|
||||
cb_data.is_liboverride_dependency_only = (item.tag &
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0;
|
||||
BKE_library_foreach_ID_link(bmain,
|
||||
id,
|
||||
foreach_libblock_append_ensure_reusable_local_id_callback,
|
||||
&cb_data,
|
||||
IDWALK_NOP);
|
||||
if (!item->reusable_local_id) {
|
||||
if (!item.reusable_local_id) {
|
||||
/* If some reusable ID was cleared, another loop over all items is needed to potentially
|
||||
* propagate this change higher in the dependency hierarchy. */
|
||||
keep_looping = true;
|
||||
@@ -1276,34 +1254,34 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
}
|
||||
}
|
||||
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item->action != LINK_APPEND_ACT_UNSET) {
|
||||
if (item.action != LINK_APPEND_ACT_UNSET) {
|
||||
/* Already set, pass. */
|
||||
BLI_assert(item->action == LINK_APPEND_ACT_KEEP_LINKED);
|
||||
BLI_assert(item.action == LINK_APPEND_ACT_KEEP_LINKED);
|
||||
continue;
|
||||
}
|
||||
BLI_assert((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) == 0);
|
||||
BLI_assert((item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) == 0);
|
||||
|
||||
if (do_reuse_local_id && item->reusable_local_id != nullptr) {
|
||||
if (do_reuse_local_id && item.reusable_local_id != nullptr) {
|
||||
CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it.", id->name);
|
||||
item->action = LINK_APPEND_ACT_REUSE_LOCAL;
|
||||
item.action = LINK_APPEND_ACT_REUSE_LOCAL;
|
||||
}
|
||||
else if (id->tag & ID_TAG_PRE_EXISTING) {
|
||||
CLOG_INFO(&LOG, 3, "Appended ID '%s' was already linked, duplicating it.", id->name);
|
||||
item->action = LINK_APPEND_ACT_COPY_LOCAL;
|
||||
item.action = LINK_APPEND_ACT_COPY_LOCAL;
|
||||
}
|
||||
else if (item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) {
|
||||
else if (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) {
|
||||
CLOG_INFO(
|
||||
&LOG,
|
||||
3,
|
||||
"Appended ID '%s' is also used as a liboverride linked dependency, duplicating it.",
|
||||
id->name);
|
||||
item->action = LINK_APPEND_ACT_COPY_LOCAL;
|
||||
item.action = LINK_APPEND_ACT_COPY_LOCAL;
|
||||
}
|
||||
else {
|
||||
/* That last action, making linked data directly local, can still be changed to
|
||||
@@ -1311,28 +1289,27 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
* complex relationships involving IDs that are kept linked and IDs that are made local,
|
||||
* both using some same dependencies. */
|
||||
CLOG_INFO(&LOG, 3, "Appended ID '%s' will be made local.", id->name);
|
||||
item->action = LINK_APPEND_ACT_MAKE_LOCAL;
|
||||
item.action = LINK_APPEND_ACT_MAKE_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some linked IDs marked to be made directly local may also be used by other items
|
||||
* marked to be kept linked. in such case, they need to be copied for the local data, such that
|
||||
* a linked version of these remains available as dependency for other linked data. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only IDs kept as linked need to be checked here. */
|
||||
if (item->action == LINK_APPEND_ACT_KEEP_LINKED) {
|
||||
if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
|
||||
BlendfileLinkAppendContextCallBack cb_data{};
|
||||
cb_data.lapp_context = lapp_context;
|
||||
cb_data.item = item;
|
||||
cb_data.lapp_context = &lapp_context;
|
||||
cb_data.item = &item;
|
||||
cb_data.reports = reports;
|
||||
cb_data.is_liboverride_dependency = (item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) !=
|
||||
0;
|
||||
cb_data.is_liboverride_dependency_only = (item->tag &
|
||||
cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
|
||||
cb_data.is_liboverride_dependency_only = (item.tag &
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0;
|
||||
BKE_library_foreach_ID_link(
|
||||
bmain, id, foreach_libblock_append_finalize_action_callback, &cb_data, IDWALK_NOP);
|
||||
@@ -1340,24 +1317,24 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext *lapp_con
|
||||
|
||||
/* If we found a matching existing local id but are not re-using it, we need to properly
|
||||
* clear its weak reference to linked data. */
|
||||
if (item->reusable_local_id != nullptr &&
|
||||
!ELEM(item->action, LINK_APPEND_ACT_KEEP_LINKED, LINK_APPEND_ACT_REUSE_LOCAL))
|
||||
if (item.reusable_local_id != nullptr &&
|
||||
!ELEM(item.action, LINK_APPEND_ACT_KEEP_LINKED, LINK_APPEND_ACT_REUSE_LOCAL))
|
||||
{
|
||||
BLI_assert_msg(!do_reuse_local_id,
|
||||
"This code should only be reached when the current append operation does not "
|
||||
"try to reuse local data.");
|
||||
BKE_main_library_weak_reference_remove_item(lapp_context->library_weak_reference_mapping,
|
||||
BKE_main_library_weak_reference_remove_item(lapp_context.library_weak_reference_mapping,
|
||||
id->lib->filepath,
|
||||
id->name,
|
||||
item->reusable_local_id);
|
||||
item->reusable_local_id = nullptr;
|
||||
item.reusable_local_id);
|
||||
item.reusable_local_id = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
|
||||
{
|
||||
if (lapp_context->num_items == 0) {
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Nothing to append. */
|
||||
return;
|
||||
}
|
||||
@@ -1379,16 +1356,16 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
LIB_ID_MAKELOCAL_LIBOVERRIDE_CLEAR :
|
||||
0);
|
||||
|
||||
new_id_to_item_mapping_create(lapp_context);
|
||||
new_id_to_item_mapping_create(*lapp_context);
|
||||
lapp_context->library_weak_reference_mapping = BKE_main_library_weak_reference_create(bmain);
|
||||
|
||||
/* Add missing items (the indirectly linked ones), and carefully define which action should be
|
||||
* applied to each of them. */
|
||||
blendfile_append_define_actions(lapp_context, reports);
|
||||
blendfile_append_define_actions(*lapp_context, reports);
|
||||
|
||||
/* Effectively perform required operation on every linked ID. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -1399,7 +1376,7 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
char lib_id_name[MAX_ID_NAME];
|
||||
STRNCPY(lib_id_name, id->name);
|
||||
|
||||
switch (item->action) {
|
||||
switch (item.action) {
|
||||
case LINK_APPEND_ACT_COPY_LOCAL:
|
||||
BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_COPY);
|
||||
local_appended_new_id = id->newid;
|
||||
@@ -1413,9 +1390,9 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
/* Nothing to do here. */
|
||||
break;
|
||||
case LINK_APPEND_ACT_REUSE_LOCAL:
|
||||
BLI_assert(item->reusable_local_id != nullptr);
|
||||
BLI_assert(item.reusable_local_id != nullptr);
|
||||
/* We only need to set `newid` to ID found in previous loop, for proper remapping. */
|
||||
ID_NEW_SET(id, item->reusable_local_id);
|
||||
ID_NEW_SET(id, item.reusable_local_id);
|
||||
/* This is not a 'new' local appended id, do not set `local_appended_new_id` here. */
|
||||
break;
|
||||
case LINK_APPEND_ACT_UNSET:
|
||||
@@ -1447,16 +1424,16 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
lapp_context->library_weak_reference_mapping = nullptr;
|
||||
|
||||
/* Remap IDs as needed. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
if (item->action == LINK_APPEND_ACT_KEEP_LINKED) {
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ID *id = item->new_id;
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (ELEM(item->action, LINK_APPEND_ACT_COPY_LOCAL, LINK_APPEND_ACT_REUSE_LOCAL)) {
|
||||
if (ELEM(item.action, LINK_APPEND_ACT_COPY_LOCAL, LINK_APPEND_ACT_REUSE_LOCAL)) {
|
||||
BLI_assert(ID_IS_LINKED(id));
|
||||
id = id->newid;
|
||||
if (id == nullptr) {
|
||||
@@ -1471,12 +1448,12 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
|
||||
/* Remove linked IDs when a local existing data has been reused instead. */
|
||||
BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
if (!ELEM(item->action, LINK_APPEND_ACT_COPY_LOCAL, LINK_APPEND_ACT_REUSE_LOCAL)) {
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
if (!ELEM(item.action, LINK_APPEND_ACT_COPY_LOCAL, LINK_APPEND_ACT_REUSE_LOCAL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ID *id = item->new_id;
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -1484,10 +1461,10 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
BLI_assert(id->newid != nullptr);
|
||||
|
||||
/* Calling code may want to access newly appended IDs from the link/append context items. */
|
||||
item->new_id = id->newid;
|
||||
item.new_id = id->newid;
|
||||
|
||||
/* Only the 'reuse local' action should leave unused newly linked data behind. */
|
||||
if (item->action != LINK_APPEND_ACT_REUSE_LOCAL) {
|
||||
if (item.action != LINK_APPEND_ACT_REUSE_LOCAL) {
|
||||
continue;
|
||||
}
|
||||
/* Do NOT delete a linked data that was already linked before this append. */
|
||||
@@ -1495,8 +1472,8 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
|
||||
continue;
|
||||
}
|
||||
/* Do NOT delete a linked data that is (also) used a liboverride dependency. */
|
||||
BLI_assert((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) == 0);
|
||||
if (item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) {
|
||||
BLI_assert((item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) == 0);
|
||||
if (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1552,7 +1529,7 @@ static int foreach_libblock_link_finalize_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
item->tag |= LINK_APPEND_TAG_INDIRECT;
|
||||
/* In linking case we already know what we want to do with these items. */
|
||||
item->action = LINK_APPEND_ACT_KEEP_LINKED;
|
||||
new_id_to_item_mapping_add(data->lapp_context, id, item);
|
||||
new_id_to_item_mapping_add(*data->lapp_context, id, *item);
|
||||
}
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
@@ -1564,22 +1541,22 @@ void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lap
|
||||
return;
|
||||
}
|
||||
if (lapp_context->params->flag & FILE_LINK) {
|
||||
new_id_to_item_mapping_create(lapp_context);
|
||||
new_id_to_item_mapping_create(*lapp_context);
|
||||
/* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
|
||||
* list.
|
||||
* NOTE: Since items are appended to the list, this list will grow and these IDs will be
|
||||
* processed later, leading to a flatten recursive processing of all the linked dependencies.
|
||||
*/
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
BLI_assert(item->userdata == nullptr);
|
||||
BLI_assert(item.userdata == nullptr);
|
||||
|
||||
BlendfileLinkAppendContextCallBack cb_data{};
|
||||
cb_data.lapp_context = lapp_context;
|
||||
cb_data.item = item;
|
||||
cb_data.item = &item;
|
||||
cb_data.reports = reports;
|
||||
BKE_library_foreach_ID_link(lapp_context->params->bmain,
|
||||
id,
|
||||
@@ -1597,21 +1574,21 @@ void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lap
|
||||
|
||||
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
|
||||
{
|
||||
if (lapp_context->num_items == 0) {
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Nothing to be linked. */
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_assert(lapp_context->num_libraries != 0);
|
||||
BLI_assert(!lapp_context->libraries.is_empty());
|
||||
|
||||
Main *mainl;
|
||||
Library *lib;
|
||||
|
||||
for (const int lib_idx : lapp_context->libraries.index_range()) {
|
||||
BlendfileLinkAppendContextLibrary *lib_context = lapp_context->libraries[lib_idx];
|
||||
const char *libname = lib_context->path;
|
||||
BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[lib_idx];
|
||||
const char *libname = lib_context.path.c_str();
|
||||
|
||||
if (!link_append_context_library_blohandle_ensure(lapp_context, lib_context, reports)) {
|
||||
if (!link_append_context_library_blohandle_ensure(*lapp_context, lib_context, reports)) {
|
||||
/* Unlikely since we just browsed it, but possible
|
||||
* Error reports will have been made by BLO_blendhandle_from_file() */
|
||||
continue;
|
||||
@@ -1619,7 +1596,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
|
||||
|
||||
/* here appending/linking starts */
|
||||
|
||||
mainl = BLO_library_link_begin(&lib_context->blo_handle, libname, lapp_context->params);
|
||||
mainl = BLO_library_link_begin(&lib_context.blo_handle, libname, lapp_context->params);
|
||||
lib = mainl->curlib;
|
||||
BLI_assert(lib != nullptr);
|
||||
/* In case lib was already existing but not found originally, see #99820. */
|
||||
@@ -1637,27 +1614,27 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
|
||||
|
||||
/* For each lib file, we try to link all items belonging to that lib,
|
||||
* and tag those successful to not try to load them again with the other libraries. */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *new_id;
|
||||
|
||||
if (!BLI_BITMAP_TEST(item->libraries, lib_idx)) {
|
||||
if (!item.libraries[lib_idx]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_id = BLO_library_link_named_part(
|
||||
mainl, &lib_context->blo_handle, item->idcode, item->name, lapp_context->params);
|
||||
mainl, &lib_context.blo_handle, item.idcode, item.name.c_str(), lapp_context->params);
|
||||
|
||||
if (new_id) {
|
||||
/* If the link is successful, clear item's libraries 'todo' flags.
|
||||
* This avoids trying to link same item with other libraries to come. */
|
||||
BLI_bitmap_set_all(item->libraries, false, lapp_context->num_libraries);
|
||||
item->new_id = new_id;
|
||||
item->source_library = new_id->lib;
|
||||
item.libraries.fill(false);
|
||||
item.new_id = new_id;
|
||||
item.source_library = new_id->lib;
|
||||
}
|
||||
}
|
||||
|
||||
BLO_library_link_end(mainl, &lib_context->blo_handle, lapp_context->params);
|
||||
link_append_context_library_blohandle_release(lapp_context, lib_context);
|
||||
BLO_library_link_end(mainl, &lib_context.blo_handle, lapp_context->params);
|
||||
link_append_context_library_blohandle_release(*lapp_context, lib_context);
|
||||
}
|
||||
|
||||
/* In linking case finalizing process (ensuring all data is valid, instantiating loose
|
||||
@@ -1676,7 +1653,7 @@ void BKE_blendfile_override(BlendfileLinkAppendContext *lapp_context,
|
||||
const eBKELibLinkOverride flags,
|
||||
ReportList * /*reports*/)
|
||||
{
|
||||
if (lapp_context->num_items == 0) {
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Nothing to override. */
|
||||
return;
|
||||
}
|
||||
@@ -1714,20 +1691,20 @@ void BKE_blendfile_override(BlendfileLinkAppendContext *lapp_context,
|
||||
FOREACH_MAIN_ID_END;
|
||||
}
|
||||
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *id = item.new_id;
|
||||
if (id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
BLI_assert(item->userdata == nullptr);
|
||||
BLI_assert(item.userdata == nullptr);
|
||||
|
||||
if (do_use_exisiting_liboverrides) {
|
||||
item->liboverride_id = linked_ids_to_local_liboverrides.lookup_default(id, nullptr);
|
||||
item.liboverride_id = linked_ids_to_local_liboverrides.lookup_default(id, nullptr);
|
||||
}
|
||||
if (item->liboverride_id == nullptr) {
|
||||
item->liboverride_id = BKE_lib_override_library_create_from_id(bmain, id, false);
|
||||
if (item.liboverride_id == nullptr) {
|
||||
item.liboverride_id = BKE_lib_override_library_create_from_id(bmain, id, false);
|
||||
if (set_runtime) {
|
||||
item->liboverride_id->tag |= ID_TAG_RUNTIME;
|
||||
item.liboverride_id->tag |= ID_TAG_RUNTIME;
|
||||
if ((id->tag & ID_TAG_PRE_EXISTING) == 0) {
|
||||
/* If the linked ID is newly linked, in case its override is runtime-only, assume its
|
||||
* reference to be indirectly linked.
|
||||
@@ -1877,14 +1854,14 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
}
|
||||
|
||||
item = BKE_blendfile_link_append_context_item_add(lapp_context, id->name + 2, idcode, id);
|
||||
BLI_bitmap_set_all(item->libraries, true, size_t(lapp_context->num_libraries));
|
||||
item->libraries.fill(true);
|
||||
|
||||
CLOG_INFO(&LOG, 4, "Datablock to seek for: %s", id->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lapp_context->num_items == 0) {
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Early out in case there is nothing to do. */
|
||||
return;
|
||||
}
|
||||
@@ -1899,8 +1876,8 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
/* We add back old id to bmain.
|
||||
* We need to do this in a first, separated loop, otherwise some of those may not be handled by
|
||||
* ID remapping, which means they would still reference old data to be deleted... */
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item->userdata);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item.userdata);
|
||||
|
||||
BLI_assert(old_id);
|
||||
BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
|
||||
@@ -1920,9 +1897,9 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
/* Note that in reload case, we also want to replace indirect usages. */
|
||||
const int remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
|
||||
(do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item->userdata);
|
||||
ID *new_id = item->new_id;
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item.userdata);
|
||||
ID *new_id = item.new_id;
|
||||
|
||||
blendfile_library_relocate_remap(bmain, old_id, new_id, reports, do_reload, remap_flags);
|
||||
if (new_id == nullptr) {
|
||||
@@ -1962,8 +1939,8 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
keep_looping = false;
|
||||
|
||||
BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
|
||||
for (BlendfileLinkAppendContextItem *item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item->userdata);
|
||||
for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
|
||||
ID *old_id = static_cast<ID *>(item.userdata);
|
||||
|
||||
if (old_id == nullptr) {
|
||||
continue;
|
||||
@@ -1973,7 +1950,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
/* Shape Keys are handled as part of their owning obdata (see below). This implies that
|
||||
* there is no way to know when the old pointer gets invalid, so just clear it immediately.
|
||||
*/
|
||||
item->userdata = nullptr;
|
||||
item.userdata = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1981,7 +1958,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
* `lapp_context->params->context` need to be updated before the old Scene ID is freed. */
|
||||
if (old_id == &lapp_context->params->context.scene->id) {
|
||||
BLI_assert(GS(old_id->name) == ID_SCE);
|
||||
Scene *new_scene = (Scene *)item->new_id;
|
||||
Scene *new_scene = reinterpret_cast<Scene *>(item.new_id);
|
||||
BLI_assert(new_scene != nullptr);
|
||||
lapp_context->params->context.scene = new_scene;
|
||||
if (lapp_context->params->context.view_layer != nullptr) {
|
||||
@@ -1996,7 +1973,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
|
||||
if (old_id->us == 0) {
|
||||
old_id->tag |= ID_TAG_DOIT;
|
||||
item->userdata = nullptr;
|
||||
item.userdata = nullptr;
|
||||
keep_looping = true;
|
||||
Key *old_key = BKE_key_from_id(old_id);
|
||||
if (old_key != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user