234 bool keep_existing_edges,
235 const bool select_new_edges,
239 if (
mesh.edges_num == 0 &&
mesh.corners_num == 0) {
244 if (
mesh.corners_num == 0 && !keep_existing_edges) {
247 mesh.tag_loose_edges_none();
253 return edge.x != edge.y;
260 const uint32_t parallel_mask = uint32_t(parallel_maps) - 1;
264 Array<int> original_edge_maps_prefix_size(edge_maps.
size() + 1, 0);
265 if (keep_existing_edges) {
270 const int original_unique_edge_num = original_edge_maps_prefix.
total_size();
271 const bool original_edges_are_distinct = original_unique_edge_num ==
mesh.edges_num;
273 if (
mesh.corners_num == 0 && keep_existing_edges && original_edges_are_distinct) {
281 const bool no_new_edges = edge_offsets.
total_size() == original_unique_edge_num;
287 corner_edges.fill(-1);
290 const int result_edges_num = edge_offsets.
total_size();
295 if (keep_existing_edges && original_edges_are_distinct && no_new_edges) {
299 faces, corner_verts, edge_maps, parallel_mask, edge_offsets, corner_edges);
301 Array<int> edge_map_to_result_index(result_edges_num);
306 original_edges, edge_maps, parallel_mask, edge_offsets, edge_map_to_result_index);
323 if (keep_existing_edges) {
326 if (original_edges_are_distinct) {
327 src_to_dst_mask =
IndexRange(original_unique_edge_num);
340 original_edges, src_to_dst_mask, edge_verts.
take_front(original_unique_edge_num));
344 Array<int> edge_map_to_result_index(result_edges_num);
349 if (original_edges_are_distinct) {
356 edge_map_to_result_index);
360 GrainSize(1024), [&](
const int src_index,
const int dst_index) {
361 const OrderedEdge edge = original_edges[src_index];
363 const int edge_index = edge_maps[map_i].index_of(edge);
364 edge_map_to_result_index[edge_offsets[map_i][edge_index]] = dst_index;
372 const int new_edges_start = original_unique_edge_num;
374 const IndexRange map_edges = edge_offsets[map_i];
375 const IndexRange prefix_edges = original_edge_maps_prefix[map_i];
378 const int new_edges_start_pos = map_edges.
start() - prefix_edges.
start();
379 const int map_new_edges_start = new_edges_start + new_edges_start_pos;
382 map_new_edges_start);
388 faces, corner_verts, edge_maps, parallel_mask, edge_offsets, corner_edges);
394 original_edge_maps_prefix,
395 edge_verts.
drop_front(original_unique_edge_num));
398 if (
mesh.edges_num != 0) {
403 return edge_maps[map_i].contains(edge);
406 original_edges, original_corner_edges, edge_maps, parallel_mask, edge_offsets, memory);
408 const int old_corner_edges_num = src_to_dst_mask.size();
412 if (!src_to_dst_mask.is_empty()) {
414 edge_map_to_result_index.
reinitialize(result_edges_num);
416 src_to_dst_mask.foreach_index([&](
const int original_edge_i) {
417 const OrderedEdge edge = original_edges[original_edge_i];
419 const int edge_index = edge_maps[edge_map].index_of(edge);
420 edge_map_to_result_index[edge_offsets[edge_map][edge_index]] = 0;
424 old_corner_edges_num);
426 src_to_dst_mask.foreach_index([&](
const int original_edge_i,
const int dst_edge_i) {
427 const OrderedEdge edge = original_edges[original_edge_i];
429 const int edge_index = edge_maps[edge_map].index_of(edge);
430 edge_map_to_result_index[edge_offsets[edge_map][edge_index]] = dst_edge_i;
434 original_edges, src_to_dst_mask, edge_verts.
take_front(old_corner_edges_num));
437 const int task_index = &edge_map - edge_maps.
data();
438 if (edge_offsets[task_index].is_empty()) {
444 edge_map_to_result_index.
as_span().slice(edge_offsets[task_index]),
449 faces, corner_verts, edge_maps, parallel_mask, edge_offsets, corner_edges);
452 edge_map_to_result_index.
as_span(), corner_edges.as_span(), corner_edges);
456 faces, corner_verts, edge_maps, parallel_mask, edge_offsets, corner_edges);
458 edge_maps, edge_offsets, original_edge_maps_prefix, edge_verts);
462 back_range_of_new_edges =
IndexRange(result_edges_num);
465 faces, corner_verts, edge_maps, parallel_mask, edge_offsets, corner_edges);
467 edge_maps, edge_offsets, original_edge_maps_prefix, edge_verts);
472 edge_verts.
begin(), edge_verts.
end(), [&](
const int2 edge) { return edge.x != edge.y; }));
477 BLI_assert(src_to_dst_mask.
size() + back_range_of_new_edges.
size() == result_edges_num);
495 for (
const StringRef attribute : attributes_to_drop) {
496 dst_attributes.
remove(attribute);
501 const void *src_data = layer.data;
505 if (src_data !=
nullptr) {
507 const Span src(
static_cast<const int *
>(src_data),
mesh.edges_num);
508 MutableSpan dst(
static_cast<int *
>(dst_data), result_edges_num);
510 dst.
slice(back_range_of_new_edges).
fill(-1);
515 const GSpan src(type, src_data,
mesh.edges_num);
519 dst.
slice(back_range_of_new_edges).
data(),
520 dst.
slice(back_range_of_new_edges).
size());
522 layer.sharing_info->remove_user_and_delete_if_last();
525 layer.data = dst_data;
529 mesh.edges_num = result_edges_num;
534 if (select_new_edges) {
535 dst_attributes.
remove(
".select_edge");
536 if (
ELEM(back_range_of_new_edges.
size(), 0,
mesh.edges_num)) {
537 const bool fill_value = back_range_of_new_edges.
size() ==
mesh.edges_num;
546 select_edge.
span.drop_back(back_range_of_new_edges.
size()).fill(
false);
547 select_edge.
span.take_back(back_range_of_new_edges.
size()).fill(
true);
552 if (!keep_existing_edges) {
554 mesh.tag_loose_edges_none();