Use parameters instead of template

Allows easier initialisation
This commit is contained in:
ange-clement 2023-10-17 15:39:42 +02:00
parent 9fc7230e64
commit f2af65444d
6 changed files with 124 additions and 76 deletions

View File

@ -43,8 +43,9 @@ int main()
Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image);
// Mesh criteria // Mesh criteria
Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1). Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1)
cell_radius_edge_ratio(3).cell_size(3)); .cell_radius_edge_ratio(3).cell_size(3)
);
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria
, params::initial_points_generator(Construct_initial_points_labeled_image(image)) , params::initial_points_generator(Construct_initial_points_labeled_image(image))

View File

@ -38,10 +38,11 @@ namespace CGAL {
namespace Mesh_3 { namespace Mesh_3 {
namespace internal { namespace internal {
template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > template < typename C3T3, typename MeshDomain, typename MeshCriteria >
void void
init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, 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<MeshDomain, C3T3>& generator = parameters::internal::Initial_points_generator_options<MeshDomain, C3T3>()())
{ {
typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Point_3 Point_3;
typedef typename MeshDomain::Index Index; 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 Initial_points_vector::iterator Ipv_iterator;
typedef typename C3T3::Vertex_handle Vertex_handle; typedef typename C3T3::Vertex_handle Vertex_handle;
typedef typename
CGAL::parameters::internal::Initial_points_generator_generator<
std::back_insert_iterator<Initial_points_vector>,
MeshDomain,
C3T3,
InitialPointsGenerator>
Initial_points_generator_generator;
// Mesh initialization : get some points and add them to the mesh // Mesh initialization : get some points and add them to the mesh
Initial_points_vector initial_points; Initial_points_vector initial_points;
auto generator_wrapped =
Initial_points_generator_generator()(generator);
if (nb_initial_points > -1) 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); nb_initial_points);
else //use default number of 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 = typename C3T3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp =
c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); c3t3.triangulation().geom_traits().construct_weighted_point_3_object();
@ -169,22 +160,23 @@ template < typename C3T3,
typename MeshDomain, typename MeshDomain,
typename MeshCriteria, typename MeshCriteria,
bool MeshDomainHasHasFeatures, bool MeshDomainHasHasFeatures,
typename HasFeatures = int, typename HasFeatures = int>
typename InitialPointsGenerator = Null_functor>
struct C3t3_initializer { }; struct C3t3_initializer { };
// Partial specialization of C3t3_initializer // Partial specialization of C3t3_initializer
// Handle cases where MeshDomain::Has_features is not a valid type // Handle cases where MeshDomain::Has_features is not a valid type
template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > template < typename C3T3, typename MD, typename MC, typename HasFeatures>
struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerator > struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures >
{ {
typedef parameters::internal::Mesh_3_options Mesh_3_options; typedef parameters::internal::Mesh_3_options Mesh_3_options;
typedef parameters::internal::Initial_points_generator_options<MD, C3T3> Initial_points_generator_options;
typedef parameters::internal::Initial_points_generator_generator<MD, C3T3> Initial_points_generator_generator;
void operator()(C3T3& c3t3, void operator()(C3T3& c3t3,
const MD& domain, const MD& domain,
const MC& criteria, const MC& criteria,
bool with_features, bool with_features,
Mesh_3_options mesh_options = Mesh_3_options(), 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 ) if ( with_features )
{ {
@ -199,18 +191,20 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerat
// Partial specialization of C3t3_initializer // Partial specialization of C3t3_initializer
// Handles cases where MeshDomain::Has_features is a valid type // Handles cases where MeshDomain::Has_features is a valid type
template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > template < typename C3T3, typename MD, typename MC, typename HasFeatures >
struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerator > struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures >
{ {
typedef parameters::internal::Mesh_3_options Mesh_3_options; typedef parameters::internal::Mesh_3_options Mesh_3_options;
typedef parameters::internal::Initial_points_generator_options<MD, C3T3> Initial_points_generator_options;
typedef parameters::internal::Initial_points_generator_generator<MD, C3T3> Initial_points_generator_generator;
void operator()(C3T3& c3t3, void operator()(C3T3& c3t3,
const MD& domain, const MD& domain,
const MC& criteria, const MC& criteria,
bool with_features, bool with_features,
Mesh_3_options mesh_options = Mesh_3_options(), 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); (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 // Partial specialization of C3t3_initializer
// Handles cases where MeshDomain::Has_features is a valid type and is defined // Handles cases where MeshDomain::Has_features is a valid type and is defined
// to CGAL::Tag_true // to CGAL::Tag_true
template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > template < typename C3T3, typename MD, typename MC >
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGenerator > struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true >
: public C3t3_initializer_base < C3T3, MD, MC > : public C3t3_initializer_base < C3T3, MD, MC >
{ {
virtual ~C3t3_initializer() { } virtual ~C3t3_initializer() { }
typedef parameters::internal::Mesh_3_options Mesh_3_options; typedef parameters::internal::Mesh_3_options Mesh_3_options;
typedef parameters::internal::Initial_points_generator_options<MD, C3T3> Initial_points_generator_options;
typedef parameters::internal::Initial_points_generator_generator<MD, C3T3> Initial_points_generator_generator;
void operator()(C3T3& c3t3, void operator()(C3T3& c3t3,
const MD& domain, const MD& domain,
const MC& criteria, const MC& criteria,
bool with_features, bool with_features,
Mesh_3_options mesh_options = Mesh_3_options(), 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 ) { if ( with_features ) {
this->initialize_features(c3t3, domain, criteria,mesh_options); 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 // Partial specialization of C3t3_initializer
// Handles cases where MeshDomain::Has_features is a valid type and is defined // Handles cases where MeshDomain::Has_features is a valid type and is defined
// to CGAL::Tag_false // to CGAL::Tag_false
template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > template < typename C3T3, typename MD, typename MC >
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGenerator > struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false >
{ {
typedef parameters::internal::Mesh_3_options Mesh_3_options; typedef parameters::internal::Mesh_3_options Mesh_3_options;
typedef parameters::internal::Initial_points_generator_options<MD, C3T3> Initial_points_generator_options;
typedef parameters::internal::Initial_points_generator_generator<MD, C3T3> Initial_points_generator_generator;
void operator()(C3T3& c3t3, void operator()(C3T3& c3t3,
const MD& domain, const MD& domain,
const MC& criteria, const MC& criteria,
bool with_features, bool with_features,
Mesh_3_options mesh_options = Mesh_3_options(), 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 ) 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::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::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()); 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<MeshDomain, C3T3> initial_points_generator_options_param =
parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>()
(choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), parameters::default_initial_points_generation()));
make_mesh_3_impl(c3t3, domain, criteria, make_mesh_3_impl(c3t3, domain, criteria,
exude_param, perturb_param, odt_param, lloyd_param, exude_param, perturb_param, odt_param, lloyd_param,
features_param.features(), mesh_options_param, features_param.features(), mesh_options_param,
manifold_options_param, manifold_options_param,
initial_points_generator_param); initial_points_generator_options_param);
return c3t3; return c3t3;
} }
@ -511,7 +512,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria,
* *
* @return The mesh as a C3T3 object * @return The mesh as a C3T3 object
*/ */
template<class C3T3, class MeshDomain, class MeshCriteria, class InitialPointsGenerator = Null_functor> template<class C3T3, class MeshDomain, class MeshCriteria>
void make_mesh_3_impl(C3T3& c3t3, void make_mesh_3_impl(C3T3& c3t3,
const MeshDomain& domain, const MeshDomain& domain,
const MeshCriteria& criteria, const MeshCriteria& criteria,
@ -524,25 +525,24 @@ void make_mesh_3_impl(C3T3& c3t3,
mesh_options = parameters::internal::Mesh_3_options(), mesh_options = parameters::internal::Mesh_3_options(),
const parameters::internal::Manifold_options& const parameters::internal::Manifold_options&
manifold_options = 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<MeshDomain, C3T3>&
initial_points_generator_options = parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>()())
{ {
// InitialPointsGenerator& generator = Null_functor_internal::default_null_functor
#ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING
CGAL::get_default_random() = CGAL::Random(0); CGAL::get_default_random() = CGAL::Random(0);
#endif #endif
// Initialize c3t3 // Initialize c3t3
Mesh_3::internal::C3t3_initializer< Mesh_3::internal::C3t3_initializer<
C3T3, C3T3,
MeshDomain, MeshDomain,
MeshCriteria, MeshCriteria,
::CGAL::internal::has_Has_features<MeshDomain>::value, ::CGAL::internal::has_Has_features<MeshDomain>::value>() (c3t3,
int, /*Type of MeshDomain::Has_features not determined*/
InitialPointsGenerator >() (c3t3,
domain, domain,
criteria, criteria,
with_features, with_features,
mesh_options, mesh_options,
generator); initial_points_generator_options);
CGAL_assertion( c3t3.triangulation().dimension() >= 2 ); CGAL_assertion( c3t3.triangulation().dimension() >= 2 );

View File

@ -168,41 +168,53 @@ private:
}; };
// Initial points generator // Initial points generator
template <typename OutputIterator, typename MeshDomain, typename C3t3> // options_holder has two roles.
struct Initial_points_generator_wrapper // 1 : determine if the default value is passed
// 2 : if not the default value, hold the user's generator
template <typename Initial_points_generator = nullptr_t>
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<nullptr_t>
{
static constexpr bool is_default = true;
};
// options is holding the generator (default or the user's one)
template <typename MeshDomain, typename C3t3>
struct Initial_points_generator_options
{
typedef typename std::back_insert_iterator<std::vector<std::pair<typename MeshDomain::Point_3, typename MeshDomain::Index>>> OutputIterator;
template <typename Initial_points_generator> template <typename Initial_points_generator>
Initial_points_generator_wrapper(Initial_points_generator& generator) Initial_points_generator_options(const Initial_points_generator& generator)
: initial_points_generator_default_(generator) : initial_points_generator_no_number_of_points_(generator)
, initial_points_generator_(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); return initial_points_generator_(pts, domain, c3t3, n);
} }
private: private:
const std::function<OutputIterator(OutputIterator,MeshDomain,C3t3)> initial_points_generator_default_; const std::function<OutputIterator(OutputIterator,MeshDomain,C3t3)> initial_points_generator_no_number_of_points_;
const std::function<OutputIterator(OutputIterator,MeshDomain,C3t3,int)> initial_points_generator_; const std::function<OutputIterator(OutputIterator,MeshDomain,C3t3,int)> initial_points_generator_;
}; };
template <typename OutputIterator, typename MeshDomain, typename C3t3>
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 // Features generator
@ -246,22 +258,43 @@ struct Domain_features_generator< MeshDomain, true >
} }
}; };
// struct Initial_points_generator_generator // struct Initial_points_generator_generator evaluate the options_holder
template <typename OutputIterator, typename MeshDomain, typename C3t3, typename Initial_points_generator> // and returns the appropriate options.
template <typename MeshDomain, typename C3t3>
struct Initial_points_generator_generator struct Initial_points_generator_generator
{ {
auto operator()(Initial_points_generator& generator) typedef typename std::back_insert_iterator<std::vector<std::pair<typename MeshDomain::Point_3, typename MeshDomain::Index>>> OutputIterator;
{
return Initial_points_generator_wrapper<OutputIterator, MeshDomain, C3t3>(generator);
}
};
template <typename OutputIterator, typename MeshDomain, typename C3t3> typedef Initial_points_generator_options<MeshDomain, C3t3> Initial_points_generator_options;
struct Initial_points_generator_generator<OutputIterator, MeshDomain, C3t3, Null_functor>
{ struct Initial_points_generator_domain_traductor
auto operator()(Null_functor&)
{ {
return Initial_points_generator_default<OutputIterator, MeshDomain, C3t3>(); 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 <typename Initial_points_generator_options_holder>
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());
} }
}; };

View File

@ -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; 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()()); 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 <typename InitialPointsGenerator>
inline Named_function_parameters<::CGAL::parameters::internal::Initial_points_generator_options_holder<InitialPointsGenerator>, ::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<InitialPointsGenerator>, ::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<InitialPointsGenerator>(generator));
}

View File

@ -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(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(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(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_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) CGAL_add_named_parameter_with_compatibility(iso_value_param_t, iso_value_param, iso_value)

View File

@ -53,9 +53,6 @@ struct Null_functor {
typedef Null_tag result_type; typedef Null_tag result_type;
typedef Null_tag second_argument_type; typedef Null_tag second_argument_type;
}; };
namespace Null_functor_internal {
static Null_functor default_null_functor;
}
// For concurrency // For concurrency
struct Sequential_tag {}; struct Sequential_tag {};