@@ -138,8 +138,6 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
138138 if (cache.edge_length > 0 && VA[v1_id].m_is_on_open_boundary ) {
139139 if (!VA[v2_id].m_is_on_open_boundary &&
140140 m_open_boundary_envelope.is_outside (VA[v2_id].m_posf )) {
141- // if (debug_flag) std::cout << "open boundary reject" << std::endl;
142-
143141 return false ;
144142 }
145143 }
@@ -158,7 +156,7 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
158156 }
159157 }
160158
161- // pre-compute energies after collapse
159+ // pre-compute after- collapse energies
162160 cache.changed_energies .reserve (cache.changed_tids .size ());
163161 for (const size_t tid : cache.changed_tids ) {
164162 std::array<size_t , 4 > vs = oriented_tet_vids (tid);
@@ -183,31 +181,26 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
183181
184182 //
185183 const auto n12_locs = get_incident_tids_for_edge (loc); // todo: duplicated computation
186- std::unordered_set<int > unique_fid;
187184 for (const size_t & tid : n12_locs) {
188185 auto vs = oriented_tet_vids (tid);
189186 std::array<size_t , 3 > f_vids = {{v1_id, 0 , 0 }};
190187 int cnt = 1 ;
188+ // get the two vertices that are not v1/v2, i.e., the edge-link vertices.
191189 for (int j = 0 ; j < 4 ; j++) {
192190 if (vs[j] != v1_id && vs[j] != v2_id) {
193191 f_vids[cnt] = vs[j];
194192 cnt++;
195193 }
196194 }
197195 auto [_1, global_fid1] = tuple_from_face (f_vids);
198- auto [it, suc] = unique_fid.insert (global_fid1);
199- if (!suc) {
200- continue ;
201- }
202-
203196 auto [_2, global_fid2] = tuple_from_face ({{v2_id, f_vids[1 ], f_vids[2 ]}});
204197 auto f_attr = m_face_attribute.at (global_fid1);
205198 f_attr.merge (m_face_attribute.at (global_fid2));
206199 cache.changed_faces .push_back (std::make_pair (f_attr, f_vids));
207200 }
208201
209202 if (VA[v1_id].m_is_on_surface ) {
210- // this code must check if a face is tagged as boundary
203+ // this code must check if a face is tagged as surface face
211204 // only checking the vertices is not enough
212205 std::vector<std::array<size_t , 3 >> fs;
213206 for (const size_t & tid : n1_locs) {
@@ -218,6 +211,7 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
218211 for (int j = 0 ; j < 4 ; j++) {
219212 const size_t vid = vs[j];
220213 if (vid == v2_id) {
214+ // ignore tets incident to the edge (v1,v2)
221215 return true ; // v1-v2 definitely not on surface.
222216 }
223217 if (vid == v1_id) j_v1 = j;
@@ -243,15 +237,14 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
243237 }
244238 wmtk::vector_unique (fs);
245239
240+ cache.surface_faces .reserve (fs.size ());
246241 for (auto & f : fs) {
247- auto [_1, global_fid1] = tuple_from_face (f);
248- if (m_face_attribute.at (global_fid1).m_is_surface_fs ) {
249- std::replace (f.begin (), f.end (), v1_id, v2_id);
250- cache.surface_faces .push_back (f);
251- }
242+ std::replace (f.begin (), f.end (), v1_id, v2_id);
243+ cache.surface_faces .push_back (f);
252244 }
253245
254246 std::vector<std::array<size_t , 2 >> bs;
247+ // iterate through all faces inicdent to v1
255248 for (const size_t & tid : n1_locs) {
256249 const auto vs = oriented_tet_vids (tid);
257250
@@ -273,15 +266,15 @@ bool TetWildMesh::collapse_edge_before(const Tuple& loc) // input is an edge
273266 // check if this face is actually on the surface
274267 continue ;
275268 }
276- if (va != v2_id) {
269+ if (va != v2_id) { // ignore collapsing edge (v1,v2)
277270 std::array<size_t , 2 > ba = {{v1_id, va}};
278271 if (is_open_boundary_edge (ba)) {
279272 ba[0 ] = v2_id; // replace v1 with v2 for check in `after` function
280273 std::sort (ba.begin (), ba.end ());
281274 bs.push_back (ba);
282275 }
283276 }
284- if (vb != v2_id) {
277+ if (vb != v2_id) { // ignore collapsing edge (v1,v2)
285278 std::array<size_t , 2 > bb = {{v1_id, vb}};
286279 if (is_open_boundary_edge (bb)) {
287280 bb[0 ] = v2_id; // replace v1 with v2 for check in `after` function
@@ -323,18 +316,16 @@ bool TetWildMesh::collapse_edge_after(const Tuple& loc)
323316
324317 // open boundary - must be set before checking for open boundary
325318 VA[v2_id].m_is_on_open_boundary =
326- VA[ v1_id] .m_is_on_open_boundary || VA[ v2_id] .m_is_on_open_boundary ;
319+ VA. at ( v1_id) .m_is_on_open_boundary || VA. at ( v2_id) .m_is_on_open_boundary ;
327320
328321 // surface
329322 // and open boundary
330323 if (cache.edge_length > 0 ) {
331324 for (auto & vids : cache.surface_faces ) {
332325 // surface envelope
333326 bool is_out = m_envelope.is_outside (
334- {{VA[ vids[0 ]] .m_posf , VA[ vids[1 ]] .m_posf , VA[ vids[2 ]] .m_posf }});
327+ {{VA. at ( vids[0 ]) .m_posf , VA. at ( vids[1 ]) .m_posf , VA. at ( vids[2 ]) .m_posf }});
335328 if (is_out) {
336- // if (debug_flag) std::cout << "surface enve reject" << std::endl;
337-
338329 return false ;
339330 }
340331
@@ -356,23 +347,31 @@ bool TetWildMesh::collapse_edge_after(const Tuple& loc)
356347 // return false;
357348 // }
358349 }
359- for (const auto & vids : cache.boundary_edges ) {
360- if (!is_open_boundary_edge (vids)) {
361- // edge was an open boundary before (that is why it got cached) but is not anymore
362- // after collapse
363- return false ;
364- }
350+ // for (const auto& vids : cache.boundary_edges) {
351+ // if (!is_open_boundary_edge(vids)) {
352+ // // edge was an open boundary before (that is why it got cached) but is not anymore
353+ // // after collapse
354+ // return false;
355+ // }
356+ // }
357+ }
358+
359+ if (VA.at (v2_id).m_is_on_open_boundary ) {
360+ // check if boundary edges are topologically still boundaries
361+ if (!is_vertex_on_boundary (v2_id)) {
362+ VA[v2_id].m_is_on_open_boundary = false ;
365363 }
366364 }
367365
366+
368367 // // update attrs
369368 // tet attr
370369 for (int i = 0 ; i < cache.changed_tids .size (); i++) {
371370 m_tet_attribute[cache.changed_tids [i]].m_quality = cache.changed_energies [i];
372371 }
373372 // vertex attr
374373 round (loc);
375- VA[v2_id].m_is_on_surface = VA[ v1_id] .m_is_on_surface || VA[ v2_id] .m_is_on_surface ;
374+ VA[v2_id].m_is_on_surface = VA. at ( v1_id) .m_is_on_surface || VA. at ( v2_id) .m_is_on_surface ;
376375
377376 // no need to update on_bbox_faces
378377 // face attr
@@ -382,8 +381,6 @@ bool TetWildMesh::collapse_edge_after(const Tuple& loc)
382381 //
383382 auto [_, global_fid] = tuple_from_face ({{v2_id, old_vids[1 ], old_vids[2 ]}});
384383 if (global_fid == -1 ) {
385- // if (debug_flag) std::cout << "whatever reject" << std::endl;
386-
387384 return false ;
388385 }
389386 m_face_attribute[global_fid] = f_attr;
@@ -968,63 +965,6 @@ bool TetWildMesh::collapse_edge_after(const Tuple& loc)
968965 }
969966 }
970967
971- // test code
972- // check global number nonmanifold vertex
973-
974- // size_t nonmani_ver_cnt = 0;
975- // for (auto v : get_vertices()) {
976- // if (m_vertex_attribute[v.vid(*this)].m_is_on_surface) {
977- // if (count_vertex_links(v) > 1) {
978- // nonmani_ver_cnt++;
979- // }
980- // }
981- // }
982- // if (nonmani_ver_cnt != cache.global_nonmani_ver_cnt) {
983- // wmtk::logger().info(
984- // "COLLAPSE EDGE CAUSE NONMANIFOLDNESS CHANGE ON VERTICE. BEFORE COUNT: {} AFTER COUNT:
985- // "
986- // "{}",
987- // cache.global_nonmani_ver_cnt,
988- // nonmani_ver_cnt);
989- // }
990-
991- // geometry preservation
992- // if (m_params.preserve_geometry) {
993- // std::vector<size_t> after_edge_incident_param_type = wmtk::set_intersection(
994- // m_vertex_attribute[loc.vid(*this)].face_param_type,
995- // m_vertex_attribute[loc.switch_vertex(*this).vid(*this)].face_param_type,
996- // );
997-
998-
999- // }
1000-
1001- // //// update attrs
1002- // // tet attr
1003- // for (int i = 0; i < cache.changed_tids.size(); i++) {
1004- // m_tet_attribute[cache.changed_tids[i]].m_quality = qs[i];
1005- // }
1006- // // vertex attr
1007- // round(loc);
1008- // VA[v2_id].m_is_on_surface = VA[v1_id].m_is_on_surface || VA[v2_id].m_is_on_surface;
1009- // // open boundary
1010- // VA[v2_id].m_is_on_open_boundary =
1011- // VA[v1_id].m_is_on_open_boundary || VA[v2_id].m_is_on_open_boundary;
1012-
1013- // // no need to update on_bbox_faces
1014- // // face attr
1015- // for (auto& info : cache.changed_faces) {
1016- // auto& f_attr = info.first;
1017- // auto& old_vids = info.second;
1018- // //
1019- // auto [_, global_fid] = tuple_from_face({{v2_id, old_vids[1], old_vids[2]}});
1020- // if (global_fid == -1) {
1021- // // if (debug_flag) std::cout << "whatever reject" << std::endl;
1022-
1023- // return false;
1024- // }
1025- // m_face_attribute[global_fid] = f_attr;
1026- // }
1027-
1028968 return true ;
1029969}
1030970
0 commit comments