Lattice and Cage Deformers

Suppose you have sculpted a beautiful character — tens of thousands of vertices, every wrinkle in place — and now the director wants the whole belly to bulge, or the ear to droop, or the loaf of bread to sag in the middle. You do not want to grab those tens of thousands of vertices by hand. Instead you drop the model inside a cage: a coarse control mesh with a handful of vertices that surrounds the shape. Grab a cage vertex, drag it, and the enclosed model flows along with it — smoothly, as if it were embedded in a piece of clear jelly you are squeezing.

You have already met the box version of this idea in free-form deformation (FFD), where the cage is a regular rectangular lattice of control points. This page pushes the idea to its general form: the cage can be any closed mesh hugging the model, and every interior point is written as a weighted blend of the cage's vertices via generalised barycentric coordinates. The whole art is in choosing which weighting scheme — and each choice buys different behaviour.

The one big idea: bind once, deform forever

Barycentric coordinates for a triangle should feel familiar: any point inside a triangle with corners v_0, v_1, v_2 can be written p = \lambda_0 v_0 + \lambda_1 v_1 + \lambda_2 v_2 with the weights \lambda_i \ge 0 summing to 1. Generalised barycentric coordinates extend exactly this to a cage with any number of vertices.

Because the weights are frozen at bind time, deformation costs one weighted sum per model vertex, no matter how the cage is dragged around. This is exactly the shape of skinning, where a mesh vertex is a weighted blend of moving bones — the cage's vertices are just a different kind of handle, and \lambda_i is again a weight.

Worked example: the centre of a square cage

Take the simplest interesting cage: a square with corners v_0, v_1, v_2, v_3, and pick the point right at its centre. By symmetry, the centre "sees" all four corners identically, so its generalised barycentric weights are equal:

\lambda_0 = \lambda_1 = \lambda_2 = \lambda_3 = \tfrac14, \qquad \sum_i \lambda_i = 1.

Now drag corner v_0 outward by a displacement d, leaving the other three fixed. The new centre is

p' = \tfrac14 (v_0 + d) + \tfrac14 v_1 + \tfrac14 v_2 + \tfrac14 v_3 = p + \tfrac14\, d.

The centre moves by exactly one quarter of the corner's displacement — its weight on that corner. Move a corner by 4 units and the centre shifts by 1. This is the golden rule of cage deformation: each interior point follows a moved vertex in proportion to its weight on that vertex. Points hugging a corner have a large weight there and follow it eagerly; points across the cage have a tiny weight and barely stir.

A point off-centre breaks the symmetry: nearer a corner, its weight there climbs toward 1; far from it, toward 0. Mean-value coordinates give a clean closed form for those weights on any polygon.

Mean-value coordinates: a formula for any cage

The mean-value coordinates (MVC) scheme is the workhorse closed form. For an interior point p and a cage vertex v_i, let r_i = \lVert v_i - p \rVert be the distance to the vertex and \alpha_i the angle at p subtended by the edge from v_i to v_{i+1}. The unnormalised weight is

w_i = \frac{\tan(\alpha_{i-1}/2) + \tan(\alpha_i/2)}{r_i}, \qquad \lambda_i = \frac{w_i}{\sum_j w_j}.

MVC are wonderfully general: they are defined for any polygon in 2-D or polyhedron in 3-D, convex or not, and they interpolate the cage smoothly. That generality is why they became a default. But there is a catch hiding in that \tan(\alpha/2): near a non-convex cage, or for points outside it, the angles can make w_i — and therefore \lambda_i — go negative.

See it move

Below is a cage (the outlined pentagon) with a scatter of interior points bound to it by mean-value coordinates. Pull the highlighted top vertex with the slider. Watch how the points nearest that vertex — which carry the largest weight on it — surge along with it, while points down at the far side, whose weight is nearly zero, hardly budge. The faint dots mark where every point started, so you can read each point's displacement as (its weight on the vertex) × (the vertex's displacement).

This is the entire mechanism: no per-point hand-editing, just one vertex handle and a frozen table of weights doing the interpolation.

Mean-value coordinates do not guarantee \lambda_i \ge 0. For a point near a reflex (dented-in) part of a non-convex cage, or for anything slightly outside the cage, some weights come out negative. A negative weight is not a rounding glitch — it has a very visible consequence. Recall the golden rule: a point moves by \lambda_i\, d when vertex i is displaced by d. If \lambda_i \lt 0, the point moves opposite to the vertex you dragged. Pull a cage vertex up and a nearby patch of the model sinks down, or bulges out through the cage wall where you never wanted it. Animators see this as an ugly overshoot or self-intersection that appears only in certain poses.

Harmonic coordinates fix this by construction — they are non-negative everywhere, so no interior point can ever run the wrong way. If your cage is convex, MVC stay non-negative and you are safe; the danger lives in concavities.

Harmonic coordinates: non-negative by construction

Harmonic coordinates trade the tidy closed form of MVC for a small numerical solve, and get non-negativity in return. For each cage vertex v_i you define a weight field \lambda_i(p) that equals 1 at v_i, falls to 0 at the other vertices, interpolates linearly along the cage edges, and — crucially — is harmonic in the interior: it satisfies Laplace's equation

\nabla^2 \lambda_i = 0 \quad \text{inside the cage.}

This locality and non-negativity is why Pixar developed harmonic coordinates for "Ratatouille" (2007): the deformers had to bend limbs and faces built from concave cages without the flesh punching through the cage or a moving arm dragging the torso with it. The price is that the weights come from a grid solve rather than a formula, so binding is heavier and the result is only as accurate as the grid is fine.

Green coordinates: keep the local shape

MVC and harmonic coordinates both write the point as a blend of cage vertex positions only. Green coordinates add a second ingredient — the cage face normals — into the blend:

p' = \sum_i \phi_i\, v_i' + \sum_f \psi_f\, s_f\, n_f',

where n_f' is the (scaled) normal of deformed face f. Feeding the normals in lets the deformation carry the cage's local rotation and stretch, so the enclosed detail is transported quasi-conformally — angles and local shape are preserved far better, and fine features do not shear or collapse when the cage twists. The trade-off: Green coordinates are not strictly interpolating (the model can float slightly relative to a moved cage boundary), which is usually a fine price for the extra rigidity.

A rough field guide. Mean-value coordinates: cheap closed form, any cage — reach for it first when the cage is convex and you want speed. Harmonic coordinates: when the cage is concave and you cannot tolerate overshoot or leakage across gaps — the "Ratatouille" choice — at the cost of a grid solve. Green coordinates: when preserving the local shape and rotation of fine detail under a twisting cage matters more than exact interpolation. All three are the same template — an interior point as a weighted blend of cage handles — differing only in how the weights are cooked.

FFD is just a box-shaped cage

With the general picture in hand, free-form deformation snaps into place as a special case. An FFD lattice is nothing but a cage whose vertices are laid out on a regular rectangular grid, and whose generalised barycentric coordinates happen to be a tensor product of Bézier (or B-spline) basis functions. Move a lattice control point and the enclosed model deforms by the same rule — a weighted blend of moving handles. Cage deformation simply frees the handles from the grid: the cage can be a loose, close-fitting shell around a hand or a face, so a few well-placed vertices give control exactly where the model needs it, instead of a coarse box that wastes control points on empty corners.

SchemeCageWeights ≥ 0?CostSpecial strength
FFD latticeregular box gridyes (Bézier basis)cheapsimple, familiar box control
Mean-valueany polygon/polyhedronnot guaranteedcheap (closed form)works on any cage
Harmonicany (esp. concave)yesgrid solveno overshoot, interior-local
Greenanymoderatequasi-conformal, keeps local shape