[Bf-blender-cvs] [45bac491ebf] geometry-nodes-curve-support: Splines: Fix curve lookup (for trim node)

Hans Goudey noreply at git.blender.org
Sun Apr 25 19:43:10 CEST 2021


Commit: 45bac491ebf1ae1be37d0872ad3b4ce7159aec10
Author: Hans Goudey
Date:   Sun Apr 25 12:43:03 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rB45bac491ebf1ae1be37d0872ad3b4ce7159aec10

Splines: Fix curve lookup (for trim node)

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

M	source/blender/blenkernel/BKE_spline.hh
M	source/blender/blenkernel/intern/spline_base.cc
M	source/blender/blenkernel/intern/spline_bezier.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc

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

diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 78f0c33861f..e4d2e366b56 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -136,8 +136,13 @@ class Spline {
      * In other words, the index of the edge that the result lies on.
      */
     int evaluated_index;
+    /*
+     * The index of the evaluated point after the result location,
+     * accounting for wrapping when the spline is cyclic.
+     */
+    int next_evaluated_index;
     /**
-     * The portion of the way from the evaluated point at #index to the next point.
+     * The portion of the way from the evaluated point at #evaluated_index to the next point.
      */
     float factor;
   };
@@ -238,6 +243,12 @@ class BezierSpline final : public Spline {
 
   blender::Span<float> evaluated_mappings() const;
   blender::Span<blender::float3> evaluated_positions() const final;
+  struct InterpolationData {
+    int control_point_index;
+    int next_control_point_index;
+    float factor;
+  };
+  InterpolationData interpolation_data_from_map(const float map) const;
 
   virtual blender::fn::GVArrayPtr interpolate_to_evaluated_points(
       const blender::fn::GVArray &source_data) const;
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 02f65611f60..f4e9ec73813 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -322,9 +322,10 @@ 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 int next_index = (index == this->size() - 1) ? 0 : index + 1;
 
   const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
   const float factor = (length - previous_length) / (lengths[index] - previous_length);
 
-  return LookupResult{index, factor};
+  return LookupResult{index, next_index, factor};
 }
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index c065f8f68cc..ef77ce085c4 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -405,6 +405,20 @@ Span<float3> BezierSpline::evaluated_positions() const
   return this->evaluated_positions_cache_;
 }
 
+BezierSpline::InterpolationData BezierSpline::interpolation_data_from_map(const float map) const
+{
+  const int points_len = this->size();
+  const int index = std::floor(map);
+  if (index == points_len) {
+    BLI_assert(this->is_cyclic);
+    return InterpolationData{points_len - 1, 0, 1.0f};
+  }
+  if (index == points_len - 1) {
+    return InterpolationData{points_len - 2, points_len - 1, 1.0f};
+  }
+  return InterpolationData{index, index + 1, map - index};
+}
+
 template<typename T>
 static void interpolate_to_evaluated_points_impl(Span<float> mappings,
                                                  const blender::VArray<T> &source_data,
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 d877a7f563b..6132fc01ce1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -74,14 +74,18 @@ static void interpolate_control_point(BezierSpline &spline,
   using namespace ::blender::fn;
 
   const int eval_index = lookup.evaluated_index;
+  const int next_eval_index = lookup.next_evaluated_index;
   Span<float> mappings = spline.evaluated_mappings();
 
-  const int index = std::floor(mappings[eval_index]) + (adjust_next ? 1 : 0);
+  BezierSpline::InterpolationData interp_data = spline.interpolation_data_from_map(
+      mappings[eval_index]);
+
+  const int index = interp_data.control_point_index + (adjust_next ? 1 : 0);
 
   Span<float3> evaluated_positions = spline.evaluated_positions();
 
   spline.positions()[index] = float3::interpolate(
-      evaluated_positions[eval_index], evaluated_positions[eval_index + 1], lookup.factor);
+      evaluated_positions[eval_index], evaluated_positions[next_eval_index], lookup.factor);
 
   /* TODO: Do this interpolation with attributes instead. */
 
@@ -90,7 +94,7 @@ static void interpolate_control_point(BezierSpline &spline,
     GVArrayPtr radii_varray = spline.interpolate_to_evaluated_points(GVArray_For_Span(radii));
     GVArray_Typed<float> radii_eval = radii_varray->typed<float>();
 
-    radii[index] = interpf(radii_eval[eval_index + 1], radii_eval[eval_index], lookup.factor);
+    radii[index] = interpf(radii_eval[next_eval_index], radii_eval[eval_index], lookup.factor);
   }
 
   {
@@ -98,7 +102,7 @@ static void interpolate_control_point(BezierSpline &spline,
     GVArrayPtr tilt_varray = spline.interpolate_to_evaluated_points(GVArray_For_Span(tilts));
     GVArray_Typed<float> tilts_eval = tilt_varray->typed<float>();
 
-    tilts[index] = interpf(tilts_eval[eval_index + 1], tilts_eval[eval_index], lookup.factor);
+    tilts[index] = interpf(tilts_eval[next_eval_index], tilts_eval[eval_index], lookup.factor);
   }
 
   {
@@ -110,7 +114,7 @@ static void interpolate_control_point(BezierSpline &spline,
 
     handle_positions_start[index] = float3::interpolate(
         handle_positions_start_eval[eval_index],
-        handle_positions_start_eval[eval_index + 1],
+        handle_positions_start_eval[next_eval_index],
         lookup.factor);
   }
 
@@ -121,7 +125,7 @@ static void interpolate_control_point(BezierSpline &spline,
     GVArray_Typed<float3> handle_positions_end_eval = handle_positions_end_varray->typed<float3>();
 
     handle_positions_end[index] = float3::interpolate(handle_positions_end_eval[eval_index],
-                                                      handle_positions_end_eval[eval_index + 1],
+                                                      handle_positions_end_eval[next_eval_index],
                                                       lookup.factor);
   }
 }



More information about the Bf-blender-cvs mailing list