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:
authorBastien Montagne <bastien@blender.org>2022-02-25 14:15:56 +0300
committerBastien Montagne <bastien@blender.org>2022-02-25 14:18:48 +0300
commit1a853a9e90e9f1a8a5028bd1ce37785e1b2ce6d5 (patch)
tree1089f60cb49c683abf52b128f4991b6f3693292c /source/blender/blenkernel/intern/lib_override.c
parent5db32ab5fc770751d5966311172f50f0572070cf (diff)
LibOverrides: fix handling of hierarchy root in complex cases.
This affects essentially the Outliner 'create hierarchy' tool currenlty. Previously code did not handle properly hierarchy root in case overrides where created from a non-root ID (e.g. an object inside of a linked collection), and in case additional partial overrides were added to an existing partially overrided hierarchy. Also did some renaming on the go to avoid using 'reference' in override context for anything else but the reference linked IDs.
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.c')
-rw-r--r--source/blender/blenkernel/intern/lib_override.c85
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);