[Bf-blender-cvs] [7ad2b93ec46] geometry-nodes-simulation: More semi-working sockets, lazyness, more TODOs, RNA

Hans Goudey noreply at git.blender.org
Thu Nov 24 00:20:06 CET 2022


Commit: 7ad2b93ec46ecb5c670dcd463b97aff15cb1fe65
Author: Hans Goudey
Date:   Wed Nov 23 16:02:39 2022 -0600
Branches: geometry-nodes-simulation
https://developer.blender.org/rB7ad2b93ec46ecb5c670dcd463b97aff15cb1fe65

More semi-working sockets, lazyness, more TODOs, RNA

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

M	source/blender/blenkernel/BKE_compute_cache.hh
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc
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 d48ca1254bb..7fd0d6225c7 100644
--- a/source/blender/blenkernel/BKE_compute_cache.hh
+++ b/source/blender/blenkernel/BKE_compute_cache.hh
@@ -13,35 +13,124 @@ namespace blender::bke {
 
 struct GeometryCacheValue {
   int frame;
+  float time;
   GeometrySet geometry_set;
 };
 
-struct CacheData {
+struct SimulationCache {
   Vector<GeometryCacheValue> geometry_per_frame;
 
-  GeometrySet *first_item_before(const int frame)
+  const GeometryCacheValue *value_at_or_before_time(const int frame) const
   {
-    if (geometry_per_frame.is_empty()) {
+    const int index = this->index_at_or_before_time(frame);
+    if (index >= geometry_per_frame.size()) {
       return nullptr;
     }
-    if (frame < geometry_per_frame.first().frame) {
+    return &geometry_per_frame[index];
+  }
+
+  const GeometryCacheValue *value_before_time(const int frame) const
+  {
+    const int index = this->index_before_time(frame);
+    if (index >= geometry_per_frame.size()) {
       return nullptr;
     }
+    return &geometry_per_frame[index];
+  }
 
-    GeometryCacheValue *last_value = nullptr;
-    for (int i = geometry_per_frame.size() - 1; i > 0; i--) {
+  GeometryCacheValue *value_at_time(const int frame)
+  {
+    for (const int i : geometry_per_frame.index_range()) {
+      if (geometry_per_frame[i].frame == frame) {
+        return &geometry_per_frame[i];
+      }
+    }
+    return nullptr;
+  }
+
+  GeometryCacheValue &value_at_time_ensure(const int frame)
+  {
+    for (const int i : geometry_per_frame.index_range()) {
+      if (geometry_per_frame[i].frame == frame) {
+        return geometry_per_frame[i];
+      }
+    }
+    const int index = this->index_before_time(frame);
+    GeometryCacheValue value{};
+    geometry_per_frame.insert(index, value);
+    return geometry_per_frame[index];
+  }
+
+  void insert(GeometrySet &geometry_set, const int frame, const float time)
+  {
+    BLI_assert(!this->value_at_time(frame));
+    GeometryCacheValue value{};
+    value.frame = frame;
+    value.time = time;
+    value.geometry_set = geometry_set;
+    const int index = this->index_before_time(frame);
+    geometry_per_frame.insert(index, value);
+  }
+
+ private:
+  int index_at_or_before_time(const int frame) const
+  {
+    if (geometry_per_frame.is_empty()) {
+      return 0;
+    }
+    int insert_index = 0;
+    for (const int i : geometry_per_frame.index_range()) {
+      if (geometry_per_frame[i].frame >= frame) {
+        break;
+      }
+      insert_index++;
+    }
+    return insert_index;
+  }
+  int index_before_time(const int frame) const
+  {
+    if (geometry_per_frame.is_empty()) {
+      return 0;
+    }
+    int insert_index = 0;
+    for (const int i : geometry_per_frame.index_range()) {
       if (geometry_per_frame[i].frame > frame) {
         break;
       }
-      last_value = &geometry_per_frame[i];
+      insert_index++;
     }
-
-    return last_value ? &last_value->geometry_set : nullptr;
+    return insert_index;
   }
 };
 
 struct ComputeCaches {
-  Map<ComputeContextHash, CacheData> cache_per_context;
+ private:
+  mutable std::mutex mutex;
+  Map<ComputeContextHash, SimulationCache> cache_per_context;
+
+ public:
+  ComputeCaches() = default;
+  ComputeCaches(const ComputeCaches &other)
+  {
+    cache_per_context = other.cache_per_context;
+  }
+
+  const SimulationCache *lookup_context(const ComputeContextHash &context_hash) const
+  {
+    std::scoped_lock lock{mutex};
+    return cache_per_context.lookup_ptr(context_hash);
+  }
+
+  SimulationCache &ensure_for_context(const ComputeContextHash &context_hash)
+  {
+    std::scoped_lock lock{mutex};
+    return cache_per_context.lookup_or_add_default(context_hash);
+  }
+
+  bool is_empty() const
+  {
+    return cache_per_context.is_empty();
+  }
 };
 
 }  // namespace blender::bke
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 616c8b6f141..5834794782f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1534,6 +1534,14 @@ typedef struct NodeGeometryUVUnwrap {
   uint8_t method;
 } NodeGeometryUVUnwrap;
 
+typedef struct NodeGeometrySimulationInput {
+  int8_t dummy;
+} NodeGeometrySimulationInput;
+
+typedef struct NodeGeometrySimulationOutput {
+  int8_t use_cache;
+} NodeGeometrySimulationOutput;
+
 typedef struct NodeGeometryDistributePointsInVolume {
   /* GeometryNodePointDistributeVolumeMode. */
   uint8_t mode;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 4a0094831b9..468f13d8817 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9686,6 +9686,21 @@ static void def_geo_set_curve_normal(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
+static void def_geo_simulation_input(StructRNA *srna)
+{
+}
+
+static void def_geo_simulation_output(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  RNA_def_struct_sdna_from(srna, "NodeGeometrySimulationOutput", "storage");
+
+  prop = RNA_def_property(srna, "use_cache", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_ui_text(prop, "Use Cache", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
 static void def_geo_curve_handle_type_selection(StructRNA *srna)
 {
   PropertyRNA *prop;
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 7dee87cc239..2ad7afab031 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -1318,7 +1318,7 @@ static void modifyGeometry(ModifierData *md,
                                   nmd,
                                   ctx);
 
-  if (orig_nmd->simulation_caches->cache_per_context.is_empty()) {
+  if (orig_nmd->simulation_caches->is_empty()) {
     delete orig_nmd->simulation_caches;
     orig_nmd->simulation_caches = nullptr;
   }
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 09b435d8d54..b46f1982bcf 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -410,8 +410,8 @@ DefNode(GeometryNode, GEO_NODE_SET_POSITION, 0, "SET_POSITION", SetPosition, "Se
 DefNode(GeometryNode, GEO_NODE_SET_SHADE_SMOOTH, 0, "SET_SHADE_SMOOTH", SetShadeSmooth, "Set Shade Smooth", "Control the smoothness of mesh normals around each face by changing the \"shade smooth\" attribute")
 DefNode(GeometryNode, GEO_NODE_SET_SPLINE_CYCLIC, 0, "SET_SPLINE_CYCLIC", SetSplineCyclic, "Set Spline Cyclic", "Control whether each spline loops back on itself by changing the \"cyclic\" attribute")
 DefNode(GeometryNode, GEO_NODE_SET_SPLINE_RESOLUTION, 0, "SET_SPLINE_RESOLUTION", SetSplineResolution, "Set Spline Resolution", "Control how many evaluated points should be generated on every curve segment")
-DefNode(GeometryNode, GEO_NODE_SIMULATION_INPUT, 0, "SIMULATION_INPUT", SimulationInput, "Simulation Input", "")
-DefNode(GeometryNode, GEO_NODE_SIMULATION_OUTPUT, 0, "SIMULATION_OUTPUT", SimulationOutput, "Simulation Output", "")
+DefNode(GeometryNode, GEO_NODE_SIMULATION_INPUT, def_geo_simulation_input, "SIMULATION_INPUT", SimulationInput, "Simulation Input", "")
+DefNode(GeometryNode, GEO_NODE_SIMULATION_OUTPUT, def_geo_simulation_output, "SIMULATION_OUTPUT", SimulationOutput, "Simulation Output", "")
 DefNode(GeometryNode, GEO_NODE_SPLIT_EDGES, 0, "SPLIT_EDGES", SplitEdges, "Split Edges", "Duplicate mesh edges and break connections with the surrounding faces")
 DefNode(GeometryNode, GEO_NODE_STORE_NAMED_ATTRIBUTE, def_geo_store_named_attribute, "STORE_NAMED_ATTRIBUTE", StoreNamedAttribute, "Store Named Attribute", "Store the result of a field on a geometry as an attribute with the specified name")
 DefNode(GeometryNode, GEO_NODE_STRING_JOIN, 0, "STRING_JOIN", StringJoin, "Join Strings", "Combine any number of input strings")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc b/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc
index 354f6190405..fc3901f359e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_simulation_input.cc
@@ -8,6 +8,8 @@
 
 namespace blender::nodes::node_geo_simulation_input_cc {
 
+NODE_STORAGE_FUNCS(NodeGeometrySimulationInput);
+
 static void node_declare(NodeDeclarationBuilder &b)
 {
   b.add_input<decl::Bool>(N_("Run"));
@@ -18,25 +20,40 @@ static void node_declare(NodeDeclarationBuilder &b)
   b.add_output<decl::Geometry>(N_("Geometry"));
 }
 
+static void node_init(bNodeTree * /*tree*/, bNode *node)
+{
+  NodeGeometrySimulationInput *data = MEM_cnew<NodeGeometrySimulationInput>(__func__);
+  data->dummy = false;
+  node->storage = data;
+}
+
 static void node_geo_exec(GeoNodeExecParams params)
 {
+  const NodeGeometrySimulationInput &storage = node_storage(params.node());
   const Scene *scene = DEG_get_input_scene(params.depsgraph());
   const float scene_ctime = BKE_scene_ctime_get(scene);
   const int scene_frame = int(scene_ctime);
-  const int previous_frame = scene_frame - 1;
+
+  /* TODO: Somehow use "Run" input. */
 
   const GeoNodesLFUserData &lf_data = *params.user_data();
   bke::ComputeCaches &all_caches = *lf_data.modifier_data->cache_per_frame;
-  bke::CacheData *cache = all_caches.cache_per_context.lookup_ptr(lf_data.compute_context->hash());
+  const bke::SimulationCache *cache = all_caches.lookup_context(lf_data.compute_context->hash());
   if (!cache) {
     params.set_output("Geometry", params.extract_input<GeometrySet>("Geometry"));
     return;
   }
 
-  if (cache->geometry_per_frame.contains(previous_frame)) {
-    GeometrySet geometry_set = cache->geometry_per_frame.lookup(previous_frame);
-    params.set_output("Geometry", std::move(geometry_set));
-    params.set_input_unused("Geometry");
+  if (const bke::GeometryCacheValue *data = cache->value_before_time(scene_frame)) {
+    if (params.lazy_output_is_required("Geometry")) {
+      par

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list