323 const int vertex_index,
324 const bool boundary_vertex,
330 if (connected_faces.
size() <= 2 && (!boundary_vertex || connected_faces.
is_empty())) {
336 for (
const int i : connected_faces.
index_range()) {
337 bool first_edge_done =
false;
338 for (
const int corner : faces[connected_faces[i]]) {
339 const int edge = corner_edges[corner];
340 if (edges[edge][0] == vertex_index || edges[edge][1] == vertex_index) {
341 if (!first_edge_done) {
342 face_vertex_corners[i].
first = corner;
343 first_edge_done =
true;
346 face_vertex_corners[i].second = corner;
353 int shared_edge_i = -1;
357 if (boundary_vertex) {
359 for (
const int i : connected_faces.
index_range()) {
360 const int corner_1 = face_vertex_corners[i].
first;
361 const int corner_2 = face_vertex_corners[i].second;
363 corner_verts[corner_1] == vertex_index)
365 shared_edge_i = corner_edges[corner_2];
366 r_sorted_corners[0] = face_vertex_corners[i].
first;
367 std::swap(connected_faces[i], connected_faces[0]);
368 std::swap(face_vertex_corners[i], face_vertex_corners[0]);
372 corner_verts[corner_2] == vertex_index)
374 shared_edge_i = corner_edges[corner_1];
375 r_sorted_corners[0] = face_vertex_corners[i].second;
376 std::swap(connected_faces[i], connected_faces[0]);
377 std::swap(face_vertex_corners[i], face_vertex_corners[0]);
381 if (shared_edge_i == -1) {
384 for (
const int i : connected_faces.
index_range()) {
385 const int corner_1 = face_vertex_corners[i].
first;
386 const int corner_2 = face_vertex_corners[i].second;
388 shared_edge_i = corner_edges[corner_2];
389 r_sorted_corners[0] = face_vertex_corners[i].
first;
390 std::swap(connected_faces[i], connected_faces[0]);
391 std::swap(face_vertex_corners[i], face_vertex_corners[0]);
395 shared_edge_i = corner_edges[corner_1];
396 r_sorted_corners[0] = face_vertex_corners[i].second;
397 std::swap(connected_faces[i], connected_faces[0]);
398 std::swap(face_vertex_corners[i], face_vertex_corners[0]);
406 const int corner_1 = face_vertex_corners.
first().first;
407 const int corner_2 = face_vertex_corners.
first().second;
408 if (corner_verts[corner_1] == vertex_index) {
409 shared_edge_i = corner_edges[corner_2];
410 r_sorted_corners[0] = face_vertex_corners[0].
first;
413 r_sorted_corners[0] = face_vertex_corners[0].second;
414 shared_edge_i = corner_edges[corner_1];
420 r_shared_edges[i] = shared_edge_i;
424 for (; j < connected_faces.
size(); ++j) {
425 const int corner_1 = face_vertex_corners[j].
first;
426 const int corner_2 = face_vertex_corners[j].second;
428 if (corner_edges[corner_1] == shared_edge_i) {
429 r_sorted_corners[i + 1] = face_vertex_corners[j].
first;
430 shared_edge_i = corner_edges[corner_2];
433 if (corner_edges[corner_2] == shared_edge_i) {
434 r_sorted_corners[i + 1] = face_vertex_corners[j].second;
435 shared_edge_i = corner_edges[corner_1];
439 if (j == connected_faces.
size()) {
445 std::swap(connected_faces[i + 1], connected_faces[j]);
446 std::swap(face_vertex_corners[i + 1], face_vertex_corners[j]);
449 if (!boundary_vertex) {
451 r_shared_edges.
last() = shared_edge_i;
615 const bool keep_boundaries,
618 const Span<float3> src_positions = src_mesh.vert_positions();
619 const Span<int2> src_edges = src_mesh.edges();
621 const Span<int> src_corner_verts = src_mesh.corner_verts();
622 const Span<int> src_corner_edges = src_mesh.corner_edges();
630 Array<int> vert_to_face_indices = src_mesh.vert_to_face_map().data;
636 for (const int i : range) {
637 if (vertex_types[i] == VertexType::Loose || vertex_types[i] >= VertexType::NonManifold ||
638 (!keep_boundaries && vertex_types[i] == VertexType::Boundary))
643 MutableSpan<int> corner_indices = vert_to_face_indices.as_mutable_span().slice(
644 vert_to_face_offsets[i]);
645 Array<int> sorted_corners(corner_indices.size());
646 bool vertex_ok = true;
647 if (vertex_types[i] == VertexType::Normal) {
648 Array<int> shared_edges(corner_indices.size());
649 vertex_ok = sort_vertex_faces(src_edges,
659 vertex_shared_edges[i] = std::move(shared_edges);
662 Array<int> shared_edges(corner_indices.size() - 1);
663 vertex_ok = sort_vertex_faces(src_edges,
673 vertex_shared_edges[i] = std::move(shared_edges);
678 vertex_types[i] = VertexType::NonManifold;
681 vertex_corners[i] = std::move(sorted_corners);
685 const GroupedSpan<int> vert_to_face_map(vert_to_face_offsets, vert_to_face_indices);
688 for (
const int i : src_faces.index_range()) {
694 if (keep_boundaries) {
696 boundary_edge_midpoint_index.
reinitialize(src_mesh.edges_num);
698 for (
const int i :
IndexRange(src_mesh.edges_num)) {
700 const int2 &edge = src_edges[i];
702 boundary_edge_midpoint_index[i] = vert_positions.
size();
703 vert_positions.append(mid);
708 Vector<int> face_sizes;
709 Vector<int> corner_verts;
710 Vector<int> corner_edges;
711 Vector<int2> new_edges;
713 Vector<int> new_to_old_face_corners_map;
714 Vector<int> new_to_old_edges_map;
716 Vector<std::pair<int, int>> boundary_vertex_to_relevant_face_map;
722 Array<int> old_to_new_edges_map(src_mesh.edges_num);
723 old_to_new_edges_map.fill(-1);
732 old_to_new_edges_map,
734 new_to_old_edges_map);
736 for (
const int i : IndexRange(src_mesh.verts_num)) {
744 Vector<int> corner_indices = vert_to_face_map[i];
745 Span<int> shared_edges = vertex_shared_edges[i];
746 Span<int> sorted_corners = vertex_corners[i];
748 if (corner_indices.size() <= 2) {
754 for (
const int i : shared_edges.index_range()) {
755 const int old_edge_i = shared_edges[i];
756 if (old_to_new_edges_map[old_edge_i] == -1) {
758 new_to_old_edges_map.append(old_edge_i);
759 old_to_new_edges_map[old_edge_i] = new_edges.size();
760 new_edges.append({corner_indices[i], corner_indices[(i + 1) % corner_indices.size()]});
762 corner_edges.append(old_to_new_edges_map[old_edge_i]);
765 new_to_old_face_corners_map.extend(sorted_corners);
793 for (
const int i : shared_edges.index_range()) {
794 const int old_edge_i = shared_edges[i];
795 if (old_to_new_edges_map[old_edge_i] == -1) {
797 new_to_old_edges_map.append(old_edge_i);
798 old_to_new_edges_map[old_edge_i] = new_edges.size();
799 new_edges.append({corner_indices[i], corner_indices[i + 1]});
801 corner_edges.append(old_to_new_edges_map[old_edge_i]);
804 new_to_old_face_corners_map.extend(sorted_corners);
811 if (corner_indices.size() >= 2) {
814 src_corner_edges.slice(src_faces[corner_indices.last()]),
819 src_corner_edges.slice(src_faces[corner_indices.first()]),
836 const int last_face_center = corner_indices.last();
837 corner_indices.append(boundary_edge_midpoint_index[edge1]);
838 new_to_old_face_corners_map.append(sorted_corners.last());
839 const int first_midpoint = corner_indices.last();
840 if (old_to_new_edges_map[edge1] == -1) {
844 new_to_old_edges_map,
847 old_to_new_edges_map[edge1] = new_edges.size() - 1;
848 boundary_vertex_to_relevant_face_map.append(std::pair(first_midpoint, last_face_center));
851 corner_edges.append(old_to_new_edges_map[edge1]);
853 corner_indices.append(vert_positions.size());
855 new_to_old_face_corners_map.append(sorted_corners.first());
856 boundary_vertex_to_relevant_face_map.append(
857 std::pair(corner_indices.last(), last_face_center));
858 vert_positions.append(src_positions[i]);
859 const int boundary_vertex = corner_indices.last();
861 edge1, first_midpoint, boundary_vertex, new_to_old_edges_map, new_edges, corner_edges);
863 corner_indices.append(boundary_edge_midpoint_index[edge2]);
864 new_to_old_face_corners_map.append(sorted_corners.first());
865 const int second_midpoint = corner_indices.last();
867 edge2, boundary_vertex, second_midpoint, new_to_old_edges_map, new_edges, corner_edges);
869 if (old_to_new_edges_map[edge2] == -1) {
870 const int first_face_center = corner_indices.first();
874 new_to_old_edges_map,
877 old_to_new_edges_map[edge2] = new_edges.size() - 1;
878 boundary_vertex_to_relevant_face_map.append(std::pair(second_midpoint, first_face_center));
881 corner_edges.append(old_to_new_edges_map[edge2]);
885 face_sizes.append(corner_indices.size());
886 for (
const int j : corner_indices) {
887 corner_verts.append(j);
891 vert_positions.size(), new_edges.size(), face_sizes.size(), corner_verts.size());
896 new_to_old_edges_map,
897 new_to_old_face_corners_map,
898 boundary_vertex_to_relevant_face_map,
900 src_mesh.attributes(),
901 mesh_out->attributes_for_write());
903 mesh_out->vert_positions_for_write().copy_from(vert_positions);
904 mesh_out->edges_for_write().copy_from(new_edges);
907 MutableSpan<int> dst_face_offsets = mesh_out->face_offsets_for_write();
908 dst_face_offsets.drop_back(1).copy_from(face_sizes);
911 mesh_out->corner_verts_for_write().copy_from(corner_verts);
912 mesh_out->corner_edges_for_write().copy_from(corner_edges);