updated html and added --recursive in the tutorial readme
This commit is contained in:
+150
-76
@@ -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’’ <span class="math">\(\mathbf{L}\)</span>, arising
|
||||
processing is the so-called “cotangent Laplacian” <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’ 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,…,n–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’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 –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’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 “differential coordinates” 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’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,"VectorXML",xmlFile);
|
||||
igl::deserialize_xml(vec,"VectorBin",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(&engine,"EV",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),
|
||||
“resolve”. Bottom row reveals inner surfaces, darker color indicates
|
||||
back-facing triangles.</figcaption></figure>
|
||||
back-facing triangles.</figcaption>
|
||||
</figure>
|
||||
|
||||
<p>The union, symmetric difference and “resolve” 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 “removed” faces and edges are set to a special
|
||||
constant value <code>IGL_COLLAPSE_EDGE_NULL</code>. Doing this ensures that we’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’s possible to <em>sign</em>
|
||||
this distance. In <code>igl::signed_distance</code> we provide two methods for signing:
|
||||
the so-called “pseudo-normal test” <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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user