index.html 17.1 KB
Newer Older
allai5's avatar
allai5 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>Bevelling - </title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script type="text/javascript" src="/assets/js/vendor/lunr.min.js"></script> <script type="text/javascript" src="/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Begin Jekyll SEO tag v2.7.1 --> <title>Bevelling</title> <meta name="generator" content="Jekyll v4.2.0" /> <meta property="og:title" content="Bevelling" /> <meta property="og:locale" content="en_US" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="Bevelling" /> <script type="application/ld+json"> {"headline":"Bevelling","@type":"WebPage","url":"/meshedit/local/bevel/","@context":"https://schema.org"}</script> <!-- End Jekyll SEO tag --> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> </svg> <div class="side-bar"> <div class="site-header"> <a href="/" class="site-title lh-tight"> </a> <a href="#" id="menu-button" class="site-button"> <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg> </a> </div> <nav role="navigation" aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item"><a href="/" class="nav-list-link">Home</a></li><li class="nav-list-item"><a href="/git/" class="nav-list-link">GitHub Setup</a></li><li class="nav-list-item"><a href="/build/" class="nav-list-link">Building Scotty3D</a></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/guide/" class="nav-list-link">User Guide</a><ul class="nav-list "><li class="nav-list-item "><a href="/guide/animate_mode/" class="nav-list-link">Animate</a></li><li class="nav-list-item "><a href="/guide/layout_mode/" class="nav-list-link">Layout</a></li><li class="nav-list-item "><a href="/guide/model_mode/" class="nav-list-link">Model</a></li><li class="nav-list-item "><a href="/guide/render_mode/" class="nav-list-link">Render</a></li><li class="nav-list-item "><a href="/guide/rigging_mode/" class="nav-list-link">Rig</a></li><li class="nav-list-item "><a href="/guide/simulate_mode/" class="nav-list-link">Simulate</a></li></ul></li><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/" class="nav-list-link">A2: MeshEdit</a><ul class="nav-list "><li class="nav-list-item "><a href="/meshedit/halfedge" class="nav-list-link">Halfedge Mesh</a></li><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/local/" class="nav-list-link">Local Operations</a><ul class="nav-list"><li class="nav-list-item "> <a href="/meshedit/local/edge_flip" class="nav-list-link">Edge Flip Tutorial</a> </li><li class="nav-list-item active"> <a href="/meshedit/local/bevel/" class="nav-list-link active">Bevelling</a> </li></ul></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/global/" class="nav-list-link">Global Operations</a><ul class="nav-list"><li class="nav-list-item "> <a href="/meshedit/global/catmull/" class="nav-list-link">Catmull-Clark Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/remesh/" class="nav-list-link">Isotropic Remeshing</a> </li><li class="nav-list-item "> <a href="/meshedit/global/linear/" class="nav-list-link">Linear Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/loop/" class="nav-list-link">Loop Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/simplify/" class="nav-list-link">Simplification</a> </li><li class="nav-list-item "> <a href="/meshedit/global/triangulate/" class="nav-list-link">Triangulation</a> </li></ul></li></ul></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/" class="nav-list-link">A3: Pathtracer</a><ul class="nav-list "><li class="nav-list-item "><a href="/pathtracer/camera_rays" class="nav-list-link">(Task 1) Camera Rays</a></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/intersecting_objects" class="nav-list-link">(Task 2) Intersections</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/ray_triangle_intersection" class="nav-list-link">Ray Triangle Intersection</a> </li><li class="nav-list-item "> <a href="/pathtracer/ray_sphere_intersection" class="nav-list-link">Ray Sphere Intersection</a> </li></ul></li><li class="nav-list-item "><a href="/pathtracer/bounding_volume_hierarchy" class="nav-list-link">(Task 3) BVH</a></li><li class="nav-list-item "><a href="/pathtracer/shadow_rays" class="nav-list-link">(Task 4) Shadow Rays</a></li><li class="nav-list-item "><a href="/pathtracer/path_tracing" class="nav-list-link">(Task 5) Path Tracing</a></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/materials" class="nav-list-link">(Task 6) Materials</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/dielectrics_and_transmission" class="nav-list-link">Dielectrics and Transmission</a> </li></ul></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/environment_lighting" class="nav-list-link">(Task 7) Environment Lighting</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/importance_sampling" class="nav-list-link">Environment Light Importance Sampling</a> </li></ul></li><li class="nav-list-item "><a href="/pathtracer/visualization_of_normals" class="nav-list-link">Visualization of normals</a></li></ul></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/animation/" class="nav-list-link">A4: Animation</a><ul class="nav-list "><li class="nav-list-item "><a href="/animation/splines" class="nav-list-link">Splines</a></li><li class="nav-list-item "><a href="/animation/skeleton_kinematics" class="nav-list-link">Skeleton Kinematics</a></li><li class="nav-list-item "><a href="/animation/skinning" class="nav-list-link">Skinning</a></li><li class="nav-list-item "><a href="/animation/particles" class="nav-list-link">Particles</a></li></ul></li></ul> </nav> <footer class="site-footer"> This site uses <a href="https://github.com/pmarsceill/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </footer> </div> <div class="main" id="top"> <div id="main-header" class="main-header"> <div class="search"> <div class="search-input-wrap"> <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search " aria-label="Search " autocomplete="off"> <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label> </div> <div id="search-results" class="search-results"></div> </div> </div> <div id="main-content-wrap" class="main-content-wrap"> <nav aria-label="Breadcrumb" class="breadcrumb-nav"> <ol class="breadcrumb-nav-list"> <li class="breadcrumb-nav-list-item"><a href="/meshedit/">A2: MeshEdit</a></li> <li class="breadcrumb-nav-list-item"><a href="/meshedit/local/">Local Operations</a></li> <li class="breadcrumb-nav-list-item"><span>Bevelling</span></li> </ol> </nav> <div id="main-content" class="main-content" role="main"> <h1 id="beveling"> <a href="#beveling" class="anchor-heading" aria-labelledby="beveling"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Beveling </h1> <p>Here we provide some additional detail about the bevel operations and their implementation in Scotty3D. Each bevel operation has two components:</p> <ol> <li>a method that modifies the <em>connectivity</em> of the mesh, creating new beveled elements, and</li> <li>a method the updates the <em>geometry</em> of the mesh, insetting and offseting the new vertices according to user input.</li> </ol> <p>The methods that update the connectivity are <code class="language-plaintext highlighter-rouge">HalfedgeMesh::bevel_vertex</code>, <code class="language-plaintext highlighter-rouge">halfedgeMesh::bevel_edge</code>, and <code class="language-plaintext highlighter-rouge">HalfedgeMesh::bevel_face</code>. The methods that update geometry are <code class="language-plaintext highlighter-rouge">HalfedgeMesh::bevel_vertex_positions</code>, <code class="language-plaintext highlighter-rouge">HalfedgeMesh::bevel_edge_positions</code>, and <code class="language-plaintext highlighter-rouge">HalfedgeMesh::bevel_face_positions</code>.</p> <p>The methods for updating connectivity can be implemented following the general strategy outlined in <a href="edge_flip">edge flip tutorial</a>. <strong>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 <a href="../guide/model">User Guide</a>.</strong></p> <p>To update the <em>geometry</em> of a beveled element, you are provided with the following data:</p> <ul> <li><code class="language-plaintext highlighter-rouge">start_positions</code> - These are the original vertex positions of the beveled mesh element, without any insetting or offsetting.</li> <li><code class="language-plaintext highlighter-rouge">face</code> - This is a reference to the face currently being beveled. This was returned by one of the connectivity functions.</li> <li><code class="language-plaintext highlighter-rouge">tangent_offset</code> - The amount by which the new face should be inset (i.e., “shrunk” or “expanded”)</li> <li><code class="language-plaintext highlighter-rouge">normal_offset</code> - (faces only) The amount by which the new face should be offset in the normal direction.</li> </ul> <p>Also note that we provide code to gather the halfedges contained in the beveled face, creating the array <code class="language-plaintext highlighter-rouge">new_halfedges</code>. You should only have to update the position (<code class="language-plaintext highlighter-rouge">Vertex::pos</code>) of the vertices associated with this list of halfedges. The basic recipe for updating these positions is:</p> <ul> <li>Iterate over the list of halfedges (<code class="language-plaintext highlighter-rouge">new_halfedges</code>)</li> <li>Grab the vertex coordinates that are needed to compute the new, updated vertex coordinates (this could be a mix of values from <code class="language-plaintext highlighter-rouge">start_positions</code>, or the members <code class="language-plaintext highlighter-rouge">Vertex::pos</code>)</li> <li>Compute the updated vertex positions using the current values of <code class="language-plaintext highlighter-rouge">tangent_offset</code> (and possibly <code class="language-plaintext highlighter-rouge">normal_offset</code>)</li> <li>Store the new vertex positions in <code class="language-plaintext highlighter-rouge">Vertex::pos</code> <em>for the vertices of the new, beveled polygon only</em> (i.e., the vertices associated with each of <code class="language-plaintext highlighter-rouge">new_halfedges</code>).</li> </ul> <p>The reason for storing <code class="language-plaintext highlighter-rouge">new_halfedges</code> and <code class="language-plaintext highlighter-rouge">start_positions</code> in an array is that it makes it easy to access positions “to the left” and “to the right” of a given vertex. For instance, suppose we want to figure out the offset from the corner of a polygon. We might want to compute some geometric quantity involving the three vertex positions <code class="language-plaintext highlighter-rouge">start_positions[i-1]</code>, <code class="language-plaintext highlighter-rouge">start_positions[i]</code>, and <code class="language-plaintext highlighter-rouge">start_positions[i+1]</code> (as well as <code class="language-plaintext highlighter-rouge">inset</code>), then set the new vertex position <code class="language-plaintext highlighter-rouge">new_halfedges[i]-&gt;vertex()-&gt;pos</code> to this new value:</p> <center><img src="bevel_diagram.png" /></center> <p>A useful trick here is <em>modular arithmetic</em>: since we really have a “loop” of vertices, we want to make sure that indexing the next element (+1) and the previous element (-1) properly “wraps around.” This can be achieved via code like</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Get the number of vertices in the new polygon
int N = (int)hs.size();

// Assuming we're looking at vertex i, compute the indices
// of the next and previous elements in the list using
// modular arithmetic---note that to get the previous index,
// we can't just subtract 1 because the mod operation in C++
// doesn't behave quite how you might expect for negative
// values!
int a = (i+N-1) % N;
int b = i;
int c = (i+1) % N;

// Get the actual 3D vertex coordinates at these vertices
Vec3 pa = start_positions[a];
Vec3 pb = start_positions[b];
Vec3 pc = start_positions[c];
</code></pre></div></div> <p>From here, you will need to compute new coordinates for vertex <code class="language-plaintext highlighter-rouge">i</code>, which can be accessed from <code class="language-plaintext highlighter-rouge">new_halfedges[i]-&gt;vertex()-&gt;pos</code>. As a “dummy” example (i.e., this is NOT what you should actually do!!) this code will set the position of the new vertex to the average of the vertices above:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>new_halfedges[i].vertex()-&gt;pos = ( pa + pb + pc ) / 3.; // replace with something that actually makes sense!
</code></pre></div></div> <p>The only question remaining is: where <em>should</em> you put the beveled vertex? <strong>We will leave this decision up to you.</strong> This question is one where you will have to think a little bit about what a good design would be. Questions to ask yourself:</p> <ul> <li>How do I compute a point that is inset from the original geometry?</li> <li>For faces, how do I shift the geometry in the normal direction? (You may wish to use the method <code class="language-plaintext highlighter-rouge">Face::normal()</code> here.)</li> <li>What should I do as the offset geometry starts to look degenerate, e.g., shrinks to a point, or goes outside some reasonable bounds?</li> <li>What should I do when the geometry is nonplanar?</li> <li>Etc.</li> </ul> <p>The best way to get a feel for whether you have a good design is <em>to try it out!</em> Can you successfully and easily use this tool to edit your mesh? Or is it a total pain, producing bizarre results? You be the judge!</p> </div> </div> <div class="search-overlay"></div> </div> </body> </html>