|
CGAL 6.1 - Dynamic Skeletonization Via Variational Medial Axis Sampling
|
The skeleton is a fundamental structure with numerous applications in shape matching, shape segmentation, shape deformation, etc. A generalization of the skeleton is the medial axis, defined as the set of points that are equidistant to two or more points on the boundary of a shape. In this context, each point of the medial axis can be viewed as the center of a maximal inscribed ball, often referred to as a medial sphere.
This package implements a skeletonization algorithm [1] that extracts a coarse, discrete approximation of the medial axis from a triangulated surface mesh without borders. Unlike the Surface_mesh_skeletonization package, which computes a purely curve-based (1D) skeleton, the output of this method is a non-manifold triangle mesh that may contain both curve (1D) and surface (2D) elements, a structure sometimes referred to as a medial mesh. Each vertex of the resulting mesh corresponds to a medial sphere, and the edges and faces encode the adjacency relationships between these spheres. One can reconstruct the original mesh by interpolating between spheres according their adjacency relationships. For each edge, interpolating between two spheres yields a medial cone. For each face, interpolating between three spheres yields a medial slab.
Figure 83.2 Interpolation of medial mesh. (a) medial cone (b) medial slab. Image taken from [2]
At the core of the method is a variational optimization problem whose objective is to minimize an error metric that measures the distance between each medial sphere and its associated surface points(cluster vertices), so that each sphere accurately represents the local geometry of the shape.
The process begins by initializing a single cluster containing all surface vertices and fitting an initial medial sphere using the variational error metric. New spheres are then progressively inserted in regions with the highest approximation error. Each insertion triggers updates to both the cluster vertices and the set of medial spheres in an iterative optimization loop. The algorithm terminates when either the target number of spheres is reached or the maximum number of iterations is exceeded. Finally, the connectivity of the medial skeleton is constructed based on the adjacency relations between vertex clusters.
Figure 83.3 Overview of the algorithm, image taken from [1]
The method takes as input triangulated surface mesh which can be a mode of FaceListGraph, such as CGAL::Surface_mesh. It also requires Eigen (version 3.2 or later) for the use of the Eigen::LDLT solver, which is employed to solve the linear systems arising during optimization.
The output is stored in a Medial_skeleton structure, which contains three containers:
std::pair<std::size_t, std::size_t> encoding the adjacency between two spheres,Sphere_ID(std::array<std::size_t, 3>) values encoding a triangular patch connecting three spheres.A helper function CGAL:IO::write_PLY() is provided to export the resulting skeleton to a .ply file, which can then be visualized in external software such as Blender.
After the optimization step, the medial spheres may deviate slightly from the true medial axis. To project them back onto the medial axis, the algorithm performs a correction step using the shrinking ball algorithm,[3] which requires computing the closest point on the surface from a given position.
To accelerate this closest point query, two types of spatial search structures are supported:
CGAL::KD_tree_tag: uses a KD-tree constructed from the surface sample points.CGAL::BVH_tag: uses a bounding volume hierarchy (BVH) built from the faces of the input triangle mesh.The user can choose the desired structure by passing the corresponding tag via the CGAL::parameters::acceleration_structure() named parameter. The essential difference is that the KD-tree restricts sphere placement to be constrained by surface sampled points only, while the BVH allows medial spheres to touch the interior of mesh faces. In general, we recommend using the KD-tree (which is also the default) since the surface will be densely sampled at the beginning of the algorithm.
The function CGAL::extract_variational_medial_skeleton() provides a convenient interface for users who want to quickly extract a medial skeleton with specified parameters. This function accepts the following parameters:
number_of_spheres: target number of medial spheresnumber_of_samples: number of points that will be sampled on the surfacelambda: weight balancing the energy termsrandom_seed: random seed for generating sample points on the surfacenumber_of_iterations: maximum number of iterationsconcurrency_tag: execution mode - sequential or parallelThe following example showcases the usage of this function:
File Variational_medial_axis/vmas_free_function.cpp
The class CGAL::Variational_medial_axis_sampling provides some advanced usage of the algorithm Several key functions are provided for algorithm control:
CGAL::Variational_medial_axis_sampling::sample(): Executes the complete algorithm with specified parameters and returns a boolean indicating success. The algorithm may fail either when the optimization does not converge (the error stays above the error threshold) or when the surface sampling is not dense enough to generate a sufficient number of medial spheres. The parameters are the same as those of the free function.CGAL::Variational_medial_axis_sampling::update_single_step(): Performs a single iteration of the optimization process, with optional sphere splitting enabled. This allows for step-by-step execution and monitoring of the algorithm's progress.CGAL::Variational_medial_axis_sampling::update(): Executes a specified number of optimization iterations without sphere splitting.CGAL::Variational_medial_axis_sampling::add_spheres(int nb_spheres): Adds a specified number of spheres by iteratively splitting existing spheres.The following example shows a different configuration of the parameters and basic usage of the above functions:
File Variational_medial_axis/vmas_class_interface.cpp
By definition, the medial axis of a shape is homotopy equivalent to the original object. However, since this algorithm aims to generate coarse approximation of medial axis, it does not provide any theoretical guarantee that the extracted skeleton preserves the topology of the input. While the algorithm can handle meshes with multiple connected components, the resulting medial skeleton is only topologically faithful when a sufficient number of spheres is used to capture the correct connectivity. Furthermore, this method does not perform well on CAD models, which typically require additional feature detection to preserve sharp features.
This package is the result of the work of Qijia Huang during the 2025 season of the Google Summer of Code, mentored by Sébastien Loriot.