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
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2021-02-09 23:53:47 +0300
committerBastien Montagne <bastien@blender.org>2021-02-09 23:53:47 +0300
commita86605fffd884bd29fc9d984a93df3fc572ef210 (patch)
tree03dc535dcc936afd654924b8cbf24fe61b1810f6 /source
parent87c75767b3b4bba8b6cd6b147dbd475d9154e0ae (diff)
LibOverride: Refactor: Switch more code to using Main.relations.
This potentially could fix some missed cases in dependency tagging (when dealing with overrides hierarchies), since relying on tag in ID itself is not a good idea to check whether an ID has been propcessed or not (exterior code may have forced that tag on some IDs e.g., which would prevent them from ever being processed properly).
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/lib_override.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 68a75e469fd..0f753018c46 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -418,52 +418,60 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
return (*(uint *)&id->tag & data->tag) != 0;
}
-static int lib_override_linked_group_tag_cb(LibraryIDLinkCallbackData *cb_data)
+static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *data)
{
- if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
- return IDWALK_RET_STOP_RECURSION;
- }
-
- LibOverrideGroupTagData *data = cb_data->user_data;
- const uint tag = data->tag;
- const uint missing_tag = data->missing_tag;
-
- ID *id_root = data->id_root;
- Library *library_root = id_root->lib;
- ID *id = *cb_data->id_pointer;
- ID *id_owner = cb_data->id_owner;
-
- BLI_assert(id_owner == cb_data->id_self);
-
- if (ELEM(id, NULL, id_owner)) {
- return IDWALK_RET_NOP;
- }
+ Main *bmain = data->bmain;
+ ID *id_owner = data->id_root;
+ BLI_assert(ID_IS_LINKED(id_owner));
- BLI_assert(id_owner->lib == library_root);
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+ id_owner);
+ BLI_assert(entry != NULL);
- if (*(uint *)&id->tag & (tag | missing_tag)) {
- /* Already processed and tagged, nothing else to do here. */
- return IDWALK_RET_STOP_RECURSION;
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
+ printf("%s already processed\n", id_owner->name);
+ return;
}
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
- if (id->lib != library_root) {
- /* We do not override data-blocks from other libraries, nor do we process them. */
- return IDWALK_RET_STOP_RECURSION;
- }
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+ * actual dependencies. */
+ continue;
+ }
- /* We tag all collections and objects for override. And we also tag all other data-blocks which
- * would use one of those.
- * Note: missing IDs (aka placeholders) are never overridden. */
- if (ELEM(GS(id->name), ID_OB, ID_GR)) {
- if ((id->tag & LIB_TAG_MISSING)) {
- id->tag |= missing_tag;
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (ELEM(to_id, NULL, id_owner)) {
+ continue;
}
- else {
- id->tag |= tag;
+ /* We only consider IDs from the same library. */
+ if (to_id->lib != id_owner->lib) {
+ continue;
+ }
+ BLI_assert(ID_IS_LINKED(to_id));
+
+ /* We tag all collections and objects for override. And we also tag all other data-blocks which
+ * would use one of those.
+ * Note: missing IDs (aka placeholders) are never overridden. */
+ if (ELEM(GS(to_id->name), ID_OB, ID_GR)) {
+ if ((to_id->tag & LIB_TAG_MISSING)) {
+ to_id->tag |= data->missing_tag;
+ }
+ else {
+ to_id->tag |= data->tag;
+ }
}
- }
- return IDWALK_RET_NOP;
+ /* Recursively process the dependencies. */
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = to_id;
+ lib_override_linked_group_tag_recursive(&sub_data);
+ }
}
/* This will tag at least all 'boundary' linked IDs for a potential override group.
@@ -490,8 +498,7 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
if (ELEM(GS(id_root->name), ID_OB, ID_GR)) {
/* Tag all collections and objects. */
- BKE_library_foreach_ID_link(
- bmain, id_root, lib_override_linked_group_tag_cb, data, IDWALK_READONLY | IDWALK_RECURSE);
+ lib_override_linked_group_tag_recursive(data);
/* Then, we remove (untag) bone shape objects, you shall never want to directly/explicitly
* override those. */
@@ -583,6 +590,8 @@ static bool lib_override_library_create_do(Main *bmain, ID *id_root)
LibOverrideGroupTagData data = {
.bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
lib_override_linked_group_tag(&data);
+
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
lib_override_hierarchy_dependencies_recursive_tag(&data);
BKE_main_relations_free(bmain);
@@ -788,6 +797,8 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
data.id_root = id_root_reference;
lib_override_linked_group_tag(&data);
+
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
lib_override_hierarchy_dependencies_recursive_tag(&data);
/* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides. */
@@ -830,6 +841,7 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
FOREACH_MAIN_ID_END;
/* Code above may have added some tags, we need to update this too. */
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
lib_override_hierarchy_dependencies_recursive_tag(&data);
BKE_main_relations_free(bmain);