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;
174 for (index_t lv = 0; lv < M.facets.nb_vertices(f); ++lv)
176 assert(!is_singular[idx2.vertex]);
177 unmarked_vertices.push_back(idx2.vertex);
179 if (edge_to_midpoint[idx2.edge] != -1)
183 idx2 = Navigation::next_around_face(M, c2e, idx2);
186 assert(edge_to_midpoint[idx2.edge] != -1);
187 assert(idx1.edge != idx2.edge);
188 assert(unmarked_vertices.front() == idx1.vertex);
189 assert(unmarked_vertices.back() == idx2.vertex);
193 int v1 = idx2.vertex;
194 int v0 = Navigation::switch_vertex(M, idx2).vertex;
195 int lv1 = M.facets.find_vertex(f, v1);
196 int v2 = M.facets.vertex(f, (lv1 + 1) % M.facets.nb_vertices(f));
200 std::reverse(unmarked_vertices.begin(), unmarked_vertices.end());
201 std::swap(idx1, idx2);
209 int sf = M.facets.nb_vertices(f);
210 int nv = (int)unmarked_vertices.size();
211 bool create_midfacet_point =
false;
216 create_midfacet_point =
false;
220 create_midfacet_point =
true;
225 create_midfacet_point =
false;
229 if (sf == 3 || sf == 4)
231 create_midfacet_point =
true;
235 create_midfacet_point =
false;
239 int ve1 = edge_to_midpoint[idx1.edge];
240 int ve2 = edge_to_midpoint[idx2.edge];
241 if (create_midfacet_point)
245 next_vertex_around_hole.resize(vf + 1);
246 assert(next_vertex_around_hole[ve1] == -1);
247 next_vertex_around_hole[ve1] = vf;
248 next_vertex_around_hole[vf] = ve2;
251 M.facets.create_quad(unmarked_vertices.front(), ve2, vf, ve1);
255 M.facets.create_quad(unmarked_vertices[0], unmarked_vertices[1], vf, ve1);
256 M.facets.create_quad(*(unmarked_vertices.rbegin() + 1), unmarked_vertices.back(), ve2, vf);
257 for (
int i = 1; i < int(unmarked_vertices.size()) - 2; ++i)
259 M.facets.create_triangle(unmarked_vertices[i], unmarked_vertices[i + 1], vf);
265 assert(next_vertex_around_hole[ve1] == -1);
266 next_vertex_around_hole[ve1] = ve2;
267 unmarked_vertices.push_back(ve2);
268 unmarked_vertices.push_back(ve1);
269 M.facets.create_polygon(unmarked_vertices);
274 std::vector<bool> marked(M.vertices.nb(),
false);
275 for (index_t v = 0; v < M.vertices.nb(); ++v)
277 if (next_vertex_around_hole[v] == -1 || marked[v])
281 GEO::vector<index_t> hole;
285 vi = next_vertex_around_hole[vi];
290 }
while (vi != (
int)v);
291 M.facets.create_polygon(hole);
295 GEO::vector<index_t> to_delete_mask(M.facets.nb(), 0u);
296 for (index_t f : facets_to_delete)
298 to_delete_mask[f] = 1;
300 M.facets.delete_elements(to_delete_mask);
302 M.vertices.remove_isolated();
306 std::vector<int> facet_to_midpoint(M.facets.nb(), -1);
307 GEO::vector<index_t> facets_to_delete;
308 for (index_t f = 0; f < M.facets.nb(); ++f) {
309 Index idx = Navigation::get_index_from_face(M, f, 0);
310 std::vector<int> marked_edges;
311 for (index_t le = 0; le < M.facets.nb_vertices(f); ++le) {
312 if (edge_to_midpoint[idx.edge] != -1) {
313 marked_edges.push_back(le);
315 idx = Navigation::next_around_face(M, idx);
318 assert(marked_edges.empty() || marked_edges.size() == 2);
319 if (!marked_edges.empty()) {
320 int e1 = marked_edges.front();
321 int e2 = marked_edges.back();
322 if (e1 + 1 == e2 || (e2 + 1) % (
int) M.facets.nb_vertices(f) == e1) {
324 facet_to_midpoint[f] = M.vertices.create_vertex(&coords[0]);
326 facets_to_delete.push_back(f);
331 std::vector<index_t> next_around_hole(M.vertices.nb(), -1);
332 std::vector<index_t> prev_around_hole(M.vertices.nb(), -1);
335 M.facets.delete_elements(facets_to_delete);
336 M.vertices.remove_isolated();