This page describes the results from my implementation of the Catmull-Clark subdivision
surfaces algorithm. I implemented this algorithm for Asssignment 3 in CS294-13 (Advanced Rendering).
The Catmull-Clark subdivision surfaces algorithm provides a method for
recursively defining a B-Spline surface from an arbitrary mesh topology.
* Subdivide arbitrary meshes
* Interactive tagging of vertices to fix their position
* Push vertices to the limit solution
* Calculate and visualize tangents, normals, and curvature
* Optimize surface according to curvature
In the above set of images, I demonstrate a simple subdivision of a cube.
The left image above demonstrates the subdivision of the same cube after two
of the original vertices are tagged. The image on the right shows an icosahedron with
all vertices tagged.
In the above two images, I demonstrate how my system can initially tag all
of the vertices and edges for the first couple subdivision passes (left), before
treating the new mesh as a regular subdivision surface control mesh and
subdividing normally (right).
My implementation allows the user to subdivide arbitrary meshes composed of either triangles or quads. In this set of images above, I demonstrate the subdivision of an
icosahedron. After each subdivision step, I randomly perturb the vertices to
create an irregularly-shaped 3D object.
The above examples illustrate subdivided surfaces of arbitrary meshes
along with the control points (shown in red).
Visualizing Tangents, Normals and Curvature
In the above example, I demonstrate how my code can render a surface
(left) and then calculate and visualize the tangents and normals at each vertex (right).
I represent the tangents and normals by drawing a small gauge figure at each
vertex and orienting it such that the disc is in the tangent plane and the
central axis points in the direction of the normal vector.
In the above images, I demonstrate how the surfaces can be shaded
using different parameters. The
object is displayed using diffuse shading in top-left. The user can also color the
surface using the surface normals (top-right). My code also calculates
curvature, and the surface can be colored according to mean curvature (bottom-left) or
Gaussian curvature (bottom-right).
In the above example images, I've subdivided a simple ridge from a ground
plane. In the top-left image, I've rendered the ridge using diffuse shading.
The top-right image shows the ridge colored according to the surface normals.
The bottom-left image is shaded according to the mean curvature, and the
bottom-right image is shaded using Gaussian curvature.
Pushing to Limit Solution
In my implementation, the user can also push the vertices to the limit
surface after an arbitrary number of subdivisions. In the above example, I
start with a cube control mesh (top left), make one subdivision pass (top right), and then push the
vertices to the limit surface (bottom left). The limit surface after many more subdivision
passes is shown in the bottom-right image. Note how the vertices in the
bottom-left image are inline with the surface in the bottom-right image.
Here is another example (above) in which an arbitrary mesh (top-left) is subdivided
once (top-right) and then pushed to the limit solution (bottom-left). The
image on the bottom-right shows how the smoothed surface appears after several
My code can also move selected vertices of a control mesh to optimize certain surface
characteristics. I implemented this using a version of gradient descent to optimize the vertex
In the above example, I demonstrate how the control mesh can be optimized to minimize the max principal curvature of the limit surface. The image on the left shows the input control mesh in red and the resulting subdivision surface (shaded object). The image on the right shows the new surface after optimizing the select vertices (left and right points)
to minimize the max principal curvature of the object. The new control mesh (after optimization) is shown
I recorded a screencast of the control mesh as it was being optimized. The mesh was redrawn at each step of the optimization to show how the vertices are changing. The movie can be found here: movie1.
Here is another example (above). The original control mesh contains about 100 vertices and they are
positioned in an irregular pattern. In this version of my optimization, all the vertices were free
to be moved. The surface without any optimization is shown on the left. The surface after minimizing
the max principal curvature is shown on the right. Another movie illustrating how the code moved the vertices
during optimization can be found here: movie2.