1 // Copyright (c) 2010 INRIA Sophia-Antipolis (France).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Mesh_3/include/CGAL/Mesh_edge_criteria_3.h $
7 // $Id: Mesh_edge_criteria_3.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Stephane Tayeb
12 //
13 //******************************************************************************
14 // File Description :
15 //******************************************************************************
16 
17 #ifndef CGAL_MESH_EDGE_CRITERIA_3_H
18 #define CGAL_MESH_EDGE_CRITERIA_3_H
19 
20 #include <CGAL/license/Mesh_3.h>
21 
22 
23 #include <CGAL/Mesh_constant_domain_field_3.h>
24 #include <CGAL/Mesh_3/Is_mesh_domain_field_3.h>
25 #include <type_traits>
26 
27 namespace CGAL {
28 namespace Mesh_3 {
29 namespace internal {
30 
31   // Those two classes are designed to handle dynamic initialization of
32   // Sizing_field type (using named parameters of make_mesh_3 for example)
33   template < typename FT_, typename Point_, typename Index_ >
34   class Sizing_field_interface
35   {
36   public:
37     typedef FT_     FT;
38     typedef Point_  Point_3;
39     typedef Index_  Index;
40 
~Sizing_field_interface()41     virtual ~Sizing_field_interface() {}
42 
43     virtual FT operator()(const Point_3& p,
44                           const int dim,
45                           const Index& index) const = 0;
46 
47     virtual Sizing_field_interface* clone() const = 0;
48   };
49 
50   template < typename Sizing_field,
51              typename FT,
52              typename Point_3,
53              typename Index>
54   struct Sizing_field_container
55     : public Sizing_field_interface < FT,
56                                       Point_3,
57                                       Index >
58   {
59     typedef Sizing_field_interface < FT,
60                                      Point_3,
61                                      Index > Base;
62 
63     typedef Sizing_field_container<Sizing_field, FT, Point_3, Index> Self;
64 
65   public:
Sizing_field_containerSizing_field_container66     Sizing_field_container(const Sizing_field& s) : s_(s) {}
~Sizing_field_containerSizing_field_container67     virtual ~Sizing_field_container() {}
68 
operatorSizing_field_container69     virtual FT operator()(const Point_3& p,
70                           const int dim,
71                           const Index& index) const
72     {
73       return s_(p,dim,index);
74     }
75 
cloneSizing_field_container76     virtual Base* clone() const
77     {
78       return new Self(*this);
79     }
80 
81   private:
82     Sizing_field s_;
83   };
84 
85 } // end namespace internal
86 } // end namespace Mesh_3
87 
88 template < typename Tr >
89 class Mesh_edge_criteria_3
90 {
91   typedef Mesh_edge_criteria_3 Self;
92 
93 public:
94   typedef typename Tr::Vertex::Index  Index;
95   typedef typename Tr::Geom_traits    Gt;
96   typedef typename Gt::FT             FT;
97   typedef typename Tr::Bare_point     Point_3;
98 
99   /// Constructors
Mesh_edge_criteria_3(const FT & value)100   Mesh_edge_criteria_3(const FT& value)
101     : p_size_(new Mesh_3::internal::Sizing_field_container<
102                 Mesh_constant_domain_field_3<Gt,Index> ,
103                 FT,
104                 Point_3,
105                 Index>(value))
106   {}
107 
108   // Nb: SFINAE to avoid wrong matches with built-in numerical types
109   // as int.
110   template < typename Sizing_field >
111   Mesh_edge_criteria_3
112   (
113    const Sizing_field& size,
114    typename std::enable_if<Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field>::value>::type* = 0
115    )
116   {
117     p_size_ = new Mesh_3::internal::Sizing_field_container<Sizing_field,
118                                                            FT,
119                                                            Point_3,
120                                                            Index>(size);
121   }
122 
Mesh_edge_criteria_3(const Self & rhs)123   Mesh_edge_criteria_3(const Self& rhs)
124     : p_size_(rhs.p_size_->clone()) {}
125 
126   /// Destructor
~Mesh_edge_criteria_3()127   ~Mesh_edge_criteria_3()
128   {
129     delete p_size_;
130   }
131 
132   /// Returns size of tuple (p,dim,index)
sizing_field(const Point_3 & p,const int dim,const Index & index)133   FT sizing_field(const Point_3& p, const int dim, const Index& index) const
134   { return (*p_size_)(p,dim,index); }
135 
136 private:
137   typedef Mesh_3::internal::Sizing_field_interface<FT,Point_3,Index>
138     Sizing_field_interface;
139 
140   // A pointer to Sizing_field_interface to handle dynamic wrapping of
141   // real Sizing_field type
142   Sizing_field_interface* p_size_;
143 };
144 
145 } // end namespace CGAL
146 
147 #endif // CGAL_MESH_EDGE_CRITERIA_3_H
148