Computer Graphics · Geometry Representation

Mesh Parameterization, Cuts, and the Distortion That Cannot Be Removed

Mapping a surface to the plane requires cutting it into a disk, and every planar map of a curved surface must distort either angles or areas by a measurable amount.

Texture coordinates are a map from a surface to a plane, and the map is a piece of geometry in its own right. It has a Jacobian at every point, and the singular values of that Jacobian measure how a small circle on the surface becomes an ellipse in the texture. A map is conformal when the ellipse is a circle at every point, meaning the Jacobian is a scalar times a rotation, so angles are preserved; it is isometric when the scalar is 1 everywhere, which is possible only for developable surfaces. Everything else is a compromise, and the compromises are quantified by how far the singular values diverge.

The disk requirement and the cuts it forces

A planar parameterization is a continuous map from the surface into $\mathbb{R}^2$, one-to-one and with a continuous inverse inside the domain. A closed sphere-like surface has no such map: the plane is simply connected and unbounded, a sphere is compact, so any continuous map must fold somewhere. The requirement, stated precisely, is that the surface be a topological disk: genus zero with a single boundary loop.

Every model that is not a disk must be cut until it is. A torus needs two cuts: one meridian opens it into an annulus with two boundary loops, and a second cut joining those loops yields a disk. A sphere needs one closed cut, which splits it into two disks that become two charts. A pair of trousers, that is, genus zero with three boundary loops, needs two cuts joining the three loops into one. Finding a short set of such cuts is a path problem on the cut graph, solved in practice with a tree-cotree decomposition of the mesh’s edges.

The cut is not visible in the renderer, but it is visible in the texture: the texels along the cut are unrelated to those on the far side, so a filter that samples across the seam reads the wrong content. The usual remedy is to duplicate the seam vertices in the mesh, so that the two sides of the cut have distinct texture coordinates, and the vertex count grows by the number of cut edges. A cut through a character’s back may duplicate a few hundred vertices; a cut through a dense region duplicates correspondingly more.

Distortion measures and why one cannot be zero

Take a triangle on the surface with area $A_s$ and its image with area $A_t$. The area distortion is the ratio, and a map with a constant ratio everywhere is called equiareal. Take two curves crossing at angle $\theta$ on the surface; their images cross at some angle $\theta’$. Angle distortion measures $|\theta - \theta’|$, and a map with zero angle distortion everywhere is conformal.

Both cannot hold simultaneously except on a developable surface. The reason is Gauss’s Theorema Egregium: Gaussian curvature is intrinsic, preserved by any isometry, and a plane has zero curvature everywhere. A surface with nonzero Gaussian curvature, which includes every sphere-like blob and every saddle, cannot be flattened without changing lengths somewhere. A conformal map preserves angles and therefore preserves the metric up to a scale factor that varies; at a point of positive curvature the scale factor must shrink in a way that no constant factor can match, so area distortion is forced. An equiareal map preserves areas and must shear angles. A map minimizing a weighted sum of both is what practical parameterizers produce.

The singular values $\sigma_1 \ge \sigma_2$ of the Jacobian make this concrete. Conformality is $\sigma_1 = \sigma_2$. Isometry is $\sigma_1 = \sigma_2 = 1$. The quasi-conformal distortion is $\sigma_1/\sigma_2$, a number at least 1, equal to 1 exactly where the map is conformal. The area scale is $\sigma_1 \sigma_2$. A single triangle contributes a local distortion value, and a mesh’s total distortion is a norm over all triangles. An area-weighted sum of squared logarithms is the standard choice, because it is symmetric under inversion of the ratio and penalizes both stretching and compression.

Measuring one triangle needs only the 3D positions and the texture coordinates, since the Jacobian is constant across a triangle under a linear map.

import numpy as np

def distortion(p, uv):
    """Quasi-conformal distortion of one triangle: sigma1 / sigma2, at least 1."""
    e1, e2 = p[1] - p[0], p[2] - p[0]
    n = np.cross(e1, e2)
    n /= np.linalg.norm(n)
    x = e1 / np.linalg.norm(e1)
    y = np.cross(n, x)                            # orthonormal frame in the triangle plane
    a = np.array([[e1 @ x, e1 @ y], [e2 @ x, e2 @ y]])   # the two edges, in that frame
    b = np.array([uv[1] - uv[0], uv[2] - uv[0]])         # the same edges, in texture space
    j = np.linalg.solve(a, b)                     # linear map from the frame to UV space
    s = np.linalg.svd(j, compute_uv=False)
    return float(s[0] / s[1])

def folded(uv):
    """True when the mapped triangle has negative signed area."""
    u1, u2 = uv[1] - uv[0], uv[2] - uv[0]
    return u1[0] * u2[1] - u1[1] * u2[0] < 0.0

An identity map returns exactly 1, a uniform scale returns 1 as well because both singular values scale together, and scaling only the $u$ coordinate by 2 returns 2. Note what the function does not do: it says nothing about a triangle so small that the frame’s normal is numerically meaningless. A degenerate triangle with near-zero area has an ill-conditioned $a$, and the solve returns noise rather than a distortion.

The linear system at the centre of it

The oldest and still common approach treats the map as a pair of scalar functions over the mesh, one for $u$ and one for $v$, and minimizes a Dirichlet energy over them. Write the map’s gradient on each triangle as a linear function of the triangle’s three texture coordinates, and the energy becomes a quadratic form $\mathbf{u}^\top L \mathbf{u} + \mathbf{v}^\top L \mathbf{v}$, where $L$ is the cotangent Laplacian assembled from the mesh’s geometry.

The cotangent weight for the edge between vertices $i$ and $j$, opposite to the angle $\alpha$ at the third vertex of one adjacent triangle and $\beta$ at the third vertex of the other, is $\tfrac{1}{2}(\cot \alpha + \cot \beta)$. Negative weights appear whenever an angle exceeds $\frac{\pi}{2}$, which happens on any mesh with an obtuse triangle, and negative weights break the maximum principle: the solution can overshoot and the map can fold. This is not a numerical detail. It is the reason a plain cotangent parameterization of a coarse mesh folds, and why implementations add a barrier that prevents triangle flips or fall back to a different energy.

Minimizing the Dirichlet energy subject to fixed boundary positions gives a harmonic map, which is conformal in the interior in the continuous setting. The catch is that a harmonic map’s conformality does not extend to the boundary, and the boundary’s shape is chosen by the user or by the cut. Fixing the boundary to a circle produces the cotangent-style map; leaving it free and solving for it produces a map that is closer to conformal overall but requires a nonlinear solve, because the boundary condition is no longer a linear constraint.

Angle-based and cone-based formulations

The angle-based approach abandons coordinates as the variables. Instead, it treats the triangle angles themselves as unknowns, constrained to sum to $\pi$ in each triangle, to equal $2\pi$ at each interior vertex, and to leave the prescribed total curvature at the boundary. The objective penalizes deviation of each angle from its original value on the surface, weighted to make the distortion measure invariant under rotation and scale.

The advantage is that the constraints are linear in the angles and the objective is separable, so the optimization is a constrained least-squares problem that can be solved with a sparse system. The disadvantage is that the angles are not independent: they must satisfy the triangle inequalities and be positive, and the solve is iterative, with an active set to keep angles in range. The ABF++ formulation reduces the cost by eliminating variables and caching the factorization across iterations, which matters because the number of iterations is not bounded a priori.

A cone-based approach places the singularities deliberately. The total angle defect around each interior vertex is fixed by the surface’s Gaussian curvature: for a vertex with incident triangle angles summing to $\sum \theta$, the angle defect is $2\pi - \sum \theta$, and the discrete curvature is that defect. A conformal map can only place angle defects at designated cone points with prescribed values, and everything else must have zero defect. Choosing the cone points, which is where the map concentrates the unavoidable distortion, is the design decision, and the optimization then finds the flattest map consistent with those choices. A good choice puts the cones at high-curvature tips and at the ends of the cut.

This is the same curvature accounting that governs subdivision limit surfaces, where the extraordinary vertices are points of concentrated curvature in the discrete sense. A quad mesh cannot be flattened to a regular grid at an extraordinary vertex for exactly the reason a cone must be placed there.

Seams, texel density, and the operational failure modes

Distortion is not the only constraint on a usable map. Texel density uniformity, the property that a unit of surface area maps to a constant number of texels, is what prevents one region being blurry while another is sharp. A map that is conformal but strongly varying in scale has uniform angles and uneven density, so a renderer with a fixed texture resolution gets blurry patches. This is why practical pipelines optimize a weighted combination rather than pure conformality, and why a conformal map is often rescaled per-chart afterward.

Density also determines what decimation can preserve, because a collapse that moves a vertex in UV space changes the local mapping scale. A decimator that treats texture coordinates as an attribute with a fixed weight will flatten a chart’s density variation without any visible geometric error, which shows up later as uneven sharpness in the rendered surface.

Chart packing introduces its own distortions at the boundaries. Charts are rectangles in practice because the texture atlas is a rectangle, and a chart whose parameter domain is an irregular blob wastes atlas space. The waste is the packing efficiency, and a typical atlas leaves a meaningful fraction of its texels unused along chart borders, which the sampler must be kept away from by a gutter.

The numerical failure mode is folding: a triangle whose image has negative signed area, meaning the map reverses orientation locally. A folded triangle is invisible in the texture map and produces a visual artifact that looks like a hole or a mirrored patch. Detecting it is a sign test on each mapped triangle’s area, cheap and mandatory, and folding is the diagnostic that distinguishes a parameterization that converged from one that merely stopped. Any pipeline that relaxes a fold-prevention constraint to gain speed tends to produce maps that pass distortion metrics and fail this test.

References

  1. ABF++: Fast and Robust Angle Based Flattening — Sheffer, Levy, Mogilnitsky, Bogomyakov, ACM Transactions on Graphics, 2005
  2. Polygon Mesh Processing — Botsch, Kobbelt, Pauly, Alliez, Levy, A K Peters
  3. Geometry and the Imagination — Hilbert & Cohn-Vossen, Chelsea Publishing
  4. Computational Conformal Geometry — Gu & Yau, International Press