Sponsored By

Building Your Own Subdivision Surfaces

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. Aaron Lee examines the process of converting triangular meshes (one of the most popular data representations) into subdivision surfaces.

Aaron Lee, Blogger

September 8, 2000

17 Min Read
Game Developer logo in a gray background | Game Developer

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).

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).

 

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.

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.

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:

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 );
};
};
};

 

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.

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.

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:

lee_14.gif

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

 

To sum up, this article presents a simple algorithm to convert triangular meshes into subdivision surfaces. The algorithm is both easy to understand and implement, the main idea being to recast the problem as geometry resampling and compute the mapping (parameterization of the original mesh) with respect to a simple base domain. Subdivision surfaces open the doors of opportunity to character animation, free form surface design and efficient rendering. The next part of this article looks at applying subdivision surfaces techniques to these tasks. Stay tuned!

Read more about:

Features

About the Author

Aaron Lee

Blogger

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 to define next generation interactive content, please don\'t hesitate to contact him at [email protected].

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like