From 076d797bda67efea6c977d424f0f89bec69fbadd Mon Sep 17 00:00:00 2001 From: Johnny Matthews Date: Mon, 4 Oct 2021 12:01:29 -0500 Subject: Geometry Nodes: Curve Trim Node Update This update allows the Trim Curve node to use float field inputs for the start and end inputs. These fields are evaluated on the spline domain. Differential Revision: https://developer.blender.org/D12744 --- .../nodes/geometry/nodes/node_geo_curve_trim.cc | 54 +++++++++++++++------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc index 97043980899..4303999f79c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc @@ -29,10 +29,19 @@ namespace blender::nodes { static void geo_node_curve_trim_declare(NodeDeclarationBuilder &b) { b.add_input("Curve"); - b.add_input("Start").min(0.0f).max(1.0f).subtype(PROP_FACTOR); - b.add_input("End").min(0.0f).max(1.0f).default_value(1.0f).subtype(PROP_FACTOR); - b.add_input("Start", "Start_001").min(0.0f).subtype(PROP_DISTANCE); - b.add_input("End", "End_001").min(0.0f).default_value(1.0f).subtype(PROP_DISTANCE); + b.add_input("Start").min(0.0f).max(1.0f).subtype(PROP_FACTOR).supports_field(); + b.add_input("End") + .min(0.0f) + .max(1.0f) + .default_value(1.0f) + .subtype(PROP_FACTOR) + .supports_field(); + b.add_input("Start", "Start_001").min(0.0f).subtype(PROP_DISTANCE).supports_field(); + b.add_input("End", "End_001") + .min(0.0f) + .default_value(1.0f) + .subtype(PROP_DISTANCE) + .supports_field(); b.add_output("Curve"); } @@ -322,13 +331,24 @@ static void trim_bezier_spline(Spline &spline, static void geometry_set_curve_trim(GeometrySet &geometry_set, const GeometryNodeCurveSampleMode mode, - const float start, - const float end) + Field &start_field, + Field &end_field) { if (!geometry_set.has_curve()) { return; } + CurveComponent &component = geometry_set.get_component_for_write(); + GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE}; + const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE); + + fn::FieldEvaluator evaluator{field_context, domain_size}; + evaluator.add(start_field); + evaluator.add(end_field); + evaluator.evaluate(); + const blender::VArray &starts = evaluator.get_evaluated(0); + const blender::VArray &ends = evaluator.get_evaluated(1); + CurveEval &curve = *geometry_set.get_curve_for_write(); MutableSpan splines = curve.splines(); @@ -343,19 +363,19 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set, /* Return a spline with one point instead of implicitly * reversing the spline or switching the parameters. */ - if (end < start) { + if (ends[i] < starts[i]) { spline.resize(1); continue; } const Spline::LookupResult start_lookup = (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) ? - spline.lookup_evaluated_length(std::clamp(start, 0.0f, spline.length())) : - spline.lookup_evaluated_factor(std::clamp(start, 0.0f, 1.0f)); + spline.lookup_evaluated_length(std::clamp(starts[i], 0.0f, spline.length())) : + spline.lookup_evaluated_factor(std::clamp(starts[i], 0.0f, 1.0f)); const Spline::LookupResult end_lookup = (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) ? - spline.lookup_evaluated_length(std::clamp(end, 0.0f, spline.length())) : - spline.lookup_evaluated_factor(std::clamp(end, 0.0f, 1.0f)); + spline.lookup_evaluated_length(std::clamp(ends[i], 0.0f, spline.length())) : + spline.lookup_evaluated_factor(std::clamp(ends[i], 0.0f, 1.0f)); switch (spline.type()) { case Spline::Type::Bezier: @@ -382,17 +402,17 @@ static void geo_node_curve_trim_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input("Curve"); if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) { - const float start = params.extract_input("Start"); - const float end = params.extract_input("End"); + Field start_field = params.extract_input>("Start"); + Field end_field = params.extract_input>("End"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - geometry_set_curve_trim(geometry_set, mode, start, end); + geometry_set_curve_trim(geometry_set, mode, start_field, end_field); }); } else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) { - const float start = params.extract_input("Start_001"); - const float end = params.extract_input("End_001"); + Field start_field = params.extract_input>("Start_001"); + Field end_field = params.extract_input>("End_001"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - geometry_set_curve_trim(geometry_set, mode, start, end); + geometry_set_curve_trim(geometry_set, mode, start_field, end_field); }); } -- cgit v1.2.3