
Building
Your Own Subdivision Surfaces
By
Aaron
Lee
Gamasutra
September
8 , 2000
URL: http://www.gamasutra.com/features/20000908/lee_01.htm
Everyone who loves Quake 3 is impressed by the high quality graphics, light maps, and character animations. Although they have done an excellent job in painting the textual details, most of their characters consist of only several hundred triangles which cannot capture highly detailed geometry. In recent years, subdivision surfaces have received a lot of attention from both academics and industry professionals, people in the movie industry even apply subdivision techniques to create complex characters and produce highly detailed, smooth animation. This article examines how to convert triangular meshes (which is one of the most popular data representations) into subdivision surfaces.
What are Subdivision Surfaces?
The idea of subdivision surfaces was first introduced by Catmull & Clark
and Doo & Sabin in 1978. Unlike traditional spline surfaces, subdivision
surfaces are defined algorithmically. Recently there has been a lot of activity
in the computer graphics research community and significant advances have been
made in rendering, texture mapping, animation and compression of subdivision
surfaces. They were also used in the production of Geri's Game and A
Bug's Life. Geri's hands, head, jacket, and pants were each modeled using
a single subdivision surface. The faces and the hands of Flick and Hopper were
also modeled with subdivision surfaces. Momentum is building in the computer
assisted geometric design (CAGD) to make subdivision surfaces one of the modeling
primitives.
Why Subdivision Surfaces?
Subdivision surfaces lie somewhere in between polygon meshes and patch surfaces,
and offer some of the best attributes of each. The well defined surface normal
allows them to be rendered smoothly without the faceted look of low polygon
count polygonal geometry, and they can represent smooth surfaces with arbitrary
topology (with holes or boundaries) without the restriction in patches where
the number of columns and rows has to be identical before two patches can be
merged. Secondly, subdivision surfaces are constructed easily through recursive
splitting and averaging: splitting involves creating four new faces by removing
one old face, averaging involves taking a weighted average of neighboring vertices
for the new vertices. Because the basic operations are so simple, they are very
easy to implement and efficient to execute. Also because of the recursive nature,
subdivision naturally accommodates level-of-details control through adaptive
subdivision. This allows triangle budgets to be spent in regions where more
details are needed by subdividing further.
What are the challenges?
The simple splitting process usually starts from a coarse control mesh, iterating
this process several times will produce so-called semi-regular meshes. A vertex
is regular if it has six neighbors (in triangle mesh) or four neighbors (in
quadrilateral mesh). Vertices which are not regular are called extraordinary.
Meshes that are coming from standard modeling packages or 3D scanning devices
usually do no have a regular structure, hence there is a need to convert these
irregular meshes into semi-regular meshes, a process known as remeshing. This
article presents an algorithm that maps the original mesh onto a simple control
mesh - base domain, thus deriving the parameterization for the original mesh.
Having this mapping information (parameterization) allows us to perform the
remeshing efficiently by subdividing the base domain and perturbing the new
vertices to approximate the original geometry. From a signal processing point
of view, we can treat it as a geometry resampling process. The beauty of this
algorithm is that it is very simple and easy to implement.
Preparation Before Programming
Before explaining the algorithms, lets take a look at input. Input can be any
arbitrary triangulated manifold mesh. By arbitrary we mean the mesh can have
holes or boundaries, triangulated means the surface is approximated/discretized
by a list of triangles. Manifold means it does not contain topological inconsistencies.
Topological inconsistencies include more than two triangles sharing an edge
or more than two corners meeting at one vertex. Make sure you have good, clean
geometries.
Overview of Algorithm
The conversion algorithm contains two major steps. The first step is called
mesh simplification. Mesh simplification has been well known to the game developers
for creating levesl-of-detail or catering to different bandwidth and computational
requirements. Most of the time, there is trade-off between model complexity
and interactivity - i.e. a higher frame rate requirement usually is translated
into simpler/coarser model. In this algorithm, mesh simplification is used only
as a tool to derive a base domain so that resampling/remeshing can be acomplished.
Developers are free to choose their favorite mesh simplification algorithm,
I recommend Michael Garland's error quadrics simplification algorithm because
it is open source and simple to understand. The second step is called remeshing;
the goal is to create a subdivision connectivity (semi-regular) mesh with geometry
sampled from the original mesh. As was mentioned earlier, subdividing the control
mesh does not add any extra information to the mesh but only increases the complexity
of the model. Hence there is a need to use the mapping information from the
first step so that we know how to perturb these vertices to approximate the
original mesh. (Figure 1).
![]() |
|
Figure
1. The algorithm consists of two major steps. The first is mesh simplification,
which allows us to derive the control mesh (base domain) and compute the
mapping (parameterization of the original mesh) with respect to this base
domain. The second step is geometry resampling (or remeshing). The goal
is to obtain a subdivision connectivity mesh (through subdividing the
base domain) and at the same time approximate the original mesh.
|
The 2D Case
Before diving into the 3D mapping algorithm, a look at the 2D curve case might
be in order. The notion of subdivision connectivity does not make much sense
here, but the conversion process can be treated as a regular sampling at the
dyadic points. Simplification (removing alternating vertices in each step -
as shown in Figure 2) is used to derive a simple line segment (base domain in
red). Mid points are then inserted in the middle of each line segment by performing
a linear interpolation between the two closest points (equivalent to the geometry
resampling process) to complete the second phase (as show in Figure 3).
![]() |
|
Figure
2. This figure shows the result of applying the first phase of the algorithm.
The idea is to do a simplification of the curve by removing every other
vertex. At each simplification step, the removed vertex is mapped onto
the simplified curve governed by the arc-length ratio. The end result
would be a curve which maps onto a simple base line segment.
|
![]() |
|
Figure
3. This shows the second phase of the conversion algorithm in 2D. The
yellow circles are the mid-points (analogy to the mid-points in the triangle
subdivision case) of the base domain line segments. Their coordinates
are computed from the linear interpolation of the two adjacent green vertices.
|
The 2D curve resampling process is computed as follows:
Insert a midpoint (yellow circle - dyadic point) on the red line segment (in Figure 3) and find out the two closest points (green circles) that were mapped from the original curve onto the red line segment. Then compute the ratio of the yellow circle within the two green circles. Based on the original geometry of the green circles and this ratio, we can linearly interpolate the coordinates and obtain the resample geometry of this yellow circle on the original curve.
Now with this simple idea, let's extend it to 3D.
3D Mesh Simplification
To illustrate the algorithm, I'm using Mike Garland's excellent simplification
algorithms from . The software can be downloaded from his site at http://graphics.cs.uiuc.edu/~garland
/software/qslim.html. The nice thing about this simplification is that it
is very fast and easy. It can simplify highly detailed polygonal surface models
automatically into faithful approximations containing much fewer polygons. The
core of the algorithm employs an error metric called Quadric error metric to
provide a characterization of local surface shape. This metric is both fast
to evaluate and does not take up too much memory space. The details of the algorithm
can be found at http://graphics.cs.uiuc.edu/~garland/research/thesis.html.
![]() |
|
Figure
4. The contraction of edge v1v2 will remove vertex v1 and it's adjacent
triangles (old triangles), thus creating a hole and retriangulation is
performed (new triangles are formed).
|
Propagating
mapping information
Each simplification step collapses an edge, removing one vertex and deleting
the triangles that surround the vertex and retriangulating the hole. In Figure
4, edge v1v2 is collapsed and v1 is removed. In order to preserve some form
of mapping between adjacent levels, we are going to compute a 4-tuple (a, b,
g, T) that describes which new triangle T that v1 is going to associate with.
The (a, b, g) tuple is the barycentric coordinates of v1 within the triangle
T. To perform this association for each simplification step, flatten the 1-ring
(as shown in Figure 5) of v1 onto a 2D plane. This planar flattening is achieved
by computing the za map. It involves scaling the angle sum subtend at v1 to
2p or p in the boundary case and raise the length of each edge subtend at v1
to power a.
The 4-tuple can be calculated as in Figure 5:
![]() |
|
Figure
5. To compute the 4-tuple, first flatten the 3D umbrella (1-ring) around
v1 onto a 2D plane. The scaling factor a is used to ensure the angle sum
is 2p, notice also that the length is scaled by the power a. Once the
umbrella is flattened, compute the location of v1 in the new triangulation.
|
Code Snippets
RemoveVertex(
Vertex V ) {
PlanarFlatten( V );
Valid = TryRetriangulate( V );
if ( Valid ) {
AssignParameter( V );
Reparameterize( V );
DoTriangulate( V );
};
};
The basic skeleton of the vertex removal is very simple. First perform a planar flattening to flatten the 3D 1-ring neighbors of vertex V (the umbrella) onto a 2D plane according to Figure 5 description, i.e. scaling the edge length and the angles subtended at vertex V. After flattening the umbrella use a retriangulation routine (e.g. a Delaunay triangulation) to remove the old triangles and try inserting new triangles. Make sure that the new triangles do not overlap with the existing triangles in the mesh, otherwise it will create topological inconsistencies and the mesh will not be a manifold (i.e. no more 2 triangles share an edge). If the new configuration is valid, proceed to compute the 4-tuple parameter for vertex V. The computation consists of two steps. The first step is to assign a new 4-tuple parameter for vertex V which involves the calculation of the barycentric coordinates and the associating triangle as indicated in Figure 6. The second step is to update the parameter values of those vertices which are currently associating with the old triangles. The function CalcNewParameters( Vi ) will perform the corresponding update according to Figure 7.
AssignParameter(
Vertex V) {
Tuple = CalcBaryCoord( V );
InsertTuple( V, Tuple );
};
Reparameterize( Vertex V ) {
ForEachFaceAroundVertex( V , Fi ) {
ForEachAssociatedVertex( Fi
, Vi ) {
NewTuple
= CalcNewParameters( Vi );
UpdateTuple(
Vi , NewTuple );
};
};
};
![]() |
|
Figure
6. In this figure, v1 is mapped onto the green triangle, proceed to compute
the barycentric coordinates (a, b, g) and the new triangle that v1 will
be associated with.
|
![]() |
|
Figure
7. When removing the 1-ring triangles, be sure to update the parameter
values of those vertices which were previous associated to the new triangulation.
This example shows the reparameterization of the white vertices onto the
new triangulation.
|
If there are vertices which were associated with the old triangles, we also need to update their parameters due to the retriangulation (old triangles will be destroyed). The update can be computed in way similar to the previous step.
At the end of the simplification there will be a simple control mesh, called a base domain. For each vertex that was removed in the simplification hierarchy, it will have the 4-tuple indicating which base domain triangle it is associating with and its barycentric coordinates. This complete the first phase of the algorithm.
Examples of
running the algorithm
The following images show the results of performing the first phase of the algorithm
on a 3-holes torus. Although this model is a bit simple, it does show the general
ability of the algorithm to handle a genus-3 object (containing 3 handles).
![]() |
![]() |
![]() |
![]() |
The first image shows the original triangular mesh, while the second image shows the base domain arrived at from the simplification routine. The third image demonstrates the visualization of mapping each vertex onto the base domain - thus shrink-wrapping the original mesh onto the base domain with each vertex having a 4-tuple association. The fourth image shows the result of subdividing the base domain and perturbing the new vertices to closely approximate the original mesh.
Geometry
resampling
At this point, the mapping computation is finished. One way to look at the mapping
is consider that each vertex has a 4-tuple parameter which tells which base
domain triangle it is associating with and it's location (given by the barycentric
coordinates) within this base domain triangle. Another way to visualize the
mapping is to imagine collapsing/wrapping the original mesh triangulation (treated
as a graph) on top of the base domain.
Control mesh subdivision
To create a mesh with subdivision connectivity, simply subdivide the control
mesh a few times by splitting an old triangle into four new triangles. The new
edge vertices are called dyadic points. Notice that this 1-4 split produces
vertices with 6 neighbors. All of the new vertices introduced are regular. The
most common subdivision schemes are Loop subdivision and Catmull-Clark subdivision.
Loop subdivision is a scheme for triangular meshes while Catmull-Clark subdivision
is for quadrilateral meshes. This article demonstrates the Loop subdivision
method, as it's a natural choice for triangle meshes. The limit surface of the
subdivision will be a smooth surface with C2 continuity everywhere except at
the extraordinary vertices. The next step is to perturb the vertices in such
a way that the subdivision mesh can approximate the original mesh. This is what
is called the geometry resampling.
Perturbing vertex coordinates
Before examining how to move these subdivision vertices to approximate our original
mesh geometry, there is a need to fix on some notations and introduce the edge
terminology so that the algorithims can be explained. Basically, an edge in
the mesh is represented as a directional edge containing pointers to its origin
vertex (e.Org), destination vertex (e.Dest), previous edge from its destination
vertex (e.Dprev) and next edge from its origin vertex (e.Onext), as show in
Figure 8.
![]() |
|
Figure
8. Directional edge notation and its pointers to neighboring data structures.
|
Once we define
the edge algebra we can proceed to the next step: perturbing the vertex coordinates.
![]() |
Code
Snippets
To compute the vertex coordinates for the subdivision vertices, first find the
triangle in the flatten mesh on the base domain which contains the dyadic points
(similar to the 2D case in Figure 3 where we locate the two green circles).
The triangle location problem is reduced to a point location problem. M denotes
the flattened original mesh on the base domain, and V is the red dyadic vertex.
The white triangle containing V can be located using the routine in listing
1.
Once
the triangle in the collapsed original mesh containing the dyadic points is
found a linear interpolation can be used to find the resample location:
![]()
Where P is the dyadic point, Triangle ABC is the collapsed original triangle with original geometry. (a, b, g) is the barycentric coordinates of P within the triangle ABC in the collapsed graph. Hence P will be a resample point on the piecewise linear original mesh geometry. Repeating this process for all new vertices allows the perturbing of the subdivision connectivity mesh to approximate the original geometry. The following examples show the results.
Horse and Venus Results
![]() |
![]() |
![]() |
![]() |
|
Figure
9. The first picture shows the original horse model with irregular connectivity.
The second picture shows the result of geometry resampling, the third
picture illustrates the base domain (as a result of mesh simplification)
while the fourth picture demonstrates the parameterization of the original
mesh with respect to the base domain.
|
![]() |
![]() |
![]() |
![]() |
|
Figure
10. Another example (the Venus head) of running our algorithm. The second
pictures shows the subdivision connectivity patch structure (color patches)
with the base domain and visualization of the parameterization.
|
|
Aaron Lee just graduated from Princeton University with a Ph.D. in Computer Graphics & Animation. He has interned at various places including Microsoft Research Lab, NASA Ames Research Center and Bell Labs, Lucent. Currently he works at a startup company doing streaming synthetic media content delivery. If you are a 2D/3D game developer looking for exciting opportunites to define next generation interactive content, please don't hesitate to contact him at admin@aaron-lee.com.
Copyright © 2003 CMP Media Inc. All rights reserved.