54 mesh_attributes, curves_attributes, skip_storage, attribute_filter);
59 attribute_filter_with_skip,
70 if (attribute_filter_with_skip.allow_skip(iter.
name)) {
107 Array<int> neighbor_offsets_data(verts_num + 1, 0);
116 const int v1 = edges[
i][0];
117 const int v2 = edges[
i][1];
118 neighbors[neighbor_offsets[v1].start() + used_slots[v1]] =
v2;
119 neighbors[neighbor_offsets[
v2].start() + used_slots[
v2]] = v1;
129 Array<int> unused_edges = std::move(used_slots);
131 for (
const int start_vert :
IndexRange(verts_num)) {
133 if (neighbor_offsets[start_vert].
size() == 2) {
138 if (unused_edges[start_vert] == 0) {
142 for (
const int neighbor : neighbors.
as_span().slice(neighbor_offsets[start_vert])) {
143 int current_vert = start_vert;
144 int next_vert = neighbor;
146 if (unused_edges[next_vert] == 0) {
152 vert_indices.
append(current_vert);
156 int last_vert = current_vert;
157 current_vert = next_vert;
159 vert_indices.
append(current_vert);
160 unused_edges[current_vert]--;
161 unused_edges[last_vert]--;
163 if (neighbor_offsets[current_vert].
size() != 2) {
167 const int offset = neighbor_offsets[current_vert].start();
168 const int next_a = neighbors[offset];
169 const int next_b = neighbors[offset + 1];
170 next_vert = (last_vert == next_a) ? next_b : next_a;
176 const int cyclic_start = curve_offsets.
size();
180 for (
const int start_vert :
IndexRange(verts_num)) {
181 if (unused_edges[start_vert] != 2) {
185 int current_vert = start_vert;
186 int next_vert = neighbors[neighbor_offsets[current_vert].start()];
189 vert_indices.
append(current_vert);
192 while (next_vert != start_vert) {
193 const int last_vert = current_vert;
194 current_vert = next_vert;
196 vert_indices.
append(current_vert);
197 unused_edges[current_vert]--;
198 unused_edges[last_vert]--;
200 const int offset = neighbor_offsets[current_vert].start();
201 const int next_a = neighbors[offset];
202 const int next_b = neighbors[offset + 1];
203 next_vert = (last_vert == next_a) ? next_b : next_a;
209 return {std::move(vert_indices), std::move(curve_offsets), cyclic_curves};
228 if (selection.
size() == edges.
size()) {
243 mesh.
runtime->face_offsets_sharing_info,
245 &curves.
runtime->curve_offsets_sharing_info);
268 return mesh.corner_verts();
289 mesh,
faces, points_by_curve, selection, point_to_vert_data);
293 src_attributes, dst_attributes, skip_storage, attribute_filter);
298 attribute_filter_with_skip,
309 if (attribute_filter_with_skip.allow_skip(iter.
name)) {
325 attribute_filter_with_skip,
332 attribute_filter_with_skip,
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 void fill(const T &value) const
constexpr T & last(const int64_t n=0) const
constexpr const T & last(const int64_t n=0) const
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void reinitialize(const int64_t new_size)
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
GAttributeReader get() const
OffsetIndices< int > points_by_curve() const
MutableAttributeAccessor attributes_for_write()
Span< int > offsets() const
void resize(int points_num, int curves_num)
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, AttrType data_type)
void gather_group_to_group(const OffsetIndices< int > src_offsets, const OffsetIndices< int > dst_offsets, const IndexMask &selection, const Span< T > src, MutableSpan< T > dst)
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)
void gather_attributes_group_to_group(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static Span< int > create_point_to_vert_map(const Mesh &mesh, const OffsetIndices< int > faces, const OffsetIndices< int > points_by_curve, const IndexMask &selection, Array< int > &map_data)
static auto filter_builtin_attributes(const bke::AttributeAccessor &mesh_attributes, const bke::AttributeAccessor &curves_attributes, Set< StringRef > &storage, const bke::AttributeFilter &attribute_filter)
static bke::CurvesGeometry create_curves_for_faces(const Mesh &mesh, const OffsetIndices< int > faces, const IndexMask &selection)
static BLI_NOINLINE CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num, const Span< int2 > edges)
bke::CurvesGeometry mesh_edges_to_curves_convert(const Mesh &mesh, const IndexMask &selection, const bke::AttributeFilter &attribute_filter)
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_faces_to_curves_convert(const Mesh &mesh, const IndexMask &selection, const bke::AttributeFilter &attribute_filter)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
CurvesGeometryRuntimeHandle * runtime
ListBase vertex_group_names
MeshRuntimeHandle * runtime
ListBase vertex_group_names
int * face_offset_indices
Vector< int > curve_offsets
Vector< int > vert_indices