30 bool has_cycle =
false;
31 auto push_curve = [&](
const int curve_i) ->
bool {
32 if ((flags[curve_i] &
Inserted) != 0) {
35 if ((flags[curve_i] &
OnStack) != 0) {
48 const int current = stack.
peek();
50 const int next = connect_to_curve[current];
52 if (push_curve(
next)) {
73 for (
const int curve_i : range) {
74 const int next = connect_to_curve[curve_i];
76 is_start_curve[
next] =
false;
83 for (
const int curve_i : range) {
84 if (is_start_curve[curve_i]) {
86 connect_to_curve, flags, curve_i, [&](
const int index) { is_reachable[index] =
true; });
94 for (
const int curve_i : range) {
95 if (is_start_curve[curve_i] || !is_reachable[curve_i]) {
97 connect_to_curve, flags, curve_i, [&](
const int index) { sorted_curves.
append(index); });
102 return sorted_curves;
113 const int mirror_i = span.
size() - 1 -
i;
133 if (iter.
domain != domain) {
147 for (const int new_i : range) {
148 const int old_i = old_by_new_map[new_i];
149 const bool flip = flip_direction[old_i];
151 GMutableSpan dst_span = dst.span.slice(dst_offsets[new_i]);
152 array_utils::copy(src.slice(src_offsets[old_i]), dst_span);
154 reverse_order(dst_span);
203 for (
const int dst_i : old_by_new_map.
index_range()) {
204 const int src_i = old_by_new_map[dst_i];
205 new_by_old_map[src_i] = dst_i;
208 r_joined_curve_offsets.
reserve(curves_range.
size() + 1);
211 int start_index = -1;
212 for (
const int dst_i : curves_range) {
213 const int src_i = old_by_new_map[dst_i];
216 const bool src_cyclic = cyclic[src_i];
218 if (start_index < 0) {
219 r_joined_curve_offsets.
append(0);
220 r_joined_cyclic.
append(src_cyclic);
224 ++r_joined_curve_offsets.
last();
226 const int src_connect_to = connect_to_curve[src_i];
227 const bool is_connected = curves_range.
contains(src_connect_to);
228 const int dst_connect_to = is_connected ? new_by_old_map[src_connect_to] : -1;
231 if (dst_connect_to != dst_i + 1) {
234 const bool is_chain = (is_connected || dst_i != start_index);
236 r_joined_cyclic.
last() = (dst_connect_to == start_index);
243 r_joined_curve_offsets.
append(0);
252 old_curves_by_new.
size());
259 const Span<int> old_by_new_map = old_curves_by_new.
data().drop_back(1);
271 const IndexRange old_curves = old_curves_by_new[new_i];
300 src_curves, old_by_new_map, connect_to_curve, src_cyclic, joined_curve_offsets, cyclic);
303 src_curves, old_by_new_map, flip_direction);
319 return merged_curves;
Low-level operations for curves.
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
constexpr void copy_from(Span< T > values) const
void fill(const T &value) const
void move_assign(void *src, void *dst) const
void destruct(void *ptr) const
void default_construct(void *ptr) const
const CPPType & type() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t size() const
constexpr bool contains(int64_t value) const
constexpr void fill(const T &value) const
constexpr Span< T > as_span() const
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void push(const T &value)
void append(const T &value)
const T & last(const int64_t n=0) const
void reserve(const int64_t min_capacity)
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader get() const
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
MutableAttributeAccessor attributes_for_write()
Span< int > offsets() const
void tag_topology_changed()
AttributeAccessor attributes() const
MutableSpan< int > offsets_for_write()
bool nurbs_has_custom_knots() const
VArray< bool > cyclic() const
MutableSpan< bool > cyclic_for_write()
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
void update_custom_knot_modes(const IndexMask &mask, const KnotsMode mode_for_regular, const KnotsMode mode_for_cyclic, bke::CurvesGeometry &curves)
auto attribute_filter_from_skip_ref(const Span< StringRef > skip)
void copy_attributes(const AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, MutableAttributeAccessor dst_attributes)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static Vector< int > toposort_connected_curves(const Span< int > connect_to_curve)
static bke::CurvesGeometry reorder_and_flip_curves(const bke::CurvesGeometry &src_curves, const Span< int > old_by_new_map, const Span< bool > flip_direction)
static void foreach_connected_curve(const Span< int > connect_to_curve, MutableSpan< uint8_t > flags, const int start, Fn fn)
static void reorder_and_flip_attributes_group_to_group(const bke::AttributeAccessor src_attributes, const bke::AttrDomain domain, const OffsetIndices< int > src_offsets, const OffsetIndices< int > dst_offsets, const Span< int > old_by_new_map, const Span< bool > flip_direction, bke::MutableAttributeAccessor dst_attributes)
static void reverse_order(GMutableSpan span)
static bke::CurvesGeometry join_curves_ranges(const bke::CurvesGeometry &src_curves, const OffsetIndices< int > old_curves_by_new)
static void find_connected_ranges(const bke::CurvesGeometry &src_curves, const Span< int > old_by_new_map, Span< int > connect_to_curve, Span< bool > cyclic, Vector< int > &r_joined_curve_offsets, Vector< bool > &r_joined_cyclic)
bke::CurvesGeometry curves_merge_endpoints(const bke::CurvesGeometry &src_curves, Span< int > connect_to_curve, Span< bool > flip_direction, const bke::AttributeFilter &attribute_filter)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
void gather_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask, MutableSpan< int > sizes)
int sum_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
ListBase vertex_group_names
int attributes_active_index