From 000b03b5958796486161d09e9df9054683ad82ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 6 Sep 2021 18:44:07 +0200 Subject: [PATCH] follow up of #5889 cherry-picking for autorefinement --- .../Output_builder_for_autorefinement.h | 296 ++++++++++++++---- .../test_autorefinement.cmd | 6 +- 2 files changed, 237 insertions(+), 65 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h index db57fbee53a..6e5b3a73705 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h @@ -245,7 +245,7 @@ public: CGAL_assertion(BGL::internal::is_index_map_valid(fids, num_faces(tm), faces(tm))); // bitset to identify coplanar faces - boost::dynamic_bitset<> tm_coplanar_faces(num_faces(tm), 0); + std::vector tm_coplanar_faces; // In the following loop we filter intersection edges that are strictly inside a patch // of coplanar facets so that we keep only the edges on the border of the patch. @@ -277,11 +277,6 @@ public: else{ halfedge_descriptor h2_opp = opposite(h2, tm); - if (is_border_edge(h1,tm) || is_border_edge(h2,tm)){ - ++epp_it; - continue; - } - //vertices from tm1 vertex_descriptor p1 = target(next(h1_opp, tm), tm); vertex_descriptor p2 = target(next(h1, tm), tm); @@ -315,20 +310,20 @@ public: //mark coplanar facets if any if (p1_eq_q1){ - tm_coplanar_faces.set(get(fids, face(h1_opp, tm))); - tm_coplanar_faces.set(get(fids, face(h2_opp, tm))); + tm_coplanar_faces.push_back(face(h1_opp, tm)); + tm_coplanar_faces.push_back(face(h2_opp, tm)); } if (p1_eq_q2){ - tm_coplanar_faces.set(get(fids, face(h1_opp, tm))); - tm_coplanar_faces.set(get(fids, face(h2, tm))); + tm_coplanar_faces.push_back(face(h1_opp, tm)); + tm_coplanar_faces.push_back(face(h2, tm)); } if (p2_eq_q1){ - tm_coplanar_faces.set(get(fids, face(h1, tm))); - tm_coplanar_faces.set(get(fids, face(h2_opp, tm))); + tm_coplanar_faces.push_back(face(h1, tm)); + tm_coplanar_faces.push_back(face(h2_opp, tm)); } if (p2_eq_q2){ - tm_coplanar_faces.set(get(fids, face(h1, tm))); - tm_coplanar_faces.set(get(fids, face(h2, tm))); + tm_coplanar_faces.push_back(face(h1, tm)); + tm_coplanar_faces.push_back(face(h2, tm)); } if ( (p1_eq_q1 || p1_eq_q2) && (p2_eq_q1 || p2_eq_q2) ) to_remove = true; @@ -368,6 +363,12 @@ public: boost::dynamic_bitset<> coplanar_patches(nb_patches,false); patches_to_keep.set(); patch_status_not_set.set(); + + // set coplanar patches flags + for (face_descriptor f : tm_coplanar_faces) + coplanar_patches.set( patch_ids[get(fids,f)] ); + + // use a union-find on patches to track the incidence between patches kept typedef Union_find UF; UF uf; @@ -404,10 +405,25 @@ public: if ( is_border_edge(h1, tm) ){ if ( is_border_edge(h2,tm) ) { + // CASE h1 and h2 are boundary edge if ( is_border(h1,tm) == is_border(h2,tm) ) { - //Orientation issue, nothing done - all_fixed = false; + std::size_t pid1 = + patch_ids[ get(fids, face( is_border(h1,tm)?opposite(h1,tm):h1 ,tm)) ]; + if (coplanar_patches[pid1]) + { + std::size_t pid2 = + patch_ids[ get(fids, face( is_border(h2,tm)?opposite(h2,tm):h2 ,tm)) ]; + CGAL_assertion(coplanar_patches[pid2]); + // the face of p and the face of q1 have the same orientation: remove both patches + patches_to_keep.reset(pid1); + patches_to_keep.reset(pid2); + } + else + { + //Orientation issue, nothing done + all_fixed = false; + } } else { @@ -415,22 +431,42 @@ public: { std::size_t pid1=patch_ids[ get(fids, face(opposite(h1,tm),tm)) ], pid2=patch_ids[ get(fids, face(h2,tm)) ]; - uf.unify_sets(patch_handles[pid1], patch_handles[pid2]); - patch_status_not_set.reset(pid1); - patch_status_not_set.reset(pid2); + + if (coplanar_patches[pid1]) + { + CGAL_assertion(coplanar_patches[pid2]); + // arbitrarily remove the patch with the smallest id + patches_to_keep.reset(pid1