diff --git a/Mesh_3/doc/Mesh_3/CGAL/lloyd_optimize_mesh_3.h b/Mesh_3/doc/Mesh_3/CGAL/lloyd_optimize_mesh_3.h deleted file mode 100644 index b891d23810f..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/lloyd_optimize_mesh_3.h +++ /dev/null @@ -1,116 +0,0 @@ -namespace CGAL { - -/*! -\ingroup PkgMesh3Functions - -The function `lloyd_optimize_mesh_3()` is a mesh optimization process -based on the minimization of a global energy function. - -In `lloyd_optimize_mesh_3()`, the minimized global energy may be interpreted -as the \f$ L^1\f$-norm of the error achieved -when the function \f$ x^2\f$ is interpolated on the mesh domain -using a piecewise linear function which is linear -in each cell of the Voronoi diagram of the mesh vertices. - -The optimizer `lloyd_optimize_mesh_3()` works in iterative steps. -At each iteration, mesh vertices are moved into -positions that bring to zero the energy gradient -and the Delaunay triangulation is updated. -Vertices on the mesh boundaries are handled -in a special way so as to preserve an accurate -representation of the domain boundaries. - -\pre `time_limit` \f$ \geq\f$ 0 and 0 \f$ \leq\f$ `convergence` \f$ \leq\f$ 1 and 0 \f$ \leq\f$ `freeze_bound` \f$ \leq\f$ 1 - -\tparam C3T3 is required to be a model of the concept -`MeshComplex_3InTriangulation_3`. -The argument `c3t3`, passed by -reference, provides the initial mesh -and is modified by the algorithm -to represent the final optimized mesh. - -\tparam MD is required to be a model of the concept -`MeshDomain_3`. The argument `domain` must be the `MD` -object used to create the `c3t3` parameter. - -The function has four optional parameters which are named parameters (we use the Boost.Parameter library). -Therefore, when calling the function, the parameters can be provided in any order -provided that the names of the parameters are used -(see example at the bottom of this page). - -\cgalHeading{Named Parameters} - -- `parameters::time_limit` -is used to set up, in seconds, -a CPU time limit after which the optimization process is stopped. This time is -measured using `Real_timer`. -The default value is 0 and means that there is no time limit. - -- `parameters::%max_iteration_number` sets a limit on the -number of performed iterations. The default value of 0 means that there is -no limit on the number of performed iterations. - -- `parameters::%convergence` is a stopping criterion based on convergence: -the optimization process is stopped, when at the last iteration, -the displacement of any vertex is less than a given percentage of the -length of the shortest edge incident to that vertex. -The parameter `convergence` gives the threshold ratio. - -- `parameters::freeze_bound` is designed to reduce running time of each optimization iteration. Any vertex -that has a displacement less than a given percentage of the length (the of its shortest incident edge, is frozen (i.e.\ is -not relocated). The parameter `freeze_bound` gives the threshold ratio. - -- `parameters::do_freeze` completes the `freeze_bound` parameter. If it is set to `true` (default value), -frozen vertices will not move anymore in next iterations. Otherwise, at each iteration, any vertex that -moves, unfreezes all its incident vertices. - - -\return -The function `lloyd_optimize_mesh_3()` returns a value of type `CGAL::Mesh_optimization_return_code` -which is: - - -\cgalHeading{Example} - - -\code{.cpp} -// Lloyd-smoothing until convergence reaches 0.01, freezing vertices which -// move less than 0.001*shortest_incident_edge_length -lloyd_optimize_mesh_3(c3t3, - domain, - parameters::convergence=0.01, - parameters::freeze_bound=0.001, - parameters::do_freeze=true); - -\endcode - -\sa `CGAL::Mesh_optimization_return_code` -\sa `CGAL::make_mesh_3()` -\sa `CGAL::refine_mesh_3()` -\sa `CGAL::exude_mesh_3()` -\sa `CGAL::perturb_mesh_3()` -\sa `CGAL::odt_optimize_mesh_3()` - -\note This function requires the \ref thirdpartyEigen library. -*/ - -template -Mesh_optimization_return_code -lloyd_optimize_mesh_3(C3T3& c3t3, - const MD& domain, - double parameters::time_limit=0, - std::size_t parameters::max_iteration_number=0, - double parameters::convergence=0.02, - double parameters::freeze_bound = 0.01, - bool parameters::do_freeze=true); - -} /* namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/Doxyfile.in b/Mesh_3/doc/Mesh_3/Doxyfile.in index e0a38426b13..307e18392de 100644 --- a/Mesh_3/doc/Mesh_3/Doxyfile.in +++ b/Mesh_3/doc/Mesh_3/Doxyfile.in @@ -8,7 +8,8 @@ INPUT += \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_domain_with_polyline_features_3.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/generate_label_weights.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/exude_mesh_3.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/odt_optimize_mesh_3.h + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/odt_optimize_mesh_3.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/lloyd_optimize_mesh_3.h PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Mesh Generation" HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \ ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_4.jpg \ diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp index fd114c63866..3fa00ebf9aa 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp @@ -54,8 +54,8 @@ int main(int argc, char*argv[]) C3t3 c3t3_bis = CGAL::make_mesh_3(domain, criteria, no_perturb(), no_exude()); - CGAL::lloyd_optimize_mesh_3(c3t3_bis, domain, time_limit=30); - CGAL::exude_mesh_3(c3t3_bis, CGAL::parameters::sliver_bound_new=10, CGAL::parameters::time_limit_new=10); + CGAL::lloyd_optimize_mesh_3(c3t3_bis, domain, time_limit_new=30); + CGAL::exude_mesh_3(c3t3_bis, sliver_bound_new=10, time_limit_new=10); // Output std::ofstream medit_file("out.mesh"); diff --git a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h index 8b3ec746e76..2726c9b92d9 100644 --- a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h @@ -21,7 +21,7 @@ #include -#include +#include #include #include #include @@ -29,44 +29,146 @@ #include #include -#include namespace CGAL { +/*! +\ingroup PkgMesh3Functions -#if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4003) // not enough actual parameters for macro -#endif +The function `lloyd_optimize_mesh_3()` is a mesh optimization process +based on the minimization of a global energy function. -// see -CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +In `lloyd_optimize_mesh_3()`, the minimized global energy may be interpreted +as the \f$ L^1\f$-norm of the error achieved +when the function \f$ x^2\f$ is interpolated on the mesh domain +using a piecewise linear function which is linear +in each cell of the Voronoi diagram of the mesh vertices. -BOOST_PARAMETER_FUNCTION( - (Mesh_optimization_return_code), - lloyd_optimize_mesh_3, - parameters::tag, - (required (in_out(c3t3),*) (domain,*) ) - (optional - (time_limit_, *, 0 ) - (max_iteration_number_, *, 0 ) - (convergence_, *, parameters::default_values_for_mesh_3::lloyd_convergence_ratio ) - (freeze_bound_, *, parameters::default_values_for_mesh_3::lloyd_freeze_ratio ) - (do_freeze_, *, parameters::default_values_for_mesh_3::do_freeze )) -) +The optimizer `lloyd_optimize_mesh_3()` works in iterative steps. +At each iteration, mesh vertices are moved into +positions that bring to zero the energy gradient +and the Delaunay triangulation is updated. +Vertices on the mesh boundaries are handled +in a special way so as to preserve an accurate +representation of the domain boundaries. + +\pre `time_limit` \f$ \geq\f$ 0 and 0 \f$ \leq\f$ `convergence` \f$ \leq\f$ 1 and 0 \f$ \leq\f$ `freeze_bound` \f$ \leq\f$ 1 + +\tparam C3T3 is required to be a model of the concept +`MeshComplex_3InTriangulation_3`. +The argument `c3t3`, passed by +reference, provides the initial mesh +and is modified by the algorithm +to represent the final optimized mesh. + +\tparam MD is required to be a model of the concept +`MeshDomain_3`. The argument `domain` must be the `MD` +object used to create the `c3t3` parameter. + +\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + +@param cdt the initial mesh that will be modified by the algorithm to represent the final optimized mesh. +@param domain ... +@param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below: + +\cgalNamedParamsBegin + \cgalParamNBegin{time_limit_new} + \cgalParamDescription{to set up, in seconds, a CPU time limit after which the optimization process is stopped. + This time is measured using `CGAL::Real_timer`. 0 means that there is no time limit.} + \cgalParamType{`double`} + \cgalParamExtra{\pre `time_limit_new` \f$ \geq\f$ 0} + \cgalParamDefault{0} + + \cgalParamNBegin{max_iteration_number_new} + \cgalParamDescription{limit on the number of performed iterations. 0 means that there is + no limit on the number of performed iterations.} + \cgalParamExtra{\pre `max_iteration_number >=0`} + \cgalParamType{`int`} + \cgalParamDefault{0} + + + \cgalParamNBegin{freeze_bound_new} + \cgalParamDescription{designed to reduce running time of each optimization iteration. + Any vertex that has a displacement less than a given fraction of the length + of its shortest incident edge, is frozen (i.e.\ is not relocated). + The parameter `freeze_bound` gives the threshold ratio. + If it is set to 0, freezing of vertices is disabled.} + \cgalParamExtra{\pre `0<= freeze_bound <=1} + \cgalParamType{`double`} + \cgalParamDefault{0.001} + + \cgalParamNBegin{convergence_new} + \cgalParamDescription{threshold ratio of stopping criterion based on convergence: the optimization process is stopped + when at the last iteration the displacement of any vertex is less than + a given fraction of the length of the shortest edge incident to that vertex.} + \cgalParamExtra{\pre `0 <=convergence <= 1`} + \cgalParamType{`double`} + \cgalParamDefault{0.001} + + \cgalParamNBegin{do_freeze_new} + \cgalParamDescription{completes the `freeze_bound` parameter. If it is set to `true` (default value), + frozen vertices will not move anymore in next iterations. Otherwise, at each iteration, any vertex that + moves, unfreezes all its incident vertices.} + \cgalParamType{`bool`} + \cgalParamDefault{true} + +\cgalNamedParamsEnd +\return +The function `lloyd_optimize_mesh_3()` returns a value of type `CGAL::Mesh_optimization_return_code` +which is: +
    +
  • `CGAL::TIME_LIMIT_REACHED` when the time limit is reached. +
  • `CGAL::MAX_ITERATION_NUMBER_REACHED` when `lloyd_optimize_mesh_3()` stops because it has performed `max_iteration_number` iterations. +
  • `CGAL::CONVERGENCE_REACHED` when `lloyd_optimize_mesh_3()` stops because the convergence criterion +is achieved. +
  • `CGAL::ALL_VERTICES_FROZEN` when all vertices have been frozen, when the +`do_freeze` parameter is set to true. +
  • `CGAL::CANT_IMPROVE_ANYMORE` when `lloyd_optimize_mesh_3()` stops because +most vertices have been frozen, and no better convergence can be reached. +
+ +\cgalHeading{Example} + + +\code{.cpp} +// Lloyd-smoothing until convergence reaches 0.01, freezing vertices which +// move less than 0.001*shortest_incident_edge_length +lloyd_optimize_mesh_3(c3t3, + domain, + parameters::convergence=0.01, + parameters::freeze_bound=0.001, + parameters::do_freeze=true); + +\endcode + +\sa `CGAL::Mesh_optimization_return_code` +\sa `CGAL::make_mesh_3()` +\sa `CGAL::refine_mesh_3()` +\sa `CGAL::exude_mesh_3()` +\sa `CGAL::perturb_mesh_3()` +\sa `CGAL::odt_optimize_mesh_3()` + +\note This function requires the \ref thirdpartyEigen library. +*/ +template +Mesh_optimization_return_code lloyd_optimize_mesh_3(C3T3& c3t3, MeshDomain& domain,const CGAL_NP_CLASS& np = parameters::default_values()) { - return lloyd_optimize_mesh_3_impl(c3t3, domain, - time_limit_, max_iteration_number_, - convergence_, freeze_bound_ - , do_freeze_); + using parameters::choose_parameter; + using parameters::get_parameter; + int max_iterations = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 0); + const double convergence_ratio = choose_parameter(get_parameter(np, internal_np::convergence_ratio), 0.001); + const double freeze_bound = choose_parameter(get_parameter(np, internal_np::vertex_freeze_bound), 0.001); + const double time_limit = choose_parameter(get_parameter(np, internal_np::maximum_running_time), 0.); + bool do_freeze = choose_parameter(get_parameter(np,internal_np::freeze),true); + return lloyd_optimize_mesh_3_impl(c3t3, domain, time_limit, max_iterations, convergence_ratio, freeze_bound, do_freeze); } -CGAL_PRAGMA_DIAG_POP - -#if defined(BOOST_MSVC) -# pragma warning(pop) -#endif - +#ifndef DOXYGEN_RUNNING +#ifndef CGAL_NO_DEPRECATED_CODE +template +Mesh_optimization_return_code lloyd_optimize_mesh_3(C3T3& c3t3,MeshDomain& domain, const NP_PACK& ...nps) +{ + return lloyd_optimize_mesh_3(c3t3,domain, internal_np::combine_named_parameters(nps...)); +} +#endif //CGAL_NO_DEPRECATED_CODE template Mesh_optimization_return_code @@ -106,10 +208,127 @@ lloyd_optimize_mesh_3_impl(C3T3& c3t3, // Launch optimization return opt(static_cast(max_iteration_number)); } +#else +namespace CGAL { +/*! +\ingroup PkgMesh3Functions +\deprecated This function is deprecated since \cgal 5.5, the overload using `NamedParameters` must be used instead. + +The function `lloyd_optimize_mesh_3()` is a mesh optimization process +based on the minimization of a global energy function. + +In `lloyd_optimize_mesh_3()`, the minimized global energy may be interpreted +as the \f$ L^1\f$-norm of the error achieved +when the function \f$ x^2\f$ is interpolated on the mesh domain +using a piecewise linear function which is linear +in each cell of the Voronoi diagram of the mesh vertices. + +The optimizer `lloyd_optimize_mesh_3()` works in iterative steps. +At each iteration, mesh vertices are moved into +positions that bring to zero the energy gradient +and the Delaunay triangulation is updated. +Vertices on the mesh boundaries are handled +in a special way so as to preserve an accurate +representation of the domain boundaries. + +\pre `time_limit` \f$ \geq\f$ 0 and 0 \f$ \leq\f$ `convergence` \f$ \leq\f$ 1 and 0 \f$ \leq\f$ `freeze_bound` \f$ \leq\f$ 1 + +\tparam C3T3 is required to be a model of the concept +`MeshComplex_3InTriangulation_3`. +The argument `c3t3`, passed by +reference, provides the initial mesh +and is modified by the algorithm +to represent the final optimized mesh. + +\tparam MD is required to be a model of the concept +`MeshDomain_3`. The argument `domain` must be the `MD` +object used to create the `c3t3` parameter. + +The function has four optional parameters which are named parameters (we use the Boost.Parameter library). +Therefore, when calling the function, the parameters can be provided in any order +provided that the names of the parameters are used +(see example at the bottom of this page). + +\cgalHeading{Named Parameters} + +- `parameters::time_limit` +is used to set up, in seconds, +a CPU time limit after which the optimization process is stopped. This time is +measured using `Real_timer`. +The default value is 0 and means that there is no time limit. + +- `parameters::%max_iteration_number` sets a limit on the +number of performed iterations. The default value of 0 means that there is +no limit on the number of performed iterations. + +- `parameters::%convergence` is a stopping criterion based on convergence: +the optimization process is stopped, when at the last iteration, +the displacement of any vertex is less than a given percentage of the +length of the shortest edge incident to that vertex. +The parameter `convergence` gives the threshold ratio. + +- `parameters::freeze_bound` is designed to reduce running time of each optimization iteration. Any vertex +that has a displacement less than a given percentage of the length (the of its shortest incident edge, is frozen (i.e.\ is +not relocated). The parameter `freeze_bound` gives the threshold ratio. + +- `parameters::do_freeze` completes the `freeze_bound` parameter. If it is set to `true` (default value), +frozen vertices will not move anymore in next iterations. Otherwise, at each iteration, any vertex that +moves, unfreezes all its incident vertices. + + +\return +The function `lloyd_optimize_mesh_3()` returns a value of type `CGAL::Mesh_optimization_return_code` +which is: +
    +
  • `CGAL::TIME_LIMIT_REACHED` when the time limit is reached. +
  • `CGAL::MAX_ITERATION_NUMBER_REACHED` when `lloyd_optimize_mesh_3()` stops because it has performed `max_iteration_number` iterations. +
  • `CGAL::CONVERGENCE_REACHED` when `lloyd_optimize_mesh_3()` stops because the convergence criterion +is achieved. +
  • `CGAL::ALL_VERTICES_FROZEN` when all vertices have been frozen, when the +`do_freeze` parameter is set to true. +
  • `CGAL::CANT_IMPROVE_ANYMORE` when `lloyd_optimize_mesh_3()` stops because +most vertices have been frozen, and no better convergence can be reached. +
+ +\cgalHeading{Example} + + +\code{.cpp} +// Lloyd-smoothing until convergence reaches 0.01, freezing vertices which +// move less than 0.001*shortest_incident_edge_length +lloyd_optimize_mesh_3(c3t3, + domain, + parameters::convergence=0.01, + parameters::freeze_bound=0.001, + parameters::do_freeze=true); + +\endcode + +\sa `CGAL::Mesh_optimization_return_code` +\sa `CGAL::make_mesh_3()` +\sa `CGAL::refine_mesh_3()` +\sa `CGAL::exude_mesh_3()` +\sa `CGAL::perturb_mesh_3()` +\sa `CGAL::odt_optimize_mesh_3()` + +\note This function requires the \ref thirdpartyEigen library. +*/ + +template +Mesh_optimization_return_code +lloyd_optimize_mesh_3(C3T3& c3t3, + const MD& domain, + double parameters::time_limit=0, + std::size_t parameters::max_iteration_number=0, + double parameters::convergence=0.02, + double parameters::freeze_bound = 0.01, + bool parameters::do_freeze=true); + +} /* namespace CGAL */ + +#endif //DOXYGEN_RUNNING } // end namespace CGAL -#include - #endif // CGAL_LLOYD_OPTIMIZE_MESH_3_H diff --git a/Mesh_3/include/CGAL/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h index b2d307db86e..cc441aba124 100644 --- a/Mesh_3/include/CGAL/refine_mesh_3.h +++ b/Mesh_3/include/CGAL/refine_mesh_3.h @@ -578,10 +578,10 @@ void refine_mesh_3_impl(C3T3& c3t3, { lloyd_optimize_mesh_3(c3t3, domain, - parameters::time_limit = lloyd.time_limit(), - parameters::max_iteration_number = lloyd.max_iteration_number(), - parameters::convergence = lloyd.convergence(), - parameters::freeze_bound = lloyd.bound()); + parameters::time_limit_new = lloyd.time_limit(), + parameters::max_iteration_number_new = lloyd.max_iteration_number(), + parameters::convergence_new = lloyd.convergence(), + parameters::freeze_bound_new = lloyd.bound()); } if( odt || lloyd) { diff --git a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp index bb29b2d383c..068a3e495bc 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp @@ -87,7 +87,7 @@ void test() oss.clear(); //LLOYD (1) - CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd); + CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number_new = nb_lloyd); c3t3.output_to_medit(oss); output_c3t3.push_back(oss.str());//[i*5+1] oss.clear(); diff --git a/Mesh_3/test/Mesh_3/test_meshing_utilities.h b/Mesh_3/test/Mesh_3/test_meshing_utilities.h index e9a2878ffe2..159bd61f160 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_utilities.h +++ b/Mesh_3/test/Mesh_3/test_meshing_utilities.h @@ -184,8 +184,8 @@ struct Tester // Vertex number should not change (obvious) C3t3 lloyd_c3t3(c3t3); std::cerr << "Lloyd...\n"; - CGAL::lloyd_optimize_mesh_3(lloyd_c3t3, domain, CGAL::parameters::time_limit=5, - CGAL::parameters::convergence=0.001, CGAL::parameters::freeze_bound=0.0005); + CGAL::lloyd_optimize_mesh_3(lloyd_c3t3, domain, CGAL::parameters::time_limit_new=5, + CGAL::parameters::convergence_new=0.001, CGAL::parameters::freeze_bound_new=0.0005); verify_c3t3(lloyd_c3t3,domain,domain_type,v,v); verify_c3t3_volume(lloyd_c3t3, volume*0.95, volume*1.05); verify_c3t3_hausdorff_distance(lloyd_c3t3, domain, domain_type, hdist);