\( \newcommand{\E}{\mathrm{E}} \) \( \newcommand{\A}{\mathrm{A}} \) \( \newcommand{\R}{\mathrm{R}} \) \( \newcommand{\N}{\mathrm{N}} \) \( \newcommand{\Q}{\mathrm{Q}} \) \( \newcommand{\Z}{\mathrm{Z}} \) \( \def\ccSum #1#2#3{ \sum_{#1}^{#2}{#3} } \def\ccProd #1#2#3{ \sum_{#1}^{#2}{#3} }\)
CGAL 5.0 - Triangulated Surface Mesh Skeletonization
Surface_mesh_skeletonization/simple_mcfskel_example.cpp
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/extract_mean_curvature_flow_skeleton.h>
#include <CGAL/boost/graph/split_graph_into_polylines.h>
#include <fstream>
typedef Kernel::Point_3 Point;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
typedef boost::graph_traits<Polyhedron>::vertex_descriptor vertex_descriptor;
typedef Skeletonization::Skeleton Skeleton;
typedef Skeleton::vertex_descriptor Skeleton_vertex;
typedef Skeleton::edge_descriptor Skeleton_edge;
//only needed for the display of the skeleton as maximal polylines
struct Display_polylines{
const Skeleton& skeleton;
std::ofstream& out;
int polyline_size;
std::stringstream sstr;
Display_polylines(const Skeleton& skeleton, std::ofstream& out)
: skeleton(skeleton), out(out)
{}
void start_new_polyline(){
polyline_size=0;
sstr.str("");
sstr.clear();
}
void add_node(Skeleton_vertex v){
++polyline_size;
sstr << " " << skeleton[v].point;
}
void end_polyline()
{
out << polyline_size << sstr.str() << "\n";
}
};
// This example extracts a medially centered skeleton from a given mesh.
int main(int argc, char* argv[])
{
std::ifstream input((argc>1)?argv[1]:"data/elephant.off");
Polyhedron tmesh;
input >> tmesh;
{
std::cout << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
Skeleton skeleton;
std::cout << "Number of vertices of the skeleton: " << boost::num_vertices(skeleton) << "\n";
std::cout << "Number of edges of the skeleton: " << boost::num_edges(skeleton) << "\n";
// Output all the edges of the skeleton.
std::ofstream output("skel-poly.cgal");
Display_polylines display(skeleton,output);
output.close();
// Output skeleton points and the corresponding surface points
output.open("correspondance-poly.cgal");
for(Skeleton_vertex v : CGAL::make_range(vertices(skeleton)))
for(vertex_descriptor vd : skeleton[v].vertices)
output << "2 " << skeleton[v].point << " "
<< get(CGAL::vertex_point, tmesh, vd) << "\n";
return EXIT_SUCCESS;
}