20 const int segment_index)
24 handle_types_left[segment_index + 1]);
39 const int size = handle_types_left.
size();
42 evaluated_offsets.
first() = 0;
44 evaluated_offsets.
last() = 1;
50 evaluated_offsets[
i] = offset;
51 offset +=
segment_is_vector(handle_types_left, handle_types_right,
i) ? 1 : resolution;
54 evaluated_offsets.
last(1) = offset;
63 evaluated_offsets.
last() = offset;
73 BLI_assert(parameter <= 1.0f && parameter >= 0.0f);
87 const float3 &other_handle,
88 const float3 &aligned_handle)
94 return position - dir *
length;
100 const float3 prev_position,
101 const float3 next_position,
106 const float3 prev_diff = position - prev_position;
107 const float3 next_diff = next_position - position;
110 if (prev_len == 0.0f) {
113 if (next_len == 0.0f) {
116 const float3 dir = next_diff / next_len + prev_diff / prev_len;
136 const float prev_len_clamped = std::min(prev_len, next_len * 5.0f);
137 left = position + dir * -(prev_len_clamped /
len);
140 const float next_len_clamped = std::min(next_len, prev_len * 5.0f);
141 right = position + dir * (next_len_clamped /
len);
191 positions[point], align_with[point], align_handles[point]);
202 const int points_num = positions.
size();
203 if (points_num == 1) {
210 cyclic ? positions.
last() : 2.0f * positions.
first() - positions[1],
212 positions_left.
first(),
213 positions_right.
first());
216 for (
const int i : range) {
231 cyclic ? positions.
first() : 2.0f * positions.
last() - positions.
last(1),
232 positions_left.
last(),
233 positions_right.
last());
241 const float inv_len = 1.0f / float(
result.size());
242 const float inv_len_squared = inv_len * inv_len;
243 const float inv_len_cubed = inv_len_squared * inv_len;
245 const T rt1 = 3.0f * (point_1 - point_0) * inv_len;
246 const T rt2 = 3.0f * (point_0 - 2.0f * point_1 + point_2) * inv_len_squared;
247 const T rt3 = (point_3 - point_0 + 3.0f * (point_1 - point_2)) * inv_len_cubed;
250 T q1 = rt1 + rt2 + rt3;
251 T q2 = 2.0f * rt2 + 6.0f * rt3;
253 for (
const int i :
result.index_range()) {
287 evaluated_positions.
first() = positions.
first();
293 handles_right.
first(),
296 evaluated_positions.
slice(evaluated_offsets[0]));
299 const int grain_size = std::max<int>(evaluated_positions.
size() / positions.
size() * 32, 1);
302 for (
const int i : range) {
303 const IndexRange evaluated_range = evaluated_offsets[
i];
304 if (evaluated_range.
size() == 1) {
305 evaluated_positions[evaluated_range.
first()] = positions[
i];
312 evaluated_positions.
slice(evaluated_range));
319 if (last_segment_points.size() == 1) {
320 evaluated_positions.
last() = positions.
last();
324 handles_right.
last(),
325 handles_left.
first(),
327 evaluated_positions.
slice(last_segment_points));
335 const float step = 1.0f / dst.
size();
348 if (src.
size() == 1) {
358 for (const int i : range) {
359 const IndexRange segment = evaluated_offsets[i];
360 linear_interpolation(src[i], src[i + 1], dst.slice(segment));
364 const IndexRange last_segment = evaluated_offsets[src.index_range().last()];
373 using T = decltype(dummy);
374 if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
375 interpolate_to_evaluated(src.typed<T>(), evaluated_offsets, dst.typed<T>());
Low-level operations for curves.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
const CPPType & type() const
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool contains(int64_t value) const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr T & first() const
constexpr IndexRange index_range() const
constexpr T & last(const int64_t n=0) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void foreach_index_optimized(Fn &&fn) const
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T mix2(float factor, const T &a, const T &b)
Insertion insert(const float3 &point_prev, const float3 &handle_prev, const float3 &handle_next, const float3 &point_next, float parameter)
bool segment_is_vector(const HandleType left, const HandleType right)
void calculate_auto_handles(bool cyclic, Span< int8_t > types_left, Span< int8_t > types_right, Span< float3 > positions, MutableSpan< float3 > positions_left, MutableSpan< float3 > positions_right)
void calculate_evaluated_offsets(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right, bool cyclic, int resolution, MutableSpan< int > evaluated_offsets)
float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
static void calculate_point_handles(const HandleType type_left, const HandleType type_right, const float3 position, const float3 prev_position, const float3 next_position, float3 &left, float3 &right)
void calculate_aligned_handles(const IndexMask &selection, Span< float3 > positions, Span< float3 > align_by, MutableSpan< float3 > align)
bool last_cyclic_segment_is_vector(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right)
static float3 calculate_aligned_handle(const float3 &position, const float3 &other_handle, const float3 &aligned_handle)
void evaluate_segment(const T &point_0, const T &point_1, const T &point_2, const T &point_3, MutableSpan< T > result)
void calculate_evaluated_positions(Span< float3 > positions, Span< float3 > handles_left, Span< float3 > handles_right, OffsetIndices< int > evaluated_offsets, MutableSpan< float3 > evaluated_positions)
void interpolate_to_evaluated(GSpan src, OffsetIndices< int > evaluated_offsets, GMutableSpan dst)
void evaluate_segment_ex(const T &point_0, const T &point_1, const T &point_2, const T &point_3, MutableSpan< T > result)
void set_handle_position(const float3 &position, HandleType type, HandleType type_other, const float3 &new_handle, float3 &handle, float3 &handle_other)
static void linear_interpolation(const T &a, const T &b, MutableSpan< T > dst)
T distance(const T &a, const T &b)
T length(const VecBase< T, Size > &a)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
VecBase< float, 3 > float3