Fix T76997: bad handling of embedded IDs in partial append.

Code dealing with embedded data was pre-existing proper generic
handling of those by `BKE_library_foreach_ID_link()` - and was never
updated for scene's master collection it would seem...

Note that such fix/refactor is a bit risky at this point in the release
cycle, but on the other end previous situation was really broken. So
finger crossed. :|
This commit is contained in:
Bastien Montagne 2020-05-25 15:11:36 +02:00
parent a8a6b3627a
commit 7a37db6125
Notes: blender-bot 2023-02-14 02:30:10 +01:00
Referenced by issue #76997, Could not link object because the collection 'Master Collection'(of appended scene) is linked
1 changed files with 26 additions and 11 deletions

View File

@ -183,8 +183,6 @@ static void lib_id_library_local_paths(Main *bmain, Library *lib, ID *id)
*/
static void lib_id_clear_library_data_ex(Main *bmain, ID *id)
{
bNodeTree *ntree = NULL;
Key *key = NULL;
const bool id_in_mainlist = (id->tag & LIB_TAG_NO_MAIN) == 0 &&
(id->flag & LIB_EMBEDDED_DATA) == 0;
@ -201,14 +199,11 @@ static void lib_id_clear_library_data_ex(Main *bmain, ID *id)
}
}
/* Internal bNodeTree blocks inside data-blocks also stores id->lib,
* make sure this stays in sync. */
if ((ntree = ntreeFromID(id))) {
lib_id_clear_library_data_ex(bmain, &ntree->id);
}
/* Same goes for shapekeys. */
if ((key = BKE_key_from_id(id))) {
/* Internal shape key blocks inside data-blocks also stores id->lib,
* make sure this stays in sync (note that we do not need any explicit handling for real EMBEDDED
* IDs here, this is down automatically in `lib_id_expand_local_cb()`. */
Key *key = BKE_key_from_id(id);
if (key != NULL) {
lib_id_clear_library_data_ex(bmain, &key->id);
}
}
@ -365,10 +360,23 @@ void BKE_id_clear_newpoin(ID *id)
static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
{
Main *bmain = cb_data->user_data;
ID *id_self = cb_data->id_self;
ID **id_pointer = cb_data->id_pointer;
int const cb_flag = cb_data->cb_flag;
if (cb_flag & IDWALK_CB_LOOPBACK) {
/* We should never have anything to do with loopback pointers here. */
return IDWALK_RET_NOP;
}
if (cb_flag & IDWALK_CB_EMBEDDED) {
/* Embedded data-blocks need to be made fully local as well. */
if (*id_pointer != NULL) {
BLI_assert(*id_pointer != id_self);
lib_id_clear_library_data_ex(bmain, *id_pointer);
}
return IDWALK_RET_NOP;
}
@ -390,7 +398,7 @@ static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
*/
void BKE_lib_id_expand_local(Main *bmain, ID *id)
{
BKE_library_foreach_ID_link(bmain, id, lib_id_expand_local_cb, NULL, IDWALK_READONLY);
BKE_library_foreach_ID_link(bmain, id, lib_id_expand_local_cb, bmain, IDWALK_READONLY);
}
/**
@ -448,6 +456,13 @@ void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
if (ntree && ntree_new) {
ID_NEW_SET(ntree, ntree_new);
}
if (GS(id->name) == ID_SCE) {
Collection *master_collection = ((Scene *)id)->master_collection,
*master_collection_new = ((Scene *)id_new)->master_collection;
if (master_collection && master_collection_new) {
ID_NEW_SET(master_collection, master_collection_new);
}
}
if (!lib_local) {
BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);