Skip to content

Commit 3ce1d15

Browse files
authored
Merge pull request #872 from wildmeshing/dzint/orig_tetwild
Fix TetWild smoothing
2 parents a1780a7 + 751736b commit 3ce1d15

File tree

16 files changed

+424
-305
lines changed

16 files changed

+424
-305
lines changed

components/tetwild/wmtk/components/tetwild/EdgeCollapsing.cpp

Lines changed: 27 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -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

components/tetwild/wmtk/components/tetwild/Parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct Parameters
2222

2323
double stop_energy = 10;
2424

25+
bool debug_output = false;
2526
bool perform_sanity_checks = false;
2627

2728
void init(const Vector3d& min_, const Vector3d& max_)

0 commit comments

Comments
 (0)