Overview
Click on the menu bar items to navigate to chapters
Click here for PDF version
VU Fundamentals of
Geometry Processing
Mesh Decimation
Julian Rakuschek
26.03.2026
Given a highly dense mesh how can we reduce
the amount of triangles while preserving features?
Given $\mathcal{M} = (\mathcal{V}, \mathcal{F})$ find $\mathcal{M}' = (\mathcal{V}', \mathcal{F}')$ s.t.
$\mathcal{M}$
$\mathcal{M}'$
Divide space around mesh into cells, $\epsilon \times \epsilon$, where $\epsilon$ is the approximation tolerance.
Inspired by [M. Pauly, "Mesh Decimation", 2006] -- Modified Example
Compute the cell representative $p$ for each cell cluster: Assign all vertices $p_1, \dots, p_k$, within this cell to $p$.
In this case, the center of each cell has been chosen.
Then connect $p$ and $x$ if $p_i \in {p_1, \dots, p_k}$ was connected to any $x_i \in {x_1, \dots, x_l}$
Many cells can become degenerate faces.
In the final step we therefore remove any degenerate faces.
There are several options to position the new cell reprsentative $p$:
Imagine a cell with three faces and two vertices.
We can now elongate the supporting planes of each face.
The resulting cell representative is the point that minimizes the (squared) distance to all supporting planes.
Consider one triangle $t_i$ within the current cell of interest.
Let $P_i = (\textbf{x}_i, \textbf{n}_i)$ be the supporting plane of this triangle.
The squared distance of a point $\textbf{x}$ from the plane $P_i$ can be computed as
\[ \text{dist}^2 (\textbf{x}, P_i) = (\textbf{n}_i^T \textbf{x} - \textbf{n}_i^T \textbf{x}_i)^2 \]Remember: $\textbf{x}_i$ is a point on the plane, while $\textbf{x}$ can be any point in space.
($\text{dist}^2$ is copied from previous slide)
\[ \text{dist}^2 (\textbf{x}, P_i) = (\textbf{n}_i^T \textbf{x} - \textbf{n}_i^T \textbf{x}_i)^2 \]Using homogeneous coordinates $\bar{\textbf{x}} = (\textbf{x}, 1)$ and $\bar{\textbf{n}}_i = (\textbf{n}_i, − \textbf{n}_i^T \textbf{x}_i)$
the above equation simplifies to
The sum of the quadratic distances to the supporting planes $P_i$ of all triangles $t_i$ within a cell $C$ is given by
\[ E(\textbf{x}) = \sum_{t_i \in C} \bar{\textbf{x}}^{T} \, \textbf{Q}_i \, \bar{\textbf{x}} = \bar{\textbf{x}}^{T} \left( \sum_{t_i \in C} \textbf{Q}_i \right) \bar{\textbf{x}} =: \bar{\textbf{x}}^{T} \, \textbf{Q} \, \bar{\textbf{x}}. \]quadric error metric (QEM)
The final cell representative $\textbf{x}_c$ is computed by finding an $\textbf{x}$ that minimizes $E$:
\[ \textbf{x}_c = \argmin_\textbf{x} E(\textbf{x}) \]To derive a solution, we first now decompose the matrix $\textbf{Q}$ again:
\[ E(\textbf{x}) = \bar{\textbf{x}}^{T} \textbf{Q} \bar{\textbf{x}} = \bar{\textbf{x}}^{T} \left( \sum_{t_i \in C} \textbf{Q}_i \right) \bar{\textbf{x}} = \bar{\textbf{x}}^{T} \begin{bmatrix} \sum_i \textbf{n}_i \textbf{n}_i^T & -\sum_i (\textbf{n}_i^T \textbf{x}_i)\textbf{n}_i \\ -\left(\sum_i (\textbf{n}_i^T \textbf{x}_i) \textbf{n}_i\right)^T & \sum_i (\textbf{n}_i^T \textbf{x}_i)^2 \end{bmatrix} \bar{\textbf{x}} \]Nota bene — this is not a $2 \times 2$ matrix, it is a symmetric $4 \times 4$ matrix:
\[ \sum_i \textbf{Q}_i = \begin{bmatrix} \sum_i \textbf{n}_i \textbf{n}_i^T \;\;\textcolor{red}{\in \mathbb{R}^{3\times 3}} & -\sum_i (\textbf{n}_i^T \textbf{x}_i) \textbf{n}_i \;\;\textcolor{red}{\in \mathbb{R}^{3\times 1}} \\ -\left(\sum_i (\textbf{n}_i^T \textbf{x}_i) \textbf{n}_i\right)^T \;\;\textcolor{red}{\in \mathbb{R}^{1\times 3}} & \sum_i (\textbf{n}_i^T \textbf{x}_i)^2 \;\;\textcolor{red}{\in \mathbb{R}} \end{bmatrix} \]We can now simplify the notation again:
\[ \sum_i \textbf{Q}_i = \begin{bmatrix} \sum_i \textbf{n}_i \textbf{n}_i^T & -\sum_i (\textbf{n}_i^T \textbf{x}_i)\textbf{n}_i \\ -\left(\sum_i (\textbf{n}_i^T \textbf{x}_i) \textbf{n}_i\right)^T & \sum_i (\textbf{n}_i^T \textbf{x}_i)^2 \end{bmatrix} := \begin{bmatrix} \mathbf{A} & -\mathbf{b}\\ -\mathbf{b}^T & c \end{bmatrix} \]The QEM is then rewritten as follows:
\[ E(\mathbf{x})=\bar{\mathbf{x}}^{T}\mathbf{Q}\bar{\mathbf{x}}, \qquad \bar{\mathbf{x}}= \begin{bmatrix} \mathbf{x}\\ 1 \end{bmatrix}, \qquad \mathbf{Q}= \begin{bmatrix} \mathbf{A} & -\mathbf{b}\\ -\mathbf{b}^T & c \end{bmatrix}. \] \[ E(\mathbf{x}) = \begin{bmatrix} \mathbf{x}^T & 1 \end{bmatrix} \begin{bmatrix} \mathbf{A} & -\mathbf{b}\\ -\mathbf{b}^T & c \end{bmatrix} \begin{bmatrix} \mathbf{x}\\ 1 \end{bmatrix} \]This is a quadratic function.
To find the minimal value of this function, we take the derivative and set it to zero.
This is a least squares system.
\[ \mathbf{x} = \mathbf{A}^{-1}\mathbf{b} \]
Remove one vertex at a time as long as
\[ ||\mathcal{M} - \mathcal{M}'|| < \epsilon \]In each step the best candidate for removal is determined.
Each of the listed decimation operators is reversible.
[Botsch, Mario et al. “Polygon Mesh Processing.” (2010).]
Coming back to this: How can we triangulate the hole?
We strongly prefer convex holes.
In a planar convex polygon, all internal angles are at most 180°. Convex polygons can be easily triangulated from any vertex.
If a polygon is non-convex, that is there are internal angles > 180°, then extra care has to be taken to avoid creating overlaps and self-intersections.
green edges are safe, red edges cause problems
Assume we want to check if the neighborhood of vertex $x$ is convex.
The m-sided hole which appears in a mesh by removing a vertex usually does not lie exactly in a 2D plane, so the notion of convexity does not make sense. Simple solution: Analyse 2D image of 3D hole.
To do that, we first need a suitable viewing angle on the neighborhood.
Looking at it from the side is probably not a good idea ...
... but the front is much better!
We need to find a direction from which we look at the hole. For this we compute the average normal vector of all adjacent faces of a vertex.
\[ n = \frac{\sum_i A_i n_i}{\sum_i A_i} \]Where $A_i$ is the area of each adjacent face with $n_i$ being the normal. This is an area-weighted average.
Looking in the direction of $n$ gives us the 2D image of the neighborhood.
Suppose the cyclic ordering of vertices $v_0, v_1, \dots, v_{m-1}$ of a planar $m$-gon is such that the polygon is traversed counter-clockwise.
Then the internal angle $\alpha_i$ is computed from
\[ \sin \textcolor{purple}{\alpha_i} = \sin(180° - \textcolor{purple}{\alpha_i}) = \left< \left( \left( \textcolor{blue}{\frac{v_i - v_{i-i}}{|v_i - v_{i-i}|}} \right) \times \left( \textcolor{red}{\frac{v_{i+1} - v_i}{|v_{i+1} - v_i|}} \right) \right), \frac{n}{|n|} \right> \]
where the normal vector $n$ is pointing towards the eye of the viewer.
Collapsing an edge $(p, q)$ is a valid operation if and only if the following two criteria hold [Hoppe et al. 93]:
If both $p$ and $q$ are boundary vertices, then the edge $(p, q)$ has to be a boundary edge.
For all vertices $r$ incident to both $p$ and $q$ there has to be a triangle $(p, q, r)$. In other words, the intersection of the one-rings of $p$ and $q$ consists of vertices opposite the edge $(p, q)$ only.
How do we find the best removal candidate?
Incremental mesh decimation ranks all removal operations. Ranking may be defined by
Greedy Reduction
For each region:
Repeat until no further reduction possible:
With Error Control
For each region:
Repeat until no further reduction possible:
The error control stops the decimation when the quality becomes too bad.
Formula for $D$ can be found in the assignment sheet.
The distance to the average plane is a local error metric: Measures the distance between a face and a subpatch.
Remember: We want to remove vertices whose absence is barely noticeable. Removing the spike would remove an important feature that can make the difference in ML models (for example).
The Hausdorff Distance — a global error metric
This distance measure is defined to be the maximum minimum distance. If we have two sets $A$ and $B$, then $H(A,B)$ is found by computing the minimum distance $d(a,B)$ for each point $a \in A$ and then taking the maximum of those values: \[ H(A,B) = \max_{a \in A} \min_{b \in B} \lVert a - b \rVert . \] Notice that, in general, $H(A,B) \neq H(B,A)$. The symmetric Hausdorff distance is defined as the maximum of both values: \[ d_H(A,B) = \max\big(H(A,B),\, H(B,A)\big). \]
Computing the Hausdorff distance for a mesh:
Vertex Clustering
Iterative Decimation