Skip to content

Commit c3cf40f

Browse files
committed
Skeletonization: Add example
1 parent 8a88edc commit c3cf40f

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

Surface_mesh_skeletonization/doc/Surface_mesh_skeletonization/examples.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
\example Surface_mesh_skeletonization/MCF_Skeleton_example.cpp
44
\example Surface_mesh_skeletonization/segmentation_example.cpp
55
\example Surface_mesh_skeletonization/MCF_Skeleton_sm_example.cpp
6+
\example Surface_mesh_skeletonization/MCF_Skeleton_om_example.cpp
67
\example Surface_mesh_skeletonization/simple_mcfskel_sm_example.cpp
78
*/

Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ find_package(CGAL REQUIRED)
99
find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater)
1010
include(CGAL_Eigen3_support)
1111

12+
find_package(OpenMesh QUIET)
13+
14+
if(OpenMesh_FOUND)
15+
include(UseOpenMesh)
16+
else()
17+
message(STATUS "Examples that use OpenMesh will not be compiled.")
18+
endif()
19+
1220
if(TARGET CGAL::Eigen3_support)
1321
create_single_source_cgal_program("simple_mcfskel_example.cpp")
1422
create_single_source_cgal_program("simple_mcfskel_sm_example.cpp")
@@ -28,6 +36,11 @@ if(TARGET CGAL::Eigen3_support)
2836
segmentation_example)
2937
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
3038
endforeach()
39+
40+
if(OpenMesh_FOUND)
41+
create_single_source_cgal_program("MCF_Skeleton_om_example.cpp")
42+
target_link_libraries( MCF_Skeleton_om_example PUBLIC CGAL::Eigen3_support PRIVATE ${OPENMESH_LIBRARIES})
43+
endif()
3144
else()
3245
message(
3346
STATUS
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
3+
#include <CGAL/Surface_mesh.h>
4+
#include <CGAL/Mean_curvature_flow_skeletonization.h>
5+
6+
#include <OpenMesh/Core/IO/MeshIO.hh>
7+
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
8+
9+
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
10+
11+
#include <fstream>
12+
13+
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
14+
typedef Kernel::Point_3 Point;
15+
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Triangle_mesh;
16+
17+
typedef boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
18+
19+
typedef CGAL::Mean_curvature_flow_skeletonization<Triangle_mesh> Skeletonization;
20+
typedef Skeletonization::Skeleton Skeleton;
21+
22+
typedef Skeleton::vertex_descriptor Skeleton_vertex;
23+
typedef Skeleton::edge_descriptor Skeleton_edge;
24+
25+
int main(int argc, char* argv[])
26+
{
27+
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off");
28+
29+
Triangle_mesh tmesh;
30+
OpenMesh::IO::read_mesh(tmesh, filename);
31+
32+
if (!CGAL::is_triangle_mesh(tmesh))
33+
{
34+
std::cout << "Input geometry is not triangulated." << std::endl;
35+
return EXIT_FAILURE;
36+
}
37+
38+
Skeleton skeleton;
39+
Skeletonization mcs(tmesh);
40+
41+
// 1. Contract the mesh by mean curvature flow.
42+
mcs.contract_geometry();
43+
44+
// 2. Collapse short edges and split bad triangles.
45+
mcs.collapse_edges();
46+
mcs.split_faces();
47+
48+
// 3. Fix degenerate vertices.
49+
mcs.detect_degeneracies();
50+
51+
// Perform the above three steps in one iteration.
52+
mcs.contract();
53+
54+
// Iteratively apply step 1 to 3 until convergence.
55+
mcs.contract_until_convergence();
56+
57+
// Convert the contracted mesh into a curve skeleton and
58+
// get the correspondent surface points
59+
mcs.convert_to_skeleton(skeleton);
60+
61+
std::cout << "Number of vertices of the skeleton: " << boost::num_vertices(skeleton) << "\n";
62+
std::cout << "Number of edges of the skeleton: " << boost::num_edges(skeleton) << "\n";
63+
64+
// Output all the edges of the skeleton.
65+
std::ofstream output("skel-sm.polylines.txt");
66+
for(Skeleton_edge e : CGAL::make_range(edges(skeleton)))
67+
{
68+
const Point& s = skeleton[source(e, skeleton)].point;
69+
const Point& t = skeleton[target(e, skeleton)].point;
70+
output << "2 "<< s << " " << t << "\n";
71+
}
72+
output.close();
73+
74+
// Output skeleton points and the corresponding surface points
75+
output.open("correspondance-sm.polylines.txt");
76+
for(Skeleton_vertex v : CGAL::make_range(vertices(skeleton)))
77+
for(vertex_descriptor vd : skeleton[v].vertices)
78+
output << "2 " << skeleton[v].point << " " << get(CGAL::vertex_point, tmesh, vd) << "\n";
79+
80+
return EXIT_SUCCESS;
81+
}

0 commit comments

Comments
 (0)