[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