85 GEO::Mesh &M,
const Eigen::VectorXi &
V,
const Eigen::MatrixX2i &E,
double t)
90 assert(M.vertices.dimension() == 2 || M.vertices.dimension() == 3);
93 std::vector<int> singulars;
94 singulars.reserve(
V.size() + E.size());
95 for (
int i = 0; i <
V.size(); ++i)
97 singulars.push_back(
V(i));
99 for (
int i = 0; i < E.size(); ++i)
101 singulars.push_back(E.data()[i]);
103 std::sort(singulars.begin(), singulars.end());
104 auto it = std::unique(singulars.begin(), singulars.end());
105 singulars.resize(std::distance(singulars.begin(), it));
107 std::vector<bool> is_singular(M.vertices.nb(),
false);
108 for (
int v : singulars)
110 is_singular[v] =
true;
114 std::vector<int> edge_to_midpoint(M.edges.nb(), -1);
115 for (index_t e = 0; e < M.edges.nb(); ++e)
117 for (index_t lv = 0; lv < 2; ++lv)
119 int v1 = M.edges.vertex(e, lv);
120 int v2 = M.edges.vertex(e, (lv + 1) % 2);
121 if (is_singular[v1] && !is_singular[v2])
129 GEO::Attribute<GEO::index_t> c2e(M.facet_corners.attributes(),
"edge_id");
132 std::vector<index_t> facets_to_delete;
133 std::vector<int> next_vertex_around_hole(M.vertices.nb(), -1);
134 for (index_t f = 0, old_num_facets = M.facets.nb(); f < old_num_facets; ++f)
144 assert(M.facets.nb_vertices(f) > 2);
147 Index idx1 = Navigation::get_index_from_face(M, c2e, f, 0);
149 for (index_t lv = 0; lv < M.facets.nb_vertices(f); ++lv)
151 if (edge_to_midpoint[idx1.edge] != -1)
155 idx1 = Navigation::next_around_face(M, c2e, idx1);
157 if (edge_to_midpoint[idx1.edge] == -1)
161 facets_to_delete.push_back(f);
164 if (is_singular[idx1.vertex])
166 idx1 = Navigation::switch_vertex(M, idx1);
167 assert(!is_singular[idx1.vertex]);
171 Index idx2 = Navigation::switch_edge(M, c2e, idx1);
172 GEO::vector<index_t> unmarked_vertices;
173 for (index_t lv = 0; lv < M.facets.nb_vertices(f); ++lv)
175 assert(!is_singular[idx2.vertex]);
176 unmarked_vertices.push_back(idx2.vertex);
177 if (edge_to_midpoint[idx2.edge] != -1)
181 idx2 = Navigation::next_around_face(M, c2e, idx2);
183 assert(edge_to_midpoint[idx2.edge] != -1);
184 assert(idx1.edge != idx2.edge);
185 assert(unmarked_vertices.front() == idx1.vertex);
186 assert(unmarked_vertices.back() == idx2.vertex);
190 int v1 = idx2.vertex;
191 int v0 = Navigation::switch_vertex(M, idx2).vertex;
192 int lv1 = M.facets.find_vertex(f, v1);
193 int v2 = M.facets.vertex(f, (lv1 + 1) % M.facets.nb_vertices(f));
197 std::reverse(unmarked_vertices.begin(), unmarked_vertices.end());
198 std::swap(idx1, idx2);
206 int sf = M.facets.nb_vertices(f);
207 int nv = (int)unmarked_vertices.size();
208 bool create_midfacet_point =
false;
213 create_midfacet_point =
false;
217 create_midfacet_point =
true;
222 create_midfacet_point =
false;
226 if (sf == 3 || sf == 4)
228 create_midfacet_point =
true;
232 create_midfacet_point =
false;
236 int ve1 = edge_to_midpoint[idx1.edge];
237 int ve2 = edge_to_midpoint[idx2.edge];
238 if (create_midfacet_point)
242 next_vertex_around_hole.resize(vf + 1);
243 assert(next_vertex_around_hole[ve1] == -1);
244 next_vertex_around_hole[ve1] = vf;
245 next_vertex_around_hole[vf] = ve2;
248 M.facets.create_quad(unmarked_vertices.front(), ve2, vf, ve1);
252 M.facets.create_quad(unmarked_vertices[0], unmarked_vertices[1], vf, ve1);
253 M.facets.create_quad(*(unmarked_vertices.rbegin() + 1), unmarked_vertices.back(), ve2, vf);
254 for (
int i = 1; i < int(unmarked_vertices.size()) - 2; ++i)
256 M.facets.create_triangle(unmarked_vertices[i], unmarked_vertices[i + 1], vf);
262 assert(next_vertex_around_hole[ve1] == -1);
263 next_vertex_around_hole[ve1] = ve2;
264 unmarked_vertices.push_back(ve2);
265 unmarked_vertices.push_back(ve1);
266 M.facets.create_polygon(unmarked_vertices);
271 std::vector<bool> marked(M.vertices.nb(),
false);
272 for (index_t v = 0; v < M.vertices.nb(); ++v)
274 if (next_vertex_around_hole[v] == -1 || marked[v])
278 GEO::vector<index_t> hole;
282 vi = next_vertex_around_hole[vi];
286 }
while (vi != (
int)v);
287 M.facets.create_polygon(hole);
291 GEO::vector<index_t> to_delete_mask(M.facets.nb(), 0u);
292 for (index_t f : facets_to_delete)
294 to_delete_mask[f] = 1;
296 M.facets.delete_elements(to_delete_mask);
298 M.vertices.remove_isolated();
302 std::vector<int> facet_to_midpoint(M.facets.nb(), -1);
303 GEO::vector<index_t> facets_to_delete;
304 for (index_t f = 0; f < M.facets.nb(); ++f) {
305 Index idx = Navigation::get_index_from_face(M, f, 0);
306 std::vector<int> marked_edges;
307 for (index_t le = 0; le < M.facets.nb_vertices(f); ++le) {
308 if (edge_to_midpoint[idx.edge] != -1) {
309 marked_edges.push_back(le);
311 idx = Navigation::next_around_face(M, idx);
314 assert(marked_edges.empty() || marked_edges.size() == 2);
315 if (!marked_edges.empty()) {
316 int e1 = marked_edges.front();
317 int e2 = marked_edges.back();
318 if (e1 + 1 == e2 || (e2 + 1) % (
int) M.facets.nb_vertices(f) == e1) {
320 facet_to_midpoint[f] = M.vertices.create_vertex(&coords[0]);
322 facets_to_delete.push_back(f);
327 std::vector<index_t> next_around_hole(M.vertices.nb(), -1);
328 std::vector<index_t> prev_around_hole(M.vertices.nb(), -1);
331 M.facets.delete_elements(facets_to_delete);
332 M.vertices.remove_isolated();