From e417a32a9f3b0784311ecdb7912241545b51ba8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Mar 2024 18:36:34 +0100 Subject: [PATCH] doc improvements --- .../PackageDescription.txt | 3 +- .../Polygon_mesh_processing.txt | 24 ++- .../Polygon_mesh_processing/acvd_example.cpp | 4 +- .../CGAL/Polygon_mesh_processing/acvd/acvd.h | 162 +++++++----------- 4 files changed, 73 insertions(+), 120 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 6fcc71621c5..4d50b86cfb8 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -139,8 +139,7 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::random_perturbation()` \cgalCRPSection{ACVD Simplification Functions} -- \link PMP_acvd_grp `CGAL::Polygon_mesh_processing::acvd_isotropic_simplification()` \endlink -- \link PMP_acvd_grp `CGAL::Polygon_mesh_processing::acvd_isotropic_simplification_polygon_soup()` \endlink +- \link PMP_acvd_grp `CGAL::Polygon_mesh_processing::acvd_isotropic_remeshing()` \endlink \cgalCRPSection{Sizing Fields} - `CGAL::Polygon_mesh_processing::Uniform_sizing_field` diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index af6cd3bbb62..76212ba5b67 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -53,7 +53,7 @@ mesh, which includes point location and self intersection tests. - \ref PMPSlicer : functor able to compute the intersections of a polygon mesh with arbitrary planes (slicer). - \ref PMPConnectedComponents : methods to deal with connected components of a polygon mesh (extraction, marks, removal, ...). -- \ref PMPACVD : methods to simplify or remesh a polygon mesh using approximated centroidal Voronoi diagrams +- \ref PMPACVD : methods to remesh a polygon mesh using approximated centroidal Voronoi diagrams as described in \cgalCite{cgal:vcp-grtmmdvd-08} and preceeding work. \subsection PMPIO Reading and Writing Polygon Meshes @@ -1313,10 +1313,10 @@ which enables to treat one or several connected components as a face graph. \cgalExample{Polygon_mesh_processing/face_filtered_graph_example.cpp} -\section PMPACVD ACVD Simplification and Remeshing +\section PMPACVD ACVD Remeshing -The Approximated Centroidal Voronoi Diagram (ACVD) package is a set of vertex-clustering-based tools to simplify -and remesh a polygon mesh. It is based on the method introduced in \cgalCite{cgal:vc-acvdupmc-04} and extended +The Approximated Centroidal Voronoi Diagram (ACVD) package is a set of vertex-clustering-based tools to +remesh a triangle mesh. It is based on the method introduced in \cgalCite{cgal:vc-acvdupmc-04} and extended in \cgalCite{cgal:vkc-apmsdcvd-05} and \cgalCite{cgal:vcp-grtmmdvd-08}. \subsection ACVDBackground Brief Background @@ -1328,16 +1328,14 @@ WIP The implementation is generic in terms of mesh data structure. It can be used on `Surface_mesh`, `Polyhedron_3` and other triangle mesh structures based on the concept `FaceGraph`. -The main function is `CGAL::Polygon_mesh_processing::acvd_isotropic_simplification()`. It takes as input a triangle mesh and -a target number of vertices and returns a remeshed version of the input mesh with the target number of vertices. - -The returned mesh can be triangle mesh in the same data structure as the input mesh representing a `FaceGraph`. -Or a polygon (triangle) soup (as a `pair, std::vector>>)`. For the latter, -use the function `CGAL::Polygon_mesh_processing::acvd_isotropic_simplification_polygon_soup()` instead. The reason for -having a polygon soup version is that there are no guarantees that the output mesh is manifold. +The main function is `CGAL::Polygon_mesh_processing::acvd_isotropic_remeshing()`. It takes as input a triangle mesh and +a lower bound on the target number of vertices and returns a remeshed version. The number of vertices in the output mesh +might be larger than the input parameters if the input is not closed or if the budget of points provided is too low +to generate a manifold output mesh. Note that providing a initial low number of vertices will affect the uniformity +of the output triangles in case some extra points are added to make the output manifold. To enable Adaptive Remeshing, the named parameter `gradation_factor` can be used. It controls the sensitivity of the -clustering algorithm to curvature. If a value of 0 is used, the algorithm is not adaptive. Moreover, the named parameter +clustering algorithm to curvature. Moreover, the named parameter `vertex_principal_curvatures_and_directions_map` can be used to provide a user-defined principal curvature map. For Clustering based on QEM, the function `CGAL::Polygon_mesh_processing::acvd_qem_simplification()` and @@ -1350,7 +1348,7 @@ WIP \subsection ACVDExample Usage Example -The example below shows the usage of the `CGAL::Polygon_mesh_processing::acvd_isotropic_simplification()` function +The example below shows the usage of the `CGAL::Polygon_mesh_processing::acvd_isotropic_remeshing()` function and how the extra named parameters can be passed. \cgalExample{Polygon_mesh_processing/acvd_example.cpp} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/acvd_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/acvd_example.cpp index 41da1260f24..c6a65b3b414 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/acvd_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/acvd_example.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) std::cout << "Uniform Isotropic ACVD ...." << std::endl; - auto acvd_mesh = PMP::acvd_isotropic_simplification(smesh, nb_clusters); + auto acvd_mesh = PMP::acvd_isotropic_remeshing(smesh, nb_clusters); CGAL::IO::write_OFF("fandisk_qem-pp3000.off", acvd_mesh); std::cout << "Completed" << std::endl; @@ -62,7 +62,7 @@ int main(int argc, char* argv[]) //PMP::interpolated_corrected_curvatures(smesh, CGAL::parameters::vertex_principal_curvatures_and_directions_map(principal_curvatures_and_directions_map)); //auto adaptive_acvd_mesh = - // PMP::acvd_isotropic_simplification( + // PMP::acvd_isotropic_remeshing( // smesh, // nb_clusters, // CGAL::parameters::vertex_principal_curvatures_and_directions_map(principal_curvatures_and_directions_map) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/acvd/acvd.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/acvd/acvd.h index 5b0b8479525..dbdb7ef8402 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/acvd/acvd.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/acvd/acvd.h @@ -220,11 +220,11 @@ struct IsotropicClusterData { } }; -template -void upsample_subdivision_property(PolygonMesh& pmesh, const NamedParameters& np = parameters::default_values()) { - typedef typename GetGeomTraits::type GT; - typedef typename boost::graph_traits::vertex_descriptor Vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor Halfedge_descriptor; +template +void upsample_subdivision_property(TriangleMesh& pmesh, const NamedParameters& np = parameters::default_values()) { + typedef typename GetGeomTraits::type GT; + typedef typename boost::graph_traits::vertex_descriptor Vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor Halfedge_descriptor; typedef Constant_property_map> Default_principal_map; typedef typename internal_np::Lookup_named_param_def::type VPM; + typedef typename CGAL::GetVertexPointMap::type VPM; VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(CGAL::vertex_point, pmesh)); @@ -249,7 +249,7 @@ void upsample_subdivision_property(PolygonMesh& pmesh, const NamedParameters& np bool curvatures_available = !is_default_parameter::value; unsigned int step = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 1); - Upsample_mask_3 mask(&pmesh, vpm); + Upsample_mask_3 mask(&pmesh, vpm); for (unsigned int i = 0; i < step; i++){ for (Vertex_descriptor vd : vertices(pmesh)) @@ -291,26 +291,26 @@ void upsample_subdivision_property(PolygonMesh& pmesh, const NamedParameters& np } } -template std::pair< - std::vector::type::Point_3>, + std::vector::type::Point_3>, std::vector> > acvd_isotropic( - PolygonMesh& pmesh, + TriangleMesh& pmesh, const int nb_clusters, const NamedParameters& np = parameters::default_values() ) { - typedef typename GetGeomTraits::type GT; - typedef typename GetVertexPointMap::const_type Vertex_position_map; - typedef typename boost::graph_traits::halfedge_descriptor Halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor Vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor Face_descriptor; - typedef typename boost::property_map >::type VertexColorMap; - typedef typename boost::property_map >::type VertexClusterMap; - typedef typename boost::property_map >::type VertexVisitedMap; - typedef typename boost::property_map >::type VertexWeightMap; + typedef typename GetGeomTraits::type GT; + typedef typename GetVertexPointMap::const_type Vertex_position_map; + typedef typename boost::graph_traits::halfedge_descriptor Halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor Vertex_descriptor; + typedef typename boost::graph_traits::face_descriptor Face_descriptor; + typedef typename boost::property_map >::type VertexColorMap; + typedef typename boost::property_map >::type VertexClusterMap; + typedef typename boost::property_map >::type VertexVisitedMap; + typedef typename boost::property_map >::type VertexWeightMap; typedef Constant_property_map> Default_principal_map; typedef typename internal_np::Lookup_named_param_def points; std::vector> polygons; - PolygonMesh simplified_mesh; + TriangleMesh simplified_mesh; // create a point for each cluster std::vector> cluster_quadrics(clusters.size()); @@ -806,104 +806,51 @@ std::pair< } // namespace internal -/** -* \ingroup PMP_acvd_grp -* -* Performs uniform (isotropic) centroidal voronoi diagram simplification on a polygon mesh. -* This can also be used for remeshing by setting the number of clusters to the desired number of vertices. -* The number of clusters is the number of vertices in the output mesh. -* -* @tparam PolygonMesh a model of `FaceListGraph` -* @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters". -* -* @param pmesh input polygon mesh -* @param nb_vertices number of target vertices in the output mesh -* @param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below -* `GT` stands for the type of the object provided to the named parameter `geom_traits()`. -* -* \cgalNamedParamsBegin -* -* \cgalParamNBegin{vertex_principal_curvatures_and_directions_map} -* \cgalParamDescription{a property map associating principal curvatures and directions to the vertices of `pmesh`, used for adaptive clustering.} -* \cgalParamType{a class model of `ReadWritePropertyMap` with -* `boost::graph_traits::%vertex_descriptor` -* as key type and `Principal_curvatures_and_directions` as value type.} -* \cgalParamExtra{If this parameter is omitted, but `gradation_factor` is not (and is > 0), an internal property map -* will be created and curvature values will be computed.} -* \cgalParamNEnd -* -* \cgalParamNBegin{gradation_factor} -* \cgalParamDescription{a factor used to gradate the weights of the vertices based on their curvature values.} -* \cgalParamType{`GT::FT`} -* \cgalParamDefault{0} -* \cgalParamExtra{If this parameter is omitted, no adaptive clustering will be performed.} -* \cgalParamNEnd -* -* \cgalParamNBegin{vertex_point_map} -* \cgalParamDescription{a property map associating points to the vertices of `pmesh`.} -* \cgalParamType{a class model of `ReadablePropertyMap` with -* `boost::graph_traits::%vertex_descriptor` -* as key type and `GT::Point_3` as value type.} -* \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`.} -* \cgalParamExtra{If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` must be available in `PolygonMesh`.} -* \cgalParamNEnd -* -* \cgalParamNBegin{geom_traits} -* \cgalParamDescription{an instance of a geometric traits class.} -* \cgalParamType{a class model of `Kernel`} -* \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`.} -* \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} -* \cgalParamNEnd -* -* \cgalNamedParamsEnd -* -* @pre only triangle meshes are supported for now -* @return a pair of vectors of points and polygons representing the simplified mesh as a polygon soup -*/ - -template std::pair< - std::vector::type::Point_3>, + std::vector::type::Point_3>, std::vector> > acvd_isotropic_simplification_polygon_soup( - PolygonMesh& pmesh, + TriangleMesh& tmesh, const int& nb_vertices, const NamedParameters& np = parameters::default_values() ) { - return internal::acvd_isotropic( - pmesh, + return internal::acvd_isotropic( + tmesh, nb_vertices, np ); } +#endif /** * \ingroup PMP_acvd_grp * -* Performs uniform (isotropic) centroidal voronoi diagram simplification on a polygon mesh. -* This can also be used for remeshing by setting the number of clusters to the desired number of vertices. -* The number of clusters is the number of vertices in the output mesh. +* performs isotropic centroidal voronoi diagram remeshing on a triangle mesh. The remeshing is either uniform or adaptative. * -* @tparam PolygonMesh a model of `FaceListGraph` +* @tparam TriangleMesh a model of `FaceListGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters". * -* @param pmesh input polygon mesh -* @param nb_vertices number of target vertices in the output mesh +* @param tmesh input triangle mesh +* @param nb_vertices lower bound on the number of target vertices in the output mesh. +* In the case the mesh is not closed or if the number of points is too low +* and no manifold mesh could be produced with that budget of points, extra points +* are added to get a manifold output. * @param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * `GT` stands for the type of the object provided to the named parameter `geom_traits()`. * * \cgalNamedParamsBegin * * \cgalParamNBegin{vertex_principal_curvatures_and_directions_map} -* \cgalParamDescription{a property map associating principal curvatures and directions to the vertices of `pmesh`, used for adaptive clustering.} +* \cgalParamDescription{a property map associating principal curvatures and directions to the vertices of `tmesh`, used for adaptive clustering.} * \cgalParamType{a class model of `ReadWritePropertyMap` with -* `boost::graph_traits::%vertex_descriptor` +* `boost::graph_traits::%vertex_descriptor` * as key type and `Principal_curvatures_and_directions` as value type.} -* \cgalParamExtra{If this parameter is omitted, but `gradation_factor` is not (and is > 0), an internal property map -* will be created and curvature values will be computed.} +* \cgalParamExtra{If this parameter is omitted, but `gradation_factor` is provided, an internal property map +* will be created and curvature values will be computed using the function `interpolated_corrected_curvatures()` will be called to initialize it.} * \cgalParamNEnd * * \cgalParamNBegin{gradation_factor} @@ -914,13 +861,13 @@ std::pair< * \cgalParamNEnd * * \cgalParamNBegin{vertex_point_map} -* \cgalParamDescription{a property map associating points to the vertices of `pmesh`.} +* \cgalParamDescription{a property map associating points to the vertices of `tmesh`.} * \cgalParamType{a class model of `ReadablePropertyMap` with -* `boost::graph_traits::%vertex_descriptor` +* `boost::graph_traits::%vertex_descriptor` * as key type and `GT::Point_3` as value type.} -* \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`.} +* \cgalParamDefault{`boost::get(CGAL::vertex_point, tmesh)`.} * \cgalParamExtra{If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` must be available in `PolygonMesh`.} +* `CGAL::vertex_point_t` must be available in `TriangleMesh`.} * \cgalParamNEnd * * \cgalParamNBegin{geom_traits} @@ -933,24 +880,30 @@ std::pair< * \cgalNamedParamsEnd * * @pre only triangle meshes are supported for now -* @return the simplified mesh as a PolygonMesh +* @return the simplified mesh as a TriangleMesh +* +* @todo how is uniform affected by input mesh ? (check area based sampling?) +* @todo implement manifold version +* @todo how to handle output vertex point map */ -template -PolygonMesh acvd_isotropic_simplification( - PolygonMesh& pmesh, +template +TriangleMesh acvd_isotropic_remeshing( + TriangleMesh& tmesh, const int& nb_vertices, const NamedParameters& np = parameters::default_values() ) { auto ps = acvd_isotropic_simplification_polygon_soup( - pmesh, + tmesh, nb_vertices, np ); - PolygonMesh simplified_mesh; + CGAL_assertion(is_polygon_soup_a_polygon_mesh(ps.second)); + + TriangleMesh simplified_mesh; polygon_soup_to_polygon_mesh(ps.first, ps.second, simplified_mesh); return simplified_mesh; } @@ -959,3 +912,6 @@ PolygonMesh acvd_isotropic_simplification( } // namespace Polygon_mesh_processing } // namespace CGAL + +#undef CGAL_CLUSTERS_TO_VERTICES_THRESHOLD +#undef CGAL_WEIGHT_CLAMP_RATIO_THRESHOLD \ No newline at end of file