diff options
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.cc')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.cc | 401 |
1 files changed, 231 insertions, 170 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 05a00fb54fd..3f1b80014ac 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -92,27 +92,22 @@ BLI_INLINE void lib_override_object_posemode_transfer(ID *id_dst, ID *id_src) } /** Get override data for a given ID. Needed because of our beloved shape keys snowflake. */ -BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main *bmain, +BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main * /*bmain*/, const ID *id, - const ID *owner_id_hint, + const ID * /*owner_id_hint*/, const ID **r_owner_id) { - if (r_owner_id != nullptr) { - *r_owner_id = id; - } if (id->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) { - const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id); - if (id_type->owner_get != nullptr) { - /* The #IDTypeInfo::owner_get callback should not modify the arguments, so casting away const - * is okay. */ - const ID *owner_id = id_type->owner_get( - const_cast<Main *>(bmain), const_cast<ID *>(id), const_cast<ID *>(owner_id_hint)); - if (r_owner_id != nullptr) { - *r_owner_id = owner_id; - } - return owner_id->override_library; + const ID *owner_id = BKE_id_owner_get(const_cast<ID *>(id)); + BLI_assert_msg(owner_id != nullptr, "Liboverride-embedded ID with no owner"); + if (r_owner_id != nullptr) { + *r_owner_id = owner_id; } - BLI_assert_msg(0, "IDTypeInfo of liboverride-embedded ID with no owner getter"); + return owner_id->override_library; + } + + if (r_owner_id != nullptr) { + *r_owner_id = id; } return id->override_library; } @@ -366,6 +361,10 @@ static int foreachid_is_hierarchy_leaf_fn(LibraryIDLinkCallbackData *cb_data) ID *id = *cb_data->id_pointer; bool *is_leaf = static_cast<bool *>(cb_data->user_data); + if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) { + return IDWALK_RET_NOP; + } + if (id != nullptr && ID_IS_OVERRIDE_LIBRARY_REAL(id) && id->override_library->hierarchy_root == id_owner->override_library->hierarchy_root) { *is_leaf = false; @@ -1208,6 +1207,7 @@ static void lib_override_library_create_post_process(Main *bmain, ID *id_root, ID *id_instance_hint, Collection *residual_storage, + const Object *old_active_object, const bool is_resync) { /* NOTE: We only care about local IDs here, if a linked object is not instantiated in any way we @@ -1269,6 +1269,8 @@ static void lib_override_library_create_post_process(Main *bmain, } } + BKE_view_layer_synced_ensure(scene, view_layer); + /* We need to ensure all new overrides of objects are properly instantiated. */ Collection *default_instantiating_collection = residual_storage; LISTBASE_FOREACH (Object *, ob, &bmain->objects) { @@ -1280,6 +1282,14 @@ static void lib_override_library_create_post_process(Main *bmain, BLI_assert(ob_new->id.override_library != nullptr && ob_new->id.override_library->reference == &ob->id); + if (old_active_object == ob) { + Base *basact = BKE_view_layer_base_find(view_layer, ob_new); + if (basact != nullptr) { + view_layer->basact = basact; + } + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + } + if (BLI_gset_lookup(all_objects_in_scene, ob_new) == nullptr) { if (id_root != nullptr && default_instantiating_collection == nullptr) { ID *id_ref = id_root->newid != nullptr ? id_root->newid : id_root; @@ -1369,6 +1379,8 @@ bool BKE_lib_override_library_create(Main *bmain, if (id_hierarchy_root_reference == nullptr) { id_hierarchy_root_reference = id_root_reference; } + BKE_view_layer_synced_ensure(scene, view_layer); + const Object *old_active_object = BKE_view_layer_active_object_get(view_layer); const bool success = lib_override_library_create_do(bmain, scene, @@ -1392,6 +1404,7 @@ bool BKE_lib_override_library_create(Main *bmain, id_root_reference, id_instance_hint, nullptr, + old_active_object, false); /* Cleanup. */ @@ -1705,6 +1718,8 @@ static bool lib_override_library_resync(Main *bmain, ID *id_root_reference = id_root->override_library->reference; ID *id; + BKE_view_layer_synced_ensure(scene, view_layer); + const Object *old_active_object = BKE_view_layer_active_object_get(view_layer); if (id_root_reference->tag & LIB_TAG_MISSING) { BKE_reportf(reports != nullptr ? reports->reports : nullptr, @@ -1785,6 +1800,10 @@ static bool lib_override_library_resync(Main *bmain, lib_override_hierarchy_dependencies_recursive_tag(&data); FOREACH_MAIN_ID_BEGIN (bmain, id) { + if ((id->lib != id_root->lib) || !ID_IS_OVERRIDE_LIBRARY(id)) { + continue; + } + /* IDs that get fully removed from linked data remain as local overrides (using place-holder * linked IDs as reference), but they are often not reachable from any current valid local * override hierarchy anymore. This will ensure they get properly deleted at the end of this @@ -1798,69 +1817,67 @@ static bool lib_override_library_resync(Main *bmain, id->tag |= LIB_TAG_MISSING; } - if ((id->lib == id_root->lib) && ID_IS_OVERRIDE_LIBRARY(id)) { - /* While this should not happen in typical cases (and won't be properly supported here), - * user is free to do all kind of very bad things, including having different local - * overrides of a same linked ID in a same hierarchy. */ - IDOverrideLibrary *id_override_library = BKE_lib_override_library_get( - bmain, id, nullptr, nullptr); + /* While this should not happen in typical cases (and won't be properly supported here), + * user is free to do all kind of very bad things, including having different local + * overrides of a same linked ID in a same hierarchy. */ + IDOverrideLibrary *id_override_library = BKE_lib_override_library_get( + bmain, id, nullptr, nullptr); - if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) { - continue; - } + if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) { + continue; + } - ID *reference_id = id_override_library->reference; - if (GS(reference_id->name) != GS(id->name)) { - switch (GS(id->name)) { - case ID_KE: - reference_id = reinterpret_cast<ID *>(BKE_key_from_id(reference_id)); - break; - case ID_GR: - BLI_assert(GS(reference_id->name) == ID_SCE); - reference_id = reinterpret_cast<ID *>( - reinterpret_cast<Scene *>(reference_id)->master_collection); - break; - case ID_NT: - reference_id = reinterpret_cast<ID *>(ntreeFromID(id)); - break; - default: - break; - } + ID *reference_id = id_override_library->reference; + if (GS(reference_id->name) != GS(id->name)) { + switch (GS(id->name)) { + case ID_KE: + reference_id = reinterpret_cast<ID *>(BKE_key_from_id(reference_id)); + break; + case ID_GR: + BLI_assert(GS(reference_id->name) == ID_SCE); + reference_id = reinterpret_cast<ID *>( + reinterpret_cast<Scene *>(reference_id)->master_collection); + break; + case ID_NT: + reference_id = reinterpret_cast<ID *>(ntreeFromID(id)); + break; + default: + 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. */ + } + if (reference_id == nullptr) { + /* Can happen e.g. when there is a local override of a shape-key, but the matching linked + * obdata (mesh etc.) does not have any shape-key anymore. */ + continue; + } + BLI_assert(GS(reference_id->name) == GS(id->name)); + + if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) { + BLI_ghash_insert(linkedref_to_old_override, reference_id, id); + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || (id->tag & LIB_TAG_DOIT) == 0) { continue; } - BLI_assert(GS(reference_id->name) == GS(id->name)); + if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) { + /* We have an override, but now it does not seem to be necessary to override that ID + * anymore. Check if there are some actual overrides from the user, otherwise assume + * that we can get rid of this local override. */ + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { + if (!ELEM(op->rna_prop_type, PROP_POINTER, PROP_COLLECTION)) { + id->override_library->reference->tag |= LIB_TAG_DOIT; + break; + } - if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) { - BLI_ghash_insert(linkedref_to_old_override, reference_id, id); - if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || (id->tag & LIB_TAG_DOIT) == 0) { - continue; - } - if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) { - /* We have an override, but now it does not seem to be necessary to override that ID - * anymore. Check if there are some actual overrides from the user, otherwise assume - * that we can get rid of this local override. */ - LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { - if (!ELEM(op->rna_prop_type, PROP_POINTER, PROP_COLLECTION)) { + bool do_break = false; + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { id->override_library->reference->tag |= LIB_TAG_DOIT; - break; - } - - bool do_break = false; - LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { - id->override_library->reference->tag |= LIB_TAG_DOIT; - do_break = true; - break; - } - } - if (do_break) { + do_break = true; break; } } + if (do_break) { + break; + } } } } @@ -1902,60 +1919,62 @@ static bool lib_override_library_resync(Main *bmain, ListBase *lb; FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) { FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id) { - if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) { - ID *id_override_new = id->newid; - ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr || + id->lib != id_root_reference->lib) { + continue; + } + ID *id_override_new = id->newid; + ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); - BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); - - /* We need to 'move back' newly created override into its proper library (since it was - * duplicated from the reference ID with 'no main' option, it should currently be the same - * as the reference ID one). */ - BLI_assert(/*!ID_IS_LINKED(id_override_new) || */ id_override_new->lib == id->lib); - BLI_assert(id_override_old == nullptr || id_override_old->lib == id_root->lib); - id_override_new->lib = id_root->lib; - /* Remap step below will tag directly linked ones properly as needed. */ - if (ID_IS_LINKED(id_override_new)) { - id_override_new->tag |= LIB_TAG_INDIRECT; - } + BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); + + /* We need to 'move back' newly created override into its proper library (since it was + * duplicated from the reference ID with 'no main' option, it should currently be the same + * as the reference ID one). */ + BLI_assert(/*!ID_IS_LINKED(id_override_new) || */ id_override_new->lib == id->lib); + BLI_assert(id_override_old == nullptr || id_override_old->lib == id_root->lib); + id_override_new->lib = id_root->lib; + /* Remap step below will tag directly linked ones properly as needed. */ + if (ID_IS_LINKED(id_override_new)) { + id_override_new->tag |= LIB_TAG_INDIRECT; + } - if (id_override_old != nullptr) { - /* Swap the names between old override ID and new one. */ - char id_name_buf[MAX_ID_NAME]; - memcpy(id_name_buf, id_override_old->name, sizeof(id_name_buf)); - memcpy(id_override_old->name, id_override_new->name, sizeof(id_override_old->name)); - memcpy(id_override_new->name, id_name_buf, sizeof(id_override_new->name)); - - BLI_insertlinkreplace(lb, id_override_old, id_override_new); - id_override_old->tag |= LIB_TAG_NO_MAIN; - id_override_new->tag &= ~LIB_TAG_NO_MAIN; - - lib_override_object_posemode_transfer(id_override_new, id_override_old); - - if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { - BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)); - - id_override_new->override_library->flag = id_override_old->override_library->flag; - - /* Copy over overrides rules from old override ID to new one. */ - BLI_duplicatelist(&id_override_new->override_library->properties, - &id_override_old->override_library->properties); - IDOverrideLibraryProperty *op_new = static_cast<IDOverrideLibraryProperty *>( - id_override_new->override_library->properties.first); - IDOverrideLibraryProperty *op_old = static_cast<IDOverrideLibraryProperty *>( - id_override_old->override_library->properties.first); - for (; op_new; op_new = op_new->next, op_old = op_old->next) { - lib_override_library_property_copy(op_new, op_old); - } + if (id_override_old != nullptr) { + /* Swap the names between old override ID and new one. */ + char id_name_buf[MAX_ID_NAME]; + memcpy(id_name_buf, id_override_old->name, sizeof(id_name_buf)); + memcpy(id_override_old->name, id_override_new->name, sizeof(id_override_old->name)); + memcpy(id_override_new->name, id_name_buf, sizeof(id_override_new->name)); + + BLI_insertlinkreplace(lb, id_override_old, id_override_new); + id_override_old->tag |= LIB_TAG_NO_MAIN; + id_override_new->tag &= ~LIB_TAG_NO_MAIN; + + lib_override_object_posemode_transfer(id_override_new, id_override_old); + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)); + + id_override_new->override_library->flag = id_override_old->override_library->flag; + + /* Copy over overrides rules from old override ID to new one. */ + BLI_duplicatelist(&id_override_new->override_library->properties, + &id_override_old->override_library->properties); + IDOverrideLibraryProperty *op_new = static_cast<IDOverrideLibraryProperty *>( + id_override_new->override_library->properties.first); + IDOverrideLibraryProperty *op_old = static_cast<IDOverrideLibraryProperty *>( + id_override_old->override_library->properties.first); + for (; op_new; op_new = op_new->next, op_old = op_old->next) { + lib_override_library_property_copy(op_new, op_old); } - - BLI_addtail(no_main_ids_list, id_override_old); - } - else { - /* Add to proper main list, ensure unique name for local ID, sort, and clear relevant - * tags. */ - BKE_libblock_management_main_add(bmain, id_override_new); } + + BLI_addtail(no_main_ids_list, id_override_old); + } + else { + /* Add to proper main list, ensure unique name for local ID, sort, and clear relevant + * tags. */ + BKE_libblock_management_main_add(bmain, id_override_new); } } FOREACH_MAIN_LISTBASE_ID_END; @@ -1974,53 +1993,56 @@ static bool lib_override_library_resync(Main *bmain, * remapped, and all new local override IDs have gotten their proper original names, otherwise * override operations based on those ID names would fail. */ FOREACH_MAIN_ID_BEGIN (bmain, id) { - if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) { - ID *id_override_new = id->newid; - if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { - continue; - } - ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr || + id->lib != id_root_reference->lib) { + continue; + } - if (id_override_old == nullptr) { - continue; - } - if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)) { - /* Apply rules on new override ID using old one as 'source' data. */ - /* Note that since we already remapped ID pointers in old override IDs to new ones, we - * can also apply ID pointer override rules safely here. */ - PointerRNA rnaptr_src, rnaptr_dst; - RNA_id_pointer_create(id_override_old, &rnaptr_src); - RNA_id_pointer_create(id_override_new, &rnaptr_dst); - - /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`, - * that way the potentially new pointer will be properly kept, when old one is still valid - * too (typical case: assigning new ID to some usage, while old one remains used elsewhere - * in the override hierarchy). */ - LISTBASE_FOREACH_MUTABLE ( - IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) { - LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) { - lib_override_library_property_operation_clear(opop); - BLI_freelinkN(&op->operations, opop); - } - } - if (BLI_listbase_is_empty(&op->operations)) { - BKE_lib_override_library_property_delete(id_override_new->override_library, op); + ID *id_override_new = id->newid; + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) { + continue; + } + + ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id)); + if (id_override_old == nullptr) { + continue; + } + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)) { + /* Apply rules on new override ID using old one as 'source' data. */ + /* Note that since we already remapped ID pointers in old override IDs to new ones, we + * can also apply ID pointer override rules safely here. */ + PointerRNA rnaptr_src, rnaptr_dst; + RNA_id_pointer_create(id_override_old, &rnaptr_src); + RNA_id_pointer_create(id_override_new, &rnaptr_dst); + + /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`, + * that way the potentially new pointer will be properly kept, when old one is still valid + * too (typical case: assigning new ID to some usage, while old one remains used elsewhere + * in the override hierarchy). */ + LISTBASE_FOREACH_MUTABLE ( + IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) { + LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) { + lib_override_library_property_operation_clear(opop); + BLI_freelinkN(&op->operations, opop); } } - - RNA_struct_override_apply(bmain, - &rnaptr_dst, - &rnaptr_src, - nullptr, - id_override_new->override_library, - do_hierarchy_enforce ? - RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS : - RNA_OVERRIDE_APPLY_FLAG_NOP); + if (BLI_listbase_is_empty(&op->operations)) { + BKE_lib_override_library_property_delete(id_override_new->override_library, op); + } } - BLI_linklist_prepend(&id_override_old_list, id_override_old); + RNA_struct_override_apply(bmain, + &rnaptr_dst, + &rnaptr_src, + nullptr, + id_override_new->override_library, + do_hierarchy_enforce ? RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS : + RNA_OVERRIDE_APPLY_FLAG_NOP); } + + BLI_linklist_prepend(&id_override_old_list, id_override_old); } FOREACH_MAIN_ID_END; @@ -2064,9 +2086,13 @@ static bool lib_override_library_resync(Main *bmain, } /* Also deal with old overrides that went missing in new linked data - only for real local * overrides for now, not those who are linked. */ - else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id)) { - BLI_assert(ID_IS_OVERRIDE_LIBRARY(id)); - if (!BKE_lib_override_library_is_user_edited(id)) { + else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && + id->override_library->reference->lib->id.tag & LIB_TAG_MISSING) { + /* Do not delete overrides which reference is missing because the library itself is missing + * (ref. T100586). */ + } + else if (!BKE_lib_override_library_is_user_edited(id)) { /* If user never edited them, we can delete them. */ id->tag |= LIB_TAG_DOIT; id->tag &= ~LIB_TAG_MISSING; @@ -2129,6 +2155,7 @@ static bool lib_override_library_resync(Main *bmain, id_root_reference, id_root, override_resync_residual_storage, + old_active_object, true); } @@ -2180,12 +2207,12 @@ static bool lib_override_resync_id_lib_level_is_valid(ID *id, } /* Find the root of the override hierarchy the given `id` belongs to. */ -static ID *lib_override_library_main_resync_root_get(Main *bmain, ID *id) +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 != nullptr) { - id = id_type->owner_get(bmain, id, nullptr); + ID *id_owner = BKE_id_owner_get(id); + if (id_owner != nullptr) { + id = id_owner; } BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id)); } @@ -2372,11 +2399,21 @@ static void lib_override_library_main_resync_on_library_indirect_level( if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { continue; } + + if (!lib_override_resync_id_lib_level_is_valid(id, library_indirect_level, true)) { + continue; + } + if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) { /* We already processed that ID as part of another ID's hierarchy. */ continue; } + /* Do not attempt to resync from missing data. */ + if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) { + continue; + } + if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { /* This ID is not part of an override hierarchy. */ continue; @@ -2405,6 +2442,11 @@ static void lib_override_library_main_resync_on_library_indirect_level( continue; } + /* Do not attempt to resync from missing data. */ + if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) { + continue; + } + if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { /* This ID is not part of an override hierarchy. */ BLI_assert((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0); @@ -2532,6 +2574,15 @@ static void lib_override_library_main_resync_on_library_indirect_level( /* Check there are no left-over IDs needing resync from the current (or higher) level of indirect * library level. */ FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (!ID_IS_OVERRIDE_LIBRARY(id)) { + continue; + } + /* Do not attempt to resync to/from missing data. */ + if (((id->tag | (ID_IS_OVERRIDE_LIBRARY_REAL(id) ? id->override_library->reference->tag : 0)) & + LIB_TAG_MISSING) != 0) { + continue; + } + const bool is_valid_tagged_need_resync = ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0 || lib_override_resync_id_lib_level_is_valid( id, library_indirect_level - 1, false)); @@ -2648,6 +2699,9 @@ void BKE_lib_override_library_main_resync(Main *bmain, /* Hide the collection from viewport and render. */ override_resync_residual_storage->flag |= COLLECTION_HIDE_VIEWPORT | COLLECTION_HIDE_RENDER; } + /* BKE_collection_add above could have tagged the view_layer out of sync. */ + BKE_view_layer_synced_ensure(scene, view_layer); + const Object *old_active_object = BKE_view_layer_active_object_get(view_layer); /* Necessary to improve performances, and prevent layers matching override sub-collections to be * lost when re-syncing the parent override collection. @@ -2669,8 +2723,15 @@ void BKE_lib_override_library_main_resync(Main *bmain, BKE_layer_collection_resync_allow(); /* Essentially ensures that potentially new overrides of new objects will be instantiated. */ - lib_override_library_create_post_process( - bmain, scene, view_layer, nullptr, nullptr, nullptr, override_resync_residual_storage, true); + lib_override_library_create_post_process(bmain, + scene, + view_layer, + nullptr, + nullptr, + nullptr, + override_resync_residual_storage, + old_active_object, + true); if (BKE_collection_is_empty(override_resync_residual_storage)) { BKE_collection_delete(bmain, override_resync_residual_storage, true); @@ -3890,7 +3951,7 @@ void BKE_lib_override_library_operations_store_end( void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage) { /* We cannot just call BKE_main_free(override_storage), not until we have option to make - * 'ghost' copies of IDs without increasing usercount of used data-blocks. */ + * 'ghost' copies of IDs without increasing user-count of used data-blocks. */ ID *id; FOREACH_MAIN_ID_BEGIN (override_storage, id) { |