diff options
author | Hans Goudey <h.goudey@me.com> | 2022-07-20 05:50:45 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-07-20 05:50:45 +0300 |
commit | 8c5d90f5ce928e45249ddd9f642c24b6dd69d64c (patch) | |
tree | ccbbf8f065eadbe85cdc1f8d70a9d036e9c030b5 /source/blender/blenkernel/intern/lib_override.cc | |
parent | 111bf7d76b080555fd524b2b4a138bcad2e5b206 (diff) | |
parent | 215f805ce6b540177dedd71721e62c56a764a5ea (diff) |
Merge branch 'master' into temp-legacy-mesh-format-optiontemp-legacy-mesh-format-option
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.cc')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.cc | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index d816b5ede5f..0c5f59be768 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -428,14 +428,42 @@ 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) { + if (reference_id->newid != 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 +572,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 +597,14 @@ 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; + if (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 +612,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 +623,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, @@ -1121,14 +1149,26 @@ static bool lib_override_library_create_do(Main *bmain, BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false); lib_override_hierarchy_dependencies_recursive_tag(&data); + /* In case the operation is on an already partially overridden hierarchy, all existing overrides + * in that hierarchy need to be tagged for remapping from linked reference ID usages to newly + * created overrides ones. */ + if (id_hierarchy_root_reference->lib != id_root_reference->lib) { + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference)); + BLI_assert(id_hierarchy_root_reference->override_library->reference->lib == + id_root_reference->lib); + + BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false); + data.hierarchy_root_id = id_hierarchy_root_reference; + data.id_root = id_hierarchy_root_reference; + data.is_override = true; + lib_override_overrides_group_tag(&data); + } + BKE_main_relations_free(bmain); lib_override_group_tag_data_clear(&data); bool success = false; if (id_hierarchy_root_reference->lib != id_root_reference->lib) { - BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference)); - BLI_assert(id_hierarchy_root_reference->override_library->reference->lib == - id_root_reference->lib); success = BKE_lib_override_library_create_from_tag(bmain, owner_library, id_root_reference, @@ -1771,6 +1811,11 @@ static bool lib_override_library_resync(Main *bmain, break; } } + if (reference_id == nullptr) { + /* Can happen e.g. when there is a local override of a shapekey, but the matching linked + * obdata (mesh etc.) does not have any shapekey anymore. */ + continue; + } BLI_assert(GS(reference_id->name) == GS(id->name)); if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) { |