#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_stop_predicate.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h>
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/Real_timer.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/Polygon_mesh_processing/stitch_borders.h>
#include <tbb/task_group.h>
#include <iostream>
#include <fstream>
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) {
}
};
struct Simplify
{
Triangle_mesh* tm_ptr;
double edge_length;
Simplify()
:tm_ptr(NULL), edge_length(0)
{}
Simplify(Triangle_mesh& tm, double edge_length)
{}
void operator()() const
{
SMS::Edge_length_cost<Triangle_mesh> cost;
SMS::Edge_length_stop_predicate<double> stop(edge_length);
Border_is_constrained_edge_map eicm(*tm_ptr);
SMS::Constrained_placement<SMS::LindstromTurk_placement<Triangle_mesh>,
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<Triangle_mesh>::face_descriptor face_descriptor;
std::ifstream in((argc>1) ? std::filesystem::path(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();
Triangle_mesh::Property_map<face_descriptor, std::size_t> fpmap
= tm.add_property_map<face_descriptor, std::size_t>("f:partition").first;
idx_t options[METIS_NOPTIONS];
METIS_SetDefaultOptions(options);
options[METIS_OPTION_CONTIG] = 1;
options[METIS_OPTION_UFACTOR] = 1;
.face_partition_id_map(fpmap));
SMS::LindstromTurk_placement<Triangle_mesh> placement;
SMS::Edge_length_cost<Triangle_mesh> cost;
SMS::Edge_length_stop_predicate<double> stop(edge_length);
std::vector<Triangle_mesh> meshes(number_of_parts);
for (int i=0; i< number_of_parts; ++i)
{
fg.set_selected_faces(i, fpmap);
}
tbb::task_group tasks;
for(int id=0; id<number_of_parts; ++id)
{
tasks.run(Simplify(meshes[id], edge_length));
}
tasks.wait();
Triangle_mesh final_mesh;
Triangle_mesh::size_type nv = 0, nf = 0, ne = 0;
for (int i=0; i< number_of_parts; ++i)
{
meshes[i].collect_garbage();
nv += num_vertices(meshes[i]);
nf += num_faces(meshes[i]);
ne += num_edges(meshes[i]);
}
final_mesh.reserve(nv, ne, nf);
for (int i=0; i< number_of_parts; ++i)
{
}
PMP::stitch_borders(final_mesh);
SMS::edge_collapse(final_mesh, stop,
CGAL::parameters::get_placement(placement)
.get_cost(cost));
final_mesh.collect_garbage();
t.stop();
std::cerr << " Total time: " << t.time() << " sec.\n"
<< " Result: #V = " << num_vertices(final_mesh)
<< " #E = " << num_edges(final_mesh)
<< " #F = " << num_faces(final_mesh) << std::endl;
std::ofstream("simplified_mesh_parallel.off") << std::setprecision(17) << final_mesh;
return EXIT_SUCCESS;
}
FT edge_length(typename boost::graph_traits< PolygonMesh >::halfedge_descriptor h, const PolygonMesh &pmesh, const NamedParameters &np=parameters::default_values())
void copy_face_graph(const SourceMesh &sm, TargetMesh &tm, const NamedParameters1 &np1=parameters::default_values(), const NamedParameters2 &np2=parameters::default_values())
bool is_border(typename boost::graph_traits< FaceGraph >::halfedge_descriptor hd, const FaceGraph &g)
void partition_dual_graph(const TriangleMesh &tm, int nparts, const NamedParameters &np=parameters::default_values())
std::filesystem::path data_file_path(const std::filesystem::path &filename)
Definition edge_collapse.h:2