In this assignment, you will learn the basics of mesh smoothing and mesh interpolation. You will be using JS to render the results interactively in your browser.
$ git clone https://gitlab.cs.dartmouth.edu/cs77-fa17/assignment3_basecode.git
You can also use a visual tool like SourceTree to clone the repository; the URL will be the same as in the command above.
Your assignment will be graded in person during office hours. You will still submit a zip file through Canvas. However, the actual grading will happen during office hours. We will send out a spreadsheet where you can sign up for a time slot.
Before you start, open
firstname-lastname-report.html in your browser. This html file will be both your report and your submitted assignment. Check the developer console of your browser for any error messages (check the x-hour slides for how to open the console).
To help you check your implementation, we provide a list of reference images for this assignment. Please refer to the
reference_images folder if you're unsure whether your implementation is correct.
We provide a full implementation of the
matrix.js file used in the first assignment as well as a
vector.js file for vector operations in JS. Before you begin the assignment, please briefly skim through this file for a list of methods you can use; the functions you have to implement in this assignment will make use of them.
Task 1: Cubic Bezier Patches (UG: 2.5 pts G: 2 pts)
In this task, you will implement a function to tesselate a cubic Bezier patch into a list of quadrilateral faces. Your function will be called by the basecode to tesselate the 32 Bezier patches of the Utah teapot into a smooth mesh. If you implemented this task correctly, you will get an image of a smooth teapot like the one shown below. The white wireframe shows the control cage of the patches, and the grey surface/black wireframe shows the tesselation. The slider on the HTML page allows you to control the fineness of the tesselation.
To help you debug your implementation, we also provide you with a simpler square Bezier patch. After tesselation, you should get an image like the one shown below:
Take a look at
task1.js. Fill in the code for the function
bezierPatchTesselation. This function receives a 4x4 array of vectors specifying the control points of the patch, and a number specifying the fineness of the tesselation. You should fill in the array
faces with the vertex positions and face indices of the tesselated quadrilaterals. The vertices should be uniformly spaced over the Bezier patch.
Hint: To do this, it will be helpful to write a utility function that allows you to evaluate the Bezier patch at given parameters (u, v). You can then write two nested for loops and call that function to evaluate the patch at uniformly spaced (u, v) to generate the vertices of the tesselation. Finally, connect the vertices with faces.
Hint: In the last assignment, you implemented Bezier evaluation with De Casteljau's algorithm. However, Bezier curves of cubic degree are much easier to evaluate in the direct form using the Bezier matrix (page 78 of the Curves lecture slides). Note: We will release code to evaluate a cubic Bezier curve on Monday, 10/1. You are encouraged to implement it yourself, but we will release reference code in case you had trouble with the last assignment.
Hint: Remember that a Bezier patch is simply two nested evaluations of a Bezier curve. You can interpret the 4x4 grid of control vertices as 4 separate Bezier curves with 4 control points each. To evaluate the Bezier patch, first evaluate the 4 curves separately using the parameter u. This gives you 4 interpolated points. Use these interpolated points as the 4 control points of a new Bezier curve, and interpolate it using the parameter v. This gives you the point on the Bezier patch for the parameters (u, v).
Task 2: Catmull-Clark Subdivision (UG: 3 pts G: 2 pts)
In this task, you will implement a function that performs one step of the Catmull-Clark subdivision algorithm. Your function will be called by the base code to generate smooth versions of different base shapes (cubes, tori, etc.). The buttons on the page allow you to choose the base mesh, and the slider on the page allows you to choose how often your function is called by the base code. Calling the function multiple times in succession generates smoother meshes.
If you implemented this task correctly, you will get an image like the one shown below.
Take a look at
task2.js. Implement the function
catmullClarkSubdivision. This function receives a list of vertices and faces specifying the input mesh. Note that the input mesh may consist of quadrilaterals, triangles or both. You should return a new mesh that corresponds to the input after one step of Catmull-Clark subdivision.
To make this task easier, we provide code that implements an edge hash map. This will allow you to check whether an edge has already been inserted as described in the lecture slides.
Hint: Follow the pseudo-code provided in
task2.js. It differs slightly from the one shown during the lecture.
Hint: Catmull-Clark subdivision performs multiple steps with many opportunities for bugs to sneak in. A useful tip is to implement the method one step at a time: First, only perform linear subdivision and verify that it works correctly; the shape of the mesh should not change, but every face should be split into smaller faces. Then, implement the averaging step and verify that vertices with four neighboring faces are smooth. Finally, implement the correction step.
Task 3: B-Spline Patches or Sharp Point Preservation (GRAD ONLY 1.5 pts)
Graduate students are required to expand upon either the first or the second tasks, and undergraduate students may do so for extra credit. You may choose to implement this within the individual tasks themselves, or use the provided basecode to make a Task 3 section. If you do task 3 within the individual tasks, please make additional tabs so the grader can view the original task as well as this additional task.
B-Spline Patches: For Task 1 you implemented Bezier Patches to render a surface from a collection of control points. Now implement B-Spline patches using those same control points. You will need to find a suitable way to handle boundary points which do not have enough neighbors.
Sharp Point Preservation: For Task 2 you implemented Catmull-Clark subdivision, and as you have probably noticed by now, this form of subdivision will remove sharp features from a shape. As discussed in class, sometimes sharp features like creased edges or sharp "dart" vertices may be desirable to achieve a particular shape. For Task 3, modify your Catmull-Clark subdivision implementation by treating all top-level control cage vertices as sharp "dart" points. To allow a customizable level of sharpness, use the sharp vertex subdivision rules for a chosen number of subdivisions before switching to smooth subdivision.
Interesting Scene (G and UG: 0.5 pts)
Take a look at
task2.js. Fill in
yourMesh with code that generates an interesting mesh, and subdivide it. Submit one (or several) interesting screenshots of your subdivided mesh. For example, you could programmatically generate mathematical shapes, or you could model an OBJ file in an external program and write an OBJ to JS converter (or simply do a few search/replace operations on the OBJ file in a text editor to convert it to a JS file) to subdivide and display it in the browser. Please keep in mind that your Catmull-Clark implementation only supports closed manifold meshes (no boundaries).