[Bf-blender-cvs] [5752d132c8c] override-refactor-tmp-2: LibOverride: Add second part of auto-resync code.

Bastien Montagne noreply at git.blender.org
Fri Mar 5 10:14:18 CET 2021


Commit: 5752d132c8ca4e33b360b355f0633e504a68d82c
Author: Bastien Montagne
Date:   Fri Mar 5 09:16:26 2021 +0100
Branches: override-refactor-tmp-2
https://developer.blender.org/rB5752d132c8ca4e33b360b355f0633e504a68d82c

LibOverride: Add second part of auto-resync code.

`BKE_lib_override_library_main_resync` uses
`LIB_TAG_LIB_OVERRIDE_NEED_RESYNC` tags set by RNA override apply code,
and perform detection for the remaining cases (those were new overrides
need to be created for data that was not present before in the library).

And then it actually resync all needed local overrides.

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

M	source/blender/blenkernel/BKE_lib_override.h
M	source/blender/blenkernel/intern/lib_override.c

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

diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 19109d67114..e548f778c71 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -80,6 +80,10 @@ bool BKE_lib_override_library_resync(struct Main *bmain,
                                      struct Scene *scene,
                                      struct ViewLayer *view_layer,
                                      struct ID *id_root);
+void BKE_lib_override_library_main_resync(struct Main *bmain,
+                                          struct Scene *scene,
+                                          struct ViewLayer *view_layer);
+
 void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root);
 
 struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index c687a49d704..089de466e09 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1042,6 +1042,191 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
   return success;
 }
 
+/**
+ * Detect and handle required resync of overrides data, when relations between reference linked IDs
+ * have changed.
+ *
+ * This is a fairly complex and costly operation, typically it should be called after
+ * #BKE_lib_override_library_main_update, which would already detect and tag a lot of cases.
+ *
+ * This function will first detect the remaining cases requiring a resync (namely, either when an
+ * existing linked ID that did not require to be overridden before now would be, or when new IDs
+ * are added to the hierarchy).
+ *
+ * Then it will handle the resync of necessary IDs (through calls to
+ * #BKE_lib_override_library_resync).
+ */
+void BKE_lib_override_library_main_resync(Main *bmain, Scene *scene, ViewLayer *view_layer)
+{
+  BKE_main_relations_create(bmain, 0);
+  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+  /* Detect all linked data that would need to be overridden if we had to create an override from
+   * those used by current existing overrides. */
+
+  /* We check collections and objects first, as in most typical usecases those are the 'root' of an
+   * override hierarchy. */
+#if 0
+  LISTBASE_FOREACH (ID *, id, &bmain->collections) {
+    if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+      continue;
+    }
+    if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) {
+      /* We already processed that ID as part of another ID's hierarchy. */
+      continue;
+    }
+
+    LibOverrideGroupTagData data = {.bmain = bmain,
+                                    .id_root = id->override_library->reference,
+                                    .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_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+  }
+  LISTBASE_FOREACH (ID *, id, &bmain->objects) {
+    if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+      continue;
+    }
+    if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) {
+      /* We already processed that ID as part of another ID's hierarchy. */
+      continue;
+    }
+
+    LibOverrideGroupTagData data = {.bmain = bmain,
+                                    .id_root = id->override_library->reference,
+                                    .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_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+  }
+#endif
+  {
+    ID *id;
+    FOREACH_MAIN_ID_BEGIN (bmain, id) {
+      if (ELEM(GS(id->name), ID_GR, ID_OB)) {
+        //        continue;
+      }
+      if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+        continue;
+      }
+      if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) {
+        /* We already processed that ID as part of another ID's hierarchy. */
+        continue;
+      }
+
+      LibOverrideGroupTagData data = {.bmain = bmain,
+                                      .id_root = id->override_library->reference,
+                                      .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_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+    }
+    FOREACH_MAIN_ID_END;
+  }
+
+  /* Now check existing overrides, those needing resync will be the one either already tagged as
+   * such, or the one using linked data that is now tagged as needing override. */
+
+  {
+    ID *id;
+    FOREACH_MAIN_ID_BEGIN (bmain, id) {
+      if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+        continue;
+      }
+
+      if (id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) {
+        printf("%s: ID %s was already tagged as needing resync.\n", __func__, id->name);
+        continue;
+      }
+
+      MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+                                                     id);
+      BLI_assert(entry != NULL);
+
+      for (MainIDRelationsEntryItem *entry_item = entry->to_ids; entry_item != NULL;
+           entry_item = entry_item->next) {
+        if (entry_item->usage_flag &
+            (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
+          continue;
+        }
+        ID *id_to = *entry_item->id_pointer.to;
+
+        /* Case where this ID pointer was to a linked ID, that now needs to be overridden. */
+        if (ID_IS_LINKED(id_to) && (id_to->tag & LIB_TAG_DOIT) != 0) {
+          id->tag |= LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
+          printf(
+              "%s: ID %s now tagged as needing resync because they use linked %s that now needs "
+              "to be overridden.\n",
+              __func__,
+              id->name,
+              id_to->name);
+          break;
+        }
+      }
+    }
+    FOREACH_MAIN_ID_END;
+  }
+
+  BKE_main_relations_free(bmain);
+  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+  bool do_loop = true;
+#if 0
+  while (do_loop) {
+    do_loop = false;
+    LISTBASE_FOREACH (ID *, id, &bmain->collections) {
+      if ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) {
+        continue;
+      }
+      do_loop = true;
+      printf("%s: Resynced %s, ", __func__, id->name);
+      const bool success = BKE_lib_override_library_resync(bmain, scene, view_layer, id);
+      printf("success: %d\n", success);
+      break;
+    }
+  }
+  do_loop = true;
+  while (do_loop) {
+    do_loop = false;
+    LISTBASE_FOREACH (ID *, id, &bmain->objects) {
+      if ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) {
+        continue;
+      }
+      do_loop = true;
+      printf("%s: Resynced %s, ", __func__, id->name);
+      const bool success = BKE_lib_override_library_resync(bmain, scene, view_layer, id);
+      printf("success: %d\n", success);
+      break;
+    }
+  }
+#endif
+  do_loop = true;
+  while (do_loop) {
+    do_loop = false;
+    ID *id;
+    FOREACH_MAIN_ID_BEGIN (bmain, id) {
+      if (ELEM(GS(id->name), ID_GR, ID_OB)) {
+        //        continue;
+      }
+      if ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) {
+        continue;
+      }
+      do_loop = true;
+      printf("%s: Resynced %s, ", __func__, id->name);
+      const bool success = BKE_lib_override_library_resync(bmain, scene, view_layer, id);
+      printf("success: %d\n", success);
+      break;
+    }
+    FOREACH_MAIN_ID_END;
+  }
+}
+
 /**
  * Advanced 'smart' function to delete library overrides (including their existing override
  * hierarchy) and remap their usages to their linked reference IDs.



More information about the Bf-blender-cvs mailing list