Blender V5.0
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_array_utils.hh"
13#include "BLI_bounds_types.hh"
15#include "BLI_index_mask_fwd.hh"
19#include "BLI_offset_indices.hh"
20#include "BLI_shared_cache.hh"
21#include "BLI_span.hh"
22#include "BLI_vector.hh"
24
25#include "BKE_attribute_math.hh"
27#include "BKE_curves.h"
28
29struct BlendDataReader;
30struct BlendWriter;
31struct MDeformVert;
32namespace blender::bke {
35enum class AttrDomain : int8_t;
37} // namespace blender::bke
38namespace blender::bke::bake {
40}
41namespace blender {
42class GVArray;
43}
44
45namespace blender::bke {
46
47namespace curves::nurbs {
48
68
69} // namespace curves::nurbs
70
149
156 public:
163 CurvesGeometry(const CurvesGeometry &other);
168
169 /* --------------------------------------------------------------------
170 * Accessors.
171 */
172
176 int points_num() const;
180 int curves_num() const;
184 bool is_empty() const;
185
186 IndexRange points_range() const;
187 IndexRange curves_range() const;
188
195 Span<int> offsets() const;
197
202
211 void fill_curve_types(CurveType type);
213 void fill_curve_types(const IndexMask &selection, CurveType type);
215 void update_curve_types();
216
217 bool has_curve_with_type(CurveType type) const;
220 bool is_single_type(CurveType type) const;
222 const std::array<int, CURVE_TYPES_NUM> &curve_type_counts() const;
228 const IndexMask &selection,
229 IndexMaskMemory &memory) const;
230
232
233 Span<float3> positions() const;
235
236 VArray<float> radius() const;
238
240 VArray<bool> cyclic() const;
243
248 VArray<int> resolution() const;
251
256 VArray<float> tilt() const;
258
265
273
280 std::optional<Span<float3>> handle_positions_left() const;
282 std::optional<Span<float3>> handle_positions_right() const;
284
291
298
302 std::optional<Span<float>> nurbs_weights() const;
304
308 std::optional<Span<float2>> surface_uv_coords() const;
310
316
322
327
328 bool nurbs_has_custom_knots() const;
329
336
341 void nurbs_custom_knots_resize(int knots_num);
342
349
353 std::optional<Bounds<float3>> bounds_min_max(bool use_radius = true) const;
354
355 void count_memory(MemoryCounter &memory) const;
356
362 std::optional<int> material_index_max() const;
363
364 private:
365 /* --------------------------------------------------------------------
366 * Evaluation.
367 */
368
369 public:
374 int evaluated_points_num() const;
375
380
386 Span<int> bezier_evaluated_offsets_for_curve(int curve_index) const;
387
388 bool has_cyclic_curve() const;
389
393
403 Span<float> evaluated_lengths_for_curve(int curve_index, bool cyclic) const;
404 float evaluated_length_total_for_curve(int curve_index, bool cyclic) const;
405
407 void ensure_evaluated_lengths() const;
408
410
418 void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const;
422 void interpolate_to_evaluated(GSpan src, GMutableSpan dst) const;
423
424 private:
428 void ensure_nurbs_basis_cache() const;
429
431 IndexRange lengths_range_for_curve(int curve_index, bool cyclic) const;
432
433 /* --------------------------------------------------------------------
434 * Operations.
435 */
436
437 public:
444 void resize(int points_num, int curves_num);
445
454 void tag_normals_changed();
459 void tag_radii_changed();
462
463 void translate(const float3 &translation);
464 void transform(const float4x4 &matrix);
465
467
468 void remove_points(const IndexMask &points_to_delete, const AttributeFilter &attribute_filter);
469 void remove_curves(const IndexMask &curves_to_delete, const AttributeFilter &attribute_filter);
470
475 void reverse_curves(const IndexMask &curves_to_reverse);
476
481
484
485 /* --------------------------------------------------------------------
486 * Attributes.
487 */
488
489 GVArray adapt_domain(const GVArray &varray, AttrDomain from, AttrDomain to) const;
490 template<typename T>
491 VArray<T> adapt_domain(const VArray<T> &varray, AttrDomain from, AttrDomain to) const
492 {
493 return this->adapt_domain(GVArray(varray), from, to).typed<T>();
494 }
495
496 /* --------------------------------------------------------------------
497 * File Read/Write.
498 */
499 void blend_read(BlendDataReader &reader);
510
514 void blend_write_prepare(BlendWriteData &write_data);
515 void blend_write(BlendWriter &writer, ID &id, const BlendWriteData &write_data);
516};
517
518static_assert(sizeof(blender::bke::CurvesGeometry) == sizeof(::CurvesGeometry));
519
525 public:
539 std::optional<Array<float3x3>> deform_mats;
540
542
543 std::optional<Span<float3>> positions() const;
544 std::optional<MutableSpan<float3>> positions_for_write();
545
550 bool is_valid() const;
551};
552
554
555namespace curves {
556
557/* -------------------------------------------------------------------- */
560
565inline int segments_num(const int points_num, const bool cyclic)
566{
567 BLI_assert(points_num > 0);
568 return (cyclic && points_num > 1) ? points_num : points_num - 1;
569}
570
572{
573 BLI_assert(std::abs(v.x + v.y + v.z - 1.0f) < 0.00001f);
574 return {v.x, v.y};
575}
576
578{
579 return {v.x, v.y, 1.0f - v.x - v.y};
580}
581
588inline IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
589{
590 return {curve_index + points.start(), points.size() + 1};
591}
592
594
595/* -------------------------------------------------------------------- */
598
599namespace poly {
600
607void calculate_tangents(Span<float3> positions, bool is_cyclic, MutableSpan<float3> tangents);
608
615
621
622} // namespace poly
623
625
626/* -------------------------------------------------------------------- */
629
630namespace bezier {
631
636bool segment_is_vector(const HandleType left, const HandleType right);
637bool segment_is_vector(const int8_t left, const int8_t right);
638bool segment_is_vector(Span<int8_t> handle_types_left,
639 Span<int8_t> handle_types_right,
640 int segment_index);
641
650bool has_vector_handles(int num_curve_points, int64_t evaluated_size, bool cyclic, int resolution);
651
656bool last_cyclic_segment_is_vector(Span<int8_t> handle_types_left,
657 Span<int8_t> handle_types_right);
658
664bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_right, int index);
665
675void calculate_evaluated_offsets(Span<int8_t> handle_types_left,
676 Span<int8_t> handle_types_right,
677 bool cyclic,
678 int resolution,
679 MutableSpan<int> evaluated_offsets);
680
689
708Insertion insert(const float3 &point_prev,
709 const float3 &handle_prev,
710 const float3 &handle_next,
711 const float3 &point_next,
712 float parameter);
713
720float3 calculate_vector_handle(const float3 &point, const float3 &next_point);
721
728void calculate_auto_handles(bool cyclic,
729 Span<int8_t> types_left,
730 Span<int8_t> types_right,
731 Span<float3> positions,
732 MutableSpan<float3> positions_left,
733 MutableSpan<float3> positions_right);
734
735void calculate_aligned_handles(const IndexMask &selection,
736 Span<float3> positions,
737 Span<float3> align_by,
738 MutableSpan<float3> align);
739
747void set_handle_position(const float3 &position,
748 HandleType type,
749 HandleType type_other,
750 const float3 &new_handle,
751 float3 &handle,
752 float3 &handle_other);
753
760template<typename T>
762 const T &point_0, const T &point_1, const T &point_2, const T &point_3, MutableSpan<T> result);
763
774 Span<float3> handles_left,
775 Span<float3> handles_right,
776 OffsetIndices<int> evaluated_offsets,
777 MutableSpan<float3> evaluated_positions);
778
784void interpolate_to_evaluated(GSpan src, OffsetIndices<int> evaluated_offsets, GMutableSpan dst);
785
786} // namespace bezier
787
789
790/* -------------------------------------------------------------------- */
793
794namespace catmull_rom {
795
801int calculate_evaluated_num(int points_num, bool cyclic, int resolution);
802
807void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst);
808
813void interpolate_to_evaluated(const GSpan src,
814 const bool cyclic,
815 const OffsetIndices<int> evaluated_offsets,
816 GMutableSpan dst);
817
818float4 calculate_basis(const float parameter);
819
826template<typename T>
827T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
828{
829 BLI_assert(0.0f <= parameter && parameter <= 1.0f);
830 const float4 weights = calculate_basis(parameter);
832 /* Save multiplications by adjusting weights after mix. */
833 return 0.5f * attribute_math::mix4<T>(weights, a, b, c, d);
834 }
835 else {
836 return attribute_math::mix4<T>(weights * 0.5f, a, b, c, d);
837 }
838}
839
840} // namespace catmull_rom
841
843
844/* -------------------------------------------------------------------- */
847
848namespace nurbs {
849
854 int points_num, int8_t order, bool cyclic, KnotsMode knots_mode, int resolution);
855
864int calculate_evaluated_num(int points_num,
865 int8_t order,
866 bool cyclic,
867 int resolution,
868 KnotsMode knots_mode,
869 Span<float> knots);
870
876int knots_num(int points_num, int8_t order, bool cyclic);
877
882int control_points_num(int num_control_points, int8_t order, bool cyclic);
883
889 int points_num,
890 int8_t order,
891 bool cyclic,
892 IndexRange curve_knots,
893 Span<float> custom_knots,
894 MutableSpan<float> knots);
895
904void calculate_knots(
905 int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots);
906
916
923void calculate_basis_cache(int points_num,
924 int evaluated_num,
925 int8_t order,
926 int resolution,
927 bool cyclic,
928 KnotsMode knots_mode,
929 Span<float> knots,
930 BasisCache &basis_cache);
931
940void interpolate_to_evaluated(const BasisCache &basis_cache,
941 int8_t order,
942 Span<float> control_weights,
943 GSpan src,
944 GMutableSpan dst);
945
946} // namespace nurbs
947
949
950} // namespace curves
951
952Curves *curves_new_nomain(int points_num, int curves_num);
954
958Curves *curves_new_nomain_single(int points_num, CurveType type);
959
964void curves_copy_parameters(const Curves &src, Curves &dst);
965
967 const IndexMask &points_to_copy,
968 const AttributeFilter &attribute_filter);
969
971 const IndexMask &curves_to_copy,
972 const AttributeFilter &attribute_filter);
973
974CurvesGeometry curves_new_no_attributes(int point_num, int curve_num);
975
976std::array<int, CURVE_TYPES_NUM> calculate_type_counts(const VArray<int8_t> &types);
977
978/* -------------------------------------------------------------------- */
981
982inline int CurvesGeometry::points_num() const
983{
984 return this->point_num;
985}
986inline int CurvesGeometry::curves_num() const
987{
988 return this->curve_num;
989}
990inline bool CurvesGeometry::nurbs_has_custom_knots() const
991{
992 return this->custom_knot_num != 0;
993}
994inline bool CurvesGeometry::is_empty() const
995{
996 /* Each curve must have at least one point. */
997 BLI_assert((this->curve_num == 0) == (this->point_num == 0));
998 return this->curve_num == 0;
999}
1000inline IndexRange CurvesGeometry::points_range() const
1001{
1002 return IndexRange(this->points_num());
1003}
1004inline IndexRange CurvesGeometry::curves_range() const
1005{
1006 return IndexRange(this->curves_num());
1007}
1008
1009inline bool CurvesGeometry::is_single_type(const CurveType type) const
1010{
1011 return this->curve_type_counts()[type] == this->curves_num();
1012}
1013
1014inline bool CurvesGeometry::has_curve_with_type(const CurveType type) const
1015{
1016 return this->curve_type_counts()[type] > 0;
1017}
1018
1019inline bool CurvesGeometry::has_curve_with_type(const Span<CurveType> types) const
1020{
1021 return std::any_of(
1022 types.begin(), types.end(), [&](CurveType type) { return this->has_curve_with_type(type); });
1023}
1024
1025inline const std::array<int, CURVE_TYPES_NUM> &CurvesGeometry::curve_type_counts() const
1026{
1027#ifndef NDEBUG
1028
1029 if (this->runtime->check_type_counts) {
1030 const std::array<int, CURVE_TYPES_NUM> actual_type_counts = calculate_type_counts(
1031 this->curve_types());
1032 BLI_assert(this->runtime->type_counts == actual_type_counts);
1033 this->runtime->check_type_counts = false;
1034 }
1035#endif
1036 return this->runtime->type_counts;
1037}
1038
1039inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
1040{
1041 return OffsetIndices<int>({this->curve_offsets, this->curve_num + 1},
1043}
1044
1045inline int CurvesGeometry::evaluated_points_num() const
1046{
1047 /* This could avoid calculating offsets in the future in simple circumstances. */
1048 return this->evaluated_points_by_curve().total_size();
1049}
1050
1051inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
1052{
1054 const IndexRange points = points_by_curve[curve_index];
1055 const IndexRange range = curves::per_curve_point_offsets_range(points, curve_index);
1056 const Span<int> offsets = this->runtime->evaluated_offsets_cache.data().all_bezier_offsets;
1057 return offsets.slice(range);
1058}
1059
1060inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
1061 const bool cyclic) const
1062{
1063 BLI_assert(cyclic == this->cyclic()[curve_index]);
1064 const IndexRange points = this->evaluated_points_by_curve()[curve_index];
1065 const int start = points.start() + curve_index;
1066 return {start, curves::segments_num(points.size(), cyclic)};
1067}
1068
1069inline Span<float> CurvesGeometry::evaluated_lengths_for_curve(const int curve_index,
1070 const bool cyclic) const
1071{
1072 const IndexRange range = this->lengths_range_for_curve(curve_index, cyclic);
1073 return this->runtime->evaluated_length_cache.data().as_span().slice(range);
1074}
1075
1076inline float CurvesGeometry::evaluated_length_total_for_curve(const int curve_index,
1077 const bool cyclic) const
1078{
1079 const Span<float> lengths = this->evaluated_lengths_for_curve(curve_index, cyclic);
1080 if (lengths.is_empty()) {
1081 return 0.0f;
1082 }
1083 return lengths.last();
1084}
1085
1087
1088namespace curves {
1089
1090/* -------------------------------------------------------------------- */
1093
1094namespace bezier {
1095
1096inline bool point_is_sharp(const Span<int8_t> handle_types_left,
1097 const Span<int8_t> handle_types_right,
1098 const int index)
1099{
1100 return ELEM(handle_types_left[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE) ||
1101 ELEM(handle_types_right[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE);
1102}
1103
1104inline bool segment_is_vector(const HandleType left, const HandleType right)
1105{
1106 return left == BEZIER_HANDLE_VECTOR && right == BEZIER_HANDLE_VECTOR;
1107}
1108
1109inline bool segment_is_vector(const int8_t left, const int8_t right)
1110{
1112}
1113
1114inline bool has_vector_handles(const int num_curve_points,
1115 const int64_t evaluated_size,
1116 const bool cyclic,
1117 const int resolution)
1118{
1119 return evaluated_size - !cyclic != int64_t(segments_num(num_curve_points, cyclic)) * resolution;
1120}
1121
1122inline float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
1123{
1124 return math::interpolate(point, next_point, 1.0f / 3.0f);
1125}
1126
1127} // namespace bezier
1128
1130
1131/* -------------------------------------------------------------------- */
1134
1135namespace nurbs {
1136
1137inline int knots_num(const int points_num, const int8_t order, const bool cyclic)
1138{
1139 /* Cyclic: points_num + order * 2 - 1 */
1140 return points_num + order + cyclic * (order - 1);
1141}
1142
1143inline int control_points_num(const int points_num, const int8_t order, const bool cyclic)
1144{
1145 return points_num + cyclic * (order - 1);
1146}
1147
1148} // namespace nurbs
1149
1151
1153
1154} // namespace curves
1155
1168
1169} // namespace blender::bke
1170
1171inline blender::bke::CurvesGeometry &CurvesGeometry::wrap()
1172{
1173 return *reinterpret_cast<blender::bke::CurvesGeometry *>(this);
1174}
1175inline const blender::bke::CurvesGeometry &CurvesGeometry::wrap() const
1176{
1177 return *reinterpret_cast<const blender::bke::CurvesGeometry *>(this);
1178}
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(...)
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
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:96
SharedCache< Vector< float3 > > evaluated_normal_cache
std::unique_ptr< bake::BakeMaterialsList > bake_materials
const ImplicitSharingInfo * custom_knots_sharing_info
Definition BKE_curves.hh:80
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:77
SharedCache< bool > has_cyclic_curve_cache
Definition BKE_curves.hh:98
std::array< int, CURVE_TYPES_NUM > type_counts
Definition BKE_curves.hh:86
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
std::optional< Span< float > > nurbs_weights() const
MutableSpan< int8_t > nurbs_orders_for_write()
void nurbs_custom_knots_resize(int knots_num)
Span< float > nurbs_custom_knots() const
MutableSpan< float2 > surface_uv_coords_for_write()
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
std::optional< Span< float3 > > handle_positions_left() 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
std::optional< Span< float3 > > handle_positions_right() 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)
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
std::optional< Span< float2 > > surface_uv_coords() 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()
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)
Vector< int > calculate_multiplicity_sequence(Span< float > knots)
int calculate_evaluated_num(int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode, Span< float > knots)
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, int resolution, bool cyclic, KnotsMode knots_mode, Span< float > knots, BasisCache &basis_cache)
bool check_valid_eval_params(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode, int resolution)
int control_points_num(int num_control_points, int8_t order, bool cyclic)
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:74
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:414
Vector< CustomDataLayer, 16 > & curve_layers
Vector< CustomDataLayer, 16 > & point_layers
AttributeStorage::BlendWriteData attribute_data