124 const Span<int2> src_edges = src_mesh.edges();
126 const Span<int> src_corner_verts = src_mesh.corner_verts();
127 const Span<int> src_corner_edges = src_mesh.corner_edges();
133 if (
const std::optional<bool> single = selection.
get_if_single()) {
134 return *single ? std::nullopt : std::make_optional<Mesh *>(
nullptr);
141 switch (selection_domain) {
142 case bke::AttrDomain::Point: {
144 threading::parallel_invoke(
146 [&]() { vert_mask = IndexMask::from_bools(span, memory.local()); },
147 [&]() { edge_mask = edge_selection_from_vert(src_edges, span, memory.local()); },
149 face_mask = face_selection_from_vert(
150 src_faces, src_corner_verts, span, memory.local());
154 case bke::AttrDomain::Edge: {
156 threading::parallel_invoke(
157 src_edges.
size() > 1024,
159 edge_mask = IndexMask::from_bools(span, memory.local());
160 vert_mask = vert_selection_from_edge(
161 src_edges, edge_mask, src_mesh.verts_num, memory.local());
164 face_mask = face_selection_from_edge(
165 src_faces, src_corner_edges, span, memory.local());
169 case bke::AttrDomain::Face: {
171 face_mask = IndexMask::from_bools(span, memory.
local());
172 threading::parallel_invoke(
173 face_mask.
size() > 1024,
175 vert_mask = vert_selection_from_face(
176 src_faces, face_mask, src_corner_verts, src_mesh.verts_num, memory.local());
179 edge_mask = edge_selection_from_face(
180 src_faces, face_mask, src_corner_edges, src_mesh.edges_num, memory.local());
192 const bool same_verts = vert_mask.
size() == src_mesh.
verts_num;
193 const bool same_edges = edge_mask.
size() == src_mesh.
edges_num;
194 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
195 if (same_verts && same_edges && same_faces) {
199 Mesh *dst_mesh = bke::mesh_new_no_attributes(
200 vert_mask.
size(), edge_mask.
size(), face_mask.
size(), 0);
207 src_faces, face_mask, dst_mesh->face_offsets_for_write());
214 threading::parallel_invoke(
215 vert_mask.
size() > 1024,
217 remap_verts(src_faces,
229 remap_edges(src_faces,
238 gather_vert_attributes(src_mesh, attribute_filter, vert_mask, *dst_mesh);
239 bke::gather_attributes(
241 bke::AttrDomain::Edge,
242 bke::AttrDomain::Edge,
243 bke::attribute_filter_with_skip_ref(attribute_filter, {
".edge_verts"}),
246 bke::gather_attributes(src_attributes,
247 bke::AttrDomain::Face,
248 bke::AttrDomain::Face,
252 bke::gather_attributes_group_to_group(
254 bke::AttrDomain::Corner,
255 bke::AttrDomain::Corner,
256 bke::attribute_filter_with_skip_ref(attribute_filter,
257 {
".corner_edge",
".corner_vert"}),
264 if (selection_domain == bke::AttrDomain::Edge) {
267 else if (selection_domain == bke::AttrDomain::Face) {
281 const Span<int2> src_edges = src_mesh.edges();
283 const Span<int> src_corner_verts = src_mesh.corner_verts();
284 const Span<int> src_corner_edges = src_mesh.corner_edges();
294 switch (selection_domain) {
295 case bke::AttrDomain::Point: {
297 threading::parallel_invoke(
298 src_edges.
size() > 1024,
299 [&]() { edge_mask = edge_selection_from_vert(src_edges, span, memory.local()); },
301 face_mask = face_selection_from_vert(
302 src_faces, src_corner_verts, span, memory.local());
306 case bke::AttrDomain::Edge: {
308 threading::parallel_invoke(
309 src_edges.
size() > 1024,
310 [&]() { edge_mask = IndexMask::from_bools(span, memory.local()); },
312 face_mask = face_selection_from_edge(
313 src_faces, src_corner_edges, span, memory.local());
317 case bke::AttrDomain::Face: {
319 face_mask = IndexMask::from_bools(span, memory.
local());
321 src_faces, face_mask, src_corner_edges, src_edges.
size(), memory.
local());
329 const bool same_edges = edge_mask.
size() == src_mesh.
edges_num;
330 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
331 if (same_edges && same_faces) {
335 Mesh *dst_mesh = bke::mesh_new_no_attributes(
341 src_faces, face_mask, dst_mesh->face_offsets_for_write());
346 threading::parallel_invoke(
357 bke::copy_attributes(src_attributes,
358 bke::AttrDomain::Point,
359 bke::AttrDomain::Point,
362 bke::gather_attributes(src_attributes,
363 bke::AttrDomain::Edge,
364 bke::AttrDomain::Edge,
368 bke::gather_attributes(src_attributes,
369 bke::AttrDomain::Face,
370 bke::AttrDomain::Face,
374 bke::gather_attributes_group_to_group(
376 bke::AttrDomain::Corner,
377 bke::AttrDomain::Corner,
378 bke::attribute_filter_with_skip_ref(attribute_filter, {
".corner_edge"}),
387 if (selection_domain == bke::AttrDomain::Face) {
409 switch (selection_domain) {
410 case bke::AttrDomain::Point:
412 src_faces, src_mesh.corner_verts(),
VArraySpan(selection), memory);
414 case bke::AttrDomain::Edge:
416 src_faces, src_mesh.corner_edges(),
VArraySpan(selection), memory);
418 case bke::AttrDomain::Face:
419 face_mask = IndexMask::from_bools(selection, memory);
426 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
431 Mesh *dst_mesh = bke::mesh_new_no_attributes(
437 src_faces, face_mask, dst_mesh->face_offsets_for_write());
442 bke::copy_attributes(src_attributes,
443 bke::AttrDomain::Point,
444 bke::AttrDomain::Point,
447 bke::copy_attributes(src_attributes,
448 bke::AttrDomain::Edge,
449 bke::AttrDomain::Edge,
452 bke::gather_attributes(src_attributes,
453 bke::AttrDomain::Face,
454 bke::AttrDomain::Face,
458 bke::gather_attributes_group_to_group(src_attributes,
459 bke::AttrDomain::Corner,
460 bke::AttrDomain::Corner,
static void remap_verts(const OffsetIndices< int > src_faces, const OffsetIndices< int > dst_faces, const int src_verts_num, const IndexMask &vert_mask, const IndexMask &edge_mask, const IndexMask &face_mask, const Span< int2 > src_edges, const Span< int > src_corner_verts, MutableSpan< int2 > dst_edges, MutableSpan< int > dst_corner_verts)