diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 4055b6a31523..e1842775fca9 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -697,6 +697,32 @@ make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) return opposite(h2,g); } +/// \cond SKIP_IN_DOC +template +bool is_degenerate_triangle_face( + typename boost::graph_traits::halfedge_descriptor hd, + TriangleMesh& tmesh, + const VertexPointMap& vpmap, + const Traits& traits) +{ + CGAL_assertion(!is_border(hd, tmesh)); + + const typename Traits::Point_3& p1 = get(vpmap, target( hd, tmesh) ); + const typename Traits::Point_3& p2 = get(vpmap, target(next(hd, tmesh), tmesh) ); + const typename Traits::Point_3& p3 = get(vpmap, source( hd, tmesh) ); + return traits.collinear_3_object()(p1, p2, p3); +} + +template +bool is_degenerate_triangle_face( + typename boost::graph_traits::face_descriptor fd, + TriangleMesh& tmesh, + const VertexPointMap& vpmap, + const Traits& traits) +{ + return is_degenerate_triangle_face(halfedge(fd,tmesh), tmesh, vpmap, traits); +} +/// \endcond namespace internal { @@ -725,7 +751,7 @@ clear_impl(FaceGraph& g) } } -} +} //end of internal namespace /** * \ingroup PkgBGLHelperFct diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h index dc02bcb7dd4e..c903be8333c2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h @@ -198,8 +198,8 @@ namespace Polygon_mesh_processing { } //face index map given as a named parameter, or as an internal property map - FIMap fim = choose_param(get_param(np, CGAL::face_index), - get_const_property_map(CGAL::face_index, pmesh)); + FIMap fim = boost::choose_param(get_param(np, CGAL::face_index), + get_const_property_map(CGAL::face_index, pmesh)); return internal::border_halfedges_impl(faces, fim, out, pmesh, np); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index 705ba2adc585..1cc413af89d0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -308,7 +308,9 @@ namespace internal { BOOST_FOREACH(face_descriptor f, face_range) { - input_triangles_.push_back(triangle(f)); + Triangle_3 t = triangle(f); + if (t.is_degenerate()) continue; + input_triangles_.push_back(t); input_patch_ids_.push_back(get_patch_id(f)); } CGAL_assertion(input_triangles_.size() == input_patch_ids_.size()); @@ -1510,7 +1512,7 @@ namespace internal { { if (is_border(h, mesh_)) continue; - if (PMP::is_degenerated(h, mesh_, vpmap_, GeomTraits())) + if (is_degenerate_triangle_face(h, mesh_, vpmap_, GeomTraits())) degenerate_faces.insert(h); } while(!degenerate_faces.empty()) @@ -1518,7 +1520,7 @@ namespace internal { halfedge_descriptor h = *(degenerate_faces.begin()); degenerate_faces.erase(degenerate_faces.begin()); - if (!PMP::is_degenerated(h, mesh_, vpmap_, GeomTraits())) + if (!is_degenerate_triangle_face(h, mesh_, vpmap_, GeomTraits())) //this can happen when flipping h has consequences further in the mesh continue; @@ -1570,10 +1572,10 @@ namespace internal { } if (!is_border(hf, mesh_) - && PMP::is_degenerated(hf, mesh_, vpmap_, GeomTraits())) + && is_degenerate_triangle_face(hf, mesh_, vpmap_, GeomTraits())) degenerate_faces.insert(hf); if (!is_border(hfo, mesh_) - && PMP::is_degenerated(hfo, mesh_, vpmap_, GeomTraits())) + && is_degenerate_triangle_face(hfo, mesh_, vpmap_, GeomTraits())) degenerate_faces.insert(hfo); break; @@ -1592,7 +1594,7 @@ namespace internal { { if (is_border(h, mesh_)) continue; - if (PMP::is_degenerated(h, mesh_, vpmap_, GeomTraits())) + if (is_degenerate_triangle_face(h, mesh_, vpmap_, GeomTraits())) return true; } return false; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index 662f8f16c2b7..d4360a694edd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -57,7 +57,8 @@ namespace Polygon_mesh_processing { * * @param pmesh a polygon mesh with triangulated surface patches to be remeshed * @param faces the range of triangular faces defining one or several surface patches to be remeshed -* @param target_edge_length the edge length that is targetted in the remeshed patch +* @param target_edge_length the edge length that is targetted in the remeshed patch. +* If `0` is passed then only the edge-flip, tangential relaxation, and projection steps will be done. * @param np optional sequence of \ref namedparameters among the ones listed below * * @pre if constraints protection is activated, the constrained edges should @@ -230,9 +231,11 @@ void isotropic_remeshing(const FaceRange& faces #ifdef CGAL_PMP_REMESHING_VERBOSE std::cout << " * Iteration " << (i + 1) << " *" << std::endl; #endif - - remesher.split_long_edges(high); - remesher.collapse_short_edges(low, high); + if (target_edge_length>0) + { + remesher.split_long_edges(high); + remesher.collapse_short_edges(low, high); + } remesher.equalize_valences(); remesher.tangential_relaxation(smoothing_1d, nb_laplacian); remesher.project_to_surface(); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h index a4bea8a6e846..300f0d92d3b3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -126,30 +126,7 @@ struct Less_along_ray{ } }; -template -bool is_degenerated( - typename boost::graph_traits::halfedge_descriptor hd, - TriangleMesh& tmesh, - const VertexPointMap& vpmap, - const Traits& traits) -{ - CGAL_assertion(!is_border(hd, tmesh)); - const typename Traits::Point_3& p1 = get(vpmap, target( hd, tmesh) ); - const typename Traits::Point_3& p2 = get(vpmap, target(next(hd, tmesh), tmesh) ); - const typename Traits::Point_3& p3 = get(vpmap, source( hd, tmesh) ); - return traits.collinear_3_object()(p1, p2, p3); -} - -template -bool is_degenerated( - typename boost::graph_traits::face_descriptor fd, - TriangleMesh& tmesh, - const VertexPointMap& vpmap, - const Traits& traits) -{ - return is_degenerated(halfedge(fd,tmesh), tmesh, vpmap, traits); -} ///\cond SKIP_IN_MANUAL @@ -163,7 +140,7 @@ degenerate_faces(const TriangleMesh& tm, typedef typename boost::graph_traits::face_descriptor face_descriptor; BOOST_FOREACH(face_descriptor fd, faces(tm)) { - if ( is_degenerated(fd, tm, vpmap, traits) ) + if ( is_degenerate_triangle_face(fd, tm, vpmap, traits) ) *out++=fd; } return out; @@ -698,7 +675,7 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh, // Then, remove triangles made of 3 collinear points std::set degenerate_face_set; BOOST_FOREACH(face_descriptor fd, faces(tmesh)) - if ( is_degenerated(fd, tmesh, vpmap, traits) ) + if ( is_degenerate_triangle_face(fd, tmesh, vpmap, traits) ) degenerate_face_set.insert(fd); nb_deg_faces+=degenerate_face_set.size(); @@ -778,14 +755,15 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh, { face_descriptor adjacent_face = face( opposite(hd, tmesh), tmesh ); if ( adjacent_face==GT::null_face() || - !degenerate_face_set.count(adjacent_face) ) + degenerate_face_set.count(adjacent_face)==0 ) boundary_hedges.push_back(hd); else + { if (cc_faces.insert(adjacent_face).second) - { - inside_hedges.push_back(hd); queue.push_back(adjacent_face); - } + if ( hd < opposite(hd, tmesh) ) + inside_hedges.push_back(hd); + } } } @@ -853,9 +831,10 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh, } // remove degenerate faces BOOST_FOREACH(face_descriptor f, cc_faces) + { degenerate_face_set.erase(f); - BOOST_FOREACH(face_descriptor f, cc_faces) remove_face(f, tmesh); + } // remove interior edges BOOST_FOREACH(halfedge_descriptor h, inside_hedges) remove_edge(edge(h, tmesh), tmesh); @@ -941,7 +920,7 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh, // since we reuse later the halfedge of the first refernce vertex // we must set it as we need. if ( source(h2,tmesh) == *ref_vertices.first) - set_halfedge(*ref_vertices.first, opposite( prev(side_two[hi], tmesh), tmesh), tmesh ); + set_halfedge(*ref_vertices.first, opposite( h2, tmesh), tmesh ); // retriangulate the face if ( face(h2, tmesh) != GT::null_face()) Euler::split_face(h2, next(side_two[hi], tmesh), tmesh); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index d39b2e9f2182..95d82ce1fea6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -2023,7 +2023,7 @@ bool Scene_polyhedron_selection_item_priv::canAddFace(Halfedge_handle hc, Halfed boost::graph_traits::halfedge_descriptor res = CGAL::Euler::add_face_to_border(t,hc, *item->polyhedron()); - if(PMP::is_degenerated(res, *item->polyhedron(), get(CGAL::vertex_point, *item->polyhedron()), Kernel())) + if(CGAL::is_degenerate_triangle_face(res, *item->polyhedron(), get(CGAL::vertex_point, *item->polyhedron()), Kernel())) { CGAL::Euler::remove_face(res, *item->polyhedron()); tempInstructions("Edge not selected : resulting facet is degenerated.", diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h index 38a759eb91ac..5af0d66db33f 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/statistics_helpers.h @@ -90,7 +90,7 @@ unsigned int nb_degenerate_faces(Polyhedron* poly, VPmap vpmap) unsigned int nb = 0; BOOST_FOREACH(face_descriptor f, faces(*poly)) { - if (CGAL::Polygon_mesh_processing::is_degenerated(f, *poly, vpmap, Kernel())) + if (CGAL::is_degenerate_triangle_face(f, *poly, vpmap, Kernel())) ++nb; } return nb;