{{FULL_COURSE}} Homework 6 - Catmull-Clark Subdivision
Overview
-----
You will implement the Catmull-Clark subdivision algorithm to smooth the
meshes you created in the previous assignment, and implement some simpler
mesh editing operations as well..
Supplied Code
---------
You will work from the base code supplied for the previous assignment, and
commit your code to the same repository.
Conceptual Questions (10 points, Due Friday, October 21 at 11:59 PM)
-------------
* (5 pts) When quadrangulating a face during Catmull-Clark subdivision, what
information must you temporarily store in order to properly link your half-edge
pointers without creating inaccessible edges?
* (5 pts) When extruding a face, what operation must be performed after all
edges have been turned into quadrangles via the extrusion algorithm discussed
in the lecture slides? What iteration of said operation must be specially
handled?
Help Log (5 points)
-------
Maintain a log of all help you receive and resources you use. Make sure the date
and time, the names of everyone you work with or get help from, and every URL
you use, except as noted in the collaboration policy. Also briefly log your
question, bug or the topic you were looking up/discussing. Ideally, you should
also the answer to your question or solution to your bug. This will help you
learn and provide a useful reference for future assignments and exams. This also
helps us know if there is a topic that people are finding difficult.
If you did not use external resources or otherwise receive help, please submit
a help log that states you did not receive external help.
You may submit your help log as an ASCII (plain) text file or as a PDF. Refer
to the Policies section of the course web site for more specifications.
Code Requirements (Due Monday, October 24 at 11:59 PM)
-------
### Polar Spherical Camera (10 points) ###
Modify the provided `Camera` class so that it moves along the surface of a
sphere centered at the origin when it is rotated, following the polar spherical
camera model. Additionally, the camera should translate along its forward vector
when it is zoomed in and out, and both the camera and its reference point should
translate along the camera's right and up vectors when the camera is panned.
To implement the spherical camera model, the following sequence of
transformations should be applied to the "unit" `eye`, `Forward`, `Right`, and
`Up` vectors every time the camera's matrices need to be computed:
`rotate(theta, y_axis) * rotate(phi, x_axis) * translate(zoom, z_axis)`
These are the following values for these "unit" variables:
* `eye`: `(0, 0, 0, 1)`
* `Forward`: `(0, 0, 1, 0)`
* `Up`: `(0, 1, 0, 0)`
* `Right`: `(1, 0, 0, 0)`
### Simple mesh topology operations (20 points) ###
Add buttons to your GUI that, when clicked, invoke the following functions:
* A function that adds a `Vertex` as the midpoint of the currently selected
`HalfEdge`. This button should do nothing if no `HalfEdge` is currently selected.
This new `Vertex` should appear in the list of vertices in your GUI, as should
the two new `HalfEdge`s that will be created by this operation.
* A function that, given a single `Face` in your mesh, triangulates the face
(you may assume the face is convex). You might consider beginning with a
function that only triangulates quadrangles, then expand that function once
you confirm it works.
### Modifying vertex and face attributes (5 points) ###
Allow the user to change face colors and vertex positions by inputting values
into the GUI's `QDoubleSpinBox` widgets. Make sure to send the updated vertex
data to your GLSL shader.
### Catmull-Clark Subdivision (50 points) ###
Add a button to your GUI that allows the user to subdivide any given polygon
mesh using Catmull-Clark subdivision. We recommend breaking up the subdivision
into testable steps, such as adding the new centroids and edge vertices first,
then moving the original vertices inward, then connecting these vertices with
half-edges. Writing a separate function to "quadrangulate" a face given the
new vertices may be helpful.
You'll know your subdivision is working properly if the provided cube OBJ converges to a
spherical shape when you subdivide it multiple times. If you can subdivide the
supplied cow OBJ file within 10 seconds, you've done very well!
Below are some expected vertex coordinates on a 1x1x1 cube after one iteration
of subdivision:
* The positions of your midpoints should be some permutation of
(0.375, 0.375, 0)
* The positions of your centroids should be some permutation of (0.5, 0, 0)
* The new positions of your original vertices should be some permutation of
(0.3055, 0.3055, 0.3055)
Below are some expected vertex coordinates on a 1x1x1 cube after TWO iterations
of subdivision:
* The position of the vertex that was originally at (0.5, 0.5, 0.5) should be
(0.2697, 0.2697, 0.2697)
* The positions of the smoothed midpoints between iteration 1's smoothed midpoints
and the mesh's original vertices should be some permutation of (0.1615, 0.3099, 0.3099)
Coding Style (10 points)
-------
To help you write better C++ and GLSL code, we will score each of your homework assignments on three different style elements, which will change from week to week. For this assignment, make sure you:
- Do not add __any__ additional member variables to your `Mesh`, `Face`, `HalfEdge`, or `Vertex` classes. Any data you need to store for subdivision can be stored as a `std::unordered_set` or `std::unordered_map`.
- Include descriptive comments in the functions you write for OBJ loading and Catmull-Clark subdivision describing what each code section is intended to do.
- Write private helper functions to further segment your OBJ loading function and subdivision function.
Extra Credit (Maximum 20 points)
---------
Make sure you include a `readme.txt` file in your repository that lists which
extra credit features you implemented and how to access them.
### Extruding Faces (10 points) ###
Add a button to your GUI that allows the user to extrude a selected face along
its geometric surface normal. Each edge of the face should become a quadrangle
that connects the extruded face to the faces it originally touched. You may
choose to hard-code the distance by which a face is extruded, as long as this
distance is non-zero.
### Sharp edges and vertices (15 points) ###
Allow the user to set specific faces, edges, and vertices as "sharp" before
subdividing a mesh. The effect of "sharpness" depends on what has been tagged
as sharp:
* Face: All of the sharp face's vertices and edges are treated as sharp during
the subdivision process.
* Edge: When a vertex is added to a sharp edge, its position is simply the
average of the sharp edge's endpoints. The resulting sub-edges are also marked
as "sharp" so that further subdivisions retain a sharp appearance.
* Vertex: When a vertex is tagged as "sharp", it simply does not move during
the smoothing process. However, if a non-sharp vertex is connected to two or
more sharp edges, its behavior changes. If a vertex is connected to two sharp
edges, its smoothed position is
`(0.75 * original) + (0.125 * edge_1_endpoint) + (0.125 * edge_2_endpoint)`.
If it is connected to three or more sharp edges, it is treated as a "sharp"
vertex.
### Semi-sharpness (5 points) ###
Allow the user to set a "sharpness" value between 0 and 1 for any mesh
component that has been tagged as sharp. This value determines how "sharp"
that component will be after subdivision, which is a simple interpolation of
its fully sharp position and its fully smooth position.
### Custom mesh operation (up to 20 points) ###
Decide upon some other mesh alteration operation, such as inserting an edge
loop or beveling an edge, and implement it. Your feature does not need to be
one described in the lecture slides. If you are unsure how valuable your
feature will be, you may post to Piazza with a description of what you want to
implement.
Submission
--------
We will grade the code you have submitted to Canvas, so make sure you
zip up your entire project! Also make sure to commit all of your files
to Github, and add a comment on your Canvas submission with a link to
your repository.