[Bf-blender-cvs] [acdc043c30a] master: Revert "Revert "LibOverride: Handle dependencies in both directions in partial override cases.""

Bastien Montagne noreply at git.blender.org
Thu Jun 30 10:39:49 CEST 2022


Commit: acdc043c30a6741229536eb9ff70d3ec94ef7b25
Author: Bastien Montagne
Date:   Wed Jun 29 10:25:00 2022 +0200
Branches: master
https://developer.blender.org/rBacdc043c30a6741229536eb9ff70d3ec94ef7b25

Revert "Revert "LibOverride: Handle dependencies in both directions in partial override cases.""

This reverts commit rB31d80ddeaad, and fixes issue introduced in rBf0b4aa5d59e3
by not doing the 'reversed dependency check' in resync case.

Rational here are:
* Supporting reversed dependency in a reliable, coinsistent way in
  resync is likely to be a nightmare, if even possible at all.
* Needs for such reversed dependency in resync should be close to 0% of
  cases, as long as users remain reasonable with their organization of
  their assets (it could only become a problem in extreme bad practice
  and corner cases, like a geometry object being added as a child of a
  rig in a completely new, otherwise un-overridden collection, in
  partial override context).

This decision may need to be re-evaluated later in case we go more
towards a very highly partial-override  workflow, but even then I would
expect current solution to work fine in all reasonable use cases.

===================================================================

M	source/blender/blenkernel/intern/lib_override.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc
index 22012662180..7bde609913b 100644
--- a/source/blender/blenkernel/intern/lib_override.cc
+++ b/source/blender/blenkernel/intern/lib_override.cc
@@ -687,6 +687,51 @@ static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data)
   memset(data, 0, sizeof(*data));
 }
 
+static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data)
+{
+  Main *bmain = data->bmain;
+  ID *id = data->id_root;
+  const bool is_override = data->is_override;
+
+  if ((*(uint *)&id->tag & data->tag) == 0) {
+    /* This ID is not tagged, no reason to proceed further to its parents. */
+    return;
+  }
+
+  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
+      BLI_ghash_lookup(bmain->relations->relations_from_pointers, id));
+  BLI_assert(entry != nullptr);
+
+  if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM) {
+    /* This ID has already been processed. */
+    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_FROM;
+
+  for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
+       from_id_entry = from_id_entry->next) {
+    if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
+      /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers)
+       * as actual dependencies. */
+      continue;
+    }
+    /* We only consider IDs from the same library. */
+    ID *from_id = from_id_entry->id_pointer.from;
+    if (from_id == nullptr || from_id->lib != id->lib ||
+        (is_override && !ID_IS_OVERRIDE_LIBRARY(from_id))) {
+      /* IDs from different libraries, or non-override IDs in case we are processing overrides,
+       * are both barriers of dependency. */
+      continue;
+    }
+    from_id->tag |= data->tag;
+    LibOverrideGroupTagData sub_data = *data;
+    sub_data.id_root = from_id;
+    lib_override_hierarchy_dependencies_recursive_tag_from(&sub_data);
+  }
+}
+
 /* Tag all IDs in dependency relationships within an override hierarchy/group.
  *
  * Requires existing `Main.relations`.
@@ -698,18 +743,19 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
   Main *bmain = data->bmain;
   ID *id = data->id_root;
   const bool is_override = data->is_override;
+  const bool is_resync = data->is_resync;
 
   MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
       BLI_ghash_lookup(bmain->relations->relations_from_pointers, id));
   BLI_assert(entry != nullptr);
 
-  if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+  if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO) {
     /* This ID has already been processed. */
     return (*(uint *)&id->tag & data->tag) != 0;
   }
   /* This way we won't process again that ID, should we encounter it again through another
    * relationship hierarchy. */
-  entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+  entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO;
 
   for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
        to_id_entry = to_id_entry->next) {
@@ -733,6 +779,15 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
     }
   }
 
+  /* If the current ID is/has been tagged for override above, then check its reversed dependencies
+   * (i.e. IDs that depend on the current one).
+   *
+   * This will cover e.g. the case where user override an armature, and would expect the mesh
+   * object deformed by that armature to also be overridden. */
+  if ((*(uint *)&id->tag & data->tag) != 0 && !is_resync) {
+    lib_override_hierarchy_dependencies_recursive_tag_from(data);
+  }
+
   return (*(uint *)&id->tag & data->tag) != 0;
 }



More information about the Bf-blender-cvs mailing list