From c29a3a2748d23e45be8cbe03f452c89b57e06104 Mon Sep 17 00:00:00 2001 From: Hui Wang <wanghehv@sjtu.edu.cn> Date: Sun, 20 Feb 2022 20:17:20 +0800 Subject: [PATCH] update meshedit md --- CMakeLists.txt | 2 +- README.md | 19 ++------------ docs/building.md | 7 ++---- docs/git.md | 20 +++++++-------- docs/index.md | 13 ++++------ docs/meshedit/bevel.md | 10 +++----- docs/meshedit/catmull.md | 9 +++---- docs/meshedit/edge_flip.md | 10 +++----- docs/meshedit/global.md | 11 +++------ docs/meshedit/halfedge.md | 11 ++++----- docs/meshedit/linear.md | 9 +++---- docs/meshedit/local.md | 11 +++------ docs/meshedit/loop.md | 11 +++------ docs/meshedit/overview.md | 10 +++----- docs/meshedit/remesh.md | 14 ++++------- docs/meshedit/simplify.md | 33 +++++++++++-------------- docs/meshedit/triangulate.md | 9 +++---- docs/pathtracer/environment_lighting.md | 2 +- 18 files changed, 72 insertions(+), 139 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 72966b5..c72c393 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16) # define project project(Scotty3D VERSION 1.1 - DESCRIPTION "CMU 15-462/662 - Computer Graphics" + DESCRIPTION "CS403 - Computer Graphics" LANGUAGES CXX) set(SCOTTY3D_BUILD_REF false) diff --git a/README.md b/README.md index d99be7f..a8c1681 100644 --- a/README.md +++ b/README.md @@ -3,24 +3,9 @@ <!--    --> -Welcome to Scotty3D! This 3D graphics software package includes components for interactive mesh +Welcome to Scotty3D! This 3D graphics software package is based on CMU462, which includes components for interactive mesh editing, realistic path tracing, and dynamic animation. Implementing functionality in each of these areas -constitutes the majority of the coursework for 15-462/662 (Computer Graphics) at Carnegie Mellon University +constitutes the coursework for CS403 (Computer Graphics) at SJTU. Pleas read the [documentation](docs/index.md) <!-- Please visit the [documentation website](https://cmu-graphics.github.io/Scotty3D/). --> - -## Sampled Student Work (Fall 2020) - -Showcase [video](https://www.youtube.com/watch?v=yJ5eY3EIImA&t=2s)! - -### MeshEdit - - - -### PathTracer - - - - - diff --git a/docs/building.md b/docs/building.md index 1818fde..4e21845 100644 --- a/docs/building.md +++ b/docs/building.md @@ -1,8 +1,5 @@ ---- -layout: default -title: "Building Scotty3D" -nav_order: 3 -permalink: /build/ +[[Home]](index) [[Mesh Edit]](meshedit/overview) [[Path Tracer]](pathtracer/overview) [[Animation]](animation/overview) + --- # Building Scotty3D diff --git a/docs/git.md b/docs/git.md index d0e4633..39ca699 100644 --- a/docs/git.md +++ b/docs/git.md @@ -1,18 +1,16 @@ +[[Home]](index) [[Mesh Edit]](meshedit/overview) [[Path Tracer]](pathtracer/overview) [[Animation]](animation/overview) + --- -layout: default -title: "GitHub Setup" -nav_order: 2 -permalink: /git/ ---- + # Github Setup Please do not use a public github fork of this repository! We do not want solutions to be public. You should work in your own private repo. We recommended creating a mirrored private repository with multiple remotes. The following steps go over how to achieve this. -The easiest (but not recommended) way is to download a zip from GitHub and make a private repository from that. The main disadvantage with this is that whenever there is an update to the base code, you will have to re-download the zip and manually merge the differences into your code. This is a pain, and you already have a lot to do in 15462/662, so instead, let `git` take care of this cumbersome "merging-updates" task: +The easiest (but not recommended) way is to download a zip from GitHub and make a private repository from that. The main disadvantage with this is that whenever there is an update to the base code, you will have to re-download the zip and manually merge the differences into your code. This is a pain, and you already have a lot to do, so instead, let `git` take care of this cumbersome "merging-updates" task: 1. Clone Scotty3D normally - - `git clone https://github.com/CMU-Graphics/Scotty3D.git` + - `git clone http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git` 2. Create a new private repository (e.g. `MyScotty3D`) - Do not initialize this repository - keep it completely empty. @@ -23,11 +21,11 @@ The easiest (but not recommended) way is to download a zip from GitHub and make - We will set the `origin` of our local clone to point to `MyScotty3D.git`, but also have a remote called `sourcerepo` for the public `Scotty3D` repository. 4. Now go back to your clone of Scotty3D. This is how we add the private remote: - - Since we cloned from the `CMU-Graphics/Scotty3D.git` repository, the current value of `origin` should be `https://github.com/CMU-Graphics/Scotty3D.git` + - Since we cloned from the `courses/scotty3d.git` repository, the current value of `origin` should be `http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git` - You can check this using `git remote -v`, which should show: ``` - origin https://github.com/CMU-Graphics/Scotty3D.git (fetch) - origin https://github.com/CMU-Graphics/Scotty3D.git (push) + origin http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git (fetch) + origin http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git (push) ``` - Rename `origin` to `sourcerepo`: - `git remote rename origin sourcerepo` @@ -38,7 +36,7 @@ The easiest (but not recommended) way is to download a zip from GitHub and make 5. Congratulations! you have successfully _mirrored_ a git repository with all past commits intact. -Now, let's see why this setup may be useful: say we start doing an assignment and commit regularly to our private repo (our `origin`). Then the 15-462 staff push some new changes to the Scotty3D skeleton code that we want to pull in. But, we don't want to mess up the changes we've added to our private copy. Here's where git comes to the rescue: +Now, let's see why this setup may be useful: say we start doing an assignment and commit regularly to our private repo (our `origin`). Then the CS403 staff push some new changes to the Scotty3D skeleton code that we want to pull in. But, we don't want to mess up the changes we've added to our private copy. Here's where git comes to the rescue: 1. Commit all local changes to your `origin`. 2. Run `git pull sourcerepo main` - this pulls all the changes from `sourcerepo` into your local copy. diff --git a/docs/index.md b/docs/index.md index 54e1fd5..0977e4c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,16 +1,13 @@ +[[Home]](index) [[Mesh Edit]](meshedit/overview) [[Path Tracer]](pathtracer/overview) [[Animation]](animation/overview) + --- -layout: default -title: Home -nav_order: 1 ---- -<!----> -<!----> - + # Scotty3D Welcome to Scotty3D! This 3D graphics software package includes components for interactive mesh editing, realistic path tracing, and dynamic animation. Implementing functionality in each of these areas -constitutes the majority of the coursework for 15-462/662 (Computer Graphics) at Carnegie Mellon University +constitutes the majority of the coursework for CS403 (Computer Graphics) at Shanghai Jiao Tong University +<!-- constitutes the majority of the coursework for 15-462/662 (Computer Graphics) at Carnegie Mellon University --> These pages describe how to set up and use Scotty3D. Start here! diff --git a/docs/meshedit/bevel.md b/docs/meshedit/bevel.md index 115c3a3..51b0091 100644 --- a/docs/meshedit/bevel.md +++ b/docs/meshedit/bevel.md @@ -1,9 +1,5 @@ ---- -layout: default -title: "Bevelling" -permalink: /meshedit/local/bevel/ -parent: "Local Operations" -grand_parent: "A2: MeshEdit" +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- # Beveling @@ -15,7 +11,7 @@ Here we provide some additional detail about the bevel operations and their impl The methods that update the connectivity are `HalfedgeMesh::bevel_vertex`, `halfedgeMesh::bevel_edge`, and `HalfedgeMesh::bevel_face`. The methods that update geometry are `HalfedgeMesh::bevel_vertex_positions`, `HalfedgeMesh::extruve_vertex_position`, `HalfedgeMesh::bevel_edge_positions`, and `HalfedgeMesh::bevel_face_positions`. -`HalfedgeMesh::extrude_vertex` will update both connectivity and geometry, as it should first perform a flat bevel on the vertex, and then insert a vertex into the new face. +`HalfedgeMesh::extrude_vertex` will update both connectivity and geometry, as it should first perform a flat bevel on the vertex, and then insert a vertex into the new face. TODO: not used in stanford The methods for updating connectivity can be implemented following the general strategy outlined in [edge flip tutorial](edge_flip). **Note that the methods that update geometry will be called repeatedly for the same bevel, in order to adjust positions according to user mouse input. See the gif in the [User Guide](../guide/model).** diff --git a/docs/meshedit/catmull.md b/docs/meshedit/catmull.md index e32bfba..035a0ed 100644 --- a/docs/meshedit/catmull.md +++ b/docs/meshedit/catmull.md @@ -1,10 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Catmull-Clark Subdivision" -parent: Global Operations -grand_parent: "A2: MeshEdit" -permalink: /meshedit/global/catmull/ ---- + # Catmull-Clark Subdivision diff --git a/docs/meshedit/edge_flip.md b/docs/meshedit/edge_flip.md index b04c048..3c14263 100644 --- a/docs/meshedit/edge_flip.md +++ b/docs/meshedit/edge_flip.md @@ -1,11 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Edge Flip Tutorial" -permalink: /meshedit/local/edge_flip -nav_order: 1 -parent: Local Operations -grand_parent: "A2: MeshEdit" ---- + # Edge Flip Tutorial diff --git a/docs/meshedit/global.md b/docs/meshedit/global.md index 9ff865f..841cba8 100644 --- a/docs/meshedit/global.md +++ b/docs/meshedit/global.md @@ -1,12 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Global Operations" -permalink: /meshedit/global/ -parent: "A2: MeshEdit" -has_children: true -has_toc: false -nav_order: 2 ---- + # Global Mesh Operations diff --git a/docs/meshedit/halfedge.md b/docs/meshedit/halfedge.md index 3cae29d..e098867 100644 --- a/docs/meshedit/halfedge.md +++ b/docs/meshedit/halfedge.md @@ -1,11 +1,8 @@ ---- -layout: default -title: "Halfedge Mesh" -permalink: /meshedit/halfedge -parent: "A2: MeshEdit" -nav_order: 0 +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- + # Halfedge Mesh ## Geometric Data Structures @@ -97,6 +94,8 @@ Finally, the **boundary** of the surface (e.g., the ankles and waist of a pair o Face::is_boundary() Halfedge::is_boundary() +TODO: explicitly save a boundary vertices list??? https://stanford-cs248.github.io/Cardinal3D/meshedit/halfedge + These methods return true if and only if the element is associated with a boundary face. Boundary faces are stored in the usual face list, i.e., they will show up when iterating over faces. You can disambiguate faces and boundaries using the above tests. The figure below should help to further explain the behavior of `Halfedge_Mesh` for surfaces with boundary: diff --git a/docs/meshedit/linear.md b/docs/meshedit/linear.md index 55a47de..1919e1c 100644 --- a/docs/meshedit/linear.md +++ b/docs/meshedit/linear.md @@ -1,10 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Linear Subdivision" -permalink: /meshedit/global/linear/ -parent: "Global Operations" -grand_parent: "A2: MeshEdit" ---- + # Linear Subdivision diff --git a/docs/meshedit/local.md b/docs/meshedit/local.md index 67275e4..456c71d 100644 --- a/docs/meshedit/local.md +++ b/docs/meshedit/local.md @@ -1,12 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: Local Operations -permalink: /meshedit/local/ -parent: "A2: MeshEdit" -has_children: true -has_toc: false -nav_order: 1 ---- + # Local Mesh Operations diff --git a/docs/meshedit/loop.md b/docs/meshedit/loop.md index 3681f9c..906236e 100644 --- a/docs/meshedit/loop.md +++ b/docs/meshedit/loop.md @@ -1,10 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Loop Subdivision" -permalink: /meshedit/global/loop/ -parent: Global Operations -grand_parent: "A2: MeshEdit" ---- + # Loop Subdivision @@ -19,7 +16,7 @@ The 4-1 subdivision looks like this:  -And the following picture illustrates the weighted average: +And the following picture illustrates the weighted average of the newly created vertex on the edge(left) and the old vertex(right):  diff --git a/docs/meshedit/overview.md b/docs/meshedit/overview.md index eec4576..410adc7 100644 --- a/docs/meshedit/overview.md +++ b/docs/meshedit/overview.md @@ -1,11 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "A2: MeshEdit" -permalink: /meshedit/ -nav_order: 5 -has_children: true -has_toc: false ---- + # MeshEdit Overview diff --git a/docs/meshedit/remesh.md b/docs/meshedit/remesh.md index 645dfc1..972e6fa 100644 --- a/docs/meshedit/remesh.md +++ b/docs/meshedit/remesh.md @@ -1,9 +1,5 @@ ---- -layout: default -title: "Isotropic Remeshing" -permalink: /meshedit/global/remesh/ -parent: Global Operations -grand_parent: "A2: MeshEdit" +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- # Isotropic Remeshing @@ -31,13 +27,13 @@ We want to flip an edge any time it reduces the total deviation from regular deg Finally, we also want to optimize the geometry of the vertices. A very simple heuristic is that a mesh will have reasonably well-shaped elements if each vertex is located at the center of its neighbors. To keep your code clean and simple, we recommend using the method `Vertex::neighborhood_center()`, which computes the average position of the vertex's neighbors. Note that you should not use this to immediately replace the current position: we don't want to be taking averages of vertices that have already been averaged. Doing so can yield some bizarre behavior that depends on the order in which vertices are traversed (if you're interested in learning more about this issue, Google around for the terms "Jacobi iterations" and "Gauss-Seidel). So, the code should (i) first compute the new positions (stored in `Vertex::new_pos`) for all vertices using their neighborhood centroids, and (ii) _then_ update the vertices with new positions (copy `new_pos` to `pos`). -<center><img src="laplacian_smoothing.png" style="height:200px"></center> +<center><img src="./global/remesh/laplacian_smoothing.png" style="height:200px"></center> How exactly should the positions be updated? One idea is to simply replace each vertex position with its centroid. We can make the algorithm slightly more stable by moving _gently_ toward the centroid, rather than immediately snapping the vertex to the center. For instance, if _p_ is the original vertex position and _c_ is the centroid, we might compute the new vertex position as _q_ = _p_ + _w_(_c_ - _p_) where _w_ is some weighting factor between 0 and 1 (we use 1/5 in the examples below). In other words, we start out at _p_ and move a little bit in the update direction _v_ = _c_ - _p_. Another important issue arises if the update direction _v_ has a large _normal_ component, then we'll end up pushing the surface in or out, rather than just sliding our sample points around on the surface. As a result, the shape of the surface will change much more than we'd like (try it!). To ameliorate this issue, we will move the vertex only in the _tangent_ direction, which we can do by projecting out the normal component, i.e., by replacing _v_ with _v_ - dot(_N_,_v_)_N_, where _N_ is the unit normal at the vertex. To get this normal, you can use the method `Vertex::normal()`, which computes the vertex normal as the area-weighted average of the incident triangle normals. In other words, at a vertex i the normal points in the direction -<center><img src="vert_normal_eq.png" style="height:80px"></center> +<center><img src="./global/remesh/vert_normal_eq.png" style="height:80px"></center> where A_ijk is the area of triangle ijk, and N_ijk is its unit normal; this quantity can be computed directly by just taking the cross product of two of the triangle's edge vectors (properly oriented). @@ -54,4 +50,4 @@ The final implementation requires very little information beyond the description Repeating this procedure about 5 or 6 times should yield results like the ones seen below; you may want to repeat the smoothing step 10-20 times for each "outer" iteration. -<center><img src="remesh_example.png" style="height:420px"></center> +<center><img src="./global/remesh/remesh_example.png" style="height:420px"></center> diff --git a/docs/meshedit/simplify.md b/docs/meshedit/simplify.md index 69d9b4b..e06fb27 100644 --- a/docs/meshedit/simplify.md +++ b/docs/meshedit/simplify.md @@ -1,14 +1,11 @@ ---- -layout: default -title: "Simplification" -permalink: /meshedit/global/simplify/ -parent: Global Operations -grand_parent: "A2: MeshEdit" +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- + # Simplification - + For an in-practice example, see the [User Guide](../guide/model). @@ -18,15 +15,13 @@ The basic idea is to iteratively collapse edges until we reach the desired numbe More precisely, we can write the distance d of a point _x_ to a plane with normal _N_ passing through a point _p_ as dist(_x_) = dot(_N_, _x_ - _p_) -<center><img src="plane_normal.png" style="height:360px"></center> - -In other words, we measure the extent of the vector from _p_ to _x_ along the normal direction. This quantity gives us a value that is either _positive_ (above the plane), or _negative_ (below the plane). Suppose that _x_ has coordinates (_x_,_y_,_z_), _N_ has coordinates (_a_,_b_,_c_), and let _d_(_x_) = -dot(_N_, _p_), then in _homogeneous_ coordinates, the distance to the plane is just +<center><img src="global/simplify/plane_normal.png" style="height:360px"></center> -dot(_u_, _v_) +In other words, we measure the extent of the vector from _p_ to _x_ along the normal direction. This quantity gives us a value that is either _positive_ (above the plane), or _negative_ (below the plane). Suppose that _x_ has coordinates (_x_,_y_,_z_), _N_ has coordinates (_a_,_b_,_c_), and let _d_(_x_) = -dot(_N_, _p_), then in _homogeneous_ coordinates, the distance to the plane is just dot(_u_, _v_) where _u_ = (_x_,_y_,_z_,_1_) and _v_ = (_a_,_b_,_c_,_d_). -where _u_ = (_x_,_y_,_z_,_1_) and _v_ = (_a_,_b_,_c_,_d_). When we're measuring the quality of an approximation, we don't care whether we're above or below the surface; just how _far away_ we are from the original surface. Therefore, we're going to consider the _square_ of the distance, which we can write in homogeneous coordinates as +When we're measuring the quality of an approximation, we don't care whether we're above or below the surface; just how _far away_ we are from the original surface. Therefore, we're going to consider the _square_ of the distance, which we can write in homogeneous coordinates as -<center><img src="homogeneous_coord.png" style="height:40px"></center> +<center><img src="global/simplify/homogeneous_coord.png" style="height:40px"></center> where T denotes the transpose of a vector. The term _vv_^T is an [outer product](https://en.wikipedia.org/wiki/Outer_product) of the vector _v_ with itself, which gives us a symmetric matrix _K_ = _vv_^T. In components, this matrix would look like @@ -39,12 +34,12 @@ but in Scotty3D it can be constructed by simply calling the method `outer( Vec4, The matrix _K_ tells us something about the distance to a plane. We can also get some idea of how far we are from a _vertex_ by considering the sum of the squared distances to the planes passing through all triangles that touch that vertex. In other words, we will say that the distance to a small neighborhood around the vertex i can be approximated by the sum of the quadrics on the incident faces ijk: -<center><img src="K_sum.png" style="height:100px"></center> -<center><img src="vert_normals.png" style="height:360px"></center> +<center><img src="global/simplify/K_sum.png" style="height:100px"></center> +<center><img src="global/simplify/vert_normals.png" style="height:360px"></center> Likewise, the distance to an _edge_ ij will be approximated by the sum of the quadrics at its two endpoints: -<center><img src="edge_k_sum.png" style="height:50px"></center> +<center><img src="global/simplify/edge_k_sum.png" style="height:50px"></center> The sums above should then be easy to compute -- you can just add up the `Mat4` objects around a vertex or along an edge using the usual "+" operator. You do not need to write an explicit loop over the 16 entries of the matrix. @@ -60,11 +55,11 @@ _Ax_ = _b_ where A is the upper-left 3x3 block of K, and b is _minus_ the upper-right 3x1 column. In other words, the entries of A are just -<center><img src="K_A_block.png" style="height:100px"></center> +<center><img src="global/simplify/K_A_block.png" style="height:100px"></center> and the entries of b are -<center><img src="b_vec.png" style="height:100px"></center> +<center><img src="global/simplify/b_vec.png" style="height:100px"></center> The cost associated with this solution can be found by plugging _x_ back into our original expression, i.e., the cost is just @@ -170,4 +165,4 @@ Steps 4 and 7 are highlighted because it is easy to get these steps wrong. For i A working implementation should look something like the examples below. You may find it easiest to implement this algorithm in stages. For instance, _first_ get the edge collapses working, using just the edge midpoint rather than the optimal point, _then_ worry about solving for the point that minimizes quadric error. <!----> -<center><img src="quad_example.png" style="height:480px"></center> +<center><img src="global/simplify/quad_example.png" style="height:480px"></center> diff --git a/docs/meshedit/triangulate.md b/docs/meshedit/triangulate.md index 1edf427..373b618 100644 --- a/docs/meshedit/triangulate.md +++ b/docs/meshedit/triangulate.md @@ -1,10 +1,7 @@ +[[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview) + --- -layout: default -title: "Triangulation" -permalink: /meshedit/global/triangulate/ -parent: Global Operations -grand_parent: "A2: MeshEdit" ---- + # Triangulation diff --git a/docs/pathtracer/environment_lighting.md b/docs/pathtracer/environment_lighting.md index 3d14bb2..e52ddf7 100644 --- a/docs/pathtracer/environment_lighting.md +++ b/docs/pathtracer/environment_lighting.md @@ -32,7 +32,7 @@ Second, implement the uniform sphere sampler in `student/samplers.cpp`. Implemen Lastly, in `Env_Map::evaluate`, convert the given direction to image coordinates (phi and theta) and look up the appropriate radiance value in the texture map using **bilinear interpolation**. -Since high dynamic range environment maps can be large files, we have not included them in the Scotty3D repository. You can download a set of sample environment maps [here](http://15462.courses.cs.cmu.edu/fall2015content/misc/asst3_images/asst3_exr_archive.zip). +Since high dynamic range environment maps can be large files, we have not included them in the Scotty3D repository. For more HDRIs for creative environment maps, check out [Poly Haven](https://polyhaven.com/hdris/) To use a particular environment map with your scene, select `layout` -> `new light` -> `environment map`-> `add`, and select your file. For more creative environment maps, check out [Poly Haven](https://polyhaven.com/) -- GitLab