[Bf-blender-cvs] [984c152c76b] override-refactor-tmp: WIP refactor of relationships handling in overrides.

Bastien Montagne noreply at git.blender.org
Thu Dec 24 18:12:31 CET 2020


Commit: 984c152c76bef8c2e11e46de22248dfbade253e1
Author: Bastien Montagne
Date:   Thu Dec 24 18:11:46 2020 +0100
Branches: override-refactor-tmp
https://developer.blender.org/rB984c152c76bef8c2e11e46de22248dfbade253e1

WIP refactor of relationships handling in overrides.

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

M	source/blender/blenkernel/BKE_lib_override.h
M	source/blender/blenkernel/intern/lib_override.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_rna.c

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

diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 13edabd4cb7..ccd6421f2e2 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -65,15 +65,6 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
                                                    struct ID *reference_id,
                                                    const bool do_tagged_remap);
 bool BKE_lib_override_library_create_from_tag(struct Main *bmain);
-void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
-                                               struct ID *id_root,
-                                               const uint tag,
-                                               const bool do_create_main_relashionships);
-void BKE_lib_override_library_override_group_tag(struct Main *bmain,
-                                                 struct ID *id_root,
-                                                 const uint tag,
-                                                 const uint missing_tag,
-                                                 const bool do_create_main_relashionships);
 bool BKE_lib_override_library_create(struct Main *bmain,
                                      struct Scene *scene,
                                      struct ViewLayer *view_layer,
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index cabc80d4024..7aa4f3bcccb 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -366,23 +366,50 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
   return success;
 }
 
-static bool lib_override_hierarchy_recursive_tag(Main *bmain,
-                                                 ID *id,
-                                                 const uint tag,
-                                                 const uint missing_tag,
-                                                 Library *override_group_lib_reference)
+typedef struct LibOverrideGroupTagData {
+  ID *id_root;
+  uint tag;
+  uint missing_tag;
+} LibOverrideGroupTagData;
+
+static int lib_override_linked_group_tag_cb(LibraryIDLinkCallbackData *cb_data)
 {
-  void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
-  if (entry_vp == NULL) {
-    /* Already processed. */
-    return (id->tag & tag) != 0;
+  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;
+  }
+
+  BLI_assert(id_owner->lib == library_root);
+
+  if (*(uint *)&id->tag & (tag | missing_tag)) {
+    /* Already processed and tagged, nothing else to do here. */
+    return IDWALK_RET_STOP_RECURSION;
+  }
+
+  if (id->lib != library_root) {
+    /* We do not override data-blocks from other libraries, nor do we process them. */
+    return IDWALK_RET_STOP_RECURSION;
   }
 
-  /* Note: in case some reference ID is missing from linked data (and therefore its override uses
-   * a placeholder as reference), use `missing_tag` instead of `tag` for this override. */
-  if (override_group_lib_reference != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
-      id->override_library->reference->lib == override_group_lib_reference) {
-    if (id->override_library->reference->tag & LIB_TAG_MISSING) {
+  /* 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;
     }
     else {
@@ -390,6 +417,25 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain,
     }
   }
 
+  return IDWALK_RET_NOP;
+}
+
+/* Tag all IDs in dependency relationships whithin an override hierarchy/group.
+ *
+ * Note: this is typically called to complete `lib_override_linked_group_tag()`.
+ * Note: BMain's relations mapping won't be valid anymore after that call.
+ */
+static bool lib_override_hierarchy_dependencies_recursive_tag(Main *bmain,
+                                                              ID *id,
+                                                              const uint tag,
+                                                              const uint missing_tag)
+{
+  void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
+  if (entry_vp == NULL) {
+    /* Already processed. */
+    return (*(uint *)&id->tag & tag) != 0;
+  }
+
   /* This way we won't process again that ID, should we encounter it again through another
    * relationship hierarchy.
    * Note that this does not free any memory from relations, so we can still use the entries.
@@ -404,80 +450,68 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain,
     }
     /* We only consider IDs from the same library. */
     if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
-      if (lib_override_hierarchy_recursive_tag(
-              bmain, *entry->id_pointer, tag, missing_tag, override_group_lib_reference) &&
-          override_group_lib_reference == NULL) {
+      if (lib_override_hierarchy_dependencies_recursive_tag(
+              bmain, *entry->id_pointer, tag, missing_tag)) {
         id->tag |= tag;
       }
     }
   }
 
-  return (id->tag & tag) != 0;
+  return (*(uint *)&id->tag & tag) != 0;
 }
 
-/**
- * Tag all IDs in given \a bmain that are being used by given \a id_root ID or its dependencies,
- * recursively.
- * It detects and tag only chains of dependencies marked at both ends by given tag.
+/* This will tag at least all 'boundary' linked IDs for a potential override group.
  *
- * This will include all local IDs, and all IDs from the same library as the \a id_root.
+ * Note that you will then need to call `lib_override_hierarchy_dependencies_recursive_tag` to
+ * complete tagging of all dependencies whitin theoverride group.
  *
- * \param id_root: The root of the hierarchy of dependencies to be tagged.
- * \param do_create_main_relashionships: Whether main relations needs to be created or already
- * exist (in any case, they will be freed by this function).
+ * We currently only consider Collections and Objects (that are not used as bone shapes) as valid
+ * boundary IDs to define an override group.
  */
-void BKE_lib_override_library_dependencies_tag(Main *bmain,
-                                               ID *id_root,
-                                               const uint tag,
-                                               const bool do_create_main_relashionships)
+static void lib_override_linked_group_tag(Main *bmain,
+                                          ID *id,
+                                          const uint tag,
+                                          const uint missing_tag)
 {
-  if (do_create_main_relashionships) {
-    BKE_main_relations_create(bmain, 0);
-  }
-
-  /* We tag all intermediary data-blocks in-between two overridden ones (e.g. if a shape-key
-   * has a driver using an armature object's bone, we need to override the shape-key/obdata,
-   * the objects using them, etc.) */
-  lib_override_hierarchy_recursive_tag(bmain, id_root, tag, 0, NULL);
+  BKE_main_relations_create(bmain, 0);
 
-  BKE_main_relations_free(bmain);
-}
+  if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+    LibOverrideGroupTagData data = {.id_root = id, .tag = tag, .missing_tag = missing_tag};
+    /* Tag all collections and objects. */
+    BKE_library_foreach_ID_link(
+        bmain, id, lib_override_linked_group_tag_cb, &data, IDWALK_READONLY | IDWALK_RECURSE);
 
-/**
- * Tag all IDs in given \a bmain that are part of the same \a id_root liboverride ID group.
- * That is, all other liboverride IDs (in)directly used by \a is_root one, and sharing the same
- * library for their reference IDs.
- *
- * \param id_root: The root of the hierarchy of liboverride dependencies to be tagged.
- * \param do_create_main_relashionships: Whether main relations needs to be created or already
- * exist (in any case, they will be freed by this function).
- */
-void BKE_lib_override_library_override_group_tag(Main *bmain,
-                                                 ID *id_root,
-                                                 const uint tag,
-                                                 const uint missing_tag,
-                                                 const bool do_create_main_relashionships)
-{
-  if (do_create_main_relashionships) {
-    BKE_main_relations_create(bmain, 0);
+    /* Then, we remove (untag) bone shape objects, you shall never want to directly/explicitely
+     * override those. */
+    LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+      if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & tag)) {
+        for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+          if (pchan->custom != NULL) {
+            pchan->custom->id.tag &= ~(tag | missing_tag);
+          }
+        }
+      }
+    }
   }
 
-  /* We tag all liboverride data-blocks from the same library as reference one,
-   * being used by the root ID. */
-  lib_override_hierarchy_recursive_tag(
-      bmain, id_root, tag, missing_tag, id_root->override_library->reference->lib);
+  lib_override_hierarchy_dependencies_recursive_tag(bmain, id, tag, missing_tag);
 
   BKE_main_relations_free(bmain);
 }
 
-static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
+static int lib_override_local_group_tag_cb(LibraryIDLinkCallbackData *cb_data)
 {
-  if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
+  if (cb_data->cb_flag &
+      (IDWALK_CB_EMBEDDED | IDWALK_C

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list