62 this->
runtime = MEM_new<CurvesGeometryRuntime>(__func__);
96 if (other.
runtime->curve_offsets_sharing_info) {
97 other.
runtime->curve_offsets_sharing_info->add_user();
111 this->
runtime = MEM_new<CurvesGeometryRuntime>(
115 other.
runtime->evaluated_offsets_cache,
116 other.
runtime->nurbs_basis_cache,
117 other.
runtime->evaluated_position_cache,
119 other.
runtime->evaluated_length_cache,
120 other.
runtime->evaluated_tangent_cache,
121 other.
runtime->evaluated_normal_cache,
125 if (other.
runtime->bake_materials) {
126 this->
runtime->bake_materials = std::make_unique<bake::BakeMaterialsList>(
127 *other.
runtime->bake_materials);
133 if (
this == &other) {
136 std::destroy_at(
this);
144 other.curve_offsets =
nullptr;
162 other.vertex_group_active_index = 0;
165 other.attributes_active_index = 0;
168 other.runtime =
nullptr;
173 if (
this == &other) {
176 std::destroy_at(
this);
181CurvesGeometry::~CurvesGeometry()
188 &this->
runtime->curve_offsets_sharing_info);
218 const T default_value)
225 if (
data !=
nullptr) {
241 if (
data ==
nullptr) {
251 const T default_value =
T())
261 if (
data !=
nullptr) {
266 if (num > 0 && span.
first() != default_value) {
267 span.
fill(default_value);
283void CurvesGeometry::fill_curve_types(
const CurveType type)
293 this->
runtime->type_counts.fill(0);
300 if (
selection.size() == this->curves_num()) {
304 if (std::optional<int8_t> single_type = this->
curve_types().get_if_single()) {
305 if (single_type == type) {
318 using CountsType = std::array<int, CURVE_TYPES_NUM>;
322 if (
types.is_single()) {
323 counts[
types.get_internal_single()] =
types.size();
333 CountsType result = init;
334 for (const int curve_index : curves_range) {
335 result[types_span[curve_index]]++;
339 [](
const CountsType &a,
const CountsType &
b) {
348void CurvesGeometry::update_curve_types()
492 if (dverts ==
nullptr) {
502 if (dvert !=
nullptr) {
521 offset += count_fn(i);
523 offsets.
last() = offset;
538 handle_types_left =
curves.handle_types_left();
539 handle_types_right =
curves.handle_types_right();
546 const IndexRange points = points_by_curve[curve_index];
547 switch (
types[curve_index]) {
550 points.
size(), cyclic[curve_index], resolution[curve_index]);
552 return points.
size();
556 handle_types_right.
slice(points),
558 resolution[curve_index],
559 all_bezier_offsets.
slice(offsets));
560 return all_bezier_offsets[offsets.
last()];
564 nurbs_orders[curve_index],
566 resolution[curve_index],
567 KnotsMode(nurbs_knots_modes[curve_index]));
624void CurvesGeometry::ensure_nurbs_basis_cache()
const
635 r_data.
resize(this->curves_num());
638 const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
645 for (
const int curve_index : segment) {
646 const IndexRange points = points_by_curve[curve_index];
647 const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
649 const int8_t order = orders[curve_index];
650 const bool is_cyclic = cyclic[curve_index];
653 if (!curves::nurbs::check_valid_num_and_order(points.
size(), order,
is_cyclic, mode)) {
654 r_data[curve_index].invalid =
true;
659 curves::nurbs::calculate_knots(points.
size(), mode, order,
is_cyclic, knots);
660 curves::nurbs::calculate_basis_cache(
661 points.
size(), evaluated_points.
size(), order,
is_cyclic, knots, r_data[curve_index]);
671 runtime.evaluated_position_cache.ensure(
675 this->ensure_nurbs_basis_cache();
708 runtime.evaluated_offsets_cache.data().all_bezier_offsets;
721 this->ensure_nurbs_basis_cache();
743 return runtime.evaluated_position_cache.data();
762 tangents.
slice(evaluated_points));
778 if (
cyclic[curve_index]) {
784 const float epsilon = 1e-6f;
795 handles_left[points.
last()]);
800 return runtime.evaluated_tangent_cache.data();
808 const float3 axis = axes[i];
818 for (
const int i :
data.index_range()) {
836 const int curve_index,
841 switch (eval_data.
types[curve_index]) {
844 src, eval_data.
cyclic[curve_index], eval_data.
resolution[curve_index], dst);
868 this->ensure_nurbs_basis_cache();
882 runtime.evaluated_offsets_cache.data().all_bezier_offsets,
883 runtime.nurbs_basis_cache.data(),
889 const bool use_tilt = !(
tilt.is_single() &&
tilt.get_internal_single() == 0.0f);
897 custom_normal_span = custom_normal;
920 if (custom_normal_span.
is_empty()) {
941 tilt_span.
slice(points));
947 tilt_span.
slice(points),
960void CurvesGeometry::interpolate_to_evaluated(
const int curve_index,
966 this->points_by_curve(),
970 runtime.evaluated_offsets_cache.data().all_bezier_offsets,
971 runtime.nurbs_basis_cache.data(),
975 BLI_assert(src.
size() == this->points_by_curve()[curve_index].size());
976 BLI_assert(dst.
size() == this->evaluated_points_by_curve()[curve_index].size());
989 runtime.evaluated_offsets_cache.data().all_bezier_offsets,
990 runtime.nurbs_basis_cache.data(),
1001 eval_data, curve_index, src.
slice(points), dst.
slice(evaluated_points));
1006void CurvesGeometry::ensure_evaluated_lengths()
const
1013 r_data.
resize(total_num);
1022 const bool cyclic = curves_cyclic[curve_index];
1024 const IndexRange lengths_range = this->lengths_range_for_curve(curve_index,
cyclic);
1027 evaluated_lengths.
slice(lengths_range));
1033void CurvesGeometry::ensure_can_interpolate_to_evaluated()
const
1035 this->evaluated_points_by_curve();
1036 this->ensure_nurbs_basis_cache();
1055 this->curve_num == 0 ? 0 : (this->curve_num + 1),
1065void CurvesGeometry::tag_positions_changed()
1073void CurvesGeometry::tag_topology_changed()
1080void CurvesGeometry::tag_normals_changed()
1084void CurvesGeometry::tag_radii_changed() {}
1089 for (float3 &position : positions.slice(range)) {
1090 position += translation;
1098 for (float3 &position : positions.slice(range)) {
1099 position = math::transform_point(matrix, position);
1108 for (float3 &normal : normals.slice(range)) {
1109 normal = normal_transform * normal;
1114void CurvesGeometry::calculate_bezier_auto_handles()
1132 for (
const int i_curve : range) {
1136 types_left.
slice(points),
1137 types_right.
slice(points),
1139 positions_left.
slice(points),
1140 positions_right.
slice(points));
1146void CurvesGeometry::translate(
const float3 &translation)
1152 std::optional<Bounds<float3>>
bounds;
1167 bounds->min += translation;
1168 bounds->max += translation;
1190std::optional<Bounds<float3>> CurvesGeometry::bounds_min_max()
const
1193 return std::nullopt;
1214 [&](
const int64_t point_i) { curve_point_counts[point_to_curve_map[point_i]]++; });
1219 return curve_point_counts[i] > 0;
1227 dst_curves.curves_num() > 1024,
1229 if (curves_to_copy.is_empty()) {
1234 curve_point_counts.
as_span(), curves_to_copy, new_curve_offsets.drop_back(1));
1243 dst_curves.attributes_for_write());
1249 dst_curves.attributes_for_write());
1252 if (dst_curves.curves_num() == curves.
curves_num()) {
1253 dst_curves.runtime->type_counts = curves.
runtime->type_counts;
1256 dst_curves.remove_attributes_based_on_types();
1262void CurvesGeometry::remove_points(
const IndexMask &points_to_delete,
1268 if (points_to_delete.
size() == this->points_num()) {
1297 dst_points_by_curve,
1314void CurvesGeometry::remove_curves(
const IndexMask &curves_to_delete,
1320 if (curves_to_delete.
size() == this->curves_num()) {
1336 GrainSize(256), [&](
const int curve_i) {
data.slice(points_by_curve[curve_i]).reverse(); });
1347 const IndexRange points = points_by_curve[curve_i];
1351 const int end_index = points.
size() - 1 - i;
1352 std::swap(a[end_index],
b[i]);
1353 std::swap(
b[end_index], a[i]);
1355 if (points.
size() % 2) {
1357 std::swap(a[middle_index],
b[middle_index]);
1362void CurvesGeometry::reverse_curves(
const IndexMask &curves_to_reverse)
1384 using T = decltype(dummy);
1385 reverse_curve_point_data<T>(*this, curves_to_reverse, attribute.span.typed<T>());
1414void CurvesGeometry::remove_attributes_based_on_types()
1436 curves.point_num = point_num;
1463 for (const int i_curve : range) {
1464 for (const int i_point : points_by_curve[i_curve]) {
1465 mixer.mix_in(i_curve, old_values[i_point]);
1468 mixer.finalize(range);
1485 r_values.
fill(
true);
1487 for (
const int i_point : points_by_curve[i_curve]) {
1488 if (!old_values[i_point]) {
1489 r_values[i_curve] =
false;
1501 using T = decltype(dummy);
1502 if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
1503 Array<T> values(curves.curves_num());
1504 adapt_curve_domain_point_to_curve_impl<T>(curves, varray.typed<T>(), values);
1505 new_varray = VArray<T>::ForContainer(std::move(values));
1525 r_values.
slice(points_by_curve[i_curve]).
fill(old_values[i_curve]);
1534 using T = decltype(dummy);
1535 Array<T> values(curves.points_num());
1536 adapt_curve_domain_curve_to_point_impl<T>(curves, varray.typed<T>(), values);
1537 new_varray = VArray<T>::ForContainer(std::move(values));
1580 this->runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
1599CurvesGeometry::BlendWriteData CurvesGeometry::blend_write_prepare()
1601 CurvesGeometry::BlendWriteData write_data;
1609 const CurvesGeometry::BlendWriteData &write_data)
1622 [&]() { BLO_write_int32_array(&writer, this->curve_num + 1, this->curve_offsets); });
Low-level operations for curves.
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
void CustomData_blend_write_prepare(CustomData &data, blender::Vector< CustomDataLayer, 16 > &layers_to_write, const blender::Set< std::string > &skip_names={})
void CustomData_count_memory(const CustomData &data, int totelem, blender::MemoryCounter &memory)
void CustomData_realloc(CustomData *data, int old_size, int new_size, eCDAllocType alloctype=CD_CONSTRUCT)
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name, const int totelem)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_reset(CustomData *data)
void CustomData_blend_write(BlendWriter *writer, CustomData *data, blender::Span< CustomDataLayer > layers_to_write, int count, eCustomDataMask cddata_mask, ID *id)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_free(CustomData *data, int totelem)
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
#define BLI_assert_unreachable()
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
#define BLO_read_struct_list(reader, struct_name, list)
void BLO_write_shared(BlendWriter *writer, const void *data, size_t approximate_size_in_bytes, const blender::ImplicitSharingInfo *sharing_info, blender::FunctionRef< void()> write_fn)
const blender::ImplicitSharingInfo * BLO_read_shared(BlendDataReader *reader, T **data_ptr, blender::FunctionRef< const blender::ImplicitSharingInfo *()> read_fn)
@ NORMAL_MODE_MINIMUM_TWIST
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
static void translate_positions(MutableSpan< float3 > positions, const float3 &translation)
constexpr void fill(const T &value) const
constexpr Span slice_safe(const int64_t start, const int64_t size) const
constexpr Span slice(int64_t start, int64_t size) const
Span< T > as_span() const
static const CPPType & get()
void copy_from(GSpan values)
GMutableSpan slice(const int64_t start, int64_t size) const
GSpan slice(const int64_t start, int64_t size) const
const CPPType & type() const
void get_internal_single(void *r_value) const
static GVArray ForSingle(const CPPType &type, int64_t size, const void *value)
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr void fill(const T &value) const
constexpr T & first() const
constexpr IndexRange index_range() 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 bool is_empty() const
static VArray ForSingle(T value, const int64_t size)
static VArray ForSpan(Span< T > values)
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
void reinitialize(const int64_t new_size)
Span< T > as_span() const
eCustomDataType data_type
SharedCache< Vector< curves::nurbs::BasisCache > > nurbs_basis_cache
SharedCache< Vector< float > > evaluated_length_cache
SharedCache< Vector< float3 > > evaluated_tangent_cache
SharedCache< EvaluatedOffsets > evaluated_offsets_cache
SharedCache< Vector< float3 > > evaluated_normal_cache
SharedCache< Bounds< float3 > > bounds_cache
SharedCache< Vector< float3 > > evaluated_position_cache
const ImplicitSharingInfo * curve_offsets_sharing_info
VArray< int8_t > handle_types_left() const
void remove_attributes_based_on_types()
MutableSpan< float3 > positions_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
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()
VArray< float > tilt() const
Span< float3 > evaluated_tangents() const
Span< float > nurbs_weights() const
Span< float3 > handle_positions_left() const
VArray< int > resolution() const
int evaluated_points_num() const
IndexRange points_range() const
Span< int > offsets() const
Span< float3 > evaluated_normals() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
bool has_curve_with_type(CurveType type) const
void tag_topology_changed()
void resize(int points_num, int curves_num)
Span< float3 > handle_positions_right() const
void tag_positions_changed()
void fill_curve_types(CurveType type)
AttributeAccessor attributes() const
IndexMask indices_for_curve_type(CurveType type, IndexMaskMemory &memory) const
bool is_single_type(CurveType type) const
MutableSpan< int > offsets_for_write()
Span< float3 > evaluated_positions() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
VArray< int8_t > nurbs_orders() const
MutableSpan< int8_t > handle_types_left_for_write()
bool remove(const StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
void foreach_segment(Fn &&fn) const
void add_shared(const ImplicitSharingInfo *sharing_info, const FunctionRef< void(MemoryCounter &shared_memory)> count_fn)
local_group_size(16, 16) .push_constant(Type b
static bool is_cyclic(const Nurb *nu)
static float normals[][3]
static void transform_positions(const Span< blender::float3 > src, const blender::float4x4 &transform, blender::MutableSpan< blender::float3 > dst)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void copy_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
typename DefaultMixerStruct< T >::type DefaultMixer
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)
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)
int calculate_evaluated_num(int points_num, bool cyclic, int resolution)
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)
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)
IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
IndexMask indices_for_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, const CurveType type, const IndexMask &selection, IndexMaskMemory &memory)
void fill_points(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, GPointer value, GMutableSpan dst)
void foreach_curve_by_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, const IndexMask &selection, FunctionRef< void(IndexMask)> catmull_rom_fn, FunctionRef< void(IndexMask)> poly_fn, FunctionRef< void(IndexMask)> bezier_fn, FunctionRef< void(IndexMask)> nurbs_fn)
static void normalize_span(MutableSpan< float3 > data)
static CustomData & domain_custom_data(CurvesGeometry &curves, const AttrDomain domain)
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)
static const std::string ATTR_HANDLE_POSITION_RIGHT
static MutableSpan< T > get_mutable_attribute(CurvesGeometry &curves, const AttrDomain domain, const StringRef name, const T default_value=T())
static VArray< T > get_varray_attribute(const CurvesGeometry &curves, const AttrDomain domain, const StringRef name, const T default_value)
static const std::string ATTR_NURBS_WEIGHT
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
static const std::string ATTR_HANDLE_TYPE_RIGHT
static const std::string ATTR_NURBS_KNOTS_MODE
static const std::string ATTR_RADIUS
static GVArray adapt_curve_domain_point_to_curve(const CurvesGeometry &curves, const GVArray &varray)
static const std::string ATTR_NORMAL_MODE
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static const std::string ATTR_POSITION
static const std::string ATTR_HANDLE_TYPE_LEFT
CurvesGeometry curves_new_no_attributes(int point_num, int curve_num)
static const std::string ATTR_CYCLIC
static const std::string ATTR_SURFACE_UV_COORDINATE
std::array< int, CURVE_TYPES_NUM > calculate_type_counts(const VArray< int8_t > &types)
static void evaluate_generic_data_for_curve(const EvalData &eval_data, const int curve_index, const GSpan src, GMutableSpan dst)
static void transform_normals(MutableSpan< float3 > normals, const float4x4 &matrix)
static const std::string ATTR_RESOLUTION
static const std::string ATTR_TILT
static const std::string ATTR_CURVE_TYPE
static Span< T > get_span_attribute(const CurvesGeometry &curves, const AttrDomain domain, const StringRef name)
static const std::string ATTR_HANDLE_POSITION_LEFT
void build_offsets(MutableSpan< int > offsets, const CountFn &count_fn)
static void reverse_curve_point_data(const CurvesGeometry &curves, const IndexMask &curve_selection, MutableSpan< T > data)
void gather_attributes_group_to_group(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static int domain_num(const CurvesGeometry &curves, const AttrDomain domain)
static const std::string ATTR_NURBS_ORDER
static void reverse_swap_curve_point_data(const CurvesGeometry &curves, const IndexMask &curve_selection, MutableSpan< T > data_a, MutableSpan< T > data_b)
static GVArray adapt_curve_domain_curve_to_point(const CurvesGeometry &curves, const GVArray &varray)
static void adapt_curve_domain_curve_to_point_impl(const CurvesGeometry &curves, const VArray< T > &old_values, MutableSpan< T > r_values)
static void rotate_directions_around_axes(MutableSpan< float3 > directions, const Span< float3 > axes, const Span< float > angles)
static void calculate_evaluated_offsets(const CurvesGeometry &curves, MutableSpan< int > offsets, MutableSpan< int > all_bezier_offsets)
static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves, const VArray< T > &old_values, MutableSpan< T > r_values)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
void resize_trivial_array(T **data, const ImplicitSharingInfo **sharing_info, int64_t old_size, int64_t new_size)
const ImplicitSharingInfo * info_for_mem_free(void *data)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
void make_trivial_data_mutable(T **data, const ImplicitSharingInfo **sharing_info, const int64_t size)
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
void accumulate_lengths(const Span< T > values, const bool cyclic, MutableSpan< float > lengths)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
CartesianBasis invert(const CartesianBasis &basis)
float3 rotate_direction_around_axis(const float3 &direction, const float3 &axis, float angle)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
bool almost_equal_relative(const VecBase< T, Size > &a, const VecBase< T, Size > &b, const T &epsilon_factor)
void build_reverse_map(OffsetIndices< int > offsets, MutableSpan< int > r_map)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
void parallel_invoke(Functions &&...functions)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MatBase< float, 4, 4 > float4x4
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
static void init(bNodeTree *, bNode *node)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
int vertex_group_active_index
CurvesGeometryRuntimeHandle * runtime
ListBase vertex_group_names
int attributes_active_index
Vector< int > all_bezier_offsets
Vector< int > evaluated_offsets
const VArray< bool > & cyclic
const Span< float > nurbs_weights
const Span< int > all_bezier_evaluated_offsets
const VArray< int > & resolution
const Span< curves::nurbs::BasisCache > nurbs_basis_cache
const VArray< int8_t > & nurbs_orders
const VArray< int8_t > & types
const OffsetIndices< int > points_by_curve