diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index 2944afcbb36..125b0cd9a91 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -2741,6 +2741,25 @@ pages = "207--221" publisher={Elsevier} } +@inproceedings{liu2008local, + title={A local/global approach to mesh parameterization}, + author={Liu, Ligang and Zhang, Lei and Xu, Yin and Gotsman, Craig and Gortler, Steven J}, + booktitle={Computer Graphics Forum}, + volume={27}, + number={5}, + pages={1495--1504}, + year={2008}, + organization={Wiley Online Library} +} + +@inproceedings{kami2005free, + title={Free-boundary linear parameterization of 3D meshes in the presence of constraints}, + author={Kami, Z and Gotsman, Craig and Gortler, Steven J}, + booktitle={International Conference on Shape Modeling and Applications 2005 (SMI'05)}, + pages={266--275}, + year={2005}, + organization={IEEE} +} % ---------------------------------------------------------------------------- % END OF BIBFILE diff --git a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/BorderParameterizer_3.h b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/BorderParameterizer_3.h index fb224642e1c..b6ed68bbb93 100644 --- a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/BorderParameterizer_3.h +++ b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/BorderParameterizer_3.h @@ -3,13 +3,13 @@ \ingroup PkgSurfaceParameterizationConcepts \cgalConcept -`BorderParameterizer_3` is a concept of class that parameterizes a given type of mesh, `TriangleMesh`, which is a model of the `FaceGraph` concept. +`BorderParameterizer_3` is a concept of class that parameterizes the border of +a given type of mesh, `TriangleMesh`, which is a model of the `FaceGraph` concept. +Some of the vertices (possibly all) of the mesh are assigned a 2D position on a +shape (a geometrical object). - -\cgalHasModel `CGAL::Circular_border_arc_length_parameterizer_3` -\cgalHasModel `CGAL::Circular_border_uniform_parameterizer_3` -\cgalHasModel `CGAL::Square_border_arc_length_parameterizer_3` -\cgalHasModel `CGAL::Square_border_uniform_parameterizer_3` +\cgalHasModel `CGAL::Circular_border_parameterizer_3` +\cgalHasModel `CGAL::Square_border_parameterizer_3` \cgalHasModel `CGAL::Two_vertices_parameterizer_3` \sa `ParameterizerTraits_3` @@ -19,38 +19,40 @@ class BorderParameterizer_3 { public: -/// \name Types +/// \name Types /// @{ /*! +A given polygon mesh type, TriangleMesh, which is a model of the `FaceGraph` concept. -*/ - typedef unspecified_type TriangleMesh; +*/ + typedef unspecified_type TriangleMesh; /*! -The various errors detected by this package. +The various errors detected by this package. -*/ -typedef unspecified_type Error_code; +*/ +typedef unspecified_type Error_code; -/// @} +/// @} -/// \name Operations +/// \name Operations /// @{ /*! -Assign to mesh's border vertices a 2D position (i.e.\ a `(u, v)` pair) on border's shape. Mark them as parameterized. Return false on error. +Assign a 2D position (i.e.\ a `(u, v)` pair) on the shape to (some of) the vertices on the +border of the mesh. Mark them as parameterized. -*/ -Error_code parameterize_border(const TriangleMesh& mesh); +*/ +Error_code parameterize_border(const TriangleMesh& mesh); /*! -Indicate if border's shape is convex. +Indicate if the shape is convex. -*/ -bool is_border_convex(); +*/ +bool is_border_convex(); /// @} diff --git a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/ParameterizerTraits_3.h b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/ParameterizerTraits_3.h index 7582245ead3..3e8a61d0bb4 100644 --- a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/ParameterizerTraits_3.h +++ b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/Concepts/ParameterizerTraits_3.h @@ -3,16 +3,17 @@ \ingroup PkgSurfaceParameterizationConcepts \cgalConcept -`ParameterizerTraits_3` is a concept of parameterization object for a given type of mesh, `TriangleMesh`, which must be a model of the `FaceGraph` concept. +`ParameterizerTraits_3` is a concept of parameterization object for a given type +of mesh, `TriangleMesh`, which must be a model of the `FaceGraph` concept. +Creation +-------------- -Creation --------------- - -Construction and destruction are undefined. +Construction and destruction are undefined. \cgalHasModel `CGAL::Parameterizer_traits_3` \cgalHasModel `CGAL::Fixed_border_parameterizer_3` +\cgalHasModel `CGAL::ARAP_parameterizer_3` \cgalHasModel `CGAL::Barycentric_mapping_parameterizer_3` \cgalHasModel `CGAL::Discrete_authalic_parameterizer_3` \cgalHasModel `CGAL::Discrete_conformal_map_parameterizer_3` @@ -24,19 +25,19 @@ Construction and destruction are undefined. class ParameterizerTraits_3 { public: -/// \name Types +/// \name Types /// @{ /*! -Export the type of mesh to parameterize. +Export the type of mesh to parameterize. -*/ -typedef unspecified_type Adaptor; +*/ +typedef unspecified_type TriangleMesh; -/// @} +/// @} -/// \name Constants +/// \name Constants /// @{ /// List of errors detected by this package @@ -52,19 +53,19 @@ typedef unspecified_type Adaptor; ERROR_OUT_OF_MEMORY, ///< Not enough memory ERROR_WRONG_PARAMETER ///< A method received an unexpected parameter }; -/// @} +/// @} -/// \name Operations +/// \name Operations /// @{ /*! -Compute a one-to-one mapping from a triangular 3D surface `mesh` to a piece of the 2D space. The mapping is linear by pieces (linear in each triangle). The result is the (u, v) pair image of each vertex of the 3D surface. +Compute a one-to-one mapping from a triangular 3D surface `mesh` to a piece of the 2D space. The mapping is linear by pieces (linear in each triangle). The result is the (u, v) pair image of each vertex of the 3D surface. -\pre `mesh` must be a surface with one connected component and no hole. `mesh` must be a triangular mesh. +\pre `mesh` must be a surface with one connected component and no hole. `mesh` must be a triangular mesh. -*/ -Error_code parameterize(TriangleMesh& mesh); +*/ +Error_code parameterize(TriangleMesh& mesh); /// @} diff --git a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/PackageDescription.txt b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/PackageDescription.txt index 584e02df026..f593dea8d86 100644 --- a/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/PackageDescription.txt +++ b/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/PackageDescription.txt @@ -12,7 +12,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.2} -\cgalPkgDependsOn{\ref PkgSolverSummary} +\cgalPkgDependsOn{\ref PkgSolverSummary} \cgalPkgBib{cgal:sal-pptsm2} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{Polyhedron demo,polyhedron_3.zip} @@ -48,6 +48,7 @@ This \cgal package implements several parameterization methods: - `CGAL::Parameterizer_traits_3` - `CGAL::Fixed_border_parameterizer_3` +- `CGAL::ARAP_parameterizer_3` - `CGAL::Barycentric_mapping_parameterizer_3` - `CGAL::Discrete_authalic_parameterizer_3` - `CGAL::Discrete_conformal_map_parameterizer_3` @@ -62,18 +63,16 @@ each instance of a vertex along the border). This package implements all common border parameterization methods: - For fixed border methods: - - the user can select a border - parameterization among two common methods: uniform or - arc-length parameterizations. + - the user can select a border parameterization among two common methods: + uniform or arc-length parameterizations. - one convex shape specified by: - one shape among a set of standard ones (circle, square). -- For free border methods: at least two constraints (the pinned -vertices). +- For free border methods: at least two constraints (the pinned vertices). -- `CGAL::Circular_border_arc_length_parameterizer_3` - `CGAL::Circular_border_uniform_parameterizer_3` -- `CGAL::Square_border_arc_length_parameterizer_3` +- `CGAL::Circular_border_arc_length_parameterizer_3` - `CGAL::Square_border_uniform_parameterizer_3` +- `CGAL::Square_border_arc_length_parameterizer_3` - `CGAL::Two_vertices_parameterizer_3` ## Mesh ## diff --git a/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h index 1e47c5010a5..185ccc3b079 100644 --- a/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h @@ -1,3 +1,23 @@ +// Copyright (c) 2016 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : + #ifndef CGAL_ARAP_PARAMETERIZER_3_H #define CGAL_ARAP_PARAMETERIZER_3_H @@ -53,16 +73,53 @@ namespace CGAL { // Declaration // ------------------------------------------------------------------------------------ +/// \ingroup PkgSurfaceParameterizationMethods +/// +/// The class `ARAP_parameterizer_3` implements the +/// *Local/Global Approach to Mesh Parameterization* \cgalCite{liu2008local}. +/// +/// This parameterization allows the user to choose to give importance to angle preservation, +/// to shape preservation, or a balance of both. +/// A parameter λ is used to control whether the priority is given to angle +/// or to shape preservation: when λ = 0, the parameterization is +/// as-similar-as-possible (ASAP) and is equivalent to the (conforming) LSCM parameterization. +/// As λ grows, the shape preservation becomes more and more important, +/// yielding, when λ goes to infinity, a parameterization that is as-rigid-as-possible (ARAP). +/// +/// This is a free border parameterization. There is no need to map the border of the surface +/// onto a convex polygon. +/// When λ = 0, only two pinned vertices are needed to ensure a unique solution. +/// When λ is non-null, the border does not need to be parameterized and +/// a random vertex is pinned. +/// +/// If flips are present in the parameterization, a post-processing step is applied +/// using `CGAL::MVC_post_processor_3` +/// to attempt to obtain a valid final embedding. +/// +/// A one-to-one mapping is *not* guaranteed. +/// +/// \cgalModels `ParameterizerTraits_3` +/// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// \tparam BorderParameterizer_3 is a Strategy to parameterize the surface border. +/// \tparam SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
+/// Note: the system is *not* symmetric. +/// +/// \sa `CGAL::Parameterizer_traits_3` +/// \sa `CGAL::Fixed_border_parameterizer_3` +/// \sa `CGAL::Barycentric_mapping_parameterizer_3` +/// \sa `CGAL::Discrete_authalic_parameterizer_3` +/// \sa `CGAL::Discrete_conformal_map_parameterizer_3` +/// \sa `CGAL::LSCM_parameterizer_3` +/// \sa `CGAL::Mean_value_coordinates_parameterizer_3` + template < - class TriangleMesh, ///< a model of `FaceGraph` + class TriangleMesh, class BorderParameterizer_3 = Two_vertices_parameterizer_3, - ///< Strategy to parameterize the surface border. - ///< The minimum is to parameterize two vertices. class SparseLinearAlgebraTraits_d = Eigen_solver_traits< > // defaults to Eigen::BICGSTAB with Eigen_sparse_matrix - ///< Traits class to solve a sparse linear system. > class ARAP_parameterizer_3 : public Parameterizer_traits_3 @@ -101,7 +158,7 @@ private: typedef boost::unordered_set Vertex_set; typedef std::vector Faces_vector; - // Mesh_Adaptor_3 subtypes: + // Traits subtypes: typedef Parameterizer_traits_3 Traits; typedef typename Traits::NT NT; typedef typename Traits::Point_2 Point_2; @@ -141,15 +198,15 @@ private: // Private fields private: - /// Object that maps (at least two) border vertices onto a 2D space + /// %Object that maps (at least two) border vertices onto a 2D space Border_param m_borderParameterizer; /// Traits object to solve a sparse linear system Sparse_LA m_linearAlgebra; - /// Controlling parameter + /// Controlling parameters const NT m_lambda; - const NT m_lambda_tolerance; + const NT m_lambda_tolerance; // used to determine when we switch to full ARAP /// Energy minimization parameters const unsigned int m_iterations; @@ -232,6 +289,8 @@ private: return status; } + /// Parameterize the border. The number of fixed vertices depends on the value + /// of the parameter λ. template Error_code parameterize_border(const TriangleMesh& mesh, const Vertex_set& vertices, @@ -409,7 +468,7 @@ private: return status; } - /// Solves the equation a3 x^3 + a2 x^2 + a1 x + a0 = 0. + /// Solves the cubic equation a3 x^3 + a2 x^2 + a1 x + a0 = 0. int solve_cubic_equation(const NT a3, const NT a2, const NT a1, const NT a0, std::vector& roots) const { @@ -431,7 +490,7 @@ private: return roots.size(); } - /// Solves the equation a3 x^3 + a2 x^2 + a1 x + a0 = 0 using CGAL's algeabric kernel. + /// Solves the equation a3 x^3 + a2 x^2 + a1 x + a0 = 0, using CGAL's algeabric kernel. int solve_cubic_equation_with_AK(const NT a3, const NT a2, const NT a1, const NT a0, std::vector& roots) const @@ -806,7 +865,7 @@ private: return Base::OK; } - /// Compute the coefficient b_ij = (i, j) of the matrix B, + /// Compute the coefficient b_ij = (i, j) of the right hand side vector B, /// for j neighbor vertex of i. void compute_b_ij(const TriangleMesh& mesh, halfedge_descriptor hd, @@ -876,7 +935,7 @@ private: std::cout << "xy: " << x << " " << y << std::endl; } - /// Compute the line i of vectors Bu and Bv + /// Compute the line i of right hand side vectors Bu and Bv /// - call compute_b_ij() for each neighbor v_j to compute the B coefficient b_i /// /// \pre Vertices must be indexed. @@ -922,6 +981,8 @@ private: } /// Compute the entries of the right hand side of the ARAP linear system. + /// + /// \pre Vertices must be indexed. template @@ -960,6 +1021,8 @@ private: return status; } + /// Compute the right hand side and solve the linear system to obtain the + /// new UV coordinates. template @@ -1130,8 +1193,43 @@ private: return Base::OK; } + /// Compute the quality of the parameterization. + void compute_quality(const TriangleMesh& mesh, + const Faces_vector& faces) const + { + + BOOST_FOREACH(face_descriptor fd, faces){ + // compute the jacobian + + // compute the singular values + } + + } + // Public operations public: + /// Compute a mapping from a triangular 3D surface mesh to a piece of the 2D space. + /// The mapping is piecewise linear (linear in each triangle). + /// The result is the (u,v) pair image of each vertex of the 3D surface. + /// + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexIndexMap must be a property map that associates a unique integer index + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexParameterizedMap must be a property map that associates a boolean + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param mesh a triangulated surface. + /// \param bhd an halfedge descriptor on the boundary of `mesh`. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vimap an instanciation of the class `VertexIndexMap`. + /// \param vpmap an instanciation of the class `VertexParameterizedMap`. + /// + /// \pre `mesh` must be a surface with one connected component. + /// \pre `mesh` must be a triangular mesh. + /// \pre The vertices must be indexed (vimap must be initialized). + /// template @@ -1211,8 +1309,8 @@ public: return status; // energy based termination - if(m_tolerance > 0.0 && ite <= m_iterations) // if tolerance <= 0 then don't compute energy - { // also no need compute energy if this iteration is the last iteration + if(m_tolerance > 0.0 && ite <= m_iterations) // if tolerance <= 0, don't compute energy + { // also no need compute energy if this iteration is the last iteration double energy_diff = std::abs((energy_last - energy_this) / energy_this); if(energy_diff < m_tolerance){ std::cout << "Minimization process over after: " @@ -1233,13 +1331,19 @@ public: public: /// Constructor + /// + /// \param border_param %Object that maps the surface's border to the 2D space. + /// \param sparse_la %Traits object to access a sparse linear system. + /// \param lambda Parameter to give importance to shape or angle preservation. + /// \param iterations Maximal number of iterations in the energy minimization process. + /// \param tolerance Minimal energy difference between two iterations for the minimization + /// process to continue. + /// ARAP_parameterizer_3(Border_param border_param = Border_param(), - ///< Object that maps the surface's border to 2D space Sparse_LA sparse_la = Sparse_LA(), - ///< Traits object to access a sparse linear system - NT lambda = 1, + NT lambda = 0., unsigned int iterations = 10, - NT tolerance = 1e-4) + NT tolerance = 1e-6) : m_borderParameterizer(border_param), m_linearAlgebra(sparse_la), diff --git a/Surface_mesh_parameterization/include/CGAL/Barycentric_mapping_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Barycentric_mapping_parameterizer_3.h index f119ac376ad..4fc65d9d7f9 100644 --- a/Surface_mesh_parameterization/include/CGAL/Barycentric_mapping_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Barycentric_mapping_parameterizer_3.h @@ -32,33 +32,33 @@ namespace CGAL { -/// \ingroup PkgSurfaceParameterizationMethods +/// \ingroup PkgSurfaceParameterizationMethods /// -/// The class Barycentric_mapping_parameterizer_3 implements Tutte Barycentric Mapping algorithm \cgalCite{t-hdg-63}. -/// This algorithm is also called Tutte Uniform Weights by other authors. +/// The class Barycentric_mapping_parameterizer_3 implements Tutte Barycentric +/// Mapping algorithm \cgalCite{t-hdg-63}. This algorithm is also called +/// Tutte Uniform Weights by other authors. /// -/// One-to-one mapping is guaranteed if the surface's border is mapped to a convex polygon. +/// A one-to-one mapping is guaranteed if the surface's border is mapped to a convex polygon. /// -/// This class is used by the main -/// parameterization algorithm Fixed_border_parameterizer_3::parameterize(). -/// - It provides default BorderParameterizer_3 and SparseLinearAlgebraTraits_d template -/// parameters. -/// - It implements compute_w_ij() to compute `w_ij = (i,j)` coefficient of matrix A -/// for `j` neighbor vertex of `i` based on Tutte Barycentric Mapping method. -/// - It implements an optimized version of is_one_to_one_mapping(). +/// This class is a Strategy \cgalCite{cgal:ghjv-dpero-95} called by the main +/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it: +/// - provides the template parameters `BorderParameterizer_3` and `SparseLinearAlgebraTraits_d`. +/// - implements compute_w_ij() to compute `w_ij = (i,j)`, coefficient of +/// the matrix A for `j` neighbor vertex of `i`, based on Tutte Barycentric +/// Mapping method. /// /// \cgalModels `ParameterizerTraits_3` /// -/// -/// \tparam TriangleMesh a model of `FaceGraph` -/// \tparam BorderParameterizer_3 Strategy to parameterize the surface border. -/// \tparam SparseLinearAlgebraTraits_d Traits class to solve a sparse linear system. -/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` -/// does not remove (yet) border vertices from the system. +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// \tparam BorderParameterizer_3 is a Strategy to parameterize the surface border. +/// \tparam SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
+/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` +/// does not remove (yet) border vertices from the system. /*! \sa `CGAL::Parameterizer_traits_3` \sa `CGAL::Fixed_border_parameterizer_3` +\sa `CGAL::ARAP_parameterizer_3` \sa `CGAL::Discrete_authalic_parameterizer_3` \sa `CGAL::Discrete_conformal_map_parameterizer_3` \sa `CGAL::LSCM_parameterizer_3` @@ -108,7 +108,7 @@ protected: public: /// Constructor Barycentric_mapping_parameterizer_3(Border_param border_param = Border_param(), - ///< object that maps the surface's border to 2D space. + ///< %Object that maps the surface's border to 2D space. Sparse_LA sparse_la = Sparse_LA()) ///< Traits object to access a sparse linear system. : Fixed_border_parameterizer_3` -/// \sa `CGAL::Circular_border_uniform_parameterizer_3` - -template ///< a model of `FaceGraph` +/// +template class Circular_border_parameterizer_3 { // Public types @@ -69,13 +73,10 @@ private: // Public operations public: - /// Destructor of base class should be virtual. - virtual ~Circular_border_parameterizer_3() { } - // Default constructor, copy constructor and operator =() are fine - /// Assign to mesh's border vertices a 2D position (i.e.\ a (u,v) pair) - /// on border's shape. Mark them as parameterized. + /// Assign to the mesh's border vertices a 2D position (i.e.\ a (u,v) pair) + /// on the circle. Mark them as parameterized. template Error_code parameterize_border(const TriangleMesh& mesh, @@ -86,7 +87,7 @@ public: VPM vpm = get(vertex_point, mesh); // TODO Nothing to do if no border //if (! is_border(bhd,tmesh)){ - // return Parameterizer_traits_3::ERROR_BORDER_TOO_SHORT; + // return Parameterizer_traits_3::ERROR_BORDER_TOO_SHORT; //} // Compute the total border length @@ -117,9 +118,8 @@ public: } -/// Indicate if border's shape is convex. - bool is_border_convex () { return true; } - + /// Indicate if border's shape is convex. + bool is_border_convex() { return true; } private: /// Compute the total length of the border @@ -142,41 +142,41 @@ private: /// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods /// /// This class parameterizes the border of a 3D surface onto a circle, -/// with an arc-length parameterization: (u,v) values are -/// proportional to the length of border edges. -/// `Circular_border_parameterizer_3` implements most of the border parameterization -/// algorithm. +/// with an arc-length parameterization: the (u,v) values are proportional +/// to the length of border edges. +/// The class `Circular_border_parameterizer_3` implements most of the border +/// parameterization algorithm. /// /// \cgalModels `BorderParameterizer_3` /// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// /// \sa `CGAL::Circular_border_parameterizer_3` -/// \sa `CGAL::Circular_border_uniform_parameterizer_3` - -template ///< 3D surface - class Circular_border_arc_length_parameterizer_3 - : public Circular_border_parameterizer_3 +/// +template +class Circular_border_arc_length_parameterizer_3 + : public Circular_border_parameterizer_3 { - // Public types +// Public types public: // We have to repeat the types exported by superclass /// @cond SKIP_IN_MANUAL typedef TriangleMesh_ TriangleMesh; /// @endcond - // Private types +// Private types private: typedef typename Parameterizer_traits_3::Point_2 Point_2; typedef typename Parameterizer_traits_3::Vector_3 Vector_3; - - // Public operations +// Public operations public: typedef typename Circular_border_parameterizer_3::vertex_descriptor vertex_descriptor; typedef typename Circular_border_parameterizer_3::halfedge_descriptor halfedge_descriptor; // Private types // Default constructor, copy constructor and operator =() are fine - // Protected operations +// Protected operations protected: /// Compute the length of an edge. virtual double compute_edge_length(const TriangleMesh& mesh, diff --git a/Surface_mesh_parameterization/include/CGAL/Discrete_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Discrete_authalic_parameterizer_3.h index 6e1831e1d08..74e8c58b0d0 100644 --- a/Surface_mesh_parameterization/include/CGAL/Discrete_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Discrete_authalic_parameterizer_3.h @@ -35,39 +35,44 @@ namespace CGAL { /// \ingroup PkgSurfaceParameterizationMethods /// /// The class `Discrete_authalic_parameterizer_3` -/// implements the *Discrete Authalic Parameterization* algorithm \cgalCite{cgal:dma-ipsm-02}. -/// This method is sometimes called DAP or just Authalic parameterization. +/// implements the *Discrete Authalic Parameterization* algorithm \cgalCite{cgal:dma-ipsm-02}. This method +/// is sometimes called DAP or just Authalic parameterization. /// /// DAP is a weak area-preserving parameterization. It is a compromise between /// area-preserving and angle-preserving. /// -/// One-to-one mapping is guaranteed if surface's border is mapped onto a convex polygon. +/// A one-to-one mapping is guaranteed if the surface's border is mapped onto a convex polygon. /// /// This class is a Strategy \cgalCite{cgal:ghjv-dpero-95} called by the main -/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()`. -/// `Discrete_authalic_parameterizer_3`: -/// - It provides default `BorderParameterizer_3` and `SparseLinearAlgebraTraits_d` template -/// parameters. -/// - It implements `compute_w_ij()` to compute w_ij = (i, j) coefficient of matrix A -/// for j neighbor vertex of i based on Discrete Authalic Parameterization algorithm. +/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it: +/// - provides the template parameters `BorderParameterizer_3` and `SparseLinearAlgebraTraits_d`. +/// - implements `compute_w_ij()` to compute w_ij = (i, j), coefficient of the matrix A +/// for j neighbor vertex of i, based on Discrete Authalic Parameterization algorithm. /// /// \cgalModels `ParameterizerTraits_3` /// -/// \sa `CGAL::Parameterizer_traits_3` +/// \tparam TriangleMesh must be a model of `FaceGraph` +/// \tparam BorderParameterizer_3 is a Strategy to parameterize the surface border. +/// \tparam SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
+/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` +/// does not remove (yet) border vertices from the system. +/// +/// \sa `CGAL::Parameterizer_traits_3`. /// \sa `CGAL::Fixed_border_parameterizer_3` +/// \sa `CGAL::ARAP_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_conformal_map_parameterizer_3` /// \sa `CGAL::LSCM_parameterizer_3` /// \sa `CGAL::Mean_value_coordinates_parameterizer_3` - +/// template < - class TriangleMesh, ///< a model of `FaceGraph` - class BorderParameterizer_3 ///< Strategy to parameterize the surface border + class TriangleMesh, + class BorderParameterizer_3 = Circular_border_arc_length_parameterizer_3, - class SparseLinearAlgebraTraits_d ///< Traits class to solve a sparse linear system + class SparseLinearAlgebraTraits_d = Eigen_solver_traits::EigenType, - Eigen::IncompleteLUT< double > > > + Eigen::IncompleteLUT > > > class Discrete_authalic_parameterizer_3 : public Fixed_border_parameterizer_3::vertex_descriptor vertex_descriptor; typedef CGAL::Vertex_around_target_circulator vertex_around_target_circulator; - // Mesh_Adaptor_3 subtypes: + // Traits subtypes: typedef typename Parameterizer_traits_3::NT NT; typedef typename Parameterizer_traits_3::Point_3 Point_3; typedef typename Parameterizer_traits_3::Vector_3 Vector_3; @@ -110,9 +115,9 @@ private: public: /// Constructor Discrete_authalic_parameterizer_3(Border_param border_param = Border_param(), - ///< Object that maps the surface's border to 2D space. + ///< %Object that maps the surface's border to 2D space. Sparse_LA sparse_la = Sparse_LA()) - ///< Traits object to access a sparse linear system. + ///< Traits object to access a sparse linear system. : Fixed_border_parameterizer_3(border_param, sparse_la) @@ -122,7 +127,11 @@ public: // Protected operations protected: - /// Compute w_ij = (i, j) coefficient of matrix A for j neighbor vertex of i. + /// Compute w_ij = (i, j), coefficient of matrix A for j neighbor vertex of i. + /// + /// \param mesh a triangulated surface. + /// \param main_vertex_v_i the vertex of `mesh` with index `i` + /// \param neighbor_vertex_v_j the vertex of `mesh` with index `j` virtual NT compute_w_ij(const TriangleMesh& mesh, vertex_descriptor main_vertex_v_i, vertex_around_target_circulator neighbor_vertex_v_j) diff --git a/Surface_mesh_parameterization/include/CGAL/Discrete_conformal_map_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Discrete_conformal_map_parameterizer_3.h index c65041820e1..18eb40c72af 100644 --- a/Surface_mesh_parameterization/include/CGAL/Discrete_conformal_map_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Discrete_conformal_map_parameterizer_3.h @@ -40,31 +40,30 @@ namespace CGAL { /// /// This is a conformal parameterization, i.e. it attempts to preserve angles. /// -/// One-to-one mapping is guaranteed if surface's border is mapped onto a convex polygon. +/// A one-to-one mapping is guaranteed if the surface's border is mapped onto a convex polygon. /// -/// This class is used by the main -/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()`. -/// - It provides default `BorderParameterizer_3` and `SparseLinearAlgebraTraits_d` template -/// parameters. -/// - It implements `compute_w_ij()` to compute w_ij = (i, j) coefficient of matrix A -/// for j neighbor vertex of i based on Discrete Conformal Map method. +/// This class is a Strategy \cgalCite{cgal:ghjv-dpero-95} called by the main +/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it: +/// - provides the template parameters `BorderParameterizer_3` and `SparseLinearAlgebraTraits_d`. +/// - implements `compute_w_ij()` to compute w_ij = (i, j), coefficient of matrix A +/// for j neighbor vertex of i, based on Discrete Conformal Map method. /// /// \cgalModels `ParameterizerTraits_3` /// -/// -/// \param TriangleMesh a model of `FaceGraph` -/// \param BorderParameterizer_3 Strategy to parameterize the surface border. -/// \param SparseLinearAlgebraTraits_d Traits class to solve a sparse linear system. +/// \param TriangleMesh must be a model of `FaceGraph`. +/// \param BorderParameterizer_3 is a Strategy to parameterize the surface border. +/// \param SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` /// does not remove (yet) border vertices from the system. /// /// \sa `CGAL::Parameterizer_traits_3` /// \sa `CGAL::Fixed_border_parameterizer_3` +/// \sa `CGAL::ARAP_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_authalic_parameterizer_3` /// \sa `CGAL::LSCM_parameterizer_3` /// \sa `CGAL::Mean_value_coordinates_parameterizer_3` - +/// template < class TriangleMesh, @@ -115,7 +114,7 @@ private: public: /// Constructor Discrete_conformal_map_parameterizer_3(Border_param border_param = Border_param(), - ///< Object that maps the surface's border to 2D space. + ///< %Object that maps the surface's border to 2D space. Sparse_LA sparse_la = Sparse_LA()) ///< Traits object to access a sparse linear system. : Fixed_border_parameterizer_3 +/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` +/// does not remove (yet) border vertices from the system. /// /// \sa `CGAL::Parameterizer_traits_3` +/// \sa `CGAL::ARAP_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_authalic_parameterizer_3` /// \sa `CGAL::Discrete_conformal_map_parameterizer_3` /// \sa `CGAL::LSCM_parameterizer_3` /// \sa `CGAL::Mean_value_coordinates_parameterizer_3` - +/// template < - class TriangleMesh, ///< a model of FaceGraph - class BorderParameterizer_3 ///< Strategy to parameterize the surface border + class TriangleMesh, + class BorderParameterizer_3 = Circular_border_arc_length_parameterizer_3, - class SparseLinearAlgebraTraits_d ///< Traits class to solve a sparse linear system + class SparseLinearAlgebraTraits_d = Eigen_solver_traits::EigenType, - Eigen::IncompleteLUT< double > > > > - + Eigen::IncompleteLUT< double > > > +> class Fixed_border_parameterizer_3 : public Parameterizer_traits_3 { @@ -111,7 +114,7 @@ private: typedef CGAL::Vertex_around_target_circulator vertex_around_target_circulator; typedef CGAL::Vertex_around_face_circulator vertex_around_face_circulator; - // Mesh_Adaptor_3 subtypes: + // Traits subtypes: typedef typename Base::NT NT; typedef typename Base::Point_2 Point_2; typedef typename Base::Point_3 Point_3; @@ -130,9 +133,9 @@ protected: public: /// Constructor Fixed_border_parameterizer_3(Border_param border_param = Border_param(), - ///< Object that maps the surface's border to 2D space + ///< %Object that maps the surface's border to 2D space Sparse_LA sparse_la = Sparse_LA()) - ///< Traits object to access a sparse linear system + ///< Traits object to access a sparse linear system : m_borderParameterizer(border_param), m_linearAlgebra(sparse_la) { } @@ -140,17 +143,30 @@ public: /// Compute a one-to-one mapping from a triangular 3D surface mesh /// to a piece of the 2D space. - /// The mapping is linear by pieces (linear in each triangle). + /// The mapping is piecewise linear (linear in each triangle). /// The result is the (u,v) pair image of each vertex of the 3D surface. /// + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexIndexMap must be a property map that associates a unique integer index + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexParameterizedMap must be a property map that associates a boolean + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param mesh a triangulated surface. + /// \param bhd an halfedge descriptor on the boundary of `mesh`. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vimap an instanciation of the class `VertexIndexMap`. + /// \param vpm an instanciation of the class `VertexParameterizedMap`. + /// /// \pre `mesh` must be a surface with one connected component. /// \pre `mesh` must be a triangular mesh. /// \pre The mesh border must be mapped onto a convex polygon. - template Error_code parameterize(TriangleMesh& mesh, - halfedge_descriptor, - VertexUVmap, + halfedge_descriptor bhd, + VertexUVmap uvmap, VertexIndexMap vimap, VertexParameterizedMap vpm); @@ -160,24 +176,38 @@ protected: /// Fill the border vertices' lines in both linear systems: /// "u = constant" and "v = constant". /// - /// \pre Vertices must be indexed. + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexIndexMap must be a property map that associates a unique integer index + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param A the matrix in both linear system + /// \param Bu the right hand side vector in the linear system of x coordinates + /// \param Bv the right hand side vector in the linear system of y coordinates + /// \param mesh a triangulated surface. + /// \param bhd an halfedge descriptor on the boundary of `mesh`. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vimap an instanciation of the class `VertexIndexMap`. + /// + /// \pre Vertices must be indexed (`vimap` must be initialized). /// \pre A, Bu and Bv must be allocated. /// \pre Border vertices must be parameterized. template void initialize_system_from_mesh_border(Matrix& A, Vector& Bu, Vector& Bv, - const TriangleMesh& tmesh, + const TriangleMesh& mesh, halfedge_descriptor bhd, VertexUVmap uvmap, VertexIndexMap vimap) { - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(bhd,tmesh)){ + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(bhd, mesh)){ // Get vertex index in sparse linear system - int index = get(vimap, target(hd,tmesh)); + int index = get(vimap, target(hd, mesh)); // Write a diagonal coefficient of A A.set_coef(index, index, 1, true /*new*/); // get the halfedge uv // Write constant in Bu and Bv - Point_2 uv = get(uvmap, target(hd,tmesh)); + Point_2 uv = get(uvmap, target(hd, mesh)); Bu[index] = uv.x(); Bv[index] = uv.y(); } @@ -185,6 +215,10 @@ protected: /// Compute w_ij = (i, j) coefficient of matrix A for j neighbor vertex of i. /// Implementation note: Subclasses must at least implement compute_w_ij(). + /// + /// \param mesh a triangulated surface. + /// \param main_vertex_v_i the vertex of `mesh` with index `i` + /// \param neighbor_vertex_v_j the vertex of `mesh` with index `j` virtual NT compute_w_ij(const TriangleMesh& mesh, vertex_descriptor main_vertex_v_i, vertex_around_target_circulator neighbor_vertex_v_j) @@ -280,15 +314,29 @@ struct Vertices_set { // Implementation // ------------------------------------------------------------------------------------ -// Compute a one-to-one mapping from a triangular 3D surface mesh -// to a piece of the 2D space. -// The mapping is linear by pieces (linear in each triangle). -// The result is the (u,v) pair image of each vertex of the 3D surface. -// -// Preconditions: -// - `mesh` must be a surface with one connected component. -// - `mesh` must be a triangular mesh. -// - The mesh border must be mapped onto a convex polygon. +/// Compute a one-to-one mapping from a triangular 3D surface mesh +/// to a piece of the 2D space. +/// The mapping is piecewise linear (linear in each triangle). +/// The result is the (u,v) pair image of each vertex of the 3D surface. +/// +/// \tparam VertexUVmap must be a property map that associates a %Point_2 +/// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` +/// (type deduced by the graph traits of `TriangleMesh`). +/// \tparam VertexIndexMap must be a property map that associates a unique integer index +/// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). +/// \tparam VertexParameterizedMap must be a property map that associates a boolean +/// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). +/// +/// \param mesh a triangulated surface. +/// \param bhd an halfedge descriptor on the boundary of `mesh`. +/// \param uvmap an instanciation of the class `VertexUVmap`. +/// \param vimap an instanciation of the class `VertexIndexMap`. +/// \param vpmap an instanciation of the class `VertexParameterizedMap`. +/// +/// \pre `mesh` must be a surface with one connected component. +/// \pre `mesh` must be a triangular mesh. +/// \pre The mesh border must be mapped onto a convex polygon. +/// \pre The vertices must be indexed (`vimap` must be initialized) template template typename Fixed_border_parameterizer_3::Error_code diff --git a/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h index ee4e8b5fe83..e736ad88fb5 100644 --- a/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h @@ -58,17 +58,22 @@ namespace CGAL { /// /// This is a conformal parameterization, i.e. it attempts to preserve angles. /// -/// This is a free border parameterization. No need to map the border of the surface -/// onto a convex polygon (only two pinned vertices are needed to ensure a -/// unique solution), but one-to-one mapping is *not* guaranteed. -/// -/// Note that his parametrization method has no template parameter for changing the sparse solver. +/// This is a free border parameterization. There is no need to map the border +/// of the surface onto a convex polygon (only two pinned vertices are needed +/// to ensure a unique solution), but a one-to-one mapping is *not* guaranteed. /// /// \cgalModels `ParameterizerTraits_3` /// +/// \tparam TriangleMesh a model of `FaceGraph` +/// \tparam BorderParameterizer_3 Strategy to parameterize the surface border.
+/// Note: The minimum is to parameterize two vertices. +/// \tparam SparseLinearAlgebraTraits_d Traits class to solve a sparse linear system.
+/// Note: We may use a symmetric definite positive solver because LSCM +/// solves the system in the least squares sense. /// /// \sa `CGAL::Parameterizer_traits_3` /// \sa `CGAL::Fixed_border_parameterizer_3` +/// \sa `CGAL::ARAP_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_authalic_parameterizer_3` /// \sa `CGAL::Discrete_conformal_map_parameterizer_3` @@ -76,20 +81,15 @@ namespace CGAL { template < - class TriangleMesh, ///< a model of `FaceGraph` + class TriangleMesh, class BorderParameterizer_3 = Two_vertices_parameterizer_3, - ///< Strategy to parameterize the surface border. - ///< The minimum is to parameterize two vertices. class SparseLinearAlgebraTraits_d #if defined(CGAL_EIGEN3_ENABLED) || defined(DOXYGEN_RUNNING) = Eigen_solver_traits::EigenType> > #else = OpenNL::SymmetricLinearSolverTraits #endif - ///< Traits class to solve a sparse linear system. - ///< We may use a symmetric definite positive solver because LSCM - ///< solves the system in the least squares sense. > class LSCM_parameterizer_3 : public Parameterizer_traits_3 @@ -133,13 +133,13 @@ private: typedef typename Sparse_LA::Vector Vector; typedef typename Sparse_LA::Matrix Matrix; - typedef typename OpenNL::LinearSolver LeastSquaresSolver ; + typedef typename OpenNL::LinearSolver LeastSquaresSolver; // Public operations public: /// Constructor LSCM_parameterizer_3(Border_param border_param = Border_param(), - ///< Object that maps the surface's border to 2D space + ///< %Object that maps the surface's border to 2D space Sparse_LA sparse_la = Sparse_LA()) ///< Traits object to access a sparse linear system : m_borderParameterizer(border_param), m_linearAlgebra(sparse_la) @@ -149,17 +149,33 @@ public: /// Compute a one-to-one mapping from a triangular 3D surface mesh /// to a piece of the 2D space. - /// The mapping is linear by pieces (linear in each triangle). + /// The mapping is piecewise linear (linear in each triangle). /// The result is the (u,v) pair image of each vertex of the 3D surface. /// + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexIndexMap must be a property map that associates a unique integer index + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexParameterizedMap must be a property map that associates a boolean + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param mesh a triangulated surface. + /// \param bhd an halfedge descriptor on the boundary of `mesh`. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vimap an instanciation of the class `VertexIndexMap`. + /// \param vpmap an instanciation of the class `VertexParameterizedMap`. + /// /// \pre `mesh` must be a surface with one connected component. /// \pre `mesh` must be a triangular mesh. + /// \pre The vertices must be indexed (`vimap` must be initialized). + /// template Error_code parameterize(TriangleMesh& mesh, halfedge_descriptor bhd, VertexUVmap uvmap, VertexIndexMap vimap, - VertexParameterizedMap vpm) + VertexParameterizedMap vpmap) { // Count vertices int nbVertices = num_vertices(mesh); @@ -169,7 +185,7 @@ public: // Compute (u,v) for (at least two) border vertices // and mark them as "parameterized" - Error_code status = get_border_parameterizer().parameterize_border(mesh,bhd,uvmap,vpm); + Error_code status = get_border_parameterizer().parameterize_border(mesh,bhd,uvmap,vpmap); if(status != Base::OK) return status; @@ -181,7 +197,7 @@ public: // Initialize the "A*X = B" linear system after // (at least two) border vertices parameterization - initialize_system_from_mesh_border(solver, mesh, uvmap, vimap, vpm); + initialize_system_from_mesh_border(solver, mesh, uvmap, vimap, vpmap); // Fill the matrix for the other vertices solver.begin_system(); @@ -219,7 +235,7 @@ public: put(uvmap, vd, Point_2(u,v)); } return status; -} + } // Private operations private: @@ -234,7 +250,7 @@ private: const TriangleMesh& mesh, UVmap uvmap, VertexIndexMap vimap, - VertexParameterizedMap vpm) + VertexParameterizedMap vpmap) { BOOST_FOREACH(vertex_descriptor v, vertices(mesh)){ // Get vertex index in sparse linear system @@ -250,7 +266,7 @@ private: solver.variable(2 * index + 1).set_value(uv.y()); // Copy (u,v) in B if vertex is parameterized - if (get(vpm,v)) { + if (get(vpmap,v)) { solver.variable(2 * index ).lock(); solver.variable(2 * index + 1).lock(); } @@ -266,11 +282,11 @@ private: /// Create two lines in the linear system per triangle (one for u, one for v). /// /// \pre vertices must be indexed. - template + template Error_code setup_triangle_relations(LeastSquaresSolver& solver, const TriangleMesh& mesh, face_descriptor facet, - HalfedgeAsVertexIndexMap); + VertexIndexMap vimap); // Private accessors private: @@ -282,7 +298,7 @@ private: // Fields private: - /// Object that maps (at least two) border vertices onto a 2D space + /// %Object that maps (at least two) border vertices onto a 2D space Border_param m_borderParameterizer; /// Traits object to solve a sparse linear system @@ -325,10 +341,9 @@ project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2, // i z2 = Point_2(x2, y2); } -// Create two lines in the linear system per triangle (one for u, one for v) -// -// Precondition: vertices must be indexed -// +/// Create two lines in the linear system per triangle (one for u, one for v). +/// +/// \pre vertices of `mesh` must be indexed. // Implementation note: LSCM equation is: // (Z1 - Z0)(U2 - U0) = (Z2 - Z0)(U1 - U0) // where Uk = uk + i.v_k is the complex number corresponding to (u,v) coords @@ -343,7 +358,7 @@ LSCM_parameterizer_3:: setup_triangle_relations(LeastSquaresSolver& solver, const TriangleMesh& mesh, face_descriptor facet, - VertexIndexMap hvimap) + VertexIndexMap vimap) { typedef typename boost::property_map::const_type PPmap; PPmap ppmap = get(vertex_point, mesh); @@ -358,9 +373,9 @@ setup_triangle_relations(LeastSquaresSolver& solver, v2 = target(h2, mesh); // Get the vertices index - int id0 = get(hvimap, v0); - int id1 = get(hvimap, v1); - int id2 = get(hvimap, v2); + int id0 = get(vimap, v0); + int id1 = get(vimap, v1); + int id2 = get(vimap, v2); // Get the vertices position const Point_3& p0 = get(ppmap, v0); diff --git a/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h b/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h index f2aa40ad0d9..e0b7f586aeb 100644 --- a/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h +++ b/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h @@ -1,3 +1,23 @@ +// Copyright (c) 2016 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : + #ifndef CGAL_MVC_POST_PROCESSOR_3_H #define CGAL_MVC_POST_PROCESSOR_3_H @@ -14,13 +34,12 @@ #include #include -#include #include #include #include -/// \file CGAL/MVC_post_processor_3.h +/// \file MVC_post_processor_3.h // @todo Determine the proper name of this file // @todo Handle non-simple boundary @@ -62,10 +81,28 @@ void assign_solution(const Vector& Xu, // Declaration // ------------------------------------------------------------------------------------ +// /// \ingroup PkgSurfaceParameterizationMethods +/// +/// The class `MVC_post_processor_3` implements +/// the *Free boundary linear Parameterization* algorithm \cgalCite{kami2005free}. +/// +/// This parameterizer provides a post processing step to other parameterizers +/// that do not necessarily return a valid embedding. It is based on +/// the convexification of the initial (2D) parameterization and the resolution +/// of a linear system with coefficients based on Mean Value Coordinates. +/// +/// \cgalModels `ParameterizerTraits_3` +/// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// \tparam SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
+/// Note: the system is *not* symmetric. +/// +/// \sa `CGAL::ARAP_parameterizer_3` +/// template < - class TriangleMesh, ///< a model of `FaceGraph` - class SparseLinearAlgebraTraits_d ///< Traits class to solve a sparse linear system. + class TriangleMesh, + class SparseLinearAlgebraTraits_d = Eigen_solver_traits::EigenType, Eigen::IncompleteLUT< double > > > > @@ -87,7 +124,6 @@ public: typedef typename Base::Error_code Error_code; /// @endcond - // Private types private: typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -99,8 +135,9 @@ private: typedef boost::unordered_set Vertex_set; typedef std::vector Faces_vector; - // Mesh_Adaptor_3 subtypes: + // Traits subtypes: typedef Parameterizer_traits_3 Traits; + typedef typename Traits::Kernel Kernel; typedef typename Traits::NT NT; typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_3 Point_3; @@ -108,10 +145,24 @@ private: typedef typename Traits::Vector_3 Vector_3; // SparseLinearAlgebraTraits_d subtypes: - typedef SparseLinearAlgebraTraits_d Sparse_LA; + typedef SparseLinearAlgebraTraits_d Sparse_LA; - typedef typename Sparse_LA::Vector Vector; - typedef typename Sparse_LA::Matrix Matrix; + typedef typename Sparse_LA::Vector Vector; + typedef typename Sparse_LA::Matrix Matrix; + + // Types used for the convexification of the mesh + // Each triangulation vertex is associated its corresponding vertex_descriptor + typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; + // Each triangultaion face is associated a color (inside/outside information) + typedef CGAL::Triangulation_face_base_with_info_2 Fb; + typedef CGAL::Constrained_triangulation_face_base_2 Cfb; + typedef CGAL::Triangulation_data_structure_2 TDS; + typedef CGAL::No_intersection_tag Itag; + + // Can choose either a triangulation or a Delauany triangulation + typedef CGAL::Constrained_triangulation_2 CT; +// typedef CGAL::Constrained_Delaunay_triangulation_2 CT; // Private fields private: @@ -622,8 +673,7 @@ private: } } - /// Solve the linear systems A*Xu=Bu and A*Xv=Bv using Eigen's BiCGSTAB - /// and incompleteLUT factorization. + /// Solve the two linear systems A*Xu=Bu and A*Xv=Bv. Error_code solve_mvc(const Matrix& A, const Vector& Bu, const Vector& Bv, Vector& Xu, Vector& Xv) const @@ -644,6 +694,7 @@ private: return status; } + /// Color the faces with inside/outside information and fix the border. template Error_code prepare_CT_for_parameterization(const CT& ct, VertexParameterizedMap mvc_vpmap) const @@ -697,8 +748,6 @@ private: } public: - /// Use the convex virtual boundary algorithm of Karni et al.[2005] to fix - /// the (hopefully few) flips in the result. template Error_code parameterize(const TriangleMesh& mesh, @@ -708,19 +757,6 @@ public: VertexUVMap uvmap, const VertexIndexMap vimap) const { - typedef typename Traits::Kernel Kernel; - - // Each triangulation vertex is associated its corresponding vertex_descriptor - typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; - // Each triangultaion face is associated a color (inside/outside information) - typedef CGAL::Triangulation_face_base_with_info_2 Fb; - typedef CGAL::Constrained_triangulation_face_base_2 Cfb; - typedef CGAL::Triangulation_data_structure_2 TDS; - typedef CGAL::No_intersection_tag Itag; - typedef CGAL::Constrained_triangulation_2 CT; -// typedef CGAL::Constrained_Delaunay_triangulation_2 CT; - // Check if the polygon is simple const bool is_param_border_simple = is_polygon_simple(mesh, bhd, uvmap); @@ -744,6 +780,21 @@ public: return Base::OK; } + /// Compute a one-to-one mapping from a triangular 2D surface mesh + /// that is not necessarily embedded to a piece of the 2D space. + /// + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexIndexMap must be a property map that associates a unique integer index + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param mesh a triangulated surface. + /// \param bhd an halfedge descriptor on the boundary of `mesh`. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vimap an instanciation of the class `VertexIndexMap`. + /// \param vpmap an instanciation of the class `VertexParameterizedMap`. + /// template Error_code parameterize(const TriangleMesh& mesh, diff --git a/Surface_mesh_parameterization/include/CGAL/Mean_value_coordinates_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Mean_value_coordinates_parameterizer_3.h index 86b974ca447..52ffa6d2ffa 100644 --- a/Surface_mesh_parameterization/include/CGAL/Mean_value_coordinates_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Mean_value_coordinates_parameterizer_3.h @@ -51,23 +51,29 @@ namespace CGAL { /// /// \cgalModels `ParameterizerTraits_3` /// +/// \tparam TriangleMesh must be a model of `FaceGraph` +/// \tparam BorderParameterizer_3 is a Strategy to parameterize the surface border. +/// \tparam SparseLinearAlgebraTraits_d is a Traits class to solve a sparse linear system.
+/// Note: the system is *not* symmetric because `Fixed_border_parameterizer_3` +/// does not remove (yet) border vertices from the system. /// /// \sa `CGAL::Parameterizer_traits_3` /// \sa `CGAL::Fixed_border_parameterizer_3` +/// \sa `CGAL::ARAP_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_authalic_parameterizer_3` /// \sa `CGAL::Discrete_conformal_map_parameterizer_3` /// \sa `CGAL::LSCM_parameterizer_3` - +/// template < - class TriangleMesh, ///< a model of `FaceGraph` - class BorderParameterizer_3 ///< Strategy to parameterize the surface border + class TriangleMesh, + class BorderParameterizer_3 = Circular_border_arc_length_parameterizer_3, - class SparseLinearAlgebraTraits_d ///< Traits class to solve a sparse linear system - = Eigen_solver_traits::EigenType, Eigen::IncompleteLUT< double > > > + class SparseLinearAlgebraTraits_d + = Eigen_solver_traits::EigenType, + Eigen::IncompleteLUT > > > - class Mean_value_coordinates_parameterizer_3 : public Fixed_border_parameterizer_3` /// \sa `CGAL::Fixed_border_parameterizer_3` /// \sa `CGAL::Barycentric_mapping_parameterizer_3` /// \sa `CGAL::Discrete_authalic_parameterizer_3` /// \sa `CGAL::Discrete_conformal_map_parameterizer_3` /// \sa `CGAL::LSCM_parameterizer_3` /// \sa `CGAL::Mean_value_coordinates_parameterizer_3` - -template //< 3D surface +/// +template class Parameterizer_traits_3 { // Public types @@ -80,7 +82,7 @@ public: typedef typename boost::property_traits::value_type Point_3; typedef typename Kernel_traits::Kernel Kernel; - // Mesh_Adaptor_3 subtypes: + // Kernel subtypes: typedef typename Kernel::Point_2 Point_2; typedef typename Kernel::Vector_3 Vector_3; typedef typename Kernel::Vector_2 Vector_2; @@ -103,7 +105,7 @@ public: /// /// \pre `mesh` must be a surface with one connected component. /// \pre `mesh` must be a triangular mesh. - //virtual Error_code parameterize (Adaptor& mesh) = 0; + //virtual Error_code parameterize (TriangleMesh& mesh) = 0; /// Get message corresponding to an error code /// \param error_code The code returned by `parameterize()` diff --git a/Surface_mesh_parameterization/include/CGAL/Square_border_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Square_border_parameterizer_3.h index ddeb6979308..7436a7b25fe 100644 --- a/Surface_mesh_parameterization/include/CGAL/Square_border_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Square_border_parameterizer_3.h @@ -38,7 +38,7 @@ namespace CGAL { // Class Square_border_parameterizer_3 // -/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods +/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods /// /// This is the base class of strategies that parameterize the border /// of a 3D surface onto a square. @@ -55,8 +55,12 @@ namespace CGAL { /// /// \cgalModels `BorderParameterizer_3` /// - -template ///< 3D surface +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// +/// \sa `CGAL::Square_border_uniform_parameterizer_3` +/// \sa `CGAL::Square_border_arc_length_parameterizer_3` +/// +template class Square_border_parameterizer_3 { // Public types @@ -79,9 +83,6 @@ private: // Public operations public: - /// Destructor of base class should be virtual. - virtual ~Square_border_parameterizer_3() {} - // Default constructor, copy constructor and operator =() are fine /// Assign to mesh's border vertices a 2D position (i.e.\ a (u,v) pair) @@ -90,8 +91,7 @@ public: parameterize_border(TriangleMesh& mesh); /// Indicate if border's shape is convex. - bool is_border_convex () { return true; } - + bool is_border_convex() { return true; } // Private operations private: @@ -119,8 +119,8 @@ double Square_border_parameterizer_3::compute_border_length(const return len; } -// Assign to mesh's border vertices a 2D position (i.e. a (u,v) pair) -// on border's shape. Mark them as "parameterized". +/// Assign to mesh's border vertices a 2D position (i.e. a (u,v) pair) +/// on border's shape. Mark them as "parameterized". template inline typename Parameterizer_traits_3::Error_code @@ -206,8 +206,8 @@ Square_border_parameterizer_3::parameterize_border(TriangleMesh& m return Parameterizer_traits_3::OK; } -// Utility method for parameterize_border(). -// Compute mesh iterator whose offset is closest to 'value'. +/// Utility method for parameterize_border(). +/// Compute mesh iterator whose offset is closest to 'value'. template inline typename Square_border_parameterizer_3::halfedge_around_face_iterator @@ -235,7 +235,7 @@ Square_border_parameterizer_3::closest_iterator(TriangleMesh& mesh // Class Square_border_uniform_parameterizer_3 // -/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods +/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods /// /// This class parameterizes the border of a 3D surface onto a square /// in a uniform manner: points are equally spaced. @@ -246,7 +246,9 @@ Square_border_parameterizer_3::closest_iterator(TriangleMesh& mesh /// /// \cgalModels `BorderParameterizer_3` /// - +/// \sa `CGAL::Square_border_parameterizer_3` +/// \sa `CGAL::Square_border_arc_length_parameterizer_3` +/// template ///< 3D surface class Square_border_uniform_parameterizer_3 : public Square_border_parameterizer_3 @@ -285,7 +287,7 @@ protected: // Class Square_border_arc_length_parameterizer_3 // -/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods +/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods /// /// This class parameterizes the border of a 3D surface onto a square, /// with an arc-length parameterization: (u,v) values are @@ -295,10 +297,14 @@ protected: /// algorithm. This class implements only compute_edge_length() to compute a /// segment's length. /// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// /// \cgalModels `BorderParameterizer_3` /// - -template //< 3D surface +/// \sa `CGAL::Square_border_parameterizer_3` +/// \sa `CGAL::Square_border_uniform_parameterizer_3` +/// +template class Square_border_arc_length_parameterizer_3 : public Square_border_parameterizer_3 { @@ -321,8 +327,8 @@ protected: typedef typename boost::property_map::const_type PPmap; PPmap ppmap = get(vertex_point, mesh.get_adapted_mesh()); - /// Arc-length border parameterization: (u,v) values are - /// proportional to the length of border edges. + /// Arc-length border parameterization: (u,v) values are proportional + /// to the length of border edges. Vector_3 v = get(ppmap, target) - get(ppmap,source); return std::sqrt(v*v); } diff --git a/Surface_mesh_parameterization/include/CGAL/Two_vertices_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Two_vertices_parameterizer_3.h index f1ca10ac48f..97eebb6cd1b 100644 --- a/Surface_mesh_parameterization/include/CGAL/Two_vertices_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Two_vertices_parameterizer_3.h @@ -37,36 +37,35 @@ namespace CGAL { // Declaration // -/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods +/// \ingroup PkgSurfaceParameterizationBorderParameterizationMethods /// -/// The class `Two_vertices_parameterizer_3` -/// parameterizes two extreme vertices of a 3D surface. +/// The class `Two_vertices_parameterizer_3` parameterizes two extreme vertices +/// of a 3D surface. /// This kind of border parameterization is used by free border parameterizations. /// /// Implementation note: -/// To simplify the implementation, `BorderParameterizer_3` models know only the -/// `TriangleMesh` class. They do not know the parameterization algorithm -/// requirements or the kind of sparse linear system used. +/// To simplify the implementation, models of the concept `BorderParameterizer_3` +/// know only the `TriangleMesh` class. They do not know the parameterization +/// algorithm requirements or the kind of sparse linear system that is used. /// /// \cgalModels `BorderParameterizer_3` /// - -template //< 3D surface +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// +template class Two_vertices_parameterizer_3 { // Public types public: - /// Export TriangleMesh template parameter - //typedef TriangleMesh TriangleMesh; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + // Private types private: - typedef Parameterizer_traits_3 Adaptor; - typedef typename Adaptor::Point_2 Point_2; - typedef typename Adaptor::Point_3 Point_3; - typedef typename Adaptor::Vector_3 Vector_3; + typedef Parameterizer_traits_3 Traits; + typedef typename Traits::Point_2 Point_2; + typedef typename Traits::Point_3 Point_3; + typedef typename Traits::Vector_3 Vector_3; vertex_descriptor vxmin, vxmax; bool vertices_given; @@ -75,16 +74,29 @@ private: public: // Default constructor, copy constructor and operator =() are fine. + /// Constructor. Two_vertices_parameterizer_3() : vertices_given(false) { } + /// Constructor where fixed vertices are provided. Two_vertices_parameterizer_3(vertex_descriptor v1, vertex_descriptor v2) : vxmin(v1), vxmax(v2), vertices_given(true) { } - /// Map two extreme vertices of the 3D mesh and mark them as parameterized. -template + /// Map two extreme vertices of the 3D mesh and mark them as parameterized. + /// + /// \tparam VertexUVmap must be a property map that associates a %Point_2 + /// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` + /// (type deduced by the graph traits of `TriangleMesh`). + /// \tparam VertexParameterizedMap must be a property map that associates a boolean + /// to a `vertex_descriptor` (type deduced by the graph traits of `TriangleMesh`). + /// + /// \param mesh a triangulated surface. + /// \param uvmap an instanciation of the class `VertexUVmap`. + /// \param vpmap an instanciation of the class `VertexParameterizedMap`. + /// + template typename Parameterizer_traits_3::Error_code parameterize_border(const TriangleMesh& mesh, halfedge_descriptor, @@ -242,9 +254,9 @@ template return Parameterizer_traits_3::OK; } - /// Indicate if border's shape is convex. + /// Indicate if the border's shape is convex. /// Meaningless for free border parameterization algorithms. - bool is_border_convex () { return false; } + bool is_border_convex() { return false; } }; } // namespace CGAL diff --git a/Surface_mesh_parameterization/include/CGAL/parameterize.h b/Surface_mesh_parameterization/include/CGAL/parameterize.h index 413fe692e27..97c30a20fcd 100644 --- a/Surface_mesh_parameterization/include/CGAL/parameterize.h +++ b/Surface_mesh_parameterization/include/CGAL/parameterize.h @@ -109,8 +109,21 @@ struct Vertices { /// The mapping is piecewise linear on the triangle mesh. /// The result is a pair (u,v) of parameter coordinates for each vertex of the input mesh. /// -/// One-to-one mapping may be guaranteed or -/// not, depending on the chosen Parameterizer algorithm. +/// A one-to-one mapping may be guaranteed or not, depending on +/// the chosen Parameterizer algorithm. +/// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// \tparam Parameterizer must be a model of `ParameterizerTraits_3`. +/// \tparam HD must be the halfedge_descriptor type corresponding to the graph +/// traits of TriangleMesh. +/// \tparam VertexUVmap must be a property map that associates a %Point_2 +/// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` +/// (type deduced by the graph traits of `TriangleMesh`). +/// +/// \param mesh a triangulated surface. +/// \param parameterizer a parameterizer. +/// \param bhd an halfedge descriptor on the boundary of `mesh`. +/// \param uvm an instanciation of the class `VertexUVmap`. /// /// \pre `mesh` must be a surface with one connected component. /// \pre `mesh` must be a triangular mesh. @@ -144,6 +157,17 @@ parameterize(TriangleMesh& mesh, /// The mapping is piecewise linear on the input mesh triangles. /// The result is a (u,v) pair of parameter coordinates for each vertex of the input mesh. /// +/// \tparam TriangleMesh must be a model of `FaceGraph`. +/// \tparam HD must be the halfedge_descriptor type corresponding to the graph +/// traits of TriangleMesh. +/// \tparam VertexUVmap must be a property map that associates a %Point_2 +/// (type deduced by `Parameterized_traits_3`) to a `vertex_descriptor` +/// (type deduced by the graph traits of `TriangleMesh`). +/// +/// \param mesh a triangulated surface. +/// \param bhd an halfedge descriptor on the boundary of `mesh`. +/// \param uvm an instanciation of the class `VertexUVmap`. +/// /// \pre `mesh` must be a surface with one connected component. /// \pre `mesh` must be a triangular mesh. template