1 // Copyright (c) 2009, 2014 INRIA Sophia-Antipolis (France).
2 // Copyright (c) 2017 GeometryFactory (France).
3 // All rights reserved.
4 //
5 // This file is part of CGAL (www.cgal.org).
6 //
7 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Periodic_3_mesh_3/include/CGAL/make_periodic_3_mesh_3.h $
8 // $Id: make_periodic_3_mesh_3.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
9 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
10 //
11 // Author(s) : Stéphane Tayeb,
12 // Mikhail Bogdanov,
13 // Mael Rouxel-Labbé
14 //
15 //******************************************************************************
16 // File Description : make_periodic_3_mesh_3 function definition.
17 //******************************************************************************
18
19 #ifndef CGAL_PERIODIC_3_MESH_3_MAKE_PERIODIC_3_MESH_3_H
20 #define CGAL_PERIODIC_3_MESH_3_MAKE_PERIODIC_3_MESH_3_H
21
22 #include <CGAL/license/Periodic_3_mesh_3.h>
23
24 #include <CGAL/Periodic_3_mesh_3/config.h>
25 #include <CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h>
26 #include <CGAL/refine_periodic_3_mesh_3.h>
27
28 #include <CGAL/assertions.h>
29 #include <CGAL/boost/parameter.h>
30 #include <CGAL/make_mesh_3.h>
31 #include <CGAL/Mesh_3/C3T3_helpers.h>
32
33 #include <boost/parameter/preprocessor.hpp>
34
35 namespace CGAL {
36 namespace Periodic_3_mesh_3 {
37 namespace internal {
38
39 template<typename C3T3>
mark_dummy_points(C3T3 & c3t3)40 void mark_dummy_points(C3T3& c3t3)
41 {
42 CGAL_precondition(c3t3.triangulation().is_1_cover());
43
44 typedef typename C3T3::Triangulation::Vertex_iterator Vertex_iterator;
45
46 for(Vertex_iterator vit = c3t3.triangulation().vertices_begin();
47 vit != c3t3.triangulation().vertices_end(); ++vit)
48 {
49 c3t3.set_index(vit, 0);
50 }
51 }
52
53 template <typename C3T3, typename MeshDomain, typename MeshCriteria>
54 void init_c3t3_with_features(C3T3& c3t3,
55 const MeshDomain& domain,
56 const MeshCriteria& criteria,
57 bool nonlinear = false)
58 {
59 typedef typename MeshCriteria::Edge_criteria Edge_criteria;
60 typedef Mesh_3::internal::Edge_criteria_sizing_field_wrapper<Edge_criteria> Sizing_field;
61
62 CGAL::Periodic_3_mesh_3::Protect_edges_sizing_field<C3T3, MeshDomain, Sizing_field>
63 protect_edges(c3t3, domain, Sizing_field(criteria.edge_criteria_object()));
64 protect_edges.set_nonlinear_growth_of_balls(nonlinear);
65
66 protect_edges(true);
67 }
68
69 // C3t3_initializer: initialize c3t3
70 template <typename C3T3,
71 typename MeshDomain,
72 typename MeshCriteria,
73 bool MeshDomainHasHasFeatures,
74 typename HasFeatures = int>
75 struct C3t3_initializer_base
76 : public CGAL::Mesh_3::internal::C3t3_initializer<
77 C3T3, MeshDomain, MeshCriteria, MeshDomainHasHasFeatures, HasFeatures>
78 {
79 typedef CGAL::Mesh_3::internal::C3t3_initializer<
80 C3T3, MeshDomain, MeshCriteria,
81 MeshDomainHasHasFeatures, HasFeatures> Base;
82
operatorC3t3_initializer_base83 void operator()(C3T3& c3t3,
84 const MeshDomain& domain,
85 const MeshCriteria& criteria,
86 bool with_features,
87 const parameters::internal::Mesh_3_options& mesh_options)
88 {
89 c3t3.triangulation().set_domain(domain.bounding_box());
90 c3t3.triangulation().insert_dummy_points();
91 mark_dummy_points(c3t3);
92
93 // Call the basic initialization from c3t3, which handles features and
94 // adds a bunch of points on the surface
95 Base::operator()(c3t3, domain, criteria, with_features, mesh_options);
96 }
97 };
98
99 template <typename C3T3,
100 typename MeshDomain,
101 typename MeshCriteria,
102 bool MeshDomainHasHasFeatures,
103 typename HasFeatures = int>
104 struct C3t3_initializer
105 : public C3t3_initializer_base<C3T3, MeshDomain, MeshCriteria, MeshDomainHasHasFeatures, HasFeatures>
106 {
107 typedef C3t3_initializer_base<C3T3, MeshDomain, MeshCriteria,
108 MeshDomainHasHasFeatures, HasFeatures> Base;
109
operatorC3t3_initializer110 void operator()(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria& criteria,
111 bool with_features,
112 const parameters::internal::Mesh_3_options& mesh_options)
113 {
114 return Base::operator()(c3t3, domain, criteria, with_features, mesh_options);
115 }
116 };
117
118 // Specialization when the mesh domain has 'Has_features'
119 template <typename C3T3,
120 typename MeshDomain,
121 typename MeshCriteria,
122 typename HasFeatures>
123 struct C3t3_initializer<C3T3, MeshDomain, MeshCriteria, true, HasFeatures>
124 {
125 void operator()(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria& criteria,
126 bool with_features,
127 const parameters::internal::Mesh_3_options& mesh_options)
128 {
129 C3t3_initializer<C3T3, MeshDomain, MeshCriteria, true, typename MeshDomain::Has_features>()
130 (c3t3, domain, criteria, with_features, mesh_options);
131 }
132 };
133
134 // Specialization when the mesh domain has 'Has_features' and it's set to CGAL::Tag_true
135 template < typename C3T3,
136 typename MeshDomain,
137 typename MeshCriteria>
138 struct C3t3_initializer<C3T3, MeshDomain, MeshCriteria, true, CGAL::Tag_true>
139 : public C3t3_initializer_base<C3T3, MeshDomain, MeshCriteria, true, CGAL::Tag_true>
140 {
141 typedef C3t3_initializer_base<C3T3, MeshDomain, MeshCriteria, true, CGAL::Tag_true> Base;
142
143 virtual ~C3t3_initializer() { }
144
145 // this override will be used when initialize_features() is called, in make_mesh_3.h
146 virtual void
147 initialize_features(C3T3& c3t3,
148 const MeshDomain& domain,
149 const MeshCriteria& criteria,
150 const parameters::internal::Mesh_3_options& mesh_options)
151 {
152 return Periodic_3_mesh_3::internal::init_c3t3_with_features
153 (c3t3, domain, criteria, mesh_options.nonlinear_growth_of_balls);
154 }
155
156 void operator()(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria& criteria,
157 bool with_features,
158 const parameters::internal::Mesh_3_options& mesh_options)
159 {
160 return Base::operator()(c3t3, domain, criteria, with_features, mesh_options);
161 }
162 };
163
164 } // namespace internal
165 } // namespace Periodic_3_mesh_3
166
167 // -----------------------------------
168 // make_periodic_3_mesh_3 stuff
169 // -----------------------------------
170
171 // Manual redirections
172 // boost::parameter can't handle make_periodic_3_mesh_3 return_type alone...
173 template <typename C3T3, typename MD, typename MC, typename ... T>
174 C3T3 make_periodic_3_mesh_3(const MD& md, const MC& mc, const T& ...t)
175 {
176 C3T3 c3t3;
177 make_periodic_3_mesh_3_bp(c3t3,md,mc,t...);
178 return c3t3;
179 }
180
181 #if defined(BOOST_MSVC)
182 # pragma warning(push)
183 # pragma warning(disable:4003) // not enough actual parameters for macro
184 #endif
185
186 // see <CGAL/config.h>
187 CGAL_PRAGMA_DIAG_PUSH
188 // see <CGAL/boost/parameter.h>
189 CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
190
191 BOOST_PARAMETER_FUNCTION(
192 (void),
193 make_periodic_3_mesh_3_bp,
194 parameters::tag,
195 (required (in_out(c3t3),*) (domain,*) (criteria,*) ) // nondeduced
196 (deduced
197 (optional
198 (features_param, (parameters::internal::Features_options), parameters::features(domain))
199 (exude_param, (parameters::internal::Exude_options), parameters::exude())
200 (perturb_param, (parameters::internal::Perturb_options), parameters::perturb())
201 (odt_param, (parameters::internal::Odt_options), parameters::no_odt())
202 (lloyd_param, (parameters::internal::Lloyd_options), parameters::no_lloyd())
203 (mesh_options_param, (parameters::internal::Mesh_3_options),
204 parameters::internal::Mesh_3_options())
205 (manifold_options_param, (parameters::internal::Manifold_options),
206 parameters::internal::Manifold_options())
207 )
208 )
209 )
210 {
211 make_periodic_3_mesh_3_impl(c3t3, domain, criteria,
212 exude_param, perturb_param, odt_param, lloyd_param,
213 features_param.features(), mesh_options_param,
214 manifold_options_param);
215 }
216 CGAL_PRAGMA_DIAG_POP
217
218 #if defined(BOOST_MSVC)
219 # pragma warning(pop)
220 #endif
221
222 /**
223 * @brief This function meshes the domain defined by mesh_traits
224 * (respecting criteria), and outputs the mesh to c3t3
225 *
226 * @param domain the domain to be discretized
227 * @param criteria the criteria
228 * @param exude if it is set to \c true, an exudation step will be done at
229 * the end of the Delaunay refinement process
230 *
231 * @return The mesh as a C3T3 object
232 */
233 template<class C3T3, class MeshDomain, class MeshCriteria>
234 void make_periodic_3_mesh_3_impl(C3T3& c3t3,
235 const MeshDomain& domain,
236 const MeshCriteria& criteria,
237 const parameters::internal::Exude_options& exude,
238 const parameters::internal::Perturb_options& perturb,
239 const parameters::internal::Odt_options& odt,
240 const parameters::internal::Lloyd_options& lloyd,
241 const bool with_features,
242 const parameters::internal::Mesh_3_options&
243 mesh_options = parameters::internal::Mesh_3_options(),
244 const parameters::internal::Manifold_options&
245 manifold_options = parameters::internal::Manifold_options())
246 {
247 // Initialize c3t3
248 Periodic_3_mesh_3::internal::C3t3_initializer<
249 C3T3, MeshDomain, MeshCriteria,
250 Mesh_3::internal::has_Has_features<MeshDomain>::value>()(c3t3,
251 domain,
252 criteria,
253 with_features,
254 mesh_options);
255
256 // Build mesher and launch refinement process
257 refine_periodic_3_mesh_3(c3t3, domain, criteria,
258 exude, perturb, odt, lloyd,
259 parameters::no_reset_c3t3(), // do not reset c3t3 as we just created it
260 mesh_options, manifold_options);
261 }
262
263 } // end namespace CGAL
264
265 #endif // CGAL_PERIODIC_3_MESH_3_MAKE_PERIODIC_3_MESH_3_H
266