[Bf-blender-cvs] [bf47fb40fd6] master: Geometry Nodes: fields and anonymous attributes

Jacques Lucke noreply at git.blender.org
Thu Sep 9 13:02:03 CEST 2021


Commit: bf47fb40fd6f0ee9386e9936cf213a1049c55b61
Author: Jacques Lucke
Date:   Thu Sep 9 12:54:20 2021 +0200
Branches: master
https://developer.blender.org/rBbf47fb40fd6f0ee9386e9936cf213a1049c55b61

Geometry Nodes: fields and anonymous attributes

This implements the initial core framework for fields and anonymous
attributes (also see T91274).

The new functionality is hidden behind the "Geometry Nodes Fields"
feature flag. When enabled in the user preferences, the following
new nodes become available: `Position`, `Index`, `Normal`,
`Set Position` and `Attribute Capture`.

Socket inspection has not been updated to work with fields yet.

Besides these changes at the user level, this patch contains the
ground work for:
* building and evaluating fields at run-time (`FN_fields.hh`) and
* creating and accessing anonymous attributes on geometry
  (`BKE_anonymous_attribute.h`).

For evaluating fields we use a new so called multi-function procedure
(`FN_multi_function_procedure.hh`). It allows composing multi-functions
in arbitrary ways and supports efficient evaluation as is required by
fields. See `FN_multi_function_procedure.hh` for more details on how
this evaluation mechanism can be used.

A new `AttributeIDRef` has been added which allows handling named
and anonymous attributes in the same way in many places.

Hans and I worked on this patch together.

Differential Revision: https://developer.blender.org/D12414

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

M	release/scripts/startup/bl_ui/space_userpref.py
M	release/scripts/startup/nodeitems_builtins.py
A	source/blender/blenkernel/BKE_anonymous_attribute.h
A	source/blender/blenkernel/BKE_anonymous_attribute.hh
M	source/blender/blenkernel/BKE_attribute_access.hh
M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/BKE_geometry_set_instances.hh
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/anonymous_attribute.cc
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/attribute_access_intern.hh
M	source/blender/blenkernel/intern/curve_eval.cc
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/geometry_component_curve.cc
M	source/blender/blenkernel/intern/geometry_component_mesh.cc
M	source/blender/blenkernel/intern/geometry_set_instances.cc
M	source/blender/blenkernel/intern/node.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
M	source/blender/functions/CMakeLists.txt
A	source/blender/functions/FN_field.hh
A	source/blender/functions/FN_field_cpp_type.hh
M	source/blender/functions/FN_multi_function_builder.hh
M	source/blender/functions/FN_multi_function_params.hh
A	source/blender/functions/FN_multi_function_procedure.hh
A	source/blender/functions/FN_multi_function_procedure_builder.hh
A	source/blender/functions/FN_multi_function_procedure_executor.hh
M	source/blender/functions/intern/cpp_types.cc
A	source/blender/functions/intern/field.cc
M	source/blender/functions/intern/multi_function_builder.cc
A	source/blender/functions/intern/multi_function_procedure.cc
A	source/blender/functions/intern/multi_function_procedure_builder.cc
A	source/blender/functions/intern/multi_function_procedure_executor.cc
A	source/blender/functions/tests/FN_field_test.cc
A	source/blender/functions/tests/FN_multi_function_procedure_test.cc
M	source/blender/makesdna/DNA_customdata_types.h
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/makesrna/intern/rna_userdef.c
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/modifiers/intern/MOD_nodes_evaluator.cc
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/node_geometry_util.hh
A	source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_endpoints.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
M	source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
A	source/blender/nodes/geometry/nodes/node_geo_input_index.cc
A	source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
A	source/blender/nodes/geometry/nodes/node_geo_input_position.cc
M	source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
M	source/blender/nodes/geometry/nodes/node_geo_point_separate.cc
A	source/blender/nodes/geometry/nodes/node_geo_set_position.cc
M	source/blender/nodes/intern/geometry_nodes_eval_log.cc
M	source/blender/nodes/intern/node_socket.cc

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

diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 1ac19d020d8..0d1cbc424d7 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -2254,6 +2254,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
                 ({"property": "use_sculpt_tools_tilt"}, "T82877"),
                 ({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")),
                 ({"property": "use_override_templates"}, ("T73318", "Milestone 4")),
+                ({"property": "use_geometry_nodes_fields"}, "T91274"),
             ),
         )
 
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 668ea4bfae5..114e654e22b 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -180,6 +180,10 @@ def object_eevee_cycles_shader_nodes_poll(context):
             eevee_cycles_shader_nodes_poll(context))
 
 
+def geometry_nodes_fields_poll(context):
+    return context.preferences.experimental.use_geometry_nodes_fields
+
+
 # All standard node categories currently used in nodes.
 
 shader_node_categories = [
@@ -478,6 +482,7 @@ geometry_node_categories = [
     GeometryNodeCategory("GEO_ATTRIBUTE", "Attribute", items=[
         NodeItem("GeometryNodeAttributeRandomize"),
         NodeItem("GeometryNodeAttributeMath"),
+        NodeItem("GeometryNodeAttributeCapture", poll=geometry_nodes_fields_poll),
         NodeItem("GeometryNodeAttributeClamp"),
         NodeItem("GeometryNodeAttributeCompare"),
         NodeItem("GeometryNodeAttributeConvert"),
@@ -534,6 +539,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeJoinGeometry"),
         NodeItem("GeometryNodeSeparateComponents"),
         NodeItem("GeometryNodeRaycast"),
+        NodeItem("GeometryNodeSetPosition", poll=geometry_nodes_fields_poll),
     ]),
     GeometryNodeCategory("GEO_INPUT", "Input", items=[
         NodeItem("GeometryNodeObjectInfo"),
@@ -544,6 +550,9 @@ geometry_node_categories = [
         NodeItem("FunctionNodeInputVector"),
         NodeItem("GeometryNodeInputMaterial"),
         NodeItem("GeometryNodeIsViewport"),
+        NodeItem("GeometryNodeInputPosition", poll=geometry_nodes_fields_poll),
+        NodeItem("GeometryNodeInputIndex", poll=geometry_nodes_fields_poll),
+        NodeItem("GeometryNodeInputNormal", poll=geometry_nodes_fields_poll),
     ]),
     GeometryNodeCategory("GEO_MATERIAL", "Material", items=[
         NodeItem("GeometryNodeMaterialAssign"),
diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.h b/source/blender/blenkernel/BKE_anonymous_attribute.h
new file mode 100644
index 00000000000..ebdb0b05160
--- /dev/null
+++ b/source/blender/blenkernel/BKE_anonymous_attribute.h
@@ -0,0 +1,43 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ *
+ * An #AnonymousAttributeID is used to identify attributes that are not explicitly named.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct AnonymousAttributeID AnonymousAttributeID;
+
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_weak(const char *debug_name);
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_strong(const char *debug_name);
+bool BKE_anonymous_attribute_id_has_strong_references(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_increment_weak(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_increment_strong(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_decrement_weak(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_decrement_strong(const AnonymousAttributeID *anonymous_id);
+const char *BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id);
+const char *BKE_anonymous_attribute_id_internal_name(const AnonymousAttributeID *anonymous_id);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.hh b/source/blender/blenkernel/BKE_anonymous_attribute.hh
new file mode 100644
index 00000000000..201fa2b2f52
--- /dev/null
+++ b/source/blender/blenkernel/BKE_anonymous_attribute.hh
@@ -0,0 +1,169 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <string>
+
+#include "BLI_hash.hh"
+#include "BLI_string_ref.hh"
+
+#include "BKE_anonymous_attribute.h"
+
+namespace blender::bke {
+
+/**
+ * Wrapper for #AnonymousAttributeID with RAII semantics.
+ * This class should typically not be used directly. Instead use #StrongAnonymousAttributeID or
+ * #WeakAnonymousAttributeID.
+ */
+template<bool IsStrongReference> class OwnedAnonymousAttributeID {
+ private:
+  const AnonymousAttributeID *data_ = nullptr;
+
+  template<bool OtherIsStrongReference> friend class OwnedAnonymousAttributeID;
+
+ public:
+  OwnedAnonymousAttributeID() = default;
+
+  /** Create a new anonymous attribute id. */
+  explicit OwnedAnonymousAttributeID(StringRefNull debug_name)
+  {
+    if constexpr (IsStrongReference) {
+      data_ = BKE_anonymous_attribute_id_new_strong(debug_name.c_str());
+    }
+    else {
+      data_ = BKE_anonymous_attribute_id_new_weak(debug_name.c_str());
+    }
+  }
+
+  /**
+   * This transfers ownership, so no incref is necessary.
+   * The caller has to make sure that it owned the anonymous id.
+   */
+  explicit OwnedAnonymousAttributeID(const AnonymousAttributeID *anonymous_id)
+      : data_(anonymous_id)
+  {
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID(const OwnedAnonymousAttributeID<OtherIsStrong> &other)
+  {
+    data_ = other.data_;
+    this->incref();
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID(OwnedAnonymousAttributeID<OtherIsStrong> &&other)
+  {
+    data_ = other.data_;
+    this->incref();
+    other.decref();
+    other.data_ = nullptr;
+  }
+
+  ~OwnedAnonymousAttributeID()
+  {
+    this->decref();
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID &operator=(const OwnedAnonymousAttributeID<OtherIsStrong> &other)
+  {
+    if (this == &other) {
+      return *this;
+    }
+    this->~OwnedAnonymousAttributeID();
+    new (this) OwnedAnonymousAttributeID(other);
+    return *this;
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID &operator=(OwnedAnonymousAttributeID<OtherIsStrong> &&other)
+  {
+    if (this == &other) {
+      return *this;
+    }
+    this->~OwnedAnonymousAttributeID();
+    new (this) OwnedAnonymousAttributeID(std::move(other));
+    return *this;
+  }
+
+  operator bool() const
+  {
+    return data_ != nullptr;
+  }
+
+  StringRefNull debug_name() const
+  {
+    BLI_assert(data_ != nullptr);
+    return BKE_anonymous_attribute_id_debug_name(data_);
+  }
+
+  bool has_strong_references() const
+  {
+    BLI_assert(data_ != nullptr);
+    return BKE_anonymous_attribute_id_has_strong_references(data_);
+  }
+
+  /** Extract the onwership of the currently wrapped anonymous id. */
+  const AnonymousAttributeID *extract()
+  {
+    const AnonymousAttributeID *extracted_data = data_;
+    /* Don't decref because the caller becomes the new owner. */
+    data_ = nullptr;
+    return extracted_data;
+  }
+
+  /** Get the wrapped anonymous id, without taking ownership. */
+  const AnonymousAttributeID *get() const
+  {
+    return data_;
+  }
+
+ private:
+  void incref()
+  {
+    if (data_ == nullptr) {
+      return;
+    }
+    if constexpr (IsStrongReference) {
+      BKE_anonymous_attribute_id_increment_strong(data_);
+    }
+    else {
+      BKE_anonymous_attribute_id_increment_weak(data_);
+    }
+  }
+
+  void decref()
+  {
+    if (data_ == nullptr) {
+      return;
+    }
+    if constexpr (IsStrongReference) {
+      BKE_anonymous_attribute_id_decrement_strong(data_);
+    }
+    else {
+      BKE_anonymous_attribute_id_decrement_weak(data_);
+    }
+  }
+};
+
+using StrongAnonymousAttributeID = OwnedAnonymousAttributeID<true>;
+using WeakAnonymousAttributeID = OwnedAnonymousAttributeID<false>;
+
+}  // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index c3f7dbd4bd9..9d309d8a1c1 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -22,6 +22,7 @@
 #include "FN_generic_span.hh"
 #include "FN_generic_virtual_array.hh"
 
+#include "BKE_anonymous_attribute.hh"
 #include "BKE_attribute.h"
 
 #include "BLI_color.hh"
@@ -29,6 +30,81 @@
 #include "BLI_float3.hh"
 #include "BLI_function_ref.hh"
 
+namespace blender::bke {
+
+/**
+ * Identifies an attribute that is either named or anonymous.
+ * It does 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list