326 const int vertex_index,
327 const bool boundary_vertex,
333 if (connected_faces.
size() <= 2 && (!boundary_vertex || connected_faces.
is_empty())) {
340 bool first_edge_done =
false;
341 for (
const int corner :
faces[connected_faces[
i]]) {
342 const int edge = corner_edges[corner];
343 if (edges[edge][0] == vertex_index || edges[edge][1] == vertex_index) {
344 if (!first_edge_done) {
345 face_vertex_corners[
i].
first = corner;
346 first_edge_done =
true;
349 face_vertex_corners[
i].second = corner;
356 int shared_edge_i = -1;
360 if (boundary_vertex) {
363 const int corner_1 = face_vertex_corners[
i].
first;
364 const int corner_2 = face_vertex_corners[
i].second;
366 corner_verts[corner_1] == vertex_index)
368 shared_edge_i = corner_edges[corner_2];
369 r_sorted_corners[0] = face_vertex_corners[
i].
first;
370 std::swap(connected_faces[
i], connected_faces[0]);
371 std::swap(face_vertex_corners[
i], face_vertex_corners[0]);
375 corner_verts[corner_2] == vertex_index)
377 shared_edge_i = corner_edges[corner_1];
378 r_sorted_corners[0] = face_vertex_corners[
i].second;
379 std::swap(connected_faces[
i], connected_faces[0]);
380 std::swap(face_vertex_corners[
i], face_vertex_corners[0]);
384 if (shared_edge_i == -1) {
388 const int corner_1 = face_vertex_corners[
i].
first;
389 const int corner_2 = face_vertex_corners[
i].second;
391 shared_edge_i = corner_edges[corner_2];
392 r_sorted_corners[0] = face_vertex_corners[
i].
first;
393 std::swap(connected_faces[
i], connected_faces[0]);
394 std::swap(face_vertex_corners[
i], face_vertex_corners[0]);
398 shared_edge_i = corner_edges[corner_1];
399 r_sorted_corners[0] = face_vertex_corners[
i].second;
400 std::swap(connected_faces[
i], connected_faces[0]);
401 std::swap(face_vertex_corners[
i], face_vertex_corners[0]);
409 const int corner_1 = face_vertex_corners.
first().first;
410 const int corner_2 = face_vertex_corners.
first().second;
411 if (corner_verts[corner_1] == vertex_index) {
412 shared_edge_i = corner_edges[corner_2];
413 r_sorted_corners[0] = face_vertex_corners[0].
first;
416 r_sorted_corners[0] = face_vertex_corners[0].second;
417 shared_edge_i = corner_edges[corner_1];
423 r_shared_edges[
i] = shared_edge_i;
427 for (; j < connected_faces.
size(); ++j) {
428 const int corner_1 = face_vertex_corners[j].
first;
429 const int corner_2 = face_vertex_corners[j].second;
431 if (corner_edges[corner_1] == shared_edge_i) {
432 r_sorted_corners[
i + 1] = face_vertex_corners[j].
first;
433 shared_edge_i = corner_edges[corner_2];
436 if (corner_edges[corner_2] == shared_edge_i) {
437 r_sorted_corners[
i + 1] = face_vertex_corners[j].second;
438 shared_edge_i = corner_edges[corner_1];
442 if (j == connected_faces.
size()) {
448 std::swap(connected_faces[
i + 1], connected_faces[j]);
449 std::swap(face_vertex_corners[
i + 1], face_vertex_corners[j]);
452 if (!boundary_vertex) {
454 r_shared_edges.
last() = shared_edge_i;
618 const bool keep_boundaries,
621 const Span<float3> src_positions = src_mesh.vert_positions();
622 const Span<int2> src_edges = src_mesh.edges();
624 const Span<int> src_corner_verts = src_mesh.corner_verts();
625 const Span<int> src_corner_edges = src_mesh.corner_edges();
633 Array<int> vert_to_face_indices = src_mesh.vert_to_face_map().data;
639 for (const int i : range) {
640 if (vertex_types[i] == VertexType::Loose || vertex_types[i] >= VertexType::NonManifold ||
641 (!keep_boundaries && vertex_types[i] == VertexType::Boundary))
646 MutableSpan<int> corner_indices = vert_to_face_indices.as_mutable_span().slice(
647 vert_to_face_offsets[i]);
648 Array<int> sorted_corners(corner_indices.size());
649 bool vertex_ok = true;
650 if (vertex_types[i] == VertexType::Normal) {
651 Array<int> shared_edges(corner_indices.size());
652 vertex_ok = sort_vertex_faces(src_edges,
662 vertex_shared_edges[i] = std::move(shared_edges);
665 Array<int> shared_edges(corner_indices.size() - 1);
666 vertex_ok = sort_vertex_faces(src_edges,
676 vertex_shared_edges[i] = std::move(shared_edges);
681 vertex_types[i] = VertexType::NonManifold;
684 vertex_corners[i] = std::move(sorted_corners);
688 const GroupedSpan<int> vert_to_face_map(vert_to_face_offsets, vert_to_face_indices);
691 for (
const int i : src_faces.index_range()) {
697 if (keep_boundaries) {
699 boundary_edge_midpoint_index.
reinitialize(src_mesh.edges_num);
701 for (
const int i :
IndexRange(src_mesh.edges_num)) {
703 const int2 &edge = src_edges[
i];
705 boundary_edge_midpoint_index[
i] = vert_positions.
size();
706 vert_positions.append(mid);
711 Vector<int> face_sizes;
712 Vector<int> corner_verts;
713 Vector<int> corner_edges;
714 Vector<int2> new_edges;
716 Vector<int> new_to_old_face_corners_map;
717 Vector<int> new_to_old_edges_map;
719 Vector<std::pair<int, int>> boundary_vertex_to_relevant_face_map;
725 Array<int> old_to_new_edges_map(src_mesh.edges_num);
726 old_to_new_edges_map.fill(-1);
735 old_to_new_edges_map,
737 new_to_old_edges_map);
739 for (
const int i : IndexRange(src_mesh.verts_num)) {
747 Vector<int> corner_indices = vert_to_face_map[
i];
748 Span<int> shared_edges = vertex_shared_edges[
i];
749 Span<int> sorted_corners = vertex_corners[
i];
751 if (corner_indices.
size() <= 2) {
758 const int old_edge_i = shared_edges[
i];
759 if (old_to_new_edges_map[old_edge_i] == -1) {
761 new_to_old_edges_map.
append(old_edge_i);
762 old_to_new_edges_map[old_edge_i] = new_edges.
size();
763 new_edges.
append({corner_indices[
i], corner_indices[(
i + 1) % corner_indices.
size()]});
765 corner_edges.
append(old_to_new_edges_map[old_edge_i]);
768 new_to_old_face_corners_map.
extend(sorted_corners);
797 const int old_edge_i = shared_edges[
i];
798 if (old_to_new_edges_map[old_edge_i] == -1) {
800 new_to_old_edges_map.
append(old_edge_i);
801 old_to_new_edges_map[old_edge_i] = new_edges.
size();
802 new_edges.
append({corner_indices[
i], corner_indices[
i + 1]});
804 corner_edges.
append(old_to_new_edges_map[old_edge_i]);
807 new_to_old_face_corners_map.
extend(sorted_corners);
814 if (corner_indices.
size() >= 2) {
817 src_corner_edges.slice(src_faces[corner_indices.
last()]),
822 src_corner_edges.slice(src_faces[corner_indices.
first()]),
839 const int last_face_center = corner_indices.
last();
840 corner_indices.
append(boundary_edge_midpoint_index[edge1]);
841 new_to_old_face_corners_map.
append(sorted_corners.
last());
842 const int first_midpoint = corner_indices.
last();
843 if (old_to_new_edges_map[edge1] == -1) {
847 new_to_old_edges_map,
850 old_to_new_edges_map[edge1] = new_edges.
size() - 1;
851 boundary_vertex_to_relevant_face_map.
append(std::pair(first_midpoint, last_face_center));
854 corner_edges.
append(old_to_new_edges_map[edge1]);
856 corner_indices.
append(vert_positions.size());
858 new_to_old_face_corners_map.
append(sorted_corners.
first());
859 boundary_vertex_to_relevant_face_map.
append(
860 std::pair(corner_indices.
last(), last_face_center));
861 vert_positions.append(src_positions[
i]);
862 const int boundary_vertex = corner_indices.
last();
864 edge1, first_midpoint, boundary_vertex, new_to_old_edges_map, new_edges, corner_edges);
866 corner_indices.
append(boundary_edge_midpoint_index[edge2]);
867 new_to_old_face_corners_map.
append(sorted_corners.
first());
868 const int second_midpoint = corner_indices.
last();
870 edge2, boundary_vertex, second_midpoint, new_to_old_edges_map, new_edges, corner_edges);
872 if (old_to_new_edges_map[edge2] == -1) {
873 const int first_face_center = corner_indices.
first();
877 new_to_old_edges_map,
880 old_to_new_edges_map[edge2] = new_edges.
size() - 1;
881 boundary_vertex_to_relevant_face_map.
append(std::pair(second_midpoint, first_face_center));
884 corner_edges.
append(old_to_new_edges_map[edge2]);
889 for (
const int j : corner_indices) {
894 vert_positions.size(), new_edges.
size(), face_sizes.
size(), corner_verts.
size());
899 new_to_old_edges_map,
900 new_to_old_face_corners_map,
901 boundary_vertex_to_relevant_face_map,
903 src_mesh.attributes(),
904 mesh_out->attributes_for_write());
906 mesh_out->vert_positions_for_write().copy_from(vert_positions);
907 mesh_out->edges_for_write().copy_from(new_edges);
910 MutableSpan<int> dst_face_offsets = mesh_out->face_offsets_for_write();
914 mesh_out->corner_verts_for_write().copy_from(corner_verts);
915 mesh_out->corner_edges_for_write().copy_from(corner_edges);