Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2021-06-09 22:53:39 +0300
committerHans Goudey <h.goudey@me.com>2021-06-09 22:53:39 +0300
commit675677ec67c6b922b3a5e602c8bf3dbb562bd687 (patch)
tree035269838d3d2e59989d5efe56f068230f947beb /source/blender/nodes
parentdf2a19eac7daf4943b22f74890cebd14eb811f4e (diff)
Splines: Add API functions for interpolating data
First, expand on the interpolation to evaluated points with a templated helper function, and a function that takes a GSPan. Next, add a set of functions to `Spline` for interpolating at arbitrary intervals between the evaluated points. The code for doing that isn't that complicated anyway, but it's nice to avoid repeating, and it might make it easier to unroll the special cases for the first and last points if we require the index factors to be sorted.
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc77
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc3
2 files changed, 25 insertions, 55 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
index 684f7d6c702..9d0820eb0b0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -76,34 +76,17 @@ struct SampleModeParam {
std::optional<int> count;
};
-template<typename T>
-static void sample_span_to_output_spline(const Spline &input_spline,
- Span<float> index_factors,
- const VArray<T> &input_data,
- MutableSpan<T> output_data)
-{
- BLI_assert(input_data.size() == input_spline.evaluated_points_size());
-
- parallel_for(output_data.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const Spline::LookupResult interp = input_spline.lookup_data_from_index_factor(
- index_factors[i]);
- output_data[i] = blender::attribute_math::mix2(interp.factor,
- input_data[interp.evaluated_index],
- input_data[interp.next_evaluated_index]);
- }
- });
-}
-
static SplinePtr resample_spline(const Spline &input_spline, const int count)
{
std::unique_ptr<PolySpline> output_spline = std::make_unique<PolySpline>();
output_spline->set_cyclic(input_spline.is_cyclic());
output_spline->normal_mode = input_spline.normal_mode;
- if (input_spline.evaluated_edges_size() < 1) {
- output_spline->resize(1);
- output_spline->positions().first() = input_spline.positions().first();
+ if (input_spline.evaluated_edges_size() < 1 || count == 1) {
+ output_spline->add_point(input_spline.positions().first(),
+ input_spline.tilts().first(),
+ input_spline.radii().first());
+ output_spline->attributes.reallocate(1);
return output_spline;
}
@@ -111,26 +94,18 @@ static SplinePtr resample_spline(const Spline &input_spline, const int count)
Array<float> uniform_samples = input_spline.sample_uniform_index_factors(count);
- {
- GVArray_For_Span positions(input_spline.evaluated_positions());
- GVArray_Typed<float3> positions_typed(positions);
- sample_span_to_output_spline<float3>(
- input_spline, uniform_samples, positions_typed, output_spline->positions());
- }
- {
- GVArrayPtr interpolated_data = input_spline.interpolate_to_evaluated_points(
- GVArray_For_Span(input_spline.radii()));
- GVArray_Typed<float> interpolated_data_typed{*interpolated_data};
- sample_span_to_output_spline<float>(
- input_spline, uniform_samples, interpolated_data_typed, output_spline->radii());
- }
- {
- GVArrayPtr interpolated_data = input_spline.interpolate_to_evaluated_points(
- GVArray_For_Span(input_spline.tilts()));
- GVArray_Typed<float> interpolated_data_typed{*interpolated_data};
- sample_span_to_output_spline<float>(
- input_spline, uniform_samples, interpolated_data_typed, output_spline->tilts());
- }
+ input_spline.sample_based_on_index_factors<float3>(
+ input_spline.evaluated_positions(), uniform_samples, output_spline->positions());
+
+ input_spline.sample_based_on_index_factors<float>(
+ input_spline.interpolate_to_evaluated_points(input_spline.radii()),
+ uniform_samples,
+ output_spline->radii());
+
+ input_spline.sample_based_on_index_factors<float>(
+ input_spline.interpolate_to_evaluated_points(input_spline.tilts()),
+ uniform_samples,
+ output_spline->tilts());
output_spline->attributes.reallocate(count);
input_spline.attributes.foreach_attribute(
@@ -147,16 +122,12 @@ static SplinePtr resample_spline(const Spline &input_spline, const int count)
BLI_assert_unreachable();
return false;
}
- GVArrayPtr interpolated_attribute = input_spline.interpolate_to_evaluated_points(
- GVArray_For_GSpan(*input_attribute));
- attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- GVArray_Typed<T> interpolated_attribute_typed{*interpolated_attribute};
- sample_span_to_output_spline<T>(input_spline,
- uniform_samples,
- interpolated_attribute_typed,
- (*output_attribute).typed<T>());
- });
+
+ input_spline.sample_based_on_index_factors(
+ *input_spline.interpolate_to_evaluated_points(*input_attribute),
+ uniform_samples,
+ *output_attribute);
+
return true;
},
ATTR_DOMAIN_POINT);
@@ -177,7 +148,7 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
else if (mode_param.mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
BLI_assert(mode_param.length);
const float length = spline->length();
- const int count = length / *mode_param.length;
+ const int count = std::max(int(length / *mode_param.length), 1);
output_curve->add_spline(resample_spline(*spline, count));
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
index fe1b23bf6d7..b6f04352929 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
@@ -181,8 +181,7 @@ static void spline_extrude_to_mesh_data(const Spline &spline,
Span<float3> normals = spline.evaluated_normals();
Span<float3> profile_positions = profile_spline.evaluated_positions();
- GVArray_Typed<float> radii{
- spline.interpolate_to_evaluated_points(blender::fn::GVArray_For_Span(spline.radii()))};
+ GVArray_Typed<float> radii = spline.interpolate_to_evaluated_points(spline.radii());
for (const int i_ring : IndexRange(spline_vert_len)) {
float4x4 point_matrix = float4x4::from_normalized_axis_data(
positions[i_ring], normals[i_ring], tangents[i_ring]);