54 {
55 std::vector<std::unordered_set<std::size_t>> vtx_to_adj_faces(mesh.vertices.size());
56 std::size_t edge_id = 0;
57 std::vector<std::unordered_set<std::size_t>> edge_to_faces;
58 std::vector<std::unordered_set<std::size_t>> vtx_to_prev_vtxs(mesh.vertices.size());
59 std::vector<std::unordered_set<std::size_t>> vtx_to_next_vtxs(mesh.vertices.size());
60 std::vector<std::unordered_map<std::size_t, std::size_t>> vtx_vtx_to_edge(mesh.vertices.size());
61
62 for (std::size_t fid = 0; fid < mesh.indices.size(); ++fid) {
63 const TriFace& face = mesh.indices[fid];
64 if (face[0] == face[1] || face[1] == face[2] || face[2] == face[0]) {
65 return false;
66 }
67 for (std::size_t i = 0; i < 3; ++i) {
68 if (static_cast<std::size_t>(face[i]) >= mesh.vertices.size()) {
69 return false;
70 }
71 vtx_to_adj_faces[face[i]].insert(fid);
72
73 std::size_t prev_vtx = face[(i + 2) % 3];
74 std::size_t next_vtx = face[(i + 1) % 3];
75
76 if (vtx_to_prev_vtxs[face[i]].
count(prev_vtx)) {
77 return false;
78 }
79 vtx_to_prev_vtxs[face[i]].insert(prev_vtx);
80
81 if (vtx_to_next_vtxs[face[i]].
count(next_vtx)) {
82 return false;
83 }
84 vtx_to_next_vtxs[face[i]].insert(next_vtx);
85 }
86
87 for (std::size_t i = 0; i < 3; ++i) {
88 std::size_t va = face[i];
89 std::size_t vb = face[(i + 1) % 3];
90 if (!vtx_vtx_to_edge[va].
count(vb)) {
91 vtx_vtx_to_edge[va][vb] = edge_id;
92 vtx_vtx_to_edge[vb][va] = edge_id;
93 ++edge_id;
94 edge_to_faces.emplace_back(std::unordered_set<std::size_t>());
95 }
96 edge_to_faces[vtx_vtx_to_edge[va][vb]].insert(fid);
97 }
98 }
99
100 for (std::size_t vid = 0; vid < mesh.vertices.size(); ++vid) {
101 if (vtx_to_adj_faces[vid].
empty()) {
102 continue;
103 }
104 std::unordered_set<std::size_t> visited_faces;
105 std::queue<std::size_t> face_queue;
106 face_queue.push(*(vtx_to_adj_faces[vid].
begin()));
107 visited_faces.insert(*(vtx_to_adj_faces[vid].
begin()));
108 while (!face_queue.empty()) {
109 std::size_t fid = face_queue.front();
110 face_queue.pop();
111 const TriFace& face = mesh.indices[fid];
112 for (std::size_t i = 0; i < 3; ++i) {
113 if (static_cast<std::size_t>(face[i]) != vid) {
114 continue;
115 }
116 std::size_t v_next = face[(i + 1) % 3];
117 std::size_t v_prev = face[(i + 2) % 3];
118 for (std::size_t nbr : {v_next, v_prev}) {
119 std::size_t eid = vtx_vtx_to_edge[vid][nbr];
120 for (std::size_t adj_fid : edge_to_faces[eid]) {
121 if (!visited_faces.count(adj_fid) && vtx_to_adj_faces[vid].count(adj_fid)) {
122 visited_faces.insert(adj_fid);
123 face_queue.push(adj_fid);
124 }
125 }
126 }
127 break;
128 }
129 }
130
131 for (std::size_t fid : vtx_to_adj_faces[vid]) {
132 if (!visited_faces.count(fid)) {
133 return false;
134 }
135 }
136 }
137
138 return true;
139}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246
T * begin(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:838
stl_triangle_vertex_indices TriFace
Definition TriMesh.hpp:12
bool empty(const BoundingBoxBase< PointType, PointsType > &bb)
Definition BoundingBox.hpp:273