diff options
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.c')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index d9418d7ec03..922c1beda38 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -321,17 +321,36 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, return local_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, Library *owner_library, const ID *id_root_reference, ID *id_hierarchy_root, + const ID *id_hierarchy_root_reference, 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)); + BLI_assert(id_root_reference != NULL && ID_IS_LINKED(id_root_reference)); + /* If we do not have any hierarchy root given, then the root reference must be tagged for + * override. */ + BLI_assert(id_hierarchy_root != NULL || id_hierarchy_root_reference != NULL || + (id_root_reference->tag & LIB_TAG_DOIT) != 0); + /* At least one of the hierarchy root pointers must be NULL, passing both is useless and can + * create confusion. */ + BLI_assert(ELEM(NULL, id_hierarchy_root, id_hierarchy_root_reference)); + + if (id_hierarchy_root != NULL) { + /* If the hierarchy root is given, it must be a valid existing override (used during partial + * resync process mainly). */ + BLI_assert((ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root) && + id_hierarchy_root->override_library->reference->lib == id_root_reference->lib)); + } + if (!ELEM(id_hierarchy_root_reference, NULL, id_root_reference)) { + /* If the reference hierarchy root is given, it must be from the same library as the reference + * root, and also tagged for override. */ + BLI_assert((id_hierarchy_root_reference->lib == id_root_reference->lib && + (id_hierarchy_root_reference->tag & LIB_TAG_DOIT) != 0)); + } const Library *reference_library = id_root_reference->lib; @@ -387,7 +406,12 @@ 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) { + if (id_hierarchy_root_reference != NULL) { + id_hierarchy_root = id_hierarchy_root_reference->newid; + } + else if (id_root_reference->newid != NULL && + (id_hierarchy_root == NULL || + id_hierarchy_root->override_library->reference == id_root_reference)) { id_hierarchy_root = id_root_reference->newid; } BLI_assert(id_hierarchy_root != NULL); @@ -887,12 +911,13 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data) static bool lib_override_library_create_do(Main *bmain, Scene *scene, Library *owner_library, - ID *id_root) + ID *id_root_reference, + ID *id_hierarchy_root_reference) { BKE_main_relations_create(bmain, 0); LibOverrideGroupTagData data = {.bmain = bmain, .scene = scene, - .id_root = id_root, + .id_root = id_root_reference, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING, .is_override = false, @@ -906,8 +931,18 @@ static bool lib_override_library_create_do(Main *bmain, BKE_main_relations_free(bmain); lib_override_group_tag_data_clear(&data); - const bool success = BKE_lib_override_library_create_from_tag( - bmain, owner_library, id_root, NULL, false); + 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, id_hierarchy_root_reference, NULL, false); + } + else { + success = BKE_lib_override_library_create_from_tag( + bmain, owner_library, id_root_reference, NULL, id_hierarchy_root_reference, false); + } return success; } @@ -917,7 +952,7 @@ static void lib_override_library_create_post_process(Main *bmain, ViewLayer *view_layer, const Library *owner_library, ID *id_root, - ID *id_reference, + ID *id_instance_hint, Collection *residual_storage, const bool is_resync) { @@ -941,8 +976,8 @@ static void lib_override_library_create_post_process(Main *bmain, (!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 ? - (Object *)id_reference : + Object *ob_reference = id_instance_hint != NULL && GS(id_instance_hint->name) == ID_OB ? + (Object *)id_instance_hint : NULL; Collection *collection_new = ((Collection *)id_root->newid); if (is_resync && BKE_collection_is_in_scene(collection_new)) { @@ -951,10 +986,10 @@ static void lib_override_library_create_post_process(Main *bmain, if (ob_reference != NULL) { BKE_collection_add_from_object(bmain, scene, ob_reference, collection_new); } - else if (id_reference != NULL) { - BLI_assert(GS(id_reference->name) == ID_GR); + else if (id_instance_hint != NULL) { + BLI_assert(GS(id_instance_hint->name) == ID_GR); BKE_collection_add_from_collection( - bmain, scene, ((Collection *)id_reference), collection_new); + bmain, scene, ((Collection *)id_instance_hint), collection_new); } else { BKE_collection_add_from_collection( @@ -1047,26 +1082,32 @@ bool BKE_lib_override_library_create(Main *bmain, Scene *scene, ViewLayer *view_layer, Library *owner_library, - ID *id_root, - ID *id_reference, + ID *id_root_reference, + ID *id_hierarchy_root_reference, + ID *id_instance_hint, ID **r_id_root_override) { if (r_id_root_override != NULL) { *r_id_root_override = NULL; } - const bool success = lib_override_library_create_do(bmain, scene, owner_library, id_root); + if (id_hierarchy_root_reference == NULL) { + id_hierarchy_root_reference = id_root_reference; + } + + const bool success = lib_override_library_create_do( + bmain, scene, owner_library, id_root_reference, id_hierarchy_root_reference); if (!success) { return success; } if (r_id_root_override != NULL) { - *r_id_root_override = id_root->newid; + *r_id_root_override = id_root_reference->newid; } lib_override_library_create_post_process( - bmain, scene, view_layer, owner_library, id_root, id_reference, NULL, false); + bmain, scene, view_layer, owner_library, id_root_reference, id_instance_hint, NULL, false); /* Cleanup. */ BKE_main_id_newptr_and_tag_clear(bmain); @@ -1527,7 +1568,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, id_root->override_library->hierarchy_root, true); + bmain, NULL, id_root_reference, id_root->override_library->hierarchy_root, NULL, true); if (!success) { BLI_ghash_free(linkedref_to_old_override, NULL, NULL); |