From 2795a6374c60d0381253bc6d07f7c83d376bb03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 12 May 2022 16:19:28 +0200 Subject: [PATCH] add an example to simplify a mesh in parallel --- .../CMakeLists.txt | 13 ++ .../collapse_small_edges_in_parallel.cpp | 157 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt b/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt index 2f0a61cc06e..e26d9e72d0a 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/CMakeLists.txt @@ -51,3 +51,16 @@ if(OpenMesh_FOUND) create_single_source_cgal_program("edge_collapse_OpenMesh.cpp") target_link_libraries(edge_collapse_OpenMesh PRIVATE ${OPENMESH_LIBRARIES}) endif() + +find_package(METIS) +include(CGAL_METIS_support) + +find_package(TBB) +include(CGAL_TBB_support) + +if(TARGET CGAL::TBB_support AND TARGET CGAL::METIS_support) + create_single_source_cgal_program("collapse_small_edges_in_parallel.cpp") + target_link_libraries(collapse_small_edges_in_parallel PUBLIC CGAL::TBB_support CGAL::METIS_support) +else() + message(STATUS "collapse_small_edges_in_parallel, which use the METIS and TBB libraries will not be compiled.") +endif() diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp new file mode 100644 index 00000000000..17eebbe0314 --- /dev/null +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/collapse_small_edges_in_parallel.cpp @@ -0,0 +1,157 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; + +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + + +namespace SMS = CGAL::Surface_mesh_simplification; +namespace PMP = CGAL::Polygon_mesh_processing; + +struct Border_is_constrained_edge_map{ + const Triangle_mesh& sm; + typedef Triangle_mesh::Edge_index key_type; + typedef bool value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + Border_is_constrained_edge_map(const Triangle_mesh& sm) + : sm(sm) + {} + friend bool get(Border_is_constrained_edge_map m, const key_type& edge) { + return CGAL::is_border(edge, m.sm); + } +}; + +struct Simplify +{ + Triangle_mesh* tm_ptr; + double edge_length; + + Simplify() + :tm_ptr(NULL), edge_length(0) + {} + + Simplify(Triangle_mesh& tm, double edge_length) + : tm_ptr(&tm), edge_length(edge_length) + {} + + void operator()() const + { + + SMS::Edge_length_cost cost; + SMS::Edge_length_stop_predicate stop(edge_length); + Border_is_constrained_edge_map eicm(*tm_ptr); + SMS::Constrained_placement, + Border_is_constrained_edge_map > placement(eicm); + + SMS::edge_collapse(*tm_ptr, stop, + CGAL::parameters::edge_is_constrained_map(eicm) + .get_placement(placement) + .get_cost(cost)); + } +}; + +int main(int argc, char** argv) +{ + typedef boost::graph_traits::face_descriptor face_descriptor; + + std::ifstream in((argc>1) ? std::string(argv[1]) : CGAL::data_file_path("meshes/elephant.off")); + double edge_length = (argc>2) ? std::atof(argv[2]) : 0.02; + int number_of_parts = (argc>3) ? std::atoi(argv[3]) : 8; + + Triangle_mesh tm; + in >> tm; + + std::cerr << "Input: #V = "<< num_vertices(tm) << " #E = "<< num_edges(tm) + << " #F = " << num_faces(tm) << std::endl; + + CGAL::Real_timer t; + t.start(); + + // Partition ID map + Triangle_mesh::Property_map fpmap + = tm.add_property_map("f:partition").first; + + // Set some custom options for METIS + idx_t options[METIS_NOPTIONS]; + METIS_SetDefaultOptions(options); + options[METIS_OPTION_CONTIG] = 1; // need to have contiguous subdomains + options[METIS_OPTION_UFACTOR] = 1; + + CGAL::METIS::partition_dual_graph(tm, number_of_parts, CGAL::parameters::METIS_options(&options) + // .vertex_index_map(get(boost::vertex_index,tm)) + .face_partition_id_map(fpmap)); + + SMS::LindstromTurk_placement placement; + SMS::Edge_length_cost cost; + SMS::Edge_length_stop_predicate stop(edge_length); + + CGAL::Face_filtered_graph fg(tm); + std::vector meshes(number_of_parts); + for (int i=0; i< number_of_parts; ++i) + { + fg.set_selected_faces(i, fpmap); + CGAL::copy_face_graph(fg, meshes[i]); + } + + tbb::task_group tasks; + for(int id=0; id