From fb898e9ab1b76897f30cae73b5c1d2adc0f44c3d Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 13 Jun 2025 14:30:05 +0200 Subject: [PATCH] remove return_empty_on_invalid_input and show in an example how to check preconditions --- .../ccdt_3_check_preconditions.cpp | 57 +++++++++++++++++-- ...ing_constrained_Delaunay_triangulation_3.h | 21 ------- ...ing_constrained_Delaunay_triangulation_3.h | 27 ++------- .../internal/parameters_interface.h | 3 - 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/Constrained_triangulation_3/examples/Constrained_triangulation_3/ccdt_3_check_preconditions.cpp b/Constrained_triangulation_3/examples/Constrained_triangulation_3/ccdt_3_check_preconditions.cpp index 5d1daff7d42..d7bf6c54402 100644 --- a/Constrained_triangulation_3/examples/Constrained_triangulation_3/ccdt_3_check_preconditions.cpp +++ b/Constrained_triangulation_3/examples/Constrained_triangulation_3/ccdt_3_check_preconditions.cpp @@ -1,11 +1,18 @@ #include -#include -#include #include +#include +#include +#include +#include + #include #include +#include +#include + +#include using K = CGAL::Exact_predicates_inexact_constructions_kernel; using Point = K::Point_3; @@ -13,13 +20,36 @@ using Surface_mesh = CGAL::Surface_mesh; namespace PMP = CGAL::Polygon_mesh_processing; +// Function to verify preconditions for a mesh input +bool verify_preconditions_mesh(const Surface_mesh& mesh) +{ + if(CGAL::is_triangle_mesh(mesh)) + return !CGAL::Polygon_mesh_processing::does_self_intersect(mesh); + + Surface_mesh triangle_mesh; + CGAL::copy_face_graph(mesh, triangle_mesh); + bool tri_ok = CGAL::Polygon_mesh_processing::triangulate_faces(triangle_mesh); + if(!tri_ok) + return false; + + return !CGAL::Polygon_mesh_processing::does_self_intersect(triangle_mesh); +} + +// Function to verify preconditions for a polygon soup input +template +bool verify_preconditions_soup(const PointRange& points, const PolygonRange& polygons) +{ + return !CGAL::Polygon_mesh_processing::does_polygon_soup_self_intersect(points, polygons); +} + int main(int argc, char* argv[]) { const auto filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/mpi_and_sphere.off"); CGAL::Surface_mesh mesh; - if(!CGAL::IO::read_polygon_mesh(filename, mesh)) { + if(!CGAL::IO::read_polygon_mesh(filename, mesh)) + { std::cerr << "Error: cannot read file " << filename << std::endl; return EXIT_FAILURE; } @@ -27,8 +57,25 @@ int main(int argc, char* argv[]) std::cout << "Number of facets in " << filename << ": " << mesh.number_of_faces() << "\n"; - auto ccdt = CGAL::make_conforming_constrained_Delaunay_triangulation_3(mesh, - CGAL::parameters::return_empty_on_invalid_input(true)); + // Verify preconditions for the mesh input + if(!verify_preconditions_mesh(mesh)) + { + // If the mesh is not a valid triangle mesh or has self-intersections, + // convert it to a polygon soup and verify the preconditions for the soup + std::vector points; + std::vector> polygons; + CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(mesh, points, polygons); + if(!verify_preconditions_soup(points, polygons)) + { + std::cerr << "Error: input polygon soup is not a valid input for CCDT_3\n"; + return EXIT_FAILURE; + } + + std::cerr << "Error: input mesh is not a valid input for CCDT_3\n"; + return EXIT_FAILURE; + } + + auto ccdt = CGAL::make_conforming_constrained_Delaunay_triangulation_3(mesh); if(ccdt.number_of_constrained_facets() == 0) { diff --git a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h index ea1a93aae76..2b76a96cb91 100644 --- a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h +++ b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h @@ -638,18 +638,6 @@ public: // ---------------------------------- using parameters::choose_parameter; using parameters::get_parameter; -#ifndef CGAL_CDT_3_DISABLE_INPUT_CHECKS - const bool return_empty_on_invalid_input = - choose_parameter(get_parameter(np, internal_np::return_empty_on_invalid_input), false); - - if (choose_parameter(get_parameter(np, internal_np::do_self_intersection_tests), true)) - { - CGAL_precondition_msg(return_empty_on_invalid_input || preconditions_verified_mesh(mesh, np), - "Conforming_constrained_Delaunay_triangulation_3: mesh self-intersects"); - } - - if(return_empty_on_invalid_input && !preconditions_verified_mesh(mesh, np)) return; -#endif auto mesh_vp_map = choose_parameter(get_parameter(np, internal_np::vertex_point), get(CGAL::vertex_point, mesh)); @@ -777,15 +765,6 @@ public: // ---------------------------------- using parameters::choose_parameter; using parameters::get_parameter; -#ifndef CGAL_CDT_3_DISABLE_INPUT_CHECKS - const bool return_empty_on_invalid_input = - choose_parameter(get_parameter(np, internal_np::return_empty_on_invalid_input), false); - - CGAL_precondition_msg(return_empty_on_invalid_input || preconditions_verified_soup(points, polygons, np), - "Conforming_constrained_Delaunay_triangulation_3: polygon soup self-intersects"); - - if(return_empty_on_invalid_input && !preconditions_verified_soup(points, polygons, np)) return; -#endif using PointRange_const_iterator = typename PointRange::const_iterator; using PointRange_value_type = typename std::iterator_traits::value_type; diff --git a/Constrained_triangulation_3/include/CGAL/make_conforming_constrained_Delaunay_triangulation_3.h b/Constrained_triangulation_3/include/CGAL/make_conforming_constrained_Delaunay_triangulation_3.h index e0e6bd6bd8d..07735bd4d48 100644 --- a/Constrained_triangulation_3/include/CGAL/make_conforming_constrained_Delaunay_triangulation_3.h +++ b/Constrained_triangulation_3/include/CGAL/make_conforming_constrained_Delaunay_triangulation_3.h @@ -43,16 +43,19 @@ namespace CGAL { By default, each face of the input is considered a polygonal constraint for the triangulation. The named parameter `plc_face_id` can be used to describe larger polygonal constraints, possibly with holes. If - used, this parameter must be a property map that associates each face of the input with a patch - identifier. Faces with the same patch identifier are considered part of the same surface patch. Each of these + used, this parameter must be a property map that associates each face of the input with a PLC face + identifier. Faces with the same face identifier are considered part of the same surface patch. Each of these surface patches (defined as the union of the input faces with a given patch identifier) is expected to be a polygon or a polygon with holes, with coplanar vertices (or nearly coplanar up to the precision of the number type used). The generated triangulation will conform to the faces of the input, or to the surface patches described by the `plc_face_id` property map if provided. + In the case where the input contains a non-planar PLC face, building the triangulation may fail with an exception + of type `CGAL::Non_planar_plc_facet_exception`. \pre The input data must not be coplanar. + \pre The input data must not have self-intersections. Template Parameters {#make_conforming_constrained_Delaunay_triangulation_3_template_parameters} ------------------- @@ -121,16 +124,6 @@ namespace CGAL { * Faces of `mesh` with the same patch identifier are considered part of the same PLC face.} * \cgalParamNEnd * - * \cgalParamNBegin{return_empty_on_invalid_input} - * \cgalParamDescription{a Boolean activating the check of preconditions on the input - * before starting to construct the triangulation. - * If the check is activated and the preconditions are not satisfied, - * an empty triangulation is immediately returned.} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamExtra{If this parameter is set to `false` and the preconditions are not satisfied, the algorithm may throw an exception or crash.} - * \cgalParamNEnd - * * \cgalParamNBegin{geom_traits} * \cgalParamDescription{an instance of a geometric traits class} * \cgalParamType{`Traits` as defined above in the section \ref make_conforming_constrained_Delaunay_triangulation_3_returned_type} @@ -199,16 +192,6 @@ auto make_conforming_constrained_Delaunay_triangulation_3(const PolygonMesh &mes * \cgalParamExtra{Otherwise facets with the same patch identifier are considered part of the same PLC face.} * \cgalParamNEnd * - * \cgalParamNBegin{return_empty_on_invalid_input} - * \cgalParamDescription{a Boolean activating the check of preconditions on the input - * before starting to construct the triangulation. - * If the check is activated and the preconditions are not satisfied, - * an empty triangulation is immediately returned.} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamExtra{If this parameter is set to `false` and the preconditions are not satisfied, the algorithm may throw an exception or crash.} - * \cgalParamNEnd - * * \cgalParamNBegin{geom_traits} * \cgalParamDescription{an instance of a geometric traits class} * \cgalParamType{`Traits` as defined above in the section \ref make_conforming_constrained_Delaunay_triangulation_3_returned_type} 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 72b2d8f8a13..8adf0d25f8b 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -325,9 +325,6 @@ CGAL_add_named_parameter(preserve_order_t, preserve_order, preserve_order) CGAL_add_named_parameter(adjust_directions_t, adjust_directions, adjust_directions) CGAL_add_named_parameter(segment_t, segment_map, segment_map) -// List of named parameters using in Constrained_triangulation_3 -CGAL_add_named_parameter(return_empty_on_invalid_input_t, return_empty_on_invalid_input, return_empty_on_invalid_input) - // List of named parameters used in Mesh_2 package CGAL_add_named_parameter_with_compatibility(seeds_t, seeds, seeds) CGAL_add_named_parameter_with_compatibility(domain_is_initialized_t, domain_is_initialized, domain_is_initialized)