diff options
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.c')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 365 |
1 files changed, 231 insertions, 134 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 649e7dab5d1..59cb6b2036e 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -161,6 +161,8 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f (ID *)src_id; id_us_plus(dst_id->override_library->reference); + dst_id->override_library->hierarchy_root = src_id->override_library->hierarchy_root; + if (do_full_copy) { BLI_duplicatelist(&dst_id->override_library->properties, &src_id->override_library->properties); @@ -211,6 +213,7 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bo } static ID *lib_override_library_create_from(Main *bmain, + Library *owner_library, ID *reference_id, const int lib_id_copy_flags) { @@ -227,6 +230,12 @@ static ID *lib_override_library_create_from(Main *bmain, } id_us_min(local_id); + /* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to + * generic ID copy code? */ + if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) == 0) { + local_id->lib = owner_library; + } + BKE_lib_override_library_init(local_id, reference_id); /* NOTE: From liboverride perspective (and RNA one), shape keys are considered as local embedded @@ -281,11 +290,12 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, BLI_assert(reference_id != NULL); BLI_assert(ID_IS_LINKED(reference_id)); - ID *local_id = lib_override_library_create_from(bmain, reference_id, 0); + ID *local_id = lib_override_library_create_from(bmain, NULL, reference_id, 0); /* We cannot allow automatic hierarchy resync on this ID, it is highly likely to generate a giant * mess in case there are a lot of hidden, non-instantiated, non-properly organized dependencies. * Ref T94650. */ local_id->override_library->flag |= IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY; + local_id->override_library->hierarchy_root = local_id; if (do_tagged_remap) { Key *reference_key, *local_key = NULL; @@ -320,9 +330,19 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, } bool BKE_lib_override_library_create_from_tag(Main *bmain, - const Library *reference_library, + Library *owner_library, + const ID *id_root_reference, + ID *id_hierarchy_root, const bool do_no_main) { + BLI_assert(id_root_reference != NULL); + BLI_assert(id_hierarchy_root != NULL || (id_root_reference->tag & LIB_TAG_DOIT) != 0); + BLI_assert(id_hierarchy_root == NULL || + (ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root) && + id_hierarchy_root->override_library->reference == id_root_reference)); + + const Library *reference_library = id_root_reference->lib; + ID *reference_id; bool success = true; @@ -351,7 +371,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, * This requires extra care further down the resync process, * see: #BKE_lib_override_library_resync. */ reference_id->newid = lib_override_library_create_from( - bmain, reference_id, do_no_main ? LIB_ID_CREATE_NO_MAIN : 0); + bmain, owner_library, reference_id, do_no_main ? LIB_ID_CREATE_NO_MAIN : 0); if (reference_id->newid == NULL) { success = false; break; @@ -375,6 +395,11 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, /* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole * existing linked IDs usages. */ if (success) { + if (id_root_reference->newid != NULL) { + id_hierarchy_root = id_root_reference->newid; + } + BLI_assert(id_hierarchy_root != NULL); + for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) { reference_id = todo_id_iter->data; ID *local_id = reference_id->newid; @@ -383,6 +408,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, continue; } + local_id->override_library->hierarchy_root = id_hierarchy_root; + Key *reference_key, *local_key = NULL; if ((reference_key = BKE_key_from_id(reference_id)) != NULL) { local_key = BKE_key_from_id(reference_id->newid); @@ -451,6 +478,7 @@ typedef struct LibOverrideGroupTagData { Main *bmain; Scene *scene; ID *id_root; + ID *hierarchy_root_id; uint tag; uint missing_tag; /* Whether we are looping on override data, or their references (linked) one. */ @@ -761,6 +789,8 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData * BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner)); BLI_assert(data->is_override); + ID *id_hierarchy_root = data->hierarchy_root_id; + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_owner) && (id_owner->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) != 0) { return; @@ -792,9 +822,15 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData * if (ELEM(to_id, NULL, id_owner)) { continue; } + /* Different libraries or different hierarchy roots are break points in override hierarchies. + */ if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id_owner->lib)) { continue; } + if (ID_IS_OVERRIDE_LIBRARY_REAL(to_id) && + to_id->override_library->hierarchy_root != id_hierarchy_root) { + continue; + } Library *reference_lib = lib_override_get(bmain, id_owner)->reference->lib; ID *to_id_reference = lib_override_get(bmain, to_id)->reference; @@ -824,6 +860,11 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data) BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root)); BLI_assert(data->is_override); + ID *id_hierarchy_root = data->hierarchy_root_id; + BLI_assert(id_hierarchy_root != NULL); + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root)); + UNUSED_VARS_NDEBUG(id_hierarchy_root); + if (id_root->override_library->reference->tag & LIB_TAG_MISSING) { id_root->tag |= data->missing_tag; } @@ -835,7 +876,10 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data) lib_override_overrides_group_tag_recursive(data); } -static bool lib_override_library_create_do(Main *bmain, Scene *scene, ID *id_root) +static bool lib_override_library_create_do(Main *bmain, + Scene *scene, + Library *owner_library, + ID *id_root) { BKE_main_relations_create(bmain, 0); LibOverrideGroupTagData data = {.bmain = bmain, @@ -854,12 +898,16 @@ static bool lib_override_library_create_do(Main *bmain, Scene *scene, ID *id_roo BKE_main_relations_free(bmain); lib_override_group_tag_data_clear(&data); - return BKE_lib_override_library_create_from_tag(bmain, id_root->lib, false); + const bool success = BKE_lib_override_library_create_from_tag( + bmain, owner_library, id_root, NULL, false); + + return success; } static void lib_override_library_create_post_process(Main *bmain, Scene *scene, ViewLayer *view_layer, + const Library *owner_library, ID *id_root, ID *id_reference, Collection *residual_storage, @@ -881,7 +929,8 @@ static void lib_override_library_create_post_process(Main *bmain, /* Instantiating the root collection or object should never be needed in resync case, since the * old override would be remapped to the new one. */ - if (!is_resync && id_root != NULL && id_root->newid != NULL && !ID_IS_LINKED(id_root->newid)) { + if (!is_resync && id_root != NULL && id_root->newid != NULL && + (!ID_IS_LINKED(id_root->newid) || id_root->newid->lib == owner_library)) { switch (GS(id_root->name)) { case ID_GR: { Object *ob_reference = id_reference != NULL && GS(id_reference->name) == ID_OB ? @@ -926,7 +975,7 @@ static void lib_override_library_create_post_process(Main *bmain, Collection *default_instantiating_collection = residual_storage; LISTBASE_FOREACH (Object *, ob, &bmain->objects) { Object *ob_new = (Object *)ob->id.newid; - if (ob_new == NULL || ID_IS_LINKED(ob_new)) { + if (ob_new == NULL || (ID_IS_LINKED(ob_new) && ob_new->id.lib != owner_library)) { continue; } @@ -989,6 +1038,7 @@ static void lib_override_library_create_post_process(Main *bmain, bool BKE_lib_override_library_create(Main *bmain, Scene *scene, ViewLayer *view_layer, + Library *owner_library, ID *id_root, ID *id_reference, ID **r_id_root_override) @@ -997,7 +1047,7 @@ bool BKE_lib_override_library_create(Main *bmain, *r_id_root_override = NULL; } - const bool success = lib_override_library_create_do(bmain, scene, id_root); + const bool success = lib_override_library_create_do(bmain, scene, owner_library, id_root); if (!success) { return success; @@ -1008,7 +1058,7 @@ bool BKE_lib_override_library_create(Main *bmain, } lib_override_library_create_post_process( - bmain, scene, view_layer, id_root, id_reference, NULL, false); + bmain, scene, view_layer, owner_library, id_root, id_reference, NULL, false); /* Cleanup. */ BKE_main_id_newptr_and_tag_clear(bmain); @@ -1033,120 +1083,187 @@ bool BKE_lib_override_library_template_create(struct ID *id) return true; } -bool BKE_lib_override_library_proxy_convert(Main *bmain, - Scene *scene, - ViewLayer *view_layer, - Object *ob_proxy) +static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int *r_best_level) { - /* `proxy_group`, if defined, is the empty instantiating the collection from which the proxy is - * coming. */ - Object *ob_proxy_group = ob_proxy->proxy_group; - const bool is_override_instancing_object = ob_proxy_group != NULL; - ID *id_root = is_override_instancing_object ? &ob_proxy_group->instance_collection->id : - &ob_proxy->proxy->id; - ID *id_reference = is_override_instancing_object ? &ob_proxy_group->id : &ob_proxy->id; + if (curr_level > 1000) { + CLOG_ERROR(&LOG, + "Levels of dependency relationships between library overrides IDs is way too high, " + "skipping further processing loops (involves at least '%s')", + id->name); + BLI_assert(0); + return NULL; + } - /* In some cases the instance collection of a proxy object may be local (see e.g. T83875). Not - * sure this is a valid state, but for now just abort the overriding process. */ - if (!ID_IS_OVERRIDABLE_LIBRARY(id_root)) { - return false; + if (!ID_IS_OVERRIDE_LIBRARY(id)) { + BLI_assert(0); + return NULL; } - /* We manually convert the proxy object into a library override, further override handling will - * then be handled by `BKE_lib_override_library_create()` just as for a regular override - * creation. - */ - ob_proxy->proxy->id.tag |= LIB_TAG_DOIT; - ob_proxy->proxy->id.newid = &ob_proxy->id; - BKE_lib_override_library_init(&ob_proxy->id, &ob_proxy->proxy->id); + MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id); + BLI_assert(entry != NULL); - ob_proxy->proxy->proxy_from = NULL; - ob_proxy->proxy = ob_proxy->proxy_group = NULL; + int best_level_candidate = curr_level; + ID *best_root_id_candidate = id; - DEG_id_tag_update(&ob_proxy->id, ID_RECALC_COPY_ON_WRITE); + for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL; + from_id_entry = from_id_entry->next) { + if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships as actual dependencies. */ + continue; + } + + ID *from_id = from_id_entry->id_pointer.from; + if (ELEM(from_id, NULL, id)) { + continue; + } + if (!ID_IS_OVERRIDE_LIBRARY(from_id) || (from_id->lib != id->lib)) { + continue; + } - /* In case of proxy conversion, remap all local ID usages to linked IDs to their newly created - * overrides. - * While this might not be 100% the desired behavior, it is likely to be the case most of the - * time. Ref: T91711. */ - ID *id_iter; - FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { - if (!ID_IS_LINKED(id_iter)) { - id_iter->tag |= LIB_TAG_DOIT; + int level_candidate = curr_level + 1; + /* Recursively process the parent. */ + ID *root_id_candidate = lib_override_root_find( + bmain, from_id, curr_level + 1, &level_candidate); + if (level_candidate > best_level_candidate && root_id_candidate != NULL) { + best_root_id_candidate = root_id_candidate; + best_level_candidate = level_candidate; } } - FOREACH_MAIN_ID_END; - return BKE_lib_override_library_create(bmain, scene, view_layer, id_root, id_reference, NULL); + *r_best_level = best_level_candidate; + return best_root_id_candidate; } -static void lib_override_library_proxy_convert_do(Main *bmain, - Scene *scene, - Object *ob_proxy, - BlendFileReadReport *reports) +static void lib_override_root_hierarchy_set(Main *bmain, ID *id_root, ID *id, ID *id_from) { - Object *ob_proxy_group = ob_proxy->proxy_group; - const bool is_override_instancing_object = ob_proxy_group != NULL; + if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + if (id->override_library->hierarchy_root == id_root) { + /* Already set, nothing else to do here, sub-hierarchy is also assumed to be properly set + * then. */ + return; + } - const bool success = BKE_lib_override_library_proxy_convert(bmain, scene, NULL, ob_proxy); + /* Hierarchy root already set, and not matching currently proposed one, try to find which is + * best. */ + if (id->override_library->hierarchy_root != NULL) { + /* Check if given `id_from` matches with the hierarchy of the linked reference ID, in which + * case we assume that the given hierarchy root is the 'real' one. + * + * NOTE: This can fail if user mixed dependencies between several overrides of a same + * reference linked hierarchy. Not much to be done in that case, it's virtually impossible to + * fix this automatically in a reliable way. */ + if (id_from == NULL || !ID_IS_OVERRIDE_LIBRARY_REAL(id_from)) { + /* Too complicated to deal with for now. */ + CLOG_WARN(&LOG, + "Inconsistency in library override hierarchy of ID '%s'.\n" + "\tNot enough data to verify validity of current proposed root '%s', assuming " + "already set one '%s' is valid.", + id->name, + id_root->name, + id->override_library->hierarchy_root->name); + return; + } - if (success) { - CLOG_INFO(&LOG, - 4, - "Proxy object '%s' successfully converted to library overrides", - ob_proxy->id.name); - /* Remove the instance empty from this scene, the items now have an overridden collection - * instead. */ - if (is_override_instancing_object) { - BKE_scene_collections_object_remove(bmain, scene, ob_proxy_group, true); - } - reports->count.proxies_to_lib_overrides_success++; - } -} + ID *id_from_ref = id_from->override_library->reference; + MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, + id->override_library->reference); + BLI_assert(entry != NULL); -void BKE_lib_override_library_main_proxy_convert(Main *bmain, BlendFileReadReport *reports) -{ - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - LinkNodePair proxy_objects = {NULL}; + bool do_replace_root = false; + for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL; + from_id_entry = from_id_entry->next) { + if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships as actual dependencies. */ + continue; + } - FOREACH_SCENE_OBJECT_BEGIN (scene, object) { - if (object->proxy_group != NULL) { - BLI_linklist_append(&proxy_objects, object); + if (id_from_ref == from_id_entry->id_pointer.from) { + /* A matching parent was found in reference linked data, assume given hierarchy root is + * the valid one. */ + do_replace_root = true; + CLOG_WARN( + &LOG, + "Inconsistency in library override hierarchy of ID '%s'.\n" + "\tCurrent proposed root '%s' detected as valid, will replace already set one '%s'.", + id->name, + id_root->name, + id->override_library->hierarchy_root->name); + break; + } } - } - FOREACH_SCENE_OBJECT_END; - FOREACH_SCENE_OBJECT_BEGIN (scene, object) { - if (object->proxy != NULL && object->proxy_group == NULL) { - BLI_linklist_append(&proxy_objects, object); + if (!do_replace_root) { + CLOG_WARN( + &LOG, + "Inconsistency in library override hierarchy of ID '%s'.\n" + "\tCurrent proposed root '%s' not detected as valid, keeping already set one '%s'.", + id->name, + id_root->name, + id->override_library->hierarchy_root->name); + return; } } - FOREACH_SCENE_OBJECT_END; - for (LinkNode *proxy_object_iter = proxy_objects.list; proxy_object_iter != NULL; - proxy_object_iter = proxy_object_iter->next) { - Object *proxy_object = proxy_object_iter->link; - lib_override_library_proxy_convert_do(bmain, scene, proxy_object, reports); + id->override_library->hierarchy_root = id_root; + } + + MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id); + BLI_assert(entry != NULL); + + for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL; + to_id_entry = to_id_entry->next) { + if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships as actual dependencies. */ + continue; } - BLI_linklist_free(proxy_objects.list, NULL); + ID *to_id = *to_id_entry->id_pointer.to; + if (ELEM(to_id, NULL, id)) { + continue; + } + if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id->lib)) { + continue; + } + + /* Recursively process the sub-hierarchy. */ + lib_override_root_hierarchy_set(bmain, id_root, to_id, id); } +} - LISTBASE_FOREACH (Object *, object, &bmain->objects) { - if (ID_IS_LINKED(object)) { - if (object->proxy != NULL) { - CLOG_WARN(&LOG, "Did not try to convert linked proxy object '%s'", object->id.name); - reports->count.linked_proxies++; - } +void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain) +{ + ID *id; + + BKE_main_relations_create(bmain, 0); + + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { continue; } + if (id->override_library->hierarchy_root != NULL) { + continue; + } + + int best_level = 0; + ID *id_root = lib_override_root_find(bmain, id, best_level, &best_level); - if (object->proxy_group != NULL || object->proxy != NULL) { - CLOG_WARN( - &LOG, "Proxy object '%s' failed to be converted to library override", object->id.name); - reports->count.proxies_to_lib_overrides_failures++; + if (!ELEM(id_root->override_library->hierarchy_root, id_root, NULL)) { + CLOG_WARN(&LOG, + "Potential inconsistency in library override hierarchy of ID '%s', detected as " + "part of the hierarchy of '%s', which has a different root '%s'", + id->name, + id_root->name, + id_root->override_library->hierarchy_root->name); + continue; } + + lib_override_root_hierarchy_set(bmain, id_root, id_root, NULL); + + BLI_assert(id->override_library->hierarchy_root != NULL); } + FOREACH_MAIN_ID_END; + + BKE_main_relations_free(bmain); } static void lib_override_library_remap(Main *bmain, @@ -1214,6 +1331,7 @@ static bool lib_override_library_resync(Main *bmain, LibOverrideGroupTagData data = {.bmain = bmain, .scene = scene, .id_root = id_root, + .hierarchy_root_id = id_root->override_library->hierarchy_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING, .is_override = true, @@ -1316,7 +1434,7 @@ static bool lib_override_library_resync(Main *bmain, * override IDs (including within the old overrides themselves, since those are tagged too * above). */ const bool success = BKE_lib_override_library_create_from_tag( - bmain, id_root_reference->lib, true); + bmain, NULL, id_root_reference, id_root->override_library->hierarchy_root, true); if (!success) { return success; @@ -1530,6 +1648,7 @@ static bool lib_override_library_resync(Main *bmain, lib_override_library_create_post_process(bmain, scene, view_layer, + NULL, id_root_reference, id_root, override_resync_residual_storage, @@ -1634,46 +1753,20 @@ static void lib_override_resync_tagging_finalize_recurse(Main *bmain, * * NOTE: Related to `lib_override_resync_tagging_finalize` above. */ -static ID *lib_override_library_main_resync_find_root_recurse(ID *id, int *level) -{ - (*level)++; - ID *return_id = id; - - switch (GS(id->name)) { - case ID_GR: { - /* Find the highest valid collection in the parenting hierarchy. - * Note that in practice, in any decent common case there is only one well defined root - * collection anyway. */ - int max_level = *level; - Collection *collection = (Collection *)id; - LISTBASE_FOREACH (CollectionParent *, collection_parent_iter, &collection->parents) { - Collection *collection_parent = collection_parent_iter->collection; - if (ID_IS_OVERRIDE_LIBRARY_REAL(collection_parent) && - collection_parent->id.lib == id->lib) { - int tmp_level = *level; - ID *tmp_id = lib_override_library_main_resync_find_root_recurse(&collection_parent->id, - &tmp_level); - if (tmp_level > max_level) { - max_level = tmp_level; - return_id = tmp_id; - } - } - } - break; - } - case ID_OB: { - Object *object = (Object *)id; - if (object->parent != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(object->parent) && - object->parent->id.lib == id->lib) { - return_id = lib_override_library_main_resync_find_root_recurse(&object->parent->id, level); - } - break; +static ID *lib_override_library_main_resync_root_get(Main *bmain, ID *id) +{ + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id); + if (id_type->owner_get != NULL) { + id = id_type->owner_get(bmain, id); } - default: - break; + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id)); } - return return_id; + ID *hierarchy_root_id = id->override_library->hierarchy_root; + BLI_assert(hierarchy_root_id != NULL); + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(hierarchy_root_id)); + return hierarchy_root_id; } /* Ensure resync of all overrides at one level of indirect usage. @@ -1815,14 +1908,13 @@ static void lib_override_library_main_resync_on_library_indirect_level( Library *library = id->lib; - int level = 0; /* In complex non-supported cases, with several different override hierarchies sharing * relations between each-other, we may end up not actually updating/replacing the given * root id (see e.g. pro/shots/110_rextoria/110_0150_A/110_0150_A.anim.blend of sprites * project repository, r2687). * This can lead to infinite loop here, at least avoid this. */ id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC; - id = lib_override_library_main_resync_find_root_recurse(id, &level); + id = lib_override_library_main_resync_root_get(bmain, id); id->tag &= ~LIB_TAG_LIB_OVERRIDE_NEED_RESYNC; BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id)); BLI_assert(id->lib == library); @@ -1863,7 +1955,8 @@ static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data) ID *id_owner = cb_data->id_owner; ID *id = *cb_data->id_pointer; if (id != NULL && ID_IS_LINKED(id) && id->lib != id_owner->lib) { - const int owner_library_indirect_level = id_owner->lib != NULL ? id_owner->lib->temp_index : 0; + const int owner_library_indirect_level = ID_IS_LINKED(id_owner) ? id_owner->lib->temp_index : + 0; if (owner_library_indirect_level > 10000) { CLOG_ERROR( &LOG, @@ -1954,7 +2047,7 @@ void BKE_lib_override_library_main_resync(Main *bmain, /* Essentially ensures that potentially new overrides of new objects will be instantiated. */ lib_override_library_create_post_process( - bmain, scene, view_layer, NULL, NULL, override_resync_residual_storage, true); + bmain, scene, view_layer, NULL, NULL, NULL, override_resync_residual_storage, true); if (BKE_collection_is_empty(override_resync_residual_storage)) { BKE_collection_delete(bmain, override_resync_residual_storage, true); @@ -1980,6 +2073,7 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root) LibOverrideGroupTagData data = {.bmain = bmain, .scene = NULL, .id_root = id_root, + .hierarchy_root_id = id_root->override_library->hierarchy_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING, .is_override = true, @@ -2904,6 +2998,8 @@ void BKE_lib_override_library_update(Main *bmain, ID *local) return; } + tmp_id->lib = local->lib; + /* This ID name is problematic, since it is an 'rna name property' it should not be editable or * different from reference linked ID. But local ID names need to be unique in a given type * list of Main, so we cannot always keep it identical, which is why we need this special @@ -2916,6 +3012,7 @@ void BKE_lib_override_library_update(Main *bmain, ID *local) Key *tmp_key = BKE_key_from_id(tmp_id); if (local_key != NULL && tmp_key != NULL) { tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE); + tmp_key->id.lib = local_key->id.lib; } PointerRNA rnaptr_src, rnaptr_dst, rnaptr_storage_stack, *rnaptr_storage = NULL; |