From 3937c5df346053de8d0f42ceeb8fdac44d0e8b35 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 13 Oct 2023 14:51:43 +0200 Subject: [PATCH 01/99] Implemented make_mesh_3 param : initial_points_generator --- Mesh_3/examples/Mesh_3/CMakeLists.txt | 6 + .../mesh_3D_image_with_initial_points.cpp | 58 +++++ ...struct_initial_points_from_labeled_image.h | 238 ++++++++++++++++++ ...tialize_triangulation_from_labeled_image.h | 231 +++-------------- Mesh_3/include/CGAL/make_mesh_3.h | 100 ++++++-- .../internal/mesh_option_classes.h | 58 +++++ .../internal/parameters_interface.h | 1 + 7 files changed, 462 insertions(+), 230 deletions(-) create mode 100644 Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp create mode 100644 Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 0b59088e04a..90857127a80 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -167,6 +167,11 @@ if(TARGET CGAL::CGAL_ImageIO) target_link_libraries(mesh_3D_gray_image_with_custom_initialization PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program( + "mesh_3D_image_with_initial_points.cpp") + target_link_libraries(mesh_3D_image_with_initial_points + PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("mesh_3D_image_variable_size.cpp") target_link_libraries(mesh_3D_image_variable_size PUBLIC CGAL::Eigen3_support) @@ -201,6 +206,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) mesh_3D_image_variable_size mesh_3D_image_with_custom_initialization mesh_3D_gray_image_with_custom_initialization + mesh_3D_image_with_initial_points mesh_3D_image_with_features mesh_3D_image_with_detection_of_features mesh_3D_image_with_input_features 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 new file mode 100644 index 00000000000..e065062697d --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp @@ -0,0 +1,58 @@ +#include "random_labeled_image.h" +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +#ifdef CGAL_CONCURRENT_MESH_3 +typedef CGAL::Parallel_tag Concurrency_tag; +#else +typedef CGAL::Sequential_tag Concurrency_tag; +#endif + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; + +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +namespace params = CGAL::parameters; + +int main() +{ + /// [Create the image] + CGAL::Image_3 image = random_labeled_image(); + /// [Create the image] + + // Domain + 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)); + + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + params::initial_points_generator(Construct_initial_points_labeled_image(image)) + ); + /// [Meshing] + + // Output + CGAL::dump_c3t3(c3t3, "out"); + + return 0; +} diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h new file mode 100644 index 00000000000..878af535821 --- /dev/null +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h @@ -0,0 +1,238 @@ +// Copyright (c) 20XX,20XX GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Ange Clement + +#ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H +#define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H + +#include + +#include + +#include +#include + +#include + +template +struct Get_point +{ + const double vx, vy, vz; + const double tx, ty, tz; + const std::size_t xdim, ydim, zdim; + Get_point(const CGAL::Image_3* image) + : vx(image->vx()) + , vy(image->vy()) + , vz(image->vz()) + , tx(image->tx()) + , ty(image->ty()) + , tz(image->tz()) + , xdim(image->xdim()) + , ydim(image->ydim()) + , zdim(image->zdim()) + {} + + Point operator()(const std::size_t i, + const std::size_t j, + const std::size_t k) const + { + double x = double(i) * vx + tx; + double y = double(j) * vy + ty; + double z = double(k) * vz + tz; + + if (i == 0) x += 1. / 6. * vx; + else if (i == xdim - 1) x -= 1. / 6. * vx; + if (j == 0) y += 1. / 6. * vy; + else if (j == ydim - 1) y -= 1. / 6. * vy; + if (k == 0) z += 1. / 6. * vz; + else if (k == zdim - 1) z -= 1. / 6. * vz; + + return Point(x, y, z); + } +}; + +struct Construct_initial_points_labeled_image +{ + const CGAL::Image_3 & image; + + Construct_initial_points_labeled_image(const CGAL::Image_3 & image_) + : image(image_) + { } + + template + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const + { + typedef typename MeshDomain::Subdomain Subdomain; + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; + + typedef typename C3t3::Triangulation Tr; + typedef typename Tr::Geom_traits GT; + typedef typename GT::FT FT; + typedef typename Tr::Weighted_point Weighted_point; + typedef typename Tr::Segment Segment_3; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef typename GT::Vector_3 Vector_3; + + const Tr& tr = c3t3.triangulation(); + + typename GT::Compare_weighted_squared_radius_3 cwsr = + tr.geom_traits().compare_weighted_squared_radius_3_object(); + typename GT::Construct_point_3 cp = + tr.geom_traits().construct_point_3_object(); + typename GT::Construct_weighted_point_3 cwp = + tr.geom_traits().construct_weighted_point_3_object(); + + const double max_v = (std::max)((std::max)(image.vx(), + image.vy()), + image.vz()); + + struct Seed { + std::size_t i, j, k; + std::size_t radius; + }; + using Seeds = std::vector; + + Seeds seeds; + Get_point get_point(&image); + std::cout << "Searching for connected components..." << std::endl; + CGAL_IMAGE_IO_CASE(image.image(), search_for_connected_components_in_labeled_image(image, + std::back_inserter(seeds), + CGAL::Emptyset_iterator(), + CGAL::Identity(), + Word())); + std::cout << " " << seeds.size() << " components were found." << std::endl; + std::cout << "Construct initial points..." << std::endl; + for(const Seed seed : seeds) + { + const Point_3 seed_point = get_point(seed.i, seed.j, seed.k); + Cell_handle seed_cell = tr.locate(cwp(seed_point)); + + const Subdomain seed_label + = domain.is_in_domain_object()(seed_point); + const Subdomain seed_cell_label + = ( tr.dimension() < 3 + || seed_cell == Cell_handle() + || tr.is_infinite(seed_cell)) + ? Subdomain() //seed_point is OUTSIDE_AFFINE_HULL + : domain.is_in_domain_object()( + seed_cell->weighted_circumcenter(tr.geom_traits())); + + if ( seed_label != std::nullopt + && seed_cell_label != std::nullopt + && *seed_label == *seed_cell_label) + continue; //this means the connected component has already been initialized + + const double radius = double(seed.radius + 1)* max_v; + CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); + typename MeshDomain::Construct_intersection construct_intersection = + domain.construct_intersection_object(); + + std::vector directions; + if(seed.radius < 2) { + // shoot in six directions + directions.push_back(Vector_3(-radius, 0, 0)); + directions.push_back(Vector_3(+radius, 0, 0)); + directions.push_back(Vector_3(0, -radius, 0)); + directions.push_back(Vector_3(0, +radius, 0)); + directions.push_back(Vector_3(0, 0, -radius)); + directions.push_back(Vector_3(0, 0, +radius)); + } else { + for(int i = 0; i < n; ++i) + { + // shoot n random directions + directions.push_back(*points_on_sphere_3++ - CGAL::ORIGIN); + } + } + + for(const Vector_3& v : directions) + { + const Point_3 test = seed_point + v; + const Segment_3 test_segment = Segment_3(seed_point, test); + + const typename MeshDomain::Intersection intersect = + construct_intersection(test_segment); + if (std::get<2>(intersect) != 0) + { + const Point_3& bpi = std::get<0>(intersect); + const Index index = std::get<1>(intersect); + Weighted_point pi = Weighted_point(bpi); + + // This would cause trouble to optimizers + // check pi will not be hidden + typename Tr::Locate_type lt; + int li, lj; + Cell_handle pi_cell = tr.locate(pi, lt, li, lj); + if(lt != Tr::OUTSIDE_AFFINE_HULL) { + switch (tr.dimension()) + { //skip dimension 0 + case 1: + if (tr.side_of_power_segment(pi_cell, pi, true) != CGAL::ON_BOUNDED_SIDE) + continue; + break; + case 2: + if (tr.side_of_power_circle(pi_cell, 3, pi, true) != CGAL::ON_BOUNDED_SIDE) + continue; + break; + case 3: + if (tr.side_of_power_sphere(pi_cell, pi, true) != CGAL::ON_BOUNDED_SIDE) + continue; + } + } + + //check pi is not inside a protecting ball + std::vector conflict_vertices; + if (tr.dimension() == 3) + { + tr.vertices_on_conflict_zone_boundary(pi, pi_cell + , std::back_inserter(conflict_vertices)); + } + else + { + for (typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); + vit != tr.finite_vertices_end(); ++vit) + { + const Weighted_point& wp = tr.point(vit); + if (cwsr(wp, FT(0)) == CGAL::SMALLER) // 0 < wp's weight + conflict_vertices.push_back(vit); + } + } + + bool pi_inside_protecting_sphere = false; + for(Vertex_handle cv : conflict_vertices) + { + if(tr.is_infinite(cv)) + continue; + + const Weighted_point& cv_wp = tr.point(cv); + if (cwsr(cv_wp, FT(0)) == CGAL::EQUAL) // 0 == wp's weight + continue; + + // if the (squared) distance between bpi and cv is smaller or equal than cv's weight + if (cwsr(cv_wp, - tr.min_squared_distance(bpi, cp(cv_wp))) != CGAL::LARGER) + { + pi_inside_protecting_sphere = true; + break; + } + } + if (pi_inside_protecting_sphere) + continue; + + *pts++ = std::make_pair(bpi, index); + } + } + } + return pts; + } +}; + +#endif // CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h index ec3e5761a9a..5035fcfd26f 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h @@ -14,56 +14,10 @@ #define CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_LABELED_IMAGE_H #include - -#include -#include -#include #include -#include -#include -#include -#include +#include -#include -#include - -template -struct Get_point -{ - const double vx, vy, vz; - const double tx, ty, tz; - const std::size_t xdim, ydim, zdim; - Get_point(const CGAL::Image_3* image) - : vx(image->vx()) - , vy(image->vy()) - , vz(image->vz()) - , tx(image->tx()) - , ty(image->ty()) - , tz(image->tz()) - , xdim(image->xdim()) - , ydim(image->ydim()) - , zdim(image->zdim()) - {} - - Point operator()(const std::size_t i, - const std::size_t j, - const std::size_t k) const - { - double x = double(i) * vx + tx; - double y = double(j) * vy + ty; - double z = double(k) * vz + tz; - - if (i == 0) x += 1. / 6. * vx; - else if (i == xdim - 1) x -= 1. / 6. * vx; - if (j == 0) y += 1. / 6. * vy; - else if (j == ydim - 1) y -= 1. / 6. * vy; - if (k == 0) z += 1. / 6. * vz; - else if (k == zdim - 1) z -= 1. / 6. * vz; - - return Point(x, y, z); - } -}; template void init_tr_from_labeled_image_call_init_features(C3T3&, const MeshDomain&, @@ -97,23 +51,17 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, { typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits GT; - typedef typename GT::FT FT; typedef typename Tr::Weighted_point Weighted_point; - typedef typename Tr::Bare_point Bare_point; - typedef typename Tr::Segment Segment_3; typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename Tr::Cell_handle Cell_handle; + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; - typedef typename GT::Vector_3 Vector_3; + typedef typename std::pair ConstructedPoint; typedef MeshDomain Mesh_domain; Tr& tr = c3t3.triangulation(); - typename GT::Compare_weighted_squared_radius_3 cwsr = - tr.geom_traits().compare_weighted_squared_radius_3_object(); - typename GT::Construct_point_3 cp = - tr.geom_traits().construct_point_3_object(); typename GT::Construct_weighted_point_3 cwp = tr.geom_traits().construct_weighted_point_3_object(); @@ -123,159 +71,36 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, CGAL::internal::Has_features()); } - const double max_v = (std::max)((std::max)(image.vx(), - image.vy()), - image.vz()); + std::vector constructedPoints; - struct Seed { - std::size_t i, j, k; - std::size_t radius; - }; - using Seeds = std::vector; - using Subdomain = typename Mesh_domain::Subdomain; + Construct_initial_points_labeled_image construct(image); + construct(std::back_inserter(constructedPoints), domain, c3t3); - Seeds seeds; - Get_point get_point(&image); - std::cout << "Searching for connected components..." << std::endl; - search_for_connected_components_in_labeled_image(image, - std::back_inserter(seeds), - CGAL::Emptyset_iterator(), - transform, - Image_word_type()); - std::cout << " " << seeds.size() << " components were found." << std::endl; - std::cout << "Construct initial points..." << std::endl; - for(const Seed seed : seeds) + std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; + + for (const ConstructedPoint & constructedPoint : constructedPoints) { - const Bare_point seed_point = get_point(seed.i, seed.j, seed.k); - Cell_handle seed_cell = tr.locate(cwp(seed_point)); + const Point_3& point = constructedPoint.first; + const Index& index = constructedPoint.second; - const Subdomain seed_label - = domain.is_in_domain_object()(seed_point); - const Subdomain seed_cell_label - = ( tr.dimension() < 3 - || seed_cell == Cell_handle() - || tr.is_infinite(seed_cell)) - ? Subdomain() //seed_point is OUTSIDE_AFFINE_HULL - : domain.is_in_domain_object()( - seed_cell->weighted_circumcenter(tr.geom_traits())); + Weighted_point pi = cwp(point); - if ( seed_label != std::nullopt - && seed_cell_label != std::nullopt - && *seed_label == *seed_cell_label) - continue; //this means the connected component has already been initialized + /// The following lines show how to insert initial points in the + /// `c3t3` object. [insert initial points] + Vertex_handle v = tr.insert(pi); + // `v` could be null if `pi` is hidden by other vertices of `tr`. + CGAL_assertion(v != Vertex_handle()); + c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_index(v, index); + /// [insert initial points] + } - const double radius = double(seed.radius + 1)* max_v; - CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); - typename Mesh_domain::Construct_intersection construct_intersection = - domain.construct_intersection_object(); - - std::vector directions; - if(seed.radius < 2) { - // shoot in six directions - directions.push_back(Vector_3(-radius, 0, 0)); - directions.push_back(Vector_3(+radius, 0, 0)); - directions.push_back(Vector_3(0, -radius, 0)); - directions.push_back(Vector_3(0, +radius, 0)); - directions.push_back(Vector_3(0, 0, -radius)); - directions.push_back(Vector_3(0, 0, +radius)); - } else { - for(int i = 0; i < 20; ++i) - { - // shoot 20 random directions - directions.push_back(*points_on_sphere_3++ - CGAL::ORIGIN); - } - } - - for(const Vector_3& v : directions) - { - const Bare_point test = seed_point + v; - - const typename Mesh_domain::Intersection intersect = - construct_intersection(Segment_3(seed_point, test)); - if (std::get<2>(intersect) != 0) - { - const Bare_point& bpi = std::get<0>(intersect); - Weighted_point pi = cwp(bpi); - - // This would cause trouble to optimizers - // check pi will not be hidden - typename Tr::Locate_type lt; - int li, lj; - Cell_handle pi_cell = tr.locate(pi, lt, li, lj); - if(lt != Tr::OUTSIDE_AFFINE_HULL) { - switch (tr.dimension()) - { //skip dimension 0 - case 1: - if (tr.side_of_power_segment(pi_cell, pi, true) != CGAL::ON_BOUNDED_SIDE) - continue; - break; - case 2: - if (tr.side_of_power_circle(pi_cell, 3, pi, true) != CGAL::ON_BOUNDED_SIDE) - continue; - break; - case 3: - if (tr.side_of_power_sphere(pi_cell, pi, true) != CGAL::ON_BOUNDED_SIDE) - continue; - } - } - - //check pi is not inside a protecting ball - std::vector conflict_vertices; - if (tr.dimension() == 3) - { - tr.vertices_on_conflict_zone_boundary(pi, pi_cell - , std::back_inserter(conflict_vertices)); - } - else - { - for (typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); - vit != tr.finite_vertices_end(); ++vit) - { - const Weighted_point& wp = tr.point(vit); - if (cwsr(wp, FT(0)) == CGAL::SMALLER) // 0 < wp's weight - conflict_vertices.push_back(vit); - } - } - - bool pi_inside_protecting_sphere = false; - for(Vertex_handle cv : conflict_vertices) - { - if(tr.is_infinite(cv)) - continue; - - const Weighted_point& cv_wp = tr.point(cv); - if (cwsr(cv_wp, FT(0)) == CGAL::EQUAL) // 0 == wp's weight - continue; - - // if the (squared) distance between bpi and cv is smaller or equal than cv's weight - if (cwsr(cv_wp, - tr.min_squared_distance(bpi, cp(cv_wp))) != CGAL::LARGER) - { - pi_inside_protecting_sphere = true; - break; - } - } - if (pi_inside_protecting_sphere) - continue; - const typename Mesh_domain::Index index = std::get<1>(intersect); - - /// The following lines show how to insert initial points in the - /// `c3t3` object. [insert initial points] - Vertex_handle v = tr.insert(pi); - - // `v` could be null if `pi` is hidden by other vertices of `tr`. - CGAL_assertion(v != Vertex_handle()); - - c3t3.set_dimension(v, 2); // by construction, points are on surface - c3t3.set_index(v, index); - /// [insert initial points] - } - // else - // { - // std::cerr << - // boost::format("Error. Segment (%1%, %2%) does not intersect the surface!\n") - // % it->first % test; - // } - } + if ( tr.dimension() != 3 ) + { + std::cout << " not enough points: triangulation.dimension() == " + << tr.dimension() << std::endl; + CGAL::Mesh_3::internal::init_c3t3(c3t3, domain, criteria, 20); + std::cout << " -> " << tr.number_of_vertices() << " initial points." << std::endl; } std::cout << " " << tr.number_of_vertices() << " initial points." << std::endl; if ( c3t3.triangulation().dimension() != 3 ) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 79277f1643f..c77efc45446 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -38,10 +38,10 @@ namespace CGAL { namespace Mesh_3 { namespace internal { -template < typename C3T3, typename MeshDomain, typename MeshCriteria > +template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, - const int nb_initial_points) + const int nb_initial_points, InitialPointsGenerator& generator = Null_functor()) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -49,13 +49,23 @@ 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) - domain.construct_initial_points_object()(std::back_inserter(initial_points), + generator_wrapped(std::back_inserter(initial_points), domain, c3t3, nb_initial_points); else //use default number of points - domain.construct_initial_points_object()(std::back_inserter(initial_points)); + generator_wrapped(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(); @@ -159,20 +169,22 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria, bool MeshDomainHasHasFeatures, - typename HasFeatures = int> + typename HasFeatures = int, + typename InitialPointsGenerator = Null_functor> 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 > -struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures > +template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > +struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerator > { typedef parameters::internal::Mesh_3_options Mesh_3_options; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, - Mesh_3_options mesh_options = Mesh_3_options()) + Mesh_3_options mesh_options = Mesh_3_options(), + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { @@ -181,23 +193,24 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures > } init_c3t3(c3t3,domain,criteria, - mesh_options.number_of_initial_points); + mesh_options.number_of_initial_points, generator); } }; // Partial specialization of C3t3_initializer // Handles cases where MeshDomain::Has_features is a valid type -template < typename C3T3, typename MD, typename MC, typename HasFeatures > -struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures > +template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitialPointsGenerator > +struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerator > { typedef parameters::internal::Mesh_3_options Mesh_3_options; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, - Mesh_3_options mesh_options = Mesh_3_options()) + Mesh_3_options mesh_options = Mesh_3_options(), + InitialPointsGenerator& generator = Null_functor()) { - C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features >() + C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() (c3t3,domain,criteria,with_features,mesh_options); } }; @@ -205,8 +218,8 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures > // 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 > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > +template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGenerator > : public C3t3_initializer_base < C3T3, MD, MC > { virtual ~C3t3_initializer() { } @@ -216,7 +229,8 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > const MD& domain, const MC& criteria, bool with_features, - Mesh_3_options mesh_options = Mesh_3_options()) + Mesh_3_options mesh_options = Mesh_3_options(), + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -242,26 +256,27 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > } if(need_more_init) { init_c3t3(c3t3, domain, criteria, - mesh_options.number_of_initial_points); + mesh_options.number_of_initial_points, generator); } } else { init_c3t3(c3t3,domain,criteria, - mesh_options.number_of_initial_points); } + mesh_options.number_of_initial_points, generator); } } }; // 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 > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > +template < typename C3T3, typename MD, typename MC, typename InitialPointsGenerator > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGenerator > { typedef parameters::internal::Mesh_3_options Mesh_3_options; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, - Mesh_3_options mesh_options = Mesh_3_options()) + Mesh_3_options mesh_options = Mesh_3_options(), + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { @@ -270,7 +285,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > } init_c3t3(c3t3,domain,criteria, - mesh_options.number_of_initial_points); + mesh_options.number_of_initial_points, generator); } }; @@ -401,6 +416,31 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * } * \cgalParamDefault{`parameters::exude()`} * \cgalParamSectionEnd + * \cgalParamSectionBegin{Mesh initialisation} + * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. + * It must folow the `InitialPointsGenerator` concept and is specified with the param: + *
    + *
  • `parameters::initial_points_generator(generator)` + *
+ * + * The `InitialPointsGenerator` concept is a function object to construct + * a set of initial points on the surface of the domain. Provides the + * following operators: + * + * `template ` + *
+ * `OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3)` + * + * `template ` + *
+ * `OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n)` + * + * Those two operators output a set of (`n`) surface points to the + * output iterator `pts`, as objects of type `std::pair`. If `n` is not given, the functor must provide enough + * points to initialize the mesh generation process.} + * \cgalParamDefault{`parameters::initial_points_generator(generator)`} + * \cgalParamSectionEnd * \cgalNamedParamsEnd * * Note that regardless of which optimization processes are activated, @@ -436,11 +476,13 @@ 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()); make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, features_param.features(), mesh_options_param, - manifold_options_param); + manifold_options_param, + initial_points_generator_param); return c3t3; } @@ -469,7 +511,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, @@ -481,7 +523,8 @@ void make_mesh_3_impl(C3T3& c3t3, const parameters::internal::Mesh_3_options& mesh_options = parameters::internal::Mesh_3_options(), const parameters::internal::Manifold_options& - manifold_options = parameters::internal::Manifold_options()) + manifold_options = parameters::internal::Manifold_options(), + InitialPointsGenerator& generator = Null_functor()) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); @@ -492,11 +535,14 @@ void make_mesh_3_impl(C3T3& c3t3, C3T3, MeshDomain, MeshCriteria, - ::CGAL::internal::has_Has_features::value > () (c3t3, + ::CGAL::internal::has_Has_features::value, + int, /*Type of MeshDomain::Has_features not determined*/ + InitialPointsGenerator >() (c3t3, domain, criteria, with_features, - mesh_options); + mesh_options, + generator); 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 09487cc44f9..195a7a271cb 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 @@ -11,6 +11,8 @@ #ifndef CGAL_MESH_OPTION_CLASSES_H #define CGAL_MESH_OPTION_CLASSES_H +#include + #include namespace CGAL { @@ -165,6 +167,43 @@ private: bool b_; }; +// Initial points generator +template +struct Initial_points_generator_wrapper +{ + template + Initial_points_generator_wrapper(Initial_points_generator& generator) + : initial_points_generator_default_(generator) + , initial_points_generator_(generator) + { } + + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) + { + return initial_points_generator_default_(pts, domain, c3t3); + } + + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) + { + return initial_points_generator_(pts, domain, c3t3, n); + } + +private: + std::function initial_points_generator_default_; + 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 // ----------------------------------- @@ -207,6 +246,25 @@ struct Domain_features_generator< MeshDomain, true > } }; +// struct Initial_points_generator_generator +template +struct Initial_points_generator_generator +{ + auto operator()(Initial_points_generator& generator) + { + return Initial_points_generator_wrapper(generator); + } +}; + +template +struct Initial_points_generator_generator +{ + auto operator()(Null_functor&) + { + return Initial_points_generator_default(); + } +}; + } // end namespace internal 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 7792ad5cdb6..1ef07d492d8 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -323,6 +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_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) From 2732dad5e47652fa05f744ccee3df4f63a50def0 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 16 Oct 2023 10:17:37 +0200 Subject: [PATCH 02/99] Fix CI --- Mesh_3/include/CGAL/make_mesh_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index c77efc45446..19d36896e10 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -211,7 +211,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerato InitialPointsGenerator& generator = Null_functor()) { C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() - (c3t3,domain,criteria,with_features,mesh_options); + (c3t3,domain,criteria,with_features,mesh_options,generator); } }; From bec5358ff19ae67949065d7018b9578bfe5714f4 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 16 Oct 2023 12:39:04 +0200 Subject: [PATCH 03/99] Fix CI --- Mesh_3/include/CGAL/make_mesh_3.h | 12 ++++++------ STL_Extension/include/CGAL/tags.h | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 19d36896e10..cfd255cf075 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -41,7 +41,7 @@ namespace internal { template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, - const int nb_initial_points, InitialPointsGenerator& generator = Null_functor()) + const int nb_initial_points, InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -184,7 +184,7 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerat const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { @@ -208,7 +208,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerato const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() (c3t3,domain,criteria,with_features,mesh_options,generator); @@ -230,7 +230,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGener const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -276,7 +276,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGene const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { @@ -524,7 +524,7 @@ 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()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 6aa1988e1cc..c003234126f 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -53,6 +53,10 @@ struct Null_functor { typedef Null_tag result_type; typedef Null_tag second_argument_type; }; +namespace Null_functor_internal +{ + static Null_functor default_null_functor; +} // namespace Null_functor_internal // For concurrency struct Sequential_tag {}; From 0d0c1f3213c6bb16680a7017d570b4b409eee463 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 16 Oct 2023 13:26:20 +0200 Subject: [PATCH 04/99] Fix CI --- .../Mesh_3/mesh_3D_image_with_initial_points.cpp | 4 ++-- Mesh_3/include/CGAL/make_mesh_3.h | 14 +++++++------- STL_Extension/include/CGAL/tags.h | 4 ---- 3 files changed, 9 insertions(+), 13 deletions(-) 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 e065062697d..cdf3a44e1a4 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 @@ -46,8 +46,8 @@ int main() 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)) + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria + , params::initial_points_generator(Construct_initial_points_labeled_image(image)) ); /// [Meshing] diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index cfd255cf075..6c04b14b67b 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -41,7 +41,7 @@ namespace internal { template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > 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, InitialPointsGenerator& generator = Null_functor()) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -59,7 +59,7 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, // Mesh initialization : get some points and add them to the mesh Initial_points_vector initial_points; - auto& generator_wrapped = + auto generator_wrapped = Initial_points_generator_generator()(generator); if (nb_initial_points > -1) generator_wrapped(std::back_inserter(initial_points), domain, c3t3, @@ -184,7 +184,7 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerat const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { @@ -208,7 +208,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerato const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + InitialPointsGenerator& generator = Null_functor()) { C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() (c3t3,domain,criteria,with_features,mesh_options,generator); @@ -230,7 +230,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGener const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -276,7 +276,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGene const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) + InitialPointsGenerator& generator = Null_functor()) { if ( with_features ) { @@ -524,7 +524,7 @@ 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) + InitialPointsGenerator& generator = Null_functor()) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index c003234126f..6aa1988e1cc 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -53,10 +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; -} // namespace Null_functor_internal // For concurrency struct Sequential_tag {}; From 9fc7230e64764d83240f587facba6d89126fc41c Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 16 Oct 2023 14:04:45 +0200 Subject: [PATCH 05/99] Fix CI --- Mesh_3/include/CGAL/make_mesh_3.h | 12 ++++++------ .../STL_Extension/internal/mesh_option_classes.h | 4 ++-- STL_Extension/include/CGAL/tags.h | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 6c04b14b67b..8c1581368f4 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -41,7 +41,7 @@ namespace internal { template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitialPointsGenerator = Null_functor > void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, - const int nb_initial_points, InitialPointsGenerator& generator = Null_functor()) + const int nb_initial_points, InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -184,7 +184,7 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitialPointsGenerat const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { @@ -208,7 +208,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitialPointsGenerato const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitialPointsGenerator >() (c3t3,domain,criteria,with_features,mesh_options,generator); @@ -230,7 +230,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitialPointsGener const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -276,7 +276,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitialPointsGene const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - InitialPointsGenerator& generator = Null_functor()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { if ( with_features ) { @@ -524,7 +524,7 @@ 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()) + InitialPointsGenerator& generator = Null_functor_internal::default_null_functor) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); 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 195a7a271cb..97defe20378 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 @@ -188,8 +188,8 @@ struct Initial_points_generator_wrapper } private: - std::function initial_points_generator_default_; - std::function initial_points_generator_; + const std::function initial_points_generator_default_; + const std::function initial_points_generator_; }; template struct Initial_points_generator_default diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 6aa1988e1cc..1fcff383e3e 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -53,6 +53,9 @@ 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 {}; From f2af65444d10eaa3164f5bee189467e9c203445f Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 17 Oct 2023 15:39:42 +0200 Subject: [PATCH 06/99] Use parameters instead of template Allows easier initialisation --- .../mesh_3D_image_with_initial_points.cpp | 5 +- Mesh_3/include/CGAL/make_mesh_3.h | 76 +++++++-------- .../internal/mesh_option_classes.h | 97 +++++++++++++------ .../internal/mesh_parameters_interface.h | 17 ++++ .../internal/parameters_interface.h | 2 +- STL_Extension/include/CGAL/tags.h | 3 - 6 files changed, 124 insertions(+), 76 deletions(-) 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 {}; From 268fd8b53c395cd9b87cc312ea4f2a65a0391519 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 17 Oct 2023 15:47:31 +0200 Subject: [PATCH 07/99] Fix CI confusion between typedef and struct --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c7bb4b368ad..85c0c3390f0 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 @@ -265,7 +265,7 @@ struct Initial_points_generator_generator { typedef typename std::back_insert_iterator>> OutputIterator; - typedef Initial_points_generator_options Initial_points_generator_options; + typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; struct Initial_points_generator_domain_traductor { From 4ee4dff969e89668909f35688567f5229477b4fc Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 17 Oct 2023 16:02:28 +0200 Subject: [PATCH 08/99] Doc change + small fix --- Mesh_3/include/CGAL/make_mesh_3.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index a62b87cf4da..80fa460e502 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -42,7 +42,7 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria > void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, - const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_options()()) + const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_generator()()) { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; @@ -416,9 +416,11 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialisation} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. - * It must folow the `InitialPointsGenerator` concept and is specified with the param: + * It must folow the `InitialPointsGenerator` concept. + * The following two named parameters control this option: *
    *
  • `parameters::initial_points_generator(generator)` + *
  • `parameters::default_initial_points_generation()` *
* * The `InitialPointsGenerator` concept is a function object to construct @@ -437,7 +439,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * output iterator `pts`, as objects of type `std::pair`. If `n` is not given, the functor must provide enough * points to initialize the mesh generation process.} - * \cgalParamDefault{`parameters::initial_points_generator(generator)`} + * \cgalParamDefault{`parameters::default_initial_points_generation()`} * \cgalParamSectionEnd * \cgalNamedParamsEnd * @@ -532,12 +534,13 @@ void make_mesh_3_impl(C3T3& c3t3, #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>() (c3t3, + ::CGAL::internal::has_Has_features::value >() (c3t3, domain, criteria, with_features, From c232929fd1c1a03d9a44604505044d9b6767edd8 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 17 Oct 2023 16:12:48 +0200 Subject: [PATCH 09/99] Fix error when no initial_points_generator --- Mesh_3/include/CGAL/make_mesh_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 80fa460e502..c6baa4e8626 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -479,7 +479,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C 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())); + (choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), parameters::default_initial_points_generation().v)); make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, From e5d26511dc8d53f1fbb6af9e607a7e77a329759c Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 17 Oct 2023 17:54:27 +0200 Subject: [PATCH 10/99] Fix unvoluntary copy --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 85c0c3390f0..b6f54fe35d4 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 @@ -212,8 +212,8 @@ struct Initial_points_generator_options } private: - const std::function initial_points_generator_no_number_of_points_; - const std::function initial_points_generator_; + const std::function initial_points_generator_no_number_of_points_; + const std::function initial_points_generator_; }; // ----------------------------------- From cb715951d0bc6c8ee24b515d9ff12134a2c41035 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 10:31:19 +0200 Subject: [PATCH 11/99] Doc changed example + Doc added parameter + Doc make_mesh_3 + Doc Construct_initial_points_labeled_image header + Remove unwanted duplicata --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 43 +++++++++++++++++++ Mesh_3/doc/Mesh_3/Mesh_3.txt | 4 +- ...struct_initial_points_from_labeled_image.h | 24 +++++++++++ ...tialize_triangulation_from_labeled_image.h | 7 --- Mesh_3/include/CGAL/make_mesh_3.h | 2 +- 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index acfb0b6efd8..e744d460a69 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -451,6 +451,49 @@ unspecified_type odt(const Named_function_parameters& np = parameters::default_v template unspecified_type perturb(const Named_function_parameters& np = parameters::default_values()); +/*! + * \ingroup PkgMesh3Parameters + * + * The function `parameters::default_initial_points_generation()` enables the user to tell the mesh generation function + * `make_mesh_3()` that the domlain's construct_initial_points_object will be called for the points initialization. + * + * \cgalHeading{Example} + * + * \code{.cpp} + * // Mesh generation using the domlain's construct_initial_points_object + * C3t3 c3t3 = make_mesh_3(domain, + * criteria, + * parameters::default_initial_points_generation()); + * \endcode + * + * \sa `CGAL::parameters::initial_points_generator(generator)` + * \sa `CGAL::make_mesh_3()` + * \sa `MeshDomain_3::construct_initial_points_object()` + * + */ +unspecified_type default_initial_points_generation(); +/*! + * \ingroup PkgMesh3Parameters + * + * The function `parameters::initial_points_generator()` enables the user to specify to the mesh generation function + * `make_mesh_3()` a Functor of the `InitialPointsGenerator` concept that will be called for the points initialization. + * + * \cgalHeading{Example} + * + * \code{.cpp} + * // Mesh generation from labelled image with connexity checks. + * C3t3 c3t3 = make_mesh_3(domain, + * criteria, + * parameters::initial_points_generator(Construct_initial_points_labeled_image(image))); + * \endcode + * + * \sa `CGAL::parameters::default_initial_points_generation()` + * \sa `CGAL::make_mesh_3()` + * \sa `Construct_initial_points_labeled_image()` + * + */ +template +unspecified_type initial_points_generator(const InitialPointsGenerator& generator); } /* namespace parameters */ } /* namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index abe63982656..6b4c003ac25 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -772,11 +772,11 @@ points in the `%c3t3` object, with the calls to The value of `index` must be consistent with the possible values of `Mesh_domain::Index`. In \ref -CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h, it is +CGAL/Mesh_3/Construct_initial_points_labeled_image.h, it is constructed using the API of the mesh domain, as follows. First the functor `construct_intersect` is created -\dontinclude CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +\dontinclude CGAL/Mesh_3/Construct_initial_points_labeled_image.h \skip Construct_intersection construct_intersection = \until construct_intersection_object then the `%Mesh_domain::Intersection` object (a `%tuple` with three diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h index 878af535821..41d2d2ce987 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h @@ -59,6 +59,30 @@ struct Get_point } }; +/*! +* \ingroup PkgMesh3Functions +* +* Functor for initial points generation in labeled images. +* This functor is a model of concept `InitialPointsGenerator`, +* and thus can be passed to `CGAL::make_mesh_3` with the parameter +* `CGAL::parameters::initial_points_generator(generator)` +* +* It is constructed using the API of the mesh domain, as follows. +* First the functor `construct_intersect` is created +* +* \dontinclude CGAL/Mesh_3/Construct_initial_points_labeled_image.h +* \skip Construct_intersection construct_intersection = +* \until construct_intersection_object +* then the `%MeshDomain_3::Intersection` object (a `%tuple` with three +* elements) is constructed using a call to the functor `construct_intersection` +* \skip Intersection intersect +* \until construct_intersection +* and eventually `%index` is the element \#1 of `%intersect`. +* \skipline get<1>(intersect) +* +* \sa `CGAL::parameters::initial_points_generator(generator)` +* \sa `CGAL::make_mesh_3()` +*/ struct Construct_initial_points_labeled_image { const CGAL::Image_3 & image; diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h index 5035fcfd26f..38db1b000cb 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h @@ -103,13 +103,6 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, std::cout << " -> " << tr.number_of_vertices() << " initial points." << std::endl; } std::cout << " " << tr.number_of_vertices() << " initial points." << std::endl; - if ( c3t3.triangulation().dimension() != 3 ) - { - std::cout << " not enough points: triangulation.dimension() == " - << c3t3.triangulation().dimension() << std::endl; - CGAL::Mesh_3::internal::init_c3t3(c3t3, domain, criteria, 20); - std::cout << " -> " << tr.number_of_vertices() << " initial points." << std::endl; - } } #endif // CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_LABELED_IMAGE_H diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index c6baa4e8626..c25176f93a5 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -414,7 +414,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * } * \cgalParamDefault{`parameters::exude()`} * \cgalParamSectionEnd - * \cgalParamSectionBegin{Mesh initialisation} + * \cgalParamSectionBegin{Mesh initialization} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. * It must folow the `InitialPointsGenerator` concept. * The following two named parameters control this option: From 6558190eda7a9f1ba7e2c605b88d625df4934d31 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 10:37:34 +0200 Subject: [PATCH 12/99] Fixed doc --- Mesh_3/doc/Mesh_3/examples.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index d9c2eb95d71..c80a3c2464f 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -10,6 +10,7 @@ \example Mesh_3/random_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp From 91d66d0bfc76572e8bc1e1f06595405f5596b9f0 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 11:01:50 +0200 Subject: [PATCH 13/99] Renamed Construct_initial_points_from_labeled_image.h --- ...labeled_image.h => Construct_initial_points_labeled_image.h} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Mesh_3/include/CGAL/Mesh_3/{Construct_initial_points_from_labeled_image.h => Construct_initial_points_labeled_image.h} (99%) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h similarity index 99% rename from Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h rename to Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 41d2d2ce987..59aa7afaa98 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -8,7 +8,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Ange Clement +// Author(s) : Laurent Rineau and Ange Clement #ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H #define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H From 23af3eb0e21ba47cef0bb58a92b0507a66587f0c Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 12:38:03 +0200 Subject: [PATCH 14/99] Updated doc example snippets + Added group "Mesh Initialization Functions" + Added concept "InitialPointsGenerator" + Documented model "Construct_initial_points_labeled_image" + Updated demo parametters + Fix reneming errors --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 10 ++-- .../Mesh_3/Concepts/InitialPointsGenerator.h | 57 +++++++++++++++++++ Mesh_3/doc/Mesh_3/Mesh_3.txt | 9 +-- Mesh_3/doc/Mesh_3/PackageDescription.txt | 10 ++++ Mesh_3/doc/Mesh_3/examples.txt | 1 - .../mesh_3D_image_with_initial_points.cpp | 4 +- .../Construct_initial_points_labeled_image.h | 56 +++++++++++------- ...tialize_triangulation_from_labeled_image.h | 4 +- Mesh_3/include/CGAL/make_mesh_3.h | 21 +------ 9 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index e744d460a69..252206644aa 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -455,7 +455,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * \ingroup PkgMesh3Parameters * * The function `parameters::default_initial_points_generation()` enables the user to tell the mesh generation function - * `make_mesh_3()` that the domlain's construct_initial_points_object will be called for the points initialization. + * `make_mesh_3()` that the domain's `construct_initial_points_object()` will be called for the points initialization. * * \cgalHeading{Example} * @@ -466,9 +466,11 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * parameters::default_initial_points_generation()); * \endcode * - * \sa `CGAL::parameters::initial_points_generator(generator)` + * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `MeshDomain_3::construct_initial_points_object()` + * \sa `MeshDomain_3` + * \sa `construct_initial_points_object()` * */ unspecified_type default_initial_points_generation(); @@ -484,12 +486,12 @@ unspecified_type default_initial_points_generation(); * // Mesh generation from labelled image with connexity checks. * C3t3 c3t3 = make_mesh_3(domain, * criteria, - * parameters::initial_points_generator(Construct_initial_points_labeled_image(image))); + * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); * \endcode * * \sa `CGAL::parameters::default_initial_points_generation()` * \sa `CGAL::make_mesh_3()` - * \sa `Construct_initial_points_labeled_image()` + * \sa `CGAL::Construct_initial_points_labeled_image()` * */ template diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h new file mode 100644 index 00000000000..0aa5a26c7a9 --- /dev/null +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -0,0 +1,57 @@ +/*! +\ingroup PkgMesh3SecondaryConcepts +\cgalConcept + +The function object concept `InitialPointsGenerator` is designed to construct +a set of initial points on the surface of the domain. + +\cgalHasModelsBegin +\cgalHasModels{CGAL::Construct_initial_points_labeled_image} +\cgalHasModelsEnd + +\sa `MeshCellCriteria_3` +\sa `MeshFacetCriteria_3` +\sa `MeshCriteria_3` +\sa `MeshCriteriaWithFeatures_3` + +*/ + +class InitialPointsGenerator { +public: + +/// \name Operations +/// @{ + +/*! +Output a set of (`n`) surface points to the +output iterator `pts`, as objects of type `std::pair`. + +@tparam OutputIterator an `OutputIterator` of points of type +`std::pair` +@tparam MeshDomain a model of `MeshDomain_3` +@tparam C3t3 a model of `MeshDomainField_3` + +*/ +template +OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n); + +/*! +Output a set of surface points to the +output iterator `pts`, as objects of type `std::pair`. As `n` is not given, the functor must provide enough +points to initialize the mesh generation process. + +@tparam OutputIterator an `OutputIterator` of points of type +`std::pair` +@tparam MeshDomain a model of `MeshDomain_3` +@tparam C3t3 a model of `MeshDomainField_3` + +*/ +template +OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3); + + +/// @} + +}; /* end MeshEdgeCriteria_3 */ diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 6b4c003ac25..72fdb25ab11 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -776,15 +776,12 @@ CGAL/Mesh_3/Construct_initial_points_labeled_image.h, it is constructed using the API of the mesh domain, as follows. First the functor `construct_intersect` is created -\dontinclude CGAL/Mesh_3/Construct_initial_points_labeled_image.h -\skip Construct_intersection construct_intersection = -\until construct_intersection_object +\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h construct intersection then the `%Mesh_domain::Intersection` object (a `%tuple` with three elements) is constructed using a call to the functor `construct_intersection` -\skip Intersection intersect = -\until construct_intersection +\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h use construct intersection and eventually `%index` is the element \#1 of `%intersect`. -\skipline get<1>(intersect) +\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection The result of the custom initialization can be seen in \cgalFigureRef{mesh3custominitimage3D}. The generated 3D image contains a diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index e063c6eeee7..51b18e4ffa4 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -29,6 +29,9 @@ /// The two main functions to generate a mesh are `make_mesh_3()` and `refine_mesh_3()`. /// The other functions enable to optimize an existing mesh. +/// \defgroup PkgMesh3Initializers Mesh Initialization Functions +/// \ingroup PkgMesh3Ref + /// \defgroup PkgMesh3Parameters Parameter Functions /// \ingroup PkgMesh3Ref @@ -77,6 +80,7 @@ related to the template parameters of some models of the main concepts: - `BisectionGeometricTraits_3` - `IntersectionGeometricTraits_3` +- `InitialPointsGenerator` - `MeshCellBase_3` - `MeshVertexBase_3` - `MeshDomainField_3` @@ -110,6 +114,10 @@ The following functors are available for feature detection: - `CGAL::Mesh_3::Detect_features_in_image` - `CGAL::Mesh_3::Detect_features_on_image_bbox` +The following functors are available for mesh initialization: + +- `CGAL::Construct_initial_points_labeled_image` + \cgalCRPSection{Function Templates} - `CGAL::make_mesh_3()` @@ -135,6 +143,8 @@ The following functors are available for feature detection: - `CGAL::parameters::manifold()` - `CGAL::parameters::manifold_with_boundary()` - `CGAL::parameters::non_manifold()` +- `CGAL::parameters::default_initial_points_generation()` +- `CGAL::parameters::initial_points_generator()` \cgalCRPSection{Enumerations} diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index c80a3c2464f..d9c2eb95d71 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -10,7 +10,6 @@ \example Mesh_3/random_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h -\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp 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 17e5fcb0638..a97170232b4 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 @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -48,7 +48,7 @@ int main() ); C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(Construct_initial_points_labeled_image(image)) + , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) ); /// [Meshing] diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 59aa7afaa98..4f28dd5e47a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -10,8 +10,8 @@ // // Author(s) : Laurent Rineau and Ange Clement -#ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H -#define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H +#ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_LABELED_IMAGE_H +#define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_LABELED_IMAGE_H #include @@ -22,6 +22,14 @@ #include +namespace CGAL +{ + +namespace Mesh_3 +{ +namespace internal +{ + template struct Get_point { @@ -59,28 +67,28 @@ struct Get_point } }; +} // end namespace internal +} // end namespace Mesh_3 + /*! -* \ingroup PkgMesh3Functions +* \ingroup PkgMesh3Initializers * * Functor for initial points generation in labeled images. * This functor is a model of concept `InitialPointsGenerator`, * and thus can be passed to `CGAL::make_mesh_3` with the parameter -* `CGAL::parameters::initial_points_generator(generator)` +* `CGAL::parameters::initial_points_generator()` * * It is constructed using the API of the mesh domain, as follows. * First the functor `construct_intersect` is created * -* \dontinclude CGAL/Mesh_3/Construct_initial_points_labeled_image.h -* \skip Construct_intersection construct_intersection = -* \until construct_intersection_object -* then the `%MeshDomain_3::Intersection` object (a `%tuple` with three +* \snippet this construct intersection +* then the `%Mesh_domain::Intersection` object (a `%tuple` with three * elements) is constructed using a call to the functor `construct_intersection` -* \skip Intersection intersect -* \until construct_intersection +* \snippet this use construct intersection * and eventually `%index` is the element \#1 of `%intersect`. -* \skipline get<1>(intersect) +* \snippet this get construct intersection * -* \sa `CGAL::parameters::initial_points_generator(generator)` +* \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` */ struct Construct_initial_points_labeled_image @@ -127,7 +135,7 @@ struct Construct_initial_points_labeled_image using Seeds = std::vector; Seeds seeds; - Get_point get_point(&image); + Mesh_3::internal::Get_point get_point(&image); std::cout << "Searching for connected components..." << std::endl; CGAL_IMAGE_IO_CASE(image.image(), search_for_connected_components_in_labeled_image(image, std::back_inserter(seeds), @@ -158,8 +166,10 @@ struct Construct_initial_points_labeled_image const double radius = double(seed.radius + 1)* max_v; CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); + /// [construct intersection] typename MeshDomain::Construct_intersection construct_intersection = domain.construct_intersection_object(); + /// [construct intersection] std::vector directions; if(seed.radius < 2) { @@ -183,13 +193,17 @@ struct Construct_initial_points_labeled_image const Point_3 test = seed_point + v; const Segment_3 test_segment = Segment_3(seed_point, test); + /// [use construct intersection] const typename MeshDomain::Intersection intersect = construct_intersection(test_segment); + /// [use construct intersection] if (std::get<2>(intersect) != 0) { - const Point_3& bpi = std::get<0>(intersect); - const Index index = std::get<1>(intersect); - Weighted_point pi = Weighted_point(bpi); + /// [get construct intersection] + const Point_3& intersect_point = std::get<0>(intersect); + const Index& intersect_index = std::get<1>(intersect); + /// [get construct intersection] + Weighted_point pi = Weighted_point(intersect_point); // This would cause trouble to optimizers // check pi will not be hidden @@ -241,8 +255,8 @@ struct Construct_initial_points_labeled_image if (cwsr(cv_wp, FT(0)) == CGAL::EQUAL) // 0 == wp's weight continue; - // if the (squared) distance between bpi and cv is smaller or equal than cv's weight - if (cwsr(cv_wp, - tr.min_squared_distance(bpi, cp(cv_wp))) != CGAL::LARGER) + // if the (squared) distance between intersect_point and cv is smaller or equal than cv's weight + if (cwsr(cv_wp, - tr.min_squared_distance(intersect_point, cp(cv_wp))) != CGAL::LARGER) { pi_inside_protecting_sphere = true; break; @@ -251,7 +265,7 @@ struct Construct_initial_points_labeled_image if (pi_inside_protecting_sphere) continue; - *pts++ = std::make_pair(bpi, index); + *pts++ = std::make_pair(intersect_point, intersect_index); } } } @@ -259,4 +273,6 @@ struct Construct_initial_points_labeled_image } }; -#endif // CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_FROM_LABELED_IMAGE_H +} // end namespace CGAL + +#endif // CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_LABELED_IMAGE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h index 38db1b000cb..5cd16b83032 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h @@ -16,7 +16,7 @@ #include #include -#include +#include template void init_tr_from_labeled_image_call_init_features(C3T3&, @@ -73,7 +73,7 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, std::vector constructedPoints; - Construct_initial_points_labeled_image construct(image); + CGAL::Construct_initial_points_labeled_image construct(image); construct(std::back_inserter(constructedPoints), domain, c3t3); std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index c25176f93a5..f790012f07d 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -416,29 +416,12 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialization} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. - * It must folow the `InitialPointsGenerator` concept. + * It must follow the `InitialPointsGenerator` concept. * The following two named parameters control this option: *
    - *
  • `parameters::initial_points_generator(generator)` + *
  • `parameters::initial_points_generator()` *
  • `parameters::default_initial_points_generation()` *
- * - * The `InitialPointsGenerator` concept is a function object to construct - * a set of initial points on the surface of the domain. Provides the - * following operators: - * - * `template ` - *
- * `OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3)` - * - * `template ` - *
- * `OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n)` - * - * Those two operators output a set of (`n`) surface points to the - * output iterator `pts`, as objects of type `std::pair`. If `n` is not given, the functor must provide enough - * points to initialize the mesh generation process.} * \cgalParamDefault{`parameters::default_initial_points_generation()`} * \cgalParamSectionEnd * \cgalNamedParamsEnd From 932e8a2b34fecdb771ede1f260498b2f8575531d Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 12:46:44 +0200 Subject: [PATCH 15/99] Fix Doc missing end of description --- Mesh_3/doc/Mesh_3/examples.txt | 1 + Mesh_3/include/CGAL/make_mesh_3.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index d9c2eb95d71..c80a3c2464f 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -10,6 +10,7 @@ \example Mesh_3/random_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index f790012f07d..66685418615 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -421,7 +421,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > *
    *
  • `parameters::initial_points_generator()` *
  • `parameters::default_initial_points_generation()` - *
+ * } * \cgalParamDefault{`parameters::default_initial_points_generation()`} * \cgalParamSectionEnd * \cgalNamedParamsEnd From df6d1ed6fd47b28f2f40dbab799d69e21674e60c Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 13:41:03 +0200 Subject: [PATCH 16/99] Fix Doc : Added Construct_initial_points_labeled_image to doxyfile --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 18 ++++++++++-------- .../Mesh_3/Concepts/InitialPointsGenerator.h | 4 ++-- Mesh_3/doc/Mesh_3/Doxyfile.in | 3 ++- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 252206644aa..f3b79cd85d4 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -454,8 +454,10 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::default_initial_points_generation()` enables the user to tell the mesh generation function - * `make_mesh_3()` that the domain's `construct_initial_points_object()` will be called for the points initialization. + * The function `parameters::default_initial_points_generation()` enables the user to + * tell the mesh generation function `make_mesh_3()` + * that the domain's `construct_initial_points_object()` + * will be called for the points initialization. * * \cgalHeading{Example} * @@ -468,17 +470,17 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` - * \sa `MeshDomain_3::construct_initial_points_object()` - * \sa `MeshDomain_3` - * \sa `construct_initial_points_object()` + * \sa `MeshDomain_3::Construct_initial_points` * */ unspecified_type default_initial_points_generation(); /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points_generator()` enables the user to specify to the mesh generation function - * `make_mesh_3()` a Functor of the `InitialPointsGenerator` concept that will be called for the points initialization. + * The function `parameters::initial_points_generator()` enables the user to + * specify a Functor of the `InitialPointsGenerator` concept + * to the mesh generation function `make_mesh_3()`. + * The functor will be called for the points initialization. * * \cgalHeading{Example} * @@ -491,7 +493,7 @@ unspecified_type default_initial_points_generation(); * * \sa `CGAL::parameters::default_initial_points_generation()` * \sa `CGAL::make_mesh_3()` - * \sa `CGAL::Construct_initial_points_labeled_image()` + * \sa `MeshDomain_3::Construct_initial_points` * */ template diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 0aa5a26c7a9..a184a1efaff 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -30,7 +30,7 @@ output iterator `pts`, as objects of type `std::pair` @tparam MeshDomain a model of `MeshDomain_3` -@tparam C3t3 a model of `MeshDomainField_3` +@tparam C3t3 a model of `MeshComplex_3InTriangulation_3` */ template @@ -45,7 +45,7 @@ points to initialize the mesh generation process. @tparam OutputIterator an `OutputIterator` of points of type `std::pair` @tparam MeshDomain a model of `MeshDomain_3` -@tparam C3t3 a model of `MeshDomainField_3` +@tparam C3t3 a model of `MeshComplex_3InTriangulation_3` */ template diff --git a/Mesh_3/doc/Mesh_3/Doxyfile.in b/Mesh_3/doc/Mesh_3/Doxyfile.in index 18c58c248e6..6f4e6300ac6 100644 --- a/Mesh_3/doc/Mesh_3/Doxyfile.in +++ b/Mesh_3/doc/Mesh_3/Doxyfile.in @@ -39,7 +39,8 @@ INPUT += \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Compact_mesh_cell_base_3.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Detect_features_in_image.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Detect_features_on_image_bbox.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_edge_criteria_3.h + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_edge_criteria_3.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Construct_initial_points_labeled_image.h PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Mesh Generation" HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \ diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index 51b18e4ffa4..a499ea4f3b0 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -143,8 +143,8 @@ The following functors are available for mesh initialization: - `CGAL::parameters::manifold()` - `CGAL::parameters::manifold_with_boundary()` - `CGAL::parameters::non_manifold()` -- `CGAL::parameters::default_initial_points_generation()` - `CGAL::parameters::initial_points_generator()` +- `CGAL::parameters::default_initial_points_generation()` \cgalCRPSection{Enumerations} From 3ac063992fa53a5ad5cdf0448a778b278cda042a Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 14:11:57 +0200 Subject: [PATCH 17/99] Small doc fix --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 1 - Mesh_3/doc/Mesh_3/examples.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index f3b79cd85d4..1c66b482543 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -493,7 +493,6 @@ unspecified_type default_initial_points_generation(); * * \sa `CGAL::parameters::default_initial_points_generation()` * \sa `CGAL::make_mesh_3()` - * \sa `MeshDomain_3::Construct_initial_points` * */ template diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index c80a3c2464f..d9c2eb95d71 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -10,7 +10,6 @@ \example Mesh_3/random_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h -\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp From 6955dbdd5ad0ae56cd6678ffbf483b9b70605246 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 18 Oct 2023 15:20:42 +0200 Subject: [PATCH 18/99] Doc operator() of Construct_initial_points_labeled_image --- .../Construct_initial_points_labeled_image.h | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 4f28dd5e47a..21f2a04f461 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -78,16 +78,6 @@ struct Get_point * and thus can be passed to `CGAL::make_mesh_3` with the parameter * `CGAL::parameters::initial_points_generator()` * -* It is constructed using the API of the mesh domain, as follows. -* First the functor `construct_intersect` is created -* -* \snippet this construct intersection -* then the `%Mesh_domain::Intersection` object (a `%tuple` with three -* elements) is constructed using a call to the functor `construct_intersection` -* \snippet this use construct intersection -* and eventually `%index` is the element \#1 of `%intersect`. -* \snippet this get construct intersection -* * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` */ @@ -99,6 +89,22 @@ struct Construct_initial_points_labeled_image : image(image_) { } + /*! + * \brief operator () The points are constructed using the API of the mesh domain, as follows. + * First the functor `construct_intersect` is created + * + * \snippet this construct intersection + * then the `%Mesh_domain::Intersection` object (a `%tuple` with three + * elements) is constructed using a call to the functor `construct_intersection` + * \snippet this use construct intersection + * and eventually `%index` is the element \#1 of `%intersect`. + * \snippet this get construct intersection + * + * @tparam OutputIterator an `OutputIterator` of points of type + * `std::pair` + * @tparam MeshDomain a model of `MeshDomain_3` + * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const { From 7eff2725450064bdd1ed58dcd4e20f2355c0ffc2 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Thu, 19 Oct 2023 09:41:31 +0200 Subject: [PATCH 19/99] Fix doc missing ref --- Mesh_3/doc/Mesh_3/examples.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index d9c2eb95d71..c80a3c2464f 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -10,6 +10,7 @@ \example Mesh_3/random_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp From c014741454367f9219f68e129e90950b41747599 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 25 Oct 2023 10:35:25 +0200 Subject: [PATCH 20/99] Doc add example + Fix for initialize_triangulation_from_gray_image --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 21 ++++++++++++------- Mesh_3/doc/Mesh_3/examples.txt | 1 + .../mesh_3D_image_with_initial_points.cpp | 1 + .../Construct_initial_points_labeled_image.h | 11 ++++++++-- ...initialize_triangulation_from_gray_image.h | 10 +++++++++ ...tialize_triangulation_from_labeled_image.h | 11 +++++++++- 6 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 72fdb25ab11..d6bd93edd26 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -759,10 +759,10 @@ that call is replaced by: \snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp Meshing The code of the function `initialize_triangulation_from_labeled_image()` is -in the non-documented header \ref -CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. As it is -undocumented and may be removed or modified at any time, if you wish to -use it then you should copy-paste it to your user code. The code of that +in the header \ref +CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. It get points from +\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and insert them +in the triangulation. The code of the Construct_initial_points_labeled_image function is rather complicated. The following lines show how to insert new points in the `%c3t3` object, with the calls to `MeshVertexBase_3::set_dimension()` and @@ -830,11 +830,16 @@ the segmented image example above, the code consists in: \snippet Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp Meshing The code of the function `initialize_triangulation_from_gray_image()` is -in the non-documented header \ref -CGAL/Mesh_3/initialize_triangulation_from_gray_image.h. As it is -undocumented and may be removed or modified at any time, if you wish to -use it then you should copy-paste it to your user code. +in the header \ref +CGAL/Mesh_3/initialize_triangulation_from_gray_image.h. +The example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp is another +way to achieve the same results. Instead of a custom initialization, +it uses the parameter `CGAL::parameters::initial_points_generator` for the function +`CGAL::make_mesh_3`. This parameter expect a functor that ouputs points for +the mesh initialization (concept `InitialPointsGenerator`). + +\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Meshing \subsection Mesh_3UsingVariableSizingField Using Variable Sizing Field diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index c80a3c2464f..f29c47e7e32 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -4,6 +4,7 @@ \example Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_image_with_features.cpp \example Mesh_3/mesh_3D_image_with_custom_initialization.cpp +\example Mesh_3/mesh_3D_image_with_initial_points.cpp \example Mesh_3/mesh_3D_image_with_detection_of_features.cpp \example Mesh_3/mesh_3D_image_with_input_features.cpp \example Mesh_3/mesh_3D_weighted_image.cpp 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 a97170232b4..c205f1502b9 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 @@ -47,6 +47,7 @@ int main() .cell_radius_edge_ratio(3).cell_size(3) ); + /// [Meshing] C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) ); diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 21f2a04f461..a05736193d1 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -89,7 +89,7 @@ struct Construct_initial_points_labeled_image : image(image_) { } - /*! + /*! * \brief operator () The points are constructed using the API of the mesh domain, as follows. * First the functor `construct_intersect` is created * @@ -107,6 +107,13 @@ struct Construct_initial_points_labeled_image */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const + { + CGAL_IMAGE_IO_CASE(image.image(), operator()(pts, domain, CGAL::Identity(), c3t3, n)); + return pts; + } + + template + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const { typedef typename MeshDomain::Subdomain Subdomain; typedef typename MeshDomain::Point_3 Point_3; @@ -146,7 +153,7 @@ struct Construct_initial_points_labeled_image CGAL_IMAGE_IO_CASE(image.image(), search_for_connected_components_in_labeled_image(image, std::back_inserter(seeds), CGAL::Emptyset_iterator(), - CGAL::Identity(), + transform, Word())); std::cout << " " << seeds.size() << " components were found." << std::endl; std::cout << "Construct initial points..." << std::endl; diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h index 1d3a6b7601e..b42875390a1 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h @@ -20,6 +20,16 @@ #include +/** + * @brief initialize_triangulation_from_gray_image Initialize a c3t3 by detecting all connected components in the 3D gray image segmented around isovalue + * @param c3t3 The c3t3 to initialize (output) + * @param domain The domain, see concept `MeshDomain_3` + * @param image The gray image + * @param criteria The initial meshing criteria + * @param iso_value The surface's value + * @param image_values_to_subdomain_indices An optional functor used to segment the gray image (default is using isovalue). + * @param protect_features Whether protect_features is called or not (default is false) + */ template > @@ -74,7 +83,7 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, std::vector constructedPoints; CGAL::Construct_initial_points_labeled_image construct(image); - construct(std::back_inserter(constructedPoints), domain, c3t3); + construct(std::back_inserter(constructedPoints), domain, transform, c3t3); std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; From 976e73cf89a75e072321033eff8a84ff31da4456 Mon Sep 17 00:00:00 2001 From: ange-clement <47100137+ange-clement@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:09:35 +0200 Subject: [PATCH 21/99] Update Mesh_3/doc/Mesh_3/Mesh_3.txt Co-authored-by: Jane Tournois --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index d6bd93edd26..96f4ad160ae 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -760,7 +760,7 @@ that call is replaced by: The code of the function `initialize_triangulation_from_labeled_image()` is in the header \ref -CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. It get points from +CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. It gets points from \ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and insert them in the triangulation. The code of the Construct_initial_points_labeled_image function is rather complicated. The following lines show how to insert new From ec5539eac3870a040e8e5a4ff70a317ce1679454 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 25 Oct 2023 14:57:48 +0200 Subject: [PATCH 22/99] Revision 1 : Doc fix + Deleted default_initial_points_generation() + Created Construct_initial_points_gray_image.h --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 28 +------ .../Mesh_3/Concepts/InitialPointsGenerator.h | 1 + Mesh_3/doc/Mesh_3/Doxyfile.in | 3 +- Mesh_3/doc/Mesh_3/Mesh_3.txt | 10 +-- Mesh_3/doc/Mesh_3/PackageDescription.txt | 1 + .../Construct_initial_points_gray_image.h | 76 +++++++++++++++++++ .../Construct_initial_points_labeled_image.h | 31 ++++++-- Mesh_3/include/CGAL/make_mesh_3.h | 8 +- .../internal/mesh_parameters_interface.h | 2 +- 9 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 1c66b482543..fd1164c2566 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -451,29 +451,6 @@ unspecified_type odt(const Named_function_parameters& np = parameters::default_v template unspecified_type perturb(const Named_function_parameters& np = parameters::default_values()); -/*! - * \ingroup PkgMesh3Parameters - * - * The function `parameters::default_initial_points_generation()` enables the user to - * tell the mesh generation function `make_mesh_3()` - * that the domain's `construct_initial_points_object()` - * will be called for the points initialization. - * - * \cgalHeading{Example} - * - * \code{.cpp} - * // Mesh generation using the domlain's construct_initial_points_object - * C3t3 c3t3 = make_mesh_3(domain, - * criteria, - * parameters::default_initial_points_generation()); - * \endcode - * - * \sa `CGAL::parameters::initial_points_generator()` - * \sa `CGAL::make_mesh_3()` - * \sa `MeshDomain_3::Construct_initial_points` - * - */ -unspecified_type default_initial_points_generation(); /*! * \ingroup PkgMesh3Parameters * @@ -481,6 +458,9 @@ unspecified_type default_initial_points_generation(); * specify a Functor of the `InitialPointsGenerator` concept * to the mesh generation function `make_mesh_3()`. * The functor will be called for the points initialization. + * If this parameter is specified without argument, the default behaviour is executed, + * i.e. the domain's `construct_initial_points_object()` + * will be called for the points initialization. * * \cgalHeading{Example} * @@ -491,8 +471,8 @@ unspecified_type default_initial_points_generation(); * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); * \endcode * - * \sa `CGAL::parameters::default_initial_points_generation()` * \sa `CGAL::make_mesh_3()` + * \sa `MeshDomain_3::Construct_initial_points` * */ template diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index a184a1efaff..da5c6846a5a 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -7,6 +7,7 @@ a set of initial points on the surface of the domain. \cgalHasModelsBegin \cgalHasModels{CGAL::Construct_initial_points_labeled_image} +\cgalHasModels{CGAL::Construct_initial_points_gray_image} \cgalHasModelsEnd \sa `MeshCellCriteria_3` diff --git a/Mesh_3/doc/Mesh_3/Doxyfile.in b/Mesh_3/doc/Mesh_3/Doxyfile.in index 6f4e6300ac6..5355f1a2635 100644 --- a/Mesh_3/doc/Mesh_3/Doxyfile.in +++ b/Mesh_3/doc/Mesh_3/Doxyfile.in @@ -40,7 +40,8 @@ INPUT += \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Detect_features_in_image.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Detect_features_on_image_bbox.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_edge_criteria_3.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Construct_initial_points_labeled_image.h + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Construct_initial_points_labeled_image.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/Construct_initial_points_gray_image.h PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Mesh Generation" HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \ diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 96f4ad160ae..15182a243f3 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -751,7 +751,7 @@ For the meshing, in the previous example (\ref Mesh_3/mesh_3D_image.cpp), we cal In the example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp, that call is replaced by: -# the creation of an empty `%c3t3` object, - -# a call to a non-documented function + -# a call to the function `initialize_triangulation_from_labeled_image()` that inserts points in the triangulation, -# then the call to `refine_mesh_3()`. @@ -761,9 +761,9 @@ that call is replaced by: The code of the function `initialize_triangulation_from_labeled_image()` is in the header \ref CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. It gets points from -\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and insert them -in the triangulation. The code of the Construct_initial_points_labeled_image -function is rather complicated. The following lines show how to insert new +\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and inserts them +in the triangulation. The code of the `Construct_initial_points_labeled_image` +functor is rather complicated. The following lines show how to insert new points in the `%c3t3` object, with the calls to `MeshVertexBase_3::set_dimension()` and `MeshVertexBase_3::set_index()`. @@ -836,7 +836,7 @@ CGAL/Mesh_3/initialize_triangulation_from_gray_image.h. The example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp is another way to achieve the same results. Instead of a custom initialization, it uses the parameter `CGAL::parameters::initial_points_generator` for the function -`CGAL::make_mesh_3`. This parameter expect a functor that ouputs points for +`CGAL::make_mesh_3`. This parameter expects a functor that returns a set of points for the mesh initialization (concept `InitialPointsGenerator`). \snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Meshing diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index a499ea4f3b0..88c90fbac25 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -117,6 +117,7 @@ The following functors are available for feature detection: The following functors are available for mesh initialization: - `CGAL::Construct_initial_points_labeled_image` +- `CGAL::Construct_initial_points_gray_image` \cgalCRPSection{Function Templates} diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h new file mode 100644 index 00000000000..5eb0f51797d --- /dev/null +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -0,0 +1,76 @@ +// Copyright (c) 20XX,20XX GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Laurent Rineau and Ange Clement + +#ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_GRAY_IMAGE_H +#define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_GRAY_IMAGE_H + +#include + +#include +#include + +#include + +namespace CGAL +{ + +/*! +* \ingroup PkgMesh3Initializers +* +* Functor for initial points generation in gray images. +* This functor is a model of concept `InitialPointsGenerator`, +* and thus can be passed to `CGAL::make_mesh_3` with the parameter +* `CGAL::parameters::initial_points_generator()` +* +* \sa `CGAL::parameters::initial_points_generator()` +* \sa `CGAL::make_mesh_3()` +*/ +template +struct Construct_initial_points_gray_image +{ + const CGAL::Image_3 & image_; + double iso_value_; + Functor image_values_to_subdomain_indices_; + + template + Construct_initial_points_gray_image(const CGAL::Image_3 & image, + const FT& iso_value, + const Functor image_values_to_subdomain_indices = CGAL::Null_functor()) + : image_(image) + , iso_value_(iso_value) + , image_values_to_subdomain_indices_(image_values_to_subdomain_indices) + { } + + /*! + * \brief Constructs the initial points using the gray image. + * + * @tparam OutputIterator an `OutputIterator` of points of type + * `std::pair` + * @tparam MeshDomain a model of `MeshDomain_3` + * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + */ + template + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const + { + using CGAL::Mesh_3::internal::Create_gray_image_values_to_subdomain_indices; + typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices_, iso_value_); + Construct_initial_points_labeled_image(image_).operator()(pts, domain, transform_fct, c3t3, n); + return pts; + } +}; + +} // end namespace CGAL + +#endif // CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_GRAY_IMAGE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index a05736193d1..50008701379 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -80,6 +80,7 @@ struct Get_point * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` +* \sa `CGAL::Construct_initial_points_gray_image()` */ struct Construct_initial_points_labeled_image { @@ -89,8 +90,8 @@ struct Construct_initial_points_labeled_image : image(image_) { } - /*! - * \brief operator () The points are constructed using the API of the mesh domain, as follows. + /*! + * \brief Constructs the points using the API of the mesh domain, as follows. * First the functor `construct_intersect` is created * * \snippet this construct intersection @@ -112,6 +113,20 @@ struct Construct_initial_points_labeled_image return pts; } + /*! + * \brief Same as above, but a `TransformOperator` is used + * + * @tparam OutputIterator an `OutputIterator` of points of type + * `std::pair` + * @tparam MeshDomain a model of `MeshDomain_3` + * @tparam TransformOperator a functor to transform values of the image. + * It must provides the following type:
+ * `result_type`
+ * and the following operator:
+ * `template`
+ * `result_type operator()(FT v)` + * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const { @@ -179,10 +194,10 @@ struct Construct_initial_points_labeled_image const double radius = double(seed.radius + 1)* max_v; CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); - /// [construct intersection] + /// \noop [construct intersection] typename MeshDomain::Construct_intersection construct_intersection = domain.construct_intersection_object(); - /// [construct intersection] + /// \noop [construct intersection] std::vector directions; if(seed.radius < 2) { @@ -206,16 +221,16 @@ struct Construct_initial_points_labeled_image const Point_3 test = seed_point + v; const Segment_3 test_segment = Segment_3(seed_point, test); - /// [use construct intersection] + /// \noop [use construct intersection] const typename MeshDomain::Intersection intersect = construct_intersection(test_segment); - /// [use construct intersection] + /// \noop [use construct intersection] if (std::get<2>(intersect) != 0) { - /// [get construct intersection] + /// \noop [get construct intersection] const Point_3& intersect_point = std::get<0>(intersect); const Index& intersect_index = std::get<1>(intersect); - /// [get construct intersection] + /// \noop [get construct intersection] Weighted_point pi = Weighted_point(intersect_point); // This would cause trouble to optimizers diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 66685418615..46e6f4332c3 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -417,12 +417,12 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * \cgalParamSectionBegin{Mesh initialization} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. * It must follow the `InitialPointsGenerator` concept. - * The following two named parameters control this option: + * The following named parameter control this option: *
    *
  • `parameters::initial_points_generator()` - *
  • `parameters::default_initial_points_generation()` *
} - * \cgalParamDefault{`parameters::default_initial_points_generation()`} + * \cgalParamDefault{empty `parameters::initial_points_generator()`, the domain's `construct_initial_points_object()` + * will be called for the points initialization.} * \cgalParamSectionEnd * \cgalNamedParamsEnd * @@ -462,7 +462,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C 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().v)); + (choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), parameters::initial_points_generator().v)); make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, 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 93e77e5b46c..04646c5eb55 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 @@ -373,7 +373,7 @@ features(const MeshDomain& /*domain*/) // 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() { +initial_points_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<>()); } From 15e75d0d042e068463fb0568dc267a9b02ce9198 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 25 Oct 2023 15:08:30 +0200 Subject: [PATCH 23/99] Small doc fix --- Mesh_3/doc/Mesh_3/PackageDescription.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index 88c90fbac25..1df5968afc6 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -145,7 +145,6 @@ The following functors are available for mesh initialization: - `CGAL::parameters::manifold_with_boundary()` - `CGAL::parameters::non_manifold()` - `CGAL::parameters::initial_points_generator()` -- `CGAL::parameters::default_initial_points_generation()` \cgalCRPSection{Enumerations} From 9d22242b6392df5d5f70b07108ebf20f7999d7dc Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 31 Oct 2023 12:21:52 +0100 Subject: [PATCH 24/99] Removed useless initialization files Removed initialize_triangulation_from_labeled_image Removed initialize_triangulation_from_gray_image --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 88 ++++++------- Mesh_3/doc/Mesh_3/examples.txt | 2 - ..._gray_image_with_custom_initialization.cpp | 52 +++++++- ...sh_3D_image_with_custom_initialization.cpp | 50 +++++++- ...initialize_triangulation_from_gray_image.h | 60 --------- ...tialize_triangulation_from_labeled_image.h | 117 ------------------ .../Plugins/Mesh_3/Mesh_3_plugin.cpp | 2 +- .../Mesh_3/Mesh_3_plugin_cgal_code.cpp | 15 +-- .../Polyhedron/Plugins/Mesh_3/Mesh_function.h | 86 +++++++++++-- 9 files changed, 211 insertions(+), 261 deletions(-) delete mode 100644 Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h delete mode 100644 Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 15182a243f3..7a0eae088a7 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -737,44 +737,21 @@ without the weights (left, 25563 vertices) and with the weights (right, 19936 ve \subsubsection Mesh_3DomainsFrom3DImagesWithCustomInitialization Domains From 3D Images, with a Custom Initialization -The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp is a modification +The example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp is a modification of \ref Mesh_3/mesh_3D_image.cpp. The goal of that example is to show how the default initialization of the triangulation, using random rays, can be replaced by a new implementation. In this case, the initialization detects all connected components in the 3D segmented image, and inserts points in the triangulation for each connected component. -For the meshing, in the previous example (\ref Mesh_3/mesh_3D_image.cpp), we called `make_mesh_3()` as follows. +\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Meshing -\snippet Mesh_3/mesh_3D_image.cpp Meshing - -In the example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp, -that call is replaced by: - -# the creation of an empty `%c3t3` object, - -# a call to the function - `initialize_triangulation_from_labeled_image()` that inserts points in - the triangulation, - -# then the call to `refine_mesh_3()`. - -\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp Meshing - -The code of the function `initialize_triangulation_from_labeled_image()` is -in the header \ref -CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h. It gets points from -\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and inserts them -in the triangulation. The code of the `Construct_initial_points_labeled_image` -functor is rather complicated. The following lines show how to insert new -points in the `%c3t3` object, with the calls to -`MeshVertexBase_3::set_dimension()` and -`MeshVertexBase_3::set_index()`. - -\snippet CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h insert initial points - -The value of `index` must be consistent with the possible values of -`Mesh_domain::Index`. In \ref -CGAL/Mesh_3/Construct_initial_points_labeled_image.h, it is -constructed using the API of the mesh domain, as follows. First the functor -`construct_intersect` is created +The parameter `CGAL::parameters::initial_points_generator` is used. +It expects a functor that returns a set of points for the mesh +initialization (concept `InitialPointsGenerator`). The functor +\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h is used. +It constructs points using the API of the mesh domain, as follows. +First the functor `construct_intersect` is created \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h construct intersection then the `%Mesh_domain::Intersection` object (a `%tuple` with three @@ -807,40 +784,57 @@ the center is meshed Right: the mesh generated after the initialization of all connected components \cgalFigureCaptionEnd - Note that the example \ref -Mesh_3/mesh_3D_image_with_custom_initialization.cpp also shows how to +Mesh_3/mesh_3D_image_with_initial_points.cpp also shows how to create a 3D image using the undocumented API of CGAL_ImageIO. -\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp Create the image +\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Create the image The code of the function `%random_labeled_image()` is in the header file \ref Mesh_3/random_labeled_image.h. +The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp features +another way to achieve these results. It is a modification +of \ref Mesh_3/mesh_3D_image.cpp. + +For the meshing, in the previous example (\ref Mesh_3/mesh_3D_image.cpp), we called `make_mesh_3()` as follows. + +\snippet Mesh_3/mesh_3D_image.cpp Meshing + +In the example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp, +that call is replaced by: + -# the creation of an empty `%c3t3` object, + -# a call to the function + `initialize_triangulation_from_labeled_image()` that inserts points in + the triangulation, + -# then the call to `refine_mesh_3()`. + +\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp Meshing + +The function `initialize_triangulation_from_labeled_image()` gets points from +\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and inserts them +in the triangulation. The following lines show how to insert new +points in the `%c3t3` object, with the calls to +`MeshVertexBase_3::set_dimension()` and +`MeshVertexBase_3::set_index()`. + +\snippet CGAL/Mesh_3/mesh_3D_image_with_custom_initialization.cpp insert initial points + +The value of `index` must be consistent with the possible values of +`Mesh_domain::Index`. + The example \ref Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp is another custom initialization example, for meshing of 3D gray-level images. Similarly to the segmented image example above, the code consists in: -# the creation of an empty `%c3t3` object, - -# a call to a non-documented function + -# a call to the function `initialize_triangulation_from_gray_image()` that inserts points in the triangulation, -# then the call to `refine_mesh_3()`. \snippet Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp Meshing -The code of the function `initialize_triangulation_from_gray_image()` is -in the header \ref -CGAL/Mesh_3/initialize_triangulation_from_gray_image.h. - -The example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp is another -way to achieve the same results. Instead of a custom initialization, -it uses the parameter `CGAL::parameters::initial_points_generator` for the function -`CGAL::make_mesh_3`. This parameter expects a functor that returns a set of points for -the mesh initialization (concept `InitialPointsGenerator`). - -\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Meshing - \subsection Mesh_3UsingVariableSizingField Using Variable Sizing Field \subsubsection Mesh_3SizingFieldasanAnalyticalFunction Sizing Field as an Analytical Function diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index f29c47e7e32..ee4ca63f372 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -9,8 +9,6 @@ \example Mesh_3/mesh_3D_image_with_input_features.cpp \example Mesh_3/mesh_3D_weighted_image.cpp \example Mesh_3/random_labeled_image.h -\example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h -\example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h \example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp index afed1a34b52..1a450497c97 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -34,6 +34,51 @@ typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; +template +void initialize_triangulation_from_gray_image(C3T3& c3t3, + const MeshDomain& domain, + const CGAL::Image_3& image, + const FT& iso_value) +{ + typedef typename C3T3::Triangulation Tr; + typedef typename Tr::Geom_traits GT; + typedef typename Tr::Weighted_point Weighted_point; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; + + typedef typename std::pair ConstructedPoint; + + Tr& tr = c3t3.triangulation(); + + typename GT::Construct_weighted_point_3 cwp = + tr.geom_traits().construct_weighted_point_3_object(); + + std::vector constructedPoints; + + CGAL::Construct_initial_points_gray_image construct(image, iso_value); + construct(std::back_inserter(constructedPoints), domain, c3t3); + + std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; + + for (const ConstructedPoint & constructedPoint : constructedPoints) + { + const Point_3& point = constructedPoint.first; + const Index& index = constructedPoint.second; + + Weighted_point pi = cwp(point); + + /// The following lines show how to insert initial points in the + /// `c3t3` object. [insert initial points] + Vertex_handle v = tr.insert(pi); + // `v` could be null if `pi` is hidden by other vertices of `tr`. + CGAL_assertion(v != Vertex_handle()); + c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_index(v, index); + /// [insert initial points] + } +} + int main(int argc, char* argv[]) { const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("images/skull_2.9.inr"); @@ -57,9 +102,8 @@ int main(int argc, char* argv[]) initialize_triangulation_from_gray_image(c3t3, domain, image, - criteria, - 2.9f,//isolevel - Image_word_type(0)); + 2.9f//isolevel + ); CGAL::refine_mesh_3(c3t3, domain, criteria); /// [Meshing] diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 253c41a920b..9a0675d80f6 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -33,6 +33,50 @@ typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; +template +void initialize_triangulation_from_labeled_image(C3T3& c3t3, + const MeshDomain& domain, + const CGAL::Image_3& image) +{ + typedef typename C3T3::Triangulation Tr; + typedef typename Tr::Geom_traits GT; + typedef typename Tr::Weighted_point Weighted_point; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; + + typedef typename std::pair ConstructedPoint; + + Tr& tr = c3t3.triangulation(); + + typename GT::Construct_weighted_point_3 cwp = + tr.geom_traits().construct_weighted_point_3_object(); + + std::vector constructedPoints; + + CGAL::Construct_initial_points_labeled_image construct(image); + construct(std::back_inserter(constructedPoints), domain, c3t3); + + std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; + + for (const ConstructedPoint & constructedPoint : constructedPoints) + { + const Point_3& point = constructedPoint.first; + const Index& index = constructedPoint.second; + + Weighted_point pi = cwp(point); + + /// The following lines show how to insert initial points in the + /// `c3t3` object. [insert initial points] + Vertex_handle v = tr.insert(pi); + // `v` could be null if `pi` is hidden by other vertices of `tr`. + CGAL_assertion(v != Vertex_handle()); + c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_index(v, index); + /// [insert initial points] + } +} + int main() { /// [Create the image] @@ -50,9 +94,7 @@ int main() C3t3 c3t3; initialize_triangulation_from_labeled_image(c3t3, domain, - image, - criteria, - static_cast(0)); + image); CGAL::refine_mesh_3(c3t3, domain, criteria); /// [Meshing] diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h deleted file mode 100644 index b42875390a1..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_gray_image.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2015,2016 GeometryFactory -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Laurent Rineau, Jane Tournois - -#ifndef CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_GRAY_IMAGE_H -#define CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_GRAY_IMAGE_H - -#include - -#include -#include - -#include - -/** - * @brief initialize_triangulation_from_gray_image Initialize a c3t3 by detecting all connected components in the 3D gray image segmented around isovalue - * @param c3t3 The c3t3 to initialize (output) - * @param domain The domain, see concept `MeshDomain_3` - * @param image The gray image - * @param criteria The initial meshing criteria - * @param iso_value The surface's value - * @param image_values_to_subdomain_indices An optional functor used to segment the gray image (default is using isovalue). - * @param protect_features Whether protect_features is called or not (default is false) - */ -template -void initialize_triangulation_from_gray_image(C3T3& c3t3, - const MeshDomain& domain, - const CGAL::Image_3& image, - const MeshCriteria& criteria, - const FT& iso_value, - Image_word_type, - const Functor image_values_to_subdomain_indices = CGAL::Null_functor(), - bool protect_features = false) -{ - typedef typename CGAL::Default::Get::type Functor_; - - using CGAL::Mesh_3::internal::Create_gray_image_values_to_subdomain_indices; - typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; - typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; - Image_values_to_subdomain_indices transform_fct = - C_i_v_t_s_i()(image_values_to_subdomain_indices, iso_value); - - initialize_triangulation_from_labeled_image(c3t3, domain, image, criteria, - Image_word_type(), - protect_features, - transform_fct); -} - -#endif // CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_GRAY_IMAGE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h deleted file mode 100644 index 14ac394d0b4..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2015,2016 GeometryFactory -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Laurent Rineau - -#ifndef CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_LABELED_IMAGE_H -#define CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_LABELED_IMAGE_H - -#include -#include - -#include - -template -void init_tr_from_labeled_image_call_init_features(C3T3&, - const MeshDomain&, - const MeshCriteria&, - CGAL::Tag_false) -{ -} -template -void init_tr_from_labeled_image_call_init_features(C3T3& c3t3, - const MeshDomain& domain, - const MeshCriteria& criteria, - CGAL::Tag_true) -{ - CGAL::Mesh_3::internal::init_c3t3_with_features(c3t3, - domain, - criteria); - std::cout << c3t3.triangulation().number_of_vertices() - << " initial points on 1D-features" << std::endl; -} - -/** - * @brief initialize_triangulation_from_labeled_image Initialize a c3t3 by detecting all connected components in the 3D segmented image - * @param c3t3 The c3t3 to initialize (output) - * @param domain The domain, see concept `MeshDomain_3` - * @param image The segmented image - * @param criteria The initial meshing criteria - * @param protect_features Whether protect_features is called or not (default is false) - * @param transform An optional functor used to transform the image's value (default is no transformation). - */ -template > -void initialize_triangulation_from_labeled_image(C3T3& c3t3, - const MeshDomain& domain, - const CGAL::Image_3& image, - const MeshCriteria& criteria, - Image_word_type, - bool protect_features = false, - TransformOperator transform = CGAL::Identity()) -{ - typedef typename C3T3::Triangulation Tr; - typedef typename Tr::Geom_traits GT; - typedef typename Tr::Weighted_point Weighted_point; - typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename MeshDomain::Point_3 Point_3; - typedef typename MeshDomain::Index Index; - - typedef typename std::pair ConstructedPoint; - - typedef MeshDomain Mesh_domain; - - Tr& tr = c3t3.triangulation(); - - typename GT::Construct_weighted_point_3 cwp = - tr.geom_traits().construct_weighted_point_3_object(); - - if(protect_features) { - init_tr_from_labeled_image_call_init_features - (c3t3, domain, criteria, - CGAL::internal::Has_features()); - } - - std::vector constructedPoints; - - CGAL::Construct_initial_points_labeled_image construct(image); - construct(std::back_inserter(constructedPoints), domain, transform, c3t3); - - std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; - - for (const ConstructedPoint & constructedPoint : constructedPoints) - { - const Point_3& point = constructedPoint.first; - const Index& index = constructedPoint.second; - - Weighted_point pi = cwp(point); - - /// The following lines show how to insert initial points in the - /// `c3t3` object. [insert initial points] - Vertex_handle v = tr.insert(pi); - // `v` could be null if `pi` is hidden by other vertices of `tr`. - CGAL_assertion(v != Vertex_handle()); - c3t3.set_dimension(v, 2); // by construction, points are on surface - c3t3.set_index(v, index); - /// [insert initial points] - } - - if ( tr.dimension() != 3 ) - { - std::cout << " not enough points: triangulation.dimension() == " - << tr.dimension() << std::endl; - CGAL::Mesh_3::internal::init_c3t3(c3t3, domain, criteria, 20); - std::cout << " -> " << tr.number_of_vertices() << " initial points." << std::endl; - } - std::cout << " " << tr.number_of_vertices() << " initial points." << std::endl; -} - -#endif // CGAL_MESH_3_INITIALIZE_TRIANGULATION_FROM_LABELED_IMAGE_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index c17f4879f1d..febdb922906 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -621,7 +621,7 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, ui.sharpFeaturesGroup->setEnabled(false); ui.facegraphCheckBox->setVisible(mesh_type == Mesh_type::SURFACE_ONLY); - ui.initializationGroup->setVisible(input_is_labeled_img); + ui.initializationGroup->setVisible(input_is_labeled_img || input_is_gray_img); ui.grayImgGroup->setVisible(input_is_gray_img); if (items->index() == POLYHEDRAL_MESH_ITEMS) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index abc82f15033..c2974d103f2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -20,19 +20,6 @@ using namespace CGAL::Three; typedef Tr::Bare_point Bare_point; -struct Compare_to_isovalue { - double iso_value; - bool less; - typedef bool result_type; - - Compare_to_isovalue(double iso_value, bool less) - : iso_value(iso_value), less(less) {} - - bool operator()(double x) const { - return (x < iso_value) == less; - } -}; - Meshing_thread* cgal_code_mesh_3(QList pMeshes, const Polylines_container& polylines, const SMesh* pBoundingMesh, @@ -337,6 +324,8 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, param.protect_features = protect_features || protect_borders || !polylines.empty(); param.detect_connected_components = detect_connected_components; + param.iso_value = iso_value; + param.inside_is_less = inside_is_less; param.facet_angle = facet_angle; param.facet_sizing = facet_sizing; param.facet_min_sizing = facet_min_sizing; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index dfd31aadd84..0c91681b952 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #include "C3t3_type.h" #include "Meshing_thread.h" @@ -40,6 +41,19 @@ namespace CGAL { class Image_3; } +struct Compare_to_isovalue { + double iso_value; + bool less; + typedef bool result_type; + + Compare_to_isovalue(double iso_value, bool less) + : iso_value(iso_value), less(less) {} + + bool operator()(double x) const { + return (x < iso_value) == less; + } +}; + struct Mesh_parameters { double facet_angle; @@ -54,6 +68,8 @@ struct Mesh_parameters double edge_min_sizing; bool protect_features; bool detect_connected_components; + float iso_value; + bool inside_is_less; int manifold; const CGAL::Image_3* image_3_ptr; const CGAL::Image_3* weights_ptr; @@ -110,6 +126,7 @@ private: void initialize(const Mesh_criteria& criteria, Mesh_fnt::Domain_tag); void initialize(const Mesh_criteria& criteria, Mesh_fnt::Labeled_image_domain_tag); + void initialize(const Mesh_criteria& criteria, Mesh_fnt::Gray_image_domain_tag); Edge_criteria edge_criteria(double b, double minb, Mesh_fnt::Domain_tag); Edge_criteria edge_criteria(double b, double minb, Mesh_fnt::Polyhedral_domain_tag); @@ -204,16 +221,60 @@ Mesh_function:: initialize(const Mesh_criteria& criteria, Mesh_fnt::Labeled_image_domain_tag) // for a labeled image { - if(p_.detect_connected_components) { - CGAL_IMAGE_IO_CASE(p_.image_3_ptr->image(), - initialize_triangulation_from_labeled_image(c3t3_ - , *domain_ - , *p_.image_3_ptr - , criteria - , Word() - , p_.protect_features); - ); - } else { + namespace p = CGAL::parameters; + // Initialization of the labeled image, either with the protection of sharp + // features, or with the initial points (or both). + if (p_.detect_connected_components) + { + CGAL::Mesh_3::internal::C3t3_initializer< + C3t3, + Domain, + Mesh_criteria, + CGAL::internal::has_Has_features::value >() + (c3t3_, + *domain_, + criteria, + p_.protect_features, + p::mesh_3_options(p::pointer_to_stop_atomic_boolean = &stop_, + p::nonlinear_growth_of_balls = true).v, + p::internal::Initial_points_generator_generator() + (p::initial_points_generator( + CGAL::Construct_initial_points_labeled_image(*p_.image_3_ptr)).v)); + } + else + { + initialize(criteria, Mesh_fnt::Domain_tag()); + } +} + +template < typename D_, typename Tag > +void +Mesh_function:: +initialize(const Mesh_criteria& criteria, Mesh_fnt::Gray_image_domain_tag) +// for a gray image +{ + namespace p = CGAL::parameters; + // Initialization of the gray image, either with the protection of sharp + // features, or with the initial points (or both). + if (p_.detect_connected_components) + { + CGAL::Mesh_3::internal::C3t3_initializer< + C3t3, + Domain, + Mesh_criteria, + CGAL::internal::has_Has_features::value >() + (c3t3_, + *domain_, + criteria, + p_.protect_features, + p::mesh_3_options(p::pointer_to_stop_atomic_boolean = &stop_, + p::nonlinear_growth_of_balls = true).v, + p::internal::Initial_points_generator_generator() + (p::initial_points_generator( + CGAL::Construct_initial_points_gray_image(*p_.image_3_ptr, p_.iso_value, Compare_to_isovalue(p_.iso_value, p_.inside_is_less))).v)); + } + else + { initialize(criteria, Mesh_fnt::Domain_tag()); } } @@ -227,8 +288,7 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Domain_tag) namespace p = CGAL::parameters; // Initialization of the mesh, either with the protection of sharp // features, or with the initial points (or both). - // If `detect_connected_components==true`, the initialization is - // already done. + CGAL::Mesh_3::internal::C3t3_initializer< C3t3, Domain, From d7f110e428b29cea0eee9a51f22e82bb631eeb0e Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 31 Oct 2023 15:34:42 +0100 Subject: [PATCH 25/99] Changed InitialPointsGenerator concept : The points' dimensions are also outputed by the initialisation. --- .../Mesh_3/Concepts/InitialPointsGenerator.h | 19 +++++++++++++------ Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- ..._gray_image_with_custom_initialization.cpp | 9 +++++---- ...sh_3D_image_with_custom_initialization.cpp | 9 +++++---- .../Construct_initial_points_gray_image.h | 6 +++--- .../Construct_initial_points_labeled_image.h | 8 ++++---- Mesh_3/include/CGAL/make_mesh_3.h | 10 +++++----- .../internal/mesh_option_classes.h | 4 ++-- 8 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index da5c6846a5a..57436a47d97 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -25,11 +25,14 @@ public: /*! Output a set of (`n`) surface points to the -output iterator `pts`, as objects of type `std::pair`. +output iterator `pts`, as objects of type +`std::tuple` where +`Point_3` is the point's position, +`int` is the point's dimension and +`Index` is the point's index. @tparam OutputIterator an `OutputIterator` of points of type -`std::pair` +`std::tuple` @tparam MeshDomain a model of `MeshDomain_3` @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` @@ -39,12 +42,16 @@ OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3 /*! Output a set of surface points to the -output iterator `pts`, as objects of type `std::pair`. As `n` is not given, the functor must provide enough +output iterator `pts`, as objects of type +`std::tuple` where +`Point_3` is the point's position, +`int` is the point's dimension and +`Index` is the point's index. +As `n` is not given, the functor must provide enough points to initialize the mesh generation process. @tparam OutputIterator an `OutputIterator` of points of type -`std::pair` +`std::tuple` @tparam MeshDomain a model of `MeshDomain_3` @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 7a0eae088a7..c401a91d2a1 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -819,7 +819,7 @@ points in the `%c3t3` object, with the calls to `MeshVertexBase_3::set_dimension()` and `MeshVertexBase_3::set_index()`. -\snippet CGAL/Mesh_3/mesh_3D_image_with_custom_initialization.cpp insert initial points +\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp insert initial points The value of `index` must be consistent with the possible values of `Mesh_domain::Index`. diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp index 1a450497c97..b734240f4cc 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp @@ -47,7 +47,7 @@ void initialize_triangulation_from_gray_image(C3T3& c3t3, typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; - typedef typename std::pair ConstructedPoint; + typedef typename std::tuple ConstructedPoint; Tr& tr = c3t3.triangulation(); @@ -63,8 +63,9 @@ void initialize_triangulation_from_gray_image(C3T3& c3t3, for (const ConstructedPoint & constructedPoint : constructedPoints) { - const Point_3& point = constructedPoint.first; - const Index& index = constructedPoint.second; + const Point_3& point = std::get<0>(constructedPoint); + const int& dimension = std::get<1>(constructedPoint); + const Index& index = std::get<2>(constructedPoint); Weighted_point pi = cwp(point); @@ -73,7 +74,7 @@ void initialize_triangulation_from_gray_image(C3T3& c3t3, Vertex_handle v = tr.insert(pi); // `v` could be null if `pi` is hidden by other vertices of `tr`. CGAL_assertion(v != Vertex_handle()); - c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_dimension(v, dimension); c3t3.set_index(v, index); /// [insert initial points] } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 9a0675d80f6..feff42b26b3 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -45,7 +45,7 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; - typedef typename std::pair ConstructedPoint; + typedef typename std::tuple ConstructedPoint; Tr& tr = c3t3.triangulation(); @@ -61,8 +61,9 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, for (const ConstructedPoint & constructedPoint : constructedPoints) { - const Point_3& point = constructedPoint.first; - const Index& index = constructedPoint.second; + const Point_3& point = std::get<0>(constructedPoint); + const int& dimension = std::get<1>(constructedPoint); + const Index& index = std::get<2>(constructedPoint); Weighted_point pi = cwp(point); @@ -71,7 +72,7 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3, Vertex_handle v = tr.insert(pi); // `v` could be null if `pi` is hidden by other vertices of `tr`. CGAL_assertion(v != Vertex_handle()); - c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_dimension(v, dimension); c3t3.set_index(v, index); /// [insert initial points] } diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 5eb0f51797d..2095596d0a0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -1,4 +1,4 @@ -// Copyright (c) 20XX,20XX GeometryFactory +// Copyright (c) 2015,2016 GeometryFactory // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -8,7 +8,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Laurent Rineau and Ange Clement +// Author(s) : Laurent Rineau, Jane Tournois and Ange Clement #ifndef CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_GRAY_IMAGE_H #define CGAL_MESH_3_CONSTRUCT_INITIAL_POINTS_GRAY_IMAGE_H @@ -54,7 +54,7 @@ struct Construct_initial_points_gray_image * \brief Constructs the initial points using the gray image. * * @tparam OutputIterator an `OutputIterator` of points of type - * `std::pair` + * `std::tuple` * @tparam MeshDomain a model of `MeshDomain_3` * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` */ diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 50008701379..1c277dc9f83 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -1,4 +1,4 @@ -// Copyright (c) 20XX,20XX GeometryFactory +// Copyright (c) 2015,2016 GeometryFactory // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -102,7 +102,7 @@ struct Construct_initial_points_labeled_image * \snippet this get construct intersection * * @tparam OutputIterator an `OutputIterator` of points of type - * `std::pair` + * `std::tuple` * @tparam MeshDomain a model of `MeshDomain_3` * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` */ @@ -117,7 +117,7 @@ struct Construct_initial_points_labeled_image * \brief Same as above, but a `TransformOperator` is used * * @tparam OutputIterator an `OutputIterator` of points of type - * `std::pair` + * `std::tuple` * @tparam MeshDomain a model of `MeshDomain_3` * @tparam TransformOperator a functor to transform values of the image. * It must provides the following type:
@@ -293,7 +293,7 @@ struct Construct_initial_points_labeled_image if (pi_inside_protecting_sphere) continue; - *pts++ = std::make_pair(intersect_point, intersect_index); + *pts++ = std::make_tuple(intersect_point, 2, intersect_index); // dimension 2 by construction, points are on surface } } } diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 46e6f4332c3..870cac12820 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -46,7 +46,7 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, { typedef typename MeshDomain::Point_3 Point_3; typedef typename MeshDomain::Index Index; - typedef std::vector > Initial_points_vector; + typedef std::vector > Initial_points_vector; typedef typename Initial_points_vector::iterator Ipv_iterator; typedef typename C3T3::Vertex_handle Vertex_handle; @@ -66,13 +66,13 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, it != initial_points.end() ; ++it ) { - Vertex_handle v = c3t3.triangulation().insert(cwp(it->first)); + Vertex_handle v = c3t3.triangulation().insert(cwp(std::get<0>(*it))); // v could be null if point is hidden if ( v != Vertex_handle() ) { - c3t3.set_dimension(v,2); // by construction, points are on surface - c3t3.set_index(v,it->second); + c3t3.set_dimension(v,std::get<1>(*it)); + c3t3.set_index(v,std::get<2>(*it)); } } } @@ -523,7 +523,7 @@ void make_mesh_3_impl(C3T3& c3t3, C3T3, MeshDomain, MeshCriteria, - ::CGAL::internal::has_Has_features::value >() (c3t3, + ::CGAL::internal::has_Has_features::value > () (c3t3, domain, criteria, with_features, 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 b6f54fe35d4..7433f419ff9 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 @@ -193,7 +193,7 @@ struct Initial_points_generator_options_holder template struct Initial_points_generator_options { - typedef typename std::back_insert_iterator>> OutputIterator; + typedef typename std::back_insert_iterator>> OutputIterator; template Initial_points_generator_options(const Initial_points_generator& generator) @@ -263,7 +263,7 @@ struct Domain_features_generator< MeshDomain, true > template struct Initial_points_generator_generator { - typedef typename std::back_insert_iterator>> OutputIterator; + typedef typename std::back_insert_iterator>> OutputIterator; typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; From ea11f328d6e8ca5e26bdde49a9220e62bda653ae Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 3 Nov 2023 17:44:05 +0100 Subject: [PATCH 26/99] Doc update + Changed initial_point_generator default parameter + Fix previous change from pair to tuple --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 6 +- .../Mesh_3/Concepts/InitialPointsGenerator.h | 30 ++++----- Mesh_3/doc/Mesh_3/Mesh_3.txt | 4 +- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- Mesh_3/doc/Mesh_3/examples.txt | 1 - .../Construct_initial_points_gray_image.h | 3 +- .../Construct_initial_points_labeled_image.h | 29 ++++----- Mesh_3/include/CGAL/make_mesh_3.h | 6 +- .../internal/mesh_option_classes.h | 62 +++++++++---------- .../internal/mesh_parameters_interface.h | 12 ++-- 10 files changed, 70 insertions(+), 85 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index fd1164c2566..dbf2ec22101 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -455,12 +455,12 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * \ingroup PkgMesh3Parameters * * The function `parameters::initial_points_generator()` enables the user to - * specify a Functor of the `InitialPointsGenerator` concept + * specify a functor following the `InitialPointsGenerator` concept * to the mesh generation function `make_mesh_3()`. - * The functor will be called for the points initialization. + * The functor will be called for initialization of the meshing process. * If this parameter is specified without argument, the default behaviour is executed, * i.e. the domain's `construct_initial_points_object()` - * will be called for the points initialization. + * is called for the initialization of the meshing process. * * \cgalHeading{Example} * diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 57436a47d97..c5097a9ca07 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -10,11 +10,6 @@ a set of initial points on the surface of the domain. \cgalHasModels{CGAL::Construct_initial_points_gray_image} \cgalHasModelsEnd -\sa `MeshCellCriteria_3` -\sa `MeshFacetCriteria_3` -\sa `MeshCriteria_3` -\sa `MeshCriteriaWithFeatures_3` - */ class InitialPointsGenerator { @@ -26,15 +21,16 @@ public: /*! Output a set of (`n`) surface points to the output iterator `pts`, as objects of type -`std::tuple` where +`std::tuple`. `Point_3` is the point's position, -`int` is the point's dimension and -`Index` is the point's index. +`int` is the dimension of the minimal dimension subcomplex on which the point lies, and +`Index` is the underlying subcomplex index. -@tparam OutputIterator an `OutputIterator` of points of type +@tparam OutputIterator model of `OutputIterator`, containing points of type `std::tuple` -@tparam MeshDomain a model of `MeshDomain_3` -@tparam C3t3 a model of `MeshComplex_3InTriangulation_3` +@tparam MeshDomain model of `MeshDomain_3` +@tparam C3t3 model of `MeshComplex_3InTriangulation_3` +@param n an estimation of the number of points to output */ template @@ -43,17 +39,17 @@ OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3 /*! Output a set of surface points to the output iterator `pts`, as objects of type -`std::tuple` where +`std::tuple`. `Point_3` is the point's position, -`int` is the point's dimension and -`Index` is the point's index. +`int` is the dimension of the minimal dimension subcomplex on which the point lies, and +`Index` is the underlying subcomplex index. As `n` is not given, the functor must provide enough points to initialize the mesh generation process. -@tparam OutputIterator an `OutputIterator` of points of type +@tparam OutputIterator model of `OutputIterator`, containing points of type `std::tuple` -@tparam MeshDomain a model of `MeshDomain_3` -@tparam C3t3 a model of `MeshComplex_3InTriangulation_3` +@tparam MeshDomain model of `MeshDomain_3` +@tparam C3t3 model of `MeshComplex_3InTriangulation_3` */ template diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index c401a91d2a1..1340e9ac3c6 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -748,8 +748,8 @@ the triangulation for each connected component. The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh -initialization (concept `InitialPointsGenerator`). The functor -\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h is used. +initialization (following the `InitialPointsGenerator`). The functor +\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h is used in this example. It constructs points using the API of the mesh domain, as follows. First the functor `construct_intersect` is created diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index 1df5968afc6..df30cd0b5d6 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -133,6 +133,7 @@ The following functors are available for mesh initialization: - `CGAL::parameters::features()` - `CGAL::parameters::no_features()` +- `CGAL::parameters::initial_points_generator()` - `CGAL::parameters::exude()` - `CGAL::parameters::no_exude()` - `CGAL::parameters::perturb()` @@ -144,7 +145,6 @@ The following functors are available for mesh initialization: - `CGAL::parameters::manifold()` - `CGAL::parameters::manifold_with_boundary()` - `CGAL::parameters::non_manifold()` -- `CGAL::parameters::initial_points_generator()` \cgalCRPSection{Enumerations} diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index ee4ca63f372..e4528dfa9b1 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -9,7 +9,6 @@ \example Mesh_3/mesh_3D_image_with_input_features.cpp \example Mesh_3/mesh_3D_weighted_image.cpp \example Mesh_3/random_labeled_image.h -\example CGAL/Mesh_3/Construct_initial_points_labeled_image.h \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_hybrid_mesh_domain.cpp \example Mesh_3/mesh_implicit_domains.cpp diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 2095596d0a0..bef74411440 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -33,12 +33,13 @@ namespace CGAL * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` +* \sa `CGAL::Construct_initial_points_labeled_image` */ template struct Construct_initial_points_gray_image { const CGAL::Image_3 & image_; - double iso_value_; + const double iso_value_; Functor image_values_to_subdomain_indices_; template diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 1c277dc9f83..27ee3d09be0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -80,7 +80,7 @@ struct Get_point * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` -* \sa `CGAL::Construct_initial_points_gray_image()` +* \sa `CGAL::Construct_initial_points_gray_image` */ struct Construct_initial_points_labeled_image { @@ -91,20 +91,13 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief Constructs the points using the API of the mesh domain, as follows. - * First the functor `construct_intersect` is created + * \brief Constructs points by collecting them in all connected components. + * This guarantees to initialize them all. * - * \snippet this construct intersection - * then the `%Mesh_domain::Intersection` object (a `%tuple` with three - * elements) is constructed using a call to the functor `construct_intersection` - * \snippet this use construct intersection - * and eventually `%index` is the element \#1 of `%intersect`. - * \snippet this get construct intersection - * - * @tparam OutputIterator an `OutputIterator` of points of type + * @tparam OutputIterator model of `OutputIterator`, containing points of type * `std::tuple` - * @tparam MeshDomain a model of `MeshDomain_3` - * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + * @tparam MeshDomain model of `MeshDomain_3` + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const @@ -116,16 +109,16 @@ struct Construct_initial_points_labeled_image /*! * \brief Same as above, but a `TransformOperator` is used * - * @tparam OutputIterator an `OutputIterator` of points of type + * @tparam OutputIterator model of `OutputIterator`, containing points of type * `std::tuple` - * @tparam MeshDomain a model of `MeshDomain_3` - * @tparam TransformOperator a functor to transform values of the image. - * It must provides the following type:
+ * @tparam MeshDomain model of `MeshDomain_3` + * @tparam TransformOperator functor that transforms values of the image. + * It must provide the following type:
* `result_type`
* and the following operator:
* `template`
* `result_type operator()(FT v)` - * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 870cac12820..6a5eec6a25a 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -415,13 +415,13 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * \cgalParamDefault{`parameters::exude()`} * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialization} - * \cgalParamDescription{an `InitialPointsGenerator` can optionally be supplied before the meshing process. + * \cgalParamDescription{an `InitialPointsGenerator` can optionally be provided to start the meshing process. * It must follow the `InitialPointsGenerator` concept. - * The following named parameter control this option: + * The following named parameter controls this option: *
    *
  • `parameters::initial_points_generator()` *
} - * \cgalParamDefault{empty `parameters::initial_points_generator()`, the domain's `construct_initial_points_object()` + * \cgalParamDefault{`CGAL::Null_Functor()`, the domain's `construct_initial_points_object()` * will be called for the points initialization.} * \cgalParamSectionEnd * \cgalNamedParamsEnd 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 7433f419ff9..37f3c2052c1 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 @@ -167,27 +167,6 @@ private: bool b_; }; -// Initial points generator -// 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 @@ -271,25 +250,42 @@ struct Initial_points_generator_generator { OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) { - return domain.construct_initial_points_object()(pts); + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; + typedef typename std::pair Domain_generated_point; + std::vector domain_generated_points; + domain.construct_initial_points_object()(std::back_inserter(domain_generated_points)); + for (Domain_generated_point domain_generated_point : domain_generated_points) + { + *pts++ = std::make_tuple(domain_generated_point.first, 2, domain_generated_point.second); + } + return pts; } OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) { - return domain.construct_initial_points_object()(pts, n); + typedef typename MeshDomain::Point_3 Point_3; + typedef typename MeshDomain::Index Index; + typedef typename std::pair Domain_generated_point; + std::vector domain_generated_points; + domain.construct_initial_points_object()(std::back_inserter(domain_generated_points), n); + for (Domain_generated_point domain_generated_point : domain_generated_points) + { + *pts++ = std::make_tuple(domain_generated_point.first, 2, domain_generated_point.second); + } + return pts; } }; - template - Initial_points_generator_options operator()(const Initial_points_generator_options_holder& initial_points_generator_options_holder_param) + template + Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) { - if constexpr (Initial_points_generator_options_holder::is_default) - { - return operator()(); - } - else - { - return Initial_points_generator_options(initial_points_generator_options_holder_param.generator_); - } + return Initial_points_generator_options(initial_points_generator); + } + + template <> + Initial_points_generator_options operator()(const Null_functor&) + { + return operator()(); } Initial_points_generator_options operator()() 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 04646c5eb55..97ba587cf26 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 @@ -372,16 +372,16 @@ features(const MeshDomain& /*domain*/) // ----------------------------------- // 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> +inline Named_function_parameters<::CGAL::Null_functor, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> initial_points_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<>()); + typedef Named_function_parameters<::CGAL::Null_functor, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> Param; + return CGAL_NP_BUILD(Param, ::CGAL::Null_functor()); } 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> +inline Named_function_parameters 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)); + typedef Named_function_parameters Param; + return CGAL_NP_BUILD(Param, generator); } From 455e8654f7987f6519bc74ea1a2fc2175d7d6ed4 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 6 Nov 2023 09:48:35 +0100 Subject: [PATCH 27/99] Fix error --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 1 - 1 file changed, 1 deletion(-) 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 37f3c2052c1..5a33d9d3cd1 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 @@ -282,7 +282,6 @@ struct Initial_points_generator_generator return Initial_points_generator_options(initial_points_generator); } - template <> Initial_points_generator_options operator()(const Null_functor&) { return operator()(); From ca7548b341e69b0c62f23dd05009eb52b46dd699 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 7 Nov 2023 15:25:50 +0100 Subject: [PATCH 28/99] Removed example + Modified example mesh_3D_image_with_custom_initialization to use new API + Changed InitialPointsGenerator concept : outputs std::tuple instead of std::tuple + custom initialization will be called even if a feature detector is set --- .../Mesh_3/Concepts/InitialPointsGenerator.h | 12 +- Mesh_3/doc/Mesh_3/Mesh_3.txt | 41 +------ Mesh_3/doc/Mesh_3/examples.txt | 1 - Mesh_3/examples/Mesh_3/CMakeLists.txt | 6 - ..._gray_image_with_custom_initialization.cpp | 115 ------------------ ...sh_3D_image_with_custom_initialization.cpp | 93 +++++++------- .../Construct_initial_points_labeled_image.h | 2 +- Mesh_3/include/CGAL/make_mesh_3.h | 21 ++-- .../internal/mesh_option_classes.h | 53 ++++---- 9 files changed, 88 insertions(+), 256 deletions(-) delete mode 100644 Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index c5097a9ca07..f2ea33d691b 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -21,13 +21,13 @@ public: /*! Output a set of (`n`) surface points to the output iterator `pts`, as objects of type -`std::tuple`. -`Point_3` is the point's position, +`std::tuple`. +`Weighted_point_3` is the point's position and weight, `int` is the dimension of the minimal dimension subcomplex on which the point lies, and `Index` is the underlying subcomplex index. @tparam OutputIterator model of `OutputIterator`, containing points of type -`std::tuple` +`std::tuple` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` @param n an estimation of the number of points to output @@ -39,15 +39,15 @@ OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3 /*! Output a set of surface points to the output iterator `pts`, as objects of type -`std::tuple`. -`Point_3` is the point's position, +`std::tuple`. +`Weighted_point_3` is the point's position and weight, `int` is the dimension of the minimal dimension subcomplex on which the point lies, and `Index` is the underlying subcomplex index. As `n` is not given, the functor must provide enough points to initialize the mesh generation process. @tparam OutputIterator model of `OutputIterator`, containing points of type -`std::tuple` +`std::tuple` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 1340e9ac3c6..edf2e81d985 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -795,45 +795,10 @@ Mesh_3/random_labeled_image.h. The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp features -another way to achieve these results. It is a modification -of \ref Mesh_3/mesh_3D_image.cpp. +a custom functor that initialize the triangulation. -For the meshing, in the previous example (\ref Mesh_3/mesh_3D_image.cpp), we called `make_mesh_3()` as follows. - -\snippet Mesh_3/mesh_3D_image.cpp Meshing - -In the example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp, -that call is replaced by: - -# the creation of an empty `%c3t3` object, - -# a call to the function - `initialize_triangulation_from_labeled_image()` that inserts points in - the triangulation, - -# then the call to `refine_mesh_3()`. - -\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp Meshing - -The function `initialize_triangulation_from_labeled_image()` gets points from -\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h and inserts them -in the triangulation. The following lines show how to insert new -points in the `%c3t3` object, with the calls to -`MeshVertexBase_3::set_dimension()` and -`MeshVertexBase_3::set_index()`. - -\snippet Mesh_3/mesh_3D_image_with_custom_initialization.cpp insert initial points - -The value of `index` must be consistent with the possible values of -`Mesh_domain::Index`. - -The example \ref Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp is another -custom initialization example, for meshing of 3D gray-level images. Similarly to -the segmented image example above, the code consists in: - -# the creation of an empty `%c3t3` object, - -# a call to the function - `initialize_triangulation_from_gray_image()` that inserts points in - the triangulation, - -# then the call to `refine_mesh_3()`. - -\snippet Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp Meshing +A struct `Custom_Initial_points_generator` that places 1D-feature points +alongside a line is created. \subsection Mesh_3UsingVariableSizingField Using Variable Sizing Field diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index e4528dfa9b1..969fb7fd1bf 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -1,7 +1,6 @@ /*! \example Mesh_3/implicit_functions.cpp \example Mesh_3/mesh_3D_image.cpp -\example Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_image_with_features.cpp \example Mesh_3/mesh_3D_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_image_with_initial_points.cpp diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 90857127a80..4899a15d588 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -162,11 +162,6 @@ if(TARGET CGAL::CGAL_ImageIO) target_link_libraries(mesh_3D_image_with_custom_initialization PUBLIC CGAL::Eigen3_support) - create_single_source_cgal_program( - "mesh_3D_gray_image_with_custom_initialization.cpp") - target_link_libraries(mesh_3D_gray_image_with_custom_initialization - PUBLIC CGAL::Eigen3_support) - create_single_source_cgal_program( "mesh_3D_image_with_initial_points.cpp") target_link_libraries(mesh_3D_image_with_initial_points @@ -205,7 +200,6 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) mesh_3D_weighted_image mesh_3D_image_variable_size mesh_3D_image_with_custom_initialization - mesh_3D_gray_image_with_custom_initialization mesh_3D_image_with_initial_points mesh_3D_image_with_features mesh_3D_image_with_detection_of_features diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp deleted file mode 100644 index b734240f4cc..00000000000 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp +++ /dev/null @@ -1,115 +0,0 @@ - -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -typedef float Image_word_type; - -// Domain -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; - -// Parallel tag -#ifdef CGAL_CONCURRENT_MESH_3 -typedef CGAL::Parallel_tag Concurrency_tag; -#else -typedef CGAL::Sequential_tag Concurrency_tag; -#endif - -// Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; -typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - -// Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; - -namespace params = CGAL::parameters; - -template -void initialize_triangulation_from_gray_image(C3T3& c3t3, - const MeshDomain& domain, - const CGAL::Image_3& image, - const FT& iso_value) -{ - typedef typename C3T3::Triangulation Tr; - typedef typename Tr::Geom_traits GT; - typedef typename Tr::Weighted_point Weighted_point; - typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename MeshDomain::Point_3 Point_3; - typedef typename MeshDomain::Index Index; - - typedef typename std::tuple ConstructedPoint; - - Tr& tr = c3t3.triangulation(); - - typename GT::Construct_weighted_point_3 cwp = - tr.geom_traits().construct_weighted_point_3_object(); - - std::vector constructedPoints; - - CGAL::Construct_initial_points_gray_image construct(image, iso_value); - construct(std::back_inserter(constructedPoints), domain, c3t3); - - std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; - - for (const ConstructedPoint & constructedPoint : constructedPoints) - { - const Point_3& point = std::get<0>(constructedPoint); - const int& dimension = std::get<1>(constructedPoint); - const Index& index = std::get<2>(constructedPoint); - - Weighted_point pi = cwp(point); - - /// The following lines show how to insert initial points in the - /// `c3t3` object. [insert initial points] - Vertex_handle v = tr.insert(pi); - // `v` could be null if `pi` is hidden by other vertices of `tr`. - CGAL_assertion(v != Vertex_handle()); - c3t3.set_dimension(v, dimension); - c3t3.set_index(v, index); - /// [insert initial points] - } -} - -int main(int argc, char* argv[]) -{ - const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("images/skull_2.9.inr"); - /// [Load image] - CGAL::Image_3 image; - if (!image.read(fname)) { - std::cerr << "Error: Cannot read file " << fname << std::endl; - return EXIT_FAILURE; - } - /// [Domain creation] - Mesh_domain domain = - Mesh_domain::create_gray_image_mesh_domain(image, params::iso_value(2.9f).value_outside(0.f)); - /// [Domain creation] - - /// [Mesh criteria] - Mesh_criteria criteria(params::facet_angle(30).facet_size(6).facet_distance(2). - cell_radius_edge_ratio(3).cell_size(8)); - - /// [Meshing] - C3t3 c3t3; - initialize_triangulation_from_gray_image(c3t3, - domain, - image, - 2.9f//isolevel - ); - CGAL::refine_mesh_3(c3t3, domain, criteria); - /// [Meshing] - - /// Output - CGAL::dump_c3t3(c3t3, "out"); - - return 0; -} diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index feff42b26b3..ff8716e85c4 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -5,17 +5,19 @@ #include #include -#include - #include #include #include #include + +#include + // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; +typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -33,70 +35,57 @@ typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; -template -void initialize_triangulation_from_labeled_image(C3T3& c3t3, - const MeshDomain& domain, - const CGAL::Image_3& image) +struct Custom_Initial_points_generator { - typedef typename C3T3::Triangulation Tr; - typedef typename Tr::Geom_traits GT; - typedef typename Tr::Weighted_point Weighted_point; - typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename MeshDomain::Point_3 Point_3; - typedef typename MeshDomain::Index Index; + CGAL::Image_3& image_; + Custom_Initial_points_generator(CGAL::Image_3& image) : image_(image) { } - typedef typename std::tuple ConstructedPoint; - - Tr& tr = c3t3.triangulation(); - - typename GT::Construct_weighted_point_3 cwp = - tr.geom_traits().construct_weighted_point_3_object(); - - std::vector constructedPoints; - - CGAL::Construct_initial_points_labeled_image construct(image); - construct(std::back_inserter(constructedPoints), domain, c3t3); - - std::cout << " " << constructedPoints.size() << " constructed points" << std::endl; - - for (const ConstructedPoint & constructedPoint : constructedPoints) + template + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 1) const { - const Point_3& point = std::get<0>(constructedPoint); - const int& dimension = std::get<1>(constructedPoint); - const Index& index = std::get<2>(constructedPoint); + typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3; - Weighted_point pi = cwp(point); + typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = + c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); - /// The following lines show how to insert initial points in the - /// `c3t3` object. [insert initial points] - Vertex_handle v = tr.insert(pi); - // `v` could be null if `pi` is hidden by other vertices of `tr`. - CGAL_assertion(v != Vertex_handle()); - c3t3.set_dimension(v, dimension); - c3t3.set_index(v, index); - /// [insert initial points] + // Add points along the segment from + // ( 0.0 50.0 66.66) to + // (100.0 50.0 66.66) + double edge_size = 5; + std::size_t nb = static_cast(100.0 / edge_size); + for (std::size_t i = 1; i < nb; i++) + { + *pts++ = std::make_tuple( + cwp(Point_3(i*edge_size, 50.0, 66.66), edge_size*edge_size), 1, 0); + } + return pts; } -} +}; int main() { - /// [Create the image] - CGAL::Image_3 image = random_labeled_image(); - /// [Create the image] + const std::string fname = CGAL::data_file_path("images/420.inr"); + // Loads image + CGAL::Image_3 image; + if(!image.read(fname)){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } // Domain - Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image + , params::features_detector(CGAL::Mesh_3::Detect_features_on_image_bbox()) + ); // 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).edge_size(3) + .cell_radius_edge_ratio(3).cell_size(3) + ); /// [Meshing] - C3t3 c3t3; - initialize_triangulation_from_labeled_image(c3t3, - domain, - image); - CGAL::refine_mesh_3(c3t3, domain, criteria); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria + , params::initial_points_generator(Custom_Initial_points_generator(image)) + ); /// [Meshing] // Output diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 27ee3d09be0..f9cf60d1a8a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -286,7 +286,7 @@ struct Construct_initial_points_labeled_image if (pi_inside_protecting_sphere) continue; - *pts++ = std::make_tuple(intersect_point, 2, intersect_index); // dimension 2 by construction, points are on surface + *pts++ = std::make_tuple(cwp(intersect_point), 2, intersect_index); // dimension 2 by construction, points are on surface } } } diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 6a5eec6a25a..5a8b83b88e9 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -44,10 +44,9 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_generator()()) { - typedef typename MeshDomain::Point_3 Point_3; + typedef typename C3T3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; typedef typename MeshDomain::Index Index; - typedef std::vector > Initial_points_vector; - typedef typename Initial_points_vector::iterator Ipv_iterator; + typedef std::vector > Initial_points_vector; typedef typename C3T3::Vertex_handle Vertex_handle; // Mesh initialization : get some points and add them to the mesh @@ -58,21 +57,15 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, else //use default number of points 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(); - // Insert points and set their index and dimension - for ( Ipv_iterator it = initial_points.begin() ; - it != initial_points.end() ; - ++it ) - { - Vertex_handle v = c3t3.triangulation().insert(cwp(std::get<0>(*it))); + for (const auto& [weighted_point_3, dimension, index] : initial_points) { + Vertex_handle v = c3t3.triangulation().insert(weighted_point_3); // v could be null if point is hidden if ( v != Vertex_handle() ) { - c3t3.set_dimension(v,std::get<1>(*it)); - c3t3.set_index(v,std::get<2>(*it)); + c3t3.set_dimension(v,dimension); + c3t3.set_index(v,index); } } } @@ -234,7 +227,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > // If c3t3 initialization is not sufficient (may happen if there is only // a planar curve as feature for example), add some surface points - bool need_more_init = c3t3.triangulation().dimension() != 3; + bool need_more_init = c3t3.triangulation().dimension() != 3 || !generator.is_default(); if(!need_more_init) { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); helper.update_restricted_facets(); 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 5a33d9d3cd1..c80235b10ab 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 @@ -14,6 +14,7 @@ #include #include +#include namespace CGAL { @@ -172,12 +173,15 @@ private: template struct Initial_points_generator_options { - typedef typename std::back_insert_iterator>> OutputIterator; + typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; + typedef typename MeshDomain::Index Index; + typedef typename std::back_insert_iterator>> OutputIterator; template - Initial_points_generator_options(const Initial_points_generator& generator) + Initial_points_generator_options(const Initial_points_generator& generator, bool is_default = false) : initial_points_generator_no_number_of_points_(generator) , initial_points_generator_(generator) + , is_default_(is_default) { } OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const @@ -190,7 +194,10 @@ struct Initial_points_generator_options return initial_points_generator_(pts, domain, c3t3, n); } + bool is_default() const { return is_default_; } + private: + const bool is_default_; const std::function initial_points_generator_no_number_of_points_; const std::function initial_points_generator_; }; @@ -242,7 +249,9 @@ struct Domain_features_generator< MeshDomain, true > template struct Initial_points_generator_generator { - typedef typename std::back_insert_iterator>> OutputIterator; + typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; + typedef typename MeshDomain::Index Index; + typedef typename std::back_insert_iterator>> OutputIterator; typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; @@ -250,28 +259,26 @@ struct Initial_points_generator_generator { OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) { - typedef typename MeshDomain::Point_3 Point_3; - typedef typename MeshDomain::Index Index; - typedef typename std::pair Domain_generated_point; - std::vector domain_generated_points; - domain.construct_initial_points_object()(std::back_inserter(domain_generated_points)); - for (Domain_generated_point domain_generated_point : domain_generated_points) - { - *pts++ = std::make_tuple(domain_generated_point.first, 2, domain_generated_point.second); - } + // Use boost to easily create an output iterator. + // This iterator take the domain's construct_initial_points_object output : an std::pair + // and outputs an std::tuple + // As points are on the surfaces by construction, dimension is always 2. + typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = + c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); + domain.construct_initial_points_object()( + boost::make_function_output_iterator([&](const auto& domain_generated_point) { + *pts++ = std::make_tuple(cwp(domain_generated_point.first), 2, domain_generated_point.second); + })); return pts; } OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) { - typedef typename MeshDomain::Point_3 Point_3; - typedef typename MeshDomain::Index Index; - typedef typename std::pair Domain_generated_point; - std::vector domain_generated_points; - domain.construct_initial_points_object()(std::back_inserter(domain_generated_points), n); - for (Domain_generated_point domain_generated_point : domain_generated_points) - { - *pts++ = std::make_tuple(domain_generated_point.first, 2, domain_generated_point.second); - } + typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = + c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); + domain.construct_initial_points_object()( + boost::make_function_output_iterator([&](const auto& domain_generated_point) { + *pts++ = std::make_tuple(cwp(domain_generated_point.first), 2, domain_generated_point.second); + }), n); return pts; } }; @@ -279,7 +286,7 @@ struct Initial_points_generator_generator template Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) { - return Initial_points_generator_options(initial_points_generator); + return Initial_points_generator_options(initial_points_generator, false); } Initial_points_generator_options operator()(const Null_functor&) @@ -289,7 +296,7 @@ struct Initial_points_generator_generator Initial_points_generator_options operator()() { - return Initial_points_generator_options(Initial_points_generator_domain_traductor()); + return Initial_points_generator_options(Initial_points_generator_domain_traductor(), true); } }; From ca605fe57f9f82cd81e4c6af32f08f2bfa5f2ad6 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Tue, 7 Nov 2023 16:24:59 +0100 Subject: [PATCH 29/99] Fix doc build --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 3 +++ Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index f2ea33d691b..8d1493d8ebc 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -30,6 +30,9 @@ output iterator `pts`, as objects of type `std::tuple` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` +@param pts the output points +@param domain the input domain +@param c3t3 the input complex @param n an estimation of the number of points to output */ diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index edf2e81d985..aa003abdbd2 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -749,7 +749,7 @@ the triangulation for each connected component. The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh initialization (following the `InitialPointsGenerator`). The functor -\ref CGAL/Mesh_3/Construct_initial_points_labeled_image.h is used in this example. +`CGAL/Mesh_3/Construct_initial_points_labeled_image.h` is used in this example. It constructs points using the API of the mesh domain, as follows. First the functor `construct_intersect` is created From ec7a6ac87642a00c7556567317a3ae35cc6710c0 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 10 Nov 2023 17:06:04 +0100 Subject: [PATCH 30/99] Added meshing parameter : initial_points --- Mesh_3/include/CGAL/make_mesh_3.h | 35 +++++++-- .../internal/mesh_option_classes.h | 73 +++++++++++++++---- .../internal/parameters_interface.h | 1 + 3 files changed, 89 insertions(+), 20 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 5a8b83b88e9..2c3d642cf74 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -407,7 +407,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * } * \cgalParamDefault{`parameters::exude()`} * \cgalParamSectionEnd - * \cgalParamSectionBegin{Mesh initialization} + * \cgalParamSectionBegin{Mesh initialization with a functor} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be provided to start the meshing process. * It must follow the `InitialPointsGenerator` concept. * The following named parameter controls this option: @@ -415,7 +415,24 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > *
  • `parameters::initial_points_generator()` * } * \cgalParamDefault{`CGAL::Null_Functor()`, the domain's `construct_initial_points_object()` - * will be called for the points initialization.} + * will be called for the points initialization.} + * \cgalParamSectionBegin{Mesh initialization with points} + * \cgalParamDescription{a `std::vector` of initial points, represented as + * `std::vector>` can optionally + * be provided to start the meshing process. + * `Weighted_point_3` is the point's position and weight, + * `int` is the dimension of the minimal dimension subcomplex on which + * the point lies, and + * `Index` is the underlying subcomplex index. + * The following named parameter controls this option: + *
      + *
    • `parameters::initial_points()` + *
    } + * \cgalParamDefault{`std::vector>()`} + * \cgalParamExtra{If this parameter is set, + * the domain's `construct_initial_points_object()` will not be called.} + * \cgalParamExtra{If the parameter `parameters::initial_points_generator()` is set, + * the points will be inserted before calling the functor.} * \cgalParamSectionEnd * \cgalNamedParamsEnd * @@ -444,6 +461,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C { using parameters::choose_parameter; using parameters::get_parameter; + using parameters::get_parameter_reference; C3T3 c3t3; parameters::internal::Exude_options exude_param = choose_parameter(get_parameter(np, internal_np::exude_options_param), parameters::exude().v); parameters::internal::Perturb_options perturb_param = choose_parameter(get_parameter(np, internal_np::perturb_options_param), parameters::perturb().v); @@ -453,9 +471,16 @@ 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::Manifold_options manifold_options_param = choose_parameter(get_parameter(np, internal_np::manifold_param), parameters::internal::Manifold_options()); - 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::initial_points_generator().v)); + using Initial_points_generator_generator = parameters::internal::Initial_points_generator_generator; + using Initial_points = typename Initial_points_generator_generator::Initial_points; + Initial_points empty_vec; + const Initial_points& initial_points + = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); + parameters::internal::Initial_points_generator_options initial_points_generator_options_param = + Initial_points_generator_generator() + (choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), + parameters::initial_points_generator().v), + initial_points); make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, 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 c80235b10ab..57989a1f008 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 @@ -175,31 +175,54 @@ struct Initial_points_generator_options { typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; typedef typename MeshDomain::Index Index; - typedef typename std::back_insert_iterator>> OutputIterator; + typedef typename std::vector> Initial_points; + typedef typename std::back_insert_iterator OutputIterator; template - Initial_points_generator_options(const Initial_points_generator& generator, bool is_default = false) + Initial_points_generator_options(const Initial_points_generator& generator, const Initial_points& initial_points, bool is_default = false) : initial_points_generator_no_number_of_points_(generator) , initial_points_generator_(generator) - , is_default_(is_default) - { } + , is_default_(is_default && initial_points.size() == 0) + { + if (initial_points.size() == 0) + { + initial_points_ = nullptr; + } + else + { + initial_points_ = &initial_points; + } + } OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const { + add_initial_points(pts); return initial_points_generator_no_number_of_points_(pts, domain, c3t3); } OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) const { + add_initial_points(pts); return initial_points_generator_(pts, domain, c3t3, n); } + OutputIterator add_initial_points(OutputIterator pts) const + { + if (initial_points_ != nullptr) + { + for (const auto& point_tuple : *initial_points_) + *pts++ = point_tuple; + } + return pts; + } + bool is_default() const { return is_default_; } private: - const bool is_default_; const std::function initial_points_generator_no_number_of_points_; const std::function initial_points_generator_; + const Initial_points* initial_points_; + const bool is_default_; }; // ----------------------------------- @@ -249,11 +272,9 @@ struct Domain_features_generator< MeshDomain, true > template struct Initial_points_generator_generator { - typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; - typedef typename MeshDomain::Index Index; - typedef typename std::back_insert_iterator>> OutputIterator; - typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; + typedef typename Initial_points_generator_options::Initial_points Initial_points; + typedef typename Initial_points_generator_options::OutputIterator OutputIterator; struct Initial_points_generator_domain_traductor { @@ -283,20 +304,42 @@ struct Initial_points_generator_generator } }; - template - Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) + struct Initial_points_generator_empty { - return Initial_points_generator_options(initial_points_generator, false); + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) + { return pts; } + OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) + { return pts; } + }; + + // With a custom InitialPointsGenerator + template + Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator, const InitalPointsRange& input_features) + { + return Initial_points_generator_options(initial_points_generator, input_features, false); } - Initial_points_generator_options operator()(const Null_functor&) + // Without a custom InitialPointsGenerator + template + Initial_points_generator_options operator()(const InitalPointsRange& input_features) { - return operator()(); + // The domain's construct_initial_points_object is called only if input_features is empty + if (input_features.size() == 0) { + return Initial_points_generator_options(Initial_points_generator_domain_traductor(), input_features, true); + } + return Initial_points_generator_options(Initial_points_generator_empty(), input_features, true); + } + + template + Initial_points_generator_options operator()(const Null_functor&, const InitalPointsRange& input_features) + { + return operator()(input_features); } Initial_points_generator_options operator()() { - return Initial_points_generator_options(Initial_points_generator_domain_traductor(), true); + Initial_points empty_input_features; + return operator()(empty_input_features); } }; 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 57715ff5a2a..8853e49bfd5 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -324,6 +324,7 @@ CGAL_add_named_parameter_with_compatibility(mesh_param_t, mesh_param, mesh_optio 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_options_param_t,initial_points_generator_options_param,initial_points_generator_options) +CGAL_add_named_parameter_with_compatibility(initial_points_param_t,initial_points_param,initial_points) 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) From c9eabbf101488d1b8de09052e6986973ff02fe4c Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 10 Nov 2023 18:20:58 +0100 Subject: [PATCH 31/99] Fix demo errors --- .../internal/mesh_option_classes.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) 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 57989a1f008..0c7129803e9 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 @@ -319,9 +319,16 @@ struct Initial_points_generator_generator return Initial_points_generator_options(initial_points_generator, input_features, false); } + template + Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) + { + Initial_points empty_input_features; + return operator()(initial_points_generator, empty_input_features); + } + // Without a custom InitialPointsGenerator template - Initial_points_generator_options operator()(const InitalPointsRange& input_features) + Initial_points_generator_options operator()(const Null_functor&, const InitalPointsRange& input_features) { // The domain's construct_initial_points_object is called only if input_features is empty if (input_features.size() == 0) { @@ -330,16 +337,10 @@ struct Initial_points_generator_generator return Initial_points_generator_options(Initial_points_generator_empty(), input_features, true); } - template - Initial_points_generator_options operator()(const Null_functor&, const InitalPointsRange& input_features) - { - return operator()(input_features); - } - + // Default construction Initial_points_generator_options operator()() { - Initial_points empty_input_features; - return operator()(empty_input_features); + return operator()(Null_functor()); } }; From d9f0f258a5e6e2b7f71c78d35c9e2b8a09f8c9f6 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Mon, 13 Nov 2023 11:53:55 +0100 Subject: [PATCH 32/99] Added initial_points to the parameter doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index dbf2ec22101..5665782338c 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -462,6 +462,10 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * i.e. the domain's `construct_initial_points_object()` * is called for the initialization of the meshing process. * + * \tparam InitialPointsGenerator a functor following the `InitialPointsGenerator` concept + * + * @param generator an instance of the InitialPointsGenerator functor + * * \cgalHeading{Example} * * \code{.cpp} @@ -471,12 +475,48 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); * \endcode * + * \sa `CGAL::parameters::initial_points()` * \sa `CGAL::make_mesh_3()` * \sa `MeshDomain_3::Construct_initial_points` * */ template unspecified_type initial_points_generator(const InitialPointsGenerator& generator); +/*! + * \ingroup PkgMesh3Parameters + * + * The function `parameters::initial_points()` enables the user to + * specify a `std::vector` of initial points + * to the mesh generation function `make_mesh_3()`. + * The initial points vector is of type `std::vector>` where + * `Weighted_point_3` is the point's position and weight, + * `int` is the dimension of the minimal dimension subcomplex on which the point lies, and + * `Index` is the underlying subcomplex index. + * + * \tparam MeshDomain model of `MeshDomain_3` + * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * + * @param initial_points a vector containing points of type + * `std::tuple` + * + * \cgalHeading{Example} + * + * \code{.cpp} + * // Creation of the initial_points vector + * std::vector> initial_points; + * // Mesh generation from labelled image with connexity checks. + * C3t3 c3t3 = make_mesh_3(domain, + * criteria, + * parameters::initial_points(std::cref(initial_points));//use std::cref to avoid a copy + * \endcode + * + * \sa `CGAL::parameters::initial_points_generator()` + * \sa `CGAL::make_mesh_3()` + * \sa `MeshDomain_3::Construct_initial_points` + * + */ +template +unspecified_type initial_points(const std::vector>& initial_points); } /* namespace parameters */ } /* namespace CGAL */ From 2c9fb5cd4edc7475eab740dee04cdbae7cfd063e Mon Sep 17 00:00:00 2001 From: ange-clement Date: Thu, 28 Mar 2024 14:14:29 +0100 Subject: [PATCH 33/99] doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 8 ++++---- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 4 ++-- Mesh_3/doc/Mesh_3/Mesh_3.txt | 4 ++-- Mesh_3/include/CGAL/make_mesh_3.h | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 5665782338c..300fc2f5748 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -458,7 +458,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * specify a functor following the `InitialPointsGenerator` concept * to the mesh generation function `make_mesh_3()`. * The functor will be called for initialization of the meshing process. - * If this parameter is specified without argument, the default behaviour is executed, + * If this parameter is specified without arguments, the default behavior is executed, * i.e. the domain's `construct_initial_points_object()` * is called for the initialization of the meshing process. * @@ -469,7 +469,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * \cgalHeading{Example} * * \code{.cpp} - * // Mesh generation from labelled image with connexity checks. + * // Mesh generation from labeled image with connexity checks. * C3t3 c3t3 = make_mesh_3(domain, * criteria, * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); @@ -489,7 +489,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * specify a `std::vector` of initial points * to the mesh generation function `make_mesh_3()`. * The initial points vector is of type `std::vector>` where - * `Weighted_point_3` is the point's position and weight, + * `Weighted_point_3` contains the point's position and weight, * `int` is the dimension of the minimal dimension subcomplex on which the point lies, and * `Index` is the underlying subcomplex index. * @@ -504,7 +504,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \code{.cpp} * // Creation of the initial_points vector * std::vector> initial_points; - * // Mesh generation from labelled image with connexity checks. + * // Mesh generation from labeled image with connexity checks. * C3t3 c3t3 = make_mesh_3(domain, * criteria, * parameters::initial_points(std::cref(initial_points));//use std::cref to avoid a copy diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 8d1493d8ebc..9c0f6a10e7b 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -19,7 +19,7 @@ public: /// @{ /*! -Output a set of (`n`) surface points to the +Outputs a set of `n` surface points to the output iterator `pts`, as objects of type `std::tuple`. `Weighted_point_3` is the point's position and weight, @@ -46,7 +46,7 @@ output iterator `pts`, as objects of type `Weighted_point_3` is the point's position and weight, `int` is the dimension of the minimal dimension subcomplex on which the point lies, and `Index` is the underlying subcomplex index. -As `n` is not given, the functor must provide enough +Since there is no `n` given like above, the functor must provide enough points to initialize the mesh generation process. @tparam OutputIterator model of `OutputIterator`, containing points of type diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index aa003abdbd2..e221482e41b 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -751,7 +751,7 @@ It expects a functor that returns a set of points for the mesh initialization (following the `InitialPointsGenerator`). The functor `CGAL/Mesh_3/Construct_initial_points_labeled_image.h` is used in this example. It constructs points using the API of the mesh domain, as follows. -First the functor `construct_intersect` is created +First the functor `construct_intersection` is created \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h construct intersection then the `%Mesh_domain::Intersection` object (a `%tuple` with three @@ -795,7 +795,7 @@ Mesh_3/random_labeled_image.h. The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp features -a custom functor that initialize the triangulation. +a custom functor that initializes the triangulation. A struct `Custom_Initial_points_generator` that places 1D-feature points alongside a line is created. diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 2c3d642cf74..9fa756977e8 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -409,7 +409,6 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialization with a functor} * \cgalParamDescription{an `InitialPointsGenerator` can optionally be provided to start the meshing process. - * It must follow the `InitialPointsGenerator` concept. * The following named parameter controls this option: *
      *
    • `parameters::initial_points_generator()` From e64e28d5ef528f5e580c3fe5333dec54dba0ad09 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 29 Mar 2024 16:29:07 +0100 Subject: [PATCH 34/99] Made initial_point parameter work with any Range With doc and example ( example "mesh_3D_image_with_initial_points.cpp" has been renamed to "mesh_3D_image_with_image_initialization.cpp") --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 9 ++- Mesh_3/doc/Mesh_3/Mesh_3.txt | 12 ++- Mesh_3/doc/Mesh_3/examples.txt | 1 + Mesh_3/examples/Mesh_3/CMakeLists.txt | 6 ++ ...sh_3D_image_with_custom_initialization.cpp | 23 ++++-- ...esh_3D_image_with_image_initialization.cpp | 60 +++++++++++++++ .../mesh_3D_image_with_initial_points.cpp | 38 +++++++--- Mesh_3/include/CGAL/make_mesh_3.h | 45 +++++++++-- .../internal/mesh_option_classes.h | 75 ++++++++++++++++--- 9 files changed, 229 insertions(+), 40 deletions(-) create mode 100644 Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 300fc2f5748..6f773d0ab14 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -486,9 +486,10 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \ingroup PkgMesh3Parameters * * The function `parameters::initial_points()` enables the user to - * specify a `std::vector` of initial points + * specify a container model of `Range` of initial points * to the mesh generation function `make_mesh_3()`. - * The initial points vector is of type `std::vector>` where + * The initial points `Range` has elements of type + * `std::tuple` where * `Weighted_point_3` contains the point's position and weight, * `int` is the dimension of the minimal dimension subcomplex on which the point lies, and * `Index` is the underlying subcomplex index. @@ -496,7 +497,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \tparam MeshDomain model of `MeshDomain_3` * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` * - * @param initial_points a vector containing points of type + * @param initial_points a `Range` containing points of type * `std::tuple` * * \cgalHeading{Example} @@ -504,7 +505,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \code{.cpp} * // Creation of the initial_points vector * std::vector> initial_points; - * // Mesh generation from labeled image with connexity checks. + * // Mesh generation from labeled image with initial points. * C3t3 c3t3 = make_mesh_3(domain, * criteria, * parameters::initial_points(std::cref(initial_points));//use std::cref to avoid a copy diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index e221482e41b..3df3b964890 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -737,14 +737,14 @@ without the weights (left, 25563 vertices) and with the weights (right, 19936 ve \subsubsection Mesh_3DomainsFrom3DImagesWithCustomInitialization Domains From 3D Images, with a Custom Initialization -The example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp is a modification +The example \ref Mesh_3/mesh_3D_image_with_image_initialization.cpp is a modification of \ref Mesh_3/mesh_3D_image.cpp. The goal of that example is to show how the default initialization of the triangulation, using random rays, can be replaced by a new implementation. In this case, the initialization detects all connected components in the 3D segmented image, and inserts points in the triangulation for each connected component. -\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Meshing +\snippet Mesh_3/mesh_3D_image_with_image_initialization.cpp Meshing The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh @@ -785,10 +785,10 @@ Right: the mesh generated after the initialization of all connected components \cgalFigureCaptionEnd Note that the example \ref -Mesh_3/mesh_3D_image_with_initial_points.cpp also shows how to +Mesh_3/mesh_3D_image_with_image_initialization.cpp also shows how to create a 3D image using the undocumented API of CGAL_ImageIO. -\snippet Mesh_3/mesh_3D_image_with_initial_points.cpp Create the image +\snippet Mesh_3/mesh_3D_image_with_image_initialization.cpp Create the image The code of the function `%random_labeled_image()` is in the header file \ref Mesh_3/random_labeled_image.h. @@ -800,6 +800,10 @@ a custom functor that initializes the triangulation. A struct `Custom_Initial_points_generator` that places 1D-feature points alongside a line is created. +Finally, the exemple \ref Mesh_3/mesh_3D_image_with_initial_points.cpp features +a point container that initializes the triangulation using the meshing parameter +`parameters::initial_points()`. + \subsection Mesh_3UsingVariableSizingField Using Variable Sizing Field \subsubsection Mesh_3SizingFieldasanAnalyticalFunction Sizing Field as an Analytical Function diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index 969fb7fd1bf..2c895af603e 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -4,6 +4,7 @@ \example Mesh_3/mesh_3D_image_with_features.cpp \example Mesh_3/mesh_3D_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_image_with_initial_points.cpp +\example Mesh_3/mesh_3D_image_with_image_initialization.cpp \example Mesh_3/mesh_3D_image_with_detection_of_features.cpp \example Mesh_3/mesh_3D_image_with_input_features.cpp \example Mesh_3/mesh_3D_weighted_image.cpp diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 4899a15d588..34b829a03ea 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -162,6 +162,11 @@ if(TARGET CGAL::CGAL_ImageIO) target_link_libraries(mesh_3D_image_with_custom_initialization PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program( + "mesh_3D_image_with_image_initialization.cpp") + target_link_libraries(mesh_3D_image_with_image_initialization + PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program( "mesh_3D_image_with_initial_points.cpp") target_link_libraries(mesh_3D_image_with_initial_points @@ -201,6 +206,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) mesh_3D_image_variable_size mesh_3D_image_with_custom_initialization mesh_3D_image_with_initial_points + mesh_3D_image_with_image_initialization mesh_3D_image_with_features mesh_3D_image_with_detection_of_features mesh_3D_image_with_input_features diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index ff8716e85c4..7b82e482771 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -35,6 +35,11 @@ typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; +// Custom_Initial_points_generator will put points on the mesh for initialisation. +// Those points are objects of type std::tuple. +// Weighted_point_3 is the point's position and weight, +// int is the dimension of the minimal dimension subcomplex on which the point lies, +// Index is the underlying subcomplex index. struct Custom_Initial_points_generator { CGAL::Image_3& image_; @@ -43,20 +48,26 @@ struct Custom_Initial_points_generator template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 1) const { - typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3; + typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3; + typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3; + typedef typename C3t3::Triangulation::Geom_traits::Segment_3 Segment_3; typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); - // Add points along the segment from - // ( 0.0 50.0 66.66) to - // (100.0 50.0 66.66) + // Add points along the segment + Segment_3 segment(Point_3( 0.0, 50.0, 66.66), + Point_3(100.0, 50.0, 66.66)); + + + Point_3 source = segment.source(); + Vector_3 vector = segment.to_vector(); double edge_size = 5; - std::size_t nb = static_cast(100.0 / edge_size); + std::size_t nb = static_cast(CGAL::sqrt(segment.squared_length()) / edge_size); for (std::size_t i = 1; i < nb; i++) { *pts++ = std::make_tuple( - cwp(Point_3(i*edge_size, 50.0, 66.66), edge_size*edge_size), 1, 0); + cwp(source + (i/(double)nb)*vector, edge_size*edge_size), 1, 0); } return pts; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp new file mode 100644 index 00000000000..c205f1502b9 --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -0,0 +1,60 @@ +#include "random_labeled_image.h" +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +#ifdef CGAL_CONCURRENT_MESH_3 +typedef CGAL::Parallel_tag Concurrency_tag; +#else +typedef CGAL::Sequential_tag Concurrency_tag; +#endif + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; + +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +namespace params = CGAL::parameters; + +int main() +{ + /// [Create the image] + CGAL::Image_3 image = random_labeled_image(); + /// [Create the image] + + // Domain + 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) + ); + + /// [Meshing] + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria + , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) + ); + /// [Meshing] + + // Output + CGAL::dump_c3t3(c3t3, "out"); + + return 0; +} 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 c205f1502b9..8487875382c 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 @@ -5,17 +5,19 @@ #include #include -#include - #include #include #include #include + +#include + // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; +typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -35,21 +37,39 @@ namespace params = CGAL::parameters; int main() { - /// [Create the image] - CGAL::Image_3 image = random_labeled_image(); - /// [Create the image] + const std::string fname = CGAL::data_file_path("images/420.inr"); + // Loads image + CGAL::Image_3 image; + if(!image.read(fname)){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } // Domain - Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image + , params::features_detector(CGAL::Mesh_3::Detect_features_in_image()) + ); // 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).edge_size(3) .cell_radius_edge_ratio(3).cell_size(3) ); + using Point_3 = K::Point_3; + using Weighted_point_3 = K::Weighted_point_3; + using Index = Mesh_domain::Index; + using Initial_point_t = std::tuple; + + // Creation of the initial_points vector + std::vector initial_points = { + std::make_tuple(Weighted_point_3(Point_3(30.0, 50.0, 83.33), 30.0), 1, 0), + std::make_tuple(Weighted_point_3(Point_3(70.0, 50.0, 83.33), 50.0), 1, 0) + }; + /// [Meshing] + // Mesh generation from labeled image with initial points. C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) + , params::initial_points(std::cref(initial_points)) ); /// [Meshing] diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 9fa756977e8..abcef5d7181 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -40,9 +40,9 @@ namespace internal { template < typename C3T3, typename MeshDomain, typename MeshCriteria > void -init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, - const int nb_initial_points, - const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_generator()()) +add_points_from_generator(C3T3& c3t3, const MeshDomain& domain, + const int nb_initial_points, + const parameters::internal::Initial_points_generator_options& generator) { typedef typename C3T3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; typedef typename MeshDomain::Index Index; @@ -70,6 +70,39 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, } } +template < typename C3T3, typename MeshDomain, typename MeshCriteria > +void +init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, + const int nb_initial_points, + const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_generator()()) +{ + add_points_from_generator(c3t3, domain, nb_initial_points, generator); + + // If c3t3 initialization is not sufficient (may happen if + // the user has not specified enough points ), add some surface points + bool need_more_init = c3t3.triangulation().dimension() != 3 || !generator.is_default(); + if(!need_more_init) { + CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); + helper.update_restricted_facets(); + + if (c3t3.number_of_facets() == 0) { + need_more_init = true; + } + else + { + helper.update_restricted_cells(); + if(c3t3.number_of_cells() == 0) { + need_more_init = true; + } + } + } + if(need_more_init) { + parameters::internal::Initial_points_generator_options domain_generator = + parameters::internal::Initial_points_generator_generator()(); + add_points_from_generator(c3t3, domain, nb_initial_points, domain_generator); + } +} + template < typename EdgeCriteria > struct Edge_criteria_sizing_field_wrapper { @@ -471,9 +504,9 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C 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; - using Initial_points = typename Initial_points_generator_generator::Initial_points; - Initial_points empty_vec; - const Initial_points& initial_points + using Value_type = typename Initial_points_generator_generator::Value_type; + std::vector empty_vec; + const auto& initial_points = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); parameters::internal::Initial_points_generator_options initial_points_generator_options_param = Initial_points_generator_generator() 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 0c7129803e9..b63baf3bb65 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,6 +168,54 @@ private: bool b_; }; +template +class Input_const_iterator_interface +{ +public: + virtual ~Input_const_iterator_interface() {} + virtual const Value& operator*() = 0; + virtual Input_const_iterator_interface* operator++() = 0; + virtual bool operator!=(const Input_const_iterator_interface* other) const = 0; + virtual Input_const_iterator_interface* clone() = 0; +}; + +template +struct Input_const_iterator_container + : Input_const_iterator_interface +{ + typedef Input_const_iterator_container Self; +public: + Input_const_iterator_container(const Iterator& it) : it_(it) {} + + virtual ~Input_const_iterator_container() {} + + virtual const Value& operator*() + { + return *it_; + } + + virtual Input_const_iterator_interface* operator++() + { + ++it_; + return this; + } + + virtual bool operator!=(const Input_const_iterator_interface* other) const + { + const Self* other_casted = dynamic_cast(other); + if (other_casted == nullptr) + return true; + return it_ != other_casted->it_; + } + + virtual Input_const_iterator_interface* clone() + { + return new Input_const_iterator_container(it_); + } + +private: + Iterator it_; +}; // options is holding the generator (default or the user's one) template @@ -175,10 +223,10 @@ struct Initial_points_generator_options { typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; typedef typename MeshDomain::Index Index; - typedef typename std::vector> Initial_points; - typedef typename std::back_insert_iterator OutputIterator; + typedef typename std::tuple Value_type; + typedef typename std::back_insert_iterator> OutputIterator; - template + template Initial_points_generator_options(const Initial_points_generator& generator, const Initial_points& initial_points, bool is_default = false) : initial_points_generator_no_number_of_points_(generator) , initial_points_generator_(generator) @@ -186,11 +234,14 @@ struct Initial_points_generator_options { if (initial_points.size() == 0) { - initial_points_ = nullptr; + begin_it = nullptr; + end_it = nullptr; } else { - initial_points_ = &initial_points; + using Iterator_type = typename Initial_points::const_iterator; + begin_it = new Input_const_iterator_container(initial_points.cbegin()); + end_it = new Input_const_iterator_container(initial_points.cend()); } } @@ -208,10 +259,11 @@ struct Initial_points_generator_options OutputIterator add_initial_points(OutputIterator pts) const { - if (initial_points_ != nullptr) + if (begin_it != nullptr && end_it != nullptr) { - for (const auto& point_tuple : *initial_points_) - *pts++ = point_tuple; + Input_const_iterator_interface& it = *(begin_it->clone()); + for (; it != end_it; ++it) + *pts++ = *it; } return pts; } @@ -221,7 +273,8 @@ struct Initial_points_generator_options private: const std::function initial_points_generator_no_number_of_points_; const std::function initial_points_generator_; - const Initial_points* initial_points_; + Input_const_iterator_interface* begin_it; + Input_const_iterator_interface* end_it; const bool is_default_; }; @@ -273,7 +326,7 @@ template struct Initial_points_generator_generator { typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; - typedef typename Initial_points_generator_options::Initial_points Initial_points; + typedef typename Initial_points_generator_options::Value_type Value_type; typedef typename Initial_points_generator_options::OutputIterator OutputIterator; struct Initial_points_generator_domain_traductor @@ -322,7 +375,7 @@ struct Initial_points_generator_generator template Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) { - Initial_points empty_input_features; + std::vector empty_input_features; return operator()(initial_points_generator, empty_input_features); } From ae0f8f37c997c171575b67ae67fec762dd8c152d Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 29 Mar 2024 16:49:33 +0100 Subject: [PATCH 35/99] Finished Merge --- Mesh_3/include/CGAL/make_mesh_3.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 6de7a2c5c7e..ff31c5b96d7 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -45,10 +45,12 @@ add_points_from_generator(C3T3& c3t3, const MeshDomain& domain, const parameters::internal::Initial_points_generator_options& generator) { 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 Initialization_point + typedef typename std::tuple Initialization_point; typedef std::vector< Initialization_point > Initial_points_vector; + typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; From b1fb29c22a919f6864511943f9e007ed4ff40052 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 29 Mar 2024 17:03:20 +0100 Subject: [PATCH 36/99] InitialPointsGenerator parameter 'n' explanation --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 9c0f6a10e7b..4a4e363d237 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -33,7 +33,9 @@ output iterator `pts`, as objects of type @param pts the output points @param domain the input domain @param c3t3 the input complex -@param n an estimation of the number of points to output +@param n an estimation of the number of points to output. +A generator can choose to ignore this parameter. +If a generator does not output enough points, then more points will be added automatically. */ template From da690fda1182fa8cd5e3551824a0104c78c6c45b Mon Sep 17 00:00:00 2001 From: ange-clement Date: Fri, 5 Apr 2024 11:09:33 +0200 Subject: [PATCH 37/99] Fixed warning unused variables --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 b63baf3bb65..659ed137860 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 @@ -359,9 +359,9 @@ struct Initial_points_generator_generator struct Initial_points_generator_empty { - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) + OutputIterator operator()(OutputIterator pts, const MeshDomain& , const C3t3& ) { return pts; } - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) + OutputIterator operator()(OutputIterator pts, const MeshDomain& , const C3t3& , int ) { return pts; } }; From f2a2051911632f50b5fb30b581ff81daea5763c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 5 Apr 2024 19:00:01 +0200 Subject: [PATCH 38/99] do not use deprecated include path --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 659ed137860..32dc74edc6a 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 @@ -14,7 +14,7 @@ #include #include -#include +#include namespace CGAL { From 27013140551cd8b77c0404e96e950cb72b838dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Apr 2024 13:53:47 +0200 Subject: [PATCH 39/99] fix warnings --- .../Mesh_3/mesh_3D_image_with_custom_initialization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 7b82e482771..8ba0e155f2f 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -46,7 +46,7 @@ struct Custom_Initial_points_generator Custom_Initial_points_generator(CGAL::Image_3& image) : image_(image) { } template - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 1) const + OutputIterator operator()(OutputIterator pts, const MeshDomain& /* domain */, const C3t3& c3t3, int /* n */ = 1) const { typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3; typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3; From 561256ee0ba935ec7d4026d427a8e5249d45c48a Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 15 Apr 2024 15:37:12 +0200 Subject: [PATCH 40/99] use override instead of virtual --- .../CGAL/STL_Extension/internal/mesh_option_classes.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 32dc74edc6a..201c50e1e4f 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 @@ -187,20 +187,20 @@ struct Input_const_iterator_container public: Input_const_iterator_container(const Iterator& it) : it_(it) {} - virtual ~Input_const_iterator_container() {} + ~Input_const_iterator_container() override {} - virtual const Value& operator*() + const Value& operator*() override { return *it_; } - virtual Input_const_iterator_interface* operator++() + Input_const_iterator_interface* operator++() override { ++it_; return this; } - virtual bool operator!=(const Input_const_iterator_interface* other) const + bool operator!=(const Input_const_iterator_interface* other) const override { const Self* other_casted = dynamic_cast(other); if (other_casted == nullptr) @@ -208,7 +208,7 @@ public: return it_ != other_casted->it_; } - virtual Input_const_iterator_interface* clone() + Input_const_iterator_interface* clone() override { return new Input_const_iterator_container(it_); } From cf01bdc179fcf248ee6c7e28655cf4dcbf046b88 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 15 Apr 2024 15:37:26 +0200 Subject: [PATCH 41/99] simplify the snippets --- .../Mesh_3/Construct_initial_points_labeled_image.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index f9cf60d1a8a..0ea81bf8085 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -187,10 +187,10 @@ struct Construct_initial_points_labeled_image const double radius = double(seed.radius + 1)* max_v; CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); - /// \noop [construct intersection] + // [construct intersection] typename MeshDomain::Construct_intersection construct_intersection = domain.construct_intersection_object(); - /// \noop [construct intersection] + // [construct intersection] std::vector directions; if(seed.radius < 2) { @@ -214,16 +214,16 @@ struct Construct_initial_points_labeled_image const Point_3 test = seed_point + v; const Segment_3 test_segment = Segment_3(seed_point, test); - /// \noop [use construct intersection] + // [use construct intersection] const typename MeshDomain::Intersection intersect = construct_intersection(test_segment); - /// \noop [use construct intersection] + // [use construct intersection] if (std::get<2>(intersect) != 0) { - /// \noop [get construct intersection] + // [get construct intersection] const Point_3& intersect_point = std::get<0>(intersect); const Index& intersect_index = std::get<1>(intersect); - /// \noop [get construct intersection] + // [get construct intersection] Weighted_point pi = Weighted_point(intersect_point); // This would cause trouble to optimizers From d7ea10123140098f0bad5981efe731cd4f292445 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 29 Apr 2024 16:19:52 +0200 Subject: [PATCH 42/99] improve the doc sentences --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 34 +++++----------- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- .../Construct_initial_points_gray_image.h | 39 +++++++++---------- 3 files changed, 30 insertions(+), 45 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 6f773d0ab14..b068289faa4 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -454,22 +454,16 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points_generator()` enables the user to - * specify a functor following the `InitialPointsGenerator` concept - * to the mesh generation function `make_mesh_3()`. - * The functor will be called for initialization of the meshing process. - * If this parameter is specified without arguments, the default behavior is executed, - * i.e. the domain's `construct_initial_points_object()` - * is called for the initialization of the meshing process. + * The function `parameters::initial_points_generator()` allows the user to specify a functor that follows the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor will be called for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * - * \tparam InitialPointsGenerator a functor following the `InitialPointsGenerator` concept + * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept * * @param generator an instance of the InitialPointsGenerator functor * * \cgalHeading{Example} * * \code{.cpp} - * // Mesh generation from labeled image with connexity checks. + * // Mesh generation from a labeled image with connexity checks. * C3t3 c3t3 = make_mesh_3(domain, * criteria, * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); @@ -485,30 +479,22 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points()` enables the user to - * specify a container model of `Range` of initial points - * to the mesh generation function `make_mesh_3()`. - * The initial points `Range` has elements of type - * `std::tuple` where - * `Weighted_point_3` contains the point's position and weight, - * `int` is the dimension of the minimal dimension subcomplex on which the point lies, and - * `Index` is the underlying subcomplex index. + * The function `parameters::initial_points()` allows the user to specify a container model of `Range` that contains initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` should have elements of type `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, `int` represents the dimension of the minimal subcomplex on which the point lies, and `Index` represents the underlying subcomplex index. * - * \tparam MeshDomain model of `MeshDomain_3` - * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * \tparam MeshDomain a model of `MeshDomain_3` + * \tparam C3t3 a model of `MeshComplex_3InTriangulation_3` * - * @param initial_points a `Range` containing points of type - * `std::tuple` + * @param initial_points a `Range` that contains points of type `std::tuple` * * \cgalHeading{Example} * * \code{.cpp} - * // Creation of the initial_points vector + * // Create the initial_points vector * std::vector> initial_points; - * // Mesh generation from labeled image with initial points. + * // Perform mesh generation from a labeled image with initial points * C3t3 c3t3 = make_mesh_3(domain, * criteria, - * parameters::initial_points(std::cref(initial_points));//use std::cref to avoid a copy + * parameters::initial_points(std::cref(initial_points))); // Use std::cref to avoid a copy * \endcode * * \sa `CGAL::parameters::initial_points_generator()` diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index df30cd0b5d6..fd19c6b8276 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -129,7 +129,7 @@ The following functors are available for mesh initialization: - `CGAL::odt_optimize_mesh_3()` - `CGAL::Mesh_3::generate_label_weights()` -\cgalCRPSection{CGAL::parameters Functions} +\cgalCRPSection{%CGAL::parameters Functions} - `CGAL::parameters::features()` - `CGAL::parameters::no_features()` diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index bef74411440..a692c72cbc8 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -24,17 +24,17 @@ namespace CGAL { /*! -* \ingroup PkgMesh3Initializers -* -* Functor for initial points generation in gray images. -* This functor is a model of concept `InitialPointsGenerator`, -* and thus can be passed to `CGAL::make_mesh_3` with the parameter -* `CGAL::parameters::initial_points_generator()` -* -* \sa `CGAL::parameters::initial_points_generator()` -* \sa `CGAL::make_mesh_3()` -* \sa `CGAL::Construct_initial_points_labeled_image` -*/ + * \ingroup PkgMesh3Initializers + * + * Functor for generating initial points in gray images. + * This functor is a model of the `InitialPointsGenerator` concept, + * and can be passed as a parameter to `CGAL::make_mesh_3` using the + * `CGAL::parameters::initial_points_generator()` parameter function. + * + * \sa `CGAL::parameters::initial_points_generator()` + * \sa `CGAL::make_mesh_3()` + * \sa `CGAL::Construct_initial_points_labeled_image` + */ template struct Construct_initial_points_gray_image { @@ -50,15 +50,14 @@ struct Construct_initial_points_gray_image , iso_value_(iso_value) , image_values_to_subdomain_indices_(image_values_to_subdomain_indices) { } - - /*! - * \brief Constructs the initial points using the gray image. - * - * @tparam OutputIterator an `OutputIterator` of points of type - * `std::tuple` - * @tparam MeshDomain a model of `MeshDomain_3` - * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` - */ + /*! + * \brief Constructs the initial points using the gray image. + * + * \tparam OutputIterator An `OutputIterator` of points of type + * `std::tuple`. + * \tparam MeshDomain A model of `MeshDomain_3`. + * \tparam C3t3 A model of `MeshComplex_3InTriangulation_3`. + */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const { From 2813d53c7f4578e6822e0bad5bc9bc981857cb15 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 29 Apr 2024 16:47:15 +0200 Subject: [PATCH 43/99] other changes I forgot to commit --- .../Construct_initial_points_labeled_image.h | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 0ea81bf8085..1b804f4dbdf 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -71,17 +71,17 @@ struct Get_point } // end namespace Mesh_3 /*! -* \ingroup PkgMesh3Initializers -* -* Functor for initial points generation in labeled images. -* This functor is a model of concept `InitialPointsGenerator`, -* and thus can be passed to `CGAL::make_mesh_3` with the parameter -* `CGAL::parameters::initial_points_generator()` -* -* \sa `CGAL::parameters::initial_points_generator()` -* \sa `CGAL::make_mesh_3()` -* \sa `CGAL::Construct_initial_points_gray_image` -*/ + * \ingroup PkgMesh3Initializers + * + * Functor for generating initial points in labeled images. + * This functor is a model of the `InitialPointsGenerator` concept, + * and can be passed as a parameter to `CGAL::make_mesh_3` using the + * `CGAL::parameters::initial_points_generator()` function. + * + * \sa `CGAL::parameters::initial_points_generator()` + * \sa `CGAL::make_mesh_3()` + * \sa `CGAL::Construct_initial_points_gray_image` + */ struct Construct_initial_points_labeled_image { const CGAL::Image_3 & image; @@ -90,15 +90,15 @@ struct Construct_initial_points_labeled_image : image(image_) { } - /*! - * \brief Constructs points by collecting them in all connected components. - * This guarantees to initialize them all. - * - * @tparam OutputIterator model of `OutputIterator`, containing points of type - * `std::tuple` - * @tparam MeshDomain model of `MeshDomain_3` - * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` - */ + /*! + * \brief Constructs points by collecting them from all connected components. + * This ensures that all points are initialized. + * + * @tparam OutputIterator a model of `OutputIterator` that contains points of type + * `std::tuple` + * @tparam MeshDomain a model of `MeshDomain_3` + * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const { @@ -107,18 +107,18 @@ struct Construct_initial_points_labeled_image } /*! - * \brief Same as above, but a `TransformOperator` is used + * \brief Same as above, but a `TransformOperator` is used. * - * @tparam OutputIterator model of `OutputIterator`, containing points of type - * `std::tuple` - * @tparam MeshDomain model of `MeshDomain_3` - * @tparam TransformOperator functor that transforms values of the image. + * @tparam OutputIterator A model of `OutputIterator` that contains points of type + * `std::tuple`. + * @tparam MeshDomain A model of `MeshDomain_3`. + * @tparam TransformOperator A functor that transforms values of the image. * It must provide the following type:
      * `result_type`
      * and the following operator:
      * `template`
      - * `result_type operator()(FT v)` - * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * `result_type operator()(FT v)`. + * @tparam C3t3 A model of `MeshComplex_3InTriangulation_3`. */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const From 8575f5358310caa7c67dd73aa8b94590f5ad72b4 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Thu, 2 May 2024 17:29:23 +0200 Subject: [PATCH 44/99] Doc upgrades + simplified initial_points_generator parameter + fixed memory leaks --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 13 ++++---- Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- ...esh_3D_image_with_image_initialization.cpp | 5 +-- .../Construct_initial_points_gray_image.h | 7 +++- .../Construct_initial_points_labeled_image.h | 16 +++++---- Mesh_3/include/CGAL/make_mesh_3.h | 8 +++-- .../internal/mesh_option_classes.h | 33 ++++++++++++++++--- .../internal/mesh_parameters_interface.h | 17 ---------- .../internal/parameters_interface.h | 2 +- 10 files changed, 64 insertions(+), 41 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index b068289faa4..003ced5956a 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -456,18 +456,16 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * * The function `parameters::initial_points_generator()` allows the user to specify a functor that follows the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor will be called for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * + * If the generator does not generate enough points, the domain's `construct_initial_points_object()` will be called. + * If the parameter `parameters::initial_points()` is set, the functor will be called after insertion of the points. + * * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept * * @param generator an instance of the InitialPointsGenerator functor * * \cgalHeading{Example} * - * \code{.cpp} - * // Mesh generation from a labeled image with connexity checks. - * C3t3 c3t3 = make_mesh_3(domain, - * criteria, - * parameters::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image))); - * \endcode + * \snippet mesh_3D_image_with_image_initialization.cpp Meshing * * \sa `CGAL::parameters::initial_points()` * \sa `CGAL::make_mesh_3()` @@ -481,6 +479,9 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * * The function `parameters::initial_points()` allows the user to specify a container model of `Range` that contains initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` should have elements of type `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, `int` represents the dimension of the minimal subcomplex on which the point lies, and `Index` represents the underlying subcomplex index. * + * If this parameter is set, the domain's `construct_initial_points_object()` will not be called. + * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. + * * \tparam MeshDomain a model of `MeshDomain_3` * \tparam C3t3 a model of `MeshComplex_3InTriangulation_3` * diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 3df3b964890..d48984d0055 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -788,7 +788,7 @@ Note that the example \ref Mesh_3/mesh_3D_image_with_image_initialization.cpp also shows how to create a 3D image using the undocumented API of CGAL_ImageIO. -\snippet Mesh_3/mesh_3D_image_with_image_initialization.cpp Create the image +\snippet Mesh_3/mesh_3D_image_with_image_initialization.cpp Create_the_image The code of the function `%random_labeled_image()` is in the header file \ref Mesh_3/random_labeled_image.h. diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index c94fd737b7d..d1095639e14 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -31,7 +31,7 @@ /// \defgroup PkgMesh3Initializers Mesh Initialization Functions /// \ingroup PkgMesh3Ref - +/// The functors in this group perform mesh initialization by providing initial points. /// \defgroup PkgMesh3Parameters Parameter Functions /// \ingroup PkgMesh3Ref diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index c205f1502b9..952df762d38 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -35,9 +35,9 @@ namespace params = CGAL::parameters; int main() { - /// [Create the image] + /// [Create_the_image] CGAL::Image_3 image = random_labeled_image(); - /// [Create the image] + /// [Create_the_image] // Domain Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); @@ -48,6 +48,7 @@ int main() ); /// [Meshing] + // Mesh generation with a custom initialization that places points in each of the image components. C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) ); diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index a692c72cbc8..fff140d0644 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -31,6 +31,9 @@ namespace CGAL * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * + * On images that contains multiple non-connected objects, + * this functor will output points on every object. + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_labeled_image` @@ -51,7 +54,9 @@ struct Construct_initial_points_gray_image , image_values_to_subdomain_indices_(image_values_to_subdomain_indices) { } /*! - * \brief Constructs the initial points using the gray image. + * \brief Constructs points by collecting them in all objects of the image, + * even if they are not connected. + * This guarantees to initialize all objects * * \tparam OutputIterator An `OutputIterator` of points of type * `std::tuple`. diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 1b804f4dbdf..24db92793f2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -78,6 +78,9 @@ struct Get_point * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` function. * + * On images that contains multiple non-connected objects, + * this functor will output points on every object. + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_gray_image` @@ -91,7 +94,8 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief Constructs points by collecting them from all connected components. + * \brief Constructs points by collecting them in all objects of the image, + * even if they are not connected. * This ensures that all points are initialized. * * @tparam OutputIterator a model of `OutputIterator` that contains points of type @@ -107,18 +111,18 @@ struct Construct_initial_points_labeled_image } /*! - * \brief Same as above, but a `TransformOperator` is used. + * \brief Same as above, but a `TransformOperator` that transforms values of the image is used. * * @tparam OutputIterator A model of `OutputIterator` that contains points of type * `std::tuple`. * @tparam MeshDomain A model of `MeshDomain_3`. * @tparam TransformOperator A functor that transforms values of the image. * It must provide the following type:
      - * `result_type`
      + * `result_type` : a type that support the '==' operator
      * and the following operator:
      - * `template`
      - * `result_type operator()(FT v)`. - * @tparam C3t3 A model of `MeshComplex_3InTriangulation_3`. + * `result_type operator()(Word v)` + * with `Word` the type of the image value. + * @tparam C3t3 A model of `MeshComplex_3InTriangulation_3` */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index ff31c5b96d7..9eee0934265 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -458,6 +458,10 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > *
    } * \cgalParamDefault{`CGAL::Null_Functor()`, the domain's `construct_initial_points_object()` * will be called for the points initialization.} + * \cgalParamExtra{If the generator does not generate enough points, + * the domain's `construct_initial_points_object()` will be called.} + * \cgalParamExtra{If the parameter `parameters::initial_points()` is set, + * the functor will be called after insertion of the points.} * \cgalParamSectionBegin{Mesh initialization with points} * \cgalParamDescription{a `std::vector` of initial points, represented as * `std::vector>` can optionally @@ -520,8 +524,8 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); parameters::internal::Initial_points_generator_options initial_points_generator_options_param = Initial_points_generator_generator() - (choose_parameter(get_parameter(np, internal_np::initial_points_generator_options_param), - parameters::initial_points_generator().v), + (choose_parameter(get_parameter(np, internal_np::initial_points_generator_param), + CGAL::Null_functor()), initial_points); make_mesh_3_impl(c3t3, domain, criteria, 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 201c50e1e4f..c2172ed5887 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,6 +168,14 @@ private: bool b_; }; +// 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 class Input_const_iterator_interface { @@ -179,6 +187,7 @@ public: virtual Input_const_iterator_interface* clone() = 0; }; +// An iterator container that implements the `Input_const_iterator_interface` interface. template struct Input_const_iterator_container : Input_const_iterator_interface @@ -217,7 +226,8 @@ private: Iterator it_; }; -// options is holding the generator (default or the user's one) +// Holds the two parameters `initial_points_generator` and `initial_points`, +// without knowing their types, into a single generator. template struct Initial_points_generator_options { @@ -245,6 +255,15 @@ struct Initial_points_generator_options } } + ~Initial_points_generator_options() + { + if (begin_it != nullptr) + delete begin_it; + if (end_it != nullptr) + delete end_it; + } + + // Firstly, the `initial_points` are inserted, then, the `initial_points_generator` is called. OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const { add_initial_points(pts); @@ -261,9 +280,11 @@ struct Initial_points_generator_options { if (begin_it != nullptr && end_it != nullptr) { - Input_const_iterator_interface& it = *(begin_it->clone()); + Input_const_iterator_interface* it_ptr = begin_it->clone(); + Input_const_iterator_interface& it = *(it_ptr); for (; it != end_it; ++it) *pts++ = *it; + delete it_ptr; } return pts; } @@ -271,10 +292,13 @@ struct Initial_points_generator_options bool is_default() const { return is_default_; } private: + // The two functions holds the `initial_points_generator` functor const std::function initial_points_generator_no_number_of_points_; const std::function initial_points_generator_; + // The two iterators holds the `initial_points` container Input_const_iterator_interface* begin_it; Input_const_iterator_interface* end_it; + // Is the option a default-constructed one ? const bool is_default_; }; @@ -320,8 +344,9 @@ struct Domain_features_generator< MeshDomain, true > } }; -// struct Initial_points_generator_generator evaluate the options_holder -// and returns the appropriate options. +// Evaluate the two parameters `initial_points_generator` and `initial_points` +// and returns the appropriate `Initial_points_generator_options`. +// If no generator and no initial points, then use the domain's construct_initial_points_object. template struct Initial_points_generator_generator { 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 00ffd6b769e..8fc2baca0c3 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,20 +368,3 @@ 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::Null_functor, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> -initial_points_generator() { - typedef Named_function_parameters<::CGAL::Null_functor, ::CGAL::internal_np::initial_points_generator_options_param_t, CGAL_NP_BASE> Param; - return CGAL_NP_BUILD(Param, ::CGAL::Null_functor()); -} - -template -inline Named_function_parameters -initial_points_generator(const InitialPointsGenerator& generator) -{ - typedef Named_function_parameters Param; - return CGAL_NP_BUILD(Param, 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 f233d24b704..f24867aa76d 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -337,7 +337,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_options_param_t,initial_points_generator_options_param,initial_points_generator_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_param_t,initial_points_param,initial_points) CGAL_add_named_parameter_with_compatibility_cref_only(image_3_param_t, image_3_param, image) From 58d5050d35b2b1a2d8aaec14a21d26228b50ef90 Mon Sep 17 00:00:00 2001 From: ange-clement Date: Wed, 22 May 2024 13:05:16 +0200 Subject: [PATCH 45/99] Updated CHANGES.md --- Installation/CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index e50986b2680..ab69a6cf614 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -55,6 +55,10 @@ Release date: June 2024 - Removed the class templates `Gray_image_mesh_domain_3`, `Implicit_mesh_domain_3`, and `Labeled_image_mesh_domain_3` which are deprecated since CGAL-4.13. +- Added two new meshing parameters that enable mesh initialization customization : + - `initial_points_generator` : enables the user to specify a functor that generate initial points. + - `initial_points` : enable the user to specify a `Range` of initial points. + ### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/6.0/Manual/packages.html#PkgOrthtree) - **Breaking change**: - Node splitting behavior and per-node data are now customizable via the Traits class. From 2f25527e94aa8883b2a215dc0347325f09c5197b Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 11:54:52 +0200 Subject: [PATCH 46/99] "at least n" --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 4a4e363d237..11a47461cce 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -19,7 +19,7 @@ public: /// @{ /*! -Outputs a set of `n` surface points to the +Outputs a set of at least `n` surface points to the output iterator `pts`, as objects of type `std::tuple`. `Weighted_point_3` is the point's position and weight, @@ -35,14 +35,14 @@ output iterator `pts`, as objects of type @param c3t3 the input complex @param n an estimation of the number of points to output. A generator can choose to ignore this parameter. -If a generator does not output enough points, then more points will be added automatically. +If it does not output enough points, then more points will be added automatically. */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n); /*! -Output a set of surface points to the +Outputs a set of surface points to the output iterator `pts`, as objects of type `std::tuple`. `Weighted_point_3` is the point's position and weight, From 86edcf8e04c7573d4b64084f8ed8d3abc22841e8 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 11:55:31 +0200 Subject: [PATCH 47/99] rename Functions to Functors --- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index d1095639e14..5022fc0c026 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -29,7 +29,7 @@ /// The two main functions to generate a mesh are `make_mesh_3()` and `refine_mesh_3()`. /// The other functions enable to optimize an existing mesh. -/// \defgroup PkgMesh3Initializers Mesh Initialization Functions +/// \defgroup PkgMesh3Initializers Mesh Initialization Functors /// \ingroup PkgMesh3Ref /// The functors in this group perform mesh initialization by providing initial points. /// \defgroup PkgMesh3Parameters Parameter Functions From b75443637a85ca855be02340000cff2cb2f12ae6 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 12:26:44 +0200 Subject: [PATCH 48/99] tell more about the "all connected components" thing --- .../Construct_initial_points_gray_image.h | 23 ++++++---- .../Construct_initial_points_labeled_image.h | 44 +++++++++++-------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index fff140d0644..08d0f62d806 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -31,8 +31,9 @@ namespace CGAL * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * - * On images that contains multiple non-connected objects, - * this functor will output points on every object. + * On images that contain multiple non-connected components, + * this functor will scan the full image and + * output points on every component. * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` @@ -53,15 +54,19 @@ struct Construct_initial_points_gray_image , iso_value_(iso_value) , image_values_to_subdomain_indices_(image_values_to_subdomain_indices) { } + /*! - * \brief Constructs points by collecting them in all objects of the image, - * even if they are not connected. - * This guarantees to initialize all objects + * \brief Constructs points by collecting them on the surface of all objects + * in the image, + * even if they are non-connected components. + * Using this functor guarantees to initialize each connected component. * - * \tparam OutputIterator An `OutputIterator` of points of type - * `std::tuple`. - * \tparam MeshDomain A model of `MeshDomain_3`. - * \tparam C3t3 A model of `MeshComplex_3InTriangulation_3`. + * \tparam OutputIterator model of `OutputIterator`, collecting points of type + * `std::tuple` + * \tparam MeshDomain model of `MeshDomain_3` + * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * + * \param n a lower bound on the number of points to be constructed */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 24db92793f2..e1b4c689908 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -76,10 +76,11 @@ struct Get_point * Functor for generating initial points in labeled images. * This functor is a model of the `InitialPointsGenerator` concept, * and can be passed as a parameter to `CGAL::make_mesh_3` using the - * `CGAL::parameters::initial_points_generator()` function. + * `CGAL::parameters::initial_points_generator()` parameter function. * - * On images that contains multiple non-connected objects, - * this functor will output points on every object. + * On images that contain multiple non-connected components, + * this functor scans the complete image and + * outputs points to initialize each component. * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` @@ -94,14 +95,17 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief Constructs points by collecting them in all objects of the image, - * even if they are not connected. - * This ensures that all points are initialized. + * \brief Constructs points by scanning the image and + * collecting points in each object in the image, + * even if they are non-connected components. + * This ensures that each component will be initialized. * - * @tparam OutputIterator a model of `OutputIterator` that contains points of type + * @tparam OutputIterator model of `OutputIterator` that contains points of type * `std::tuple` - * @tparam MeshDomain a model of `MeshDomain_3` - * @tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + * @tparam MeshDomain model of `MeshDomain_3` + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * + * @param n a lower bound on the number of constructed points */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const @@ -113,16 +117,18 @@ struct Construct_initial_points_labeled_image /*! * \brief Same as above, but a `TransformOperator` that transforms values of the image is used. * - * @tparam OutputIterator A model of `OutputIterator` that contains points of type - * `std::tuple`. - * @tparam MeshDomain A model of `MeshDomain_3`. - * @tparam TransformOperator A functor that transforms values of the image. - * It must provide the following type:
    - * `result_type` : a type that support the '==' operator
    - * and the following operator:
    - * `result_type operator()(Word v)` - * with `Word` the type of the image value. - * @tparam C3t3 A model of `MeshComplex_3InTriangulation_3` + * @tparam OutputIterator model of `OutputIterator` that contains points of type + * `std::tuple` + * @tparam MeshDomain model of `MeshDomain_3` + * @tparam TransformOperator functor that transforms values of the image. + * It must provide the following type:
    + * `result_type` : a type that supports the '==' operator
    + * and the following operator:
    + * `result_type operator()(Word v)` + * with `Word` the type of the image values. + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * + * @param n a lower bound on the number of constructed points */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const From f09c8d9a57b55a7ef63e051b5a45920eb23461ea Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 12:26:56 +0200 Subject: [PATCH 49/99] cleaning --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 003ced5956a..4e400391ba1 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -454,14 +454,17 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points_generator()` allows the user to specify a functor that follows the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor will be called for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. + * The function `parameters::initial_points_generator()` allows the user to specify a functor that follows + * the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor will be called + * for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior + * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * * If the generator does not generate enough points, the domain's `construct_initial_points_object()` will be called. * If the parameter `parameters::initial_points()` is set, the functor will be called after insertion of the points. * * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept * - * @param generator an instance of the InitialPointsGenerator functor + * @param generator an instance of `InitialPointsGenerator` * * \cgalHeading{Example} * @@ -477,7 +480,10 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points()` allows the user to specify a container model of `Range` that contains initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` should have elements of type `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, `int` represents the dimension of the minimal subcomplex on which the point lies, and `Index` represents the underlying subcomplex index. + * The function `parameters::initial_points()` allows the user to specify a container model of `Range` that contains + * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` should have elements of type + * `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, + * `int` represents the dimension of the minimal subcomplex on which the point lies, and `Index` represents the underlying subcomplex index. * * If this parameter is set, the domain's `construct_initial_points_object()` will not be called. * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. From a36074788f55a248761d4d61638e5a07db3e4276 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 12:31:18 +0200 Subject: [PATCH 50/99] typos --- Installation/CHANGES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index ab69a6cf614..410efd7d7a9 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -55,9 +55,9 @@ Release date: June 2024 - Removed the class templates `Gray_image_mesh_domain_3`, `Implicit_mesh_domain_3`, and `Labeled_image_mesh_domain_3` which are deprecated since CGAL-4.13. -- Added two new meshing parameters that enable mesh initialization customization : - - `initial_points_generator` : enables the user to specify a functor that generate initial points. - - `initial_points` : enable the user to specify a `Range` of initial points. +- Added two new meshing parameters that enable mesh initialization customization : + - `initial_points_generator` : enables the user to specify a functor that generates initial points. + - `initial_points` : enables the user to specify a `Range` of initial points. ### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/6.0/Manual/packages.html#PkgOrthtree) - **Breaking change**: From 4d40a050c3a7532c4155d943721f7582687be3f1 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 12:52:49 +0200 Subject: [PATCH 51/99] doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 21 +++++++++++-------- .../Mesh_3/Concepts/InitialPointsGenerator.h | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 4e400391ba1..babe7a9f9a1 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -454,36 +454,38 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points_generator()` allows the user to specify a functor that follows - * the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor will be called + * The function `parameters::initial_points_generator()` enables the user to specify a functor that follows + * the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor is called * for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * + * If the parameter `parameters::initial_points()` is used, the points it provides are inserted before any other initialization. + * * If the generator does not generate enough points, the domain's `construct_initial_points_object()` will be called. - * If the parameter `parameters::initial_points()` is set, the functor will be called after insertion of the points. * * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept * - * @param generator an instance of `InitialPointsGenerator` + * @param generator an instance of `InitialPointsGenerator` * * \cgalHeading{Example} * * \snippet mesh_3D_image_with_image_initialization.cpp Meshing * - * \sa `CGAL::parameters::initial_points()` * \sa `CGAL::make_mesh_3()` + * \sa `CGAL::parameters::initial_points()` * \sa `MeshDomain_3::Construct_initial_points` * */ template unspecified_type initial_points_generator(const InitialPointsGenerator& generator); + /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points()` allows the user to specify a container model of `Range` that contains - * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` should have elements of type + * The function `parameters::initial_points()` enables the user to specify a container model of `Range` that contains + * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` contains elements of type * `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, - * `int` represents the dimension of the minimal subcomplex on which the point lies, and `Index` represents the underlying subcomplex index. + * `int` the dimension of the minimal subcomplex on which the point lies, and `Index` the corresponding subcomplex index. * * If this parameter is set, the domain's `construct_initial_points_object()` will not be called. * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. @@ -491,7 +493,8 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \tparam MeshDomain a model of `MeshDomain_3` * \tparam C3t3 a model of `MeshComplex_3InTriangulation_3` * - * @param initial_points a `Range` that contains points of type `std::tuple` + * @param initial_points a `Range` that contains points of type + * `std::tuple` * * \cgalHeading{Example} * diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 11a47461cce..d14a7ae1f87 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -24,7 +24,7 @@ output iterator `pts`, as objects of type `std::tuple`. `Weighted_point_3` is the point's position and weight, `int` is the dimension of the minimal dimension subcomplex on which the point lies, and -`Index` is the underlying subcomplex index. +`Index` is the corresponding subcomplex index. @tparam OutputIterator model of `OutputIterator`, containing points of type `std::tuple` @@ -47,7 +47,7 @@ output iterator `pts`, as objects of type `std::tuple`. `Weighted_point_3` is the point's position and weight, `int` is the dimension of the minimal dimension subcomplex on which the point lies, and -`Index` is the underlying subcomplex index. +`Index` is the corresponding subcomplex index. Since there is no `n` given like above, the functor must provide enough points to initialize the mesh generation process. From 636fceb129bd2144837415b4919e32d52f2d7f5c Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 14:41:21 +0200 Subject: [PATCH 52/99] remove the hardly readable std::tuple and use MeshDomain::Intersection instead --- .../doc/Mesh_3/Concepts/InitialPointsGenerator.h | 14 ++++---------- .../Mesh_3/Construct_initial_points_gray_image.h | 2 +- .../Construct_initial_points_labeled_image.h | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index d14a7ae1f87..3a9776ffcbd 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -21,13 +21,10 @@ public: /*! Outputs a set of at least `n` surface points to the output iterator `pts`, as objects of type -`std::tuple`. -`Weighted_point_3` is the point's position and weight, -`int` is the dimension of the minimal dimension subcomplex on which the point lies, and -`Index` is the corresponding subcomplex index. +`MeshDomain::Intersection`. @tparam OutputIterator model of `OutputIterator`, containing points of type -`std::tuple` +`MeshDomain::Intersection` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` @param pts the output points @@ -44,15 +41,12 @@ OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3 /*! Outputs a set of surface points to the output iterator `pts`, as objects of type -`std::tuple`. -`Weighted_point_3` is the point's position and weight, -`int` is the dimension of the minimal dimension subcomplex on which the point lies, and -`Index` is the corresponding subcomplex index. +`MeshDomain::Intersection`. Since there is no `n` given like above, the functor must provide enough points to initialize the mesh generation process. @tparam OutputIterator model of `OutputIterator`, containing points of type -`std::tuple` + `MeshDomain::Intersection` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 08d0f62d806..2acf6538916 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -62,7 +62,7 @@ struct Construct_initial_points_gray_image * Using this functor guarantees to initialize each connected component. * * \tparam OutputIterator model of `OutputIterator`, collecting points of type - * `std::tuple` + * `MeshDomain::Intersection` * \tparam MeshDomain model of `MeshDomain_3` * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` * diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index e1b4c689908..d5a137d9e7e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -101,7 +101,7 @@ struct Construct_initial_points_labeled_image * This ensures that each component will be initialized. * * @tparam OutputIterator model of `OutputIterator` that contains points of type - * `std::tuple` + * `MeshDomain::Intersection` * @tparam MeshDomain model of `MeshDomain_3` * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` * @@ -118,7 +118,7 @@ struct Construct_initial_points_labeled_image * \brief Same as above, but a `TransformOperator` that transforms values of the image is used. * * @tparam OutputIterator model of `OutputIterator` that contains points of type - * `std::tuple` + * `MeshDomain::Intersection` * @tparam MeshDomain model of `MeshDomain_3` * @tparam TransformOperator functor that transforms values of the image. * It must provide the following type:
    From c55477cda3592261887e0e41327863ade0841ee0 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 12 Sep 2024 14:48:28 +0200 Subject: [PATCH 53/99] document n --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 8 ++++---- .../CGAL/Mesh_3/Construct_initial_points_gray_image.h | 3 +-- .../CGAL/Mesh_3/Construct_initial_points_labeled_image.h | 7 ++----- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 3a9776ffcbd..ff9934dd44d 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -19,7 +19,7 @@ public: /// @{ /*! -Outputs a set of at least `n` surface points to the +Outputs a set of surface points, for mesh initialization, to the output iterator `pts`, as objects of type `MeshDomain::Intersection`. @@ -27,19 +27,19 @@ output iterator `pts`, as objects of type `MeshDomain::Intersection` @tparam MeshDomain model of `MeshDomain_3` @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + @param pts the output points @param domain the input domain @param c3t3 the input complex -@param n an estimation of the number of points to output. +@param n a lower bound on the number of points to construct for initialization. A generator can choose to ignore this parameter. If it does not output enough points, then more points will be added automatically. - */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n); /*! -Outputs a set of surface points to the +Outputs a set of surface points, for mesh initialization, to the output iterator `pts`, as objects of type `MeshDomain::Intersection`. Since there is no `n` given like above, the functor must provide enough diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 2acf6538916..19ae3698780 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -56,7 +56,7 @@ struct Construct_initial_points_gray_image { } /*! - * \brief Constructs points by collecting them on the surface of all objects + * \brief Constructs at least `n` points by collecting them on the surface of all objects * in the image, * even if they are non-connected components. * Using this functor guarantees to initialize each connected component. @@ -66,7 +66,6 @@ struct Construct_initial_points_gray_image * \tparam MeshDomain model of `MeshDomain_3` * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` * - * \param n a lower bound on the number of points to be constructed */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index d5a137d9e7e..dd57a09a1c4 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -95,7 +95,8 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief Constructs points by scanning the image and + * \brief Constructs at least `n` initial points, + * by scanning the image and * collecting points in each object in the image, * even if they are non-connected components. * This ensures that each component will be initialized. @@ -104,8 +105,6 @@ struct Construct_initial_points_labeled_image * `MeshDomain::Intersection` * @tparam MeshDomain model of `MeshDomain_3` * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` - * - * @param n a lower bound on the number of constructed points */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const @@ -127,8 +126,6 @@ struct Construct_initial_points_labeled_image * `result_type operator()(Word v)` * with `Word` the type of the image values. * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` - * - * @param n a lower bound on the number of constructed points */ template OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const From ce9cd9e596ac7f811d3cba62fa73c30d47b47306 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 17 Sep 2024 18:02:36 +0200 Subject: [PATCH 54/99] wip PR https://github.com/CGAL/cgal/pull/7798 --- ...sh_3D_image_with_custom_initialization.cpp | 26 +-- .../mesh_3D_image_with_initial_points.cpp | 4 +- .../Construct_initial_points_labeled_image.h | 2 +- Mesh_3/include/CGAL/make_mesh_3.h | 172 ++++++++++------- .../internal/mesh_option_classes.h | 180 ++++++------------ 5 files changed, 168 insertions(+), 216 deletions(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 8ba0e155f2f..400b9df6be2 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -35,22 +35,23 @@ typedef CGAL::Mesh_criteria_3 Mesh_criteria; 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 is the point's position and weight, // int is the dimension of the minimal dimension subcomplex on which the point lies, // Index is the underlying subcomplex index. -struct Custom_Initial_points_generator +struct Custom_initial_points_generator { - CGAL::Image_3& image_; - Custom_Initial_points_generator(CGAL::Image_3& image) : image_(image) { } + const CGAL::Image_3& image_; - template - OutputIterator operator()(OutputIterator pts, const MeshDomain& /* domain */, const C3t3& c3t3, int /* n */ = 1) const + template + OutputIterator operator()(OutputIterator pts) const { - typedef typename C3t3::Triangulation::Geom_traits::Point_3 Point_3; - typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3; - typedef typename C3t3::Triangulation::Geom_traits::Segment_3 Segment_3; + typedef Tr::Geom_traits Gt; + typedef Gt::Point_3 Point_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 = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); @@ -64,10 +65,11 @@ struct Custom_Initial_points_generator Vector_3 vector = segment.to_vector(); double edge_size = 5; std::size_t nb = static_cast(CGAL::sqrt(segment.squared_length()) / edge_size); + const double frac = 1. / (double)nb; + for (std::size_t i = 1; i < nb; i++) { - *pts++ = std::make_tuple( - cwp(source + (i/(double)nb)*vector, edge_size*edge_size), 1, 0); + *pts++ = {cwp(source + (i * frac) * vector), 1, Index(1)); } return pts; } @@ -95,7 +97,7 @@ int main() /// [Meshing] C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(Custom_Initial_points_generator(image)) + , params::initial_points_generator(Custom_initial_points_generator{ image }) ); /// [Meshing] 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 8487875382c..7b7e0cb41ea 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 @@ -62,8 +62,8 @@ int main() // Creation of the initial_points vector std::vector initial_points = { - std::make_tuple(Weighted_point_3(Point_3(30.0, 50.0, 83.33), 30.0), 1, 0), - std::make_tuple(Weighted_point_3(Point_3(70.0, 50.0, 83.33), 50.0), 1, 0) + {Weighted_point_3(Point_3(30.0, 50.0, 83.33), 30.0), 1, Index(1)}, + {Weighted_point_3(Point_3(70.0, 50.0, 83.33), 50.0), 1, Index(1)} }; /// [Meshing] diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index dd57a09a1c4..8c8ae6e4839 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -293,7 +293,7 @@ struct Construct_initial_points_labeled_image if (pi_inside_protecting_sphere) 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 } } } diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 9eee0934265..80a47480a4d 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -38,38 +38,55 @@ namespace CGAL { namespace Mesh_3 { namespace internal { -template < typename C3T3, typename MeshDomain, typename MeshCriteria > +template < typename C3T3, typename MeshDomain, typename InitialPointsGenerator > 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 parameters::internal::Initial_points_generator_options& generator) + const InitialPointsGenerator& generator) { 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 Initialization_point; - typedef std::vector< Initialization_point > Initial_points_vector; - typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; - // Mesh initialization : get some points and add them to the mesh - Initial_points_vector initial_points; - if (nb_initial_points > -1) - generator(std::back_inserter(initial_points), domain, c3t3, - nb_initial_points); - else //use default number of points - generator(std::back_inserter(initial_points), domain, c3t3); + using Point_3 = typename Tr::Geom_traits::Point_3; + using Index = typename MeshDomain::Index; + using PointIndexPair = std::pair; + using PointDimIndex = parameters::internal::Initial_point_type; + + struct InitialPointPair2TupleConverter + { + 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 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 - for (const auto& [weighted_point_3, dimension, index] : initial_points) { - if(Th().inside_protecting_balls(triangulation, Vertex_handle(), weighted_point_3.point())) + for (const auto& [wpoint, dimension, index] : initial_points) + { + if(Th().inside_protecting_balls(c3t3.triangulation(), Vertex_handle(), wpoint.point())) 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 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 init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, - const parameters::internal::Initial_points_generator_options& generator = parameters::internal::Initial_points_generator_generator()()) + const InitializationOptions& init_generator) { - add_points_from_generator(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 // the user has not specified enough points ), add some surface points - bool need_more_init = c3t3.triangulation().dimension() != 3 || !generator.is_default(); - if(!need_more_init) { + bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_generator.is_default(); + if(!need_more_init) + { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); helper.update_restricted_facets(); @@ -106,10 +124,10 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, } } } - if(need_more_init) { - parameters::internal::Initial_points_generator_options domain_generator = - parameters::internal::Initial_points_generator_generator()(); - add_points_from_generator(c3t3, domain, nb_initial_points, domain_generator); + if(need_more_init) + { + InitializationOptions init_options(domain.construct_initial_points_object()); + add_points_from_generator(c3t3, domain, nb_initial_points, init_options); } } @@ -196,23 +214,22 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria, bool MeshDomainHasHasFeatures, - typename HasFeatures = int> + typename HasFeatures, + typename InitOptions> 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> -struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures > +template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitOptions> +struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitOptions > { 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(), - const Initial_points_generator_options& generator = Initial_points_generator_generator()()) + const InitOptions& init_options = InitOptions()) { if ( with_features ) { @@ -221,48 +238,47 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures > } 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 // Handles cases where MeshDomain::Has_features is a valid type -template < typename C3T3, typename MD, typename MC, typename HasFeatures > -struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures > +template < typename C3T3, typename MD, typename MC, typename HasFeatures, typename InitOptions> +struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitOptions> { 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(), - 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,domain,criteria,with_features,mesh_options,generator); + C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitOptions >() + (c3t3,domain,criteria,with_features,mesh_options,init_options); } }; // 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 > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > +template < typename C3T3, typename MD, typename MC, typename InitOptions > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitOptions > : 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(), - const Initial_points_generator_options& generator = Initial_points_generator_generator()()) + const InitOptions& init_options = InitOptions()) { if ( with_features ) { 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 // 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) { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); helper.update_restricted_facets(); @@ -288,29 +304,28 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true > } if(need_more_init) { 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, - mesh_options.number_of_initial_points, generator); } + mesh_options.number_of_initial_points, init_options); } } }; // 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 > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > +template < typename C3T3, typename MD, typename MC, typename InitOptions > +struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitOptions > { 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; + typedef parameters::internal::Initialization_options Initialization_options; void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, 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 ) { @@ -319,7 +334,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false > } 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::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; - using Value_type = typename Initial_points_generator_generator::Value_type; - std::vector empty_vec; - const auto& initial_points - = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); - parameters::internal::Initial_points_generator_options initial_points_generator_options_param = - Initial_points_generator_generator() - (choose_parameter(get_parameter(np, internal_np::initial_points_generator_param), - CGAL::Null_functor()), - initial_points); + // range of initial points + using Initial_point = parameters::internal::Initial_point_type; + using Initial_points_range_ref = typename internal_np::Lookup_named_param_def>::type; + std::vector empty_vec; + const Initial_points_range_ref initial_points = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); + + // initial points generator + using Initial_points_generator = typename internal_np::Lookup_named_param_def::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 + initial_points_gen_param(initial_points_generator, initial_points); 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_options_param); + initial_points_gen_param); return c3t3; } @@ -561,7 +582,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, @@ -574,25 +595,28 @@ 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(), - const parameters::internal::Initial_points_generator_options& - initial_points_generator_options = parameters::internal::Initial_points_generator_generator()()) + const parameters::internal::Initialization_options& + initialization_options = parameters::internal::Initialization_options()) { -// 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 + using Init_options = parameters::internal::Initialization_options; + // Initialize c3t3 Mesh_3::internal::C3t3_initializer< C3T3, MeshDomain, MeshCriteria, - ::CGAL::internal::has_Has_features::value > () (c3t3, + ::CGAL::internal::has_Has_features::value, + int, + Init_options>() (c3t3, domain, criteria, with_features, mesh_options, - initial_points_generator_options); + initialization_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 c2172ed5887..14b9cdebef6 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 @@ -15,6 +15,8 @@ #include #include +#include +#include namespace CGAL { @@ -169,135 +171,59 @@ private: }; // 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 -class Input_const_iterator_interface +template +struct Initial_point_type { -public: - virtual ~Input_const_iterator_interface() {} - virtual const Value& operator*() = 0; - virtual Input_const_iterator_interface* operator++() = 0; - virtual bool operator!=(const Input_const_iterator_interface* other) const = 0; - virtual Input_const_iterator_interface* clone() = 0; -}; - -// An iterator container that implements the `Input_const_iterator_interface` interface. -template -struct Input_const_iterator_container - : Input_const_iterator_interface -{ - typedef Input_const_iterator_container 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* operator++() override - { - ++it_; - return this; - } - - bool operator!=(const Input_const_iterator_interface* other) const override - { - const Self* other_casted = dynamic_cast(other); - if (other_casted == nullptr) - return true; - return it_ != other_casted->it_; - } - - Input_const_iterator_interface* clone() override - { - return new Input_const_iterator_container(it_); - } - -private: - Iterator it_; + typename C3t3::Triangulation::Point m_point; + int m_dimension; + typename MeshDomain::Index m_index; }; // Holds the two parameters `initial_points_generator` and `initial_points`, // without knowing their types, into a single generator. -template -struct Initial_points_generator_options +template > > +struct Initialization_options { - typedef typename C3t3::Triangulation::Geom_traits::Weighted_point_3 Weighted_point_3; - typedef typename MeshDomain::Index Index; - typedef typename std::tuple Value_type; - typedef typename std::back_insert_iterator> OutputIterator; + using DefaultGenerator = typename MeshDomain::Construct_initial_points; + using Initial_points_const_iterator = typename InitialPointsRange::const_iterator; + using Initial_point = typename std::iterator_traits::value_type; - template - Initial_points_generator_options(const Initial_points_generator& generator, const Initial_points& initial_points, bool is_default = false) - : 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(initial_points.cbegin()); - end_it = new Input_const_iterator_container(initial_points.cend()); - } - } + Initialization_options() + : is_default_(true) + {} - ~Initial_points_generator_options() - { - if (begin_it != nullptr) - delete begin_it; - if (end_it != nullptr) - delete end_it; - } + Initialization_options(const InitialPointsGenerator& generator, + const InitialPointsRange& initial_points = InitialPointsRange()) + : initial_points_generator_(generator) + , begin_it(initial_points.begin()) + , end_it(initial_points.end()) + , is_default_(boost::is_same::value + && std::empty(initial_points)) + {} - // Firstly, the `initial_points` are inserted, then, the `initial_points_generator` is called. - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) const + template + OutputIterator operator()(OutputIterator pts, int n = 0) const { - add_initial_points(pts); - return initial_points_generator_no_number_of_points_(pts, domain, c3t3); - } + // add initial_points + 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 - { - 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* it_ptr = begin_it->clone(); - Input_const_iterator_interface& it = *(it_ptr); - for (; it != end_it; ++it) - *pts++ = *it; - delete it_ptr; - } - return pts; + return initial_points_generator_(pts, n); } bool is_default() const { return is_default_; } private: - // The two functions holds the `initial_points_generator` functor - const std::function initial_points_generator_no_number_of_points_; - const std::function initial_points_generator_; - // The two iterators holds the `initial_points` container - Input_const_iterator_interface* begin_it; - Input_const_iterator_interface* end_it; + InitialPointsGenerator initial_points_generator_; + + // The two iterators point to the `initial_points` container + Initial_points_const_iterator begin_it; + Initial_points_const_iterator end_it; + // Is the option a default-constructed one ? const bool is_default_; }; @@ -345,14 +271,14 @@ struct Domain_features_generator< MeshDomain, true > }; // 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. template struct Initial_points_generator_generator { - typedef typename CGAL::parameters::internal::Initial_points_generator_options Initial_points_generator_options; - typedef typename Initial_points_generator_options::Value_type Value_type; - typedef typename Initial_points_generator_options::OutputIterator OutputIterator; + typedef typename CGAL::parameters::internal::Initialization_options Initialization_options; + typedef typename Initialization_options::Value_type Value_type; + typedef typename Initialization_options::OutputIterator OutputIterator; struct Initial_points_generator_domain_traductor { @@ -392,31 +318,31 @@ struct Initial_points_generator_generator // With a custom InitialPointsGenerator template - 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 - Initial_points_generator_options operator()(const InitialPointsGenerator& initial_points_generator) + Initialization_options operator()(const InitialPointsGenerator& initial_points_generator) { - std::vector empty_input_features; - return operator()(initial_points_generator, empty_input_features); + std::vector empty_input_points; + return operator()(initial_points_generator, empty_input_points); } // Without a custom InitialPointsGenerator template - 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 - if (input_features.size() == 0) { - return Initial_points_generator_options(Initial_points_generator_domain_traductor(), input_features, true); + // The domain's construct_initial_points_object is called only if input_points is empty + if (input_points.empty()) { + 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 - Initial_points_generator_options operator()() + Initialization_options operator()() { return operator()(Null_functor()); } From 026850cf974c484baa9f3c2a52fc3d50b591d3d9 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Sep 2024 12:24:18 +0200 Subject: [PATCH 55/99] use initial points vector --- Mesh_3/include/CGAL/make_mesh_3.h | 58 +++++++++---------- .../internal/mesh_option_classes.h | 4 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 80a47480a4d..692ab54d32e 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -27,6 +27,7 @@ #include #include +#include #include @@ -49,29 +50,24 @@ add_points_from_generator(C3T3& c3t3, typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; - using Point_3 = typename Tr::Geom_traits::Point_3; - using Index = typename MeshDomain::Index; - using PointIndexPair = std::pair; using PointDimIndex = parameters::internal::Initial_point_type; - struct InitialPointPair2TupleConverter - { - 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 }; - } - }; + const auto& cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); std::vector initial_points; - InitialPointPair2TupleConverter pair2tuple; auto push_initial_point = [&](const auto& initial_pt)->void { - initial_points.push_back(pair2tuple(initial_pt)); + using T = std::remove_cv_t < std::remove_reference_t>; + if constexpr (std::tuple_size_v == 3) + { + const auto& [wp, d, i] = initial_pt; + initial_points.push_back(PointDimIndex{ wp, d, i }); + } + else + { + const auto& [p, i] = initial_pt; + initial_points.push_back(PointDimIndex{ cwp(p), 2, i }); + } }; if (nb_initial_points > 0) @@ -101,13 +97,13 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename I void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, - const InitializationOptions& init_generator) + const InitializationOptions& init_options) { - add_points_from_generator(c3t3, domain, nb_initial_points, init_generator); + add_points_from_generator(c3t3, domain, nb_initial_points, init_options.generator()); // If c3t3 initialization is not sufficient (may happen if // the user has not specified enough points ), add some surface points - bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_generator.is_default(); + bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_options.is_default(); if(!need_more_init) { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); @@ -126,8 +122,8 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, } if(need_more_init) { - InitializationOptions init_options(domain.construct_initial_points_object()); - add_points_from_generator(c3t3, domain, nb_initial_points, init_options); + add_points_from_generator(c3t3, domain, nb_initial_points, + domain.construct_initial_points_object()); } } @@ -536,17 +532,19 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C using Initial_point = parameters::internal::Initial_point_type; using Initial_points_range_ref = typename internal_np::Lookup_named_param_def>::type; + std::vector>::reference; + using Initial_points_range = std::remove_cv_t>; std::vector empty_vec; - const Initial_points_range_ref initial_points = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); + Initial_points_range initial_points = choose_parameter(get_parameter_reference(np, internal_np::initial_points_param), empty_vec); // initial points generator using Initial_points_generator = typename internal_np::Lookup_named_param_def::reference; + auto default_generator = domain.construct_initial_points_object(); 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 + default_generator); + const parameters::internal::Initialization_options initial_points_gen_param(initial_points_generator, initial_points); make_mesh_3_impl(c3t3, domain, criteria, @@ -582,7 +580,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, @@ -595,14 +593,14 @@ 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(), - const parameters::internal::Initialization_options& - initialization_options = parameters::internal::Initialization_options()) + const parameters::internal::Initialization_options& + initialization_options = parameters::internal::Initialization_options()) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); #endif - using Init_options = parameters::internal::Initialization_options; + using Init_options = parameters::internal::Initialization_options; // Initialize c3t3 Mesh_3::internal::C3t3_initializer< 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 14b9cdebef6..6df410a1f4b 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 @@ -175,7 +175,7 @@ private: template struct Initial_point_type { - typename C3t3::Triangulation::Point m_point; + typename C3t3::Triangulation::Point m_weighted_point; int m_dimension; typename MeshDomain::Index m_index; }; @@ -215,6 +215,8 @@ struct Initialization_options return initial_points_generator_(pts, n); } + InitialPointsGenerator generator() const { return initial_points_generator_; } + bool is_default() const { return is_default_; } private: From b5740393b2cae82c50797a87562c606d8043aebb Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 20 Sep 2024 13:58:24 +0200 Subject: [PATCH 56/99] compilation of examples fixed --- ...sh_3D_image_with_custom_initialization.cpp | 9 ++- ...esh_3D_image_with_image_initialization.cpp | 5 +- .../Construct_initial_points_labeled_image.h | 65 ++++++++++++------- Mesh_3/include/CGAL/make_mesh_3.h | 11 ++-- .../internal/parameters_interface.h | 1 + 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 400b9df6be2..600fa805b6a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -40,12 +40,13 @@ namespace params = CGAL::parameters; // Weighted_point_3 is the point's position and weight, // int is the dimension of the minimal dimension subcomplex on which the point lies, // Index is the underlying subcomplex index. + struct Custom_initial_points_generator { const CGAL::Image_3& image_; template - OutputIterator operator()(OutputIterator pts) const + OutputIterator operator()(OutputIterator pts, int n = 20) const { typedef Tr::Geom_traits Gt; typedef Gt::Point_3 Point_3; @@ -53,14 +54,12 @@ struct Custom_initial_points_generator typedef Gt::Segment_3 Segment_3; typedef Mesh_domain::Index Index; - typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = - c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); + Gt::Construct_weighted_point_3 cwp = Gt().construct_weighted_point_3_object(); // Add points along the segment Segment_3 segment(Point_3( 0.0, 50.0, 66.66), Point_3(100.0, 50.0, 66.66)); - Point_3 source = segment.source(); Vector_3 vector = segment.to_vector(); double edge_size = 5; @@ -69,7 +68,7 @@ struct Custom_initial_points_generator for (std::size_t i = 1; i < nb; i++) { - *pts++ = {cwp(source + (i * frac) * vector), 1, Index(1)); + *pts++ = std::make_tuple( cwp(source + (i * frac) * vector), 1, Index(1) ); } return pts; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index 952df762d38..c08d245bf76 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -49,8 +49,9 @@ int main() /// [Meshing] // Mesh generation with a custom initialization that places points in each of the image components. - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(CGAL::Construct_initial_points_labeled_image(image)) + CGAL::Construct_initial_points_labeled_image img_pts_generator(image, domain); + + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, params::initial_points_generator(img_pts_generator) ); /// [Meshing] diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 8c8ae6e4839..024f2cc878f 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -82,16 +82,23 @@ struct Get_point * this functor scans the complete image and * outputs points to initialize each component. * + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * @tparam MeshDomain model of `MeshDomain_3` + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_gray_image` */ +template struct Construct_initial_points_labeled_image { - const CGAL::Image_3 & image; + const CGAL::Image_3& image_; + const MeshDomain& domain_; - Construct_initial_points_labeled_image(const CGAL::Image_3 & image_) - : image(image_) + Construct_initial_points_labeled_image(const CGAL::Image_3& image, + const MeshDomain& domain) + : image_(image) + , domain_(domain) { } /*! @@ -102,14 +109,12 @@ struct Construct_initial_points_labeled_image * This ensures that each component will be initialized. * * @tparam OutputIterator model of `OutputIterator` that contains points of type - * `MeshDomain::Intersection` - * @tparam MeshDomain model of `MeshDomain_3` - * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * @todo describe type */ - template - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const + template + OutputIterator operator()(OutputIterator pts, int n = 20) const { - CGAL_IMAGE_IO_CASE(image.image(), operator()(pts, domain, CGAL::Identity(), c3t3, n)); + CGAL_IMAGE_IO_CASE(image_.image(), operator()(pts, CGAL::Identity(), n)); return pts; } @@ -127,8 +132,8 @@ struct Construct_initial_points_labeled_image * with `Word` the type of the image values. * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` */ - template - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, TransformOperator transform, const C3t3& c3t3, int n = 20) const + template + OutputIterator operator()(OutputIterator pts, TransformOperator transform, int n = 20) const { typedef typename MeshDomain::Subdomain Subdomain; typedef typename MeshDomain::Point_3 Point_3; @@ -143,7 +148,8 @@ struct Construct_initial_points_labeled_image typedef typename Tr::Cell_handle Cell_handle; typedef typename GT::Vector_3 Vector_3; - const Tr& tr = c3t3.triangulation(); + C3t3 c3t3; + Tr& tr = c3t3.triangulation(); typename GT::Compare_weighted_squared_radius_3 cwsr = tr.geom_traits().compare_weighted_squared_radius_3_object(); @@ -152,9 +158,9 @@ struct Construct_initial_points_labeled_image typename GT::Construct_weighted_point_3 cwp = tr.geom_traits().construct_weighted_point_3_object(); - const double max_v = (std::max)((std::max)(image.vx(), - image.vy()), - image.vz()); + const double max_v = (std::max)((std::max)(image_.vx(), + image_.vy()), + image_.vz()); struct Seed { std::size_t i, j, k; @@ -163,9 +169,9 @@ struct Construct_initial_points_labeled_image using Seeds = std::vector; Seeds seeds; - Mesh_3::internal::Get_point get_point(&image); + Mesh_3::internal::Get_point get_point(&image_); std::cout << "Searching for connected components..." << std::endl; - CGAL_IMAGE_IO_CASE(image.image(), search_for_connected_components_in_labeled_image(image, + CGAL_IMAGE_IO_CASE(image_.image(), search_for_connected_components_in_labeled_image(image_, std::back_inserter(seeds), CGAL::Emptyset_iterator(), transform, @@ -178,13 +184,13 @@ struct Construct_initial_points_labeled_image Cell_handle seed_cell = tr.locate(cwp(seed_point)); const Subdomain seed_label - = domain.is_in_domain_object()(seed_point); + = domain_.is_in_domain_object()(seed_point); const Subdomain seed_cell_label = ( tr.dimension() < 3 || seed_cell == Cell_handle() || tr.is_infinite(seed_cell)) ? Subdomain() //seed_point is OUTSIDE_AFFINE_HULL - : domain.is_in_domain_object()( + : domain_.is_in_domain_object()( seed_cell->weighted_circumcenter(tr.geom_traits())); if ( seed_label != std::nullopt @@ -196,7 +202,7 @@ struct Construct_initial_points_labeled_image CGAL::Random_points_on_sphere_3 points_on_sphere_3(radius); // [construct intersection] typename MeshDomain::Construct_intersection construct_intersection = - domain.construct_intersection_object(); + domain_.construct_intersection_object(); // [construct intersection] std::vector directions; @@ -219,7 +225,7 @@ struct Construct_initial_points_labeled_image for(const Vector_3& v : directions) { const Point_3 test = seed_point + v; - const Segment_3 test_segment = Segment_3(seed_point, test); + const Segment_3 test_segment(seed_point, test); // [use construct intersection] const typename MeshDomain::Intersection intersect = @@ -231,7 +237,7 @@ struct Construct_initial_points_labeled_image const Point_3& intersect_point = std::get<0>(intersect); const Index& intersect_index = std::get<1>(intersect); // [get construct intersection] - Weighted_point pi = Weighted_point(intersect_point); + Weighted_point pi(intersect_point); // This would cause trouble to optimizers // check pi will not be hidden @@ -293,7 +299,20 @@ struct Construct_initial_points_labeled_image if (pi_inside_protecting_sphere) continue; - *pts++ = {cwp(intersect_point), 2, intersect_index}; // dimension 2 by construction, points are on surface + // insert point in temporary triangulation + + /// The following lines show how to insert initial points in the + /// `c3t3` object. [insert initial points] + Vertex_handle v = tr.insert(pi); + + // `v` could be null if `pi` is hidden by other vertices of `tr`. + CGAL_assertion(v != Vertex_handle()); + + c3t3.set_dimension(v, 2); // by construction, points are on surface + c3t3.set_index(v, intersect_index); + /// [insert initial points] + + *pts++ = std::make_pair(pi, intersect_index); // dimension 2 by construction, points are on surface } } } diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 692ab54d32e..438f5a01328 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -60,13 +60,13 @@ add_points_from_generator(C3T3& c3t3, using T = std::remove_cv_t < std::remove_reference_t>; if constexpr (std::tuple_size_v == 3) { - const auto& [wp, d, i] = initial_pt; - initial_points.push_back(PointDimIndex{ wp, d, i }); + const auto& [weighted_pt, dim, index] = initial_pt; + initial_points.push_back(PointDimIndex{ weighted_pt, dim, index }); } else { - const auto& [p, i] = initial_pt; - initial_points.push_back(PointDimIndex{ cwp(p), 2, i }); + const auto& [pt, index] = initial_pt; + initial_points.push_back(PointDimIndex{ cwp(pt), 2, index }); } }; @@ -519,7 +519,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C using parameters::choose_parameter; using parameters::get_parameter; using parameters::get_parameter_reference; - C3T3 c3t3; + parameters::internal::Exude_options exude_param = choose_parameter(get_parameter(np, internal_np::exude_options_param), parameters::exude().v); parameters::internal::Perturb_options perturb_param = choose_parameter(get_parameter(np, internal_np::perturb_options_param), parameters::perturb().v); parameters::internal::Odt_options odt_param = choose_parameter(get_parameter(np, internal_np::odt_options_param), parameters::no_odt().v); @@ -547,6 +547,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C const parameters::internal::Initialization_options initial_points_gen_param(initial_points_generator, initial_points); + C3T3 c3t3; make_mesh_3_impl(c3t3, domain, criteria, exude_param, perturb_param, odt_param, lloyd_param, features_param.features(), mesh_options_param, 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 f24867aa76d..82e1778a9f0 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -339,6 +339,7 @@ CGAL_add_named_parameter_with_compatibility(manifold_param_t, manifold_param, ma 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_param_t,initial_points_param,initial_points) +CGAL_add_named_parameter_with_compatibility(c3t3_initializer_param_t, c3t3_initializer_param, c3t3_initializer) 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) From 39254bb7dbcde5e65d190aebfc67f701c74950b8 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 20 Sep 2024 17:17:41 +0200 Subject: [PATCH 57/99] introduce Dummy_initial_points_generator fix compilation of Mesh_3 tests and examples --- Mesh_3/include/CGAL/make_mesh_3.h | 57 +++++++++++-------- .../internal/mesh_option_classes.h | 29 ++++++---- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 438f5a01328..4cc6827311e 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -50,7 +50,7 @@ add_points_from_generator(C3T3& c3t3, typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; - using PointDimIndex = parameters::internal::Initial_point_type; + using PointDimIndex = parameters::internal::Initial_point_type; const auto& cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); @@ -210,22 +210,24 @@ template < typename C3T3, typename MeshDomain, typename MeshCriteria, bool MeshDomainHasHasFeatures, - typename HasFeatures, - typename InitOptions> -struct C3t3_initializer { }; + 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 InitOptions> -struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitOptions > +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::Initialization_options Default_init_options; + + template void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - const InitOptions& init_options = InitOptions()) + const InitOptions& init_options = Default_init_options()) { if ( with_features ) { @@ -241,19 +243,21 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures, InitOptions > // 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 InitOptions> -struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitOptions> +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::Initialization_options Default_init_options; + template void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - const InitOptions& init_options = InitOptions()) + const InitOptions& init_options = Default_init_options()) { - C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features, InitOptions >() + C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features >() (c3t3,domain,criteria,with_features,mesh_options,init_options); } }; @@ -261,20 +265,22 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures, InitOptions> // 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 InitOptions > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitOptions > +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::Initialization_options Default_init_options; + template void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - const InitOptions& init_options = InitOptions()) + const InitOptions& init_options = Default_init_options()) { if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); @@ -311,17 +317,19 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true, InitOptions > // 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 InitOptions > -struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false, InitOptions > +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::Initialization_options Initialization_options; + typedef parameters::internal::Initialization_options Default_init_options; + + template void operator()(C3T3& c3t3, const MD& domain, const MC& criteria, bool with_features, Mesh_3_options mesh_options = Mesh_3_options(), - const Initialization_options& init_options = Initialization_options()) + const InitOptions& init_options = Default_init_options()) { if ( with_features ) { @@ -609,13 +617,12 @@ void make_mesh_3_impl(C3T3& c3t3, MeshDomain, MeshCriteria, ::CGAL::internal::has_Has_features::value, - int, - Init_options>() (c3t3, - domain, - criteria, - with_features, - mesh_options, - initialization_options); + int>()(c3t3, + domain, + criteria, + with_features, + mesh_options, + initialization_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 6df410a1f4b..180dd59b5f6 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 @@ -17,6 +17,7 @@ #include #include #include +#include namespace CGAL { @@ -180,20 +181,26 @@ struct Initial_point_type typename MeshDomain::Index m_index; }; +struct Dummy_initial_points_generator +{ + template + OutputIterator operator()(OutputIterator oit, int n = 0) const { return oit; } +}; + // Holds the two parameters `initial_points_generator` and `initial_points`, // without knowing their types, into a single generator. template > > struct Initialization_options { - using DefaultGenerator = typename MeshDomain::Construct_initial_points; + using DefaultGenerator = Dummy_initial_points_generator; using Initial_points_const_iterator = typename InitialPointsRange::const_iterator; using Initial_point = typename std::iterator_traits::value_type; + Initialization_options() - : is_default_(true) {} Initialization_options(const InitialPointsGenerator& generator, @@ -201,8 +208,6 @@ struct Initialization_options : initial_points_generator_(generator) , begin_it(initial_points.begin()) , end_it(initial_points.end()) - , is_default_(boost::is_same::value - && std::empty(initial_points)) {} template @@ -215,9 +220,16 @@ struct Initialization_options return initial_points_generator_(pts, n); } - InitialPointsGenerator generator() const { return initial_points_generator_; } + const InitialPointsGenerator& generator() const + { + return initial_points_generator_; + } - bool is_default() const { return is_default_; } + bool is_default() const + { + return begin_it == end_it + && std::is_same_v; + } private: InitialPointsGenerator initial_points_generator_; @@ -225,9 +237,6 @@ private: // The two iterators point to the `initial_points` container Initial_points_const_iterator begin_it; Initial_points_const_iterator end_it; - - // Is the option a default-constructed one ? - const bool is_default_; }; // ----------------------------------- From b3a8530dcf2b1cff7799ee332e2b3c974f7e32ca Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 24 Sep 2024 11:05:41 +0200 Subject: [PATCH 58/99] use new API with named paremeter initial_points_generator in demo and fix compilation issues --- Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h | 13 +++--- .../Construct_initial_points_gray_image.h | 19 +++++---- Mesh_3/include/CGAL/make_mesh_3.h | 29 +++++++++---- .../internal/mesh_option_classes.h | 41 +++++++++---------- 4 files changed, 60 insertions(+), 42 deletions(-) diff --git a/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h b/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h index cf2ffaf9caa..99552b05b7f 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h +++ b/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h @@ -257,9 +257,7 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Labeled_image_domain_tag) p_.protect_features, p::mesh_3_options(p::pointer_to_stop_atomic_boolean = &stop_, p::nonlinear_growth_of_balls = true).v, - p::internal::Initial_points_generator_generator() - (p::initial_points_generator( - CGAL::Construct_initial_points_labeled_image(*p_.image_3_ptr)).v)); + CGAL::Construct_initial_points_labeled_image(*p_.image_3_ptr, *domain_)); } else { @@ -278,6 +276,11 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Gray_image_domain_tag) // features, or with the initial points (or both). if (p_.detect_connected_components) { + CGAL::Construct_initial_points_gray_image generator + (*p_.image_3_ptr, + *domain_, + p_.iso_value, + Compare_to_isovalue(p_.iso_value, p_.inside_is_less)); CGAL::Mesh_3::internal::C3t3_initializer< C3t3, Domain, @@ -289,9 +292,7 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Gray_image_domain_tag) p_.protect_features, p::mesh_3_options(p::pointer_to_stop_atomic_boolean = &stop_, p::nonlinear_growth_of_balls = true).v, - p::internal::Initial_points_generator_generator() - (p::initial_points_generator( - CGAL::Construct_initial_points_gray_image(*p_.image_3_ptr, p_.iso_value, Compare_to_isovalue(p_.iso_value, p_.inside_is_less))).v)); + generator); } else { diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 19ae3698780..9264d44d844 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -39,19 +39,21 @@ namespace CGAL * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_labeled_image` */ -template +template struct Construct_initial_points_gray_image { const CGAL::Image_3 & image_; - const double iso_value_; + const MeshDomain& domain_; + const typename MeshDomain::R::FT iso_value_; Functor image_values_to_subdomain_indices_; - template Construct_initial_points_gray_image(const CGAL::Image_3 & image, - const FT& iso_value, + const MeshDomain& domain, + const double iso_value, const Functor image_values_to_subdomain_indices = CGAL::Null_functor()) : image_(image) - , iso_value_(iso_value) + , domain_(domain) + , iso_value_(static_cast(iso_value)) , image_values_to_subdomain_indices_(image_values_to_subdomain_indices) { } @@ -67,15 +69,16 @@ struct Construct_initial_points_gray_image * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` * */ - template - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n = 20) const + template + OutputIterator operator()(OutputIterator pts, int n = 20) const { using CGAL::Mesh_3::internal::Create_gray_image_values_to_subdomain_indices; typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; Image_values_to_subdomain_indices transform_fct = C_i_v_t_s_i()(image_values_to_subdomain_indices_, iso_value_); - Construct_initial_points_labeled_image(image_).operator()(pts, domain, transform_fct, c3t3, n); + Construct_initial_points_labeled_image init_pts{ image_, domain_ }; + init_pts(pts, transform_fct, n); return pts; } }; diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 4cc6827311e..6e38a36bc7b 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -50,7 +50,12 @@ add_points_from_generator(C3T3& c3t3, typedef typename C3T3::Vertex_handle Vertex_handle; typedef CGAL::Mesh_3::Triangulation_helpers Th; - using PointDimIndex = parameters::internal::Initial_point_type; + struct PointDimIndex + { + typename Tr::Point m_wpt; + int m_dim; + typename MeshDomain::Index m_index; + }; const auto& cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); @@ -99,11 +104,18 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, const InitializationOptions& init_options) { - add_points_from_generator(c3t3, domain, nb_initial_points, init_options.generator()); + add_points_from_generator(c3t3, domain, nb_initial_points, init_options); + + typedef CGAL::parameters::internal::Initialization_options Default_init_options; + bool is_default_init = false; + if constexpr (std::is_same_v) + { + is_default_init = init_options.is_default(); + } // If c3t3 initialization is not sufficient (may happen if // the user has not specified enough points ), add some surface points - bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_options.is_default(); + bool need_more_init = c3t3.triangulation().dimension() != 3 || !is_default_init; if(!need_more_init) { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); @@ -287,8 +299,13 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true> // If c3t3 initialization is not sufficient (may happen if there is only // a planar curve as feature for example), add some surface points + bool is_default_init = false; + if constexpr (std::is_same_v) + { + is_default_init = init_options.is_default(); + } - bool need_more_init = c3t3.triangulation().dimension() != 3 || !init_options.is_default(); + bool need_more_init = c3t3.triangulation().dimension() != 3 || !is_default_init; if(!need_more_init) { CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); helper.update_restricted_facets(); @@ -537,7 +554,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C parameters::internal::Manifold_options manifold_options_param = choose_parameter(get_parameter(np, internal_np::manifold_param), parameters::internal::Manifold_options()); // range of initial points - using Initial_point = parameters::internal::Initial_point_type; + using Initial_point = std::pair; using Initial_points_range_ref = typename internal_np::Lookup_named_param_def>::reference; @@ -609,8 +626,6 @@ void make_mesh_3_impl(C3T3& c3t3, CGAL::get_default_random() = CGAL::Random(0); #endif - using Init_options = parameters::internal::Initialization_options; - // Initialize c3t3 Mesh_3::internal::C3t3_initializer< C3T3, 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 180dd59b5f6..8505194049c 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 @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -172,15 +173,6 @@ private: }; // Mesh initialization - -template -struct Initial_point_type -{ - typename C3t3::Triangulation::Point m_weighted_point; - int m_dimension; - typename MeshDomain::Index m_index; -}; - struct Dummy_initial_points_generator { template @@ -191,20 +183,27 @@ struct Dummy_initial_points_generator // without knowing their types, into a single generator. template > > + typename InitialPointsGenerator = CGAL::Default, + typename InitialPointsRange = CGAL::Default +> struct Initialization_options { - using DefaultGenerator = Dummy_initial_points_generator; - using Initial_points_const_iterator = typename InitialPointsRange::const_iterator; - using Initial_point = typename std::iterator_traits::value_type; + using Default_generator = Dummy_initial_points_generator; + using Initial_points_generator + = typename CGAL::Default::Get::type; + using Default_initial_point_type + = std::tuple; + using Initial_points_range + = typename CGAL::Default::Get>::type; + using Initial_points_const_iterator = typename Initial_points_range::const_iterator; + using Initial_point = typename std::iterator_traits::value_type; Initialization_options() {} - Initialization_options(const InitialPointsGenerator& generator, - const InitialPointsRange& initial_points = InitialPointsRange()) + Initialization_options(const Initial_points_generator& generator, + const Initial_points_range& initial_points = Initial_points_range()) : initial_points_generator_(generator) , begin_it(initial_points.begin()) , end_it(initial_points.end()) @@ -214,13 +213,13 @@ struct Initialization_options OutputIterator operator()(OutputIterator pts, int n = 0) const { // add initial_points - for (typename InitialPointsRange::const_iterator it = begin_it; it != end_it; ++it) + for (Initial_points_const_iterator it = begin_it; it != end_it; ++it) *pts++ = *it; return initial_points_generator_(pts, n); } - const InitialPointsGenerator& generator() const + const Initial_points_generator& generator() const { return initial_points_generator_; } @@ -228,11 +227,11 @@ struct Initialization_options bool is_default() const { return begin_it == end_it - && std::is_same_v; + && std::is_same_v; } private: - InitialPointsGenerator initial_points_generator_; + Initial_points_generator initial_points_generator_; // The two iterators point to the `initial_points` container Initial_points_const_iterator begin_it; @@ -349,7 +348,7 @@ struct Initial_points_generator_generator if (input_points.empty()) { return Initialization_options(Initial_points_generator_domain_traductor(), input_points, true); } - return Initialization_options(Initial_points_generator_empty(), input_features, true); + return Initialization_options(Initial_points_generator_empty(), input_points, true); } // Default construction From 490a6ad5894b015c75bee95816be97f35f185187 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 24 Sep 2024 12:22:32 +0200 Subject: [PATCH 59/99] update doc --- .../Mesh_3/Concepts/InitialPointsGenerator.h | 54 +++++++++++-------- Mesh_3/include/CGAL/make_mesh_3.h | 6 +-- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index ff9934dd44d..7d5f54eb107 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -15,46 +15,54 @@ a set of initial points on the surface of the domain. class InitialPointsGenerator { public: +/// \name Types +/// @{ + +/*! +* Mesh domain type to be meshed, model of `MeshDomain_3` +*/ +typedef unspecified_type MeshDomain; + +/*! + * Type of the output mesh complex, model of `MeshComplex_3InTriangulation_3` + */ +typedef unspecified_type C3t3; +/// @} + /// \name Operations /// @{ /*! Outputs a set of surface points, for mesh initialization, to the -output iterator `pts`, as objects of type -`MeshDomain::Intersection`. +output iterator `pts`. -@tparam OutputIterator model of `OutputIterator`, containing points of type -`MeshDomain::Intersection` -@tparam MeshDomain model of `MeshDomain_3` -@tparam C3t3 model of `MeshComplex_3InTriangulation_3` +@tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : + - a `C3t3::Triangulation::Point` : the point `p`, + - a `int` : the minimal dimension of the subcomplexes on which `p` lies, + - a `MeshDomain_3::Index` : the index of the corresponding subcomplex. @param pts the output points -@param domain the input domain -@param c3t3 the input complex @param n a lower bound on the number of points to construct for initialization. A generator can choose to ignore this parameter. -If it does not output enough points, then more points will be added automatically. +If this operator does not output enough points, then more points will be added automatically +by the mesher. */ -template -OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n); +template +OutputIterator operator()(OutputIterator pts, int n); /*! -Outputs a set of surface points, for mesh initialization, to the -output iterator `pts`, as objects of type -`MeshDomain::Intersection`. +Same as above, without the `n` parameter. Since there is no `n` given like above, the functor must provide enough points to initialize the mesh generation process. -@tparam OutputIterator model of `OutputIterator`, containing points of type - `MeshDomain::Intersection` -@tparam MeshDomain model of `MeshDomain_3` -@tparam C3t3 model of `MeshComplex_3InTriangulation_3` - +@tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : + - a `C3t3::Triangulation::Point` : the point `p`, + - a `int` : the minimal dimension of the subcomplexes to which `p` belongs, + - a `MeshDomain_3::Index` : the index of the corresponding subcomplex. */ -template -OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3); - +template +OutputIterator operator()(OutputIterator pts); /// @} -}; /* end MeshEdgeCriteria_3 */ +}; /* end InitialPointsGenerator */ diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 6e38a36bc7b..3ca6e664809 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -499,13 +499,13 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false> * \cgalParamExtra{If the parameter `parameters::initial_points()` is set, * the functor will be called after insertion of the points.} * \cgalParamSectionBegin{Mesh initialization with points} - * \cgalParamDescription{a `std::vector` of initial points, represented as - * `std::vector>` can optionally + * \cgalParamDescription{a `Range` of initial points, represented as + * tuple-like objects made of `tuple-like` can optionally * be provided to start the meshing process. * `Weighted_point_3` is the point's position and weight, * `int` is the dimension of the minimal dimension subcomplex on which * the point lies, and - * `Index` is the underlying subcomplex index. + * `Index` is the corresponding subcomplex index. * The following named parameter controls this option: *
      *
    • `parameters::initial_points()` From f4e2b3db695482ece5ca914162987c110275dbd9 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 26 Sep 2024 11:02:34 +0200 Subject: [PATCH 60/99] remove useless generator() accessor --- .../CGAL/STL_Extension/internal/mesh_option_classes.h | 5 ----- 1 file changed, 5 deletions(-) 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 8505194049c..7b9fe4b2485 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 @@ -219,11 +219,6 @@ struct Initialization_options return initial_points_generator_(pts, n); } - const Initial_points_generator& generator() const - { - return initial_points_generator_; - } - bool is_default() const { return begin_it == end_it From 8d6e7f2fb489367a5c2f7e5124fd6f3d8d1c36ae Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 26 Sep 2024 11:36:17 +0200 Subject: [PATCH 61/99] doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index babe7a9f9a1..bdbe61bcfce 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -487,6 +487,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, * `int` the dimension of the minimal subcomplex on which the point lies, and `Index` the corresponding subcomplex index. * + * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. * If this parameter is set, the domain's `construct_initial_points_object()` will not be called. * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. * From f3b5333b69f11fdfec2d075973a3502024177556 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 26 Sep 2024 11:51:45 +0200 Subject: [PATCH 62/99] doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index bdbe61bcfce..4b6e03b5e59 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -483,19 +483,21 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \ingroup PkgMesh3Parameters * * The function `parameters::initial_points()` enables the user to specify a container model of `Range` that contains - * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` contains elements of type - * `std::tuple`, where `Weighted_point_3` represents the position and weight of the point, - * `int` the dimension of the minimal subcomplex on which the point lies, and `Index` the corresponding subcomplex index. + * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` contains + * tuple-like objects containing a `Weighted_point_3`, an `int`, and an `Index`, + * where `Weighted_point_3` represents the position and weight of the point, + * `int` the dimension of the minimal subcomplex on which the point lies, + * and `Index` the corresponding subcomplex index. * * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. - * If this parameter is set, the domain's `construct_initial_points_object()` will not be called. - * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. + * If the insertion of initial points, together with the input generator, do not generate enough points, + * the domain's `construct_initial_points_object()` will be called. * * \tparam MeshDomain a model of `MeshDomain_3` * \tparam C3t3 a model of `MeshComplex_3InTriangulation_3` * - * @param initial_points a `Range` that contains points of type - * `std::tuple` + * @param initial_points a `Range` that contains points of tuple-like objects of + * `C3t3::Triangulation::Geom_traits::Weighted_point_3, int, MeshDomain::Index`. * * \cgalHeading{Example} * From 88457ee5b38b6af8c50b837fcb08498d88a477e0 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 11:10:14 +0200 Subject: [PATCH 63/99] make initialization logic consistent and fix doc accordingly 1. protect features 2. insert initial_points() range 3. use initial_points_generator(), if provided 4. use domain.construct_initial_points_object(), if initialization not complete --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 19 +++- .../Mesh_3/Concepts/InitialPointsGenerator.h | 14 ++- Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- .../Construct_initial_points_gray_image.h | 7 +- .../Construct_initial_points_labeled_image.h | 14 ++- Mesh_3/include/CGAL/make_mesh_3.h | 98 +++++++++---------- 6 files changed, 91 insertions(+), 63 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 4b6e03b5e59..58934b9fe54 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -461,7 +461,11 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * * If the parameter `parameters::initial_points()` is used, the points it provides are inserted before any other initialization. * - * If the generator does not generate enough points, the domain's `construct_initial_points_object()` will be called. + * Initialization is considered to be complete if the triangulation is a 3D triangulation + * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the + * input surface). + * If the generator does not generate enough points for the initialization to be complete, + * the domain's `construct_initial_points_object()` will be called to generate enough input points. * * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept * @@ -489,8 +493,15 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * `int` the dimension of the minimal subcomplex on which the point lies, * and `Index` the corresponding subcomplex index. * - * If the parameter `parameters::initial_points_generator()` is set, the points will be inserted before calling the functor. - * If the insertion of initial points, together with the input generator, do not generate enough points, + * Initialization is considered to be complete if the triangulation is a 3D triangulation + * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the + * input surface). + * + * If the parameter `parameters::initial_points_generator()` is set, + * the points will be inserted before calling the functor. + * + * If after the insertion of initial points, together with the input generator, + * the initialization is not complete, * the domain's `construct_initial_points_object()` will be called. * * \tparam MeshDomain a model of `MeshDomain_3` @@ -510,8 +521,8 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * parameters::initial_points(std::cref(initial_points))); // Use std::cref to avoid a copy * \endcode * - * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` + * \sa `CGAL::parameters::initial_points_generator()` * \sa `MeshDomain_3::Construct_initial_points` * */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 7d5f54eb107..958506295a7 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -36,6 +36,11 @@ typedef unspecified_type C3t3; Outputs a set of surface points, for mesh initialization, to the output iterator `pts`. +If, after insertion of these points, the triangulation is still not 3D, +or does not have any facets +in the restricted Delaunay triangulation, then more points will be added automatically +by the mesher. + @tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : - a `C3t3::Triangulation::Point` : the point `p`, - a `int` : the minimal dimension of the subcomplexes on which `p` lies, @@ -44,8 +49,7 @@ output iterator `pts`. @param pts the output points @param n a lower bound on the number of points to construct for initialization. A generator can choose to ignore this parameter. -If this operator does not output enough points, then more points will be added automatically -by the mesher. + */ template OutputIterator operator()(OutputIterator pts, int n); @@ -53,7 +57,11 @@ OutputIterator operator()(OutputIterator pts, int n); /*! Same as above, without the `n` parameter. Since there is no `n` given like above, the functor must provide enough -points to initialize the mesh generation process. +points to initialize the mesh generation process, i.e. to have a 3D triangulation +with at least one facet in the restricted Delaunay triangulation. + +If these conditions are not satisfied, then more points will be added automatically +by the mesher. @tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : - a `C3t3::Triangulation::Point` : the point `p`, diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index d48984d0055..dd2c6418279 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -749,7 +749,7 @@ the triangulation for each connected component. The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh initialization (following the `InitialPointsGenerator`). The functor -`CGAL/Mesh_3/Construct_initial_points_labeled_image.h` is used in this example. +`Construct_initial_points_labeled_image` is used in this example. It constructs points using the API of the mesh domain, as follows. First the functor `construct_intersection` is created diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 9264d44d844..3ad11f85df5 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -63,8 +63,11 @@ struct Construct_initial_points_gray_image * even if they are non-connected components. * Using this functor guarantees to initialize each connected component. * - * \tparam OutputIterator model of `OutputIterator`, collecting points of type - * `MeshDomain::Intersection` + * @tparam OutputIterator model of `OutputIterator` for + * tuple-like objects containing + * - a `Weighted_point_3` for the point + * - an `int` for the minimal dimension of the subcomplexes on which the point lies + * - a `MeshDomain::Index` for the corresponding subcomplex index * \tparam MeshDomain model of `MeshDomain_3` * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` * diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 024f2cc878f..423906d3cd4 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -108,8 +108,11 @@ struct Construct_initial_points_labeled_image * even if they are non-connected components. * This ensures that each component will be initialized. * - * @tparam OutputIterator model of `OutputIterator` that contains points of type - * @todo describe type + * @tparam OutputIterator model of `OutputIterator` for + * tuple-like objects containing + * - a `Weighted_point_3` for the point + * - an `int` for the minimal dimension of the subcomplexes on which the point lies + * - a `MeshDomain::Index` for the corresponding subcomplex index */ template OutputIterator operator()(OutputIterator pts, int n = 20) const @@ -121,8 +124,11 @@ struct Construct_initial_points_labeled_image /*! * \brief Same as above, but a `TransformOperator` that transforms values of the image is used. * - * @tparam OutputIterator model of `OutputIterator` that contains points of type - * `MeshDomain::Intersection` + * @tparam OutputIterator model of `OutputIterator` for + * tuple-like objects containing + * - a `Weighted_point_3` for the point + * - an `int` for the minimal dimension of the subcomplexes on which the point lies + * - a `MeshDomain::Index` for the corresponding subcomplex index * @tparam MeshDomain model of `MeshDomain_3` * @tparam TransformOperator functor that transforms values of the image. * It must provide the following type:
      diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 3ca6e664809..f662736b73d 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -98,41 +98,48 @@ add_points_from_generator(C3T3& c3t3, } } +template +bool +needs_more_init(C3T3& c3t3, const MeshDomain& domain) +{ + // If c3t3 initialization is not sufficient (may happen if + // the user has not specified enough points ), add some surface points + + if (c3t3.triangulation().dimension() != 3) + return true; + else // dimension is 3 but it may not be enough + { + CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); + helper.update_restricted_facets(); + + if (c3t3.number_of_facets() == 0) { + return true; + } + else + { + helper.update_restricted_cells(); + if (c3t3.number_of_cells() == 0) { + return true; + } + } + return false; + } +} + template < typename C3T3, typename MeshDomain, typename MeshCriteria, typename InitializationOptions> void init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&, const int nb_initial_points, const InitializationOptions& init_options) { + // 1st insert points from initial_points range and initial_points_generator add_points_from_generator(c3t3, domain, nb_initial_points, init_options); - typedef CGAL::parameters::internal::Initialization_options Default_init_options; - bool is_default_init = false; - if constexpr (std::is_same_v) - { - is_default_init = init_options.is_default(); - } - // If c3t3 initialization is not sufficient (may happen if // the user has not specified enough points ), add some surface points - bool need_more_init = c3t3.triangulation().dimension() != 3 || !is_default_init; - if(!need_more_init) - { - CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); - helper.update_restricted_facets(); - if (c3t3.number_of_facets() == 0) { - need_more_init = true; - } - else - { - helper.update_restricted_cells(); - if(c3t3.number_of_cells() == 0) { - need_more_init = true; - } - } - } - if(need_more_init) + // use mesh domain's Construct_initial_points to complete initialization + if(needs_more_init(c3t3, domain)) { add_points_from_generator(c3t3, domain, nb_initial_points, domain.construct_initial_points_object()); @@ -297,31 +304,21 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true> if ( with_features ) { this->initialize_features(c3t3, domain, criteria,mesh_options); - // If c3t3 initialization is not sufficient (may happen if there is only - // a planar curve as feature for example), add some surface points - bool is_default_init = false; - if constexpr (std::is_same_v) + // If the initial points are not provided by the default generator, + // there is no need to count the restricted facets and cells for now + // because more vertices will be inserted anyway. + // The check will be done later in init_c3t3() + bool use_default_initializer = false; + if constexpr (std::is_same_v) // check default type { - is_default_init = init_options.is_default(); + use_default_initializer = init_options.is_default(); //check it also has no additional vertices } - bool need_more_init = c3t3.triangulation().dimension() != 3 || !is_default_init; - if(!need_more_init) { - CGAL::Mesh_3::C3T3_helpers helper(c3t3, domain); - helper.update_restricted_facets(); - - if (c3t3.number_of_facets() == 0) { - need_more_init = true; - } - else - { - helper.update_restricted_cells(); - if(c3t3.number_of_cells() == 0) { - need_more_init = true; - } - } - } - if(need_more_init) { + // If c3t3 initialization from features initialization + // is not sufficient (may happen if there is only + // a planar curve as feature for example), add some surface points. + if (!use_default_initializer || CGAL::Mesh_3::internal::needs_more_init(c3t3, domain)) + { init_c3t3(c3t3, domain, criteria, mesh_options.number_of_initial_points, init_options); } @@ -492,15 +489,16 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false> *
        *
      • `parameters::initial_points_generator()` *
      } - * \cgalParamDefault{`CGAL::Null_Functor()`, the domain's `construct_initial_points_object()` + * \cgalParamDefault{the domain's `construct_initial_points_object()` * will be called for the points initialization.} * \cgalParamExtra{If the generator does not generate enough points, * the domain's `construct_initial_points_object()` will be called.} * \cgalParamExtra{If the parameter `parameters::initial_points()` is set, * the functor will be called after insertion of the points.} + * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialization with points} * \cgalParamDescription{a `Range` of initial points, represented as - * tuple-like objects made of `tuple-like` can optionally + * tuple-like objects made of `tuple-like` objects of `` can optionally * be provided to start the meshing process. * `Weighted_point_3` is the point's position and weight, * `int` is the dimension of the minimal dimension subcomplex on which @@ -512,7 +510,9 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false> *
    } * \cgalParamDefault{`std::vector>()`} * \cgalParamExtra{If this parameter is set, - * the domain's `construct_initial_points_object()` will not be called.} + * the domain's `construct_initial_points_object()` will be called + * only if there is no facet in the restricted Delaunay triangulation + * after points insertion.} * \cgalParamExtra{If the parameter `parameters::initial_points_generator()` is set, * the points will be inserted before calling the functor.} * \cgalParamSectionEnd From 76ee84e88eebf2c6195ae7df6f69671cf4d35cee Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 12:12:35 +0200 Subject: [PATCH 64/99] mention features initialization in the insertion order description --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 58934b9fe54..1da81734b87 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -459,7 +459,8 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * - * If the parameter `parameters::initial_points()` is used, the points it provides are inserted before any other initialization. + * If the parameter `parameters::initial_points()` is used, + * the points it provides are inserted after one dimensional features initialization. * * Initialization is considered to be complete if the triangulation is a 3D triangulation * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the @@ -488,10 +489,11 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * * The function `parameters::initial_points()` enables the user to specify a container model of `Range` that contains * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` contains - * tuple-like objects containing a `Weighted_point_3`, an `int`, and an `Index`, + * tuple-like objects containing a `Weighted_point_3`, an `int`, and a `MeshDomain::Index`, * where `Weighted_point_3` represents the position and weight of the point, * `int` the dimension of the minimal subcomplex on which the point lies, * and `Index` the corresponding subcomplex index. + * These initial points are inserted after one dimensional features initialization. * * Initialization is considered to be complete if the triangulation is a 3D triangulation * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the From f0ad731919ad31705a2a1b341c3a7aac937424d8 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 12:12:54 +0200 Subject: [PATCH 65/99] cleaning --- .../internal/mesh_option_classes.h | 80 +------------------ 1 file changed, 1 insertion(+), 79 deletions(-) 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 7b9fe4b2485..8e23e22a4cb 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 @@ -203,7 +203,7 @@ struct Initialization_options {} Initialization_options(const Initial_points_generator& generator, - const Initial_points_range& initial_points = Initial_points_range()) + const Initial_points_range& initial_points) : initial_points_generator_(generator) , begin_it(initial_points.begin()) , end_it(initial_points.end()) @@ -275,84 +275,6 @@ struct Domain_features_generator< MeshDomain, true > } }; -// Evaluate the two parameters `initial_points_generator` and `initial_points` -// and returns the appropriate `Initialization_options`. -// If no generator and no initial points, then use the domain's construct_initial_points_object. -template -struct Initial_points_generator_generator -{ - typedef typename CGAL::parameters::internal::Initialization_options Initialization_options; - typedef typename Initialization_options::Value_type Value_type; - typedef typename Initialization_options::OutputIterator OutputIterator; - - struct Initial_points_generator_domain_traductor - { - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3) - { - // Use boost to easily create an output iterator. - // This iterator take the domain's construct_initial_points_object output : an std::pair - // and outputs an std::tuple - // As points are on the surfaces by construction, dimension is always 2. - typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = - c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); - domain.construct_initial_points_object()( - boost::make_function_output_iterator([&](const auto& domain_generated_point) { - *pts++ = std::make_tuple(cwp(domain_generated_point.first), 2, domain_generated_point.second); - })); - return pts; - } - OutputIterator operator()(OutputIterator pts, const MeshDomain& domain, const C3t3& c3t3, int n) - { - typename C3t3::Triangulation::Geom_traits::Construct_weighted_point_3 cwp = - c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); - domain.construct_initial_points_object()( - boost::make_function_output_iterator([&](const auto& domain_generated_point) { - *pts++ = std::make_tuple(cwp(domain_generated_point.first), 2, domain_generated_point.second); - }), n); - return pts; - } - }; - - struct Initial_points_generator_empty - { - OutputIterator operator()(OutputIterator pts, const MeshDomain& , const C3t3& ) - { return pts; } - OutputIterator operator()(OutputIterator pts, const MeshDomain& , const C3t3& , int ) - { return pts; } - }; - - // With a custom InitialPointsGenerator - template - Initialization_options operator()(const InitialPointsGenerator& initial_points_generator, const InitalPointsRange& input_points) - { - return Initialization_options(initial_points_generator, input_points, false); - } - - template - Initialization_options operator()(const InitialPointsGenerator& initial_points_generator) - { - std::vector empty_input_points; - return operator()(initial_points_generator, empty_input_points); - } - - // Without a custom InitialPointsGenerator - template - Initialization_options operator()(const Null_functor&, const InitalPointsRange& input_points) - { - // The domain's construct_initial_points_object is called only if input_points is empty - if (input_points.empty()) { - return Initialization_options(Initial_points_generator_domain_traductor(), input_points, true); - } - return Initialization_options(Initial_points_generator_empty(), input_points, true); - } - - // Default construction - Initialization_options operator()() - { - return operator()(Null_functor()); - } -}; - } // end namespace internal From f3b9a5ac84e306233a99e6d834cefb466ef8b0da Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 12:46:29 +0200 Subject: [PATCH 66/99] doc (Mael's review) --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 26 ++++++++++--------- .../Mesh_3/Concepts/InitialPointsGenerator.h | 12 ++++----- ...esh_3D_image_with_image_initialization.cpp | 7 +++-- .../mesh_3D_image_with_initial_points.cpp | 11 +++----- .../Construct_initial_points_gray_image.h | 9 ++++--- .../Construct_initial_points_labeled_image.h | 6 +++-- .../internal/mesh_option_classes.h | 6 ++--- 7 files changed, 40 insertions(+), 37 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 1da81734b87..5fabe1892eb 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -456,7 +456,8 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * * The function `parameters::initial_points_generator()` enables the user to specify a functor that follows * the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor is called - * for the initialization of the meshing process. If this parameter is specified without arguments, the default behavior + * for the initialization of the meshing process, by inserting well-distributed surface vertices. + * If this parameter is specified without arguments, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * * If the parameter `parameters::initial_points()` is used, @@ -468,7 +469,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * If the generator does not generate enough points for the initialization to be complete, * the domain's `construct_initial_points_object()` will be called to generate enough input points. * - * \tparam InitialPointsGenerator a functor that follows the `InitialPointsGenerator` concept + * \tparam InitialPointsGenerator a model of the `InitialPointsGenerator` concept * * @param generator an instance of `InitialPointsGenerator` * @@ -487,12 +488,12 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato /*! * \ingroup PkgMesh3Parameters * - * The function `parameters::initial_points()` enables the user to specify a container model of `Range` that contains - * initial points to be used in the `make_mesh_3()` function for mesh generation. The `Range` contains + * The function `parameters::initial_points()` enables the user to specify a container, model of `Range`, that contains + * initial points to be used in the `make_mesh_3()` function for mesh generation. Items in the container are * tuple-like objects containing a `Weighted_point_3`, an `int`, and a `MeshDomain::Index`, - * where `Weighted_point_3` represents the position and weight of the point, + * where `Weighted_point_3` represents the position and the weight of the point, * `int` the dimension of the minimal subcomplex on which the point lies, - * and `Index` the corresponding subcomplex index. + * and `MeshDomain::Index` the corresponding subcomplex index. * These initial points are inserted after one dimensional features initialization. * * Initialization is considered to be complete if the triangulation is a 3D triangulation @@ -500,17 +501,18 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * input surface). * * If the parameter `parameters::initial_points_generator()` is set, - * the points will be inserted before calling the functor. + * the points from this parameter will be inserted before calling the initial points generator * - * If after the insertion of initial points, together with the input generator, + * If after the insertion of initial points (possibly together with the input generator), * the initialization is not complete, * the domain's `construct_initial_points_object()` will be called. * * \tparam MeshDomain a model of `MeshDomain_3` * \tparam C3t3 a model of `MeshComplex_3InTriangulation_3` + * \tparam InitialPointsRange a model of `Range` containing tuple-like objects of + * `C3t3::Triangulation::Geom_traits::Weighted_point_3, int, MeshDomain::Index`. * - * @param initial_points a `Range` that contains points of tuple-like objects of - * `C3t3::Triangulation::Geom_traits::Weighted_point_3, int, MeshDomain::Index`. + * @param initial_points an instance of `InitialPointsRange` * * \cgalHeading{Example} * @@ -528,8 +530,8 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \sa `MeshDomain_3::Construct_initial_points` * */ -template -unspecified_type initial_points(const std::vector>& initial_points); +template +unspecified_type initial_points(const InitialPointsRange& initial_points); } /* namespace parameters */ } /* namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 958506295a7..ba7362204d3 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -33,7 +33,7 @@ typedef unspecified_type C3t3; /// @{ /*! -Outputs a set of surface points, for mesh initialization, to the +outputs a set of surface points for mesh initialization to the output iterator `pts`. If, after insertion of these points, the triangulation is still not 3D, @@ -41,12 +41,12 @@ or does not have any facets in the restricted Delaunay triangulation, then more points will be added automatically by the mesher. -@tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : +@tparam OutputIterator model of `OutputIterator` whose value type is a tuple-like object made of 3 elements: - a `C3t3::Triangulation::Point` : the point `p`, - - a `int` : the minimal dimension of the subcomplexes on which `p` lies, + - an `int` : the minimal dimension of the subcomplexes on which `p` lies, - a `MeshDomain_3::Index` : the index of the corresponding subcomplex. -@param pts the output points +@param pts an output iterator for the points @param n a lower bound on the number of points to construct for initialization. A generator can choose to ignore this parameter. @@ -63,9 +63,9 @@ with at least one facet in the restricted Delaunay triangulation. If these conditions are not satisfied, then more points will be added automatically by the mesher. -@tparam OutputIterator model of `OutputIterator`, containing tuple-like objects made of 3 elements : +@tparam OutputIterator model of `OutputIterator` whose value type is a tuple-like object made of 3 elements : - a `C3t3::Triangulation::Point` : the point `p`, - - a `int` : the minimal dimension of the subcomplexes to which `p` belongs, + - an `int` : the minimal dimension of the subcomplexes to which `p` belongs, - a `MeshDomain_3::Index` : the index of the corresponding subcomplex. */ template diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index c08d245bf76..aff744355fb 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -44,15 +44,14 @@ int main() // Mesh criteria 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)); /// [Meshing] // Mesh generation with a custom initialization that places points in each of the image components. CGAL::Construct_initial_points_labeled_image img_pts_generator(image, domain); - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, params::initial_points_generator(img_pts_generator) - ); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + params::initial_points_generator(img_pts_generator)); /// [Meshing] // Output 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 7b7e0cb41ea..067c5e623f4 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 @@ -47,13 +47,11 @@ int main() // Domain Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image - , params::features_detector(CGAL::Mesh_3::Detect_features_in_image()) - ); + , params::features_detector(CGAL::Mesh_3::Detect_features_in_image())); // Mesh criteria Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1).edge_size(3) - .cell_radius_edge_ratio(3).cell_size(3) - ); + .cell_radius_edge_ratio(3).cell_size(3)); using Point_3 = K::Point_3; using Weighted_point_3 = K::Weighted_point_3; @@ -68,9 +66,8 @@ int main() /// [Meshing] // Mesh generation from labeled image with initial points. - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points(std::cref(initial_points)) - ); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + params::initial_points(std::cref(initial_points))); /// [Meshing] // Output diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 3ad11f85df5..db796094fd8 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -35,6 +35,8 @@ namespace CGAL * this functor will scan the full image and * output points on every component. * + * \cgalModels{InitialPointsGenerator} + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_labeled_image` @@ -58,7 +60,7 @@ struct Construct_initial_points_gray_image { } /*! - * \brief Constructs at least `n` points by collecting them on the surface of all objects + * \brief constructs at least `n` points by collecting them on the surface of all objects * in the image, * even if they are non-connected components. * Using this functor guarantees to initialize each connected component. @@ -76,8 +78,9 @@ struct Construct_initial_points_gray_image OutputIterator operator()(OutputIterator pts, int n = 20) const { using CGAL::Mesh_3::internal::Create_gray_image_values_to_subdomain_indices; - typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; - typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + using C_i_v_t_s_i = Create_gray_image_values_to_subdomain_indices; + using Image_values_to_subdomain_indices = typename C_i_v_t_s_i::type; + Image_values_to_subdomain_indices transform_fct = C_i_v_t_s_i()(image_values_to_subdomain_indices_, iso_value_); Construct_initial_points_labeled_image init_pts{ image_, domain_ }; diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 423906d3cd4..f40adadc0e6 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -85,6 +85,8 @@ struct Get_point * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` * @tparam MeshDomain model of `MeshDomain_3` * + * \cgalModels{InitialPointsGenerator} + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_gray_image` @@ -102,7 +104,7 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief Constructs at least `n` initial points, + * \brief constructs at least `n` initial points, * by scanning the image and * collecting points in each object in the image, * even if they are non-connected components. @@ -132,7 +134,7 @@ struct Construct_initial_points_labeled_image * @tparam MeshDomain model of `MeshDomain_3` * @tparam TransformOperator functor that transforms values of the image. * It must provide the following type:
    - * `result_type` : a type that supports the '==' operator
    + * `result_type` a type that supports the '==' operator
    * and the following operator:
    * `result_type operator()(Word v)` * with `Word` the type of the image values. 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 8e23e22a4cb..79db0543bab 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 @@ -11,14 +11,14 @@ #ifndef CGAL_MESH_OPTION_CLASSES_H #define CGAL_MESH_OPTION_CLASSES_H -#include - #include #include + #include -#include + #include #include +#include namespace CGAL { From 96455895a1909aee286110a6fced9dc8f90a81b2 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 12:49:23 +0200 Subject: [PATCH 67/99] apply Mael's suggestions Co-authored-by: Mael --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index dd2c6418279..13751a868f8 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -748,10 +748,10 @@ the triangulation for each connected component. The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh -initialization (following the `InitialPointsGenerator`). The functor +initialization (following the concept `InitialPointsGenerator`). The functor `Construct_initial_points_labeled_image` is used in this example. It constructs points using the API of the mesh domain, as follows. -First the functor `construct_intersection` is created +First, the functor `construct_intersection` is created: \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h construct intersection then the `%Mesh_domain::Intersection` object (a `%tuple` with three From 7c4ab1ca0091068e603a3bd8048b0533eaad5eda Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 13:04:00 +0200 Subject: [PATCH 68/99] remove outdated named parameter --- .../include/CGAL/STL_Extension/internal/parameters_interface.h | 1 - 1 file changed, 1 deletion(-) 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 82e1778a9f0..f24867aa76d 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -339,7 +339,6 @@ CGAL_add_named_parameter_with_compatibility(manifold_param_t, manifold_param, ma 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_param_t,initial_points_param,initial_points) -CGAL_add_named_parameter_with_compatibility(c3t3_initializer_param_t, c3t3_initializer_param, c3t3_initializer) 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) From 32f147f6e2b213c1de27222c0d0d99e019b660b0 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 13:06:47 +0200 Subject: [PATCH 69/99] cleaning --- .../Mesh_3/mesh_3D_image_with_custom_initialization.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 600fa805b6a..37bdc503dbc 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -86,18 +86,15 @@ int main() // Domain Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image - , params::features_detector(CGAL::Mesh_3::Detect_features_on_image_bbox()) - ); + , params::features_detector(CGAL::Mesh_3::Detect_features_on_image_bbox())); // Mesh criteria Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1).edge_size(3) - .cell_radius_edge_ratio(3).cell_size(3) - ); + .cell_radius_edge_ratio(3).cell_size(3)); /// [Meshing] C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(Custom_initial_points_generator{ image }) - ); + , params::initial_points_generator(Custom_initial_points_generator{ image })); /// [Meshing] // Output From 74cd65efcf31dec82652b7ec59adf26ebc6dc043 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 13:49:04 +0200 Subject: [PATCH 70/99] move to 6.1 --- Installation/CHANGES.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 410efd7d7a9..4ed784d0939 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -1,6 +1,16 @@ Release History =============== +[Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1) +----------- + +### [3D Mesh Generation](https://doc.cgal.org/6.0/Manual/packages.html#PkgMesh3) + +- Added two new meshing parameters that enable mesh initialization customization : + - `initial_points_generator` : enables the user to specify a functor that generates initial points. + - `initial_points` : enables the user to specify a `Range` of initial points. + + [Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0) ----------- @@ -55,10 +65,6 @@ Release date: June 2024 - Removed the class templates `Gray_image_mesh_domain_3`, `Implicit_mesh_domain_3`, and `Labeled_image_mesh_domain_3` which are deprecated since CGAL-4.13. -- Added two new meshing parameters that enable mesh initialization customization : - - `initial_points_generator` : enables the user to specify a functor that generates initial points. - - `initial_points` : enables the user to specify a `Range` of initial points. - ### [Quadtrees, Octrees, and Orthtrees](https://doc.cgal.org/6.0/Manual/packages.html#PkgOrthtree) - **Breaking change**: - Node splitting behavior and per-node data are now customizable via the Traits class. From 4573f78d8b04f7b5833b2a45744ec357e080711b Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 14:02:50 +0200 Subject: [PATCH 71/99] doc --- .../CGAL/Mesh_3/Construct_initial_points_labeled_image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index f40adadc0e6..b07cc5a7a1b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -134,7 +134,7 @@ struct Construct_initial_points_labeled_image * @tparam MeshDomain model of `MeshDomain_3` * @tparam TransformOperator functor that transforms values of the image. * It must provide the following type:
    - * `result_type` a type that supports the '==' operator
    + * `result_type`: a type that supports the '==' operator
    * and the following operator:
    * `result_type operator()(Word v)` * with `Word` the type of the image values. From 435ea6ea9cf80f8c4cc51d71ad9b4097aece2545 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 30 Sep 2024 14:29:47 +0200 Subject: [PATCH 72/99] doc --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 5fabe1892eb..07987f19ad4 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -501,7 +501,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * input surface). * * If the parameter `parameters::initial_points_generator()` is set, - * the points from this parameter will be inserted before calling the initial points generator + * the points from this parameter will be inserted before calling the initial points generator. * * If after the insertion of initial points (possibly together with the input generator), * the initialization is not complete, From 75d3d30cb40b9b010bd0ef6be568e195627fb301 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Nov 2024 10:27:54 +0100 Subject: [PATCH 73/99] fix unused variable warnings and add a const --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 2 +- .../include/CGAL/Mesh_3/Construct_initial_points_gray_image.h | 2 +- .../CGAL/Mesh_3/Construct_initial_points_labeled_image.h | 2 +- Mesh_3/include/CGAL/make_mesh_3.h | 2 +- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index ba7362204d3..3453e3b27d1 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -52,7 +52,7 @@ A generator can choose to ignore this parameter. */ template -OutputIterator operator()(OutputIterator pts, int n); +OutputIterator operator()(OutputIterator pts, const int n); /*! Same as above, without the `n` parameter. diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index db796094fd8..9bbafbf57dd 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -75,7 +75,7 @@ struct Construct_initial_points_gray_image * */ template - OutputIterator operator()(OutputIterator pts, int n = 20) const + OutputIterator operator()(OutputIterator pts, const int n = 20) const { using CGAL::Mesh_3::internal::Create_gray_image_values_to_subdomain_indices; using C_i_v_t_s_i = Create_gray_image_values_to_subdomain_indices; diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index b07cc5a7a1b..caf5d0fe63f 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -117,7 +117,7 @@ struct Construct_initial_points_labeled_image * - a `MeshDomain::Index` for the corresponding subcomplex index */ template - OutputIterator operator()(OutputIterator pts, int n = 20) const + OutputIterator operator()(OutputIterator pts, const int n = 20) const { CGAL_IMAGE_IO_CASE(image_.image(), operator()(pts, CGAL::Identity(), n)); return pts; diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index c6f189abbeb..989cbe7d649 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -42,7 +42,7 @@ namespace internal { template < typename C3T3, typename MeshDomain, typename InitialPointsGenerator > void add_points_from_generator(C3T3& c3t3, - const MeshDomain& domain, + const MeshDomain&, const int nb_initial_points, const InitialPointsGenerator& generator) { 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 79db0543bab..b017dac3111 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 @@ -176,7 +176,7 @@ private: struct Dummy_initial_points_generator { template - OutputIterator operator()(OutputIterator oit, int n = 0) const { return oit; } + OutputIterator operator()(OutputIterator oit, const int) const { return oit; } }; // Holds the two parameters `initial_points_generator` and `initial_points`, @@ -210,7 +210,7 @@ struct Initialization_options {} template - OutputIterator operator()(OutputIterator pts, int n = 0) const + OutputIterator operator()(OutputIterator pts, const int n = 0) const { // add initial_points for (Initial_points_const_iterator it = begin_it; it != end_it; ++it) From 13328c335e9596edb39e6c14897c124cf5ad88a6 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Wed, 6 Nov 2024 13:34:52 +0100 Subject: [PATCH 74/99] fix warning Co-authored-by: Andreas Fabri --- .../Mesh_3/mesh_3D_image_with_custom_initialization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 37bdc503dbc..c0a78b4da3a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -46,7 +46,7 @@ struct Custom_initial_points_generator const CGAL::Image_3& image_; template - OutputIterator operator()(OutputIterator pts, int n = 20) const + OutputIterator operator()(OutputIterator pts, int) const { typedef Tr::Geom_traits Gt; typedef Gt::Point_3 Point_3; From d5203e3124e24aca8579c947ff5a5a1472e8e4ab Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 7 Nov 2024 09:27:10 +0100 Subject: [PATCH 75/99] doc Co-authored-by: Andreas Fabri --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 4 ++-- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 07987f19ad4..8d170fdb076 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -464,7 +464,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * the points it provides are inserted after one dimensional features initialization. * * Initialization is considered to be complete if the triangulation is a 3D triangulation - * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the + * with at least one facet in the restricted Delaunay triangulation (i.e., its dual intersects the * input surface). * If the generator does not generate enough points for the initialization to be complete, * the domain's `construct_initial_points_object()` will be called to generate enough input points. @@ -497,7 +497,7 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * These initial points are inserted after one dimensional features initialization. * * Initialization is considered to be complete if the triangulation is a 3D triangulation - * with at least one facet in the restricted Delaunay triangulation (i.e. its dual intersects the + * with at least one facet in the restricted Delaunay triangulation (i.e., its dual intersects the * input surface). * * If the parameter `parameters::initial_points_generator()` is set, diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 3453e3b27d1..78639e752eb 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -57,7 +57,7 @@ OutputIterator operator()(OutputIterator pts, const int n); /*! Same as above, without the `n` parameter. Since there is no `n` given like above, the functor must provide enough -points to initialize the mesh generation process, i.e. to have a 3D triangulation +points to initialize the mesh generation process, i.e., to have a 3D triangulation with at least one facet in the restricted Delaunay triangulation. If these conditions are not satisfied, then more points will be added automatically From 4215e18a8b314d463364207e3d16f2abd7090314 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 7 Nov 2024 09:37:52 +0100 Subject: [PATCH 76/99] fix CHANGES.md (lost by merge f77f9c68476de3abc9033e9f28b1b471e42c234b) --- Installation/CHANGES.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 405a1b25c5a..862196df915 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -1,14 +1,22 @@ # Release History -## [Release 6.0.1](https://github.com/CGAL/cgal/releases/tag/v6.0.1) +[Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1) +----------- + +Release date: + +### [3D Mesh Generation](https://doc.cgal.org/6.1/Manual/packages.html#PkgMesh3) + +- Added two new meshing parameters that enable mesh initialization customization : + - `initial_points_generator` : enables the user to specify a functor that generates initial points, + - `initial_points` : enables the user to specify a `Range` of initial points. + + +[Release 6.0.1](https://github.com/CGAL/cgal/releases/tag/v6.0.1) ### [Poisson Surface Reconstruction](https://doc.cgal.org/6.0.1/Manual/packages.html#PkgPoissonSurfaceReconstruction3) - Made the implicit function thread-safe so that the parallel version of `make_mesh_3()` can be used. -## [Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0) -[Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1) ------------ - [Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0) ----------- From 25b89cbd83c2f0cbe48adc97dc9c79e4beac2259 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 7 Nov 2024 12:55:12 +0100 Subject: [PATCH 77/99] fix CHANGES.md --- Installation/CHANGES.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index bb0f4023393..697eb2ede8a 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -7,7 +7,6 @@ - **Breaking change**: Classes based on the RS Library are no longer provided. - ### [3D Mesh Generation](https://doc.cgal.org/6.1/Manual/packages.html#PkgMesh3) - Added two new meshing parameters that enable mesh initialization customization : @@ -15,14 +14,12 @@ - `initial_points` : enables the user to specify a `Range` of initial points. -[Release 6.0.1](https://github.com/CGAL/cgal/releases/tag/v6.0.1) +## [Release 6.0.1](https://github.com/CGAL/cgal/releases/tag/v6.0.1) ### [Poisson Surface Reconstruction](https://doc.cgal.org/6.0.1/Manual/packages.html#PkgPoissonSurfaceReconstruction3) - Made the implicit function thread-safe so that the parallel version of `make_mesh_3()` can be used. - -[Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0) ------------ +## [Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0) Release date: September 2024 From 5c70d487a1f817b0c50fcb49b66244789d4823cd Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 17 Dec 2024 18:27:13 +0100 Subject: [PATCH 78/99] actually allow tuple-like objects, and test that feature --- Mesh_3/include/CGAL/make_mesh_3.h | 25 ++++++++++++++----- .../Mesh_3/test_meshing_unit_tetrahedron.cpp | 12 +++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 989cbe7d649..04de44c7d73 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,18 @@ namespace CGAL { namespace Mesh_3 { namespace internal { +template +constexpr bool has_tuple_size_v = false; + +template +constexpr bool has_tuple_size_v::value)>> = true; + +template > +constexpr bool tuple_like_of_size_2 = false; + +template +constexpr bool tuple_like_of_size_2 = (std::tuple_size_v == 2); + template < typename C3T3, typename MeshDomain, typename InitialPointsGenerator > void add_points_from_generator(C3T3& c3t3, @@ -62,16 +75,16 @@ add_points_from_generator(C3T3& c3t3, std::vector initial_points; auto push_initial_point = [&](const auto& initial_pt)->void { - using T = std::remove_cv_t < std::remove_reference_t>; - if constexpr (std::tuple_size_v == 3) + using T = CGAL::cpp20::remove_cvref_t; + if constexpr (tuple_like_of_size_2) { - const auto& [weighted_pt, dim, index] = initial_pt; - initial_points.push_back(PointDimIndex{ weighted_pt, dim, index }); + const auto& [pt, index] = initial_pt; + initial_points.push_back(PointDimIndex{cwp(pt), 2, index}); } else { - const auto& [pt, index] = initial_pt; - initial_points.push_back(PointDimIndex{ cwp(pt), 2, index }); + const auto& [weighted_pt, dim, index] = initial_pt; + initial_points.push_back(PointDimIndex{weighted_pt, dim, index}); } }; diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index 5781f445050..ff2028a926a 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -66,6 +66,18 @@ struct Polyhedron_tester : public Tester // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + // test initial_points with a tuple-like object + using Weighted_point = typename K::Weighted_point_3; + using Index = typename Mesh_domain::Index; + struct Initial_point + { + Weighted_point weighted_point; + int dimension; + Index index; + }; + std::vector initial_points = { Initial_point{ Weighted_point(.5, .5, .5), 3, Index{}} }; + c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::initial_points(initial_points)); + CGAL::remove_far_points_in_mesh_3(c3t3); double vol = 1/6.; From 79ebe7aa4d162505bd025dacb7773738c73dc09d Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 17 Dec 2024 18:35:00 +0100 Subject: [PATCH 79/99] minor fixes --- Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index 78639e752eb..b20f602123b 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -6,8 +6,8 @@ The function object concept `InitialPointsGenerator` is designed to construct a set of initial points on the surface of the domain. \cgalHasModelsBegin -\cgalHasModels{CGAL::Construct_initial_points_labeled_image} -\cgalHasModels{CGAL::Construct_initial_points_gray_image} +\cgalHasModels{CGAL::Construct_initial_points_labeled_image} +\cgalHasModels{CGAL::Construct_initial_points_gray_image} \cgalHasModelsEnd */ @@ -39,7 +39,7 @@ output iterator `pts`. If, after insertion of these points, the triangulation is still not 3D, or does not have any facets in the restricted Delaunay triangulation, then more points will be added automatically -by the mesher. +by the mesh generator. @tparam OutputIterator model of `OutputIterator` whose value type is a tuple-like object made of 3 elements: - a `C3t3::Triangulation::Point` : the point `p`, @@ -61,7 +61,7 @@ points to initialize the mesh generation process, i.e., to have a 3D triangulati with at least one facet in the restricted Delaunay triangulation. If these conditions are not satisfied, then more points will be added automatically -by the mesher. +by the mesh generator. @tparam OutputIterator model of `OutputIterator` whose value type is a tuple-like object made of 3 elements : - a `C3t3::Triangulation::Point` : the point `p`, From 9803ab49dc147d9c5688ec2d3e4efec490c4c537 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 17 Dec 2024 18:37:29 +0100 Subject: [PATCH 80/99] add test of initial_points_generator with a generator generating tuple-like object --- Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index ff2028a926a..e8e9268e323 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -78,6 +78,14 @@ struct Polyhedron_tester : public Tester std::vector initial_points = { Initial_point{ Weighted_point(.5, .5, .5), 3, Index{}} }; c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::initial_points(initial_points)); + // test initial_points_generator with a generator generating tuple-like object + auto initial_points_generator = [](auto oit, const int) { + *oit++ = Initial_point{ Weighted_point(.5, .5, .5), 3, Index{} }; + return oit; + }; + c3t3 = CGAL::make_mesh_3(domain, criteria, + CGAL::parameters::initial_points_generator(initial_points_generator)); + CGAL::remove_far_points_in_mesh_3(c3t3); double vol = 1/6.; From 820762da524216fe8fa6badb38b25fa18d9d2bd5 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 11:00:55 +0100 Subject: [PATCH 81/99] proposal for a rewrite using a lamba expression as the point generator --- .../Mesh_3/Concepts/InitialPointsGenerator.h | 3 +- ...sh_3D_image_with_custom_initialization.cpp | 91 ++++++++----------- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index b20f602123b..eb89399fd75 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -15,8 +15,9 @@ a set of initial points on the surface of the domain. class InitialPointsGenerator { public: -/// \name Types +/// \name Types (exposition only) /// @{ +/// These types are used in the concept's description but are not part of the concept itself. /*! * Mesh domain type to be meshed, model of `MeshDomain_3` diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index c0a78b4da3a..a3d5209a74b 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -15,65 +15,25 @@ #include // Domain -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_mesh_domain_3 Image_domain; -typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Image_domain = CGAL::Labeled_mesh_domain_3; +using Mesh_domain = CGAL::Mesh_domain_with_polyline_features_3; #ifdef CGAL_CONCURRENT_MESH_3 -typedef CGAL::Parallel_tag Concurrency_tag; +using Concurrency_tag = CGAL::Parallel_tag; #else -typedef CGAL::Sequential_tag Concurrency_tag; +using Concurrency_tag = CGAL::Sequential_tag; #endif // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; - -typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; +using Tr = CGAL::Mesh_triangulation_3::type; +using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +using Mesh_criteria = CGAL::Mesh_criteria_3; namespace params = CGAL::parameters; -// Custom_initial_points_generator will put points on the mesh for initialisation. -// Those points are objects of type std::tuple. -// Weighted_point_3 is the point's position and weight, -// int is the dimension of the minimal dimension subcomplex on which the point lies, -// Index is the underlying subcomplex index. - -struct Custom_initial_points_generator -{ - const CGAL::Image_3& image_; - - template - OutputIterator operator()(OutputIterator pts, int) const - { - typedef Tr::Geom_traits Gt; - typedef Gt::Point_3 Point_3; - typedef Gt::Vector_3 Vector_3; - typedef Gt::Segment_3 Segment_3; - typedef Mesh_domain::Index Index; - - Gt::Construct_weighted_point_3 cwp = Gt().construct_weighted_point_3_object(); - - // Add points along the segment - Segment_3 segment(Point_3( 0.0, 50.0, 66.66), - Point_3(100.0, 50.0, 66.66)); - - Point_3 source = segment.source(); - Vector_3 vector = segment.to_vector(); - double edge_size = 5; - std::size_t nb = static_cast(CGAL::sqrt(segment.squared_length()) / edge_size); - const double frac = 1. / (double)nb; - - for (std::size_t i = 1; i < nb; i++) - { - *pts++ = std::make_tuple( cwp(source + (i * frac) * vector), 1, Index(1) ); - } - return pts; - } -}; - int main() { const std::string fname = CGAL::data_file_path("images/420.inr"); @@ -89,12 +49,41 @@ int main() , params::features_detector(CGAL::Mesh_3::Detect_features_on_image_bbox())); // Mesh criteria - Mesh_criteria criteria(params::facet_angle(30).facet_size(3).facet_distance(1).edge_size(3) + const double edge_size = 3; + Mesh_criteria criteria(params::edge_size(edge_size) + .facet_angle(30).facet_size(3).facet_distance(1) .cell_radius_edge_ratio(3).cell_size(3)); + // custom_initial_points_generator will put points on the mesh for initialisation. + // Those points are objects of type std::tuple. + // Weighted_point_3 is the point's position and weight, + // int is the dimension of the minimal dimension subcomplex on which the point lies, + // Index is the underlying subcomplex index. + auto custom_initial_points_generator = [&](auto pts_out_iterator, int) { + using Point_3 = K::Point_3; + using Weighted_point_3 = K::Weighted_point_3; + using Index = Mesh_domain::Index; + using Point_dim_index = std::tuple; + + Point_3 a{0.0, 50.0, 66.66}; + Point_3 b{100.0, 50.0, 66.66}; + + // Add points along the segment [a, b] + double dist_ab = CGAL::sqrt(CGAL::squared_distance(a, b)); + int nb = static_cast(std::floor(dist_ab / edge_size)); + auto vector = (b - a) / static_cast(nb); + + Point_3 p = a; + for(int i = 0; i < nb; ++i) { + *pts_out_iterator++ = Point_dim_index{Weighted_point_3{p}, 1, Index(1)}; + p += vector; + } + return pts_out_iterator; + }; + /// [Meshing] - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria - , params::initial_points_generator(Custom_initial_points_generator{ image })); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + params::initial_points_generator(custom_initial_points_generator)); /// [Meshing] // Output From e2d11a0fc5b384fd65bdaec27b4ed9d5c0212a59 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 13:44:54 +0100 Subject: [PATCH 82/99] allow a range as parameter The preview implementation enforced the use of a full container. --- Mesh_3/include/CGAL/make_mesh_3.h | 6 +++--- .../Mesh_3/test_meshing_unit_tetrahedron.cpp | 12 ++++++++++++ .../STL_Extension/internal/mesh_option_classes.h | 16 ++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 04de44c7d73..8563c016e41 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -88,11 +88,11 @@ add_points_from_generator(C3T3& c3t3, } }; + auto output_it = boost::make_function_output_iterator(push_initial_point); if (nb_initial_points > 0) - generator(boost::make_function_output_iterator(push_initial_point), nb_initial_points); + generator(output_it, nb_initial_points); else - generator(boost::make_function_output_iterator(push_initial_point)); - + generator(output_it); // Insert points and set their index and dimension for (const auto& [wpoint, dimension, index] : initial_points) diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index e8e9268e323..6276758bfcc 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -10,6 +10,14 @@ #include +template class Non_copyable_range_view { + Range& r; +public: + Non_copyable_range_view(Range& r) : r(r) {} + auto begin() const { return r.begin(); } + auto end() const { return r.end(); } +}; + template struct Polyhedron_tester : public Tester { @@ -78,6 +86,10 @@ struct Polyhedron_tester : public Tester std::vector initial_points = { Initial_point{ Weighted_point(.5, .5, .5), 3, Index{}} }; c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::initial_points(initial_points)); + // test initial_points with a non-copyable range + Non_copyable_range_view initial_points_view{ initial_points }; + c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::initial_points(initial_points_view)); + // test initial_points_generator with a generator generating tuple-like object auto initial_points_generator = [](auto oit, const int) { *oit++ = Initial_point{ Weighted_point(.5, .5, .5), 3, Index{} }; 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 b017dac3111..6061a523675 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 @@ -196,8 +196,16 @@ struct Initialization_options using Initial_points_range = typename CGAL::Default::Get>::type; - using Initial_points_const_iterator = typename Initial_points_range::const_iterator; - using Initial_point = typename std::iterator_traits::value_type; + template + static auto cbegin(Range&& range) { + return std::cbegin(std::forward(range)); + } + + template + static auto cend(Range&& range) { + return std::cend(std::forward(range)); + } + using Initial_points_const_iterator = decltype(cbegin(std::declval())); Initialization_options() {} @@ -205,8 +213,8 @@ struct Initialization_options Initialization_options(const Initial_points_generator& generator, const Initial_points_range& initial_points) : initial_points_generator_(generator) - , begin_it(initial_points.begin()) - , end_it(initial_points.end()) + , begin_it(cbegin(initial_points)) + , end_it(cend(initial_points)) {} template From eecff9d71a68fa53a51cd2d1116c307bdc0aeb35 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 13:48:21 +0100 Subject: [PATCH 83/99] add initial_points to the list of available functors for mesh initialization --- Mesh_3/doc/Mesh_3/PackageDescription.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index 5022fc0c026..18541cbb3de 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -133,6 +133,7 @@ The following functors are available for mesh initialization: - `CGAL::parameters::features()` - `CGAL::parameters::no_features()` +- `CGAL::parameters::initial_points()` - `CGAL::parameters::initial_points_generator()` - `CGAL::parameters::exude()` - `CGAL::parameters::no_exude()` From 8e5fab0c98479c7383af0207f76d2eb85c96591e Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 16:22:18 +0100 Subject: [PATCH 84/99] allow the initial points generator to be non-const A lot of type erasure was necessary. --- Mesh_3/include/CGAL/make_mesh_3.h | 60 ++++---- .../Mesh_3/test_meshing_unit_tetrahedron.cpp | 4 +- .../internal/mesh_option_classes.h | 140 +++++++++++++++--- 3 files changed, 152 insertions(+), 52 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 8563c016e41..7110489d4db 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -40,17 +41,33 @@ namespace CGAL { namespace Mesh_3 { namespace internal { -template -constexpr bool has_tuple_size_v = false; +template +struct Push_to_initial_point { + // This struct cannot be a lambda-expression before C++20, because we need it to be copyable/assignable. + std::vector* points_vector_ptr; + C3T3* c3t3_ptr; -template -constexpr bool has_tuple_size_v::value)>> = true; + Push_to_initial_point(std::vector* points_vector_ptr, C3T3* c3t3_ptr) + : points_vector_ptr(points_vector_ptr) + , c3t3_ptr(c3t3_ptr) + {} -template > -constexpr bool tuple_like_of_size_2 = false; - -template -constexpr bool tuple_like_of_size_2 = (std::tuple_size_v == 2); + template + void operator()(const Initial_point_and_info& initial_pt) const { + using T = CGAL::cpp20::remove_cvref_t; + if constexpr (tuple_like_of_size_2) + { + const auto& [pt, index] = initial_pt; + const auto& cwp = c3t3_ptr->triangulation().geom_traits().construct_weighted_point_3_object(); + points_vector_ptr->push_back(PointDimIndex{cwp(pt), 2, index}); + } + else + { + const auto& [weighted_pt, dim, index] = initial_pt; + points_vector_ptr->push_back(PointDimIndex{weighted_pt, dim, index}); + } + }; +}; template < typename C3T3, typename MeshDomain, typename InitialPointsGenerator > void @@ -70,24 +87,9 @@ add_points_from_generator(C3T3& c3t3, typename MeshDomain::Index m_index; }; - const auto& cwp = c3t3.triangulation().geom_traits().construct_weighted_point_3_object(); std::vector initial_points; - auto push_initial_point = [&](const auto& initial_pt)->void - { - using T = CGAL::cpp20::remove_cvref_t; - if constexpr (tuple_like_of_size_2) - { - const auto& [pt, index] = initial_pt; - initial_points.push_back(PointDimIndex{cwp(pt), 2, index}); - } - else - { - const auto& [weighted_pt, dim, index] = initial_pt; - initial_points.push_back(PointDimIndex{weighted_pt, dim, index}); - } - }; - + Push_to_initial_point push_initial_point{&initial_points, &c3t3}; auto output_it = boost::make_function_output_iterator(push_initial_point); if (nb_initial_points > 0) generator(output_it, nb_initial_points); @@ -621,7 +623,7 @@ C3T3 make_mesh_3(const MeshDomain& domain, const MeshCriteria& criteria, const C auto default_generator = domain.construct_initial_points_object(); Initial_points_generator initial_points_generator = choose_parameter(get_parameter(np, internal_np::initial_points_generator_param), default_generator); - const parameters::internal::Initialization_options + const parameters::internal::Initialization_options initial_points_gen_param(initial_points_generator, initial_points); C3T3 c3t3; @@ -658,7 +660,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, @@ -671,8 +673,8 @@ 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(), - const parameters::internal::Initialization_options& - initialization_options = parameters::internal::Initialization_options()) + const parameters::internal::Initialization_options& + initialization_options = parameters::internal::Initialization_options()) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index 6276758bfcc..3e62a7d11ae 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -90,8 +90,8 @@ struct Polyhedron_tester : public Tester Non_copyable_range_view initial_points_view{ initial_points }; c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::initial_points(initial_points_view)); - // test initial_points_generator with a generator generating tuple-like object - auto initial_points_generator = [](auto oit, const int) { + // test initial_points_generator with a non-const generator generating tuple-like object + auto initial_points_generator = [](auto oit, const int) mutable { *oit++ = Initial_point{ Weighted_point(.5, .5, .5), 3, Index{} }; return oit; }; 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 6061a523675..fe7e7d75287 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 @@ -13,6 +13,8 @@ #include #include +#include +#include #include @@ -173,26 +175,17 @@ private: }; // Mesh initialization -struct Dummy_initial_points_generator -{ - template - OutputIterator operator()(OutputIterator oit, const int) const { return oit; } -}; - // Holds the two parameters `initial_points_generator` and `initial_points`, // without knowing their types, into a single generator. template struct Initialization_options { - using Default_generator = Dummy_initial_points_generator; - using Initial_points_generator - = typename CGAL::Default::Get::type; + using Point = typename C3t3::Triangulation::Point; using Default_initial_point_type - = std::tuple; + = std::tuple; using Initial_points_range = typename CGAL::Default::Get>::type; @@ -207,34 +200,139 @@ struct Initialization_options } using Initial_points_const_iterator = decltype(cbegin(std::declval())); + struct Output_function_ref { + // This reference-like type uses type erasure to store a reference to a callable + // + // See the video "Breaking Dependencies - C++ Type Erasure - The Implementation Details" + // by Klaus Iglberger at CppCon 2022, from time code 49:57. + // URL: https://youtu.be/qn6OqefuH08?si=YzhwpgNLur8_jOeC&t=2997" + + using Erased_call_function_pointer_type = void(*)(void*, const Default_initial_point_type&); + + // store the address of the callable + void* const f_ = nullptr; + // and the call function (the non-capturing lambda generated by the templated constructor) + Erased_call_function_pointer_type const call_ = nullptr; + + template , + Output_function_ref> + > + > + Output_function_ref(Function&& f) + : f_(std::addressof(f)) + , call_( [](void* f, const Default_initial_point_type& p) { + using F = CGAL::cpp20::remove_cvref_t; + auto* real_f = static_cast(f); + (*real_f)(p); + } ) + { + } + + template + void operator()(Tuple_like&& p) const + { + using Tuple_like_no_cvref = CGAL::cpp20::remove_cvref_t; + if constexpr (CGAL::Mesh_3::internal::tuple_like_of_size_2) { + const auto& [pt, index] = p; + call_(f_, Default_initial_point_type(pt, 2, index)); + } else if constexpr (std::is_same_v) { + call_(f_, std::forward(p)); + } else { + const auto& [pt, dim, index] = p; + call_(f_, Default_initial_point_type(pt, dim, index)); + } + } + }; // end of struct Output_function_ref + + using Point_output_function_iterator = boost::function_output_iterator; + + struct Generator_ref { // type-erased reference to a generator, same as Output_function_ref + using Erased_call_function_pointer_type = Point_output_function_iterator(*)(void*, Point_output_function_iterator, const int); + + void * const generator_ = nullptr; + Erased_call_function_pointer_type const call_ = nullptr; + + template , + Generator_ref> + > + > + Generator_ref(Generator&& generator) + : generator_(std::addressof(generator)) + , call_( [](void* g, Point_output_function_iterator oit, const int n) { + using Real_generator = CGAL::cpp20::remove_cvref_t; + auto* real_g = static_cast(g); + return (*real_g)(oit, n); + } ) + { + } + + Generator_ref() = default; + + Point_output_function_iterator operator()(Point_output_function_iterator oit, const int n) const + { + return call_(generator_, oit, n); + } + + Point_output_function_iterator operator()(Point_output_function_iterator oit, const int n) + { + return call_(generator_, oit, n); + } + + bool operator==(std::nullptr_t) const { return generator_ == nullptr; } + }; // end of struct Generator_ref + Initialization_options() {} - Initialization_options(const Initial_points_generator& generator, + template + Initialization_options(Initial_points_generator& generator, const Initial_points_range& initial_points) - : initial_points_generator_(generator) + : initial_points_generator_(std::forward(generator)) , begin_it(cbegin(initial_points)) , end_it(cend(initial_points)) {} + template + static OutputIterator call_operator(Self& self, OutputIterator pts_it, const int n) + { + // add initial_points + pts_it = std::copy(self.begin_it, self.end_it, pts_it); + + if(self.initial_points_generator_ == nullptr) { + return pts_it; + } + + // Now, create an output iterator type-erasing the type of `pts_it`... + auto output_to_pts_it = [&](const Default_initial_point_type& p) { *pts_it++ = p; }; + Output_function_ref function_ref{ output_to_pts_it }; // maintains a non-const reference to pts_it + Point_output_function_iterator output_iterator{ function_ref }; + + // ...and use the type-erased output iterator with the type-erased generator. + self.initial_points_generator_(output_iterator, n); + return pts_it; + } + + template + OutputIterator operator()(OutputIterator pts, const int n = 0) + { + return call_operator(*this, pts, n); + } + template OutputIterator operator()(OutputIterator pts, const int n = 0) const { - // add initial_points - for (Initial_points_const_iterator it = begin_it; it != end_it; ++it) - *pts++ = *it; - - return initial_points_generator_(pts, n); + return call_operator(*this, pts, n); } bool is_default() const { - return begin_it == end_it - && std::is_same_v; + return begin_it == end_it && initial_points_generator_ == nullptr; } private: - Initial_points_generator initial_points_generator_; + Generator_ref initial_points_generator_; //reference that type-erases the generator type // The two iterators point to the `initial_points` container Initial_points_const_iterator begin_it; From 9ef32fb832a0b8af6660d88421cbdc7114511311 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 18:25:55 +0100 Subject: [PATCH 85/99] remove memory leaks with VTK objects --- Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp index ce8fc8db39c..d3d718138ad 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp @@ -1,5 +1,5 @@ -#include +#include #include #include #include @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/squircle.nii"); - vtkImageData* vtk_image = nullptr; + vtkSmartPointer vtk_image = nullptr; Image_word_type iso = (argc>2)? boost::lexical_cast(argv[2]): 1; double fs = (argc>3)? boost::lexical_cast(argv[3]): 1; double fd = (argc>4)? boost::lexical_cast(argv[4]): 0.1; @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) if (path.has_extension()){ fs::path stem = path.stem(); if ((path.extension() == ".nii") || (stem.has_extension() && (stem.extension() == ".nii") && (path.extension() == ".gz"))) { - vtkNIFTIImageReader* reader = vtkNIFTIImageReader::New(); + auto reader = vtkSmartPointer::New(); reader->SetFileName(fname.c_str()); reader->Update(); vtk_image = reader->GetOutput(); @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) } } else if (fs::is_directory(path)) { - vtkDICOMImageReader* dicom_reader = vtkDICOMImageReader::New(); + auto dicom_reader = vtkSmartPointer::New(); dicom_reader->SetDirectoryName(argv[1]); vtkDemandDrivenPipeline* executive = @@ -91,7 +91,7 @@ int main(int argc, char* argv[]) executive->SetReleaseDataFlag(0, 0); // where 0 is the port index } - vtkImageGaussianSmooth* smoother = vtkImageGaussianSmooth::New(); + auto smoother = vtkSmartPointer::New(); smoother->SetStandardDeviations(1., 1., 1.); smoother->SetInputConnection(dicom_reader->GetOutputPort()); smoother->Update(); From 51b9c4a4b2635cf1be2d24a516cab4a3ac4f955b Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 18 Dec 2024 18:50:02 +0100 Subject: [PATCH 86/99] cleanup --- Mesh_3/include/CGAL/make_mesh_3.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 7110489d4db..68e5534096e 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -669,12 +669,10 @@ void make_mesh_3_impl(C3T3& c3t3, const parameters::internal::Odt_options& odt, const parameters::internal::Lloyd_options& lloyd, const bool with_features, - const parameters::internal::Mesh_3_options& - mesh_options = parameters::internal::Mesh_3_options(), - const parameters::internal::Manifold_options& - manifold_options = parameters::internal::Manifold_options(), + const parameters::internal::Mesh_3_options& mesh_options = {}, + const parameters::internal::Manifold_options& manifold_options = {}, const parameters::internal::Initialization_options& - initialization_options = parameters::internal::Initialization_options()) + initialization_options = {}) { #ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING CGAL::get_default_random() = CGAL::Random(0); From 740863cb024d1d9831319dc36fc51896a9a6bc03 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 11:50:10 +0100 Subject: [PATCH 87/99] doc review --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 8 +++-- .../Mesh_3/Concepts/InitialPointsGenerator.h | 31 ++++++------------- .../mesh_3D_image_with_initial_points.cpp | 8 ++--- .../Construct_initial_points_gray_image.h | 12 ++++--- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 8d170fdb076..b770c01a8ee 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -460,12 +460,14 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * If this parameter is specified without arguments, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * - * If the parameter `parameters::initial_points()` is used, - * the points it provides are inserted after one dimensional features initialization. - * * Initialization is considered to be complete if the triangulation is a 3D triangulation * with at least one facet in the restricted Delaunay triangulation (i.e., its dual intersects the * input surface). + * + * If one dimensional features are requested, their initialization is performed first. + * If provided, the points of `parameters::initial_points()` are inserted next. + * Then, `parameters::initial_points_generator()` is used to generate more initial points + * and complete the initialization. * If the generator does not generate enough points for the initialization to be complete, * the domain's `construct_initial_points_object()` will be called to generate enough input points. * diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h index eb89399fd75..23c1a07a7d5 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h @@ -32,10 +32,11 @@ typedef unspecified_type C3t3; /// \name Operations /// @{ +/// Initial points generators are designed to output, via their operators `operator(OutputIterator)`, +/// a set of surface points for mesh initialization to an output iterator. /*! -outputs a set of surface points for mesh initialization to the -output iterator `pts`. +outputs a set of surface points for mesh initialization. If, after insertion of these points, the triangulation is still not 3D, or does not have any facets @@ -49,28 +50,14 @@ by the mesh generator. @param pts an output iterator for the points @param n a lower bound on the number of points to construct for initialization. -A generator can choose to ignore this parameter. - + When `n` is set to its default value `0`, the functor must provide enough + points to initialize the mesh generation process, i.e., to have a 3D triangulation + with at least one facet in the restricted Delaunay triangulation. + If these conditions are not satisfied, then more points will be added automatically + by the mesh generator. */ template -OutputIterator operator()(OutputIterator pts, const int n); - -/*! -Same as above, without the `n` parameter. -Since there is no `n` given like above, the functor must provide enough -points to initialize the mesh generation process, i.e., to have a 3D triangulation -with at least one facet in the restricted Delaunay triangulation. - -If these conditions are not satisfied, then more points will be added automatically -by the mesh generator. - -@tparam OutputIterator model of `OutputIterator` whose value type is a tuple-like object made of 3 elements : - - a `C3t3::Triangulation::Point` : the point `p`, - - an `int` : the minimal dimension of the subcomplexes to which `p` belongs, - - a `MeshDomain_3::Index` : the index of the corresponding subcomplex. -*/ -template -OutputIterator operator()(OutputIterator pts); +OutputIterator operator()(OutputIterator pts, const int n = 0); /// @} 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 067c5e623f4..947fe4d890d 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 @@ -9,11 +9,10 @@ #include #include -#include - - #include +#include + // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Labeled_mesh_domain_3 Image_domain; @@ -71,7 +70,8 @@ int main() /// [Meshing] // Output - CGAL::dump_c3t3(c3t3, "out"); + std::ofstream ofs("out.mesh"); + CGAL::IO::write_MEDIT(ofs, c3t3); return 0; } diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 9bbafbf57dd..5ef09bb565e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -31,9 +31,11 @@ namespace CGAL * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * - * On images that contain multiple non-connected components, + * On images that contain multiple connected components, * this functor will scan the full image and - * output points on every component. + * output enough points on the surface of each component + * to initialize them all. Each connected component is guaranteed to be + * represented by at least one cell of the triangulation. * * \cgalModels{InitialPointsGenerator} * @@ -60,9 +62,9 @@ struct Construct_initial_points_gray_image { } /*! - * \brief constructs at least `n` points by collecting them on the surface of all objects - * in the image, - * even if they are non-connected components. + * \brief constructs at least `n` points by collecting them on the surface of all + * subdomains in the image, + * even if they are not connected components. * Using this functor guarantees to initialize each connected component. * * @tparam OutputIterator model of `OutputIterator` for From 7e5b9eec9b79ec75effc1b92882e147e326fa6fc Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 12:04:10 +0100 Subject: [PATCH 88/99] rename concept with _3 postfix --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 4 ++-- ...{InitialPointsGenerator.h => InitialPointsGenerator_3.h} | 6 +++--- Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- Mesh_3/doc/Mesh_3/PackageDescription.txt | 2 +- .../CGAL/Mesh_3/Construct_initial_points_gray_image.h | 4 ++-- .../CGAL/Mesh_3/Construct_initial_points_labeled_image.h | 4 ++-- Mesh_3/include/CGAL/make_mesh_3.h | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) rename Mesh_3/doc/Mesh_3/Concepts/{InitialPointsGenerator.h => InitialPointsGenerator_3.h} (93%) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index b770c01a8ee..a5d349e5ed7 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -455,7 +455,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * \ingroup PkgMesh3Parameters * * The function `parameters::initial_points_generator()` enables the user to specify a functor that follows - * the `InitialPointsGenerator` concept to the mesh generation function `make_mesh_3()`. This functor is called + * the `InitialPointsGenerator_3` concept to the mesh generation function `make_mesh_3()`. This functor is called * for the initialization of the meshing process, by inserting well-distributed surface vertices. * If this parameter is specified without arguments, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. @@ -471,7 +471,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * If the generator does not generate enough points for the initialization to be complete, * the domain's `construct_initial_points_object()` will be called to generate enough input points. * - * \tparam InitialPointsGenerator a model of the `InitialPointsGenerator` concept + * \tparam InitialPointsGenerator a model of the `InitialPointsGenerator_3` concept * * @param generator an instance of `InitialPointsGenerator` * diff --git a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator_3.h similarity index 93% rename from Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h rename to Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator_3.h index 23c1a07a7d5..351ac34126f 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator.h +++ b/Mesh_3/doc/Mesh_3/Concepts/InitialPointsGenerator_3.h @@ -2,7 +2,7 @@ \ingroup PkgMesh3SecondaryConcepts \cgalConcept -The function object concept `InitialPointsGenerator` is designed to construct +The function object concept `InitialPointsGenerator_3` is designed to construct a set of initial points on the surface of the domain. \cgalHasModelsBegin @@ -12,7 +12,7 @@ a set of initial points on the surface of the domain. */ -class InitialPointsGenerator { +class InitialPointsGenerator_3 { public: /// \name Types (exposition only) @@ -61,4 +61,4 @@ OutputIterator operator()(OutputIterator pts, const int n = 0); /// @} -}; /* end InitialPointsGenerator */ +}; /* end InitialPointsGenerator_3 */ diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 28c08630ec5..73fc0b179f2 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -748,7 +748,7 @@ the triangulation for each connected component. The parameter `CGAL::parameters::initial_points_generator` is used. It expects a functor that returns a set of points for the mesh -initialization (following the concept `InitialPointsGenerator`). The functor +initialization (following the concept `InitialPointsGenerator_3`). The functor `Construct_initial_points_labeled_image` is used in this example. It constructs points using the API of the mesh domain, as follows. First, the functor `construct_intersection` is created: diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index 18541cbb3de..926491fc627 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -80,7 +80,7 @@ related to the template parameters of some models of the main concepts: - `BisectionGeometricTraits_3` - `IntersectionGeometricTraits_3` -- `InitialPointsGenerator` +- `InitialPointsGenerator_3` - `MeshCellBase_3` - `MeshVertexBase_3` - `MeshDomainField_3` diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 5ef09bb565e..b7e3b8cfad7 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -27,7 +27,7 @@ namespace CGAL * \ingroup PkgMesh3Initializers * * Functor for generating initial points in gray images. - * This functor is a model of the `InitialPointsGenerator` concept, + * This functor is a model of the `InitialPointsGenerator_3` concept, * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * @@ -37,7 +37,7 @@ namespace CGAL * to initialize them all. Each connected component is guaranteed to be * represented by at least one cell of the triangulation. * - * \cgalModels{InitialPointsGenerator} + * \cgalModels{InitialPointsGenerator_3} * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index caf5d0fe63f..60ea8523258 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -74,7 +74,7 @@ struct Get_point * \ingroup PkgMesh3Initializers * * Functor for generating initial points in labeled images. - * This functor is a model of the `InitialPointsGenerator` concept, + * This functor is a model of the `InitialPointsGenerator_3` concept, * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * @@ -85,7 +85,7 @@ struct Get_point * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` * @tparam MeshDomain model of `MeshDomain_3` * - * \cgalModels{InitialPointsGenerator} + * \cgalModels{InitialPointsGenerator_3} * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 68e5534096e..a2ead361ee6 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -538,7 +538,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false> * \cgalParamDefault{`parameters::exude()`} * \cgalParamSectionEnd * \cgalParamSectionBegin{Mesh initialization with a functor} - * \cgalParamDescription{an `InitialPointsGenerator` can optionally be provided to start the meshing process. + * \cgalParamDescription{an `InitialPointsGenerator_3` can optionally be provided to start the meshing process. * The following named parameter controls this option: *
      *
    • `parameters::initial_points_generator()` From 249612270767e37a9062ed5cce0240af1cde9ebe Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 Dec 2024 12:20:27 +0100 Subject: [PATCH 89/99] fix missing fix --- .../CGAL/Mesh_3/internal/tuple_like_helpers.h | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h b/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h new file mode 100644 index 00000000000..22eebb94f98 --- /dev/null +++ b/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h @@ -0,0 +1,35 @@ +// Copyright (c) 2024 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Laurent Rineau + +#ifndef CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H +#define CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H + +#include + +#include +#include + +namespace CGAL::Mesh_3::internal { + + template + constexpr bool has_tuple_size_v = false; + + template + constexpr bool has_tuple_size_v::value)>> = true; + + template > + constexpr bool tuple_like_of_size_2 = false; + + template + constexpr bool tuple_like_of_size_2 = (std::tuple_size_v == 2); + +} // end namespace CGAL::Mesh_3::internal + +#endif // CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H From 7f4e5b7e84ac4b649fb6d3ab496751788406104d Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 12:45:29 +0100 Subject: [PATCH 90/99] make doc more clear --- .../mesh_3D_image_with_image_initialization.cpp | 3 ++- .../Construct_initial_points_labeled_image.h | 16 +++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index aff744355fb..e90af4e9868 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -47,7 +47,8 @@ int main() .cell_radius_edge_ratio(3).cell_size(3)); /// [Meshing] - // Mesh generation with a custom initialization that places points in each of the image components. + // Mesh generation with a custom initialization that places points + // on the surface of each connected component of the image. CGAL::Construct_initial_points_labeled_image img_pts_generator(image, domain); C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 60ea8523258..e4819813c8d 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -78,9 +78,12 @@ struct Get_point * and can be passed as a parameter to `CGAL::make_mesh_3` using the * `CGAL::parameters::initial_points_generator()` parameter function. * - * On images that contain multiple non-connected components, - * this functor scans the complete image and - * outputs points to initialize each component. + * This functor scans the complete image to detect all its connected components, + * and constructs points on the surface of each of them. + * Its goal is to initialize each component, each of them corresponding + * to a subdomain. + * It ensures that each component will be initialized, i.e. represented + * by at least one cell of the triangulation. * * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` * @tparam MeshDomain model of `MeshDomain_3` @@ -104,11 +107,7 @@ struct Construct_initial_points_labeled_image { } /*! - * \brief constructs at least `n` initial points, - * by scanning the image and - * collecting points in each object in the image, - * even if they are non-connected components. - * This ensures that each component will be initialized. + * \brief constructs at least `n` initial points. * * @tparam OutputIterator model of `OutputIterator` for * tuple-like objects containing @@ -131,7 +130,6 @@ struct Construct_initial_points_labeled_image * - a `Weighted_point_3` for the point * - an `int` for the minimal dimension of the subcomplexes on which the point lies * - a `MeshDomain::Index` for the corresponding subcomplex index - * @tparam MeshDomain model of `MeshDomain_3` * @tparam TransformOperator functor that transforms values of the image. * It must provide the following type:
      * `result_type`: a type that supports the '==' operator
      From 1a4cc658f361b1ef17c567632b8e73d07e26817b Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 16:53:49 +0100 Subject: [PATCH 91/99] wip apply Laurent's reviews --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 3 ++- .../Mesh_3/mesh_3D_image_with_image_initialization.cpp | 6 ++++-- .../CGAL/Mesh_3/Construct_initial_points_gray_image.h | 3 +++ .../CGAL/Mesh_3/Construct_initial_points_labeled_image.h | 9 ++++----- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index a5d349e5ed7..3a834536db6 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -491,7 +491,8 @@ unspecified_type initial_points_generator(const InitialPointsGenerator& generato * \ingroup PkgMesh3Parameters * * The function `parameters::initial_points()` enables the user to specify a container, model of `Range`, that contains - * initial points to be used in the `make_mesh_3()` function for mesh generation. Items in the container are + * initial points constructed on surfaces, + * to be used in the `make_mesh_3()` function for mesh generation. Items in the container are * tuple-like objects containing a `Weighted_point_3`, an `int`, and a `MeshDomain::Index`, * where `Weighted_point_3` represents the position and the weight of the point, * `int` the dimension of the minimal subcomplex on which the point lies, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index e90af4e9868..1117c2ed351 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -56,7 +56,9 @@ int main() /// [Meshing] // Output - CGAL::dump_c3t3(c3t3, "out"); + std::ofstream medit_file("out.mesh"); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index b7e3b8cfad7..83e9896ec27 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -51,6 +51,9 @@ struct Construct_initial_points_gray_image const typename MeshDomain::R::FT iso_value_; Functor image_values_to_subdomain_indices_; + /*! + * @todo + */ Construct_initial_points_gray_image(const CGAL::Image_3 & image, const MeshDomain& domain, const double iso_value, diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index e4819813c8d..79982147582 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -100,6 +100,9 @@ struct Construct_initial_points_labeled_image const CGAL::Image_3& image_; const MeshDomain& domain_; + /*! + * @todo + */ Construct_initial_points_labeled_image(const CGAL::Image_3& image, const MeshDomain& domain) : image_(image) @@ -122,7 +125,7 @@ struct Construct_initial_points_labeled_image return pts; } - /*! + /* //internal undocumented * \brief Same as above, but a `TransformOperator` that transforms values of the image is used. * * @tparam OutputIterator model of `OutputIterator` for @@ -306,9 +309,6 @@ struct Construct_initial_points_labeled_image continue; // insert point in temporary triangulation - - /// The following lines show how to insert initial points in the - /// `c3t3` object. [insert initial points] Vertex_handle v = tr.insert(pi); // `v` could be null if `pi` is hidden by other vertices of `tr`. @@ -316,7 +316,6 @@ struct Construct_initial_points_labeled_image c3t3.set_dimension(v, 2); // by construction, points are on surface c3t3.set_index(v, intersect_index); - /// [insert initial points] *pts++ = std::make_pair(pi, intersect_index); // dimension 2 by construction, points are on surface } From 2ed54dfa3a23190a10588d29bef4bff27f267a27 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 17:17:30 +0100 Subject: [PATCH 92/99] add constructors documentation --- .../Construct_initial_points_gray_image.h | 21 ++++++++++++++++--- .../Construct_initial_points_labeled_image.h | 4 +++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h index 83e9896ec27..6dd6c4a3c9c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_gray_image.h @@ -39,6 +39,12 @@ namespace CGAL * * \cgalModels{InitialPointsGenerator_3} * + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * @tparam MeshDomain model of `MeshDomain_3` + * @tparam Functor a function object that takes the number type in which the image is encoded, + * and returns the `MeshDomain::Index` of the corresponding subcomplex index. + * The default type is `CGAL::Null_functor`. + * * \sa `CGAL::parameters::initial_points_generator()` * \sa `CGAL::make_mesh_3()` * \sa `CGAL::Construct_initial_points_labeled_image` @@ -52,7 +58,16 @@ struct Construct_initial_points_gray_image Functor image_values_to_subdomain_indices_; /*! - * @todo + * Constructs a functor for generating initial points in gray images. + * @param image the gray image that defines the mesh domain + * @param domain the mesh domain + * @param iso_value the iso value corresponding to the surface of the domain + * @param image_values_to_subdomain_indices a function object that takes + * the number type in which `image` is encoded, + * and returns the corresponding `MeshDomain::Index`. + * The default functor is `CGAL::Null_functor` + * and corresponds to meshing the areas where the image values are + * greater than `iso_value`. */ Construct_initial_points_gray_image(const CGAL::Image_3 & image, const MeshDomain& domain, @@ -75,8 +90,8 @@ struct Construct_initial_points_gray_image * - a `Weighted_point_3` for the point * - an `int` for the minimal dimension of the subcomplexes on which the point lies * - a `MeshDomain::Index` for the corresponding subcomplex index - * \tparam MeshDomain model of `MeshDomain_3` - * \tparam C3t3 model of `MeshComplex_3InTriangulation_3` + * @tparam MeshDomain model of `MeshDomain_3` + * @tparam C3t3 model of `MeshComplex_3InTriangulation_3` * */ template diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index 79982147582..ac79ecce0b6 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -101,7 +101,9 @@ struct Construct_initial_points_labeled_image const MeshDomain& domain_; /*! - * @todo + * Constructs a functor for generating initial points in labeled images. + * @param image the labeled image that defines the mesh domain + * @param domain the mesh domain */ Construct_initial_points_labeled_image(const CGAL::Image_3& image, const MeshDomain& domain) From 84e55c39821cef6b2f35228786cabefdc6e12a15 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 17:23:57 +0100 Subject: [PATCH 93/99] fix include --- Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h b/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h index 22eebb94f98..d88bf624a0e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h @@ -14,7 +14,7 @@ #include #include -#include +#include namespace CGAL::Mesh_3::internal { From a98101aa75c90dfa0f09a464b39b1e90d333d9e9 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 17:38:14 +0100 Subject: [PATCH 94/99] move tuple_like_helpers.h to STL_Extension to avoid dependency on Mesh_3 --- .../include/CGAL/STL_Extension/internal/mesh_option_classes.h | 4 ++-- .../include/CGAL/STL_Extension}/internal/tuple_like_helpers.h | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename {Mesh_3/include/CGAL/Mesh_3 => STL_Extension/include/CGAL/STL_Extension}/internal/tuple_like_helpers.h (100%) 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 fe7e7d75287..10611ef80bd 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 @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include @@ -233,7 +233,7 @@ struct Initialization_options void operator()(Tuple_like&& p) const { using Tuple_like_no_cvref = CGAL::cpp20::remove_cvref_t; - if constexpr (CGAL::Mesh_3::internal::tuple_like_of_size_2) { + if constexpr (CGAL::STL_Extension::internal::tuple_like_of_size_2) { const auto& [pt, index] = p; call_(f_, Default_initial_point_type(pt, 2, index)); } else if constexpr (std::is_same_v) { diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h b/STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h similarity index 100% rename from Mesh_3/include/CGAL/Mesh_3/internal/tuple_like_helpers.h rename to STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h From 7e3aa09f2a1a3b5bdfc15503563030a2972ad387 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 19 Dec 2024 22:03:28 +0100 Subject: [PATCH 95/99] complete move file --- Mesh_3/include/CGAL/make_mesh_3.h | 4 ++-- .../CGAL/STL_Extension/internal/tuple_like_helpers.h | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index a2ead361ee6..4350b92faff 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -55,7 +55,7 @@ struct Push_to_initial_point { template void operator()(const Initial_point_and_info& initial_pt) const { using T = CGAL::cpp20::remove_cvref_t; - if constexpr (tuple_like_of_size_2) + if constexpr (CGAL::STL_Extension::internal::tuple_like_of_size_2) { const auto& [pt, index] = initial_pt; const auto& cwp = c3t3_ptr->triangulation().geom_traits().construct_weighted_point_3_object(); diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h b/STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h index d88bf624a0e..de9cc33c7eb 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/tuple_like_helpers.h @@ -8,15 +8,13 @@ // // Author(s) : Laurent Rineau -#ifndef CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H -#define CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H - -#include +#ifndef CGAL_STL_EXTENSION_INTERNAL_TUPLE_LIKE_HELPERS_H +#define CGAL_STL_EXTENSION_INTERNAL_TUPLE_LIKE_HELPERS_H #include #include -namespace CGAL::Mesh_3::internal { +namespace CGAL::STL_Extension::internal { template constexpr bool has_tuple_size_v = false; @@ -30,6 +28,6 @@ namespace CGAL::Mesh_3::internal { template constexpr bool tuple_like_of_size_2 = (std::tuple_size_v == 2); -} // end namespace CGAL::Mesh_3::internal +} // end namespace CGAL::STL_Extension::internal -#endif // CGAL_MESH_3_INTERNAL_TUPLE_LIKE_HELPERS_H +#endif // CGAL_STL_EXTENSION_INTERNAL_TUPLE_LIKE_HELPERS_H From bc64faaab31fd059deb6d45ba797138720ec1a1c Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 17 Jan 2025 16:22:24 +0100 Subject: [PATCH 96/99] Laurent's review --- Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h | 2 +- Mesh_3/doc/Mesh_3/Mesh_3.txt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h index 3a834536db6..018449f3585 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_3/parameters.h @@ -457,7 +457,7 @@ unspecified_type perturb(const Named_function_parameters& np = parameters::defau * The function `parameters::initial_points_generator()` enables the user to specify a functor that follows * the `InitialPointsGenerator_3` concept to the mesh generation function `make_mesh_3()`. This functor is called * for the initialization of the meshing process, by inserting well-distributed surface vertices. - * If this parameter is specified without arguments, the default behavior + * If this parameter is not specified, the default behavior * is executed, which calls the domain's `construct_initial_points_object()` for the initialization of the meshing process. * * Initialization is considered to be complete if the triangulation is a 3D triangulation diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 73fc0b179f2..77afe7fd7ea 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -757,8 +757,9 @@ First, the functor `construct_intersection` is created: then the `%Mesh_domain::Intersection` object (a `%tuple` with three elements) is constructed using a call to the functor `construct_intersection` \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h use construct intersection -and eventually `%index` is the element \#1 of `%intersect`. -\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection +and eventually `%intersect_index` is the element \#1 of `%intersect`. +\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection. +The dimension of the underlying simplex is stored as the element \#2 of `%intersect``. The result of the custom initialization can be seen in \cgalFigureRef{mesh3custominitimage3D}. The generated 3D image contains a From c161fc1ccf10e78b378b6e6770056d05d95e7c52 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 20 Jan 2025 09:48:53 +0100 Subject: [PATCH 97/99] with the point, snippet can't be found --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 77afe7fd7ea..f78d9a28a3f 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -758,7 +758,8 @@ then the `%Mesh_domain::Intersection` object (a `%tuple` with three elements) is constructed using a call to the functor `construct_intersection` \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h use construct intersection and eventually `%intersect_index` is the element \#1 of `%intersect`. -\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection. +\snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection +. The dimension of the underlying simplex is stored as the element \#2 of `%intersect``. The result of the custom initialization can be seen in From 19502356539ec7d35541244683934286d7e7dee2 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 20 Jan 2025 16:28:36 +0100 Subject: [PATCH 98/99] remove extra point --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index f78d9a28a3f..5365c9143a9 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -759,7 +759,6 @@ elements) is constructed using a call to the functor `construct_intersection` \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h use construct intersection and eventually `%intersect_index` is the element \#1 of `%intersect`. \snippet CGAL/Mesh_3/Construct_initial_points_labeled_image.h get construct intersection -. The dimension of the underlying simplex is stored as the element \#2 of `%intersect``. The result of the custom initialization can be seen in From 1d6e3056b76946f584259c86690f27586ddcbafb Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 20 Jan 2025 16:56:58 +0100 Subject: [PATCH 99/99] typo --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index 5365c9143a9..7de626783d4 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -801,7 +801,7 @@ a custom functor that initializes the triangulation. A struct `Custom_Initial_points_generator` that places 1D-feature points alongside a line is created. -Finally, the exemple \ref Mesh_3/mesh_3D_image_with_initial_points.cpp features +Finally, the example \ref Mesh_3/mesh_3D_image_with_initial_points.cpp features a point container that initializes the triangulation using the meshing parameter `parameters::initial_points()`.