diff options
author | Jacques Lucke <jacques@blender.org> | 2022-06-03 16:39:21 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-06-03 16:40:18 +0300 |
commit | 2780c7e3123653efc28be92210c67ff0d078947b (patch) | |
tree | 717ec337fbce2be499578ab6128b295b1835c9ad /source | |
parent | 9d8fb80f218f05f743943a289e2aad579e709058 (diff) |
Cleanup: deduplicate resampling curve after moving last point
Diffstat (limited to 'source')
4 files changed, 37 insertions, 75 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index 6ee660434c7..11d3548a082 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -13,6 +13,7 @@ #include "UI_interface.h" #include "BLI_enumerable_thread_specific.hh" +#include "BLI_length_parameterize.hh" #include "BLI_task.hh" /** @@ -277,6 +278,37 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr return matrices; } +void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position) +{ + /* Find the accumulated length of each point in the original curve, + * treating it as a poly curve for performance reasons and simplicity. */ + Array<float> orig_lengths(length_parameterize::lengths_num(positions.size(), false)); + length_parameterize::accumulate_lengths<float3>(positions, false, orig_lengths); + const float orig_total_length = orig_lengths.last(); + + /* Find the factor by which the new curve is shorter or longer than the original. */ + const float new_last_segment_length = math::distance(positions.last(1), new_last_position); + const float new_total_length = orig_lengths.last(1) + new_last_segment_length; + const float length_factor = safe_divide(new_total_length, orig_total_length); + + /* Calculate the lengths to sample the original curve with by scaling the original lengths. */ + Array<float> new_lengths(positions.size() - 1); + new_lengths.first() = 0.0f; + for (const int i : new_lengths.index_range().drop_front(1)) { + new_lengths[i] = orig_lengths[i - 1] * length_factor; + } + + Array<int> indices(positions.size() - 1); + Array<float> factors(positions.size() - 1); + length_parameterize::create_samples_from_sorted_lengths( + orig_lengths, new_lengths, false, indices, factors); + + Array<float3> new_positions(positions.size() - 1); + length_parameterize::linear_interpolation<float3>(positions, indices, factors, new_positions); + positions.drop_back(1).copy_from(new_positions); + positions.last() = new_last_position; +} + CurvesSculptCommonContext::CurvesSculptCommonContext(const bContext &C) { this->depsgraph = CTX_data_depsgraph_pointer(&C); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 4f574509bc2..3420659520b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -151,50 +151,10 @@ class ExtrapolateCurvesEffect : public CurvesEffect { const float3 direction = math::normalize(old_last_pos_cu - direction_reference_point); const float3 new_last_pos_cu = old_last_pos_cu + direction * move_distance_cu; - this->move_last_point_and_resample(positions_cu, curve_points, new_last_pos_cu); + move_last_point_and_resample(positions_cu.slice(curve_points), new_last_pos_cu); } }); } - - void move_last_point_and_resample(MutableSpan<float3> positions, - const IndexRange curve_points, - const float3 &new_last_point_position) const - { - Vector<float> old_lengths; - old_lengths.append(0.0f); - /* Used to (1) normalize the segment sizes over time and (2) support making zero-length - * segments */ - const float extra_length = 0.001f; - for (const int segment_i : IndexRange(curve_points.size() - 1)) { - const float3 &p1 = positions[curve_points[segment_i]]; - const float3 &p2 = positions[curve_points[segment_i] + 1]; - const float length = math::distance(p1, p2); - old_lengths.append(old_lengths.last() + length + extra_length); - } - Vector<float> point_factors; - for (float &old_length : old_lengths) { - point_factors.append(old_length / old_lengths.last()); - } - - PolySpline new_spline; - new_spline.resize(curve_points.size()); - MutableSpan<float3> new_spline_positions = new_spline.positions(); - for (const int i : IndexRange(curve_points.size() - 1)) { - new_spline_positions[i] = positions[curve_points[i]]; - } - new_spline_positions.last() = new_last_point_position; - new_spline.mark_cache_invalid(); - - for (const int i : IndexRange(curve_points.size())) { - const float factor = point_factors[i]; - const Spline::LookupResult lookup = new_spline.lookup_evaluated_factor(factor); - const float index_factor = lookup.evaluated_index + lookup.factor; - float3 p; - new_spline.sample_with_index_factors<float3>( - new_spline_positions, {&index_factor, 1}, {&p, 1}); - positions[curve_points[i]] = p; - } - } }; /** diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index 4c45f49b83a..4aaf6671cdb 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -95,6 +95,8 @@ VArray<float> get_point_selection(const Curves &curves_id); */ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices); +void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position); + class CurvesSculptCommonContext { public: const Depsgraph *depsgraph = nullptr; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index dbda37c918d..166ef133c68 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -216,7 +216,7 @@ struct SnakeHookOperatorExecutor { new_position_wo); const float3 new_position_cu = brush_transform * (world_to_curves_mat_ * new_position_wo); - this->move_last_point_and_resample(positions_cu.slice(points), new_position_cu); + move_last_point_and_resample(positions_cu.slice(points), new_position_cu); } }); } @@ -278,42 +278,10 @@ struct SnakeHookOperatorExecutor { const float3 new_pos_cu = old_pos_cu + weight * brush_diff_cu; - this->move_last_point_and_resample(positions_cu.slice(points), new_pos_cu); + move_last_point_and_resample(positions_cu.slice(points), new_pos_cu); } }); } - - void move_last_point_and_resample(MutableSpan<float3> positions, - const float3 &new_last_position) const - { - /* Find the accumulated length of each point in the original curve, - * treating it as a poly curve for performance reasons and simplicity. */ - Array<float> orig_lengths(length_parameterize::lengths_num(positions.size(), false)); - length_parameterize::accumulate_lengths<float3>(positions, false, orig_lengths); - const float orig_total_length = orig_lengths.last(); - - /* Find the factor by which the new curve is shorter or longer than the original. */ - const float new_last_segment_length = math::distance(positions.last(1), new_last_position); - const float new_total_length = orig_lengths.last(1) + new_last_segment_length; - const float length_factor = new_total_length / orig_total_length; - - /* Calculate the lengths to sample the original curve with by scaling the original lengths. */ - Array<float> new_lengths(positions.size() - 1); - new_lengths.first() = 0.0f; - for (const int i : new_lengths.index_range().drop_front(1)) { - new_lengths[i] = orig_lengths[i - 1] * length_factor; - } - - Array<int> indices(positions.size() - 1); - Array<float> factors(positions.size() - 1); - length_parameterize::create_samples_from_sorted_lengths( - orig_lengths, new_lengths, false, indices, factors); - - Array<float3> new_positions(positions.size() - 1); - length_parameterize::linear_interpolation<float3>(positions, indices, factors, new_positions); - positions.drop_back(1).copy_from(new_positions); - positions.last() = new_last_position; - } }; void SnakeHookOperation::on_stroke_extended(const bContext &C, |