booleans in tutorial

This commit is contained in:
Alec Jacobson
2014-11-04 11:57:16 -05:00
parent 0ce56f2a70
commit 7a8984f6ae
21 changed files with 483 additions and 36 deletions
+75 -1
View File
@@ -129,6 +129,7 @@ lecture notes links to a cross-platform example application.</p>
<li><a href="#606">606 Baking ambient occlusion</a></li>
<li><a href="#607">607 Picking vertices and faces</a></li>
<li><a href="#608">608 Locally Injective Maps</a></li>
<li><a href="#609">609 Boolean Operations on Meshes</a></li>
</ul></li>
<li><a href="#future">Chapter 7: Outlook for continuing development</a></li>
</ul>
@@ -2422,6 +2423,78 @@ editing plus the anti-flipping constraints (right)." />
<figcaption>A mesh (left) deformed using Laplacian editing (middle) and with Laplacian
editing plus the anti-flipping constraints (right).</figcaption></figure>
<h2 id="609">Boolean operations on meshes</h2>
<p>Constructive solid geometry (CSG) is a technique to define a complex surface as
the result of a number of set operations on solid regions of space: union,
intersection, set difference, symmetric difference, complement. Typically, CSG
libraries represent the inputs and outputs to these operations <em>implicitly</em>:
the solid <span class="math">\(A\)</span> is defined as the open set of points <span class="math">\(\mathbf{x}\)</span> for which some
function <span class="math">\(a(\mathbf{x})\)</span> ``returns true&#8217;&#8217;. The surface of this shape is the
<em>closure</em> of all points <span class="math">\(x\)</span> in <span class="math">\(A\)</span>.</p>
<p>With this sort of representation, boolean
operations are straightforward. For example, the union of solids <span class="math">\(A\)</span> and <span class="math">\(B\)</span>
is simply</p>
<p><span class="math">\(A \cup B = \{\mathbf{x} \left.\right|
a(\mathbf{x}) \text{ or } b(\mathbf{x})\},\)</span></p>
<p>the intersection is</p>
<p><span class="math">\(A \cap B = \{\mathbf{x} \left.\right|
a(\mathbf{x}) \text{ and } b(\mathbf{x})\},\)</span></p>
<p>the difference <span class="math">\(A\)</span> <em>minus</em> <span class="math">\(B\)</span> is</p>
<p><span class="math">\(A \setminus B = \{\mathbf{x} \left.\right|
a(\mathbf{x}) \text{ and _not_ } b(\mathbf{x})\},\)</span></p>
<p>and the symmetric difference (XOR) is</p>
<p><span class="math">\(A \setminus B = \{\mathbf{x} \left.\right|
\text{either } a(\mathbf{x}) \text{ or } b(\mathbf{x}) \text{ but not both }\}.\)</span></p>
<p>Stringing together many of these operations, one can design quite complex
shapes. A typical CSG library might only keep explicit <em>base-case</em>
representations of canonical shapes: half-spaces, quadrics, etc.</p>
<p>In libigl, we do currently <em>not</em> have an implicit surface representation.
Instead we expect our users to be working with <em>explicit</em> triangle mesh
<em>boundary representations</em> of solid shapes. CSG operations are much hard to
compute robustly with boundary representations, but are nonetheless useful.</p>
<p>To compute a boolean operation on a triangle mesh with vertices <code>VA</code> and
triangles <code>FA</code> and another mesh <code>VB</code> and <code>FB</code>, libigl first computes a unified
mesh with vertices <code>V</code> and triangles <code>F</code> where all triangle-triangle
intersections have been &#8220;resolved&#8221;. That is, edges and vertices are added
exactly at the intersection lines, so the resulting <em>non-manifold</em> mesh <code>(V,F)</code>
has no self-intersections.</p>
<p>Then libigl <em>peals</em> the outer hull <span class="externalcitation">[#attene_14]</span> off this mesh recursively,
keeping track of the iteration parity and orientation flips for each layer.
For any boolean operation, these two pieces of information determine for each
triangle (1) if it should be included in the output, and (2) if its orientation
should be reversed before added to the output.</p>
<p>Calling libigl&#8217;s boolean operations is simple. To compute the union of
<code>(VA,FA)</code> and <code>(VB,FB)</code> into a new mesh <code>(VC,FC)</code>, use:</p>
<pre><code class="cpp">igl::mesh_boolean(VA,FA,VB,FB,MESH_BOOLEAN_TYPE_UNION,VC,FC);
</code></pre>
<figure>
<img src="images/cheburashka-knight-boolean.jpg" alt="The example Boolean conducts
boolean operations on the Cheburashka (red) and Knight (green). From left
to right: union, intersection, set minus, symmetric difference (XOR),
``resolve. Bottom row reveals inner surfaces, darker color indicates
back-facing triangles." />
<figcaption>The example <a href="609_Boolean/main.cpp">Boolean</a> conducts
boolean operations on the <em>Cheburashka</em> (red) and <em>Knight</em> (green). From left
to right: union, intersection, set minus, symmetric difference (XOR),
``resolve&#8217;&#8217;. Bottom row reveals inner surfaces, darker color indicates
back-facing triangles.</figcaption></figure>
<h1 id="future">Outlook for continuing development</h1>
<p>Libigl is in active development, and we plan to focus on the following features
@@ -2557,7 +2630,8 @@ Nicolas Ray, Bruno Vallet, Wan Chiu Li, Bruno Lévy TOG 2008</p>
</li>
<li id="fn:21" class="citation"><span class="citekey" style="display:none">bommes_2009</span><p><a href="http://www-sop.inria.fr/members/David.Bommes/publications/miq.pdf">Mixed-integer
quadrangulation</a>, David Bommes, Henrik Zimmer, Leif Kobbelt SIGGRAPH 2009</p>
quadrangulation</a>,
David Bommes, Henrik Zimmer, Leif Kobbelt SIGGRAPH 2009</p>
</li>
<li id="fn:22" class="citation"><span class="citekey" style="display:none">knoppel_2013</span><p><a href="http://www.cs.columbia.edu/~keenan/Projects/GloballyOptimalDirectionFields/paper.pdf">Globally Optimal Direction