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);
121 dst_attributes.
append(std::move(dst_attribute));
181 result.src_no_interpolation,
182 result.dst_no_interpolation,
191 result.dst_attributes.append(std::move(dst_attribute));
198 result.dst_attributes.append(std::move(dst_attribute));
215 for (
const int i : attributes.
src.index_range()) {
242 for (
const int i :
data.index_range()) {
251 for (
const int i_curve : curve_selection) {
273 this->heap_allocated.
resize(size_in_bytes);
320 for (
const int i_curve : selection_segment) {
321 const bool cyclic = curves_cyclic[i_curve];
322 const IndexRange dst_points = dst_points_by_curve[i_curve];
331 !curves_cyclic[i_curve],
339 for (
const int i_attribute : attributes.
dst.index_range()) {
340 const CPPType &type = attributes.
src[i_attribute].type();
342 using T =
decltype(dummy);
343 Span<T> src = attributes.
src[i_attribute].typed<
T>();
346 for (
const int i_curve : selection_segment) {
347 const IndexRange src_points = src_points_by_curve[i_curve];
348 const IndexRange dst_points = dst_points_by_curve[i_curve];
352 sample_indices.
as_span().slice(dst_points),
353 sample_factors.
as_span().slice(dst_points),
354 dst.slice(dst_points));
358 evaluated_points_by_curve[i_curve].
size());
362 sample_indices.
as_span().slice(dst_points),
363 sample_factors.
as_span().slice(dst_points),
364 dst.slice(dst_points));
371 for (
const int i_curve : selection_segment) {
372 const IndexRange src_points = evaluated_points_by_curve[i_curve];
373 const IndexRange dst_points = dst_points_by_curve[i_curve];
375 sample_indices.
as_span().slice(dst_points),
376 sample_factors.
as_span().slice(dst_points),
377 dst.slice(dst_points));
382 interpolate_evaluated_data(evaluated_positions, dst_positions);
395 for (
const int i_curve : selection_segment) {
396 const IndexRange dst_points = dst_points_by_curve[i_curve];
473 [&](
const int count) { return count > 0; }));
500 const bool keep_last_segment)
516 curves_cyclic[curve_i]);
518 curve_length, sample_lengths[curve_i], keep_last_segment);
540 const bool keep_last_segment)
583 for (
const int i_attribute : attributes.
dst.index_range()) {
584 for (
const int i_curve : selection_segment) {
585 const IndexRange src_points = src_points_by_curve[i_curve];
586 const IndexRange dst_points = dst_points_by_curve[i_curve];
588 attributes.
src[i_attribute].slice(src_points),
589 attributes.
dst[i_attribute].slice(dst_points));
594 for (
const int i_curve : selection_segment) {
595 const IndexRange src_points = src_evaluated_points_by_curve[i_curve];
596 const IndexRange dst_points = dst_points_by_curve[i_curve];
597 dst.
slice(dst_points).copy_from(src.
slice(src_points));
602 copy_evaluated_data(evaluated_positions, dst_positions);
615 for (
const int i_curve : selection_segment) {
616 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
eCustomDataType data_type
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, eCustomDataType 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 > Create(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)
eCustomDataType cpp_type_to_custom_data_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