Contour Analysis of 3D Meshes

with Aric B. and Tianxin D.

Winter 2013, Stanford CS348A

The Project

Tracing the Contour

To calculate the contour, we followed the DeCarlo paper with a few adjustments. For each triangle, we find the location where kw is zero along the edges and compute Dwkw at those locations. However, instead of having Dkw at that location, we have a Dkw per face.We assume that this is approximately the correct quantity and use it to compute Dwkw where the first w is from the zero crossing to the camera position. Note that it is not necessary to project the vector v from the zero crossing to the camera position onto the tangent plane. We can use this approximation since we are dealing with relatively small triangles with respect to the distance to the camera position and so the derivative will be nearly constant along a triangle.

When computing principal curvatures and curvature directions, we negate the eigenvectors and eigenvalues of matrix M to account for differences between the Taubin and De Carlo papers. Once we reversed the directions of these vectors, our suggestive contours looked much smoother and more realistic.


We implemented a subset of the ideas described in High Quality Hatching and the technical report Creating High Quality Hatching Illustrations . Specifically, we implemented sections 3.1 and 3.3 of the paper. The other parts were either unnecessary or too complex to consider implementing in a short timeframe. Parts of our code come from Real­Time Collision Detection to implement various geometric computations.

To implement section 3.1, we mostly just copied our code from hw3 with the modification that we now sort the eigenvalues and the corresponding eigenvectors so that in abs(k1) > abs(k2). This gives T1 is the direction of maximum curvature, T.

For section 3.3, we made several modifications. First, we decided upon using OBB’s instead of cylinders. OBB’s are much faster and easier to intersect with each other and triangles than cylinders. Beyond this OBB’s are a reasonable approximation to a cylinder and so we expected that our results would still be satisfactory, which they were. We also changed the integration scheme. The scheme in the paper describes computing T(p) where p is the current position of integration by a spherical barycentric interpolation of T(v1), T(v2), T(v3) in which v1,v2,v3 are the vertices of the triangles that p lies in. This is then used in a fourth order Runge­Kutta scheme. Instead, we decided upon a more simplistic euler integration scheme and computed T(p) by baycentric interpolating the curvature matrices at the three vertices and computing their eigenvalues and eigenvectors (Hw3). Finally, we simplified the method of seeding. We decided upon using the centroids of the triangles as the only seeding locations instead of points orthogonal to the streamline at some distance away. Although this may seem to not be justified, the models that we have used all have approximately the same sized triangles. At least from our experiments, streamlines turned out to have reasonable consistent spacings.

Toon Shader

To make these illustrations visually appealing, we implemented a Toon Shader that uses basic Phong Shading and clips intensity values to 4 intervals. We also experimented with adding thick outlines to the figures by expanding each silhouette line segment into a quad. This technique posed a challenge at line segment intersections, where gaps formed due to the differing angles of the lines. The gaps can be eliminated by either drawing a circle at the end of each line segment, or connecting adjacent quads with triangles. We left this as something to be implemented in the future along with a shader to clip and fade line segments in the 4 different intervals.