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:
Diffstat (limited to 'source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc')
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc73
1 files changed, 40 insertions, 33 deletions
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 709ecc79967..408139d6653 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
@@ -4,8 +4,7 @@
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_float4x4.hh"
-#include "BLI_kdtree.h"
-#include "BLI_rand.hh"
+#include "BLI_length_parameterize.hh"
#include "BLI_vector.hh"
#include "PIL_time.h"
@@ -14,19 +13,13 @@
#include "BKE_attribute_math.hh"
#include "BKE_brush.h"
-#include "BKE_bvhutils.h"
#include "BKE_context.h"
#include "BKE_curves.hh"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
#include "BKE_paint.h"
-#include "BKE_spline.hh"
#include "DNA_brush_enums.h"
#include "DNA_brush_types.h"
#include "DNA_curves_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -70,6 +63,24 @@ class ShrinkCurvesEffect : public CurvesEffect {
private:
const Brush &brush_;
+ /** Storage of per-curve parameterization data to avoid reallocation. */
+ struct ParameterizationBuffers {
+ Array<float3> old_positions;
+ Array<float> old_lengths;
+ Array<float> sample_lengths;
+ Array<int> indices;
+ Array<float> factors;
+
+ void reinitialize(const int points_num)
+ {
+ this->old_positions.reinitialize(points_num);
+ this->old_lengths.reinitialize(length_parameterize::segments_num(points_num, false));
+ this->sample_lengths.reinitialize(points_num);
+ this->indices.reinitialize(points_num);
+ this->factors.reinitialize(points_num);
+ }
+ };
+
public:
ShrinkCurvesEffect(const Brush &brush) : brush_(brush)
{
@@ -81,46 +92,42 @@ class ShrinkCurvesEffect : public CurvesEffect {
{
MutableSpan<float3> positions_cu = curves.positions_for_write();
threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) {
+ ParameterizationBuffers data;
for (const int influence_i : range) {
const int curve_i = curve_indices[influence_i];
const float move_distance_cu = move_distances_cu[influence_i];
- const IndexRange curve_points = curves.points_for_curve(curve_i);
- this->shrink_curve(positions_cu, curve_points, move_distance_cu);
+ const IndexRange points = curves.points_for_curve(curve_i);
+ this->shrink_curve(positions_cu.slice(points), move_distance_cu, data);
}
});
}
+ private:
void shrink_curve(MutableSpan<float3> positions,
- const IndexRange curve_points,
- const float shrink_length) const
+ const float shrink_length,
+ ParameterizationBuffers &data) const
{
- PolySpline spline;
- spline.resize(curve_points.size());
- MutableSpan<float3> spline_positions = spline.positions();
- spline_positions.copy_from(positions.slice(curve_points));
- spline.mark_cache_invalid();
+ namespace lp = length_parameterize;
+ data.reinitialize(positions.size());
+
+ /* Copy the old positions to facilitate mixing from neighbors for the resulting curve. */
+ data.old_positions.as_mutable_span().copy_from(positions);
+
+ lp::accumulate_lengths<float3>(data.old_positions, false, data.old_lengths);
+
const float min_length = brush_.curves_sculpt_settings->minimum_length;
- const float old_length = spline.length();
+ const float old_length = data.old_lengths.last();
const float new_length = std::max(min_length, old_length - shrink_length);
const float length_factor = std::clamp(new_length / old_length, 0.0f, 1.0f);
- Vector<float> old_point_lengths;
- old_point_lengths.append(0.0f);
- for (const int i : spline_positions.index_range().drop_back(1)) {
- const float3 &p1 = spline_positions[i];
- const float3 &p2 = spline_positions[i + 1];
- const float length = math::distance(p1, p2);
- old_point_lengths.append(old_point_lengths.last() + length);
+ data.sample_lengths.first() = 0.0f;
+ for (const int i : data.old_lengths.index_range()) {
+ data.sample_lengths[i + 1] = data.old_lengths[i] * length_factor;
}
- for (const int i : spline_positions.index_range()) {
- const float eval_length = old_point_lengths[i] * length_factor;
- const Spline::LookupResult lookup = spline.lookup_evaluated_length(eval_length);
- const float index_factor = lookup.evaluated_index + lookup.factor;
- float3 p;
- spline.sample_with_index_factors<float3>(spline_positions, {&index_factor, 1}, {&p, 1});
- positions[curve_points[i]] = p;
- }
+ lp::sample_at_lengths(data.old_lengths, data.sample_lengths, data.indices, data.factors);
+
+ lp::linear_interpolation<float3>(data.old_positions, data.indices, data.factors, positions);
}
};