// Copyright (c) 2005 INRIA (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // 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) : Laurent Saboret, Pierre Alliez #ifndef CGAL_PARAMETERIZER_3_H #define CGAL_PARAMETERIZER_3_H #include #include CGAL_BEGIN_NAMESPACE /// The class Parameterizer_traits_3 /// is the base class of all parameterization methods. /// This class is a pure virtual class, thus cannot be instantiated. /// /// This class doesn't do much. Its main goal is to ensure that subclasses /// will be proper models of the ParameterizerTraits_3 concept: /// - Parameterizer_traits_3 defines the Error_code list of errors detected by this package /// - Parameterizer_traits_3 declares a pure virtual method parameterize() /// /// Concept: /// Model of the ParameterizerTraits_3 concept (although you cannot instantiate this class). /// /// Design Pattern: /// ParameterizerTraits_3 models are Strategies [GHJV95]: they implement /// a strategy of surface parameterization for models of ParameterizationMesh_3. template //< 3D surface class Parameterizer_traits_3 { // Public types public: /// List of errors detected by this package enum Error_code { OK, ///< Success ERROR_EMPTY_MESH, ///< Error: input mesh is empty ERROR_NON_TRIANGULAR_MESH, ///< Error: input mesh is not triangular ERROR_NO_SURFACE_MESH, ///< Error: input mesh is not a surface ERROR_INVALID_BORDER, ///< Error: parameterization requires a convex border ERROR_BAD_MATRIX_CONDITIONING, ///< Error: result is mathematically unstable ERROR_CANNOT_SOLVE_LINEAR_SYSTEM,///< Error: cannot solve linear system ERROR_NO_1_TO_1_MAPPING, ///< Error: parameterization does not ensure 1 to 1 mapping ERROR_NOT_ENOUGH_MEMORY, ///< Error: not enough memory ERROR_WRONG_PARAMETER ///< Error: a method received an unexpected parameter }; /// Export ParameterizationMesh_3 template parameter typedef ParameterizationMesh_3 Adaptor; // Private types private: // Mesh_Adaptor_3 subtypes: typedef typename Adaptor::NT NT; typedef typename Adaptor::Point_2 Point_2; typedef typename Adaptor::Point_3 Point_3; typedef typename Adaptor::Vector_2 Vector_2; typedef typename Adaptor::Vector_3 Vector_3; typedef typename Adaptor::Facet Facet; typedef typename Adaptor::Facet_handle Facet_handle; typedef typename Adaptor::Facet_const_handle Facet_const_handle; typedef typename Adaptor::Facet_iterator Facet_iterator; typedef typename Adaptor::Facet_const_iterator Facet_const_iterator; typedef typename Adaptor::Vertex Vertex; typedef typename Adaptor::Vertex_handle Vertex_handle; typedef typename Adaptor::Vertex_const_handle Vertex_const_handle; typedef typename Adaptor::Vertex_iterator Vertex_iterator; typedef typename Adaptor::Vertex_const_iterator Vertex_const_iterator; typedef typename Adaptor::Border_vertex_iterator Border_vertex_iterator; typedef typename Adaptor::Border_vertex_const_iterator Border_vertex_const_iterator; typedef typename Adaptor::Vertex_around_facet_circulator Vertex_around_facet_circulator; typedef typename Adaptor::Vertex_around_facet_const_circulator Vertex_around_facet_const_circulator; typedef typename Adaptor::Vertex_around_vertex_circulator Vertex_around_vertex_circulator; typedef typename Adaptor::Vertex_around_vertex_const_circulator Vertex_around_vertex_const_circulator; // Public operations public: /// Destructor of base class should be virtual. virtual ~Parameterizer_traits_3() {} // Default constructor, copy constructor and operator =() are fine /// Compute a 1 to 1 mapping from a 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 1 connected component. /// - 'mesh' must be a triangular mesh. virtual Error_code parameterize (Adaptor* mesh) = 0; // Protected operations /// @cond SKIP_IN_MANUAL protected: // -> -> /// Return cotangent of (P,Q,R) corner (ie cotan of QP,QR angle). double cotangent(const Point_3& P, const Point_3& Q, const Point_3& R) { Vector_3 u = P - Q; Vector_3 v = R - Q; // (u . v)/((u x v).len) double dot = (u*v); Vector_3 cross_vector = CGAL::cross_product(u,v); double cross_norm = std::sqrt(cross_vector*cross_vector); CGAL_parameterization_assertion(cross_norm != 0.0); if(cross_norm != 0.0) return (dot/cross_norm); else return 0.0; // undefined } // -> -> /// Return tangent of (P,Q,R) corner (ie tangent of QP,QR angle). double tangent(const Point_3& P, const Point_3& Q, const Point_3& R) { Vector_3 u = P - Q; Vector_3 v = R - Q; // (u . v)/((u x v).len) double dot = (u*v); CGAL_parameterization_assertion(dot != 0.0); Vector_3 cross_vector = CGAL::cross_product(u,v); double cross_norm = std::sqrt(cross_vector*cross_vector); if(dot != 0.0) return (cross_norm/dot); else return 0.0; // undefined } // -> -> /// Return angle (in radians) of of (P,Q,R) corner (ie QP,QR angle). static double compute_angle_rad(const Point_3& P, const Point_3& Q, const Point_3& R) { static const double PI = 3.14159265359; Vector_3 u = P - Q; Vector_3 v = R - Q; // check double product = std::sqrt(u*u) * std::sqrt(v*v); if(product == 0) return 0.0; // cosine double dot = (u*v); double cosine = dot / product; // sine Vector_3 w = CGAL::cross_product(u,v); double AbsSine = std::sqrt(w*w) / product; if(cosine >= 0) return std::asin(fix_sine(AbsSine)); else return PI-std::asin(fix_sine(AbsSine)); } /// @endcond // Private operations private: /// Fix sine. static double fix_sine(double sine) { if(sine >= 1) return 1; else if(sine <= -1) return -1; else return sine; } }; CGAL_END_NAMESPACE #endif //CGAL_PARAMETERIZER_3_H