LibOverride: Fix/improve handling of hierarchy root in tagged creation.

Decouple the reference (linked) root ID and the hierarchy (override) root ID.
Previous code was assuming that the reference ID was always also tagged
for override creation, which is true in current master, but cannot be
assumed in general (and won't be true with partial resync anymore).

Also add asserts to validate conditions that the reference/hierarchy_root
variables must meet.
This commit is contained in:
Bastien Montagne 2022-02-10 14:55:12 +01:00
parent d16e5babaf
commit e9c9a2183d
2 changed files with 21 additions and 6 deletions

View File

@ -103,8 +103,12 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
* \param owner_library: the library in which the overrides should be created. Besides versioning
* and resync code path, this should always be NULL (i.e. the local .blend file).
*
* \param reference_library: the library from which the linked data being overridden come from
* (i.e. the library of the linked reference ID).
* \param id_root_reference: the linked ID that is considered as the root of the overridden
* hierarchy.
*
* \param id_hierarchy_root: the override ID that is the root of the hierarchy. May be NULL, in
* which case it is assumed that the given `id_root_reference` is tagged for override, and its
* newly created override will be used as hierarchy root.
*
* \param do_no_main: Create the new override data outside of Main database.
* Used for resyncing of linked overrides.
@ -114,6 +118,7 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
struct Library *owner_library,
const struct ID *id_root_reference,
struct ID *id_hierarchy_root,
bool do_no_main);
/**
* Advanced 'smart' function to create fully functional overrides.

View File

@ -332,8 +332,15 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain,
bool BKE_lib_override_library_create_from_tag(Main *bmain,
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;
@ -388,7 +395,10 @@ 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) {
ID *hierarchy_root_id = id_root_reference->newid;
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;
@ -398,7 +408,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
continue;
}
local_id->override_library->hierarchy_root = hierarchy_root_id;
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) {
@ -889,7 +899,7 @@ static bool lib_override_library_create_do(Main *bmain,
lib_override_group_tag_data_clear(&data);
const bool success = BKE_lib_override_library_create_from_tag(
bmain, owner_library, id_root, false);
bmain, owner_library, id_root, NULL, false);
return success;
}
@ -1424,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, NULL, id_root_reference, true);
bmain, NULL, id_root_reference, id_root->override_library->hierarchy_root, true);
if (!success) {
return success;