Fix T99261: partial LibOverride creation would not properly remap all needed data.

When creating partial overrides, there may also be need to reamap usage
of linked data towards already existing overrides, in newly created
overrides.
This commit is contained in:
Bastien Montagne 2022-07-12 14:27:50 +02:00
parent 4344b2bf19
commit 57097e9a85
Notes: blender-bot 2023-02-14 08:25:14 +01:00
Referenced by commit 4a445c8dc0, LibOverride: Fix some issues from.revealed by recent previous commit.
Referenced by issue #99261, Driver relationship is broken in linked scenes, when override is done in wrong order
1 changed files with 38 additions and 13 deletions

View File

@ -428,14 +428,40 @@ static void lib_override_prefill_newid_from_existing_overrides(Main *bmain, ID *
{
ID *id_iter;
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) &&
id_iter->override_library->hierarchy_root == id_hierarchy_root) {
id_iter->override_library->reference->newid = id_iter;
ID *id = id_iter;
if (GS(id_iter->name) == ID_KE) {
id = reinterpret_cast<Key *>(id_iter)->from;
BLI_assert(id != nullptr);
}
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
id->override_library->hierarchy_root == id_hierarchy_root) {
id->override_library->reference->newid = id;
if (GS(id_iter->name) == ID_KE) {
Key *reference_key = BKE_key_from_id(id->override_library->reference);
if (reference_key != nullptr) {
reference_key->id.newid = id_iter;
}
}
}
}
FOREACH_MAIN_ID_END;
}
static void lib_override_remapper_overrides_add(IDRemapper *id_remapper,
ID *reference_id,
ID *local_id)
{
BKE_id_remapper_add(id_remapper, reference_id, local_id);
Key *reference_key, *local_key = nullptr;
if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
local_key = BKE_key_from_id(reference_id->newid);
BLI_assert(local_key != nullptr);
BKE_id_remapper_add(id_remapper, &reference_key->id, &local_key->id);
}
}
/* TODO: Make this static local function instead? API is becoming complex, and it's not used
* outside of this file anyway. */
bool BKE_lib_override_library_create_from_tag(Main *bmain,
@ -544,6 +570,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
BLI_assert(id_hierarchy_root != nullptr);
LinkNode *relinked_ids = nullptr;
IDRemapper *id_remapper = BKE_id_remapper_create();
/* Still checking the whole Main, that way we can tag other local IDs as needing to be
* remapped to use newly created overriding IDs, if needed. */
ID *id;
@ -568,6 +595,13 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
* consider we should also relink it, as part of recursive resync. */
if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib != id_root_reference->lib) {
BLI_linklist_prepend(&relinked_ids, other_id);
if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) &&
other_id->override_library->hierarchy_root == id_hierarchy_root) {
reference_id = other_id->override_library->reference;
ID *local_id = reference_id->newid;
BLI_assert(other_id == local_id);
lib_override_remapper_overrides_add(id_remapper, reference_id, local_id);
}
}
if (other_id != id) {
other_id->lib = id_root_reference->lib;
@ -575,7 +609,6 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
}
FOREACH_MAIN_ID_END;
IDRemapper *id_remapper = BKE_id_remapper_create();
for (todo_id_iter = static_cast<LinkData *>(todo_ids.first); todo_id_iter != nullptr;
todo_id_iter = todo_id_iter->next) {
reference_id = static_cast<ID *>(todo_id_iter->data);
@ -587,15 +620,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
local_id->override_library->hierarchy_root = id_hierarchy_root;
BKE_id_remapper_add(id_remapper, reference_id, local_id);
Key *reference_key, *local_key = nullptr;
if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
local_key = BKE_key_from_id(reference_id->newid);
BLI_assert(local_key != nullptr);
BKE_id_remapper_add(id_remapper, &reference_key->id, &local_key->id);
}
lib_override_remapper_overrides_add(id_remapper, reference_id, local_id);
}
BKE_libblock_relink_multiple(bmain,