Note that is important to use a signed type for the loop variable. The warning is: > C:\CGAL_ROOT\CGAL-6.2-Ic-103\include\CGAL\bisect_failures.h(195,40): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data See https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-6.2-Ic-103/STL_Extension_Examples/TestReport_Christo_MSVC-2026-Community-Release.gz
111 lines
3.5 KiB
C++
111 lines
3.5 KiB
C++
// CGAL::bisect_failures requires the code to be compiled with assertions
|
|
// enabled. That means NDEBUG and CGAL_NDEBUG should not be defined.
|
|
#if defined(NDEBUG)
|
|
# undef NDEBUG
|
|
#endif
|
|
#if defined(CGAL_NDEBUG)
|
|
# undef CGAL_NDEBUG
|
|
#endif
|
|
#include <CGAL/config.h>
|
|
#include <CGAL/bisect_failures.h>
|
|
#include <CGAL/boost/graph/Euler_operations.h>
|
|
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
#include <CGAL/IO/polygon_mesh_io.h>
|
|
#include <CGAL/Polygon_mesh_processing/clip.h>
|
|
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
|
|
#include <CGAL/Surface_mesh/Surface_mesh.h>
|
|
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
|
using Point = Kernel::Point_3;
|
|
using Mesh = CGAL::Surface_mesh<Point>;
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/non_manifold.off");
|
|
|
|
Mesh mesh_a;
|
|
if(!CGAL::IO::read_polygon_mesh(filename, mesh_a)) {
|
|
std::cerr << "Error: cannot read file " << filename << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
std::cout << "Loaded mesh with " << mesh_a.number_of_vertices() << " vertices and "
|
|
<< mesh_a.number_of_faces() << " faces" << std::endl;
|
|
|
|
const std::string clip_name = (argc > 2) ? argv[2] : CGAL::data_file_path("meshes/cube.off");
|
|
Mesh mesh_b;
|
|
if(!CGAL::IO::read_polygon_mesh(clip_name, mesh_b)) {
|
|
std::cerr << "Error: cannot read file " << clip_name << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
std::cout << "Loaded clipping mesh mesh with " << mesh_b.number_of_vertices() << " vertices and "
|
|
<< mesh_b.number_of_faces() << " faces" << std::endl;
|
|
|
|
//! [bisect_failures_snippet]
|
|
// Define the callbacks for bisect_failures
|
|
|
|
auto get_size = [](const Mesh& m) -> std::size_t {
|
|
return m.number_of_faces();
|
|
};
|
|
|
|
auto simplify = [](Mesh& m, std::ptrdiff_t start, std::ptrdiff_t end) -> bool {
|
|
for(auto i = end - 1; i >= start; --i) {
|
|
const auto f = m.faces().begin() + i;
|
|
CGAL::Euler::remove_face(halfedge(*f, m), m);
|
|
}
|
|
|
|
return m.is_valid();
|
|
};
|
|
|
|
auto run = [&mesh_b](Mesh& mesh) -> int {
|
|
return CGAL::Polygon_mesh_processing::clip(mesh, mesh_b) ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
};
|
|
|
|
auto save = [](const Mesh& m, CGAL::Bisection_event event) {
|
|
std::string prefix;
|
|
switch(event) {
|
|
case CGAL::BAD_DATA:
|
|
prefix = "bad_data";
|
|
break;
|
|
case CGAL::FINAL_BAD_DATA:
|
|
prefix = "final_bad_data";
|
|
break;
|
|
case CGAL::ERROR_DATA:
|
|
prefix = "error_data";
|
|
break;
|
|
case CGAL::CURRENT_DATA:
|
|
prefix = "current_data";
|
|
break;
|
|
default:
|
|
CGAL_UNREACHABLE();
|
|
}
|
|
std::string out_filename = prefix + ".off";
|
|
if(!CGAL::IO::write_polygon_mesh(out_filename, m)) {
|
|
std::cerr << "Warning: Could not save mesh to " << out_filename << std::endl;
|
|
} else {
|
|
std::cout << "Saved mesh with " << m.number_of_faces()
|
|
<< " faces to " << out_filename << std::endl;
|
|
}
|
|
};
|
|
|
|
std::cout << "\n=== Starting bisection to find smaller failing case ===\n" << std::endl;
|
|
|
|
int result = CGAL::bisect_failures(mesh_a, get_size, simplify, run, save);
|
|
//! [bisect_failures_snippet]
|
|
|
|
if(result == EXIT_SUCCESS) {
|
|
std::cout << "\nNo failure detected during bisection." << std::endl;
|
|
} else {
|
|
std::cout << "\nFailure detected during bisection. Result code: " << result << std::endl;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|