|
@@ -1,416 +0,0 @@
|
|
|
-<html>
|
|
|
- <head>
|
|
|
- <title>libigl developer tutorial</title>
|
|
|
- <link href="./style.css" rel="stylesheet" type="text/css">
|
|
|
- </head>
|
|
|
- <body>
|
|
|
- <div id=fixed_sidebar>
|
|
|
- <ul>
|
|
|
- <li>
|
|
|
- <a href=#header_library>Headers (.h) only library</a>
|
|
|
- <ul>
|
|
|
- <li><a href=#widget>IGL_HEADER_ONLY widget</a></li>
|
|
|
- <li><a href=#header_benefits_drawbacks>Benefits and drawbacks</a></li>
|
|
|
- </ul>
|
|
|
- </li>
|
|
|
- <li>
|
|
|
- <a href=#static_library>Statically linked library (libigl.a)</a>
|
|
|
- <ul>
|
|
|
- <li><a href=#static_benefits_drawbacks>Benefits and drawbacks</a></li>
|
|
|
- </ul>
|
|
|
- </li>
|
|
|
- <li>
|
|
|
- <a href=#compress>Compressed igl.h/igl.cpp pair</a>
|
|
|
- <ul>
|
|
|
- <li><a href=#compress_benefits_drawbacks>Benefits and drawbacks</a></li>
|
|
|
- </ul>
|
|
|
- </li>
|
|
|
- <li>
|
|
|
- <a href=#dependencies>Dependencies</a>
|
|
|
- </li>
|
|
|
- <li><a href=#matlab>Conversion from matlab</a>
|
|
|
- <ul>
|
|
|
- </div>
|
|
|
- <div id=container>
|
|
|
- <div class=article_outer>
|
|
|
- <div class=article_inner>
|
|
|
- <a href=.><img src=libigl-logo.jpg alt="igl logo" class=center></a>
|
|
|
- <h1>Using the libigl library</h1>
|
|
|
- <p>
|
|
|
- The <a href=.>libigl</a> library is a collection of useful/reusable/sharable C++ functions
|
|
|
- with very few external <a href="#dependencies">dependencies</a>. The
|
|
|
- library may be used as a <a href="#header_library">"headers only"
|
|
|
- library</a>, a <a href=#static_library>statically linked library</a>, or as a compressed <a href="#compress">.h/.cpp pair</a>.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p>
|
|
|
- This duality between statically compiled and header-only is illustrated
|
|
|
- in the example <code>examples/example_fun</code>. When built, this example
|
|
|
- compiles two binaries, one using the <code>example_fun</code> routine of
|
|
|
- the igl library, either as a headers-only library or linking against the
|
|
|
- igl static library.
|
|
|
- </p>
|
|
|
-
|
|
|
- <h2 id=header_library>Headers (.h) only library</h2>
|
|
|
- <p>
|
|
|
- All classes and functions in the libigl library are written in a way in
|
|
|
- which the entire library may be compiled <i>just-in-time</i>,
|
|
|
- effectively behaiving as if it were a "headers only" library (like e.g.
|
|
|
- Eigen). This is achieved by careful organization of each pair of .h and
|
|
|
- .cpp files. To take advantage of this one must only include the path to
|
|
|
- <code>libigl</code> directory in one's project's include path and
|
|
|
- define the preprocessor macro <code>IGL_HEADER_ONLY</code>.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p>
|
|
|
- Defining <code>IGL_HEADER_ONLY</code> may be done at the project level,
|
|
|
- prescribing that all included igl headers be treated as code that
|
|
|
- should be inlined. Consequently all templated functions will be derived
|
|
|
- at compile time if need be.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p id=widget>
|
|
|
- One may also define <code>IGL_HEADER_ONLY</code> not only on a per-file
|
|
|
- basis, but a <i>per-include</i> basis. For example it may be useful for a
|
|
|
- project to use the static library for most functionality from IGL, but then
|
|
|
- include a certain IGL function as an inlined function. This may be achieved
|
|
|
- by surrounding the relevant include with a define and undefine of the
|
|
|
- <code>IGL_HEADER_ONLY</code> macro. Here's an example of the little
|
|
|
- widget:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-...
|
|
|
-#include <igl/some_other_igl_function.h>
|
|
|
-#ifdef IGL_STATIC_LIBRARY
|
|
|
-# define IGL_HEADER_ONLY
|
|
|
-# define IGL_HEADER_ONLY_WAS_NOT_DEFINED
|
|
|
-#endif
|
|
|
-#include <igl/igl_function_to_inline.h>
|
|
|
-#ifndef IGL_STATIC_LIBRARY_WAS_NOT_DEFINED
|
|
|
-# undef IGL_HEADER_ONLY
|
|
|
-#endif
|
|
|
-#include <igl/yet_another_igl_function.h>
|
|
|
-...
|
|
|
- </code></pre>
|
|
|
- <span class=todo>example <code>examples/XXX</code> also highlights this
|
|
|
- feature</span>
|
|
|
-
|
|
|
- <div class=note>This practice is not recommended outside of debugging
|
|
|
- purposes.</div>
|
|
|
-
|
|
|
-
|
|
|
- <h3 id=header_benefits_drawbacks>Benefits of headers-only library</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Easy templates:</strong> When using the libigl library as a
|
|
|
- headers-only library no special care need be taken when using templated
|
|
|
- functions.</li>
|
|
|
- </ul>
|
|
|
- <h3>Drawbacks of headers-only library</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Inlining not guaranteed:</strong> Most compilers do not
|
|
|
- guarantee that functions will get inlined even if explicitly told to do
|
|
|
- so. Though we have not yet encountered this problem, it is always a
|
|
|
- risk.</li>
|
|
|
- <li><strong>Long compile, large binary:</strong>As a headers-only
|
|
|
- library we depend on the compiler to properly inline each function
|
|
|
- call. This means compile time is high and binary size can be quite
|
|
|
- large.</li>
|
|
|
- </ul>
|
|
|
-
|
|
|
- <h2 id=static_library>Statically linked library</h2>
|
|
|
- <h3 id=explicit_specialization_of_templated_functions>Explicit
|
|
|
- specialization of templated functions</h3>
|
|
|
- <p>
|
|
|
- Special care must be taken by the developers of each function and
|
|
|
- class in the libigl library that uses C++ templates. If this function
|
|
|
- is intended to be compiled into the statically linked libigl library
|
|
|
- then function is only compiled for each <i>explicitly</i> specialized
|
|
|
- declaration. These should be added at the bottom of the corresponding
|
|
|
- .cpp file surrounded by a <code>#ifdef IGL_STATIC_LIBRARY</code>.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p>
|
|
|
- Of course, a developer may not know ahead of time which
|
|
|
- specializations should be explicitly included in the igl static lib.
|
|
|
- One way to find out is to add one explicit specialization for each
|
|
|
- call in one's own project. This only ever needs to be done once for
|
|
|
- each template.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p>
|
|
|
- The process is somewhat mechanical using a linker with reasonable error
|
|
|
- output.
|
|
|
- </p>
|
|
|
-
|
|
|
- <p>
|
|
|
- Supposed for example we have compiled the igl static lib, including the
|
|
|
- cat.h and cat.cpp functions, without any explicit instanciation. Say
|
|
|
- using the makefile in the <code>libigl</code> directory:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-cd $LIBIGL
|
|
|
-make
|
|
|
- </code></pre>
|
|
|
- <p>
|
|
|
- Now if we try to compile a project and link against it we may get
|
|
|
- an error like:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-Undefined symbols for architecture x86_64:
|
|
|
- "<span class=highlight>Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&)</span>", referenced from:
|
|
|
- uniform_sample(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, int, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>&)in Skinning.o
|
|
|
- "Eigen::SparseMatrix<double, 0, int> igl::cat<Eigen::SparseMatrix<double, 0, int> >(int, Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&)", referenced from:
|
|
|
- covariance_scatter_matrix(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, ArapEnergy, Eigen::SparseMatrix<double, 0, int>&)in arap_dof.o
|
|
|
- arap_rhs(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, ArapEnergy, Eigen::SparseMatrix<double, 0, int>&)in arap_dof.o
|
|
|
- </code></pre>
|
|
|
- <p>
|
|
|
- This looks like a mess, but luckily we don't really need to read it
|
|
|
- all. Just copy the first highlighted part in quotes, then append it
|
|
|
- to the list of explicit templat specializations at the end of
|
|
|
- <code>cat.cpp</code> after the word
|
|
|
- <strong><code>template</code></strong> and followed by a semi-colon.
|
|
|
- Like this:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-...
|
|
|
-#ifdef IGL_STATIC_LIBRARY
|
|
|
- // Explicit template specialization
|
|
|
- <strong>template</strong> <span class=highlight>Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&)</span>;
|
|
|
-#endif
|
|
|
- </code></pre>
|
|
|
- <p>
|
|
|
- Then you must recompile the IGL static library.
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-cd $LIBIGL
|
|
|
-make
|
|
|
- </code></pre>
|
|
|
- <p>
|
|
|
- And try to compile your project again, potentially repeating this
|
|
|
- process until no more symbols are undefined.
|
|
|
- </p>
|
|
|
-
|
|
|
- <div class=note>It may be useful to check that you code compiles with
|
|
|
- no errors first using the <a href=#header_library>headers-only
|
|
|
- version</a> to be sure that all errors are from missing template
|
|
|
- specializations.</div>
|
|
|
-
|
|
|
- <p>
|
|
|
- If you're using make then the following command will
|
|
|
- reveal each missing symbol on its own line:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-make 2>&1 | grep "referenced from" | sed -e "s/, referenced from.*//"
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <p>
|
|
|
- Alternatively you can use the <code>autoexplicit.sh</code> function
|
|
|
- which (for well organized .h/.cpp pairs in libigl) automatically
|
|
|
- create explicit instanciations from your compiler's error messages.
|
|
|
- Repeat this process until convergence:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-cd /to/your/project
|
|
|
-make 2>$LIBIGL/make.err
|
|
|
-cd $LIBIGL
|
|
|
-cat make.err | ./autoexplicit.sh
|
|
|
-make clean
|
|
|
-make
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <h3 id=static_benefits_drawbacks>Benefits of static library</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Faster compile time:</strong> Because the libigl library
|
|
|
- is already compiled, only the new code in ones project must be
|
|
|
- compiled and then linked to IGL. This means compile times are
|
|
|
- generally faster.</li>
|
|
|
- <li><strong>Debug <i>or</i> optimized:</strong> The IGL static
|
|
|
- library may be compiled in debug mode or optimized release mode
|
|
|
- regardless of whether one's project is being optimized or
|
|
|
- debugged.</li>
|
|
|
- </ul>
|
|
|
- <h3>Drawbacks of static library</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Hard to use templates:</strong> <a
|
|
|
- href="#explicit_specialization_of_templated_functions">Special
|
|
|
- care</a> (by the developers of the library) needs to be taken when
|
|
|
- exposing templated functions.</li>
|
|
|
- </ul>
|
|
|
-
|
|
|
- <h2 id=compress>Compressed .h/.cpp pair</h2>
|
|
|
- <p>Calling the script:</p>
|
|
|
- <pre><code>scripts/compress.sh igl.h igl.cpp</code></pre>
|
|
|
- <p>will create a single header
|
|
|
- <code>igl.h</code> and a single cpp file <code>igl.cpp</code>.
|
|
|
-
|
|
|
- <p>Alternatively, you can also compress everything into a single header file (analagous to IGL_HEADER_ONLY):</p>
|
|
|
- <pre><code>scripts/compress.sh igl.h</code></pre>
|
|
|
-
|
|
|
- <h3 id=compress_benefits_drawbacks>Benefits of compressed .h/.cpp pair</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Easy incorporation:</strong> This can be easily incorporated
|
|
|
- into external projects.</li>
|
|
|
- </ul>
|
|
|
- <h3>Drawbacks of compressed .h/.cpp pair</h3>
|
|
|
- <ul>
|
|
|
- <li><strong>Hard to debug/edit:</strong> The compressed files are
|
|
|
- automatically generated. They're huge and should not be edited. Thus
|
|
|
- debugging and editting are near impossible.</li>
|
|
|
- <li><strong>Compounded dependencies:</strong>
|
|
|
- An immediate disadvantage of this
|
|
|
- seems to be that even to use a single function (e.g.
|
|
|
- <code>cotmatrix</code>), compiling and linking against
|
|
|
- <code>igl.cpp</code> will require linking to all of <code>libigl</code>'s
|
|
|
- dependencies (<code>OpenGL</code>, <code>GLUT</code>,
|
|
|
- <code>AntTweakBar</code>, <code>BLAS</code>). However, because all
|
|
|
- depencies other than Eigen should be encapsulated between
|
|
|
- <code>#ifndef</code> guards (e.g. <code>#ifndef IGL_NO_OPENGL</code>, it
|
|
|
- is possible to ignore certain functions that have such dependencies.</li>
|
|
|
- <li><strong>Long compile:</strong> Compiling <code>igl.cpp</code> takes a long time and isn't easily parallelized (no <code>make -j12</code> equivalent).</li>
|
|
|
- </ul>
|
|
|
-
|
|
|
- <p>Here's a tiny test example using <code>igl.h</code> and <code>igl.cpp</code>. Save the following in <code>test.cpp</code>:</p>
|
|
|
- <pre><code>
|
|
|
-#include <igl.h>
|
|
|
-#include <Eigen/Core>
|
|
|
-
|
|
|
-int main(int argc, char * argv[])
|
|
|
-{
|
|
|
- Eigen::MatrixXd V;
|
|
|
- Eigen::MatrixXi F;
|
|
|
- return (argc>=2 && igl::read_triangle_mesh(argv[1],V,F)?0:1);
|
|
|
-}
|
|
|
- </code></pre>
|
|
|
- <p>Then compile <code>igl.cpp</code> with:
|
|
|
- <pre><code>
|
|
|
-g++ -o igl.o -c igl.cpp -I/opt/local/include/eigen3 -DIGL_NO_OPENGL -DIGL_NO_ANTTWEAKBAR
|
|
|
- </code></pre>
|
|
|
- <p>Notice that we're using <code>-DIGL_NO_OPENGL -DIGL_NO_ANTTWEAKBAR</code> to disable any libigl dependencies on OpenGL and AntTweakBar.</p>
|
|
|
-
|
|
|
- <p>Now compile <code>test.cpp</code> with:
|
|
|
- <pre><code>
|
|
|
-g++ -g -I/opt/local/include/eigen3/ -I/usr/local/igl/libigl/ -L/usr/local/igl/libigl/ -ligl -DIGL_NO_OPENGL -DIGL_NO_ANTTWEAKBAR -o test
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <p>Try running it with:</p>
|
|
|
- <pre><code>
|
|
|
-./test path/to/mesh.obj
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <p>The following bash one-liner will find all source files that contain the string <code>OpenGL</code> but don't contain and <code>IGL_NO_OPENGL</code> guard:
|
|
|
- <pre><code>
|
|
|
-grep OpenGL `grep -L IGL_NO_OPENGL include/igl/*`
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <h2 id="dependencies">Dependencies</h2>
|
|
|
- <p>
|
|
|
- By design the libigl library has very few external dependencies.
|
|
|
- </p>
|
|
|
- <h3>Mandatory dependencies</h3>
|
|
|
- <p> <a href=http://eigen.tuxfamily.org/>Eigen3</a> and the Standard
|
|
|
- Template Library (STL) are the only truly mandatory dependencies.
|
|
|
- Without them libigl will not compile or work properly.</p>
|
|
|
- <p> OpenGL is an <i>assumed</i> dependency, but is in fact also
|
|
|
- optional. All OpenGL-dependent functions may be disabled by defining
|
|
|
- the <code>IGL_NO_OPENGL</code> preprocessor macro.</p>
|
|
|
- </p>
|
|
|
- <p> Likewise,
|
|
|
- <a href="http://www.antisphere.com/Wiki/tools:anttweakbar">AntTweakBar</a>
|
|
|
- is an
|
|
|
- <i>assumed</i> dependency, similarly diabled by defining
|
|
|
- the <code>IGL_NO_ANTTWEAKBAR</code> preprocessor macro.</p>
|
|
|
-
|
|
|
- <p><span class=todo>Each IGL_NO_XXX should just be replaced by a libiglXXX.a extra</span></p>
|
|
|
- <h3>Optional dependencies</h3>
|
|
|
- <p>
|
|
|
- Certain <i>extra</i> functions and classes included the libigl
|
|
|
- library have external dependencies by construction (e.g. the
|
|
|
- matlab_interface routines are only useful when matlab is present
|
|
|
- anyway). These are <strong>never</strong> compiled by default into
|
|
|
- the static igl library, rather they are compiled as "extras" (e.g.
|
|
|
- libiglmatlab.a contains the MATLAB-dependent functions).
|
|
|
- </p>
|
|
|
- <p>Currently these include:<p>
|
|
|
- <table>
|
|
|
- <tr class=header><th>Extra</th><th>Dependency</th></tr>
|
|
|
- <tr class=d0><td>libiglmatlab.a</td><td>MATLAB</td></tr>
|
|
|
- <tr class=d1><td>libiglmosek.a</td><td>Mosek</td></tr>
|
|
|
- <tr class=d0><td>libigltetgen.a</td><td>TetGen</td></tr>
|
|
|
- <tr class=d1><td>libiglxml.a</td><td>TinyXml2</td></tr>
|
|
|
- <tr class=d0><td>libiglpng.a</td><td>LibPNG</td></tr>
|
|
|
- <tr class=d1><td>libiglembree.a</td><td>Embree</td></tr>
|
|
|
- </table>
|
|
|
- <p>Some of our examples (<code>libigl/examples</code>) also depend on GLUT.</p>
|
|
|
-
|
|
|
- <h2 id=matlab>Converting matlab code to C++ using IGL and Eigen</h2>
|
|
|
- <p>
|
|
|
- Eigen's matrix API often makes it fairly to translate to and from
|
|
|
- matlab code (Eigen provides a <a
|
|
|
- href=http://eigen.tuxfamily.org/dox/AsciiQuickReference.txt>
|
|
|
- translation table</a>). We have implemented a few additional
|
|
|
- matlab-esque functions to make the translation even easier. <a
|
|
|
- href="matlab-to-eigen.html">Our own translation table</a> shows a list
|
|
|
- of common matlab functions and their igl-eigen equivalents.
|
|
|
- </p>
|
|
|
-
|
|
|
- <h3>Including OpenGL</h3>
|
|
|
- <p>Just include the convenience header, which takes care of system dependent paths, <code>glew</code>, etc.:</p>
|
|
|
- <pre><code>
|
|
|
-#include "OpenGL_convenience.h"
|
|
|
- </code></pre>
|
|
|
- <!--<p>Likewise for GLUT:</p>
|
|
|
- <pre><code>
|
|
|
-#include "GLUT_convenience.h"
|
|
|
- </code></pre>-->
|
|
|
- <del>
|
|
|
- <p>
|
|
|
- A standard include for the OpenGL headers should be placed in the .cpp file if possible. To ensure compilability on Mac OS X, Windows and Linux, use:
|
|
|
- <pre><code>
|
|
|
-#if __APPLE__
|
|
|
-# include <OpenGL/gl.h>
|
|
|
-#elif defined(_WIN32)
|
|
|
-# define NOMINMAX
|
|
|
-# include <Windows.h>
|
|
|
-# undef NOMINMAX
|
|
|
-# include <GL/glew.h>
|
|
|
-# include <GL/gl.h>
|
|
|
-#else
|
|
|
-# define GL_GLEXT_PROTOTYPES
|
|
|
-# include <GL/gl.h>
|
|
|
-# include <GL/glext.h>
|
|
|
-#endif
|
|
|
- </code></pre>
|
|
|
- </p>
|
|
|
- </del>
|
|
|
- <h3>Including headers to other igl functions</h3>
|
|
|
- <p>
|
|
|
- Source files in the main igl directory should include other libigl headers using the name of the file in quotation marks:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-#include "other_function.h"
|
|
|
- </code></pre>
|
|
|
-
|
|
|
- <p>
|
|
|
- Source files in your project and in libigl <i>extras</i> should include libigl headers using the igl directory and name file in angle brackets:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-#include <igl/some_function.h>
|
|
|
- </code></pre>
|
|
|
- <p>
|
|
|
- libigl headers of extras can then be included using:
|
|
|
- </p>
|
|
|
- <pre><code>
|
|
|
-#include <igl/extra/some_extra_function.h>
|
|
|
- </code></pre>
|
|
|
-
|
|
|
-
|
|
|
- <hr>
|
|
|
- <p>See also: <a href=style_guidelines.html>style guidlines</a>, <a
|
|
|
- href=doc.html>auto-documentation</a>, <a
|
|
|
- href=file-formats/index.html>file formats</a></p>
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </body>
|
|
|
-</html>
|