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);
80 result.left_handle =
math::interpolate(result.handle_prev, center_point, parameter);
81 result.right_handle =
math::interpolate(center_point, result.handle_next, parameter);
82 result.position =
math::interpolate(result.left_handle, result.right_handle, parameter);
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 const int points_num = positions.size();
192 if (points_num == 1) {
199 cyclic ? positions.last() : 2.0f * positions.first() - positions[1],
201 positions_left.
first(),
202 positions_right.
first());
205 for (
const int i :
range) {
220 cyclic ? positions.first() : 2.0f * positions.last() - positions.last(1),
221 positions_left.
last(),
222 positions_right.
last());
227 const T &point_0,
const T &point_1,
const T &point_2,
const T &point_3,
MutableSpan<T> result)
230 const float inv_len = 1.0f /
float(result.size());
231 const float inv_len_squared = inv_len * inv_len;
232 const float inv_len_cubed = inv_len_squared * inv_len;
234 const T rt1 = 3.0f * (point_1 - point_0) * inv_len;
235 const T rt2 = 3.0f * (point_0 - 2.0f * point_1 + point_2) * inv_len_squared;
236 const T rt3 = (point_3 - point_0 + 3.0f * (point_1 - point_2)) * inv_len_cubed;
239 T
q1 = rt1 + rt2 + rt3;
240 T q2 = 2.0f * rt2 + 6.0f * rt3;
242 for (
const int i : result.index_range()) {
276 evaluated_positions.
first() = positions.first();
282 handles_right.
first(),
285 evaluated_positions.
slice(evaluated_offsets[0]));
288 const int grain_size = std::max<int>(evaluated_positions.
size() / positions.size() * 32, 1);
291 for (
const int i :
range) {
292 const IndexRange evaluated_range = evaluated_offsets[i];
293 if (evaluated_range.
size() == 1) {
294 evaluated_positions[evaluated_range.
first()] = positions[i];
301 evaluated_positions.
slice(evaluated_range));
307 const IndexRange last_segment_points = evaluated_offsets[positions.index_range().last()];
308 if (last_segment_points.size() == 1) {
309 evaluated_positions.
last() = positions.last();
313 handles_right.
last(),
314 handles_left.
first(),
316 evaluated_positions.
slice(last_segment_points));
324 const float step = 1.0f / dst.
size();
337 if (src.
size() == 1) {
347 for (const int i : range) {
348 const IndexRange segment = evaluated_offsets[i];
349 linear_interpolation(src[i], src[i + 1], dst.slice(segment));
353 const IndexRange last_segment = evaluated_offsets[src.index_range().last()];
361 attribute_math::convert_to_static_type(src.
type(), [&](
auto dummy) {
362 using T = decltype(dummy);
363 if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
364 interpolate_to_evaluated(src.typed<T>(), evaluated_offsets, dst.typed<T>());
Low-level operations for curves.
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
const CPPType & type() const
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t size() const
constexpr bool contains(int64_t value) const
constexpr IndexRange index_range() 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
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
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)
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))