From 17021adceaee28295b89301b4f715b6bcd8d5fca Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 20 Sep 2021 20:23:26 -0500 Subject: Geometry Nodes: Curve Sample Node This node allows sampling positions, tangents, and normals at any arbitrary point along a curve. The curve can include multiple splines, all are taken into account. The node does not yet support transferring generic attributes like radius, because some more general tooling will make that much more feasible and useful in different scenarios. This is a field node, so it is evaluated in the context of a data-flow node like "Set Position". One nice thing about that is it can easily be used to move an entire geometry like the follow path constraint. The point along the curve is chosen either with a factor of the total length of the curve, or a length into the curve, the same choice used in the curve trim node. Differential Revision: https://developer.blender.org/D12565 --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/BKE_spline.hh | 1 + source/blender/blenkernel/intern/curve_eval.cc | 17 +++++++++++++++++ source/blender/blenkernel/intern/node.cc | 1 + 4 files changed, 20 insertions(+) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 45ce843ef78..e4e9a6eff3a 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1495,6 +1495,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_MATERIAL_ASSIGN 1082 #define GEO_NODE_REALIZE_INSTANCES 1083 #define GEO_NODE_ATTRIBUTE_STATISTIC 1084 +#define GEO_NODE_CURVE_SAMPLE 1085 /** \} */ diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh index 0fbf39a52fa..541ff19c1cd 100644 --- a/source/blender/blenkernel/BKE_spline.hh +++ b/source/blender/blenkernel/BKE_spline.hh @@ -565,6 +565,7 @@ struct CurveEval { blender::Array control_point_offsets() const; blender::Array evaluated_point_offsets() const; + blender::Array accumulated_spline_lengths() const; void assert_valid_point_attributes() const; }; diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc index ea84766943d..8eec7f5dfab 100644 --- a/source/blender/blenkernel/intern/curve_eval.cc +++ b/source/blender/blenkernel/intern/curve_eval.cc @@ -143,6 +143,23 @@ blender::Array CurveEval::evaluated_point_offsets() const return offsets; } +/** + * Return the accumulated length at the start of every spline in the curve. + * + * \note The result is one longer than the spline count; the last element is the total length. + */ +blender::Array CurveEval::accumulated_spline_lengths() const +{ + Array spline_lengths(splines_.size() + 1); + float spline_length = 0.0f; + for (const int i : splines_.index_range()) { + spline_lengths[i] = spline_length; + spline_length += splines_[i]->length(); + } + spline_lengths.last() = spline_length; + return spline_lengths; +} + static BezierSpline::HandleType handle_type_from_dna_bezt(const eBezTriple_Handle dna_handle_type) { switch (dna_handle_type) { diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 7d679cfd076..e2891f00119 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -5183,6 +5183,7 @@ static void registerGeometryNodes() register_node_type_geo_bounding_box(); register_node_type_geo_collection_info(); register_node_type_geo_convex_hull(); + register_node_type_geo_curve_sample(); register_node_type_geo_curve_endpoints(); register_node_type_geo_curve_fill(); register_node_type_geo_curve_length(); -- cgit v1.2.3