|
|
|
|
@ -16,13 +16,11 @@ Right: extracted triangle mesh with less than 250 triangles.
|
|
|
|
|
|
|
|
|
|
For many applications ranging from geometry compression to reverse engineering, finding the concise and faithful approximation of an excessively verbose 3D data (in particular, scanned meshes) is beneficial for subsequent processing and may reduce the computational cost dramatically.
|
|
|
|
|
|
|
|
|
|
This package implements the <em>Variational Shape Approximation</em> \cgalCite{cgal:cad-vsa-04} (VSA) method to approximate an input surface mesh by a simpler triangle surface mesh or triangle soup. Given a triangulated surface mesh, referred to as <em>mesh</em> in the following, VSA leverages the Lloyd's iteration \cgalCite{cgal:l-lsqp-82}
|
|
|
|
|
to drive the approximation error down between the input surface triangle mesh and a set of geometric proxies. By default the proxies are planar, but the algorithm design is generic for future extensions to non-planar proxies. Two error metrics (\f$ \mathcal{L}^2 \f$, \f$ \mathcal{L}^{2,1} \f$) are provided, but the algorithm is generic to other user-defined metrics.
|
|
|
|
|
This package implements the <em>Variational Shape Approximation</em> \cgalCite{cgal:cad-vsa-04} (VSA) method to approximate an input surface mesh by a simpler indexed face set or polyhedral surface mesh. Given a triangulated surface mesh, referred to as <em>mesh</em> in the following, VSA leverages the Lloyd's clustering iteration \cgalCite{cgal:l-lsqp-82} to drive the approximation error down between the input surface triangle mesh and a set of geometric proxies. By default the proxies are planar, but the algorithm design is generic for future extensions to non-planar proxies. Two error metrics (\f$ \mathcal{L}^2 \f$, \f$ \mathcal{L}^{2,1} \f$) are provided, and the algorithm is generic to other user-defined metrics.
|
|
|
|
|
|
|
|
|
|
An overview of the algorithm is provided in \ref sma_approximation.
|
|
|
|
|
|
|
|
|
|
This package offers both the approximation and mesh extraction functionalities. They can be accessed through a free function or more advanced flexible class interfaces with customizable steps and parameters.
|
|
|
|
|
Apart from approximation, the package can be used for shape analysis or a complement to the current mesh segmentation package.
|
|
|
|
|
This package offers both the approximation and mesh extraction functionalities. They can be accessed through a free function or a more advanced flexible class interface with customizable steps and parameters. Apart from approximation, the package can be used for shape segmentation via another free function to access the clustering partition.
|
|
|
|
|
|
|
|
|
|
\section sma_overview Overview
|
|
|
|
|
|
|
|
|
|
@ -51,15 +49,13 @@ For a sequence of iteration with the fitting error \f$ \{ E^1, \cdots, E^m \} \f
|
|
|
|
|
\subsection sma_metrics Metrics and Proxies
|
|
|
|
|
|
|
|
|
|
Intuitively, each region \f$ \mathcal{R}_i \f$ of a partition \f$ \mathcal{R} \f$ can be summarily represented to first order as an "average" point \f$ X_i \f$ and an "average" normal \f$ N_i \f$.
|
|
|
|
|
We denote such local representative pair \f$ P_i = (X_i, N_i) \f$, a <em>planar proxy</em> of the associated region. In the package, we provide such plane proxy as `CGAL::VSA::Plane_proxy`.
|
|
|
|
|
We denote such local representative pair \f$ P_i = (X_i, N_i) \f$, a <em>planar proxy</em> of the associated region. In the package, we provide such a planar proxy as `CGAL::VSA::Plane_proxy`.
|
|
|
|
|
|
|
|
|
|
Defining an appropriate error metric is the key ingredient for the algorithm.
|
|
|
|
|
The \f$ \mathcal{L}^2 \f$ metric is defined as:
|
|
|
|
|
\f[ \mathcal{L}^2(\mathcal{R}_i, P_i) = \iint_{x \in \mathcal{R}_i}\Vert x - \Pi_i(x)\Vert^2 dx. \f] where \f$ \Pi_i(\cdot) \f$ denotes the orthogonal projection of the argument onto the "proxy plane" going through \f$ X_i \f$ and normal to \f$ N_i \f$.
|
|
|
|
|
\f[ \mathcal{L}^2(\mathcal{R}_i, P_i) = \iint_{x \in \mathcal{R}_i}\Vert x - \Pi_i(x)\Vert^2 dx. \f] where \f$ \Pi_i(\cdot) \f$ denotes the orthogonal projection of the argument onto the proxy plane passing through \f$ X_i \f$ and normal to \f$ N_i \f$. The \f$ \mathcal{L}^2 \f$ metric tries to match the input shape through approximation of the geometric position.
|
|
|
|
|
|
|
|
|
|
The \f$ \mathcal{L}^2 \f$ metric tries to match geometry through approximation of the geometric position.
|
|
|
|
|
In the paper \cgalCite{cgal:cad-vsa-04}, the author proposed the \f$ \mathcal{L}^{2,1} \f$ metrics with the belief that normal field is fundamental to the visual interpretation of the shape. The \f$ \mathcal{L}^{2,1} \f$ is defined as:
|
|
|
|
|
\f[ \mathcal{L}^{2,1}(\mathcal{R}_i, P_i) = \iint_{x \in \mathcal{R}_i}\Vert \mathbf{n}(x) - \mathbf{n}_i\Vert^2 dx. \f]
|
|
|
|
|
In the paper \cgalCite{cgal:cad-vsa-04}, the author proposed the \f$ \mathcal{L}^{2,1} \f$ metrics, arguing that the normals are fundamental to the visual interpretation of the shape. The \f$ \mathcal{L}^{2,1} \f$ is defined as: \f[ \mathcal{L}^{2,1}(\mathcal{R}_i, P_i) = \iint_{x \in \mathcal{R}_i}\Vert \mathbf{n}(x) - \mathbf{n}_i\Vert^2 dx. \f]
|
|
|
|
|
|
|
|
|
|
The \f$ \mathcal{L}^{2,1} \f$ is numerically superior to \f$ \mathcal{L}^2 \f$ in several ways:
|
|
|
|
|
- The anisotropy of the surface is better captured.
|
|
|
|
|
@ -75,77 +71,65 @@ The package provides both two metrics as `CGAL::VSA::L2_metric` and `CGAL::VSA::
|
|
|
|
|
|
|
|
|
|
\subsection sma_init Initialization
|
|
|
|
|
|
|
|
|
|
(TODO: discuss choice of naming as initialization may confuse with seeding)
|
|
|
|
|
<!-- As discussed above, the iteration needs a set of initial proxies \f$ \{ P_1^0, \cdots, P_k^0 \} \f$. -->
|
|
|
|
|
|
|
|
|
|
<!-- As indicated in the previous section, the iteration needs a set of initial proxies \f$ \{ P_1^0, \cdots, P_k^0 \} \f$. -->
|
|
|
|
|
|
|
|
|
|
The algorithm must be initialized by determining either the number of proxies required to approximate the geometry or the maximum tolerance approximation error. More specifically, we can decide:
|
|
|
|
|
- <b>Target number of proxies</b>. The algorithm adds proxies until the specified target number is met.
|
|
|
|
|
- <b>Absolute error value</b>. The algorithm adds proxies until the approximation error is below the specified value. (WIP)
|
|
|
|
|
- <b>Target relative error drop</b>. We start from the proxy fitted from the first facet of the surface with the fitting error \f$ \hat E \f$. The algorithm adds proxies until the approximation error drops below the specified percentage \f$ target\_drop * \hat E \f$.
|
|
|
|
|
The algorithm must be initialized by determining either the maximum number of proxies required to approximate the geometry or the minimum error drop rate between two iterations. More specifically, we can decide:
|
|
|
|
|
- <b>Maximum number of proxies</b>. The algorithm adds proxies until the specified target number is met.
|
|
|
|
|
- <b>Minimum error drop</b>. We start from the proxy fitted from the first facet of the surface with the fitting error \f$ \hat E \f$. The algorithm adds proxies until the approximation error drops below the specified percentage \f$ target\_drop * \hat E \f$, between two iterations.
|
|
|
|
|
|
|
|
|
|
Different initialization examples are provided in \cgalFigureRef{meshing}.
|
|
|
|
|
|
|
|
|
|
(TODO: precise whether drop refers to relative drop rate or absolute value)
|
|
|
|
|
|
|
|
|
|
\subsection sma_seeding Seeding
|
|
|
|
|
|
|
|
|
|
Seeding is used to decide how to insert a new proxy.
|
|
|
|
|
In the implementation, each proxy is always associated with a <em>seed</em> facet.
|
|
|
|
|
While the proxy parameters are viewed as the center in a geometric error sense, the seed of each proxy is used as the topological start point in the partition process.
|
|
|
|
|
When we want to add one more proxy to drive the approximation error down,
|
|
|
|
|
we have to specify a facet of the surface as the seed to initialize the proxy parameters.
|
|
|
|
|
Each proxy is always associated with a <em>seed</em> triangle facet in the input surface mesh.
|
|
|
|
|
While the proxy parameters are viewed as the center in a geometric error sense, the seed of each proxy is used as the topological start point in the partition process. When we want to add more proxies to drive the approximation error down, we must specify facets of the input surface mesh as seeds to initialize the proxy parameters.
|
|
|
|
|
|
|
|
|
|
The package provides 3 different seeding methods:
|
|
|
|
|
- <b>Random</b>. The proxy seeds are picked randomly on the surface mesh.
|
|
|
|
|
- <b>Incremental</b>. Each time a proxy is initialized from a facet in the worst region.
|
|
|
|
|
- <b>Hierarchical</b>. The requested number of proxies are dispatched within current partition, where each region is added with the number of proxies proportional to their fitting error.
|
|
|
|
|
- <b>Incremental</b>. Each new proxy is initialized from a facet of the worse region matching the largest approximation error. The facet itself is chosen as the one realizing the largest error in its region.
|
|
|
|
|
- <b>Hierarchical</b>. The requested number of proxies are dispatched within the current partition, where each region is refined with a number of proxies chosen in accordance to their fitting error.
|
|
|
|
|
|
|
|
|
|
(TODO: precise formula used and justify)
|
|
|
|
|
|
|
|
|
|
\cgalFigureBegin{seeding_method, seeding_method.png}
|
|
|
|
|
Comparison of different seeding methods on a sphere-cube union model, all with \f$ \mathcal{L}^{2,1} \f$ metrics and 20 proxies.
|
|
|
|
|
From left to right are random, incremental and hierarchical seeding respectively.
|
|
|
|
|
From left to right: random, incremental and hierarchical seeding.
|
|
|
|
|
Notice the entrapped local minima in the yellow rectangles.
|
|
|
|
|
\cgalFigureEnd
|
|
|
|
|
|
|
|
|
|
From \cgalFigureRef{seeding_method} we can see the effect of different seeding methods to initialize the algorithm with targeted 20 proxies.
|
|
|
|
|
Generally speaking, random initialization is random in position, very fast but can be entrapped in local minima areas (left),
|
|
|
|
|
incremental one focuses on the most distorted region, interleaved with fitting process thus can be pretty slow.
|
|
|
|
|
Hierarchical initialization gives fitting patches with more evenly distributed fitting errors and the time consumption is somewhere in between the former two.
|
|
|
|
|
Some statistics and comparisons are available in \ref sma_perf.
|
|
|
|
|
Figure \cgalFigureRef{seeding_method} depicts the effect of different seeding methods to initialize the algorithm with 20 proxies. Random initialization is random in choice of facets, very fast but can be entrapped in local minima areas espeically on shapes with regions surrounded by sharp creases (left). Incremental initialization adds proxies one by one, focusing on the most distorted region. It can thus be slow due to the interleaving with the clustering process. Hierarchical initialization yields fitting patches with more evenly distributed fitting errors, hence time consumption is somewhere in between the former two. Some statistics and comparisons are available in \ref sma_perf.
|
|
|
|
|
|
|
|
|
|
\subsection sma_operations Operations
|
|
|
|
|
|
|
|
|
|
To yield better approximations of the geometry, some operations are available:
|
|
|
|
|
For interactive use, the approach can yield better approximations of the geometry and tunnel out of local minima via additional operations:
|
|
|
|
|
- <b>Merging</b>. Merging two adjacent regions.
|
|
|
|
|
- <b>Splitting</b>. Splitting larger region into smaller ones to reduce the error. It is a reverse operation to merging.
|
|
|
|
|
- <b>Adding</b>. Adding a proxy to further reduce the approximation error. As for the seeding process, we can choose between either incremental or hierarchical addition.
|
|
|
|
|
- <b>Teleportation</b>. It is a combination of merging and adding proxies: merging the local minimum region to its adjacent area and adding a proxy seed to the worst region.
|
|
|
|
|
- <b>Teleportation</b>. It is a combination of merging and adding proxies: merging the local minimum region to its adjacent area and adding a proxy seed to the worst region. More specifically, the pair of regions whose merging realizes the smallest error after merging and local re-fitting, is selected for merging.
|
|
|
|
|
|
|
|
|
|
\cgalFigureBegin{operations, operations.png}
|
|
|
|
|
Operations on the sphere-cube union model. Left: partition of 20 randomly initialized proxies after 10 iterations. Right: result after one merging and one teleportation operations.
|
|
|
|
|
Operations on the sphere-cube union model. Left: partition of 20 randomly initialized proxies after 10 iterations. Right: result after one merging and one teleportation operation.
|
|
|
|
|
\cgalFigureEnd
|
|
|
|
|
|
|
|
|
|
As depicted in \cgalFigureRef{operations}, teleportation provides a means to relocate a local minimum region entrapped in the planar plart (left) to the most needed regions on the sphere (right). In \ref sma_example3, the class interface is used to control the approximation process with above operations.
|
|
|
|
|
|
|
|
|
|
\subsection sma_extraction Mesh Extraction
|
|
|
|
|
|
|
|
|
|
This package also implements the meshing algorithm described in \cgalCite{cgal:cad-vsa-04}. More specifically, it attaches an anchor point to each intersection vertex and approximate the boundary of the geometry partition. Each polygon boundary is then triangulated and assembled to produce the output mesh. As there is no guarantee that the output mesh is 2-manifold and oriented, we provide an alternate output in the form of a triangle soup (indexed triangle set).
|
|
|
|
|
|
|
|
|
|
This package implements the meshing algorithm described in \cgalCite{cgal:cad-vsa-04}. More specifically, it attaches an anchor point to each intersection vertex and approximate the boundary of the geometry partition. Each polygon boundary is then triangulated and assembled to produce the output mesh. As there is no guarantee that the output mesh is 2-manifold and oriented, the main input is an indexed triangle set, and additional output is possible in the form of a polyhedral surface mesh.
|
|
|
|
|
|
|
|
|
|
\cgalFigureBegin{meshing, meshing.png}
|
|
|
|
|
Meshing the bear model with decreasing target error drop.
|
|
|
|
|
From left to right, the target error drop are 6\%, 4\% and 2\% to the initial error respectively, the output mesh densify.
|
|
|
|
|
From left to right, the target error drop are 6\%, 4\% and 2\% to the initial error respectively, the output mesh densifies.
|
|
|
|
|
Notice the boundary subdivision in the black rectangle area.
|
|
|
|
|
\cgalFigureEnd
|
|
|
|
|
|
|
|
|
|
In \cgalFigureRef{meshing}, the bear model is approximated through \f$ \mathcal{L}^{2,1} \f$ metric and the number of proxies are determined by error drop.
|
|
|
|
|
In \cgalFigureRef{meshing}, the bear model is approximated through \f$ \mathcal{L}^{2,1} \f$ metric and the final number of proxies is determined by monitoring the error drop.
|
|
|
|
|
The anchor points (black) are attached to the corresponding vertex on the mesh (white).
|
|
|
|
|
The red lines connecting the anchor points approximate the boundary of each region.
|
|
|
|
|
|
|
|
|
|
When approximate the boundary of the proxy region, the recursive chord-length subdividing technique described in \cgalCite{cgal:cad-vsa-04} is used to give better approximation as illustrated in \cgalFigureRef{meshing}. Basically, we add an extra anchor point when the furthest vertex of distance \f$ d \f$ on the boundary arc \f$ (\mathbf{a}, \mathbf{b}) \f$ is too far away. The subdivision criterion is defined as:
|
|
|
|
|
\f[ d\cdot sin(\mathbf{N}_i,\mathbf{N}_j)/\Vert(\mathbf{a}, \mathbf{b})\Vert, \f]
|
|
|
|
|
where \f$ \mathbf{N}_i,\mathbf{N}_j \f$ is the normal of the proxies separated by the boundary arc \f$ (\mathbf{a}, \mathbf{b}) \f$.
|
|
|
|
|
If the angle between proxy \f$ P_i \f$ and \f$ P_j \f$ is rather small, even a coarse approximation of the boundary will do: it does not add geometric information on the shape.
|
|
|
|
|
When approximate the boundary of the proxy region, the recursive chord-length subdividing technique described in \cgalCite{cgal:cad-vsa-04} is used to give better approximation as illustrated in \cgalFigureRef{meshing}. More specifically, we add an extra anchor point when the furthest vertex of distance \f$ d \f$ on the boundary arc \f$ (\mathbf{a}, \mathbf{b}) \f$ is too far away. The subdivision criterion is defined as: \f[ d\cdot sin(\mathbf{N}_i,\mathbf{N}_j)/\Vert(\mathbf{a}, \mathbf{b})\Vert, \f]
|
|
|
|
|
where \f$ \mathbf{N}_i,\mathbf{N}_j \f$ is the normal of the proxies separated by the boundary arc \f$ (\mathbf{a}, \mathbf{b}) \f$. If the angle between proxy \f$ P_i \f$ and \f$ P_j \f$ is rather small, even a coarse approximation will do as it does not add geometric information on the shape.
|
|
|
|
|
On the contrary, when there is a large angle in between the two proxies, a more accurate discretization is desirable. \cgalCite{cgal:cad-vsa-04}
|
|
|
|
|
|
|
|
|
|
\subsection sma_api API
|
|
|
|
|
@ -160,7 +144,7 @@ Class interface:
|
|
|
|
|
- `CGAL::VSA::Mesh_approximation`: allowing more customization of the proxy, metric and approximation process.
|
|
|
|
|
|
|
|
|
|
The input of the algorithm is expected to be:
|
|
|
|
|
- Combinatorially 2-manifold
|
|
|
|
|
- Combinatorially 2-manifold and oriented
|
|
|
|
|
- Triangulated
|
|
|
|
|
|
|
|
|
|
\section sma_examples Examples
|
|
|
|
|
@ -169,14 +153,15 @@ The input of the algorithm is expected to be:
|
|
|
|
|
|
|
|
|
|
The following example calls the free function `CGAL::VSA::mesh_approximation()` on the input triangle mesh with default `CGAL::VSA::L21_metric`.
|
|
|
|
|
|
|
|
|
|
\cgalExample{Surface_mesh_approximation/vsa_approximation_example.cpp}
|
|
|
|
|
\cgalExample{Surface_mesh_approximation/vsa_simple_approximation_example.cpp}
|
|
|
|
|
|
|
|
|
|
Note that the function parameters are provided through \ref namedparameters.
|
|
|
|
|
To set the non-default parameter values, we just need to call the functions with the name of the required parameters connected by a dot in an arbitrary order like:
|
|
|
|
|
Note that the function parameters are provided through \ref namedparameters. To set the non-default parameter values, we need to call the functions with the name of the required parameters connected by a dot in an arbitrary order as follows:
|
|
|
|
|
|
|
|
|
|
TODO: add output indexed face set
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// input: input triangle surface mesh
|
|
|
|
|
// output: output polyhedron surface mesh
|
|
|
|
|
// output: indexed face set
|
|
|
|
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
|
|
|
|
typedef CGAL::VSA::Plane_proxy<Kernel::VSA> Plane_proxy;
|
|
|
|
|
typedef std::map<face_descriptor, std::size_t> Facet_index_map;
|
|
|
|
|
@ -188,7 +173,7 @@ BOOST_FOREACH(face_discreptor f, faces(input))
|
|
|
|
|
Facet_proxy_pmap fpxmap(fidx_map);
|
|
|
|
|
// plane proxies;
|
|
|
|
|
std::vector<Plane_proxy> proxies;
|
|
|
|
|
CGAL::VSA::mesh_approximation(input, output,
|
|
|
|
|
CGAL::VSA::mesh_approximation(input,
|
|
|
|
|
CGAL::VSA::parameters::min_error_drop(err_drop) // init the algorithm by target error drop
|
|
|
|
|
.init_method(method) // set proxy seeding method in the initialization
|
|
|
|
|
.iterations(num_iterations) // set number of fitting iterations after initialization
|
|
|
|
|
@ -201,11 +186,11 @@ CGAL::VSA::mesh_approximation(input, output,
|
|
|
|
|
...
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
With the facet proxy index map and the output proxies, we render the partition and the proxy parameters as illustrated in \cgalFigureRef{relaxation}, etc.
|
|
|
|
|
With the facet proxy index map and the output proxies, we render the partition and the proxy parameters as illustrated in \cgalFigureRef{relaxation}.
|
|
|
|
|
|
|
|
|
|
\subsection sma_example2 Free Function Segmentation
|
|
|
|
|
|
|
|
|
|
It is also possible to use the package as a partition algorithm with the free function `CGAL::VSA::mesh_segmentation()` with the default `CGAL::VSA::L21_metric` approximation:
|
|
|
|
|
The package can be used for segmenting via the free function `CGAL::VSA::mesh_segmentation()`, with the default `CGAL::VSA::L21_metric` approximation:
|
|
|
|
|
|
|
|
|
|
\cgalExample{Surface_mesh_approximation/vsa_segmentation_example.cpp}
|
|
|
|
|
|
|
|
|
|
|