updated html and added --recursive in the tutorial readme

This commit is contained in:
Daniele Panozzo
2015-07-08 09:55:24 +02:00
parent b2e1759206
commit 56000af671
4 changed files with 193 additions and 214 deletions
+150 -76
View File
@@ -19,7 +19,7 @@
<figure>
<img src="images/libigl-logo.jpg" alt="" />
<figcaption></figcaption></figure>
</figure>
<p>Libigl is an open source C++ library for geometry processing research and
development. Dropping the heavy data structures of tradition geometry
@@ -164,7 +164,7 @@ libigl:</p>
we wrap them in a small set of functions.</p></li>
<li><p><strong>Header-only.</strong> It is straight forward to use our library since it is only
one additional include directory in your project. (if you are worried about
compilation speed, it is also possible to build the library as a <a href="../build/">static
compilation speed, it is also possible to build the library as a <a href="../optional/">static
library</a>)</p></li>
<li><p><strong>Function encapsulation.</strong> Every function (including its full
implementation) is contained in a pair of .h/.cpp files with the same name of
@@ -176,23 +176,12 @@ libigl:</p>
<p>libigl can be downloaded from our <a href="https://github.com/libigl/libigl">github
repository</a> or cloned with git:</p>
<pre><code class="bash">git clone https://github.com/libigl/libigl.git
<pre><code class="bash">git clone --recursive https://github.com/libigl/libigl.git
</code></pre>
<p>The core libigl functionality only depends on the C++ Standard Library and
Eigen.</p>
<p>The examples in this tutorial depend on <a href="http://www.glfw.org">glfw</a>,
<a href="http://glew.sourceforge.net">glew</a> and <a href="http://anttweakbar.sourceforge.net/doc/">AntTweakBar</a>.
The source code of each library is bundled with libigl
and they can be compiled all at once using:</p>
<pre><code class="bash">sh compile_dependencies_macosx.sh (MACOSX)
sh compile_dependencies_linux.sh (LINUX)
</code></pre>
<p>For windows, precompiled binaries are provided (Visual Studio 2014 64bit).</p>
<p>To build all the examples in the tutorial, you can use the CMakeLists.txt in
the tutorial folder:</p>
@@ -232,7 +221,8 @@ represented as indices pointing to rows of <code>V</code>.</p>
<figure>
<img src="images/VF.png" alt="A simple mesh made of 2 triangles and 4 vertices." />
<figcaption>A simple mesh made of 2 triangles and 4 vertices.</figcaption></figure>
<figcaption>A simple mesh made of 2 triangles and 4 vertices.</figcaption>
</figure>
<p>Note that the order of the vertex indices in <code>F</code> determines the orientation of
the triangles and it should thus be consistent for the entire surface.
@@ -302,7 +292,8 @@ Please see the documentation in
<img src="images/102_DrawMesh.png" alt="(Example 102) loads and draws a
mesh." />
<figcaption>(<a href="102_DrawMesh/main.cpp">Example 102</a>) loads and draws a
mesh.</figcaption></figure>
mesh.</figcaption>
</figure>
<h2 id="interactionwithkeyboardandmouse">Interaction with keyboard and mouse</h2>
@@ -389,7 +380,8 @@ vertex) and the second calls a libigl functions that converts a scalar field to
<img src="images/104_Colors.png" alt="(Example 104) igl::jet converts a scalar field to a
color field." />
<figcaption>(<a href="104_Colors/main.cpp">Example 104</a>) igl::jet converts a scalar field to a
color field.</figcaption></figure>
color field.</figcaption>
</figure>
<p><code>igl::jet</code> is an example of a standard function in libigl: it takes simple
types and can be easily reused for many different tasks. Not committing to
@@ -428,7 +420,8 @@ Eigen::Vector3d M = V.colwise().maxCoeff();
<img src="images/105_Overlays.png" alt="(Example 105) The bounding box of a mesh is shown
using overlays." />
<figcaption>(<a href="105_Overlays/main.cpp">Example 105</a>) The bounding box of a mesh is shown
using overlays.</figcaption></figure>
using overlays.</figcaption>
</figure>
<h1 id="chapter2:discretegeometricquantitiesandoperators">Chapter 2: Discrete Geometric Quantities and Operators</h1>
@@ -495,7 +488,8 @@ normals of faces incident on the corresponding vertex which do not deviate by mo
<img src="images/fandisk-normals.jpg" alt="The Normals example computes per-face (left), per-vertex (middle) and
per-corner (right) normals" />
<figcaption>The <code>Normals</code> example computes per-face (left), per-vertex (middle) and
per-corner (right) normals</figcaption></figure>
per-corner (right) normals</figcaption>
</figure>
<h2 id="gaussiancurvature">Gaussian curvature</h2>
@@ -527,7 +521,8 @@ elliptic, hyperbolic and parabolic vertices on the domain, as demonstrated in <a
<img src="images/bumpy-gaussian-curvature.jpg" alt="The GaussianCurvature example computes discrete Gaussian curvature and
visualizes it in pseudocolor." />
<figcaption>The <code>GaussianCurvature</code> example computes discrete Gaussian curvature and
visualizes it in pseudocolor.</figcaption></figure>
visualizes it in pseudocolor.</figcaption>
</figure>
<h2 id="curvaturedirections">Curvature directions</h2>
@@ -578,7 +573,8 @@ fitting and visualizes mean curvature in pseudocolor and principal directions
with a cross field." />
<figcaption>The <code>CurvatureDirections</code> example computes principal curvatures via quadric
fitting and visualizes mean curvature in pseudocolor and principal directions
with a cross field.</figcaption></figure>
with a cross field.</figcaption>
</figure>
<h2 id="gradient">Gradient</h2>
@@ -595,7 +591,8 @@ vertex <span class="math">\(i\)</span> and zero at the other corners.</p>
<img src="images/hat-function.jpg" alt="Hat function $\phi_i$ is one at vertex $i$, zero at all other vertices, and
linear on incident triangles." />
<figcaption>Hat function <span class="math">\(\phi_i\)</span> is one at vertex <span class="math">\(i\)</span>, zero at all other vertices, and
linear on incident triangles.</figcaption></figure>
linear on incident triangles.</figcaption>
</figure>
<p>Thus gradients of such piecewise linear functions are simply sums of gradients
of the hat functions:</p>
@@ -621,7 +618,8 @@ triangle and tetrahedral meshes (<a href="204_Gradient/main.cpp">Example 204</a>
<img src="images/cheburashka-gradient.jpg" alt="The Gradient example computes gradients of an input function on a mesh and
visualizes the vector field." />
<figcaption>The <code>Gradient</code> example computes gradients of an input function on a mesh and
visualizes the vector field.</figcaption></figure>
visualizes the vector field.</figcaption>
</figure>
<h2 id="laplacian">Laplacian</h2>
@@ -641,7 +639,7 @@ Hessian):</p>
<p>When considering piecewise-linear functions on a triangle mesh, a discrete
Laplacian may be derived in a variety of ways. The most popular in geometry
processing is the so-called ``cotangent Laplacian&#8217;&#8217; <span class="math">\(\mathbf{L}\)</span>, arising
processing is the so-called &#8220;cotangent Laplacian&#8221; <span class="math">\(\mathbf{L}\)</span>, arising
simultaneously from FEM, DEC and applying divergence theorem to vertex
one-rings. As a linear operator taking vertex values to vertex values, the
Laplacian <span class="math">\(\mathbf{L}\)</span> is a <span class="math">\(n\times n\)</span> matrix with elements:</p>
@@ -696,7 +694,8 @@ the surface along the mean curvature normal direction (<a href="205_Laplacian/ma
<img src="images/cow-curvature-flow.jpg" alt="The Laplacian example computes conformalized mean curvature flow using the
cotangent Laplacian ." />
<figcaption>The <code>Laplacian</code> example computes conformalized mean curvature flow using the
cotangent Laplacian <a class="citation" href="#fn:5" title="Jump to citation">[5]<span class="citekey" style="display:none">kazhdan_2012</span></a>.</figcaption></figure>
cotangent Laplacian <a class="citation" href="#fn:5" title="Jump to citation">[5]<span class="citekey" style="display:none">kazhdan_2012</span></a>.</figcaption>
</figure>
<h3 id="massmatrix">Mass matrix</h3>
@@ -787,7 +786,8 @@ functionality is provided in libigl using <code>slice_into</code>:</p>
<img src="images/decimated-knight-slice-color.jpg" alt="The example Slice shows how to use igl::slice to change the colors for
triangles on a mesh." />
<figcaption>The example <code>Slice</code> shows how to use <code>igl::slice</code> to change the colors for
triangles on a mesh.</figcaption></figure>
triangles on a mesh.</figcaption>
</figure>
<h2 id="sort">Sort</h2>
@@ -826,11 +826,12 @@ X(I(i,j),j);</code>. That is, <code>I</code> reveals how <code>X</code> is sorte
<figure>
<img src="images/decimated-knight-sort-color.jpg" alt="The example Sort shows how to use igl::sortrows to
pseudocolor triangles according to their barycenters sorted
pseudocolor triangles according to their barycenters' sorted
order (Example 302)." />
<figcaption>The example <code>Sort</code> shows how to use <code>igl::sortrows</code> to
pseudocolor triangles according to their barycenters&#8217; sorted
order (<a href="302_Sort/main.cpp">Example 302</a>).</figcaption></figure>
order (<a href="302_Sort/main.cpp">Example 302</a>).</figcaption>
</figure>
<h3 id="othermatlab-stylefunctions">Other Matlab-style functions</h3>
@@ -884,7 +885,7 @@ functionality as common Matlab functions.</p>
<td style="text-align:left;">Find subscripts of non-zero entries</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::floot</code></td>
<td style="text-align:left;"><code>igl::floor</code></td>
<td style="text-align:left;">Round entries down to nearest integer</td>
</tr>
<tr>
@@ -915,18 +916,50 @@ functionality as common Matlab functions.</p>
<td style="text-align:left;"><code>igl::mode</code></td>
<td style="text-align:left;">Compute the mode per column</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::null</code></td>
<td style="text-align:left;">Compute the null space basis of a matrix</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::nchoosek</code></td>
<td style="text-align:left;">Compute all k-size combinations of n-long vector</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::orth</code></td>
<td style="text-align:left;">Orthogonalization of a basis</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::parula</code></td>
<td style="text-align:left;">Generate a quantized colormap from blue to yellow</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::randperm</code></td>
<td style="text-align:left;">Generate a random permutation of [0,&#8230;,n&#8211;1]</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::rgb_to_hsv</code></td>
<td style="text-align:left;">Convert RGB colors to HSV (cf. Matlab&#8217;s <code>rgb2hsv</code>)</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::setdiff</code></td>
<td style="text-align:left;">Set difference of matrix elements</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::sort</code></td>
<td style="text-align:left;">Sort elements or rows of matrix</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::speye</code></td>
<td style="text-align:left;">Identity as sparse matrix</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::sum</code></td>
<td style="text-align:left;">Sum along columns or rows (of sparse matrix)</td>
</tr>
<tr>
<td style="text-align:left;"><code>igl::unique</code></td>
<td style="text-align:left;">Extract unique elements or rows of matrix</td>
</tr>
</tbody>
</table>
@@ -997,7 +1030,8 @@ rows of <code>Z</code> corresponding to the interior vertices (<a href="303_Lapl
<img src="images/camelhead-laplace-equation.jpg" alt="The LaplaceEquation example solves a Laplace equation with Dirichlet
boundary conditions." />
<figcaption>The <code>LaplaceEquation</code> example solves a Laplace equation with Dirichlet
boundary conditions.</figcaption></figure>
boundary conditions.</figcaption>
</figure>
<h3 id="quadraticenergyminimization">Quadratic energy minimization</h3>
@@ -1145,7 +1179,8 @@ hand and foot constrained to be equal)." />
<figcaption>The example <code>LinearEqualityConstraints</code> first solves with just fixed value
constraints (left: 1 and &#8211;1 on the left hand and foot respectively), then
solves with an additional linear equality constraint (right: points on right
hand and foot constrained to be equal).</figcaption></figure>
hand and foot constrained to be equal).</figcaption>
</figure>
<h2 id="quadraticprogramming">Quadratic programming</h2>
@@ -1194,7 +1229,8 @@ discrete biharmonic kernels at multiple scales
." />
<figcaption> <a href="305_QuadraticProgramming/main.cpp">Example 305</a> uses an active set solver to optimize
discrete biharmonic kernels <a class="citation" href="#fn:6" title="Jump to citation">[6]<span class="citekey" style="display:none">rustamov_2011</span></a> at multiple scales
.</figcaption></figure>
.</figcaption>
</figure>
<h1 id="chapter4:shapedeformation">Chapter 4: Shape deformation</h1>
@@ -1294,7 +1330,8 @@ surface (top) and using a biharmonic displacements
(bottom)." />
<figcaption>The <a href="401_BiharmonicDeformation/main.cpp">BiharmonicDeformation</a> example deforms a statue&#8217;s head as a <em>biharmonic
surface</em> (top) and using a <em>biharmonic displacements</em>
(bottom).</figcaption></figure>
(bottom).</figcaption>
</figure>
<h4 id="relationshiptodifferentialcoordinatesandlaplaciansurfaceediting">Relationship to &#8220;differential coordinates&#8221; and Laplacian surface editing</h4>
@@ -1338,7 +1375,8 @@ igl::harmonic(V,F,b,bc,k,Z);
<img src="images/bump-k-harmonic.jpg" alt="The PolyharmonicDeformation example deforms a flat domain (left) into a bump as a
solution to various $k$-harmonic PDEs." />
<figcaption>The <a href="402_PolyharmonicDeformation/main.cpp">PolyharmonicDeformation</a> example deforms a flat domain (left) into a bump as a
solution to various <span class="math">\(k\)</span>-harmonic PDEs.</figcaption></figure>
solution to various <span class="math">\(k\)</span>-harmonic PDEs.</figcaption>
</figure>
<h2 id="boundedbiharmonicweights">Bounded biharmonic weights</h2>
@@ -1406,7 +1444,8 @@ mesh given a skeleton (top) and then animates a linear blend skinning
deformation (bottom)." />
<figcaption>The example <a href="403_BoundedBiharmonicWeights/main.cpp">BoundedBiharmonicWeights</a> computes weights for a tetrahedral
mesh given a skeleton (top) and then animates a linear blend skinning
deformation (bottom).</figcaption></figure>
deformation (bottom).</figcaption>
</figure>
<h2 id="dualquaternionskinning">Dual quaternion skinning</h2>
@@ -1458,7 +1497,8 @@ quaternion skinning (bottom), highlighting LBSs candy wrapper effect (middle)
and joint collapse (right)." />
<figcaption>The example <a href="404_DualQuaternionSkinning/main.cpp">DualQuaternionSkinning</a> compares linear blend skinning (top) to dual
quaternion skinning (bottom), highlighting LBS&#8217;s candy wrapper effect (middle)
and joint collapse (right).</figcaption></figure>
and joint collapse (right).</figcaption>
</figure>
<h2 id="as-rigid-as-possible">As-rigid-as-possible</h2>
@@ -1562,7 +1602,8 @@ the highly optimized singular value decomposition code from McAdams et al.
<img src="images/decimated-knight-arap.jpg" alt="The example AsRigidAsPossible deforms a surface as if it were made of an
elastic material" />
<figcaption>The example <a href="405_AsRigidAsPossible/main.cpp">AsRigidAsPossible</a> deforms a surface as if it were made of an
elastic material</figcaption></figure>
elastic material</figcaption>
</figure>
<p>The concept of local rigidity will be revisited shortly in the context of
surface parameterization.</p>
@@ -1675,7 +1716,8 @@ rotation edge sets (right of middle), to the very fast subpsace method
<figcaption>The example <a href="406_FastAutomaticSkinningTransformations/main.cpp">FastAutomaticSkinningTransformations</a> compares a full (slow)
ARAP deformation on a detailed shape (left of middle), to ARAP with grouped
rotation edge sets (right of middle), to the very fast subpsace method
(right).</figcaption></figure>
(right).</figcaption>
</figure>
<h1 id="chapter5:parametrization">Chapter 5: Parametrization</h1>
@@ -1745,7 +1787,8 @@ mesh with texture, (right) UV parametrization with
texture" />
<figcaption>(<a href="501_HarmonicParam/main.cpp">Example 501</a>) Harmonic parametrization. (left)
mesh with texture, (right) UV parametrization with
texture</figcaption></figure>
texture</figcaption>
</figure>
<h2 id="leastsquareconformalmaps">Least squares conformal maps</h2>
@@ -1794,7 +1837,8 @@ vertices to two arbitrary positions. The full source code is provided in <a href
<img src="images/502_LSCMParam.png" alt="(Example 502) LSCM parametrization. (left) mesh
with texture, (right) UV parametrization" />
<figcaption>(<a href="502_LSCMParam/main.cpp">Example 502</a>) LSCM parametrization. (left) mesh
with texture, (right) UV parametrization</figcaption></figure>
with texture, (right) UV parametrization</figcaption>
</figure>
<h2 id="asrigidaspossible">As-rigid-as-possible parametrization</h2>
@@ -1820,7 +1864,8 @@ the distortion.</p>
texture" />
<figcaption>(<a href="502_ARAPParam/main.cpp">Example 503</a>) As-Rigid-As-Possible parametrization.
(left) mesh with texture, (right) UV parametrization with
texture</figcaption></figure>
texture</figcaption>
</figure>
<h2 id="nrotationallysymmetrictangetfields">N-rotationally symmetric tangent fields</h2>
@@ -1845,7 +1890,8 @@ the triangle mesh (output_field), plus the singularities of the field
<figure>
<img src="images/504_vector_field.png" alt="Design of a unit-length vector field" />
<figcaption>Design of a unit-length vector field</figcaption></figure>
<figcaption>Design of a unit-length vector field</figcaption>
</figure>
<p>The singularities are vertices where the field vanishes (highlighted in red in
the figure above). <code>igl::nrosy</code> can also generate N-RoSy fields <a class="citation" href="#fn:20" title="Jump to citation">[20]<span class="citekey" style="display:none">levy_2008</span></a>,
@@ -1856,7 +1902,8 @@ N are of different types and they appear in different positions.</p>
<figure>
<img src="images/504_nrosy_field.png" alt="Design of a 2-,4- and 9-RoSy field" />
<figcaption>Design of a 2-,4- and 9-RoSy field</figcaption></figure>
<figcaption>Design of a 2-,4- and 9-RoSy field</figcaption>
</figure>
<p>We demonstrate how to call and plot N-RoSy fields in <a href="504_NRosyDesign/main.cpp">Example
504</a>, where the degree of the field can be change
@@ -1883,7 +1930,8 @@ from the principal curvature directions. In [<a href="506_FrameField/main.cpp">E
<figure>
<img src="images/505_MIQ_1.png" alt="Initial cross field prescribing the edge alignment." />
<figcaption>Initial cross field prescribing the edge alignment.</figcaption></figure>
<figcaption>Initial cross field prescribing the edge alignment.</figcaption>
</figure>
<h3 id="combingandcutting">Combing and cutting</h3>
@@ -1898,7 +1946,8 @@ length cross fields.</p>
<figure>
<img src="images/505_MIQ_2.png" alt="Bisector field." />
<figcaption>Bisector field.</figcaption></figure>
<figcaption>Bisector field.</figcaption>
</figure>
<p>and we remove the rotation ambiguity by assigning to each face a u and a v
direction. The assignment is done with a breadth-first search starting from a
@@ -1906,7 +1955,8 @@ random face.</p>
<figure>
<img src="images/505_MIQ_3.png" alt="Combed bisector field." />
<figcaption>Combed bisector field.</figcaption></figure>
<figcaption>Combed bisector field.</figcaption>
</figure>
<p>You can imagine this process as combing an hairy surface: you will be able to
comb part of it, but at some point you will not be able to consistently comb
@@ -1916,14 +1966,16 @@ in the combing define the cut graph:</p>
<figure>
<img src="images/505_MIQ_4.png" alt="Cut graph." />
<figcaption>Cut graph.</figcaption></figure>
<figcaption>Cut graph.</figcaption>
</figure>
<p>Finally, we rotate the combed field by 45 degrees to undo the initial degrees
rotation:</p>
<figure>
<img src="images/505_MIQ_5.png" alt="Combed cross field." />
<figcaption>Combed cross field.</figcaption></figure>
<figcaption>Combed cross field.</figcaption>
</figure>
<p>The combed cross field can be seen as the ideal Jacobian of the parametrization
that will be computed in the next section.</p>
@@ -1943,21 +1995,24 @@ input cross field.</p>
<figure>
<img src="images/505_MIQ_8.png" alt="Poisson parametrization." />
<figcaption>Poisson parametrization.</figcaption></figure>
<figcaption>Poisson parametrization.</figcaption>
</figure>
<p>We hide the seams by adding integer constraints to the Poisson problem
that align the isolines on both sides of each seam <a class="citation" href="#fn:21" title="Jump to citation">[21]<span class="citekey" style="display:none">bommes_2009</span></a>.</p>
<figure>
<img src="images/505_MIQ_7.png" alt="Seamless Poisson parametrization." />
<figcaption>Seamless Poisson parametrization.</figcaption></figure>
<figcaption>Seamless Poisson parametrization.</figcaption>
</figure>
<p>Note that this parametrization can only be used for remeshing purposes, since
it contains many overlaps.</p>
<figure>
<img src="images/505_MIQ_6.png" alt="Seamless Poisson parametrization (in 2D)." />
<figcaption>Seamless Poisson parametrization (in 2D).</figcaption></figure>
<figcaption>Seamless Poisson parametrization (in 2D).</figcaption>
</figure>
<p>A quad mesh can be extracted from this parametrization using
<a href="https://github.com/hcebke/libQEx">libQEx</a> (not included in libigl).
@@ -1984,7 +2039,8 @@ scale. The red faces contains the frame field
constraints." />
<figcaption>Interpolation of a frame field. Colors on the vectors denote the desired
scale. The red faces contains the frame field
constraints.</figcaption></figure>
constraints.</figcaption>
</figure>
<p>After the interpolation, the surface is warped to transform each frame into an
orthogonal and unit length cross (i.e. removing the scaling and skewness from
@@ -1995,14 +2051,16 @@ surface.</p>
<img src="images/506_FrameField_2.png" alt="The surface is deformed to transform the frame field in a cross
field." />
<figcaption>The surface is deformed to transform the frame field in a cross
field.</figcaption></figure>
field.</figcaption>
</figure>
<p>The deformed surface can the be isotropically remeshed using the MIQ algorithm
that has been presented in the previous section.</p>
<figure>
<img src="images/506_FrameField_3.png" alt="The deformed surface is isotropically remeshed." />
<figcaption>The deformed surface is isotropically remeshed.</figcaption></figure>
<figcaption>The deformed surface is isotropically remeshed.</figcaption>
</figure>
<p>The UV coordinates of the deformed surface can then be used to transport the
parametrization to the original surface, where the isolines will trace a quad
@@ -2013,7 +2071,8 @@ field.</p>
<img src="images/506_FrameField_4.png" alt="The global parametrization is lifted to the original surface to create the
anisotropic quad meshing." />
<figcaption>The global parametrization is lifted to the original surface to create the
anisotropic quad meshing.</figcaption></figure>
anisotropic quad meshing.</figcaption>
</figure>
<p>Our implementation (<a href="506_FrameField/main.cpp">Example 506</a>) uses MIQ to
generate the UV parametrization, but other algorithms could be applied: the
@@ -2030,7 +2089,8 @@ sparse set of constraints (<a href="507_PolyVectorField/main.cpp">Example 507</a
<figure>
<img src="images/507_PolyVectorField.png" alt="Interpolation of a 6-PolyVector field (right) and a 12-PolyVector field from a sparse set of random constraints." />
<figcaption>Interpolation of a 6-PolyVector field (right) and a 12-PolyVector field from a sparse set of random constraints.</figcaption></figure>
<figcaption>Interpolation of a 6-PolyVector field (right) and a 12-PolyVector field from a sparse set of random constraints.</figcaption>
</figure>
<p>The core idea is to represent the vector set as the roots of a complex
polynomial: The polynomial coefficients are then harmonically interpolated
@@ -2064,7 +2124,8 @@ closest conjugate field (<a href="508_ConjugateField/main.cpp">Example 508</a>).
<img src="images/508_ConjugateField.png" alt="A smooth 4-PolyVector field (left) is deformed to become a conjugate field
(right)." />
<figcaption>A smooth 4-PolyVector field (left) is deformed to become a conjugate field
(right).</figcaption></figure>
(right).</figcaption>
</figure>
<h2 id="planarization">Planarization</h2>
@@ -2081,7 +2142,8 @@ igl::palanarize (right). The colors represent the planarity of the
quads." />
<figcaption>A non-planar quad mesh (left) is planarized using the libigl function
igl::palanarize (right). The colors represent the planarity of the
quads.</figcaption></figure>
quads.</figcaption>
</figure>
<h1 id="chapter6:externallibraries">Chapter 6: External libraries</h1>
@@ -2197,7 +2259,7 @@ igl::deserialize_xml(vec,&quot;VectorXML&quot;,xmlFile);
igl::deserialize_xml(vec,&quot;VectorBin&quot;,xmlFile);
</code></pre>
<p>For user defined types derive from <code>XMLSerializable</code>. </p>
<p>For user defined types derive from <code>XMLSerializable</code>.</p>
<p>The code snippets above are extracted from <a href="601_Serialization/main.cpp">Example
601</a>. We strongly suggest that you make the entire
@@ -2245,7 +2307,8 @@ see the sparsity pattern of L using spy:</p>
<img src="images/602_Matlab_1.png" alt="The Matlab spy function is called from a libigl-based
application." />
<figcaption>The Matlab spy function is called from a libigl-based
application.</figcaption></figure>
application.</figcaption>
</figure>
<p>The results of Matlab computations can be returned back to the C++ application</p>
@@ -2259,7 +2322,8 @@ igl::mlgetmatrix(&amp;engine,&quot;EV&quot;,EV);
<img src="images/602_Matlab_2.png" alt="4 Eigenfunctions of the Laplacian plotted in the libigl
viewer." />
<figcaption>4 Eigenfunctions of the Laplacian plotted in the libigl
viewer.</figcaption></figure>
viewer.</figcaption>
</figure>
<h3 id="savingamatlabworkspace">Saving a Matlab workspace</h3>
@@ -2364,7 +2428,8 @@ in its interior) is triangulated.</p>
<figure>
<img src="images/604_Triangle.png" alt="Triangulation of the interior of a polygon." />
<figcaption>Triangulation of the interior of a polygon.</figcaption></figure>
<figcaption>Triangulation of the interior of a polygon.</figcaption>
</figure>
<h2 id="tetrahedralizationofclosedsurfaces">Tetrahedralization of closed surfaces</h2>
@@ -2377,7 +2442,8 @@ using the function <code>igl::tetrahedralize</code> which wraps the Tetgen libra
<figure>
<img src="images/605_Tetgen.png" alt="Tetrahedralization of the interior of a surface mesh." />
<figcaption>Tetrahedralization of the interior of a surface mesh.</figcaption></figure>
<figcaption>Tetrahedralization of the interior of a surface mesh.</figcaption>
</figure>
<h2 id="bakingambientocclusion">Baking ambient occlusion</h2>
@@ -2413,7 +2479,8 @@ single scalar for each sample.</p>
<img src="images/606_AmbientOcclusion.png" alt="A mesh rendered without (left) and with (right) ambient
occlusion." />
<figcaption>A mesh rendered without (left) and with (right) ambient
occlusion.</figcaption></figure>
occlusion.</figcaption>
</figure>
<h2 id="pickingverticesandfaces">Picking</h2>
@@ -2447,7 +2514,8 @@ by Embree, and <code>fid</code> and <code>vid</code> are the picked face and ver
<img src="images/607_Picking.png" alt="(Example 607) Picking via ray casting. The selected
vertices are colored in red." />
<figcaption>(<a href="607_Picking/main.cpp">Example 607</a>) Picking via ray casting. The selected
vertices are colored in red.</figcaption></figure>
vertices are colored in red.</figcaption>
</figure>
<h2 id="locallyinjectivemaps">Locally Injective Maps</h2>
@@ -2464,7 +2532,8 @@ deformation energies. A simple deformation of a 2D grid is computed in <a href="
<img src="images/608_LIM.png" alt="A mesh (left) deformed using Laplacian editing (middle) and with Laplacian
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>
editing plus the anti-flipping constraints (right).</figcaption>
</figure>
<h2 id="booleanoperationsonmeshes">Boolean operations on meshes</h2>
@@ -2538,7 +2607,8 @@ back-facing triangles." />
boolean operations on the <em>Cheburashka</em> (red) and <em>Knight</em> (green). From left
to right: union, intersection, set minus, symmetric difference (XOR),
&#8220;resolve&#8221;. Bottom row reveals inner surfaces, darker color indicates
back-facing triangles.</figcaption></figure>
back-facing triangles.</figcaption>
</figure>
<p>The union, symmetric difference and &#8220;resolve&#8221; have the same outward
appearance, but differ in their treatment of internal structures. The union has
@@ -2647,7 +2717,8 @@ generalized winding number function for a tetrahedral mesh inside a cat with
holes and self intersections (gold). The silver mesh is surface of the
extracted interior tets, and slices show the winding number function on all
tets in the convex hull: blue (~0), green (~1), yellow
(~2).</figcaption></figure>
(~2).</figcaption>
</figure>
<h2 id="meshdecimation">Mesh Decimation</h2>
@@ -2663,8 +2734,8 @@ collapsing edges <a class="citation" href="#fn:30" title="Jump to citation">[30]
construct a sequence of n meshes from the initial high-resolution mesh <span class="math">\(M_0\)</span> to
the lowest resolution mesh <span class="math">\(M_n\)</span> by collapsing a single edge:</p>
<p><span class="math">\(M_0 \mathop{\longrightarrow}_\text{edge collapse}
M_1 \mathop{\longrightarrow}_\text{edge collapse}
<p><span class="math">\(M_0 \mathop{\longrightarrow}_\text{edge collapse}
M_1 \mathop{\longrightarrow}_\text{edge collapse}
\dots \mathop{\longrightarrow}_\text{edge collapse}
M_{n-1} \mathop{\longrightarrow}_\text{edge collapse} M_n.\)</span></p>
@@ -2678,7 +2749,7 @@ collapsed and costs of neighboring edges are updated.</p>
sphere or a torus etc.), one should assign infinite cost to edges whose
collapse would alter the mesh topology. Indeed this happens if and only if the
number of mutual neighbors of the endpoints of the collapsing edge is not
exactly two! </p>
exactly two!</p>
<p>If there exists a third shared vertex, then another face will be removed, but 2
edges will be removed. This can result in unwanted holes or non-manifold
@@ -2686,7 +2757,8 @@ edges will be removed. This can result in unwanted holes or non-manifold
<figure>
<img src="images/edge-collapse.jpg" alt="A valid edge collapse and an invalid edge collapse." />
<figcaption>A valid edge collapse and an invalid edge collapse.</figcaption></figure>
<figcaption>A valid edge collapse and an invalid edge collapse.</figcaption>
</figure>
<blockquote>
<p>There is also a one-off condition that no edges of a tetrahedron should be
@@ -2738,7 +2810,7 @@ opposite).</p>
<p>When a collapse occurs, the sizes of the <code>F</code>,<code>E</code>, etc. matrices do not change.
Rather rows corresponding to &#8220;removed&#8221; faces and edges are set to a special
constant value <code>IGL_COLLAPSE_EDGE_NULL</code>. Doing this ensures that we&#8217;re able to
remove edges in truly constant time O(1). </p>
remove edges in truly constant time O(1).</p>
<blockquote>
<p>Conveniently <code>IGL_COLLAPSE_EDGE_NULL==0</code>. This means most OPENGL style renderings of <code>F</code>
@@ -2777,7 +2849,8 @@ reinserted with infinite cost.</p>
<img src="images/fertility-edge-collapse.gif" alt="Example 703 conducts edge collapses on the fertility
model." />
<figcaption>Example 703 conducts edge collapses on the fertility
model.</figcaption></figure>
model.</figcaption>
</figure>
<p>The <a href="./703_Decimation/main.cpp">Example 703</a> demonstrates using this priority
queue based approach with the simple shortest-edge-midpoint cost/placement
@@ -2859,7 +2932,7 @@ tree.squared_distance(V,F,P,sqrD,I,C);
<p>Finally, from the closest point or the winding number it&#8217;s possible to <em>sign</em>
this distance. In <code>igl::signed_distance</code> we provide two methods for signing:
the so-called &#8220;pseudo-normal test&#8221; <a class="citation" href="#fn:31" title="Jump to citation">[31]<span class="citekey" style="display:none">baerentzen_2005</span></a> and the generalized
winding number <a class="citation" href="#fn:29" title="Jump to citation">[29]<span class="citekey" style="display:none">jacobson_2013</span></a>. </p>
winding number <a class="citation" href="#fn:29" title="Jump to citation">[29]<span class="citekey" style="display:none">jacobson_2013</span></a>.</p>
<p>The pseudo-normal test (see also <code>igl::pseudonormal_test</code>) assumes the input
mesh is a watertight (closed, non-self-intersecting, manifold) mesh. Then given
@@ -2890,7 +2963,8 @@ with the pseudo-normal test.</p>
<img src="images/bunny-signed-distance.gif" alt="Example 704 computes signed distance on
slices through the bunny." />
<figcaption>Example <a href="704_SignedDistance/main.cpp">704</a> computes signed distance on
slices through the bunny.</figcaption></figure>
slices through the bunny.</figcaption>
</figure>
<h1 id="future">Outlook for continuing development</h1>