#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/Seam_mesh.h>
#include <CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Timer.h>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#include <utility>
#include <vector>
typedef boost::graph_traits<SurfaceMesh>::vertex_descriptor SM_vertex_descriptor;
typedef boost::graph_traits<SurfaceMesh>::halfedge_descriptor SM_halfedge_descriptor;
typedef boost::graph_traits<SurfaceMesh>::edge_descriptor SM_edge_descriptor;
typedef SurfaceMesh::Property_map<SM_edge_descriptor, bool> Seam_edge_pmap;
typedef SurfaceMesh::Property_map<SM_vertex_descriptor, bool> Seam_vertex_pmap;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef SurfaceMesh::Property_map<SM_halfedge_descriptor, Point_2> UV_pmap;
namespace SMP = CGAL::Surface_mesh_parameterization;
int main(int argc, char * argv[])
{
const char* mesh_filename = (argc>1) ? argv[1] : "data/bear.off";
std::ifstream in_mesh(mesh_filename);
if(!in_mesh) {
std::cerr << "Error: problem loading the input data" << std::endl;
return 1;
}
SurfaceMesh sm;
in_mesh >> sm;
const char* cone_filename = (argc>2) ? argv[2] : "data/bear.selection.txt";
std::vector<SM_vertex_descriptor> cone_sm_vds;
SMP::read_cones<SurfaceMesh>(sm, cone_filename, std::back_inserter(cone_sm_vds));
Seam_edge_pmap seam_edge_pm = sm.add_property_map<SM_edge_descriptor, bool>("e:on_seam", false).first;
Seam_vertex_pmap seam_vertex_pm = sm.add_property_map<SM_vertex_descriptor, bool>("v:on_seam",false).first;
Mesh mesh(sm, seam_edge_pm, seam_vertex_pm);
SM_halfedge_descriptor smhd = mesh.add_seams(cone_filename);
if(smhd == SM_halfedge_descriptor() ) {
std::cout << "No seams given in input, computing the shortest paths between consecutive cones" << std::endl;
std::list<SM_edge_descriptor> seam_edges;
BOOST_FOREACH(SM_edge_descriptor e, seam_edges) {
mesh.add_seam(source(e, sm), target(e, sm));
}
}
std::cout << mesh.number_of_seam_edges() << " seam edges in input" << std::endl;
typedef boost::unordered_map<vertex_descriptor, int> Indices;
Indices indices;
boost::associative_property_map<Indices> vimap(indices);
int counter = 0;
BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)) {
put(vimap, vd, counter++);
}
boost::unordered_map<vertex_descriptor, SMP::Cone_type> cmap;
UV_pmap uvmap = sm.add_property_map<SM_halfedge_descriptor, Point_2>("h:uv").first;
typedef SMP::Orbifold_Tutte_parameterizer_3<Mesh> Parameterizer;
halfedge_descriptor bhd = CGAL::Polygon_mesh_processing::longest_border(mesh,
CGAL::Polygon_mesh_processing::parameters::all_default()).first;
parameterizer.parameterize(mesh, bhd, cmap, uvmap, vimap);
std::cout <<
"Finished in " << task_timer.
time() <<
" seconds" << std::endl;
}