diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp index cdf3a44e1a4..17e5fcb0638 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp @@ -43,8 +43,9 @@ int main() Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria - Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1). - cell_radius_edge_ratio(3).cell_size(3)); + Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1) + .cell_radius_edge_ratio(3).cell_size(3) + ); C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria , params::initial_points_generator(Construct_initial_points_labeled_image(image)) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 8c1581368f4..a62b87cf4da 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -38,10 +38,11 @@ namespace CGAL { namespace Mesh_3 { namespace internal { -template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > +template < typename C3T3, typename MeshDomain, typename MeshCriteria > void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, - const int nb_initial_points, InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const int nb_initial_points, + const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_options()()) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -49,23 +50,13 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, typedef typename Initial_points_vector::iterator Ipv_iterator; typedef typename C3T3::Vertex_handle Vertex_handle; - typedef typename - CGAL::parameters::internal::Initial_points_generator_generator< - std::back_insert_iterator, - MeshDomain, - C3T3, - InitialPointsGenerator> - Initial_points_generator_generator; - // Mesh initialization : get some points and add them to the mesh Initial_points_vector initial_points; - auto generator_wrapped = - Initial_points_generator_generator()(generator); if (nb_initial_points > -1) - generator_wrapped(std::back_inserter(initial_points), domain, c3t3, + generator(std::back_inserter(initial_points), domain, c3t3, nb_initial_points); else //use default number of points - generator_wrapped(std::back_inserter(initial_points), domain, c3t3); + generator(std::back_inserter(initial_points), domain, c3t3); typename C3T3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); @@ -169,22 +160,23 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria, bool MeshDomainHasHasFeatures, - typename HasFeatures = int, - typename InitialPointsGenerator = Null_functor> + typename HasFeatures = int> struct C3t3_initializer { }; // Partial specialization of C3t3_initializer // Handle cases where MeshDomain::Has_features is not a valid type -template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > -struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerator > +template < typename C3T3, typename MD, typename MC, typename HasFeatures> +struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures > { typedef parameters::internal::Mesh_3_options Mesh_3_options; + typedef parameters::internal::Initial_points_generator_options Initial_points_generator_options; + typedef parameters::internal::Initial_points_generator_generator Initial_points_generator_generator; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const Initial_points_generator_options& generator = Initial_points_generator_generator()()) { if ( with_features ) { @@ -199,18 +191,20 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerat // Partial specialization of C3t3_initializer // Handles cases where MeshDomain::Has_features is a valid type -template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > -struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerator > +template < typename C3T3, typename MD, typename MC, typename HasFeatures > +struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures > { typedef parameters::internal::Mesh_3_options Mesh_3_options; + typedef parameters::internal::Initial_points_generator_options Initial_points_generator_options; + typedef parameters::internal::Initial_points_generator_generator Initial_points_generator_generator; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const Initial_points_generator_options& generator = Initial_points_generator_generator()()) { - C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() + C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features >() (c3t3,domain,criteria,with_features,mesh_options,generator); } }; @@ -218,19 +212,21 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerato // Partial specialization of C3t3_initializer // Handles cases where MeshDomain::Has_features is a valid type and is defined // to CGAL::Tag_true -template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGenerator > +template < typename C3T3, typename MD, typename MC > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > : public C3t3_initializer_base < C3T3, MD, MC > { virtual ~C3t3_initializer() { } typedef parameters::internal::Mesh_3_options Mesh_3_options; + typedef parameters::internal::Initial_points_generator_options Initial_points_generator_options; + typedef parameters::internal::Initial_points_generator_generator Initial_points_generator_generator; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const Initial_points_generator_options& generator = Initial_points_generator_generator()()) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -267,16 +263,18 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGener // Partial specialization of C3t3_initializer // Handles cases where MeshDomain::Has_features is a valid type and is defined // to CGAL::Tag_false -template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGenerator > +template < typename C3T3, typename MD, typename MC > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > { typedef parameters::internal::Mesh_3_options Mesh_3_options; + typedef parameters::internal::Initial_points_generator_options Initial_points_generator_options; + typedef parameters::internal::Initial_points_generator_generator Initial_points_generator_generator; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const Initial_points_generator_options& generator = Initial_points_generator_generator()()) { if ( with_features ) { @@ -476,13 +474,16 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C parameters::internal::Features_options features_param = choose_parameter(get_parameter(np, internal_np::features_options_param), parameters::features(domain).v); parameters::internal::Mesh_3_options mesh_options_param = choose_parameter(get_parameter(np, internal_np::mesh_param), parameters::internal::Mesh_3_options()); parameters::internal::Manifold_options manifold_options_param = choose_parameter(get_parameter(np, internal_np::manifold_param), parameters::internal::Manifold_options()); - auto initial_points_generator_param = choose_parameter(get_parameter(np, internal_np::initial_points_generator_param), Null_functor()); + + parameters::internal::Initial_points_generator_options initial_points_generator_options_param = + parameters::internal::Initial_points_generator_generator() + (choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), parameters::default_initial_points_generation())); make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, features_param.features(), mesh_options_param, manifold_options_param, - initial_points_generator_param); + initial_points_generator_options_param); return c3t3; } @@ -511,7 +512,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, * * @return The mesh as a C3T3 object */ -template +template void make_mesh_3_impl(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria& criteria, @@ -524,25 +525,24 @@ void make_mesh_3_impl(C3T3& c3t3, mesh_options = parameters::internal::Mesh_3_options(), const parameters::internal::Manifold_options& manifold_options = parameters::internal::Manifold_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + const parameters::internal::Initial_points_generator_options& + initial_points_generator_options = parameters::internal::Initial_points_generator_generator()()) { +// InitialPointsGenerator& generator = Null_functor_internal::default_null_functor #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); #endif - // Initialize c3t3 Mesh_3::internal::C3t3_initializer< C3T3, MeshDomain, MeshCriteria, - ::CGAL::internal::has_Has_features::value, - int, /*Type of MeshDomain::Has_features not determined*/ - InitialPointsGenerator >() (c3t3, + ::CGAL::internal::has_Has_features::value>() (c3t3, domain, criteria, with_features, mesh_options, - generator); + initial_points_generator_options); CGAL_assertion( c3t3.triangulation().dimension() >= 2 ); diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_option_classes.h b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_option_classes.h index 97defe20378..c7bb4b368ad 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_option_classes.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_option_classes.h @@ -168,41 +168,53 @@ private: }; // Initial points generator -template -struct Initial_points_generator_wrapper +// options_holder has two roles. +// 1 : determine if the default value is passed +// 2 : if not the default value, hold the user's generator +template +struct Initial_points_generator_options_holder { + static constexpr bool is_default = false; + + Initial_points_generator_options_holder(const Initial_points_generator& generator) + : generator_(generator) + { } + + const Initial_points_generator& generator_; +}; + +template <> +struct Initial_points_generator_options_holder +{ + static constexpr bool is_default = true; +}; + +// options is holding the generator (default or the user's one) +template +struct Initial_points_generator_options +{ + typedef typename std::back_insert_iterator>> OutputIterator; + template - Initial_points_generator_wrapper(Initial_points_generator& generator) - : initial_points_generator_default_(generator) + Initial_points_generator_options(const Initial_points_generator& generator) + : initial_points_generator_no_number_of_points_(generator) , initial_points_generator_(generator) { } - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const { - return initial_points_generator_default_(pts, domain, c3t3); + return initial_points_generator_no_number_of_points_(pts, domain, c3t3); } - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) const { return initial_points_generator_(pts, domain, c3t3, n); } private: - const std::function initial_points_generator_default_; + const std::function initial_points_generator_no_number_of_points_; const std::function initial_points_generator_; }; -template -struct Initial_points_generator_default -{ - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) - { - return domain.construct_initial_points_object()(pts); - } - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) - { - return domain.construct_initial_points_object()(pts, n); - } -}; // ----------------------------------- // Features generator @@ -246,22 +258,43 @@ struct Domain_features_generator< MeshDomain, true > } }; -// struct Initial_points_generator_generator -template +// struct Initial_points_generator_generator evaluate the options_holder +// and returns the appropriate options. +template struct Initial_points_generator_generator { - auto operator()(Initial_points_generator& generator) - { - return Initial_points_generator_wrapper(generator); - } -}; + typedef typename std::back_insert_iterator>> OutputIterator; -template -struct Initial_points_generator_generator -{ - auto operator()(Null_functor&) + typedef Initial_points_generator_options Initial_points_generator_options; + + struct Initial_points_generator_domain_traductor { - return Initial_points_generator_default(); + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) + { + return domain.construct_initial_points_object()(pts); + } + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) + { + return domain.construct_initial_points_object()(pts, n); + } + }; + + template + Initial_points_generator_options operator()(const Initial_points_generator_options_holder& initial_points_generator_options_holder_param) + { + if constexpr (Initial_points_generator_options_holder::is_default) + { + return operator()(); + } + else + { + return Initial_points_generator_options(initial_points_generator_options_holder_param.generator_); + } + } + + Initial_points_generator_options operator()() + { + return Initial_points_generator_options(Initial_points_generator_domain_traductor()); } }; diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h index ece342c321b..93e77e5b46c 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h @@ -368,3 +368,20 @@ features(const MeshDomain& /*domain*/) typedef Named_function_parameters<::CGAL::parameters::internal::Features_options, ::CGAL::internal_np::features_option_param_t, CGAL_NP_BASE> Param; return CGAL_NP_BUILD(Param,Generator()()); } + +// ----------------------------------- +// Initial_points_generator_options +// ----------------------------------- +inline Named_function_parameters<::CGAL::parameters::internal::Initial_points_generator_options_holder<>, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> +default_initial_points_generation() { + typedef Named_function_parameters<::CGAL::parameters::internal::Initial_points_generator_options_holder<>, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> Param; + return CGAL_NP_BUILD(Param, ::CGAL::parameters::internal::Initial_points_generator_options_holder<>()); +} + +template +inline Named_function_parameters<::CGAL::parameters::internal::Initial_points_generator_options_holder, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> +initial_points_generator(const InitialPointsGenerator& generator) +{ + typedef Named_function_parameters<::CGAL::parameters::internal::Initial_points_generator_options_holder, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> Param; + return CGAL_NP_BUILD(Param, ::CGAL::parameters::internal::Initial_points_generator_options_holder(generator)); +} diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 1ef07d492d8..57715ff5a2a 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -323,7 +323,7 @@ CGAL_add_named_parameter_with_compatibility(do_reset_c3t3_t, do_reset_c3t3, do_r CGAL_add_named_parameter_with_compatibility(mesh_param_t, mesh_param, mesh_options) CGAL_add_named_parameter_with_compatibility(manifold_param_t, manifold_param, manifold_option) CGAL_add_named_parameter_with_compatibility(features_option_param_t,features_options_param,features_options) -CGAL_add_named_parameter_with_compatibility(initial_points_generator_param_t,initial_points_generator_param,initial_points_generator) +CGAL_add_named_parameter_with_compatibility(initial_points_generator_options_param_t,initial_points_generator_options_param,initial_points_generator_options) CGAL_add_named_parameter_with_compatibility_cref_only(image_3_param_t, image_3_param, image) CGAL_add_named_parameter_with_compatibility(iso_value_param_t, iso_value_param, iso_value) diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 1fcff383e3e..6aa1988e1cc 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -53,9 +53,6 @@ struct Null_functor { typedef Null_tag result_type; typedef Null_tag second_argument_type; }; -namespace Null_functor_internal { - static Null_functor default_null_functor; -} // For concurrency struct Sequential_tag {};