mirror of https://github.com/CGAL/cgal
This commit is contained in:
parent
c55477cda3
commit
ce9cd9e596
|
|
@ -35,22 +35,23 @@ typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
||||||
namespace params = CGAL::parameters;
|
namespace params = CGAL::parameters;
|
||||||
|
|
||||||
// Custom_Initial_points_generator will put points on the mesh for initialisation.
|
// Custom_initial_points_generator will put points on the mesh for initialisation.
|
||||||
// Those points are objects of type std::tuple<Weighted_point_3, int, Index>.
|
// Those points are objects of type std::tuple<Weighted_point_3, int, Index>.
|
||||||
// Weighted_point_3 is the point's position and weight,
|
// Weighted_point_3 is the point's position and weight,
|
||||||
// int is the dimension of the minimal dimension subcomplex on which the point lies,
|
// int is the dimension of the minimal dimension subcomplex on which the point lies,
|
||||||
// Index is the underlying subcomplex index.
|
// Index is the underlying subcomplex index.
|
||||||
struct Custom_Initial_points_generator
|
struct Custom_initial_points_generator
|
||||||
{
|
{
|
||||||
CGAL::Image_3& image_;
|
const CGAL::Image_3& image_;
|
||||||
Custom_Initial_points_generator(CGAL::Image_3& image) : image_(image) { }
|
|
||||||
|
|
||||||
template <typename OutputIterator, typename MeshDomain, typename C3t3>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(OutputIterator pts, const MeshDomain& /* domain */, const C3t3& c3t3, int /* n */ = 1) const
|
OutputIterator operator()(OutputIterator pts) const
|
||||||
{
|
{
|
||||||
typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3;
|
typedef Tr::Geom_traits Gt;
|
||||||
typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3;
|
typedef Gt::Point_3 Point_3;
|
||||||
typedef typename C3t3::Triangulation::Geom_traits::Segment_3 Segment_3;
|
typedef Gt::Vector_3 Vector_3;
|
||||||
|
typedef Gt::Segment_3 Segment_3;
|
||||||
|
typedef Mesh_domain::Index Index;
|
||||||
|
|
||||||
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();
|
||||||
|
|
@ -64,10 +65,11 @@ struct Custom_Initial_points_generator
|
||||||
Vector_3 vector = segment.to_vector();
|
Vector_3 vector = segment.to_vector();
|
||||||
double edge_size = 5;
|
double edge_size = 5;
|
||||||
std::size_t nb = static_cast<int>(CGAL::sqrt(segment.squared_length()) / edge_size);
|
std::size_t nb = static_cast<int>(CGAL::sqrt(segment.squared_length()) / edge_size);
|
||||||
|
const double frac = 1. / (double)nb;
|
||||||
|
|
||||||
for (std::size_t i = 1; i < nb; i++)
|
for (std::size_t i = 1; i < nb; i++)
|
||||||
{
|
{
|
||||||
*pts++ = std::make_tuple(
|
*pts++ = {cwp(source + (i * frac) * vector), 1, Index(1));
|
||||||
cwp(source + (i/(double)nb)*vector, edge_size*edge_size), 1, 0);
|
|
||||||
}
|
}
|
||||||
return pts;
|
return pts;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +97,7 @@ int main()
|
||||||
|
|
||||||
/// [Meshing]
|
/// [Meshing]
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria
|
||||||
, params::initial_points_generator(Custom_Initial_points_generator(image))
|
, params::initial_points_generator(Custom_initial_points_generator{ image })
|
||||||
);
|
);
|
||||||
/// [Meshing]
|
/// [Meshing]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ int main()
|
||||||
|
|
||||||
// Creation of the initial_points vector
|
// Creation of the initial_points vector
|
||||||
std::vector<Initial_point_t> initial_points = {
|
std::vector<Initial_point_t> initial_points = {
|
||||||
std::make_tuple(Weighted_point_3(Point_3(30.0, 50.0, 83.33), 30.0), 1, 0),
|
{Weighted_point_3(Point_3(30.0, 50.0, 83.33), 30.0), 1, Index(1)},
|
||||||
std::make_tuple(Weighted_point_3(Point_3(70.0, 50.0, 83.33), 50.0), 1, 0)
|
{Weighted_point_3(Point_3(70.0, 50.0, 83.33), 50.0), 1, Index(1)}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [Meshing]
|
/// [Meshing]
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ struct Construct_initial_points_labeled_image
|
||||||
if (pi_inside_protecting_sphere)
|
if (pi_inside_protecting_sphere)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*pts++ = std::make_tuple(cwp(intersect_point), 2, intersect_index); // dimension 2 by construction, points are on surface
|
*pts++ = {cwp(intersect_point), 2, intersect_index}; // dimension 2 by construction, points are on surface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,38 +38,55 @@ namespace CGAL {
|
||||||
namespace Mesh_3 {
|
namespace Mesh_3 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template < typename C3T3, typename MeshDomain, typename MeshCriteria >
|
template < typename C3T3, typename MeshDomain, typename InitialPointsGenerator >
|
||||||
void
|
void
|
||||||
add_points_from_generator(C3T3& c3t3, const MeshDomain& domain,
|
add_points_from_generator(C3T3& c3t3,
|
||||||
|
const MeshDomain& domain,
|
||||||
const int nb_initial_points,
|
const int nb_initial_points,
|
||||||
const parameters::internal::Initial_points_generator_options<MeshDomain, C3T3>& generator)
|
const InitialPointsGenerator& generator)
|
||||||
{
|
{
|
||||||
typedef typename C3T3::Triangulation Tr;
|
typedef typename C3T3::Triangulation Tr;
|
||||||
|
|
||||||
typedef typename Tr::Geom_traits::Weighted_point_3 Weighted_point_3;
|
|
||||||
typedef typename MeshDomain::Index Index;
|
|
||||||
typedef typename std::tuple<Weighted_point_3, int, Index> Initialization_point;
|
|
||||||
typedef std::vector< Initialization_point > Initial_points_vector;
|
|
||||||
|
|
||||||
typedef typename C3T3::Vertex_handle Vertex_handle;
|
typedef typename C3T3::Vertex_handle Vertex_handle;
|
||||||
typedef CGAL::Mesh_3::Triangulation_helpers<Tr> Th;
|
typedef CGAL::Mesh_3::Triangulation_helpers<Tr> Th;
|
||||||
|
|
||||||
// Mesh initialization : get some points and add them to the mesh
|
using Point_3 = typename Tr::Geom_traits::Point_3;
|
||||||
Initial_points_vector initial_points;
|
using Index = typename MeshDomain::Index;
|
||||||
if (nb_initial_points > -1)
|
using PointIndexPair = std::pair<Point_3, Index>;
|
||||||
generator(std::back_inserter(initial_points), domain, c3t3,
|
using PointDimIndex = parameters::internal::Initial_point_type<MeshDomain, C3t3>;
|
||||||
nb_initial_points);
|
|
||||||
else //use default number of points
|
struct InitialPointPair2TupleConverter
|
||||||
generator(std::back_inserter(initial_points), domain, c3t3);
|
{
|
||||||
|
PointDimIndex operator()(const PointDimIndex& wp_d_i) const
|
||||||
|
{
|
||||||
|
return wp_d_i;
|
||||||
|
}
|
||||||
|
PointDimIndex operator()(const PointIndexPair& p_i) const
|
||||||
|
{
|
||||||
|
auto cwp = Tr::Geom_traits().construct_weighted_point_3_object();
|
||||||
|
return PointDimIndex{ cwp(p_i.first), 2, p_i.second };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<PointDimIndex> initial_points;
|
||||||
|
InitialPointPair2TupleConverter pair2tuple;
|
||||||
|
auto push_initial_point = [&](const auto& initial_pt)->void
|
||||||
|
{
|
||||||
|
initial_points.push_back(pair2tuple(initial_pt));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nb_initial_points > 0)
|
||||||
|
generator(boost::make_function_output_iterator(push_initial_point), nb_initial_points);
|
||||||
|
else
|
||||||
|
generator(boost::make_function_output_iterator(push_initial_point));
|
||||||
|
|
||||||
Tr& triangulation = c3t3.triangulation();
|
|
||||||
|
|
||||||
// Insert points and set their index and dimension
|
// Insert points and set their index and dimension
|
||||||
for (const auto& [weighted_point_3, dimension, index] : initial_points) {
|
for (const auto& [wpoint, dimension, index] : initial_points)
|
||||||
if(Th().inside_protecting_balls(triangulation, Vertex_handle(), weighted_point_3.point()))
|
{
|
||||||
|
if(Th().inside_protecting_balls(c3t3.triangulation(), Vertex_handle(), wpoint.point()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Vertex_handle v = c3t3.triangulation().insert(weighted_point_3);
|
Vertex_handle v = c3t3.triangulation().insert(wpoint);
|
||||||
|
|
||||||
// v could be null if point is hidden
|
// v could be null if point is hidden
|
||||||
if ( v != Vertex_handle() )
|
if ( v != Vertex_handle() )
|
||||||
|
|
@ -80,18 +97,19 @@ add_points_from_generator(C3T3& c3t3, const MeshDomain& domain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename C3T3, typename MeshDomain, typename MeshCriteria >
|
template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitializationOptions>
|
||||||
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,
|
const int nb_initial_points,
|
||||||
const parameters::internal::Initial_points_generator_options<MeshDomain, C3T3>& generator = parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>()())
|
const InitializationOptions& init_generator)
|
||||||
{
|
{
|
||||||
add_points_from_generator<C3T3, MeshDomain, MeshCriteria>(c3t3, domain, nb_initial_points, generator);
|
add_points_from_generator(c3t3, domain, nb_initial_points, init_generator);
|
||||||
|
|
||||||
// If c3t3 initialization is not sufficient (may happen if
|
// If c3t3 initialization is not sufficient (may happen if
|
||||||
// the user has not specified enough points ), add some surface points
|
// the user has not specified enough points ), add some surface points
|
||||||
bool need_more_init = c3t3.triangulation().dimension() != 3 || !generator.is_default();
|
bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_generator.is_default();
|
||||||
if(!need_more_init) {
|
if(!need_more_init)
|
||||||
|
{
|
||||||
CGAL::Mesh_3::C3T3_helpers<C3T3, MeshDomain> helper(c3t3, domain);
|
CGAL::Mesh_3::C3T3_helpers<C3T3, MeshDomain> helper(c3t3, domain);
|
||||||
helper.update_restricted_facets();
|
helper.update_restricted_facets();
|
||||||
|
|
||||||
|
|
@ -106,10 +124,10 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(need_more_init) {
|
if(need_more_init)
|
||||||
parameters::internal::Initial_points_generator_options<MeshDomain, C3T3> domain_generator =
|
{
|
||||||
parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>()();
|
InitializationOptions init_options(domain.construct_initial_points_object());
|
||||||
add_points_from_generator<C3T3, MeshDomain, MeshCriteria>(c3t3, domain, nb_initial_points, domain_generator);
|
add_points_from_generator(c3t3, domain, nb_initial_points, init_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,23 +214,22 @@ template < typename C3T3,
|
||||||
typename MeshDomain,
|
typename MeshDomain,
|
||||||
typename MeshCriteria,
|
typename MeshCriteria,
|
||||||
bool MeshDomainHasHasFeatures,
|
bool MeshDomainHasHasFeatures,
|
||||||
typename HasFeatures = int>
|
typename HasFeatures,
|
||||||
|
typename InitOptions>
|
||||||
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>
|
template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitOptions>
|
||||||
struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures >
|
struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitOptions >
|
||||||
{
|
{
|
||||||
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(),
|
||||||
const Initial_points_generator_options& generator = Initial_points_generator_generator()())
|
const InitOptions& init_options = InitOptions())
|
||||||
{
|
{
|
||||||
if ( with_features )
|
if ( with_features )
|
||||||
{
|
{
|
||||||
|
|
@ -221,48 +238,47 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures >
|
||||||
}
|
}
|
||||||
|
|
||||||
init_c3t3(c3t3,domain,criteria,
|
init_c3t3(c3t3,domain,criteria,
|
||||||
mesh_options.number_of_initial_points, generator);
|
mesh_options.number_of_initial_points,
|
||||||
|
init_options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 >
|
template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitOptions>
|
||||||
struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures >
|
struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitOptions>
|
||||||
{
|
{
|
||||||
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(),
|
||||||
const Initial_points_generator_options& generator = Initial_points_generator_generator()())
|
const InitOptions& init_options = InitOptions())
|
||||||
{
|
{
|
||||||
C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features >()
|
C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitOptions >()
|
||||||
(c3t3,domain,criteria,with_features,mesh_options,generator);
|
(c3t3,domain,criteria,with_features,mesh_options,init_options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 >
|
template < typename C3T3, typename MD, typename MC, typename InitOptions >
|
||||||
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true >
|
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitOptions >
|
||||||
: 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(),
|
||||||
const Initial_points_generator_options& generator = Initial_points_generator_generator()())
|
const InitOptions& init_options = InitOptions())
|
||||||
{
|
{
|
||||||
if ( with_features ) {
|
if ( with_features ) {
|
||||||
this->initialize_features(c3t3, domain, criteria,mesh_options);
|
this->initialize_features(c3t3, domain, criteria,mesh_options);
|
||||||
|
|
@ -270,7 +286,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true >
|
||||||
// If c3t3 initialization is not sufficient (may happen if there is only
|
// If c3t3 initialization is not sufficient (may happen if there is only
|
||||||
// a planar curve as feature for example), add some surface points
|
// a planar curve as feature for example), add some surface points
|
||||||
|
|
||||||
bool need_more_init = c3t3.triangulation().dimension() != 3 || !generator.is_default();
|
bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_options.is_default();
|
||||||
if(!need_more_init) {
|
if(!need_more_init) {
|
||||||
CGAL::Mesh_3::C3T3_helpers<C3T3, MD> helper(c3t3, domain);
|
CGAL::Mesh_3::C3T3_helpers<C3T3, MD> helper(c3t3, domain);
|
||||||
helper.update_restricted_facets();
|
helper.update_restricted_facets();
|
||||||
|
|
@ -288,29 +304,28 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true >
|
||||||
}
|
}
|
||||||
if(need_more_init) {
|
if(need_more_init) {
|
||||||
init_c3t3(c3t3, domain, criteria,
|
init_c3t3(c3t3, domain, criteria,
|
||||||
mesh_options.number_of_initial_points, generator);
|
mesh_options.number_of_initial_points, init_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { init_c3t3(c3t3,domain,criteria,
|
else { init_c3t3(c3t3,domain,criteria,
|
||||||
mesh_options.number_of_initial_points, generator); }
|
mesh_options.number_of_initial_points, init_options); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 >
|
template < typename C3T3, typename MD, typename MC, typename InitOptions >
|
||||||
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false >
|
struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitOptions >
|
||||||
{
|
{
|
||||||
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::Initialization_options<MD, C3T3> Initialization_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(),
|
||||||
const Initial_points_generator_options& generator = Initial_points_generator_generator()())
|
const Initialization_options& init_options = Initialization_options())
|
||||||
{
|
{
|
||||||
if ( with_features )
|
if ( with_features )
|
||||||
{
|
{
|
||||||
|
|
@ -319,7 +334,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false >
|
||||||
}
|
}
|
||||||
|
|
||||||
init_c3t3(c3t3,domain,criteria,
|
init_c3t3(c3t3,domain,criteria,
|
||||||
mesh_options.number_of_initial_points, generator);
|
mesh_options.number_of_initial_points, init_options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -517,22 +532,28 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C
|
||||||
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());
|
||||||
|
|
||||||
using Initial_points_generator_generator = parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>;
|
// range of initial points
|
||||||
using Value_type = typename Initial_points_generator_generator::Value_type;
|
using Initial_point = parameters::internal::Initial_point_type<MeshDomain, C3T3>;
|
||||||
std::vector<Value_type> empty_vec;
|
using Initial_points_range_ref = typename internal_np::Lookup_named_param_def<internal_np::initial_points_param_t,
|
||||||
const auto& initial_points
|
CGAL_NP_CLASS,
|
||||||
= choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec);
|
std::vector<Initial_point>>::type;
|
||||||
parameters::internal::Initial_points_generator_options initial_points_generator_options_param =
|
std::vector<Initial_point> empty_vec;
|
||||||
Initial_points_generator_generator()
|
const Initial_points_range_ref initial_points = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec);
|
||||||
(choose_parameter(get_parameter(np, internal_np::initial_points_generator_param),
|
|
||||||
CGAL::Null_functor()),
|
// initial points generator
|
||||||
initial_points);
|
using Initial_points_generator = typename internal_np::Lookup_named_param_def<internal_np::initial_points_generator_param_t,
|
||||||
|
CGAL_NP_CLASS,
|
||||||
|
typename MeshDomain::Construct_initial_points>::reference;
|
||||||
|
Initial_points_generator initial_points_generator = choose_parameter(get_parameter(np, internal_np::initial_points_generator_param),
|
||||||
|
domain.construct_initial_points_object());
|
||||||
|
const parameters::internal::Initialization_options<MeshDomain, C3T3, Initial_points_generator, Initial_points_range_ref>
|
||||||
|
initial_points_gen_param(initial_points_generator, initial_points);
|
||||||
|
|
||||||
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_options_param);
|
initial_points_gen_param);
|
||||||
return c3t3;
|
return c3t3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -561,7 +582,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>
|
template<class C3T3, class MeshDomain, class MeshCriteria, class InitPtsGenerator>
|
||||||
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,
|
||||||
|
|
@ -574,25 +595,28 @@ 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(),
|
||||||
const parameters::internal::Initial_points_generator_options<MeshDomain, C3T3>&
|
const parameters::internal::Initialization_options<MeshDomain, C3T3, InitPtsGenerator>&
|
||||||
initial_points_generator_options = parameters::internal::Initial_points_generator_generator<MeshDomain, C3T3>()())
|
initialization_options = parameters::internal::Initialization_options<MeshDomain, C3T3, InitPtsGenerator>())
|
||||||
{
|
{
|
||||||
// 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
|
||||||
|
|
||||||
|
using Init_options = parameters::internal::Initialization_options<MeshDomain, C3T3, InitPtsGenerator>;
|
||||||
|
|
||||||
// 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 > () (c3t3,
|
::CGAL::internal::has_Has_features<MeshDomain>::value,
|
||||||
|
int,
|
||||||
|
Init_options>() (c3t3,
|
||||||
domain,
|
domain,
|
||||||
criteria,
|
criteria,
|
||||||
with_features,
|
with_features,
|
||||||
mesh_options,
|
mesh_options,
|
||||||
initial_points_generator_options);
|
initialization_options);
|
||||||
|
|
||||||
CGAL_assertion( c3t3.triangulation().dimension() >= 2 );
|
CGAL_assertion( c3t3.triangulation().dimension() >= 2 );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include <CGAL/STL_Extension/internal/Has_features.h>
|
#include <CGAL/STL_Extension/internal/Has_features.h>
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
#include <boost/iterator/function_output_iterator.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -169,135 +171,59 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mesh initialization
|
// Mesh initialization
|
||||||
// This process has two parameters : `initial_points_generator` and `initial_points`.
|
|
||||||
// These two parameters are packed into a `Initial_points_generator_options`
|
|
||||||
// that do not know the parameters types.
|
|
||||||
// To remove the type of the `initial_points_generator` functor, two `std::function` are used.
|
|
||||||
// To remove the type of the `initial_points` container, two `Input_const_iterator_interface` are used.
|
|
||||||
|
|
||||||
// A common interface for an iterator to a const value.
|
template<typename MeshDomain, typename C3t3>
|
||||||
template <typename Value>
|
struct Initial_point_type
|
||||||
class Input_const_iterator_interface
|
|
||||||
{
|
{
|
||||||
public:
|
typename C3t3::Triangulation::Point m_point;
|
||||||
virtual ~Input_const_iterator_interface() {}
|
int m_dimension;
|
||||||
virtual const Value& operator*() = 0;
|
typename MeshDomain::Index m_index;
|
||||||
virtual Input_const_iterator_interface<Value>* operator++() = 0;
|
|
||||||
virtual bool operator!=(const Input_const_iterator_interface<Value>* other) const = 0;
|
|
||||||
virtual Input_const_iterator_interface<Value>* clone() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// An iterator container that implements the `Input_const_iterator_interface` interface.
|
|
||||||
template <typename Value, typename Iterator>
|
|
||||||
struct Input_const_iterator_container
|
|
||||||
: Input_const_iterator_interface<Value>
|
|
||||||
{
|
|
||||||
typedef Input_const_iterator_container<Value, Iterator> Self;
|
|
||||||
public:
|
|
||||||
Input_const_iterator_container(const Iterator& it) : it_(it) {}
|
|
||||||
|
|
||||||
~Input_const_iterator_container() override {}
|
|
||||||
|
|
||||||
const Value& operator*() override
|
|
||||||
{
|
|
||||||
return *it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Input_const_iterator_interface<Value>* operator++() override
|
|
||||||
{
|
|
||||||
++it_;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const Input_const_iterator_interface<Value>* other) const override
|
|
||||||
{
|
|
||||||
const Self* other_casted = dynamic_cast<const Self*>(other);
|
|
||||||
if (other_casted == nullptr)
|
|
||||||
return true;
|
|
||||||
return it_ != other_casted->it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Input_const_iterator_interface<Value>* clone() override
|
|
||||||
{
|
|
||||||
return new Input_const_iterator_container<Value, Iterator>(it_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Iterator it_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Holds the two parameters `initial_points_generator` and `initial_points`,
|
// Holds the two parameters `initial_points_generator` and `initial_points`,
|
||||||
// without knowing their types, into a single generator.
|
// without knowing their types, into a single generator.
|
||||||
template <typename MeshDomain, typename C3t3>
|
template <typename MeshDomain,
|
||||||
struct Initial_points_generator_options
|
typename C3t3,
|
||||||
|
typename InitialPointsGenerator = typename MeshDomain::Construct_initial_points,
|
||||||
|
typename InitialPointsRange = std::vector<Initial_point_type<MeshDomain, C3t3> > >
|
||||||
|
struct Initialization_options
|
||||||
{
|
{
|
||||||
typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3;
|
using DefaultGenerator = typename MeshDomain::Construct_initial_points;
|
||||||
typedef typename MeshDomain::Index Index;
|
using Initial_points_const_iterator = typename InitialPointsRange::const_iterator;
|
||||||
typedef typename std::tuple<Weighted_point_3, int, Index> Value_type;
|
using Initial_point = typename std::iterator_traits<Initial_points_const_iterator>::value_type;
|
||||||
typedef typename std::back_insert_iterator<std::vector<Value_type>> OutputIterator;
|
|
||||||
|
|
||||||
template <typename Initial_points_generator, typename Initial_points>
|
Initialization_options()
|
||||||
Initial_points_generator_options(const Initial_points_generator& generator, const Initial_points& initial_points, bool is_default = false)
|
: is_default_(true)
|
||||||
: initial_points_generator_no_number_of_points_(generator)
|
{}
|
||||||
, initial_points_generator_(generator)
|
|
||||||
, is_default_(is_default && initial_points.size() == 0)
|
|
||||||
{
|
|
||||||
if (initial_points.size() == 0)
|
|
||||||
{
|
|
||||||
begin_it = nullptr;
|
|
||||||
end_it = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using Iterator_type = typename Initial_points::const_iterator;
|
|
||||||
begin_it = new Input_const_iterator_container<Value_type, Iterator_type>(initial_points.cbegin());
|
|
||||||
end_it = new Input_const_iterator_container<Value_type, Iterator_type>(initial_points.cend());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Initial_points_generator_options()
|
Initialization_options(const InitialPointsGenerator& generator,
|
||||||
{
|
const InitialPointsRange& initial_points = InitialPointsRange())
|
||||||
if (begin_it != nullptr)
|
: initial_points_generator_(generator)
|
||||||
delete begin_it;
|
, begin_it(initial_points.begin())
|
||||||
if (end_it != nullptr)
|
, end_it(initial_points.end())
|
||||||
delete end_it;
|
, is_default_(boost::is_same<InitialPointsGenerator, DefaultGenerator>::value
|
||||||
}
|
&& std::empty(initial_points))
|
||||||
|
{}
|
||||||
|
|
||||||
// Firstly, the `initial_points` are inserted, then, the `initial_points_generator` is called.
|
template<typename OutputIterator>
|
||||||
OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const
|
OutputIterator operator()(OutputIterator pts, int n = 0) const
|
||||||
{
|
{
|
||||||
add_initial_points(pts);
|
// add initial_points
|
||||||
return initial_points_generator_no_number_of_points_(pts, domain, c3t3);
|
for (typename InitialPointsRange::const_iterator it = begin_it; it != end_it; ++it)
|
||||||
}
|
*pts++ = *it;
|
||||||
|
|
||||||
OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) const
|
return initial_points_generator_(pts, n);
|
||||||
{
|
|
||||||
add_initial_points(pts);
|
|
||||||
return initial_points_generator_(pts, domain, c3t3, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputIterator add_initial_points(OutputIterator pts) const
|
|
||||||
{
|
|
||||||
if (begin_it != nullptr && end_it != nullptr)
|
|
||||||
{
|
|
||||||
Input_const_iterator_interface<Value_type>* it_ptr = begin_it->clone();
|
|
||||||
Input_const_iterator_interface<Value_type>& it = *(it_ptr);
|
|
||||||
for (; it != end_it; ++it)
|
|
||||||
*pts++ = *it;
|
|
||||||
delete it_ptr;
|
|
||||||
}
|
|
||||||
return pts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_default() const { return is_default_; }
|
bool is_default() const { return is_default_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The two functions holds the `initial_points_generator` functor
|
InitialPointsGenerator initial_points_generator_;
|
||||||
const std::function<OutputIterator(OutputIterator&,const MeshDomain&,const C3t3&)> initial_points_generator_no_number_of_points_;
|
|
||||||
const std::function<OutputIterator(OutputIterator&,const MeshDomain&,const C3t3&,int)> initial_points_generator_;
|
// The two iterators point to the `initial_points` container
|
||||||
// The two iterators holds the `initial_points` container
|
Initial_points_const_iterator begin_it;
|
||||||
Input_const_iterator_interface<Value_type>* begin_it;
|
Initial_points_const_iterator end_it;
|
||||||
Input_const_iterator_interface<Value_type>* end_it;
|
|
||||||
// Is the option a default-constructed one ?
|
// Is the option a default-constructed one ?
|
||||||
const bool is_default_;
|
const bool is_default_;
|
||||||
};
|
};
|
||||||
|
|
@ -345,14 +271,14 @@ struct Domain_features_generator< MeshDomain, true >
|
||||||
};
|
};
|
||||||
|
|
||||||
// Evaluate the two parameters `initial_points_generator` and `initial_points`
|
// Evaluate the two parameters `initial_points_generator` and `initial_points`
|
||||||
// and returns the appropriate `Initial_points_generator_options`.
|
// and returns the appropriate `Initialization_options`.
|
||||||
// If no generator and no initial points, then use the domain's construct_initial_points_object.
|
// If no generator and no initial points, then use the domain's construct_initial_points_object.
|
||||||
template <typename MeshDomain, typename C3t3>
|
template <typename MeshDomain, typename C3t3>
|
||||||
struct Initial_points_generator_generator
|
struct Initial_points_generator_generator
|
||||||
{
|
{
|
||||||
typedef typename CGAL::parameters::internal::Initial_points_generator_options<MeshDomain, C3t3> Initial_points_generator_options;
|
typedef typename CGAL::parameters::internal::Initialization_options<MeshDomain, C3t3> Initialization_options;
|
||||||
typedef typename Initial_points_generator_options::Value_type Value_type;
|
typedef typename Initialization_options::Value_type Value_type;
|
||||||
typedef typename Initial_points_generator_options::OutputIterator OutputIterator;
|
typedef typename Initialization_options::OutputIterator OutputIterator;
|
||||||
|
|
||||||
struct Initial_points_generator_domain_traductor
|
struct Initial_points_generator_domain_traductor
|
||||||
{
|
{
|
||||||
|
|
@ -392,31 +318,31 @@ struct Initial_points_generator_generator
|
||||||
|
|
||||||
// With a custom InitialPointsGenerator
|
// With a custom InitialPointsGenerator
|
||||||
template <typename InitialPointsGenerator, typename InitalPointsRange>
|
template <typename InitialPointsGenerator, typename InitalPointsRange>
|
||||||
Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator, const InitalPointsRange& input_features)
|
Initialization_options operator()(const InitialPointsGenerator& initial_points_generator, const InitalPointsRange& input_points)
|
||||||
{
|
{
|
||||||
return Initial_points_generator_options(initial_points_generator, input_features, false);
|
return Initialization_options(initial_points_generator, input_points, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InitialPointsGenerator>
|
template <typename InitialPointsGenerator>
|
||||||
Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator)
|
Initialization_options operator()(const InitialPointsGenerator& initial_points_generator)
|
||||||
{
|
{
|
||||||
std::vector<Value_type> empty_input_features;
|
std::vector<Value_type> empty_input_points;
|
||||||
return operator()(initial_points_generator, empty_input_features);
|
return operator()(initial_points_generator, empty_input_points);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without a custom InitialPointsGenerator
|
// Without a custom InitialPointsGenerator
|
||||||
template <typename InitalPointsRange>
|
template <typename InitalPointsRange>
|
||||||
Initial_points_generator_options operator()(const Null_functor&, const InitalPointsRange& input_features)
|
Initialization_options operator()(const Null_functor&, const InitalPointsRange& input_points)
|
||||||
{
|
{
|
||||||
// The domain's construct_initial_points_object is called only if input_features is empty
|
// The domain's construct_initial_points_object is called only if input_points is empty
|
||||||
if (input_features.size() == 0) {
|
if (input_points.empty()) {
|
||||||
return Initial_points_generator_options(Initial_points_generator_domain_traductor(), input_features, true);
|
return Initialization_options(Initial_points_generator_domain_traductor(), input_points, true);
|
||||||
}
|
}
|
||||||
return Initial_points_generator_options(Initial_points_generator_empty(), input_features, true);
|
return Initialization_options(Initial_points_generator_empty(), input_features, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default construction
|
// Default construction
|
||||||
Initial_points_generator_options operator()()
|
Initialization_options operator()()
|
||||||
{
|
{
|
||||||
return operator()(Null_functor());
|
return operator()(Null_functor());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue