[Bf-blender-cvs] [25543e69836] master: LibOverride: Better handling of missing linked data during resync.

Bastien Montagne noreply at git.blender.org
Wed Dec 16 15:13:04 CET 2020


Commit: 25543e6983602b4d14f51d73396c652b2aa65aa0
Author: Bastien Montagne
Date:   Wed Dec 16 15:10:28 2020 +0100
Branches: master
https://developer.blender.org/rB25543e6983602b4d14f51d73396c652b2aa65aa0

LibOverride: Better handling of missing linked data during resync.

We do not generate overrides for missing data-blocks (aka placeholder
ones) anymore, and properly delete the remaining old overrides of those
during the resync process.

This should prevent constant 'missing data-blocks' messages when opening
blend files with overrides whose libraries have beed edited.

Issue reported by @andy from Blender studio, thanks.

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

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 bf6b5cbccef..13edabd4cb7 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -72,6 +72,7 @@ void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
 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,
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index d82315a0e7f..11544d83ba9 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -369,6 +369,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
 static bool lib_override_hierarchy_recursive_tag(Main *bmain,
                                                  ID *id,
                                                  const uint tag,
+                                                 const uint missing_tag,
                                                  Library *override_group_lib_reference)
 {
   void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
@@ -377,9 +378,16 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain,
     return (id->tag & tag) != 0;
   }
 
+  /* 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) {
-    id->tag |= tag;
+    if (id->override_library->reference->tag & LIB_TAG_MISSING) {
+      id->tag |= missing_tag;
+    }
+    else {
+      id->tag |= tag;
+    }
   }
 
   /* This way we won't process again that ID, should we encounter it again through another
@@ -397,7 +405,7 @@ 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, override_group_lib_reference) &&
+              bmain, *entry->id_pointer, tag, missing_tag, override_group_lib_reference) &&
           override_group_lib_reference == NULL) {
         id->tag |= tag;
       }
@@ -430,7 +438,7 @@ void BKE_lib_override_library_dependencies_tag(Main *bmain,
   /* 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, NULL);
+  lib_override_hierarchy_recursive_tag(bmain, id_root, tag, 0, NULL);
 
   BKE_main_relations_free(bmain);
 }
@@ -447,6 +455,7 @@ void BKE_lib_override_library_dependencies_tag(Main *bmain,
 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) {
@@ -456,7 +465,7 @@ void BKE_lib_override_library_override_group_tag(Main *bmain,
   /* 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, id_root->override_library->reference->lib);
+      bmain, id_root, tag, missing_tag, id_root->override_library->reference->lib);
 
   BKE_main_relations_free(bmain);
 }
@@ -492,8 +501,9 @@ static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_da
   }
 
   /* We tag all collections and objects for override. And we also tag all other data-blocks which
-   * would use one of those. */
-  if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+   * would use one of those.
+   * Note: missing IDs (aka placeholders) are never overridden. */
+  if (ELEM(GS(id->name), ID_OB, ID_GR) && !(id->tag & LIB_TAG_MISSING)) {
     id->tag |= LIB_TAG_DOIT;
   }
 
@@ -725,7 +735,7 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
 
   /* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, and tag
    * linked reference ones to be overridden again. */
-  BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true);
+  BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_MISSING, true);
 
   GHash *linkedref_to_old_override = BLI_ghash_new(
       BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
@@ -835,6 +845,12 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
       }
       id->tag &= ~LIB_TAG_DOIT;
     }
+    /* Also cleanup old overrides that went missing in new linked data. */
+    else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id)) {
+      BLI_assert(ID_IS_OVERRIDE_LIBRARY(id));
+      id->tag |= LIB_TAG_DOIT;
+      id->tag &= ~LIB_TAG_MISSING;
+    }
   }
   FOREACH_MAIN_ID_END;
   BKE_id_multi_tagged_delete(bmain);
@@ -876,7 +892,7 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
   id_root->tag |= LIB_TAG_DOIT;
 
   /* Tag all library overrides in the chains of dependencies from the given root one. */
-  BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true);
+  BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_DOIT, true);
 
   ID *id;
   FOREACH_MAIN_ID_BEGIN (bmain, id) {



More information about the Bf-blender-cvs mailing list