forked from libigl/libigl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtutorial.html
More file actions
416 lines (385 loc) · 17.7 KB
/
tutorial.html
File metadata and controls
416 lines (385 loc) · 17.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
<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>
#ifndef IGL_HEADER_ONLY
# define IGL_HEADER_ONLY
# define IGL_HEADER_ONLY_WAS_NOT_DEFINED
#endif
#include <igl/igl_function_to_inline.h>
#ifdef IGL_HEADER_ONLY_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>#ifndef IGL_HEADER_ONLY</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>
...
#ifndef IGL_HEADER_ONLY
// 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(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>