Blender V4.5
BKE_curves.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11
12#include "BLI_bounds_types.hh"
14#include "BLI_index_mask_fwd.hh"
18#include "BLI_offset_indices.hh"
19#include "BLI_shared_cache.hh"
20#include "BLI_span.hh"
21#include "BLI_vector.hh"
23
24#include "BKE_attribute_math.hh"
26#include "BKE_curves.h"
27
28struct BlendDataReader;
29struct BlendWriter;
30struct MDeformVert;
31namespace blender::bke {
34enum class AttrDomain : int8_t;
36} // namespace blender::bke
37namespace blender::bke::bake {
39}
40namespace blender {
41class GVArray;
42}
43
44namespace blender::bke {
45
46namespace curves::nurbs {
47
67
68} // namespace curves::nurbs
69
146
153 public:
160 CurvesGeometry(const CurvesGeometry &other);
165
166 /* --------------------------------------------------------------------
167 * Accessors.
168 */
169
173 int points_num() const;
177 int curves_num() const;
181 bool is_empty() const;
182
183 IndexRange points_range() const;
184 IndexRange curves_range() const;
185
192 Span<int> offsets() const;
194
199
208 void fill_curve_types(CurveType type);
210 void fill_curve_types(const IndexMask &selection, CurveType type);
212 void update_curve_types();
213
214 bool has_curve_with_type(CurveType type) const;
217 bool is_single_type(CurveType type) const;
219 const std::array<int, CURVE_TYPES_NUM> &curve_type_counts() const;
225 const IndexMask &selection,
226 IndexMaskMemory &memory) const;
227
229
230 Span<float3> positions() const;
232
233 VArray<float> radius() const;
235
237 VArray<bool> cyclic() const;
240
245 VArray<int> resolution() const;
248
253 VArray<float> tilt() const;
255
262
270
281
288
295
301
307
313
319
324
325 bool nurbs_has_custom_knots() const;
326
333
338 void nurbs_custom_knots_resize(int knots_num);
339
346
350 std::optional<Bounds<float3>> bounds_min_max(bool use_radius = true) const;
351
352 void count_memory(MemoryCounter &memory) const;
353
359 std::optional<int> material_index_max() const;
360
361 private:
362 /* --------------------------------------------------------------------
363 * Evaluation.
364 */
365
366 public:
371 int evaluated_points_num() const;
372
377
383 Span<int> bezier_evaluated_offsets_for_curve(int curve_index) const;
384
388
398 Span<float> evaluated_lengths_for_curve(int curve_index, bool cyclic) const;
399 float evaluated_length_total_for_curve(int curve_index, bool cyclic) const;
400
402 void ensure_evaluated_lengths() const;
403
405
413 void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const;
417 void interpolate_to_evaluated(GSpan src, GMutableSpan dst) const;
418
419 private:
423 void ensure_nurbs_basis_cache() const;
424
426 IndexRange lengths_range_for_curve(int curve_index, bool cyclic) const;
427
428 /* --------------------------------------------------------------------
429 * Operations.
430 */
431
432 public:
439 void resize(int points_num, int curves_num);
440
449 void tag_normals_changed();
454 void tag_radii_changed();
457
458 void translate(const float3 &translation);
459 void transform(const float4x4 &matrix);
460
462
463 void remove_points(const IndexMask &points_to_delete, const AttributeFilter &attribute_filter);
464 void remove_curves(const IndexMask &curves_to_delete, const AttributeFilter &attribute_filter);
465
470 void reverse_curves(const IndexMask &curves_to_reverse);
471
476
479
480 /* --------------------------------------------------------------------
481 * Attributes.
482 */
483
484 GVArray adapt_domain(const GVArray &varray, AttrDomain from, AttrDomain to) const;
485 template<typename T>
486 VArray<T> adapt_domain(const VArray<T> &varray, AttrDomain from, AttrDomain to) const
487 {
488 return this->adapt_domain(GVArray(varray), from, to).typed<T>();
489 }
490
491 /* --------------------------------------------------------------------
492 * File Read/Write.
493 */
494 void blend_read(BlendDataReader &reader);
505
509 void blend_write_prepare(BlendWriteData &write_data);
510 void blend_write(BlendWriter &writer, ID &id, const BlendWriteData &write_data);
511};
512
513static_assert(sizeof(blender::bke::CurvesGeometry) == sizeof(::CurvesGeometry));
514
520 public:
534 std::optional<Array<float3x3>> deform_mats;
535
537
538 std::optional<Span<float3>> positions() const;
539 std::optional<MutableSpan<float3>> positions_for_write();
540
545 bool is_valid() const;
546};
547
549
550namespace curves {
551
552/* -------------------------------------------------------------------- */
555
560inline int segments_num(const int points_num, const bool cyclic)
561{
562 BLI_assert(points_num > 0);
563 return (cyclic && points_num > 1) ? points_num : points_num - 1;
564}
565
567{
568 BLI_assert(std::abs(v.x + v.y + v.z - 1.0f) < 0.00001f);
569 return {v.x, v.y};
570}
571
573{
574 return {v.x, v.y, 1.0f - v.x - v.y};
575}
576
583inline IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
584{
585 return {curve_index + points.start(), points.size() + 1};
586}
587
589
590/* -------------------------------------------------------------------- */
593
594namespace poly {
595
602void calculate_tangents(Span<float3> positions, bool is_cyclic, MutableSpan<float3> tangents);
603
610
616
617} // namespace poly
618
620
621/* -------------------------------------------------------------------- */
624
625namespace bezier {
626
631bool segment_is_vector(const HandleType left, const HandleType right);
632bool segment_is_vector(const int8_t left, const int8_t right);
633bool segment_is_vector(Span<int8_t> handle_types_left,
634 Span<int8_t> handle_types_right,
635 int segment_index);
636
645bool has_vector_handles(int num_curve_points, int64_t evaluated_size, bool cyclic, int resolution);
646
651bool last_cyclic_segment_is_vector(Span<int8_t> handle_types_left,
652 Span<int8_t> handle_types_right);
653
659bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_right, int index);
660
670void calculate_evaluated_offsets(Span<int8_t> handle_types_left,
671 Span<int8_t> handle_types_right,
672 bool cyclic,
673 int resolution,
674 MutableSpan<int> evaluated_offsets);
675
684
703Insertion insert(const float3 &point_prev,
704 const float3 &handle_prev,
705 const float3 &handle_next,
706 const float3 &point_next,
707 float parameter);
708
715float3 calculate_vector_handle(const float3 &point, const float3 &next_point);
716
723void calculate_auto_handles(bool cyclic,
724 Span<int8_t> types_left,
725 Span<int8_t> types_right,
726 Span<float3> positions,
727 MutableSpan<float3> positions_left,
728 MutableSpan<float3> positions_right);
729
730void calculate_aligned_handles(const IndexMask &selection,
731 Span<float3> positions,
732 Span<float3> align_by,
733 MutableSpan<float3> align);
734
742void set_handle_position(const float3 &position,
743 HandleType type,
744 HandleType type_other,
745 const float3 &new_handle,
746 float3 &handle,
747 float3 &handle_other);
748
755template<typename T>
757 const T &point_0, const T &point_1, const T &point_2, const T &point_3, MutableSpan<T> result);
758
769 Span<float3> handles_left,
770 Span<float3> handles_right,
771 OffsetIndices<int> evaluated_offsets,
772 MutableSpan<float3> evaluated_positions);
773
779void interpolate_to_evaluated(GSpan src, OffsetIndices<int> evaluated_offsets, GMutableSpan dst);
780
781} // namespace bezier
782
784
785/* -------------------------------------------------------------------- */
788
789namespace catmull_rom {
790
796int calculate_evaluated_num(int points_num, bool cyclic, int resolution);
797
802void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst);
803
808void interpolate_to_evaluated(const GSpan src,
809 const bool cyclic,
810 const OffsetIndices<int> evaluated_offsets,
811 GMutableSpan dst);
812
813float4 calculate_basis(const float parameter);
814
821template<typename T>
822T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
823{
824 BLI_assert(0.0f <= parameter && parameter <= 1.0f);
825 const float4 weights = calculate_basis(parameter);
827 /* Save multiplications by adjusting weights after mix. */
828 return 0.5f * attribute_math::mix4<T>(weights, a, b, c, d);
829 }
830 else {
831 return attribute_math::mix4<T>(weights * 0.5f, a, b, c, d);
832 }
833}
834
835} // namespace catmull_rom
836
838
839/* -------------------------------------------------------------------- */
842
843namespace nurbs {
844
848bool check_valid_num_and_order(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode);
849
859 int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode);
860
866int knots_num(int points_num, int8_t order, bool cyclic);
867
873 int points_num,
874 int8_t order,
875 bool cyclic,
876 IndexRange curve_knots,
877 Span<float> custom_knots,
878 MutableSpan<float> knots);
879
888void calculate_knots(
889 int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots);
890
900
907void calculate_basis_cache(int points_num,
908 int evaluated_num,
909 int8_t order,
910 bool cyclic,
911 Span<float> knots,
912 BasisCache &basis_cache);
913
922void interpolate_to_evaluated(const BasisCache &basis_cache,
923 int8_t order,
924 Span<float> control_weights,
925 GSpan src,
926 GMutableSpan dst);
927
928} // namespace nurbs
929
931
932} // namespace curves
933
934Curves *curves_new_nomain(int points_num, int curves_num);
936
940Curves *curves_new_nomain_single(int points_num, CurveType type);
941
946void curves_copy_parameters(const Curves &src, Curves &dst);
947
949 const IndexMask &points_to_copy,
950 const AttributeFilter &attribute_filter);
951
953 const IndexMask &curves_to_copy,
954 const AttributeFilter &attribute_filter);
955
956CurvesGeometry curves_new_no_attributes(int point_num, int curve_num);
957
958std::array<int, CURVE_TYPES_NUM> calculate_type_counts(const VArray<int8_t> &types);
959
960/* -------------------------------------------------------------------- */
963
964inline int CurvesGeometry::points_num() const
965{
966 return this->point_num;
967}
968inline int CurvesGeometry::curves_num() const
969{
970 return this->curve_num;
971}
972inline bool CurvesGeometry::nurbs_has_custom_knots() const
973{
974 return this->custom_knot_num != 0;
975}
976inline bool CurvesGeometry::is_empty() const
977{
978 /* Each curve must have at least one point. */
979 BLI_assert((this->curve_num == 0) == (this->point_num == 0));
980 return this->curve_num == 0;
981}
982inline IndexRange CurvesGeometry::points_range() const
983{
984 return IndexRange(this->points_num());
985}
986inline IndexRange CurvesGeometry::curves_range() const
987{
988 return IndexRange(this->curves_num());
989}
990
991inline bool CurvesGeometry::is_single_type(const CurveType type) const
992{
993 return this->curve_type_counts()[type] == this->curves_num();
994}
995
996inline bool CurvesGeometry::has_curve_with_type(const CurveType type) const
997{
998 return this->curve_type_counts()[type] > 0;
999}
1000
1001inline bool CurvesGeometry::has_curve_with_type(const Span<CurveType> types) const
1002{
1003 return std::any_of(
1004 types.begin(), types.end(), [&](CurveType type) { return this->has_curve_with_type(type); });
1005}
1006
1007inline const std::array<int, CURVE_TYPES_NUM> &CurvesGeometry::curve_type_counts() const
1008{
1009#ifndef NDEBUG
1010
1011 if (this->runtime->check_type_counts) {
1012 const std::array<int, CURVE_TYPES_NUM> actual_type_counts = calculate_type_counts(
1013 this->curve_types());
1014 BLI_assert(this->runtime->type_counts == actual_type_counts);
1015 this->runtime->check_type_counts = false;
1016 }
1017#endif
1018 return this->runtime->type_counts;
1019}
1020
1021inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
1022{
1023 return OffsetIndices<int>({this->curve_offsets, this->curve_num + 1},
1025}
1026
1027inline int CurvesGeometry::evaluated_points_num() const
1028{
1029 /* This could avoid calculating offsets in the future in simple circumstances. */
1030 return this->evaluated_points_by_curve().total_size();
1031}
1032
1033inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
1034{
1036 const IndexRange points = points_by_curve[curve_index];
1037 const IndexRange range = curves::per_curve_point_offsets_range(points, curve_index);
1038 const Span<int> offsets = this->runtime->evaluated_offsets_cache.data().all_bezier_offsets;
1039 return offsets.slice(range);
1040}
1041
1042inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
1043 const bool cyclic) const
1044{
1045 BLI_assert(cyclic == this->cyclic()[curve_index]);
1046 const IndexRange points = this->evaluated_points_by_curve()[curve_index];
1047 const int start = points.start() + curve_index;
1048 return {start, curves::segments_num(points.size(), cyclic)};
1049}
1050
1051inline Span<float> CurvesGeometry::evaluated_lengths_for_curve(const int curve_index,
1052 const bool cyclic) const
1053{
1054 const IndexRange range = this->lengths_range_for_curve(curve_index, cyclic);
1055 return this->runtime->evaluated_length_cache.data().as_span().slice(range);
1056}
1057
1058inline float CurvesGeometry::evaluated_length_total_for_curve(const int curve_index,
1059 const bool cyclic) const
1060{
1061 const Span<float> lengths = this->evaluated_lengths_for_curve(curve_index, cyclic);
1062 if (lengths.is_empty()) {
1063 return 0.0f;
1064 }
1065 return lengths.last();
1066}
1067
1069
1070namespace curves {
1071
1072/* -------------------------------------------------------------------- */
1075
1076namespace bezier {
1077
1078inline bool point_is_sharp(const Span<int8_t> handle_types_left,
1079 const Span<int8_t> handle_types_right,
1080 const int index)
1081{
1082 return ELEM(handle_types_left[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE) ||
1083 ELEM(handle_types_right[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE);
1084}
1085
1086inline bool segment_is_vector(const HandleType left, const HandleType right)
1087{
1088 return left == BEZIER_HANDLE_VECTOR && right == BEZIER_HANDLE_VECTOR;
1089}
1090
1091inline bool segment_is_vector(const int8_t left, const int8_t right)
1092{
1094}
1095
1096inline bool has_vector_handles(const int num_curve_points,
1097 const int64_t evaluated_size,
1098 const bool cyclic,
1099 const int resolution)
1100{
1101 return evaluated_size - !cyclic != int64_t(segments_num(num_curve_points, cyclic)) * resolution;
1102}
1103
1104inline float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
1105{
1106 return math::interpolate(point, next_point, 1.0f / 3.0f);
1107}
1108
1109} // namespace bezier
1110
1112
1114
1115} // namespace curves
1116
1129
1130} // namespace blender::bke
1131
1132inline blender::bke::CurvesGeometry &CurvesGeometry::wrap()
1133{
1134 return *reinterpret_cast<blender::bke::CurvesGeometry *>(this);
1135}
1136inline const blender::bke::CurvesGeometry &CurvesGeometry::wrap() const
1137{
1138 return *reinterpret_cast<const blender::bke::CurvesGeometry *>(this);
1139}
Low-level operations for curves that cannot be defined in the C++ header yet.
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ELEM(...)
CurveType
HandleType
@ BEZIER_HANDLE_FREE
@ BEZIER_HANDLE_VECTOR
KnotsMode
ATTR_WARN_UNUSED_RESULT const BMVert * v
long long int int64_t
constexpr int64_t size() const
constexpr int64_t start() const
constexpr const T & last(const int64_t n=0) const
Definition BLI_span.hh:325
constexpr bool is_empty() const
Definition BLI_span.hh:260
std::optional< MutableSpan< float3 > > positions_for_write()
ImplicitSharingPtrAndData positions_data
std::optional< Span< float3 > > positions() const
CurvesEditHints(const Curves &curves_id_orig)
std::optional< Array< float3x3 > > deform_mats
SharedCache< Vector< curves::nurbs::BasisCache > > nurbs_basis_cache
Definition BKE_curves.hh:97
SharedCache< Vector< float > > evaluated_length_cache
SharedCache< Bounds< float3 > > bounds_with_radius_cache
SharedCache< Vector< int > > custom_knot_offsets_cache
SharedCache< Vector< float3 > > evaluated_tangent_cache
SharedCache< EvaluatedOffsets > evaluated_offsets_cache
Definition BKE_curves.hh:95
SharedCache< Vector< float3 > > evaluated_normal_cache
std::unique_ptr< bake::BakeMaterialsList > bake_materials
const ImplicitSharingInfo * custom_knots_sharing_info
Definition BKE_curves.hh:79
SharedCache< std::optional< int > > max_material_index_cache
SharedCache< Bounds< float3 > > bounds_cache
SharedCache< Vector< float3 > > evaluated_position_cache
const ImplicitSharingInfo * curve_offsets_sharing_info
Definition BKE_curves.hh:76
std::array< int, CURVE_TYPES_NUM > type_counts
Definition BKE_curves.hh:85
VArray< int8_t > handle_types_left() const
std::optional< int > material_index_max() const
void reverse_curves(const IndexMask &curves_to_reverse)
void blend_read(BlendDataReader &reader)
MutableSpan< float3 > positions_for_write()
void translate(const float3 &translation)
Array< int > point_to_curve_map() const
MutableSpan< MDeformVert > deform_verts_for_write()
MutableSpan< float > nurbs_custom_knots_for_write()
OffsetIndices< int > points_by_curve() const
VArray< int8_t > normal_mode() 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
MutableSpan< int8_t > curve_types_for_write()
MutableSpan< int > resolution_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()
MutableSpan< int8_t > nurbs_knots_modes_for_write()
Span< float > evaluated_lengths_for_curve(int curve_index, bool cyclic) const
MutableSpan< float > tilt_for_write()
VArray< float > radius() const
VArray< float > tilt() const
void blend_write(BlendWriter &writer, ID &id, const BlendWriteData &write_data)
Span< float3 > evaluated_tangents() const
void blend_write_prepare(BlendWriteData &write_data)
Span< MDeformVert > deform_verts() const
MutableSpan< int8_t > nurbs_orders_for_write()
void nurbs_custom_knots_resize(int knots_num)
Span< float > nurbs_weights() const
Span< float > nurbs_custom_knots() const
MutableSpan< float2 > surface_uv_coords_for_write()
Span< float3 > handle_positions_left() 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
IndexRange points_range() const
VArray< int8_t > nurbs_knots_modes() const
Span< float3 > evaluated_normals() const
Span< float3 > positions() const
MutableSpan< float > radius_for_write()
OffsetIndices< int > evaluated_points_by_curve() const
bool has_curve_with_type(CurveType type) const
MutableSpan< float > nurbs_weights_for_write()
GVArray adapt_domain(const GVArray &varray, AttrDomain from, AttrDomain to) const
void resize(int points_num, int curves_num)
Span< float3 > handle_positions_right() const
void remove_curves(const IndexMask &curves_to_delete, const AttributeFilter &attribute_filter)
MutableSpan< int8_t > normal_mode_for_write()
VArray< T > adapt_domain(const VArray< T > &varray, AttrDomain from, AttrDomain to) const
void fill_curve_types(CurveType type)
AttributeAccessor attributes() const
IndexMask nurbs_custom_knot_curves(IndexMaskMemory &memory) const
float evaluated_length_total_for_curve(int curve_index, bool cyclic) const
IndexMask indices_for_curve_type(CurveType type, IndexMaskMemory &memory) const
void count_memory(MemoryCounter &memory) const
bool is_single_type(CurveType type) const
MutableSpan< int > offsets_for_write()
Span< float2 > surface_uv_coords() const
std::optional< Bounds< float3 > > bounds_min_max(bool use_radius=true) const
void remove_points(const IndexMask &points_to_delete, const AttributeFilter &attribute_filter)
bool nurbs_has_custom_knots() const
void transform(const float4x4 &matrix)
OffsetIndices< int > nurbs_custom_knots_by_curve() const
Span< float3 > evaluated_positions() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
CurvesGeometry & operator=(const CurvesGeometry &other)
MutableSpan< bool > cyclic_for_write()
VArray< int8_t > nurbs_orders() const
MutableSpan< int8_t > handle_types_left_for_write()
static bool is_cyclic(const Nurb *nu)
static float normals[][3]
static char ** types
Definition makesdna.cc:71
static int left
#define T
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)
bool segment_is_vector(const HandleType left, const HandleType right)
bool point_is_sharp(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right, int index)
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)
void calculate_aligned_handles(const IndexMask &selection, Span< float3 > positions, Span< float3 > align_by, MutableSpan< float3 > align)
bool has_vector_handles(int num_curve_points, int64_t evaluated_size, bool cyclic, int resolution)
bool last_cyclic_segment_is_vector(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right)
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 set_handle_position(const float3 &position, HandleType type, HandleType type_other, const float3 &new_handle, float3 &handle, float3 &handle_other)
T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
int calculate_evaluated_num(int points_num, bool cyclic, int resolution)
float4 calculate_basis(const float parameter)
void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst)
int calculate_evaluated_num(int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode)
Vector< int > calculate_multiplicity_sequence(Span< float > knots)
bool check_valid_num_and_order(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode)
void calculate_knots(int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan< float > knots)
void calculate_basis_cache(int points_num, int evaluated_num, int8_t order, bool cyclic, Span< float > knots, BasisCache &basis_cache)
int knots_num(int points_num, int8_t order, bool cyclic)
void load_curve_knots(KnotsMode mode, int points_num, int8_t order, bool cyclic, IndexRange curve_knots, Span< float > custom_knots, MutableSpan< float > knots)
void interpolate_to_evaluated(const BasisCache &basis_cache, int8_t order, Span< float > control_weights, GSpan src, GMutableSpan dst)
void calculate_normals_z_up(Span< float3 > tangents, MutableSpan< float3 > normals)
void calculate_normals_minimum(Span< float3 > tangents, bool cyclic, MutableSpan< float3 > normals)
void calculate_tangents(Span< float3 > positions, bool is_cyclic, MutableSpan< float3 > tangents)
Definition curve_poly.cc:54
IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
float3 decode_surface_bary_coord(const float2 &v)
int segments_num(const int points_num, const bool cyclic)
const AttributeAccessorFunctions & get_attribute_accessor_functions()
float2 encode_surface_bary_coord(const float3 &v)
CurvesGeometry curves_copy_curve_selection(const CurvesGeometry &curves, const IndexMask &curves_to_copy, const AttributeFilter &attribute_filter)
CurvesGeometry curves_copy_point_selection(const CurvesGeometry &curves, const IndexMask &points_to_copy, const AttributeFilter &attribute_filter)
void curves_copy_parameters(const Curves &src, Curves &dst)
CurvesGeometry curves_new_no_attributes(int point_num, int curve_num)
std::array< int, CURVE_TYPES_NUM > calculate_type_counts(const VArray< int8_t > &types)
Curves * curves_new_nomain_single(int points_num, CurveType type)
Curves * curves_new_nomain(int points_num, int curves_num)
void curves_normals_point_domain_calc(const CurvesGeometry &curves, MutableSpan< float3 > normals)
T interpolate(const T &a, const T &b, const FactorT &t)
constexpr bool is_same_any_v
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
CurvesGeometryRuntimeHandle * runtime
Definition DNA_ID.h:404
Vector< CustomDataLayer, 16 > & curve_layers
Vector< CustomDataLayer, 16 > & point_layers
AttributeStorage::BlendWriteData attribute_data