Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.cc')
-rw-r--r--source/blender/blenkernel/intern/lib_override.cc77
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)) {