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