diff options
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 20 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 14 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ID.c | 8 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access_compare_override.c | 7 |
5 files changed, 52 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 1c30db7a714..6e4864d8abc 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -84,6 +84,9 @@ bool BKE_lib_override_library_is_user_edited(struct ID *id); /** * Create an overridden local copy of linked reference. + * + * \note This function is very basic, low-level. It does not consider any hierarcical dependency, + * and also prevents any automatic resync of this local override. */ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain, struct ID *reference_id, diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 07ec8d32ad0..b0231585f68 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -282,6 +282,10 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, BLI_assert(ID_IS_LINKED(reference_id)); ID *local_id = lib_override_library_create_from(bmain, 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; if (do_tagged_remap) { Key *reference_key, *local_key = NULL; @@ -734,6 +738,11 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData * ID *id_owner = data->id_root; BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner)); BLI_assert(data->is_override); + + if (id_owner->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { + return; + } + const uint tag = data->tag; const uint missing_tag = data->missing_tag; @@ -1643,6 +1652,11 @@ static void lib_override_library_main_resync_on_library_indirect_level( continue; } + if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { + /* This ID is not part of an override hierarchy. */ + continue; + } + data.id_root = id->override_library->reference; lib_override_linked_group_tag(&data); BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false); @@ -1660,6 +1674,12 @@ static void lib_override_library_main_resync_on_library_indirect_level( 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); + continue; + } + if (id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) { CLOG_INFO(&LOG, 4, "ID %s (%p) was already tagged as needing resync", id->name, id->lib); lib_override_resync_tagging_finalize_recurse(bmain, id, library_indirect_level); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 17b3fb302e6..9fdf7be04e2 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -315,8 +315,22 @@ typedef struct IDOverrideLibrary { struct ID *storage; IDOverrideLibraryRuntime *runtime; + + void *_pad_0; + + unsigned int flag; + char _pad_1[4]; } IDOverrideLibrary; +/* IDOverrideLibrary->flag */ +enum { + /** + * The override data-block should not be considered as part of an override hierarchy (generally + * because it was created as an single override, outside of any hierarchy consideration). + */ + IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY = 1 << 0, +}; + /* watch it: Sequence has identical beginning. */ /** * ID is the first thing included in all serializable types. It diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index be612a1602b..c43b80204cf 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -1808,6 +1808,14 @@ static void rna_def_ID_override_library(BlenderRNA *brna) RNA_def_pointer( srna, "reference", "ID", "Reference ID", "Linked ID used as reference by this override"); + prop = RNA_def_boolean(srna, + "is_in_hierarchy", + true, + "Is In Hierarchy", + "Whether this library override is defined as part of a library " + "hierarchy, or as a single, isolated and autonomous override"); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY); + prop = RNA_def_collection(srna, "properties", "IDOverrideLibraryProperty", diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 19c678a4222..2af83c8adcb 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -1095,6 +1095,13 @@ static void rna_property_override_check_resync(Main *bmain, ID *id_src = rna_property_override_property_real_id_owner(bmain, ptr_item_src, NULL, NULL); ID *id_dst = rna_property_override_property_real_id_owner(bmain, ptr_item_dst, NULL, NULL); + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_owner)); + + /* If the owner ID is not part of an override hierarchy, there is no possible resync. */ + if (id_owner->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) { + return; + } + /* If `id_src` is not a liboverride, we cannot perform any further 'need resync' checks from * here. */ if (id_src != NULL && !ID_IS_OVERRIDE_LIBRARY_REAL(id_src)) { |