23 ".selection", selection_domain,
true);
24 const int domain_size_orig = attributes.
domain_size(selection_domain);
27 switch (selection_domain) {
38 return attributes.
domain_size(selection_domain) != domain_size_orig;
48 const int num_points_to_add =
mask.size();
50 int curr_dst_point_start = 0;
51 Array<int> dst_to_src_point(num_points_to_add);
57 for (
const int curve_i :
curves.curves_range()) {
58 const IndexRange points = points_by_curve[curve_i];
59 const Span<bool> curve_points_to_duplicate = points_to_duplicate.
as_span().slice(points);
60 const bool curve_cyclic = src_cyclic[curve_i];
64 curve_points_to_duplicate,
true);
66 if (ranges_to_duplicate.
is_empty()) {
70 const bool is_last_segment_selected = curve_cyclic &&
71 ranges_to_duplicate.
first().first() == 0 &&
72 ranges_to_duplicate.
last().last() == points.
size() - 1;
73 const bool is_curve_self_joined = is_last_segment_selected && ranges_to_duplicate.
size() != 1;
74 const bool is_cyclic = ranges_to_duplicate.
size() == 1 && is_last_segment_selected;
79 const IndexRange range = ranges_to_duplicate[range_i];
84 curr_dst_point_start += range.
size();
87 dst_to_src_curve.
append(curve_i);
92 if (is_curve_self_joined) {
97 curr_dst_point_start += first_range.
size();
98 dst_curve_counts[dst_curve_counts.
size() - 1] += first_range.
size();
102 const int old_curves_num =
curves.curves_num();
103 const int old_points_num =
curves.points_num();
104 const int num_curves_to_add = dst_to_src_curve.
size();
111 curves.resize(old_points_num + num_points_to_add, old_curves_num + num_curves_to_add);
128 if (iter.
name ==
"cyclic") {
159 curves.update_curve_types();
160 curves.tag_topology_changed();
165 selection.span.take_back(num_points_to_add).fill(
true);
172 const int orig_points_num =
curves.points_num();
173 const int orig_curves_num =
curves.curves_num();
181 const IndexRange orig_curves_range =
curves.curves_range().take_front(orig_curves_num);
182 const IndexRange new_curves_range =
curves.curves_range().drop_front(orig_curves_num);
200 points_by_curve.
slice(new_curves_range),
215 curves.update_curve_types();
216 curves.tag_topology_changed();
228 const int orig_points_num =
curves.points_num();
229 const int orig_curves_num =
curves.curves_num();
230 curves.resize(orig_points_num, orig_curves_num + new_sizes.
size());
246 curves.update_curve_types();
261 std::optional<IndexRange> range = curves_to_resize.
to_range();
263 if (range &&
curves.curves_range() == *range) {
268 curves_to_copy = curves_to_resize.
complement(
curves.curves_range(), memory);
298 const IndexRange src_points = src_offsets[curve_i];
299 const IndexRange dst_points = dst_offsets[curve_i];
300 if (dst_points.
size() < src_points.
size()) {
301 const int src_excees = src_points.
size() - dst_points.
size();
305 const int dst_excees = dst_points.
size() - src_points.
size();
318 curves = std::move(dst_curves);
319 curves.tag_topology_changed();
Low-level operations for curves.
Low-level operations for curves.
#define BLI_assert_unreachable()
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
constexpr MutableSpan drop_back(const int64_t n) const
constexpr const T & last(const int64_t n=0) const
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void value_initialize_n(void *ptr, int64_t n) const
void copy_from(GSpan values)
GMutableSpan slice(const int64_t start, int64_t size) const
const CPPType & type() const
GSpan slice(const int64_t start, int64_t size) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange take_back(int64_t n) const
constexpr IndexRange drop_front(int64_t n) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr void copy_from(Span< T > values) const
constexpr MutableSpan take_front(const int64_t n) const
constexpr int64_t size() const
T get_internal_single() const
void append(const T &value)
const T & last(const int64_t n=0) const
IndexRange index_range() const
Span< T > as_span() const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
int domain_size(const AttrDomain domain) const
eCustomDataType data_type
GAttributeReader get() const
OffsetIndices< int > points_by_curve() const
void update_curve_types()
MutableAttributeAccessor attributes_for_write()
Span< int > offsets() const
void resize(int points_num, int curves_num)
MutableSpan< int > offsets_for_write()
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
std::optional< IndexRange > to_range() const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
OffsetIndices slice(const IndexRange range) const
static bool is_cyclic(const Nurb *nu)
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
void scatter(const Span< T > src, const Span< IndexT > indices, MutableSpan< T > dst, const 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)
Vector< IndexRange > find_all_ranges(const Span< T > span, const T &value)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void fill_index_range(MutableSpan< T > span, const T start=0)
void gather(GSpan src, Span< int > map, GMutableSpan dst)
void gather_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
bool attribute_name_is_anonymous(const StringRef name)
void fill_attribute_range_default(MutableAttributeAccessor dst_attributes, AttrDomain domain, const AttributeFilter &attribute_filter, IndexRange range)
bool remove_selection(bke::CurvesGeometry &curves, const bke::AttrDomain selection_domain)
void resize_curves(bke::CurvesGeometry &curves, const IndexMask &curves_to_resize, const Span< int > new_sizes)
void remove_selection_attributes(bke::MutableAttributeAccessor &attributes, Span< StringRef > selection_attribute_names)
void duplicate_curves(bke::CurvesGeometry &curves, const IndexMask &mask)
void duplicate_points(bke::CurvesGeometry &curves, const IndexMask &mask)
void add_curves(bke::CurvesGeometry &curves, const Span< int > new_sizes)
Span< StringRef > get_curves_selection_attribute_names(const bke::CurvesGeometry &curves)
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)
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
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[]