51 attribute_filter_with_skip,
62 if (attribute_filter_with_skip.allow_skip(iter.
name)) {
99 Array<int> neighbor_offsets_data(verts_num + 1, 0);
108 const int v1 = edges[i][0];
109 const int v2 = edges[i][1];
110 neighbors[neighbor_offsets[v1].start() + used_slots[v1]] =
v2;
111 neighbors[neighbor_offsets[
v2].start() + used_slots[
v2]] = v1;
121 Array<int> unused_edges = std::move(used_slots);
123 for (
const int start_vert :
IndexRange(verts_num)) {
125 if (neighbor_offsets[start_vert].
size() == 2) {
130 if (unused_edges[start_vert] == 0) {
134 for (
const int neighbor : neighbors.
as_span().slice(neighbor_offsets[start_vert])) {
135 int current_vert = start_vert;
136 int next_vert = neighbor;
138 if (unused_edges[next_vert] == 0) {
144 vert_indices.
append(current_vert);
148 int last_vert = current_vert;
149 current_vert = next_vert;
151 vert_indices.
append(current_vert);
152 unused_edges[current_vert]--;
153 unused_edges[last_vert]--;
155 if (neighbor_offsets[current_vert].
size() != 2) {
159 const int offset = neighbor_offsets[current_vert].start();
160 const int next_a = neighbors[offset];
161 const int next_b = neighbors[offset + 1];
162 next_vert = (last_vert == next_a) ? next_b : next_a;
168 const int cyclic_start = curve_offsets.
size();
172 for (
const int start_vert :
IndexRange(verts_num)) {
173 if (unused_edges[start_vert] != 2) {
177 int current_vert = start_vert;
178 int next_vert = neighbors[neighbor_offsets[current_vert].start()];
181 vert_indices.
append(current_vert);
184 while (next_vert != start_vert) {
185 const int last_vert = current_vert;
186 current_vert = next_vert;
188 vert_indices.
append(current_vert);
189 unused_edges[current_vert]--;
190 unused_edges[last_vert]--;
192 const int offset = neighbor_offsets[current_vert].start();
193 const int next_a = neighbors[offset];
194 const int next_b = neighbors[offset + 1];
195 next_vert = (last_vert == next_a) ? next_b : next_a;
201 return {std::move(vert_indices), std::move(curve_offsets), cyclic_curves};
Low-level operations for curves.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr T & last(const int64_t n=0) const
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
constexpr bool is_empty() const
constexpr IndexRange drop_front(int64_t n) const
constexpr void fill(const T &value) const
constexpr void copy_from(Span< T > values) const
Span< NewT > constexpr cast() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
bool is_builtin(const StringRef attribute_id) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
Set< StringRefNull > all_ids() const
eCustomDataType data_type
GAttributeReader get() const
MutableAttributeAccessor attributes_for_write()
void fill_curve_types(CurveType type)
MutableSpan< int > offsets_for_write()
MutableSpan< bool > cyclic_for_write()
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void gather(GSpan src, Span< int > map, GMutableSpan dst)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
auto attribute_filter_with_skip_ref(AttributeFilter filter, const Span< StringRef > skip)
static BLI_NOINLINE CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num, const Span< int2 > edges)
bke::CurvesGeometry create_curve_from_vert_indices(const bke::AttributeAccessor &mesh_attributes, Span< int > vert_indices, Span< int > curve_offsets, IndexRange cyclic_curves, const bke::AttributeFilter &attribute_filter)
void debug_randomize_curve_order(bke::CurvesGeometry *curves)
static BLI_NOINLINE bke::CurvesGeometry edges_to_curves_convert(const Mesh &mesh, const Span< int2 > edges, const bke::AttributeFilter &attribute_filter)
bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask &selection, const bke::AttributeFilter &attribute_filter)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > 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[]
Vector< int > curve_offsets
Vector< int > vert_indices