28 static auto max_one_fn = mf::build::SI1_SO<int, int>(
30 [](
int value) {
return std::max(1, value); },
31 mf::build::exec_presets::AllSpanOrSingle());
36 const float sample_length,
37 const bool keep_last_segment)
41 if (
UNLIKELY(sample_length == 0.0f)) {
44 const int count = int(curve_length / sample_length) + 1;
45 return std::max(keep_last_segment ? 2 : 1,
count);
49 const bool keep_last_segment)
51 static auto get_count_fn = mf::build::SI3_SO<float, float, bool, int>(
52 "Length Input to Count",
54 mf::build::exec_presets::SomeSpanOrSingle<0, 1>());
70 const std::array<int, CURVE_TYPES_NUM> &type_counts)
75 if (
ELEM(attribute_id,
"handle_type_left",
"handle_type_right",
"handle_left",
"handle_right")) {
78 if (
ELEM(attribute_id,
"nurbs_weight")) {
96 return !no_interpolation.
contains(attribute_id);
120 dst_attributes.
append(std::move(dst_attribute));
180 result.src_no_interpolation,
181 result.dst_no_interpolation,
190 result.dst_attributes.append(std::move(dst_attribute));
197 result.dst_attributes.append(std::move(dst_attribute));
214 for (
const int i : attributes.
src.index_range()) {
241 for (
const int i :
data.index_range()) {
250 for (
const int i_curve : curve_selection) {
272 this->heap_allocated.
resize(size_in_bytes);
319 for (
const int i_curve : selection_segment) {
320 const bool cyclic = curves_cyclic[i_curve];
321 const IndexRange dst_points = dst_points_by_curve[i_curve];
330 !curves_cyclic[i_curve],
338 for (
const int i_attribute : attributes.
dst.index_range()) {
339 const CPPType &type = attributes.
src[i_attribute].type();
341 using T =
decltype(dummy);
342 Span<T> src = attributes.
src[i_attribute].typed<
T>();
345 for (
const int i_curve : selection_segment) {
346 const IndexRange src_points = src_points_by_curve[i_curve];
347 const IndexRange dst_points = dst_points_by_curve[i_curve];
351 sample_indices.
as_span().slice(dst_points),
352 sample_factors.
as_span().slice(dst_points),
353 dst.slice(dst_points));
357 evaluated_points_by_curve[i_curve].
size());
361 sample_indices.
as_span().slice(dst_points),
362 sample_factors.
as_span().slice(dst_points),
363 dst.slice(dst_points));
370 for (
const int i_curve : selection_segment) {
371 const IndexRange src_points = evaluated_points_by_curve[i_curve];
372 const IndexRange dst_points = dst_points_by_curve[i_curve];
374 sample_indices.
as_span().slice(dst_points),
375 sample_factors.
as_span().slice(dst_points),
376 dst.slice(dst_points));
381 interpolate_evaluated_data(evaluated_positions, dst_positions);
394 for (
const int i_curve : selection_segment) {
395 const IndexRange dst_points = dst_points_by_curve[i_curve];
472 [&](
const int count) { return count > 0; }));
499 const bool keep_last_segment)
515 curves_cyclic[curve_i]);
517 curve_length, sample_lengths[curve_i], keep_last_segment);
539 const bool keep_last_segment)
582 for (
const int i_attribute : attributes.
dst.index_range()) {
583 for (
const int i_curve : selection_segment) {
584 const IndexRange src_points = src_points_by_curve[i_curve];
585 const IndexRange dst_points = dst_points_by_curve[i_curve];
587 attributes.
src[i_attribute].slice(src_points),
588 attributes.
dst[i_attribute].slice(dst_points));
593 for (
const int i_curve : selection_segment) {
594 const IndexRange src_points = src_evaluated_points_by_curve[i_curve];
595 const IndexRange dst_points = dst_points_by_curve[i_curve];
596 dst.
slice(dst_points).copy_from(src.
slice(src_points));
601 copy_evaluated_data(evaluated_positions, dst_positions);
614 for (
const int i_curve : selection_segment) {
615 const IndexRange dst_points = dst_points_by_curve[i_curve];
Low-level operations for curves.
Low-level operations for curves.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void value_initialize_n(void *ptr, int64_t n) const
GMutableSpan slice(const int64_t start, int64_t size) const
const CPPType & type() const
MutableSpan< T > typed() const
const CPPType & type() const
static constexpr size_t min_alignment
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan< NewT > cast() const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr Span< T > as_span() const
constexpr T * end() const
constexpr T * begin() const
constexpr T & last(const int64_t n=0) const
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
bool contains(const Key &key) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void add_new(const Key &key)
void remove_contained(const Key &key)
void append(const T &value)
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
MutableSpan< float3 > positions_for_write()
OffsetIndices< int > points_by_curve() const
void ensure_can_interpolate_to_evaluated() const
IndexRange curves_range() const
const std::array< int, CURVE_TYPES_NUM > & curve_type_counts() const
MutableAttributeAccessor attributes_for_write()
Span< float > evaluated_lengths_for_curve(int curve_index, bool cyclic) const
Span< float3 > evaluated_tangents() const
void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const
Span< float3 > evaluated_normals() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
void resize(int points_num, int curves_num)
void fill_curve_types(CurveType type)
AttributeAccessor attributes() const
float evaluated_length_total_for_curve(int curve_index, bool cyclic) const
MutableSpan< int > offsets_for_write()
void ensure_evaluated_lengths() const
Span< float3 > evaluated_positions() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
void set_selection(Field< bool > selection)
IndexMask get_evaluated_selection_as_mask() const
int add_with_destination(GField field, GVMutableArray dst)
static std::shared_ptr< FieldOperation > from(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
void foreach_segment(Fn &&fn) const
OffsetIndices slice(const IndexRange range) const
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
void copy_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
void copy_custom_knots(const bke::CurvesGeometry &src_curves, const IndexMask &exclude_curves, bke::CurvesGeometry &dst_curves)
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
void fill_points(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, GPointer value, GMutableSpan dst)
bool attribute_name_is_anonymous(const StringRef name)
AttrType cpp_type_to_attribute_type(const CPPType &type)
GField make_constant_field(const CPPType &type, const void *value)
static fn::Field< int > get_count_input_max_one(const fn::Field< int > &count_field)
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 normalize_span(MutableSpan< float3 > data)
static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_curves, const IndexMask &unselected_curves, const AttributesForResample &attributes, CurvesGeometry &dst_curves)
CurvesGeometry resample_to_count(const CurvesGeometry &src_curves, const IndexMask &selection, const VArray< int > &counts, const ResampleCurvesOutputAttributeIDs &output_ids={})
static bool interpolate_attribute_to_poly_curve(const StringRef attribute_id)
CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const IndexMask &selection, const ResampleCurvesOutputAttributeIDs &output_ids={})
static int get_count_from_length(const float curve_length, const float sample_length, const bool keep_last_segment)
CurvesGeometry resample_to_length(const CurvesGeometry &src_curves, const IndexMask &selection, const VArray< float > &sample_lengths, const ResampleCurvesOutputAttributeIDs &output_ids={}, bool keep_last_segment=false)
static void resample_to_uniform(const CurvesGeometry &src_curves, const IndexMask &selection, const ResampleCurvesOutputAttributeIDs &output_ids, CurvesGeometry &dst_curves)
static bool interpolate_attribute_to_curves(const StringRef attribute_id, const std::array< int, CURVE_TYPES_NUM > &type_counts)
static AttributesForInterpolation gather_point_attributes_to_interpolate(const CurvesGeometry &from_curves, const CurvesGeometry &to_curves, CurvesGeometry &dst_curves)
static fn::Field< int > get_count_input_from_length(const fn::Field< float > &length_field, const bool keep_last_segment)
static void normalize_curve_point_data(const IndexMaskSegment curve_selection, const OffsetIndices< int > points_by_curve, MutableSpan< float3 > data)
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)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
void copy_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask, MutableSpan< int > sizes)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
std::optional< OffsetIndices< int > > accumulate_counts_to_offsets_with_overflow_check(MutableSpan< int > counts_to_offsets, int start_offset=0)
VecBase< float, 3 > float3
ListBase vertex_group_names
Span< float3 > src_evaluated_tangents
MutableSpan< float3 > dst_normals
Vector< bke::GSpanAttributeWriter > dst_attributes
Vector< GMutableSpan > dst_no_interpolation
Vector< GVArraySpan > src
Vector< GVArraySpan > src_no_interpolation
MutableSpan< float3 > dst_tangents
Span< float3 > src_evaluated_normals
Vector< GMutableSpan > dst
GuardedAlignedAllocator<> AllocatorType
MutableSpan< T > resize(const int64_t size)
std::array< std::byte, 1024 > inline_buffer
Vector< std::byte, 0, AllocatorType > heap_allocated
std::optional< std::string > tangent_id
std::optional< std::string > normal_id