[Bf-blender-cvs] [52cb657e915] geometry-nodes-curve-support: Geometry Nodes Curves: Fixes for curve trim node

Hans Goudey noreply at git.blender.org
Mon Apr 19 00:14:43 CEST 2021


Commit: 52cb657e9155fd2b1b6c8cfe856d5747a64b9edf
Author: Hans Goudey
Date:   Sun Apr 18 17:14:34 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rB52cb657e9155fd2b1b6c8cfe856d5747a64b9edf

Geometry Nodes Curves: Fixes for curve trim node

The remaining issue is interpolation and recalculation of bezier handles.
Other than that the node should work fine.

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

M	source/blender/blenkernel/intern/derived_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc

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

diff --git a/source/blender/blenkernel/intern/derived_curve.cc b/source/blender/blenkernel/intern/derived_curve.cc
index 6cea835d0d9..372d184b86a 100644
--- a/source/blender/blenkernel/intern/derived_curve.cc
+++ b/source/blender/blenkernel/intern/derived_curve.cc
@@ -515,9 +515,8 @@ Spline::LookupResult Spline::lookup_evaluated_length(const float length) const
   const float *offset = std::lower_bound(lengths.begin(), lengths.end(), length);
   const int index = offset - lengths.begin();
 
-  const float segment_length = lengths[index];
   const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
-  const float factor = (length - previous_length) / (segment_length - previous_length);
+  const float factor = (length - previous_length) / (lengths[index] - previous_length);
 
   return LookupResult{index, factor};
 }
@@ -634,7 +633,6 @@ void BezierSpline::add_point(const float3 position,
 
 void BezierSpline::drop_front(const int count)
 {
-  std::cout << __func__ << ": " << count << "\n";
   BLI_assert(this->size() - count > 0);
   this->handle_types_start_.remove(0, count);
   this->handle_positions_start_.remove(0, count);
@@ -648,7 +646,6 @@ void BezierSpline::drop_front(const int count)
 
 void BezierSpline::drop_back(const int count)
 {
-  std::cout << __func__ << ": " << count << "\n";
   const int new_size = this->size() - count;
   BLI_assert(new_size > 0);
   this->handle_types_start_.resize(new_size);
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 5464af00a56..01c9eac2036 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -67,25 +67,20 @@ static void geo_node_curve_trim_update(bNodeTree *UNUSED(ntree), bNode *node)
 
 namespace blender::nodes {
 
-static void interpolate_control_point(Spline &spline, const Spline::LookupResult lookup)
+static void interpolate_control_point(Spline &spline,
+                                      const bool adjust_next,
+                                      const Spline::LookupResult lookup)
 {
   const int evaluated_index = lookup.evaluated_index;
   Span<PointMapping> mappings = spline.evaluated_mappings();
   const PointMapping &mapping = mappings[evaluated_index];
-  const int index = mapping.control_point_index;
+  const int index = mapping.control_point_index + (adjust_next ? 1 : 0);
 
   Span<float3> evaluated_positions = spline.evaluated_positions();
 
-  const float3 new_position = float3::interpolate(evaluated_positions[evaluated_index],
+  spline.positions()[index] = float3::interpolate(evaluated_positions[evaluated_index],
                                                   evaluated_positions[evaluated_index + 1],
                                                   lookup.factor);
-  if (BezierSpline *bezier_spline = dynamic_cast<BezierSpline *>(&spline)) {
-    /* TODO: This could be converted to a virtual function in the Spline class. */
-    bezier_spline->move_control_point(index, new_position);
-  }
-  else {
-    spline.positions()[index] = new_position;
-  }
 
   /* TODO: Do this interpolation with attributes instead. */
 
@@ -109,6 +104,25 @@ static void interpolate_control_point(Spline &spline, const Spline::LookupResult
         weights.as_span(), neighboring_weights.as_mutable_span(), evaluated_index);
     weights[index] = interpf(neighboring_weights[1], neighboring_weights[0], lookup.factor);
   }
+  else if (BezierSpline *bezier_spline = dynamic_cast<BezierSpline *>(&spline)) {
+    MutableSpan<float3> handle_positions_start = bezier_spline->handle_positions_start();
+    Array<float3, 2> neighboring_handle_positions_start(2);
+    spline.interpolate_data_to_evaluated_points(
+        handle_positions_start.as_span(),
+        neighboring_handle_positions_start.as_mutable_span(),
+        evaluated_index);
+    handle_positions_start[index] = float3::interpolate(neighboring_handle_positions_start[0],
+                                                        neighboring_handle_positions_start[1],
+                                                        lookup.factor);
+
+    MutableSpan<float3> handle_positions_end = bezier_spline->handle_positions_end();
+    Array<float3, 2> neighboring_handle_positions_end(2);
+    spline.interpolate_data_to_evaluated_points(handle_positions_end.as_span(),
+                                                neighboring_handle_positions_end.as_mutable_span(),
+                                                evaluated_index);
+    handle_positions_end[index] = float3::interpolate(
+        neighboring_handle_positions_end[0], neighboring_handle_positions_end[1], lookup.factor);
+  }
 }
 
 static void trim_spline(Spline &spline,
@@ -122,18 +136,18 @@ static void trim_spline(Spline &spline,
 
   const int points_len = spline.size();
   const int start_index = mappings[start.evaluated_index].control_point_index;
-  const int end_index = std::min(mappings[end.evaluated_index].control_point_index + 1,
-                                 points_len - 1);
+  const int end_index = std::min(mappings[end.evaluated_index].control_point_index + 2,
+                                 points_len);
 
   if (!(start.evaluated_index == 0 && start.factor == 0.0f)) {
-    interpolate_control_point(spline, start);
+    interpolate_control_point(spline, false, start);
   }
   if (end.evaluated_index != spline.evaluated_points_size() - 1) {
-    interpolate_control_point(spline, end);
+    interpolate_control_point(spline, true, end);
   }
 
   spline.drop_back(std::min(points_len - end_index, points_len));
-  spline.drop_front(std::max(start_index - 1, 0));
+  spline.drop_front(std::max(start_index, 0));
 }
 
 static void geo_node_curve_trim_exec(GeoNodeExecParams params)



More information about the Bf-blender-cvs mailing list