mirror of https://github.com/CGAL/cgal
remove return_empty_on_invalid_input
and show in an example how to check preconditions
This commit is contained in:
parent
1323411457
commit
fb898e9ab1
|
|
@ -1,11 +1,18 @@
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/IO/polygon_mesh_io.h>
|
|
||||||
#include <CGAL/IO/write_MEDIT.h>
|
|
||||||
#include <CGAL/Surface_mesh/Surface_mesh.h>
|
#include <CGAL/Surface_mesh/Surface_mesh.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
|
||||||
|
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
|
||||||
|
|
||||||
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
|
#include <CGAL/make_conforming_constrained_Delaunay_triangulation_3.h>
|
||||||
|
|
||||||
#include <CGAL/draw_constrained_triangulation_3.h>
|
#include <CGAL/draw_constrained_triangulation_3.h>
|
||||||
|
#include <CGAL/IO/polygon_mesh_io.h>
|
||||||
|
#include <CGAL/IO/write_MEDIT.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||||
using Point = K::Point_3;
|
using Point = K::Point_3;
|
||||||
|
|
@ -13,13 +20,36 @@ using Surface_mesh = CGAL::Surface_mesh<Point>;
|
||||||
|
|
||||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
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 <typename PointRange, typename PolygonRange>
|
||||||
|
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[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
const auto filename = (argc > 1) ? argv[1]
|
const auto filename = (argc > 1) ? argv[1]
|
||||||
: CGAL::data_file_path("meshes/mpi_and_sphere.off");
|
: CGAL::data_file_path("meshes/mpi_and_sphere.off");
|
||||||
|
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh;
|
CGAL::Surface_mesh<K::Point_3> 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;
|
std::cerr << "Error: cannot read file " << filename << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -27,8 +57,25 @@ int main(int argc, char* argv[])
|
||||||
std::cout << "Number of facets in " << filename << ": "
|
std::cout << "Number of facets in " << filename << ": "
|
||||||
<< mesh.number_of_faces() << "\n";
|
<< mesh.number_of_faces() << "\n";
|
||||||
|
|
||||||
auto ccdt = CGAL::make_conforming_constrained_Delaunay_triangulation_3(mesh,
|
// Verify preconditions for the mesh input
|
||||||
CGAL::parameters::return_empty_on_invalid_input(true));
|
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<K::Point_3> points;
|
||||||
|
std::vector<std::vector<std::size_t>> 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)
|
if(ccdt.number_of_constrained_facets() == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -638,18 +638,6 @@ public:
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
using parameters::get_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));
|
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::choose_parameter;
|
||||||
using parameters::get_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_const_iterator = typename PointRange::const_iterator;
|
||||||
using PointRange_value_type = typename std::iterator_traits<PointRange_const_iterator>::value_type;
|
using PointRange_value_type = typename std::iterator_traits<PointRange_const_iterator>::value_type;
|
||||||
|
|
|
||||||
|
|
@ -43,16 +43,19 @@ namespace CGAL {
|
||||||
|
|
||||||
By default, each face of the input is considered a polygonal constraint for the triangulation. The
|
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
|
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
|
used, this parameter must be a property map that associates each face of the input with a PLC face
|
||||||
identifier. Faces with the same patch identifier are considered part of the same surface patch. Each of these
|
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
|
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).
|
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
|
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.
|
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 be coplanar.
|
||||||
|
\pre The input data must not have self-intersections.
|
||||||
|
|
||||||
Template Parameters {#make_conforming_constrained_Delaunay_triangulation_3_template_parameters}
|
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.}
|
* Faces of `mesh` with the same patch identifier are considered part of the same PLC face.}
|
||||||
* \cgalParamNEnd
|
* \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}
|
* \cgalParamNBegin{geom_traits}
|
||||||
* \cgalParamDescription{an instance of a geometric traits class}
|
* \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}
|
* \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.}
|
* \cgalParamExtra{Otherwise facets with the same patch identifier are considered part of the same PLC face.}
|
||||||
* \cgalParamNEnd
|
* \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}
|
* \cgalParamNBegin{geom_traits}
|
||||||
* \cgalParamDescription{an instance of a geometric traits class}
|
* \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}
|
* \cgalParamType{`Traits` as defined above in the section \ref make_conforming_constrained_Delaunay_triangulation_3_returned_type}
|
||||||
|
|
|
||||||
|
|
@ -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(adjust_directions_t, adjust_directions, adjust_directions)
|
||||||
CGAL_add_named_parameter(segment_t, segment_map, segment_map)
|
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
|
// 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(seeds_t, seeds, seeds)
|
||||||
CGAL_add_named_parameter_with_compatibility(domain_is_initialized_t, domain_is_initialized, domain_is_initialized)
|
CGAL_add_named_parameter_with_compatibility(domain_is_initialized_t, domain_is_initialized, domain_is_initialized)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue