[Bf-blender-cvs] [7772880d696] master: ViewLayer resync: Add sanity checks for objects/bases mappings.

Bastien Montagne noreply at git.blender.org
Fri Aug 13 16:38:59 CEST 2021


Commit: 7772880d696c306fa41a27af65f7a21a9168c616
Author: Bastien Montagne
Date:   Fri Aug 13 12:40:56 2021 +0200
Branches: master
https://developer.blender.org/rB7772880d696c306fa41a27af65f7a21a9168c616

ViewLayer resync: Add sanity checks for objects/bases mappings.

Add a debug-only check regarding consistency of the cache (mapping from
objects to their bases) for a given ViewLayer.

Issues can happen otherwise when some code does remapping of objects,
and forgets to call `BKE_main_collection_sync_remap()` (which clears
those caches) instead of `BKE_main_collection_sync()`.

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

M	source/blender/blenkernel/intern/layer.c

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

diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index e7d83c668c8..b489675cd74 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1174,6 +1174,52 @@ static void layer_collection_sync(ViewLayer *view_layer,
                                 parent_local_collections_bits);
 }
 
+#ifndef NDEBUG
+static bool view_layer_objects_base_cache_validate(ViewLayer *view_layer, LayerCollection *layer)
+{
+  bool is_valid = true;
+
+  if (layer == NULL) {
+    layer = view_layer->layer_collections.first;
+  }
+
+  /* Only check for a collection's objects if its layer is not excluded. */
+  if ((layer->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
+    LISTBASE_FOREACH (CollectionObject *, cob, &layer->collection->gobject) {
+      if (cob->ob == NULL) {
+        continue;
+      }
+      if (BLI_ghash_lookup(view_layer->object_bases_hash, cob->ob) == NULL) {
+        CLOG_FATAL(
+            &LOG,
+            "Object '%s' from collection '%s' has no entry in view layer's object bases cache",
+            cob->ob->id.name + 2,
+            layer->collection->id.name + 2);
+        is_valid = false;
+        break;
+      }
+    }
+  }
+
+  if (is_valid) {
+    LISTBASE_FOREACH (LayerCollection *, layer_child, &layer->layer_collections) {
+      if (!view_layer_objects_base_cache_validate(view_layer, layer_child)) {
+        is_valid = false;
+        break;
+      }
+    }
+  }
+
+  return is_valid;
+}
+#else
+static bool view_layer_objects_base_cache_validate(ViewLayer *UNUSED(view_layer),
+                                                   LayerCollection *UNUSED(layer))
+{
+  return true;
+}
+#endif
+
 /**
  * Update view layer collection tree from collections used in the scene.
  * This is used when collections are removed or added, both while editing
@@ -1240,6 +1286,12 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
     }
 
     if (base->object) {
+      /* Those asserts are commented, since they are too expensive to perform even in debug, as
+       * this layer resync function currently gets called way too often. */
+#if 0
+      BLI_assert(BLI_findindex(&new_object_bases, base) == -1);
+      BLI_assert(BLI_findptr(&new_object_bases, base->object, offsetof(Base, object)) == NULL);
+#endif
       BLI_ghash_remove(view_layer->object_bases_hash, base->object, NULL, NULL);
     }
   }
@@ -1247,6 +1299,8 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
   BLI_freelistN(&view_layer->object_bases);
   view_layer->object_bases = new_object_bases;
 
+  view_layer_objects_base_cache_validate(view_layer, NULL);
+
   LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
     BKE_base_eval_flags(base);
   }



More information about the Bf-blender-cvs mailing list