[Bf-blender-cvs] [f487dbae97f] temp-geometry-nodes-fields: use GFieldRef where appropriate

Jacques Lucke noreply at git.blender.org
Fri Sep 3 13:29:32 CEST 2021


Commit: f487dbae97f08e9830d202ca1fdd8fefacb78205
Author: Jacques Lucke
Date:   Fri Sep 3 13:29:22 2021 +0200
Branches: temp-geometry-nodes-fields
https://developer.blender.org/rBf487dbae97f08e9830d202ca1fdd8fefacb78205

use GFieldRef where appropriate

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

M	source/blender/functions/FN_field.hh
M	source/blender/functions/intern/field.cc
M	source/blender/functions/tests/FN_field_test.cc

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

diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 29bb2cc25ba..482fdab0600 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -73,27 +73,35 @@ class FieldSource {
   }
 };
 
-/**
- * Descibes the output of a function. Generally corresponds to the combination of an output socket
- * and link combination in a node graph.
- */
-class GField {
-  std::shared_ptr<FieldSource> source_;
+/** Common base class for fields to avoid declaring the same methods for #GField and #GFieldRef. */
+template<typename SourcePtr> class GFieldBase {
+ protected:
+  SourcePtr source_ = nullptr;
   int source_output_index_ = 0;
 
- public:
-  GField() = default;
-
-  GField(std::shared_ptr<FieldSource> source, const int source_output_index = 0)
+  GFieldBase(SourcePtr source, const int source_output_index)
       : source_(std::move(source)), source_output_index_(source_output_index)
   {
   }
 
+ public:
+  GFieldBase() = default;
+
   operator bool() const
   {
     return source_ != nullptr;
   }
 
+  friend bool operator==(const GFieldBase &a, const GFieldBase &b)
+  {
+    return &*a.source_ == &*b.source_ && a.source_output_index_ == b.source_output_index_;
+  }
+
+  uint64_t hash() const
+  {
+    return get_default_hash_2(source_, source_output_index_);
+  }
+
   const fn::CPPType &cpp_type() const
   {
     return source_->cpp_type_of_output_index(source_output_index_);
@@ -120,6 +128,38 @@ class GField {
   }
 };
 
+/**
+ * Describes the output of a function. Generally corresponds to the combination of an output socket
+ * and link combination in a node graph.
+ */
+class GField : public GFieldBase<std::shared_ptr<FieldSource>> {
+ public:
+  GField() = default;
+
+  GField(std::shared_ptr<FieldSource> source, const int source_output_index = 0)
+      : GFieldBase<std::shared_ptr<FieldSource>>(std::move(source), source_output_index)
+  {
+  }
+};
+
+/** Same as #GField but is cheaper to copy/move around, because it does not contain a
+ * #std::shared_ptr.
+ */
+class GFieldRef : public GFieldBase<const FieldSource *> {
+ public:
+  GFieldRef() = default;
+
+  GFieldRef(const GField &field)
+      : GFieldBase<const FieldSource *>(&field.source(), field.source_output_index())
+  {
+  }
+
+  GFieldRef(const FieldSource &source, const int source_output_index = 0)
+      : GFieldBase<const FieldSource *>(&source, source_output_index)
+  {
+  }
+};
+
 template<typename T> class Field : public GField {
  public:
   Field() = default;
@@ -235,14 +275,14 @@ class ContextFieldSource : public FieldSource {
 };
 
 Vector<const GVArray *> evaluate_fields(ResourceScope &scope,
-                                        Span<const GField *> fields_to_evaluate,
+                                        Span<GFieldRef> fields_to_evaluate,
                                         IndexMask mask,
                                         const FieldContext &context,
                                         Span<GVMutableArray *> dst_hints = {});
 
 void evaluate_constant_field(const GField &field, void *r_value);
 
-void evaluate_fields_to_spans(Span<const GField *> fields_to_evaluate,
+void evaluate_fields_to_spans(Span<GFieldRef> fields_to_evaluate,
                               IndexMask mask,
                               const FieldContext &context,
                               Span<GMutableSpan> out_spans);
@@ -352,9 +392,9 @@ class FieldEvaluator : NonMovable, NonCopyable {
   void evaluate()
   {
     BLI_assert_msg(!is_evaluated_, "Cannot evaluate fields twice.");
-    Array<const GField *> fields(fields_to_evaluate_.size());
+    Array<GFieldRef> fields(fields_to_evaluate_.size());
     for (const int i : fields_to_evaluate_.index_range()) {
-      fields[i] = &fields_to_evaluate_[i];
+      fields[i] = fields_to_evaluate_[i];
     }
     evaluated_varrays_ = evaluate_fields(scope_, fields, mask_, context_, dst_hints_);
     BLI_assert(fields_to_evaluate_.size() == evaluated_varrays_.size());
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 073908e6c1d..dbc355e1be3 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -24,62 +24,39 @@
 
 namespace blender::fn {
 
-struct GFieldRef {
-  const FieldSource *source;
-  int index;
-
-  GFieldRef(const FieldSource &source, const int index) : source(&source), index(index)
-  {
-  }
-
-  GFieldRef(const GField &field) : source(&field.source()), index(field.source_output_index())
-  {
-  }
-
-  uint64_t hash() const
-  {
-    return get_default_hash_2(*source, index);
-  }
-
-  friend bool operator==(const GFieldRef &a, const GFieldRef &b)
-  {
-    return *a.source == *b.source && a.index == b.index;
-  }
-};
-
 struct FieldGraphInfo {
-  MultiValueMap<GFieldRef, const GField *> field_users;
+  MultiValueMap<GFieldRef, GFieldRef> field_users;
   VectorSet<std::reference_wrapper<const ContextFieldSource>> deduplicated_context_sources;
 };
 
-static FieldGraphInfo preprocess_field_graph(Span<const GField *> entry_fields)
+static FieldGraphInfo preprocess_field_graph(Span<GFieldRef> entry_fields)
 {
   FieldGraphInfo graph_info;
 
-  Stack<const GField *> fields_to_check;
-  Set<const GField *> handled_fields;
+  Stack<GFieldRef> fields_to_check;
+  Set<GFieldRef> handled_fields;
 
-  for (const GField *field : entry_fields) {
+  for (GFieldRef field : entry_fields) {
     if (handled_fields.add(field)) {
       fields_to_check.push(field);
     }
   }
 
   while (!fields_to_check.is_empty()) {
-    const GField *field = fields_to_check.pop();
-    if (field->has_context_source()) {
+    GFieldRef field = fields_to_check.pop();
+    if (field.has_context_source()) {
       const ContextFieldSource &context_source = static_cast<const ContextFieldSource &>(
-          field->source());
+          field.source());
       graph_info.deduplicated_context_sources.add(context_source);
       continue;
     }
-    BLI_assert(field->has_operation_source());
+    BLI_assert(field.has_operation_source());
     const OperationFieldSource &operation = static_cast<const OperationFieldSource &>(
-        field->source());
-    for (const GField &operation_input : operation.inputs()) {
+        field.source());
+    for (const GFieldRef operation_input : operation.inputs()) {
       graph_info.field_users.add(operation_input, field);
-      if (handled_fields.add(&operation_input)) {
-        fields_to_check.push(&operation_input);
+      if (handled_fields.add(operation_input)) {
+        fields_to_check.push(operation_input);
       }
     }
   }
@@ -104,11 +81,11 @@ static Vector<const GVArray *> get_field_context_inputs(ResourceScope &scope,
   return field_context_inputs;
 }
 
-static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
-                                               Span<const GVArray *> field_context_inputs)
+static Set<GFieldRef> find_varying_fields(const FieldGraphInfo &graph_info,
+                                          Span<const GVArray *> field_context_inputs)
 {
-  Set<const GField *> found_fields;
-  Stack<const GField *> fields_to_check;
+  Set<GFieldRef> found_fields;
+  Stack<GFieldRef> fields_to_check;
   for (const int i : field_context_inputs.index_range()) {
     const GVArray *varray = field_context_inputs[i];
     if (varray->is_single()) {
@@ -116,17 +93,17 @@ static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
     }
     const ContextFieldSource &context_source = graph_info.deduplicated_context_sources[i];
     const GFieldRef context_source_field{context_source, 0};
-    const Span<const GField *> users = graph_info.field_users.lookup(context_source_field);
-    for (const GField *field : users) {
+    const Span<GFieldRef> users = graph_info.field_users.lookup(context_source_field);
+    for (const GFieldRef &field : users) {
       if (found_fields.add(field)) {
         fields_to_check.push(field);
       }
     }
   }
   while (!fields_to_check.is_empty()) {
-    const GField *field = fields_to_check.pop();
-    const Span<const GField *> users = graph_info.field_users.lookup(*field);
-    for (const GField *field : users) {
+    GFieldRef field = fields_to_check.pop();
+    const Span<GFieldRef> users = graph_info.field_users.lookup(field);
+    for (GFieldRef field : users) {
       if (found_fields.add(field)) {
         fields_to_check.push(field);
       }
@@ -138,7 +115,7 @@ static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
 static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
                                                       ResourceScope &scope,
                                                       const FieldGraphInfo &graph_info,
-                                                      Span<const GField *> output_fields)
+                                                      Span<GFieldRef> output_fields)
 {
   MFProcedureBuilder builder{procedure};
   Map<GFieldRef, MFVariable *> variable_by_field;
@@ -149,16 +126,16 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
   }
 
   struct FieldWithIndex {
-    const GField *field;
+    GFieldRef field;
     int current_input_index = 0;
   };
 
-  for (const GField *field : output_fields) {
+  for (GFieldRef field : output_fields) {
     Stack<FieldWithIndex> fields_to_check;
     fields_to_check.push({field, 0});
     while (!fields_to_check.is_empty()) {
       FieldWithIndex &field_with_index = fields_to_check.peek();
-      const GField &field = *field_with_index.field;
+      const GFieldRef &field = field_with_index.field;
       if (variable_by_field.contains(field)) {
         fields_to_check.pop();
         continue;
@@ -170,7 +147,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
       const Span<GField> operation_inputs = operation_field_source.inputs();
       if (field_with_index.current_input_index < operation_inputs.size()) {
         /* Push next input. */
-        fields_to_check.push({&operation_inputs[field_with_index.current_input_index], 0});
+        fiel

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list