Commit c29a3a27 authored by Hui Wang's avatar Hui Wang
Browse files

update meshedit md

parent 5917989f
...@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16) ...@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
# define project # define project
project(Scotty3D VERSION 1.1 project(Scotty3D VERSION 1.1
DESCRIPTION "CMU 15-462/662 - Computer Graphics" DESCRIPTION "CS403 - Computer Graphics"
LANGUAGES CXX) LANGUAGES CXX)
set(SCOTTY3D_BUILD_REF false) set(SCOTTY3D_BUILD_REF false)
......
...@@ -3,24 +3,9 @@ ...@@ -3,24 +3,9 @@
<!-- ![Ubuntu Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/Ubuntu/badge.svg) ![MacOS Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/MacOS/badge.svg) ![Windows Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/Windows/badge.svg) --> <!-- ![Ubuntu Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/Ubuntu/badge.svg) ![MacOS Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/MacOS/badge.svg) ![Windows Build Status](https://github.com/CMU-Graphics/Scotty3D/workflows/Windows/badge.svg) -->
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 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) Pleas read the [documentation](docs/index.md)
<!-- Please visit the [documentation website](https://cmu-graphics.github.io/Scotty3D/). --> <!-- 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
![fall 2020 meshes](docs/results/me_f20.png)
### PathTracer
![fall 2020 path tracer 0](docs/results/pt_f20_0.jpg)
![fall 2020 path tracer 1](docs/results/pt_f20_1.png)
![fall 2020 path tracer 2](docs/results/pt_f20_2.png)
![fall 2020 path tracer 3](docs/results/pt_f20_3.png)
--- [[Home]](index) [[Mesh Edit]](meshedit/overview) [[Path Tracer]](pathtracer/overview) [[Animation]](animation/overview)
layout: default
title: "Building Scotty3D"
nav_order: 3
permalink: /build/
--- ---
# Building Scotty3D # Building Scotty3D
......
[[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 # 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. 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. 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 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`) 2. Create a new private repository (e.g. `MyScotty3D`)
- Do not initialize this repository - keep it completely empty. - 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 ...@@ -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. - 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: 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: - You can check this using `git remote -v`, which should show:
``` ```
origin https://github.com/CMU-Graphics/Scotty3D.git (fetch) origin http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git (fetch)
origin https://github.com/CMU-Graphics/Scotty3D.git (push) origin http://dalab.se.sjtu.edu.cn/gitlab/courses/scotty3d.git (push)
``` ```
- Rename `origin` to `sourcerepo`: - Rename `origin` to `sourcerepo`:
- `git remote rename origin 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 ...@@ -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. 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`. 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. 2. Run `git pull sourcerepo main` - this pulls all the changes from `sourcerepo` into your local copy.
......
[[Home]](index) [[Mesh Edit]](meshedit/overview) [[Path Tracer]](pathtracer/overview) [[Animation]](animation/overview)
--- ---
layout: default
title: Home
nav_order: 1
---
<!--![15-462 F20 Renders](results/me_f20.png)-->
<!--![15-462 F20 Renders](results/pt_f20_2.png)-->
![15-462 F20 Renders](results/me_f20_crop.png)
# Scotty3D # Scotty3D
Welcome to Scotty3D! This 3D graphics software package includes components for interactive mesh 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 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! These pages describe how to set up and use Scotty3D. Start here!
......
--- [[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview)
layout: default
title: "Bevelling"
permalink: /meshedit/local/bevel/
parent: "Local Operations"
grand_parent: "A2: MeshEdit"
--- ---
# Beveling # Beveling
...@@ -15,7 +11,7 @@ Here we provide some additional detail about the bevel operations and their impl ...@@ -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`. 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).** 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).**
......
[[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 # Catmull-Clark Subdivision
......
[[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 # Edge Flip Tutorial
......
[[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 # Global Mesh Operations
......
--- [[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview)
layout: default
title: "Halfedge Mesh"
permalink: /meshedit/halfedge
parent: "A2: MeshEdit"
nav_order: 0
--- ---
# Halfedge Mesh # Halfedge Mesh
## Geometric Data Structures ## Geometric Data Structures
...@@ -97,6 +94,8 @@ Finally, the **boundary** of the surface (e.g., the ankles and waist of a pair o ...@@ -97,6 +94,8 @@ Finally, the **boundary** of the surface (e.g., the ankles and waist of a pair o
Face::is_boundary() Face::is_boundary()
Halfedge::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. 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: The figure below should help to further explain the behavior of `Halfedge_Mesh` for surfaces with boundary:
......
[[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 # Linear Subdivision
......
[[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 # Local Mesh Operations
......
[[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 # Loop Subdivision
...@@ -19,7 +16,7 @@ The 4-1 subdivision looks like this: ...@@ -19,7 +16,7 @@ The 4-1 subdivision looks like this:
![4-1 Subdivision](global/loop/loop_41.png) ![4-1 Subdivision](global/loop/loop_41.png)
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):
![Loop subdivision weights](global/loop/loop_weights.png) ![Loop subdivision weights](global/loop/loop_weights.png)
......
[[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 # MeshEdit Overview
......
--- [[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview)
layout: default
title: "Isotropic Remeshing"
permalink: /meshedit/global/remesh/
parent: Global Operations
grand_parent: "A2: MeshEdit"
--- ---
# Isotropic Remeshing # Isotropic Remeshing
...@@ -31,13 +27,13 @@ We want to flip an edge any time it reduces the total deviation from regular deg ...@@ -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`). 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_. 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 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). 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 ...@@ -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. 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>
--- [[Home]](../index) [[Mesh Edit]](../meshedit/overview) [[Path Tracer]](../pathtracer/overview) [[Animation]](../animation/overview)
layout: default
title: "Simplification"
permalink: /meshedit/global/simplify/
parent: Global Operations
grand_parent: "A2: MeshEdit"
--- ---
# Simplification # Simplification
![Surface simplification via quadric error metric](quad_simplify.png) ![Surface simplification via quadric error metric](global/simplify/quad_simplify.png)
For an in-practice example, see the [User Guide](../guide/model). 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 ...@@ -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_) 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> <center><img src="global/simplify/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
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 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, ...@@ -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: 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="global/simplify/K_sum.png" style="height:100px"></center>
<center><img src="vert_normals.png" style="height:360px"></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: 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. 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_ ...@@ -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 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 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 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 ...@@ -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. 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.
<!--![Quadric error simplification examples](quad_example.png)--> <!--![Quadric error simplification examples](quad_example.png)-->
<center><img src="quad_example.png" style="height:480px"></center> <center><img src="global/simplify/quad_example.png" style="height:480px"></center>
[[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 # Triangulation
......
...@@ -32,7 +32,7 @@ Second, implement the uniform sphere sampler in `student/samplers.cpp`. Implemen ...@@ -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**. 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/) 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/)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment