[Bf-blender-cvs] [c9958c8e9f0] geometry-nodes-simulation: Basics of temporary and persistent cache working again

Hans Goudey noreply at git.blender.org
Thu Dec 8 07:06:41 CET 2022


Commit: c9958c8e9f0ad674e14b71003850ffed6635c2c3
Author: Hans Goudey
Date:   Thu Dec 8 00:06:35 2022 -0600
Branches: geometry-nodes-simulation
https://developer.blender.org/rBc9958c8e9f0ad674e14b71003850ffed6635c2c3

Basics of temporary and persistent cache working again

Edge cases not really tested still though

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

M	source/blender/blenkernel/BKE_compute_cache.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc

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

diff --git a/source/blender/blenkernel/BKE_compute_cache.hh b/source/blender/blenkernel/BKE_compute_cache.hh
index 0eadf08ad7f..1b06bbfc676 100644
--- a/source/blender/blenkernel/BKE_compute_cache.hh
+++ b/source/blender/blenkernel/BKE_compute_cache.hh
@@ -4,6 +4,7 @@
 
 #include <map>
 
+#include "BLI_bit_vector.hh"
 #include "BLI_compute_context.hh"
 #include "BLI_map.hh"
 
@@ -30,28 +31,23 @@ struct TimePoint {
 /* TODO: Clear cache when editing nodes? Only sometimes, when persistent caching is turned off. */
 class SimulationCache {
 
+  /* TODO: These will need to be a generic value at some point. */
   struct CacheValues {
-    /* TODO: This will need to be a generic value at some point. */
-    /* Map from simulation time index (see #SimulationCache::times) to value. */
     Vector<GeometrySet> persistent_cache;
+    BitVector<> persistent_caches_filled;
 
     std::optional<GeometrySet> non_persistent_value;
 
-    GeometrySet lookup_index(const int index) const
+    void ensure_size(const int size)
     {
-      if (!persistent_cache.index_range().contains(index)) {
-        return persistent_cache[index];
-      }
-      return {};
+      persistent_cache.resize(size);
+      persistent_caches_filled.resize(size);
     }
   };
 
   /* Map from cache data identifier (socket name) to values at stored times. */
   Map<std::string, CacheValues> caches_;
 
-  /* Ordered list of cached simulation frames. */
-  Vector<TimePoint> persistent_times_;
-
   std::optional<TimePoint> start_time_;
 
   std::optional<TimePoint> last_run_time_;
@@ -68,20 +64,13 @@ class SimulationCache {
 
   std::optional<GeometrySet> value_at_or_before_time(StringRef data_name, TimePoint time)
   {
-    const CacheValues *values = caches_.lookup_ptr(data_name);
-    if (!values) {
-      return std::nullopt;
+    if (std::optional<GeometrySet> value = this->value_at_time(data_name, time)) {
+      return value;
     }
-    if (last_run_time_->time < time.time) {
-      if (values->non_persistent_value) {
-        return std::move(values->non_persistent_value);
-      }
+    if (std::optional<GeometrySet> value = this->value_before_time(data_name, time)) {
+      return value;
     }
-    const int index = this->index_at_or_before_time(time);
-    if (!values->persistent_cache.index_range().contains(index)) {
-      return std::nullopt;
-    }
-    return values->persistent_cache[index];
+    return std::nullopt;
   }
 
   std::optional<GeometrySet> value_before_time(StringRef data_name, TimePoint time)
@@ -95,10 +84,22 @@ class SimulationCache {
         return std::move(values->non_persistent_value);
       }
     }
-    const int index = this->index_before_time(time);
-    if (!values->persistent_cache.index_range().contains(index)) {
+    /* TODO: Maybe separate retrieval of persistent and temprary cache values? Though that doesn't
+     * really provide a benefit right now. */
+    if (values->persistent_cache.is_empty()) {
       return std::nullopt;
     }
+    int index = std::min<int>(values->persistent_cache.index_range().last(),
+                              time.frame - start_time_->frame);
+    if (index < 0) {
+      return std::nullopt;
+    }
+    while (!values->persistent_caches_filled[index]) {
+      index--;
+      if (index < 0) {
+        return std::nullopt;
+      }
+    }
     return values->persistent_cache[index];
   }
 
@@ -108,11 +109,14 @@ class SimulationCache {
     if (!values) {
       return std::nullopt;
     }
-    const std::optional<int> index = this->index_at_time(time);
-    if (!index) {
+    const int index = time.frame - start_time_->frame;
+    if (!values->persistent_cache.index_range().contains(index)) {
+      return std::nullopt;
+    }
+    if (!values->persistent_caches_filled[index]) {
       return std::nullopt;
     }
-    return values->persistent_cache[*index];
+    return values->persistent_cache[index];
   }
 
   void store_temporary(const StringRef data_name, const TimePoint time, GeometrySet value)
@@ -131,62 +135,31 @@ class SimulationCache {
     if (!start_time_) {
       start_time_.emplace(time);
     }
-    const int index = this->index_before_time(time);
-    persistent_times_.resize(index);
-    persistent_times_[index] = time;
     CacheValues &values = caches_.lookup_or_add_default_as(data_name);
-    values.persistent_cache.resize(index);
+    const int index = time.frame - start_time_->frame;
+    values.ensure_size(index + 1);
     values.persistent_cache[index] = std::move(value);
+    values.persistent_caches_filled[index].set();
   }
 
   void clear()
   {
-    persistent_times_.clear();
     caches_.clear();
+    start_time_.reset();
+    last_run_time_.reset();
   }
 
   bool is_empty() const
   {
-    return persistent_times_.is_empty();
-  }
-
- private:
-  int index_at_or_before_time(const TimePoint time) const
-  {
-    if (persistent_times_.is_empty()) {
-      return 0;
-    }
-    int insert_index = 0;
-    for (const int i : persistent_times_.index_range()) {
-      if (persistent_times_[i].frame <= time.frame) {
-        break;
-      }
-      insert_index++;
-    }
-    return insert_index;
-  }
-  int index_before_time(const TimePoint time) const
-  {
-    if (persistent_times_.is_empty()) {
-      return 0;
-    }
-    int insert_index = 0;
-    for (const int i : persistent_times_.index_range()) {
-      if (persistent_times_[i].frame < time.frame) {
-        break;
+    for (const CacheValues &values : caches_.values()) {
+      if (values.non_persistent_value) {
+        return false;
       }
-      insert_index++;
-    }
-    return insert_index;
-  }
-  std::optional<int> index_at_time(const TimePoint time) const
-  {
-    for (const int i : persistent_times_.index_range()) {
-      if (persistent_times_[i].frame == time.frame) {
-        return i;
+      if (!values.persistent_cache.is_empty()) {
+        return false;
       }
     }
-    return std::nullopt;
+    return true;
   }
 };
 
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f56acc43582..0db6d55d3e3 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -345,6 +345,7 @@ set(SRC
   BKE_colorband.h
   BKE_colortools.h
   BKE_compute_contexts.hh
+  BKE_compute_cache.hh
   BKE_constraint.h
   BKE_context.h
   BKE_cpp_types.h
diff --git a/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc b/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc
index d90dd67ff4d..97ad87f9718 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_simulation_output.cc
@@ -91,6 +91,11 @@ static void node_geo_exec(GeoNodeExecParams params)
   GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
   geometry_set.ensure_owns_direct_data();
   if (storage.use_persistent_cache) {
+    if (!cache.is_empty()) {
+      if (time.time < cache.start_time()->time) {
+        cache.clear();
+      }
+    }
     /* If using the cache or there is no cached data yet, write the input in a new cache value. */
     cache.store_persistent("Geometry", time, geometry_set);
   }



More information about the Bf-blender-cvs mailing list