{{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 OBJ file loading to render and modify more complex meshes. Supplied Code --------- You will work from the base code supplied for the previous assignment, and commit your code to the same repository. [Click here to download the OBJ files to load into your program](obj_files.zip) Conceptual Questions (10 points, Due Friday, October 16 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 Wednesday, October 21 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)` ### 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 a cube 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) ### OBJ File Importing (25 points) ### Add a button to your GUI that opens a `QFileDialog` that allows the user to select an OBJ file to be read. Your program should generate a half-edge data structure from the input file and then render the resulting mesh using VBOs, wherein each `Face` is assigned a random color. You will only be required to handle closed and manifold meshes, but you should be able to handle faces with any number of edges (i.e. n-gons) without triangulating them within your half-edge mesh structure. You may have your OBJ mesh, once built, replace any previously existing mesh such as the cube you built for the previous assignment or a previously loaded OBJ mesh. If you are unfamiliar with the OBJ file format, we recommend you read the [Wikipedia article](https://en.wikipedia.org/wiki/Wavefront_.obj_file) describing their formatting (it is fairly straightforward). When loading an OBJ file, you only need to store its vertex position information for building your faces. You may choose to only support OBJ files that follow the face format of `position/uv/normal` (as opposed to `face//normal` or `face/uv`). This is the format of all the OBJ files we have provided. If you can load the supplied cow OBJ file within 3 seconds, you've done well! An important feature some people may forget is to set up is all of the SYM pointers for the `HalfEdge`s. They are not needed to draw your meshes using VBOs, but they are vital to performing mesh operations. Make sure you've properly created your SYM pointers (you can visually test them using the debugging features you implemented in the previous assignment). Coding Style (10 points) ------- We will provide you with feedback on the organization and clarity of the code you have written for this assignment. Please refer to our course style guide as you implement your shaders and VBOs. 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. ### Selection via ray casting (15 points) ### If you did not implement ray casting in the previous assignment for extra credit, you may do so for this assignment. Allow the user to select faces, half-edges, and vertices by clicking on the GL window. The component nearest to the camera should be the one selected. The more intersections you implement, the more points you'll be awarded. If you select a component through ray casting, the GUI list containing that component should also be updated to reflect your selection. We recommend treating vertices as small spheres, faces as sets of triangles, and half-edges as cylinders. To test against half-edges, you might consider finding the nearest point between the ray and the edge and seeing if that point's distance from the Half-edge is within some radius. ### 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.