[Bf-blender-cvs] [62d485e4702] temp-geometry-nodes-fields-prototype: initial evaluate curve node

Jacques Lucke noreply at git.blender.org
Wed Aug 18 14:53:44 CEST 2021


Commit: 62d485e470290d0f93c6edd9d87c4e23549c5b8a
Author: Jacques Lucke
Date:   Wed Aug 18 14:53:34 2021 +0200
Branches: temp-geometry-nodes-fields-prototype
https://developer.blender.org/rB62d485e470290d0f93c6edd9d87c4e23549c5b8a

initial evaluate curve node

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/geometry/nodes/node_geo_evaluate_curve.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index a96d63dbdbb..bb8db65f4a0 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -484,7 +484,6 @@ geometry_node_categories = [
         NodeItem("GeometryNodeAttributeTransfer"),
         NodeItem("GeometryNodeAttributeExtract"),
         NodeItem("GeometryNodeAttributeFreeze"),
-        NodeItem("GeometryNodeSampleMeshSurface"),
     ]),
     GeometryNodeCategory("GEO_COLOR", "Color", items=[
         NodeItem("ShaderNodeRGBCurve"),
@@ -505,6 +504,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeCurveSplineType"),
         NodeItem("GeometryNodeCurveSetHandles"),
         NodeItem("GeometryNodeCurveSelectHandles"),
+        NodeItem("GeometryNodeEvaluateCurve"),
     ]),
     GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[
         NodeItem("GeometryNodeCurvePrimitiveLine"),
@@ -554,6 +554,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeMeshSubdivide"),
         NodeItem("GeometryNodeExtrude"),
         NodeItem("GeometryNodeExtrudeAndMove"),
+        NodeItem("GeometryNodeSampleMeshSurface"),
     ]),
     GeometryNodeCategory("GEO_PRIMITIVES_MESH", "Mesh Primitives", items=[
         NodeItem("GeometryNodeMeshCircle"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7b3321bf70f..1f7aa4dd26f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1488,6 +1488,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_POSITION 1083
 #define GEO_NODE_SET_POSITION 1084
 #define GEO_NODE_SAMPLE_MESH_SURFACE 1085
+#define GEO_NODE_EVALUATE_CURVE 1086
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 33b227ae73d..b2d485b5720 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5161,6 +5161,7 @@ static void registerGeometryNodes()
   register_node_type_geo_curve_trim();
   register_node_type_geo_delete_geometry();
   register_node_type_geo_edge_split();
+  register_node_type_geo_evaluate_curve();
   register_node_type_geo_extrude_and_move();
   register_node_type_geo_index();
   register_node_type_geo_input_material();
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 9ac8dff68ab..aff21e9d906 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -188,6 +188,7 @@ set(SRC
   geometry/nodes/node_geo_curve_trim.cc
   geometry/nodes/node_geo_delete_geometry.cc
   geometry/nodes/node_geo_edge_split.cc
+  geometry/nodes/node_geo_evaluate_curve.cc
   geometry/nodes/node_geo_extrude.cc
   geometry/nodes/node_geo_extrude_and_move.cc
   geometry/nodes/node_geo_index.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index b6390825625..1f648789981 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -75,6 +75,7 @@ void register_node_type_geo_curve_to_points(void);
 void register_node_type_geo_curve_trim(void);
 void register_node_type_geo_delete_geometry(void);
 void register_node_type_geo_edge_split(void);
+void register_node_type_geo_evaluate_curve(void);
 void register_node_type_geo_index(void);
 void register_node_type_geo_input_material(void);
 void register_node_type_geo_is_viewport(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index b29cb1389e0..8266e22eb81 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -317,6 +317,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "
 DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "")
 DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, def_geo_delete, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "")
+DefNode(GeometryNode, GEO_NODE_EVALUATE_CURVE, 0, "EVALUATE_CURVE", EvaluateCurve, "Evaluate Curve", "")
 DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "")
 DefNode(GeometryNode, GEO_NODE_INDEX, 0, "INDEX", Index, "Index", "")
 DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_evaluate_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_curve.cc
new file mode 100644
index 00000000000..b8b79e2e609
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_curve.cc
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_customdata.h"
+#include "BKE_spline.hh"
+
+#include "node_geometry_util.hh"
+
+static bNodeSocketTemplate geo_node_evaluate_curve_in[] = {
+    {SOCK_GEOMETRY, N_("Curve")},
+    {SOCK_FLOAT,
+     N_("Length"),
+     0.0f,
+     0.0f,
+     0.0f,
+     0.0f,
+     -FLT_MAX,
+     FLT_MAX,
+     PROP_TRANSLATION,
+     SOCK_FIELD},
+    {SOCK_RGBA, N_("Custom"), 1, 1, 1, 1, 0, 1, PROP_NONE, SOCK_FIELD},
+    {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_evaluate_curve_out[] = {
+    {SOCK_VECTOR, N_("Position")},
+    {SOCK_VECTOR, N_("Tangent")},
+    {SOCK_VECTOR, N_("Normal")},
+    {SOCK_RGBA, N_("Custom")},
+    {-1, ""},
+};
+
+namespace blender::nodes {
+
+class EvaluateCurveFunction : public fn::MultiFunction {
+ private:
+  GeometrySet geometry_set_;
+  AnonymousCustomDataLayerID *attribute_id_;
+
+ public:
+  EvaluateCurveFunction(GeometrySet geometry_set, AnonymousCustomDataLayerID *attribute_id)
+      : geometry_set_(std::move(geometry_set)), attribute_id_(attribute_id)
+  {
+    static fn::MFSignature signature = create_signature();
+    this->set_signature(&signature);
+    CustomData_anonymous_id_strong_increment(attribute_id_);
+  }
+
+  ~EvaluateCurveFunction() override
+  {
+    CustomData_anonymous_id_strong_decrement(attribute_id_);
+  }
+
+  static fn::MFSignature create_signature()
+  {
+    blender::fn::MFSignatureBuilder signature{"Evaluate Curve"};
+    signature.single_input<float>("Length");
+    signature.single_output<float3>("Position");
+    signature.single_output<float3>("Tangent");
+    signature.single_output<float3>("Normal");
+    signature.single_output<ColorGeometry4f>("Custom");
+    return signature.build();
+  }
+
+  void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+  {
+    const VArray<float> &src_lengths = params.readonly_single_input<float>(0, "Length");
+    MutableSpan<float3> sampled_positions = params.uninitialized_single_output<float3>(1,
+                                                                                       "Position");
+    MutableSpan<float3> sampled_tangents = params.uninitialized_single_output<float3>(2,
+                                                                                      "Tangent");
+    MutableSpan<float3> sampled_normals = params.uninitialized_single_output<float3>(3, "Normal");
+    MutableSpan<ColorGeometry4f> sampled_custom =
+        params.uninitialized_single_output<ColorGeometry4f>(4, "Custom");
+
+    auto return_default = [&]() {
+      sampled_positions.fill_indices(mask, {0, 0, 0});
+      sampled_tangents.fill_indices(mask, {0, 0, 0});
+      sampled_normals.fill_indices(mask, {0, 0, 0});
+      sampled_custom.fill_indices(mask, {0, 0, 0, 1});
+    };
+
+    if (!geometry_set_.has_curve()) {
+      return return_default();
+    }
+
+    const CurveComponent *curve_component = geometry_set_.get_component_for_read<CurveComponent>();
+    const CurveEval *curve = curve_component->get_for_read();
+    if (curve->splines().is_empty()) {
+      return return_default();
+    }
+    const Spline &spline = *curve->splines()[0];
+    std::optional<GSpan> custom_generic = spline.attributes.get_anonymous_for_read(*attribute_id_);
+    if (!custom_generic) {
+      return return_default();
+    }
+
+    Span<ColorGeometry4f> custom = (*custom_generic).typed<ColorGeometry4f>();
+    GVArray_Typed<ColorGeometry4f> evaluated_custom = spline.interpolate_to_evaluated(custom);
+
+    const float spline_length = spline.length();
+    const Span<float3> evaluated_positions = spline.evaluated_positions();
+    const Span<float3> evaluated_tangents = spline.evaluated_tangents();
+    const Span<float3> evaluated_normals = spline.evaluated_normals();
+    for (const int i : mask) {
+      const float length = std::clamp(src_lengths[i], 0.0f, spline_length);
+      Spline::LookupResult lookup = spline.lookup_evaluated_length(length);
+      const int i1 = lookup.evaluated_index;
+      const int i2 = lookup.next_evaluated_index;
+      sampled_positions[i] = attribute_math::mix2(
+          lookup.factor, evaluated_positions[i1], evaluated_positions[i2]);
+      sampled_tangents[i] = attribute_math::mix2(
+                                lookup.factor, evaluated_tangents[i1], evaluated_tangents[i2])
+                                .normalized();
+      sampled_normals[i] = attribute_math::mix2(
+                               lookup.factor, evaluated_normals[i1], eval

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list