25using bke::CurvesGeometry;
31 const int samples_num)
35 sample_by_point[0] = 0.0f;
37 sample_by_point[
i] = sample_by_point[
i - 1] +
math::distance(positions[
i - 1], positions[
i]);
39 sample_by_point.
last() = cyclic ? sample_by_point[points.
size() - 1] +
41 sample_by_point[points.
size() - 1];
44 constexpr float length_epsilon = 1e-4f;
45 if (sample_by_point.
last() <= length_epsilon) {
49 const float total_length = sample_by_point.
last();
51 const float length_to_sample_count =
math::safe_divide(
float(samples_num), total_length);
52 for (
float &sample_value : sample_by_point) {
53 sample_value *= length_to_sample_count;
56 return sample_by_point;
71 const int num_free_samples = num_dst_points - int(src_points.
size());
73 src_positions, cyclic, num_free_samples);
75 int samples_start = 0;
76 for (
const int src_point_i : src_points) {
77 dst_sample_offsets[src_point_i] = samples_start;
80 const int free_samples =
math::round(sample_by_point[src_point_i + 1]) -
82 samples_start += 1 + free_samples;
86 dst_sample_offsets.
last() = num_dst_points;
94 const int num_dst_points = r_indices.
size();
98 if (num_dst_points == 0) {
101 if (num_dst_points == 1) {
102 r_indices.
first() = 0;
103 r_factors.
first() = 0.0f;
110 if (src_points.
size() == 1) {
112 r_factors.
fill(0.0f);
120 if (num_dst_points >= src_points.
size()) {
126 for (
const int src_point_i : src_points.
index_range()) {
127 const IndexRange samples = dst_samples_by_src_point[src_point_i];
129 r_indices.
slice(samples).
fill(src_point_i);
131 const int sample = samples[sample_i];
132 const float factor =
float(sample_i) / samples.
size();
133 r_factors[
sample] = factor;
139 positions, cyclic, num_dst_points - (cyclic ? 0 : 1));
141 for (
const int src_point_i : src_points.
index_range()) {
142 const float sample_start = sample_by_point[src_point_i];
143 const float sample_end = sample_by_point[src_point_i + 1];
147 for (
const int sample : samples) {
148 r_indices[
sample] = src_point_i;
150 sample_end - sample_start);
154 r_indices.
last() = src_points.
size() - 1;
155 r_factors.
last() = 0.0f;
170 const int index = r_indices[
i];
171 const float factor = r_factors[
i];
172 const bool is_last_segment = index >= points_num - 1;
174 if (is_last_segment && factor > 0.0f) {
175 reverse_indices.
append(points_num - 1);
176 reverse_factors.
append(1.0f - factor);
181 const int index = r_indices[
i];
182 const float factor = r_factors[
i];
183 const bool is_last_segment = index >= points_num - 1;
187 if (is_last_segment) {
190 reverse_indices.
append(points_num - 2 - index);
191 reverse_factors.
append(1.0f - r_factors[
i]);
195 reverse_indices.
append(points_num - 1 - index);
196 reverse_factors.
append(0.0f);
205 const int curve_index,
217 const int points_num = positions.
size();
220 reverse_positions[
i] = positions[points_num - 1 -
i];
237 const std::array<int, CURVE_TYPES_NUM> &type_counts)
243 if (
ELEM(attribute_id,
"handle_type_left",
"handle_type_right",
"handle_left",
"handle_right")) {
246 if (
ELEM(attribute_id,
"nurbs_weight")) {
264 return !no_interpolation.
contains(attribute_id);
291 const GVArray src_from_attribute = *src_from_attributes.
lookup(ids[
i], domain);
292 if (src_from_attribute) {
295 const GVArray src_to_attribute = *src_to_attributes.
lookup(ids[
i], domain, data_type);
297 result.src_from.append(src_from_attribute);
301 const GVArray src_to_attribute = *src_to_attributes.
lookup(ids[
i], domain);
308 result.src_to.append(src_to_attribute);
312 ids[
i], domain, data_type);
313 result.dst.append(std::move(dst_attribute));
341 if (iter.name ==
"position") {
372 if (iter.name ==
"curve_type") {
389 const GSpan src_data,
404 const int dst_points_num = dst_data.
size();
410 using T =
decltype(dummy);
416 const int i_src_curve = src_curve_indices[
pos];
417 if (i_src_curve < 0) {
421 const IndexRange src_points = src_points_by_curve[i_src_curve];
422 const IndexRange dst_points = dst_points_by_curve[i_dst_curve];
426 dst_sample_indices.
slice(dst_points),
427 dst_sample_factors.
slice(dst_points),
428 dst.
slice(dst_points));
431 const IndexRange src_evaluated_points = src_evaluated_points_by_curve[i_src_curve];
432 evaluated_data.reinitialize(src_evaluated_points.
size());
434 i_src_curve, src.
slice(src_points), evaluated_data.as_mutable_span());
443 const int dst_i = dst_points[
i];
444 const int dst_index = dst_sample_indices[dst_i];
445 const float dst_factor = dst_sample_factors[dst_i];
447 offsets[dst_index], offsets[dst_index + 1]);
449 const float segment_parameter = segment_eval.
first() +
450 dst_factor * segment_eval.
size();
452 dst_sample_indices_eval[
i] =
math::floor(segment_parameter);
453 dst_sample_factors_eval[
i] =
math::mod(segment_parameter, 1.0f);
457 const int src_size = src_points.
size();
458 const int eval_size = src_evaluated_points.
size();
461 const int dst_i = dst_points[
i];
462 const int dst_index = dst_sample_indices[dst_i];
463 const float dst_factor = dst_sample_factors[dst_i];
465 const float segment_parameter = (dst_index + dst_factor) *
float(eval_size) /
468 dst_sample_indices_eval[
i] =
math::floor(segment_parameter);
469 dst_sample_factors_eval[
i] =
math::mod(segment_parameter, 1.0f);
473 const int resolution = resolutions[i_src_curve];
476 const int dst_i = dst_points[
i];
477 const int dst_index = dst_sample_indices[dst_i];
478 const float dst_factor = dst_sample_factors[dst_i];
480 const float segment_parameter = (dst_index + dst_factor) * resolution;
482 dst_sample_indices_eval[
i] =
math::floor(segment_parameter);
483 dst_sample_factors_eval[
i] =
math::mod(segment_parameter, 1.0f);
488 dst_sample_indices_eval,
489 dst_sample_factors_eval,
490 dst.slice(dst_points));
498 const float t = parameter;
499 const float s = 1.0f - parameter;
501 s * (3.0f * t - 1.0f),
502 9.0f * t * t - 10.0f * t,
503 10.0f * s - 9.0f * s * s,
504 t * (3.0f * t - 2.0f),
509 const int src_index_last,
512 int src_index_a = src_index - 1;
513 int src_index_b = src_index;
514 int src_index_c = src_index + 1;
515 int src_index_d = src_index + 2;
517 if (src_index_a == -1) {
519 src_index_a = src_index_last;
526 if (src_index_c > src_index_last) {
528 src_index_c -= src_index_last;
531 src_index_c = src_index_last;
535 if (src_index_d > src_index_last) {
537 src_index_d -= src_index_last;
540 src_index_d = src_index_last;
544 return int4(src_index_a, src_index_b, src_index_c, src_index_d);
552 const int8_t dst_type,
566 const int i_prev = (
i - 1 + dst_points.
size()) % dst_points.
size();
567 const int i_next = (
i + 1) % dst_points.
size();
570 if (cyclic ||
i != 0) {
577 if (cyclic ||
i != dst_points.
size() - 1) {
593 const int8_t dst_type,
604 const int src_index = dst_indices[
i];
605 const float src_factor = dst_factors[
i];
607 const int i_prev = (
i - 1 + dst_points.
size()) % dst_points.
size();
608 const float src_factor_prev = dst_factors[i_prev];
610 const int i_next = (
i + 1) % dst_points.
size();
611 const float src_factor_next = dst_factors[i_next];
615 const float3 &pos_a = src_pos[src_indices[0]];
616 const float3 &pos_b = src_pos[src_indices[1]];
617 const float3 &pos_c = src_pos[src_indices[2]];
618 const float3 &pos_d = src_pos[src_indices[3]];
620 if (src_factor == 0.0f) {
621 dst_pos[
i] = src_pos[src_index];
624 const float3 derivative = 0.5f * (pos_c - pos_a);
625 dst_right[
i] = dst_pos[
i] + derivative / 3.0f;
626 dst_left[
i] = dst_pos[
i] - derivative / 3.0f;
628 if ((cyclic ||
i != 0) && dst_indices[i_prev] == src_index - 1) {
629 dst_left[
i] = dst_pos[
i] + (dst_left[
i] - dst_pos[
i]) * (1.0f - src_factor_prev);
631 if ((cyclic ||
i != dst_points.
size() - 1) && dst_indices[i_next] == src_index) {
632 dst_right[
i] = dst_pos[
i] + (dst_right[
i] - dst_pos[
i]) * src_factor_next;
644 dwdt, pos_a, pos_b, pos_c, pos_d);
647 dst_right[
i] = dst_pos[
i] + derivative / 3.0f;
648 dst_left[
i] = dst_pos[
i] - derivative / 3.0f;
650 if ((cyclic ||
i != 0) && dst_indices[i_prev] == src_index - 1) {
651 dst_left[
i] = dst_pos[
i] + (dst_left[
i] - dst_pos[
i]) * (src_factor - src_factor_prev);
653 if ((cyclic ||
i != dst_points.
size() - 1) && dst_indices[i_next] == src_index) {
654 dst_right[
i] = dst_pos[
i] + (dst_right[
i] - dst_pos[
i]) * (src_factor_next - src_factor);
681 const int src_index = dst_indices[
i];
682 const float src_factor = dst_factors[
i];
684 const int i_prev = (
i - 1 + dst_points.
size()) % dst_points.
size();
685 const float src_factor_prev = dst_factors[i_prev];
687 const int i_next = (
i + 1) % dst_points.
size();
688 const float src_factor_next = dst_factors[i_next];
690 if (src_factor == 0.0f) {
691 dst_pos[
i] = src_pos[src_index];
692 dst_left[
i] = src_left[src_index];
693 dst_right[
i] = src_right[src_index];
695 if ((cyclic ||
i != 0) && dst_indices[i_prev] == src_index - 1) {
696 dst_left[
i] = dst_pos[
i] + (dst_left[
i] - dst_pos[
i]) * (1.0f - src_factor_prev);
698 if ((cyclic ||
i != dst_points.
size() - 1) && dst_indices[i_next] == src_index) {
699 dst_right[
i] = dst_pos[
i] + (dst_right[
i] - dst_pos[
i]) * src_factor_next;
702 dst_types_left[
i] = src_types_left[src_index];
703 dst_types_right[
i] = src_types_right[src_index];
706 const int src_index_next = (src_index + 1) % src_pos.
size();
710 src_right[src_index],
711 src_left[src_index_next],
712 src_pos[src_index_next],
719 if ((cyclic ||
i != 0) && dst_indices[i_prev] == src_index) {
721 dst_left[
i] = dst_pos[
i] +
722 (dst_left[
i] - dst_pos[
i]) * (src_factor - src_factor_prev) / src_factor;
724 if ((cyclic ||
i != dst_points.
size() - 1) && dst_indices[i_next] == src_index) {
727 dst_right[
i] = dst_pos[
i] + (dst_right[
i] - dst_pos[
i]) * (src_factor_next - src_factor) /
770 const int dst_points_num = dst_positions.
size();
778 const int i_src_curve = src_curve_indices[
pos];
779 if (i_src_curve < 0) {
783 const bool cyclic = src_cyclic[i_src_curve];
785 const IndexRange src_points = src_points_by_curve[i_src_curve];
786 const IndexRange dst_points = dst_points_by_curve[i_dst_curve];
789 const Span<int> dst_indices = dst_sample_indices.
slice(dst_points);
804 dst_types[i_dst_curve],
824 dst_types[i_dst_curve],
860 const float mix_factor,
863 if (mix_factor == 0.0f) {
866 else if (mix_factor == 1.0f) {
883 using T = decltype(dummy);
884 const Span<T> from = src_from.typed<T>();
885 const Span<T> to = src_to.typed<T>();
886 const MutableSpan<T> dst_typed = dst.typed<T>();
887 selection.foreach_index(GrainSize(512), [&](const int curve) {
888 const float mix_factor = mix_factors[curve];
889 if (mix_factor == 0.0f) {
890 dst_typed[curve] = from[curve];
892 else if (mix_factor == 1.0f) {
893 dst_typed[curve] = to[curve];
896 dst_typed[curve] = math::interpolate(from[curve], to[curve], mix_factor);
912 using T = decltype(dummy);
913 const Span<T> from = src_from.typed<T>();
914 const Span<T> to = src_to.typed<T>();
915 const MutableSpan<T> dst_typed = dst.typed<T>();
916 mix_arrays(from.slice(range), to.slice(range), mix_factors[curve], dst_typed.slice(range));
948 for (
const int i : groups[curve]) {
963 const int i_from_curve = from_curve_indices[
pos];
964 const int i_to_curve = to_curve_indices[
pos];
966 if (i_from_curve < 0) {
967 dst_curve_types[i_dst_curve] = to_types[i_to_curve];
970 if (i_to_curve < 0) {
971 dst_curve_types[i_dst_curve] = from_types[i_from_curve];
975 const int8_t from_type = from_types[i_from_curve];
976 const int8_t to_type = to_types[i_to_curve];
1003 const float mix_factor,
1037 from_curves, to_curves, dst_curves);
1039 from_curves, to_curves, dst_curves);
1048 const int i_from_curve = from_curve_indices[
pos];
1049 const int i_to_curve = to_curve_indices[
pos];
1050 if (i_from_curve >= 0 && i_to_curve >= 0) {
1051 mix_factors[i_dst_curve] = mix_factor;
1052 mix_from_to[i_dst_curve] =
true;
1053 exclusive_from[i_dst_curve] =
false;
1054 exclusive_to[i_dst_curve] =
false;
1056 else if (i_to_curve >= 0) {
1057 mix_factors[i_dst_curve] = 1.0f;
1058 mix_from_to[i_dst_curve] =
false;
1059 exclusive_from[i_dst_curve] =
false;
1060 exclusive_to[i_dst_curve] =
true;
1063 mix_factors[i_dst_curve] = 0.0f;
1064 mix_from_to[i_dst_curve] =
false;
1065 exclusive_from[i_dst_curve] =
true;
1066 exclusive_to[i_dst_curve] =
false;
1079 for (
const int i_attribute : point_attributes.
dst.index_range()) {
1081 if (!point_attributes.
dst[i_attribute]) {
1085 const GSpan src_from = point_attributes.
src_from[i_attribute];
1086 const GSpan src_to = point_attributes.
src_to[i_attribute];
1096 dst_points_by_curve,
1099 from_sample_indices,
1100 from_sample_factors,
1104 dst_points_by_curve,
1110 mix_arrays(from_samples, to_samples, mix_factors, dst_curve_mask, dst_points_by_curve, dst);
1115 dst_points_by_curve,
1118 from_sample_indices,
1119 from_sample_factors,
1125 dst_points_by_curve,
1152 dst_points_by_curve,
1155 from_sample_indices,
1156 from_sample_factors,
1164 dst_points_by_curve,
1179 dst_points_by_curve,
1185 dst_points_by_curve,
1191 dst_points_by_curve,
1197 dst_points_by_curve,
1202 dst_points_by_curve,
1208 for (
const int i_attribute : curve_attributes.
dst.index_range()) {
1210 if (!curve_attributes.
dst[i_attribute]) {
1214 const GSpan src_from = curve_attributes.
src_from[i_attribute];
1215 const GSpan src_to = curve_attributes.
src_to[i_attribute];
1232 mix_arrays(from_samples, to_samples, mix_factors, mix_curve_mask, dst);
1255 const int curve_index,
1264 r_segment_indices.
fill(0);
1265 r_factors.
fill(0.0f);
1271 segment_lengths, !cyclic, r_segment_indices, r_factors);
1284 const float mix_factor,
1307 const int i_from_curve = from_curve_indices[
pos];
1308 const int i_to_curve = to_curve_indices[
pos];
1310 const IndexRange dst_points = dst_points_by_curve[i_dst_curve];
1314 from_curves_cyclic[i_from_curve],
1320 to_curves_cyclic[i_to_curve],
1321 dst_curve_flip_direction[i_dst_curve],
1330 from_sample_indices,
1332 from_sample_factors,
Low-level operations for curves.
#define BLI_assert_unreachable()
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
const T & last(const int64_t n=0) const
IndexRange index_range() const
const CPPType & type() const
MutableSpan< T > typed() const
const CPPType & type() const
const CPPType & type() const
static GVArray from_span(GSpan span)
constexpr int64_t first() const
constexpr int64_t size() const
constexpr bool is_empty() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
constexpr bool contains(int64_t value) const
constexpr IndexRange index_range() const
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
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 void fill(const T &value) const
constexpr T & first() const
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr T & last(const int64_t n=0) const
bool contains(const Key &key) const
constexpr Span slice(int64_t start, int64_t size) 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 append(const T &value)
void reserve(const int64_t min_capacity)
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
VArray< int8_t > handle_types_left() const
MutableSpan< float3 > positions_for_write()
OffsetIndices< int > points_by_curve() const
MutableSpan< int8_t > handle_types_right_for_write()
VArray< int8_t > handle_types_right() const
void ensure_can_interpolate_to_evaluated() const
IndexRange curves_range() const
void update_curve_types()
MutableSpan< int8_t > curve_types_for_write()
const std::array< int, CURVE_TYPES_NUM > & curve_type_counts() const
MutableSpan< float3 > handle_positions_left_for_write()
MutableAttributeAccessor attributes_for_write()
MutableSpan< float3 > handle_positions_right_for_write()
Span< float > evaluated_lengths_for_curve(int curve_index, bool cyclic) const
VArray< int > resolution() const
Span< int > bezier_evaluated_offsets_for_curve(int curve_index) const
void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const
std::optional< Span< float3 > > handle_positions_left() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
std::optional< Span< float3 > > handle_positions_right() const
void tag_topology_changed()
AttributeAccessor attributes() const
void ensure_evaluated_lengths() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
void calculate_bezier_auto_handles()
MutableSpan< int8_t > handle_types_left_for_write()
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
void foreach_index(Fn &&fn) const
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
void fill_index_range(MutableSpan< T > span, const T start=0)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T mix4(const float4 &weights, const T &v0, const T &v1, const T &v2, const T &v3)
Insertion insert(const float3 &point_prev, const float3 &handle_prev, const float3 &handle_next, const float3 &point_next, float parameter)
float4 calculate_basis(const float parameter)
bool attribute_name_is_anonymous(const StringRef name)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
AttrType cpp_type_to_attribute_type(const CPPType &type)
static void sample_catmull_rom_curve_positions_handles(const bool cyclic, const IndexRange src_points, const Span< float3 > src_pos, const Span< int > dst_indices, const Span< float > dst_factors, const IndexRange dst_points, const int8_t dst_type, MutableSpan< float3 > dst_pos, MutableSpan< float3 > dst_left, MutableSpan< float3 > dst_right, MutableSpan< int8_t > dst_types_left, MutableSpan< int8_t > dst_types_right)
static AttributesForInterpolation gather_curve_attributes_to_interpolate(const CurvesGeometry &from_curves, const CurvesGeometry &to_curves, CurvesGeometry &dst_curves)
static void mix_arrays(const Span< T > from, const Span< T > to, const float mix_factor, const MutableSpan< T > dst)
static AttributesForInterpolation retrieve_attribute_spans(const Span< StringRef > ids, const CurvesGeometry &src_from_curves, const CurvesGeometry &src_to_curves, const bke::AttrDomain domain, CurvesGeometry &dst_curves)
static void sample_bezier_curve_positions_handles(const bool cyclic, const IndexRange src_points, const Span< float3 > src_pos, const Span< float3 > src_handle_left, const Span< float3 > src_handle_right, const VArray< int8_t > src_types_left, const VArray< int8_t > src_types_right, const Span< int > dst_indices, const Span< float > dst_factors, const IndexRange dst_points, MutableSpan< float3 > dst_pos, MutableSpan< float3 > dst_left, MutableSpan< float3 > dst_right, MutableSpan< int8_t > dst_types_left, MutableSpan< int8_t > dst_types_right)
void interpolate_curves_with_samples(const bke::CurvesGeometry &from_curves, const bke::CurvesGeometry &to_curves, Span< int > from_curve_indices, Span< int > to_curve_indices, Span< int > from_sample_indices, Span< int > to_sample_indices, Span< float > from_sample_factors, Span< float > to_sample_factors, const IndexMask &dst_curve_mask, float mix_factor, bke::CurvesGeometry &dst_curves, IndexMaskMemory &memory)
static void sample_poly_curve_positions_handles(const bool cyclic, const Span< float3 > src_pos, const Span< int > dst_indices, const Span< float > dst_factors, const IndexRange dst_points, const int8_t dst_type, MutableSpan< float3 > dst_pos, MutableSpan< float3 > dst_left, MutableSpan< float3 > dst_right, MutableSpan< int8_t > dst_types_left, MutableSpan< int8_t > dst_types_right)
static void sample_curve_positions_and_handles(const bke::CurvesGeometry &src_curves, const Span< int > src_curve_indices, const OffsetIndices< int > dst_points_by_curve, const VArray< int8_t > dst_types, const IndexMask &dst_curve_mask, const Span< int > dst_sample_indices, const Span< float > dst_sample_factors, MutableSpan< float3 > dst_positions, MutableSpan< float3 > dst_handles_left, MutableSpan< float3 > dst_handles_right, MutableSpan< int8_t > dst_handle_types_left, MutableSpan< int8_t > dst_handle_types_right)
static float4 calculate_catmull_rom_basis_derivative(const float parameter)
static Array< float > build_point_to_sample_map(const Span< float3 > positions, const bool cyclic, const int samples_num)
static void mix_curve_type(const Span< int > from_curve_indices, const Span< int > to_curve_indices, const VArray< int8_t > &from_types, const VArray< int8_t > &to_types, const IndexMask &dst_curve_mask, MutableSpan< int8_t > dst_curve_types)
void sample_curve_padded(const Span< float3 > positions, bool cyclic, MutableSpan< int > r_indices, MutableSpan< float > r_factors)
static void sample_curve_attribute(const bke::CurvesGeometry &src_curves, const Span< int > src_curve_indices, const OffsetIndices< int > dst_points_by_curve, const GSpan src_data, const IndexMask &dst_curve_mask, const Span< int > dst_sample_indices, const Span< float > dst_sample_factors, GMutableSpan dst_data)
static void mix_handle_type_arrays(const Span< int8_t > src_from, const Span< int8_t > src_to, const IndexMask &group_selection, const OffsetIndices< int > groups, const MutableSpan< int8_t > dst)
static int4 get_catmull_rom_indices(const int src_index, const int src_index_last, const bool cyclic)
static void sample_curve_uniform(const bke::CurvesGeometry &curves, const int curve_index, const bool cyclic, const bool reverse, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void interpolate_curves(const bke::CurvesGeometry &from_curves, const bke::CurvesGeometry &to_curves, Span< int > from_curve_indices, Span< int > to_curve_indices, const IndexMask &dst_curve_mask, Span< bool > dst_curve_flip_direction, float mix_factor, bke::CurvesGeometry &dst_curves, IndexMaskMemory &memory)
static bool interpolate_attribute_to_poly_curve(const StringRef attribute_id)
static void assign_samples_to_segments(const int num_dst_points, const Span< float3 > src_positions, const bool cyclic, MutableSpan< int > dst_sample_offsets)
static bool interpolate_attribute_to_curves(const StringRef attribute_id, const std::array< int, CURVE_TYPES_NUM > &type_counts)
static int8_t mix_handle_type(const int8_t from_type, const int8_t to_type)
static AttributesForInterpolation gather_point_attributes_to_interpolate(const CurvesGeometry &from_curves, const CurvesGeometry &to_curves, CurvesGeometry &dst_curves)
static void reverse_samples(const int points_num, MutableSpan< int > r_indices, MutableSpan< float > r_factors)
void sample_uniform_reverse(Span< float > accumulated_segment_lengths, bool include_first_point, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void interpolate(const Span< T > src, const Span< int > indices, const Span< float > factors, MutableSpan< T > dst)
void sample_uniform(Span< float > accumulated_segment_lengths, bool include_last_point, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
T safe_divide(const T &a, const T &b)
T distance(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)
T mod(const T &a, const T &b)
VecBase< int32_t, 4 > int4
VecBase< float, 4 > float4
VecBase< float, 3 > float3
Vector< bke::GSpanAttributeWriter > dst
Vector< GVArraySpan > src_from
Vector< GVArraySpan > src_to