Browse Source

Merge branch 'master' of https://github.com/libigl/libigl

Conflicts:
	include/igl/barycenter.cpp

Former-commit-id: c155c57bacb36fa756f45ef86c9577ce7eb446ff
Olga Diamanti 10 năm trước cách đây
mục cha
commit
cae8d73321
39 tập tin đã thay đổi với 1519 bổ sung1533 xóa
  1. 65 350
      README.md
  2. 69 0
      RELEASE_HISTORY.txt
  3. 1 1
      build/Makefile_cgal
  4. 386 0
      build/README.md
  5. 472 0
      build/index.html
  6. 1 0
      examples/multi-viewport/example.cpp
  7. 3 1
      examples/principal_curvature/curvature.cpp
  8. 41 11
      examples/skeleton-posing/example.cpp
  9. 2 2
      include/igl/WindingNumberTree.h
  10. 1 1
      include/igl/all_pairs_distances.cpp
  11. 1 1
      include/igl/boundary_conditions.cpp
  12. 12 4
      include/igl/cgal/SelfIntersectMesh.h
  13. 0 2
      include/igl/cgal/intersect_other.cpp
  14. 6 0
      include/igl/cgal/point_mesh_squared_distance.cpp
  15. 2 1
      include/igl/cgal/signed_distance.cpp
  16. 5 0
      include/igl/doublearea.cpp
  17. 18 12
      include/igl/edge_lengths.cpp
  18. 43 55
      include/igl/exterior_edges.cpp
  19. 1 1
      include/igl/exterior_edges.h
  20. 16 3
      include/igl/facet_components.cpp
  21. 4 2
      include/igl/facet_components.h
  22. 25 7
      include/igl/internal_angles.cpp
  23. 3 3
      include/igl/massmatrix.cpp
  24. 200 130
      include/igl/outer_hull.cpp
  25. 11 5
      include/igl/per_edge_normals.cpp
  26. 2 0
      include/igl/per_vertex_normals.cpp
  27. 0 3
      include/igl/principal_curvature.h
  28. 2 2
      include/igl/project_to_line.cpp
  29. 4 0
      include/igl/sortrows.cpp
  30. 1 0
      include/igl/unique.cpp
  31. 2 2
      include/igl/unique_edge_map.h
  32. 9 1
      include/igl/unique_simplices.cpp
  33. 9 9
      include/igl/winding_number.h
  34. 64 505
      index.html
  35. 30 0
      scripts/update_gh-pages.sh
  36. 0 416
      tutorial.html
  37. 6 1
      tutorial/403_BoundedBiharmonicWeights/main.cpp
  38. 1 1
      tutorial/tutorial.html.REMOVED.git-id
  39. 1 1
      tutorial/tutorial.md.REMOVED.git-id

+ 65 - 350
README.md

@@ -1,28 +1,37 @@
-libigl - A simple c++ geometry processing library
-=================================================
+# libigl - A simple C++ geometry processing library
 
 ![](tutorial/images/libigl-logo.jpg)
 
-<http://libigl.github.io/libigl/>
 <https://github.com/libigl/libigl/>
 
-Copyright 2014 - Alec Jacobson, Daniele Panozzo, Olga Diamanti, Kenshi
-Takayama, Leo Sacht, Wenzel Jacob, etc.
+libigl is a simple C++ geometry processing library. We have a wide
+functionality including construction of sparse discrete differential geometry
+operators and finite-elements matrices such as the contangent Laplacian and
+diagonalized mass matrix, simple facet and edge-based topology data structures,
+mesh-viewing utilities for OpenGL and GLSL, and many core functions for matrix
+manipulation which make [Eigen](http://eigen.tuxfamily.org) feel a lot more
+like MATLAB.
 
-Libigl is first and foremost a *header* library. Each header file should
-contain a single function.  This function may have multiple overloads and
-prototypes. All functions should use the `igl::` namespace and should adhere to
-the conventions and styles listed in the [style
-guidelines](style_guidelines.html).
+It is first and foremost a header library. Each header file contains a single
+function. Most are tailored to operate on a generic triangle mesh stored in an
+n-by-3 matrix of vertex positions V and an m-by-3 matrix of triangle indices F.
+The library may also be [compiled](build/) into a statically linked
+library, for faster compile times with your projects.
 
-> **New:** As of 1 July 2014, we have released libigl as beta version 1.0.
-> There are a number of changes we collected for this release to minimize
-> confusion and changes to how you use libigl. See [Version 1.0
-> Changes][version1.0changes].
+We use the [Eigen](http://eigen.tuxfamily.org) library heavily in our code. Our
+group prototypes a lot in MATLAB, and we have a useful [conversion
+table](matlab-to-eigen.html) from
+MATLAB to libigl/Eigen.
 
-## Installation ##
+# Tutorial
+
+As of version 1.0, libigl includes an introductory
+[tutorial](tutorial/tutorial.html) that covers
+its basic functionalities.
+
+## Installation
 Libigl is a *header* library. You do **not** need to build anything to install.
-Simple add `igl/` to your include path and include relevant headers. Here's a
+Simply add `igl/` to your include path and include relevant headers. Here is a
 small "Hello, World" program:
 
 ```cpp
@@ -47,8 +56,8 @@ int main()
 }
 ```
 
-If you save this in `hello.cpp`, then on `gcc` with Eigen installed via
-macports for example you could compile this with:
+If you save this in `hello.cpp`, then you could compile this with (assuming
+Eigen is installed in /opt/local/include/eigen3):
 
 ```bash
 gcc -I/opt/local/include/eigen3 -I./igl/ hello.cpp -o hello
@@ -64,344 +73,30 @@ Hello, mesh:
  0.5 -0.5
 ```
 
-## Tutorial ##
-
-As of version 1.0, libigl includes an introductory
-[tutorial](http://libigl.github.io/libigl/tutorial/tutorial.html) that covers
-its basic functionalities.
-
-## Dependencies ##
-- Eigen3  Last tested with Eigen Version 3.2
-
-### Optional ###
-- OpenGL (disable with `IGL_NO_OPENGL`)
-    * OpenGL >= 4 (enable with `IGL_OPENGL_4`)
-- AntTweakBar  (disable with `IGL_NO_ANTTWEAKBAR`) Last tested 1.16 (see
-  `libigl/external/AntTweakBar`)
-- GLEW  Windows and Linux
-- OpenMP
-- libpng  libiglpng extra only
-- Mosek  libiglmosek extra only
-- Matlab  libiglmatlab extra only
-- boost  libiglboost, libiglcgal extra only
-- SSE/AVX  libiglsvd3x3 extra only
-- CGAL  libiglcgal extra only
-    * boost
-    * gmp
-    * mpfr
-- CoMiSo libcomiso extra only
-
-### Optional (included in external/) ###
-- TetGen  libigltetgen extra only
-- Embree  libiglembree extra only
-- tinyxml2  libiglxml extra only
-- glfw libviewer extra only
-- LIM  liblim extra only
-
-## Header only ##
-Libigl is designed to work "out-of-the-box" as a headers only library. To
-include libigl in your project. You need only include the libigl/include/
-directory in your include path. To
-compile a hello-word example.cpp:
-
-    #include <Eigen/Dense>
-    #include <igl/readOBJ.h>
-    #include <iostream>
-    int main(int argc, char * argv[])
-    {
-      if(argc>1)
-      {
-        Eigen::MatrixXd V;
-        Eigen::MatrixXi F;
-        igl::readOBJ(argv[1],V,F);
-        std::cout<<"Hello, mesh with "<<V.rows()<<" vertices!"<<std::endl;
-      }else{
-        std::cout<<"Hello, world!"<<std::endl;
-      }
-      return 0;
-    }
-
-using gcc (replacing appropriate paths):
-
-    g++ -I/usr/local/igl/libigl/include \
-      -I/opt/local/include/eigen3 example.cpp -o example
-
-Then run this example with:
-
-    ./example examples/shared/TinyTorus.obj
-
-## Compilation as a static library ##
-Libigl is developed most often on Mac OS X, though has current users in Linux
-and Windows.
-
-### Linux/Mac OS X/Cygwin ###
-
-Libigl may also be compiled to a static library. This is advantageous when
-building a project with libigl, since when used as an header-only library can
-slow down compile times.
-
-To build the entire libigl library producing lib/libigl.a, issue:
-
-    cd build
-    make lib
-
-You may need to edit Makefile.conf accordingly. Best to give yourself an
-`IGL_USERNAME` and add a custom install suite for yourself. Then you can enable
-appropriate extras.
-
-#### Extras ####
-Once you've set up an `IGL_USERNAME` and enabled extras within Makefile.conf.
-You can build the extra libraries (into lib/ligiglpng.a, lib/libiglmatlab.a,
-lib/libigltetgen.a, lib/libiglmosek.a, etc.) by issuing:
-
-    cd build
-    make extras
-
-#### Examples ####
-You can make a slew of examples by issuing:
-
-    cd build
-    make examples
-
-#### External ####
-Finally there are a number of external libraries that we include in
-./external/ because they are either difficult to obtain or they have been
-patched for easier use with libigl. Please see the respective readmes in
-those directories.
-
-
-##### Installing AntTweakBar #####
-To build the a static AntTweakBar library on Mac OS X issue:
-
-    cd external/AntTweakBar/src
-    make -f Makefile.osx.igl
-
-##### Installing Tetgen #####
-To build the tetgen library and executable on Mac OS X issue:
-
-    cd external/tetgen
-    make clean
-    rm -f obj/*.o
-    make -f Makefile.igl tetgen
-    rm -f obj/*.o
-    make -f Makefile.igl tetlib
-
-##### Installing medit #####
-To build the igl version of the medit executable on Mac OS X issue:
-
-    cd external/medit
-    make -C libmesh
-    make -f Makefile.igl medit
-
-##### Installing Embree 2.0 #####
-To build the embree library and executables on Mac OS X issue:
-
-    cd external/embree
-    mkdir build
-    cd build
-    cmake ..
-    # Or using a different compiler
-    #cmake .. -DCMAKE_C_COMPILER=/opt/local/bin/gcc -DCMAKE_CXX_COMPILER=/opt/local/bin/g++
-    make
-    # Could also install embree to your root, but libigl examples don't expect
-    # this
-    #sudo make install
-
-##### Installing tinyxml2 #####
-To build the a static tinyxml2 library on Mac OS X issue:
-
-    cd external/tinyxml2
-    cmake .
-    make
-
-
-##### Installing YImg #####
-To build the a static YImg library on Mac OS X issue:
-
-    cd external/yimg
-    make
+## Dependencies
+Dependencies are on a per-include basis and the majority of the functions in
+libigl depends only on the [Eigen](http://eigen.tuxfamily.org) library.
 
-You may need to install libpng. Systems with X11 might find this already
-installed at `/usr/X11/lib`.
+For more information see our [tutorial](tutorial/tutorial.html).
 
+# Download
+You can keep up to date by cloning a read-only copy of our GitHub
+[repository](https://github.com/libigl).
 
-### Windows (Experimental) ###
-To build a static library (.lib) on windows, open Visual Studio 2010.
+## How to contribute
 
-- New > Project ...
-- Visual C++ > Win32
-- Win32 Console Application
-- Name: libiglVisualStudio
-- Uncheck "Create directory for solution"
-- Then hit OK, and then Next
-- Check "Static Library"
-- Uncheck "Precompiled headers"
-- Add all include/igl/*.cpp to the sources directory
-- Add all include/igl/*.h to the headers directory
-- Open Project > libigl Properties...
-- Add the path to eigen3 to the include paths
-- Change the target name to libigl
-- Build and pray (this should create libigl.lib
+If you are interested in joining development, please fork the repository and
+submit a [pull request](https://help.github.com/articles/using-pull-requests/)
+with your changes.
 
-[Source](http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx)
+## License
+libigl is primarily [MPL2](http://www.mozilla.org/MPL/2.0/) licensed
+([FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html)). Some files contain
+third-party code under other licenses. We're currently in the processes of
+identifying these and marking appropriately.
 
-## Examples ##
-To get started, we advise that you take a look at a few examples:
-
-    ./examples/hello-world/
-
-    ./examples/meshio/
-
-    ./examples/basic-topology/
-
-    ./examples/ReAntTweakBar/
-
-## Extras ##
-Libigl compartmentalizes dependences via its organization into a _main_ libigl
-library and "extras."
-
-
-### bbw ###
-This library extra contains functions for computing Bounded Biharmonic Weights, can
-be used with and without the [mosek](#mosek) extra via the `IGL_NO_MOSEK`
-macro.
-
-### boost ###
-This library extra utilizes the graph functions in the boost library for find
-connected components and performing breadth-first traversals.
-
-### cgal ###
-This library extra utilizes CGAL's efficient and exact intersection and
-proximity queries.
-
-### embree ###
-This library extra utilizes embree's efficient ray tracing queries.
-
-### matlab ###
-This library extra provides support for reading and writing `.mat` workspace
-files, interfacing with Matlab at run time and compiling mex functions.
-
-### mosek ###
-This library extra utilizes mosek's efficient interior-point solver for
-quadratic programs.
-
-### png ###
-This library extra uses `libpng` and `YImage` to read and write `.png` files.
-
-### svd3x3 ###
-This library extra implements "as-rigid-as-possible" (ARAP) deformation
-techniques using the fast singular value decomposition routines
-written specifically for 3x3 matrices to use `SSE` intrinsics. This extra can
-still be compiled without sse support and support should be determined
-automatically at compile time via the `__SSE__` macro.
-
-### tetgen ###
-This library extra provides a simplified wrapper to the tetgen 3d tetrahedral meshing
-library.
-
-### viewer ###
-This library extra utilizes glfw and glew to open an opengl context and launch
-a simple mesh viewer.
-
-### xml ###
-This library extra utilizes tinyxml2 to read and write serialized classes
-containing Eigen matrices and other standard simple data-structures.
-
-## Development ##
-Further documentation for developers is listed in tutorial.html,
-style_guidelines.html
-
-## License ##
-See `LICENSE.txt`
-
-## Zipping ##
-Zip this directory without .git litter and binaries using:
-
-    git archive -prefix=libigl/ -o libigl.zip master
-
-## Version 1.0 Changes ##
-Our beta release marks our confidence that this library can be used outside of
-casual experimenting. To maintain order, we have made a few changes which
-current users should read and adapt their code accordingly.
-
-### Renamed functions ###
-The following table lists functions which have changed name as of version
-1.0.0:
-
-Old                              | New
--------------------------------- | -------------------------------------
-`igl::add_barycenter`            | `igl::false_barycentric_subdivision`
-`igl::areamatrix`                | `igl::vector_area_matrix`
-`igl::barycentric2global`        | `igl::barycentric_to_global`
-`igl::boundary_faces`            | `igl::boundary_facets`
-`igl::boundary_vertices_sorted`  | `igl::boundary_loop`
-`igl::cotangent`                 | `igl::cotmatrix_entries`
-`igl::edgetopology`              | `igl::edge_topology`
-`igl::gradMat`                   | `igl::grad`
-`igl::is_manifold`               | `igl::is_edge_manifold`
-`igl::mexStream`                 | `igl::MexStream`
-`igl::moveFV`                    | `igl::average_onto_vertices`
-`igl::moveVF`                    | `igl::average_onto_faces`
-`igl::plot_vector`               | `igl::print_vector`
-`igl::pos`                       | `igl::HalfEdgeIterator`
-`igl::plane_project`             | `igl::project_isometrically_to_plane`
-`igl::project_points_mesh`       | `igl::line_mesh_intersection`
-`igl::read`                      | `igl::read_triangle_mesh`
-`igl::removeDuplicates.cpp`      | `igl::remove_duplicates`
-`igl::removeUnreferenced`        | `igl::remove_unreferenced`
-`igl::tt`                        | `igl::triangle_triangle_adjacency`
-`igl::vf`                        | `igl::vertex_triangle_adjacency`
-`igl::write`                     | `igl::write_triangle_mesh`
-`igl::manifold_patches`          | `igl::orientable_patches`
-`igl::selfintersect`             | `igl::remesh_self_intersections`
-`igl::project_mesh`              | `igl::line_mesh_intersection`
-`igl::triangulate`               | `igl::polygon_mesh_to_triangle_mesh`
-`igl::is_manifold`               | `igl::is_edge_manifold`
-`igl::triangle_wrapper`          | `igl::triangulate`
-
-### Miscellaneous ###
- - To match interfaces provided by (all) other quadratic optimization
-   libraries, `igl::min_quad_with_fixed` and `igl::active_set` now expect as
-   input twice the quadratic coefficients matrix, i.e. the Hessian. For
-   example, `igl::min_quad_with_fixed(H,B,...)` minimizes $\frac{1}{2}x^T H
-   x+x^T B$.
- - We have inverted the `IGL_HEADER_ONLY` macro to `IGL_STATIC_LIBRARY`. To
-   compile using libigl as a header-only library, simply include headers and
-   libigl in the header search path. To link to libigl, you must define the
-   `IGL_STATIC_LIBRARY` macro at compile time and link to the `libigl*.a`
-   libraries.
- - Building libigl as a static library is now more organized. There is a
-   `build/` directory with Makefiles for the main library (`Makefile`) and each
-   dependency (e.g. `Makefile_mosek` for `libiglmosek.a`)
- - `igl::polar_svd` now always returns a rotation in `R`, never a reflection.
-   This mirrors the behavior of `igl::polar_svd3x3`.  Consequently the `T`
-   part may have negative skews.
- - We have organized the static
- - The previous `igl::grad` function, which computed the per-triangle gradient
-   of a per-vertex scalar function has been replaced. Now `igl::grad` computes
-   the linear operator (previous computed using `igl::gradMat`). The gradient
-   values can still be recovered by multiplying the operator against the scalar
-   field as a vector and reshaping to have gradients per row.
- - `MASSMATRIX_*` has become `MASSMATRIX_TYPE_*`
- - The function `igl::project_normals`, which cast a line for each vertex of
-   mesh _A_ in the normal direction and found the closest intersection along
-   these lines with mesh _B_, has been removed.
-
-## Contact ##
-Libigl is a group endeavor led by Alec Jacobson and Daniele Panozzo. Please
-contact [alecjacobson@gmail.com](mailto:alecjacobson@gmail.com) if you have
-questions or comments. We are happy to get feedback! Enjoy!
-
-If you're using libigl in your projects, quickly [drop us a
-note](mailto:alecjacobson@gmail.com). Tell us who you are and what you're using
-it for. This helps us apply for funding and justify spending time maintaining
-this.
-
-If you find bugs or have problems please use our [github issue tracking
-page](https://github.com/libigl/libigl/issues).
-
-## Academic citation ##
-If you use libigl in your research projects, please cite the papers we
+## Attribution
+If you use libigl in your academic projects, please cite the papers we
 implement as appropriate. To cite the library in general, you could use this
 BibTeX entry:
 
@@ -413,3 +108,23 @@ BibTeX entry:
   year = {2014},
 }
 ```
+
+# Contact
+
+Libigl is a group endeavor led by [Alec
+Jacobson](http://www.cs.columbia.edu/~jacobson/) and [Daniele
+Panozzo](http://www.inf.ethz.ch/personal/dpanozzo/). Please [contact
+us](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com) if you have
+questions or comments. We are happy to get feedback!
+
+If you're using libigl in your projects, quickly [drop us a
+note](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com). Tell us who you
+are and what you're using it for. This helps us apply for funding and justify
+spending time maintaining this.
+
+If you find bugs or have problems please use our [github issue tracking
+page](https://github.com/libigl/libigl/issues).
+
+### Copyright
+2014 Alec Jacobson, Daniele Panozzo, Olga Diamanti, Kenshi
+Takayama, Leo Sacht, Wenzel Jacob, Nico Pietroni, Amir Vaxman

+ 69 - 0
RELEASE_HISTORY.txt

@@ -3,6 +3,75 @@
 1.0.2  Bug fix in winding number code
 1.0.1  Bug fixes and more CGAL support
 1.0.0  Major beta release: many renames, tutorial, triangle wrapper, org. build
+
+## Version 1.0 Changes ##
+Our beta release marks our confidence that this library can be used outside of
+casual experimenting. To maintain order, we have made a few changes which
+current users should read and adapt their code accordingly.
+
+### Renamed functions ###
+The following table lists functions which have changed name as of version
+1.0.0:
+
+Old                              | New
+-------------------------------- | -------------------------------------
+`igl::add_barycenter`            | `igl::false_barycentric_subdivision`
+`igl::areamatrix`                | `igl::vector_area_matrix`
+`igl::barycentric2global`        | `igl::barycentric_to_global`
+`igl::boundary_faces`            | `igl::boundary_facets`
+`igl::boundary_vertices_sorted`  | `igl::boundary_loop`
+`igl::cotangent`                 | `igl::cotmatrix_entries`
+`igl::edgetopology`              | `igl::edge_topology`
+`igl::gradMat`                   | `igl::grad`
+`igl::is_manifold`               | `igl::is_edge_manifold`
+`igl::mexStream`                 | `igl::MexStream`
+`igl::moveFV`                    | `igl::average_onto_vertices`
+`igl::moveVF`                    | `igl::average_onto_faces`
+`igl::plot_vector`               | `igl::print_vector`
+`igl::pos`                       | `igl::HalfEdgeIterator`
+`igl::plane_project`             | `igl::project_isometrically_to_plane`
+`igl::project_points_mesh`       | `igl::line_mesh_intersection`
+`igl::read`                      | `igl::read_triangle_mesh`
+`igl::removeDuplicates.cpp`      | `igl::remove_duplicates`
+`igl::removeUnreferenced`        | `igl::remove_unreferenced`
+`igl::tt`                        | `igl::triangle_triangle_adjacency`
+`igl::vf`                        | `igl::vertex_triangle_adjacency`
+`igl::write`                     | `igl::write_triangle_mesh`
+`igl::manifold_patches`          | `igl::orientable_patches`
+`igl::selfintersect`             | `igl::remesh_self_intersections`
+`igl::project_mesh`              | `igl::line_mesh_intersection`
+`igl::triangulate`               | `igl::polygon_mesh_to_triangle_mesh`
+`igl::is_manifold`               | `igl::is_edge_manifold`
+`igl::triangle_wrapper`          | `igl::triangulate`
+
+### Miscellaneous ###
+ - To match interfaces provided by (all) other quadratic optimization
+   libraries, `igl::min_quad_with_fixed` and `igl::active_set` now expect as
+   input twice the quadratic coefficients matrix, i.e. the Hessian. For
+   example, `igl::min_quad_with_fixed(H,B,...)` minimizes $\frac{1}{2}x^T H
+   x+x^T B$.
+ - We have inverted the `IGL_HEADER_ONLY` macro to `IGL_STATIC_LIBRARY`. To
+   compile using libigl as a header-only library, simply include headers and
+   libigl in the header search path. To link to libigl, you must define the
+   `IGL_STATIC_LIBRARY` macro at compile time and link to the `libigl*.a`
+   libraries.
+ - Building libigl as a static library is now more organized. There is a
+   `build/` directory with Makefiles for the main library (`Makefile`) and each
+   dependency (e.g. `Makefile_mosek` for `libiglmosek.a`)
+ - `igl::polar_svd` now always returns a rotation in `R`, never a reflection.
+   This mirrors the behavior of `igl::polar_svd3x3`.  Consequently the `T`
+   part may have negative skews.
+ - We have organized the static
+ - The previous `igl::grad` function, which computed the per-triangle gradient
+   of a per-vertex scalar function has been replaced. Now `igl::grad` computes
+   the linear operator (previous computed using `igl::gradMat`). The gradient
+   values can still be recovered by multiplying the operator against the scalar
+   field as a vector and reshaping to have gradients per row.
+ - `MASSMATRIX_*` has become `MASSMATRIX_TYPE_*`
+ - The function `igl::project_normals`, which cast a line for each vertex of
+   mesh _A_ in the normal direction and found the closest intersection along
+   these lines with mesh _B_, has been removed.
+
 0.4.6  Generalized Winding Numbers
 0.4.5  CGAL extra: mesh selfintersection
 0.4.4  STL file format support

+ 1 - 1
build/Makefile_cgal

@@ -26,7 +26,7 @@ INC+=$(EIGEN3_INC)
 # CGAL dependency
 CGAL=$(DEFAULT_PREFIX)
 CGAL_INC=-I$(CGAL)/include
-CGAL_FLAGS=-frounding-math -fsignaling-nans 
+CGAL_FLAGS=-frounding-math -fsignaling-nans ${OPENMP}
 CFLAGS+=$(CGAL_FLAGS)
 INC+=$(CGAL_INC)
 

+ 386 - 0
build/README.md

@@ -0,0 +1,386 @@
+# Compiling libigl as a static library
+
+> Warning: compiling libigl as a static library is considerably more difficult
+> than using it as a header-only library (see `../README.md` instead). Do it
+> only if you are experienced with C++ and you want to improve your compilation
+> times.
+
+Libigl is developed most often on Mac OS X, though has current users in Linux
+and Windows.
+
+### Linux/Mac OS X/Cygwin ###
+
+Libigl may also be compiled to a static library. This is advantageous when
+building a project with libigl, since when used as an header-only library can
+slow down compile times.
+
+To build the entire libigl library producing `lib/libigl.a`, issue:
+
+    cd build
+    make lib
+
+You may need to edit `Makefile.conf` accordingly. Best to give yourself an
+`IGL_USERNAME` and add a custom install suite for yourself. Then you can enable
+appropriate extras.
+
+#### Extras ####
+Once you've set up an `IGL_USERNAME` and enabled extras within Makefile.conf.
+You can build the extra libraries (into `lib/ligiglpng.a`, `lib/libiglmatlab.a`,
+`lib/libigltetgen.a`, `lib/libiglmosek.a`, etc.) by issuing:
+
+    cd build
+    make extras
+
+#### Examples ####
+You can make a slew of examples by issuing:
+
+    cd build
+    make examples
+
+#### External ####
+Finally there are a number of external libraries that we include in
+`./external/` because they are either difficult to obtain or they have been
+patched for easier use with libigl. Please see the respective readmes in those
+directories.
+
+
+##### Installing AntTweakBar #####
+To build the a static AntTweakBar library on Mac OS X issue:
+
+    cd external/AntTweakBar/src
+    make -f Makefile.osx.igl
+
+##### Installing Tetgen #####
+To build the tetgen library and executable on Mac OS X issue:
+
+    cd external/tetgen
+    make clean
+    rm -f obj/*.o
+    make -f Makefile.igl tetgen
+    rm -f obj/*.o
+    make -f Makefile.igl tetlib
+
+##### Installing medit #####
+To build the igl version of the medit executable on Mac OS X issue:
+
+    cd external/medit
+    make -C libmesh
+    make -f Makefile.igl medit
+
+##### Installing Embree 2.0 #####
+To build the embree library and executables on Mac OS X issue:
+
+    cd external/embree
+    mkdir build
+    cd build
+    cmake ..
+    # Or using a different compiler
+    #cmake .. -DCMAKE_C_COMPILER=/opt/local/bin/gcc -DCMAKE_CXX_COMPILER=/opt/local/bin/g++
+    make
+    # Could also install embree to your root, but libigl examples don't expect
+    # this
+    #sudo make install
+
+##### Installing tinyxml2 #####
+To build the a static tinyxml2 library on Mac OS X issue:
+
+    cd external/tinyxml2
+    cmake .
+    make
+
+
+##### Installing YImg #####
+To build the a static YImg library on Mac OS X issue:
+
+    cd external/yimg
+    make
+
+You may need to install libpng. Systems with X11 might find this already
+installed at `/usr/X11/lib`.
+
+
+### Windows (Experimental) ###
+To build a static library (.lib) on windows, open Visual Studio 2010.
+
+- New > Project ...
+- Visual C++ > Win32
+- Win32 Console Application
+- Name: libiglVisualStudio
+- Uncheck "Create directory for solution"
+- Then hit OK, and then Next
+- Check "Static Library"
+- Uncheck "Precompiled headers"
+- Add all include/igl/*.cpp to the sources directory
+- Add all include/igl/*.h to the headers directory
+- Open Project > libigl Properties...
+- Add the path to eigen3 to the include paths
+- Change the target name to libigl
+- Build and pray (this should create libigl.lib
+
+[Source](http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx)
+
+## Examples ##
+To get started, we advise that you take a look at a few examples:
+
+    ./examples/hello-world/
+
+    ./examples/meshio/
+
+    ./examples/basic-topology/
+
+    ./examples/ReAntTweakBar/
+
+## Extras ##
+Libigl compartmentalizes dependences via its organization into a _main_ libigl
+library and "extras."
+
+
+### bbw ###
+This library extra contains functions for computing Bounded Biharmonic Weights, can
+be used with and without the [mosek](#mosek) extra via the `IGL_NO_MOSEK`
+macro.
+
+### boost ###
+This library extra utilizes the graph functions in the boost library for find
+connected components and performing breadth-first traversals.
+
+### cgal ###
+This library extra utilizes CGAL's efficient and exact intersection and
+proximity queries.
+
+### embree ###
+This library extra utilizes embree's efficient ray tracing queries.
+
+### matlab ###
+This library extra provides support for reading and writing `.mat` workspace
+files, interfacing with Matlab at run time and compiling mex functions.
+
+### mosek ###
+This library extra utilizes mosek's efficient interior-point solver for
+quadratic programs.
+
+### png ###
+This library extra uses `libpng` and `YImage` to read and write `.png` files.
+
+### svd3x3 ###
+This library extra implements "as-rigid-as-possible" (ARAP) deformation
+techniques using the fast singular value decomposition routines
+written specifically for 3x3 matrices to use `SSE` intrinsics. This extra can
+still be compiled without sse support and support should be determined
+automatically at compile time via the `__SSE__` macro.
+
+### tetgen ###
+This library extra provides a simplified wrapper to the tetgen 3d tetrahedral meshing
+library.
+
+### viewer ###
+This library extra utilizes glfw and glew to open an opengl context and launch
+a simple mesh viewer.
+
+### xml ###
+This library extra utilizes tinyxml2 to read and write serialized classes
+containing Eigen matrices and other standard simple data-structures.
+
+## Development ##
+Further documentation for developers is listed in 
+[style_guidelines.html](../style_guidelines.html).
+
+## License ##
+See `LICENSE.txt`
+
+## Zipping ##
+Zip this directory without .git litter and binaries using:
+
+    git archive -prefix=libigl/ -o libigl.zip master
+
+## Explicit specialization of templated functions
+
+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
+
+    #ifdef IGL_STATIC_LIBRARY
+
+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.
+
+The process is somewhat mechanical using a linker with reasonable error
+output.
+
+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 `libigl` directory:
+
+    cd $LIBIGL
+    make
+
+Now if we try to compile a project and link against it we may get
+an error like:
+
+
+    Undefined symbols for architecture x86_64:
+    "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&)", 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
+
+This looks like a mess, but luckily we don't really need to read it
+all. Just copy the first part in quotes
+
+    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&)
+
+, then append it
+to the list of explicit template specializations at the end of
+`cat.cpp` after the word
+**template** and followed by a semi-colon.
+Like this:
+
+    #ifdef IGL_STATIC_LIBRARY
+    // Explicit template specialization
+    template 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&);
+    #endif
+
+Then you must recompile the IGL static library.
+
+    cd $LIBIGL
+    make
+
+And try to compile your project again, potentially repeating this
+process until no more symbols are undefined.
+
+`It may be useful to check that you code compiles with
+no errors first using the headers-only version to be sure that all errors are from missing template
+specializations.`
+
+If you're using make then the following command will
+reveal each missing symbol on its own line:
+
+    make 2>&1 | grep "referenced from" | sed -e "s/, referenced from.*//"
+
+Alternatively you can use the `autoexplicit.sh` 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:
+
+    cd /to/your/project
+    make 2>$LIBIGL/make.err
+    cd $LIBIGL
+    cat make.err | ./autoexplicit.sh
+    make clean
+    make
+
+
+### Benefits of static library
+
+* **Faster compile time**: 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.
+* **Debug or optimized**: 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.
+
+### Drawbacks of static library
+
+*  **Hard to use templates**: Special
+    care</a> (by the developers of the library) needs to be taken when
+    exposing templated functions.
+
+# Compressed .h/.cpp pair
+Calling the script:
+
+    scripts/compress.sh igl.h igl.cpp
+
+will create a single header `igl.h` and a single cpp file `igl.cpp`.
+
+Alternatively, you can also compress everything into a single header file:
+
+    scripts/compress.sh igl.h
+
+### Benefits of compressed .h/.cpp pair
+
+* **Easy incorporation**: This can be easily incorporated
+  into external projects.
+
+### Drawbacks of compressed .h/.cpp pair
+
+* **Hard to debug/edit**: The compressed files are
+  automatically generated. They're huge and should not be edited. Thus
+  debugging and editting are near impossible.
+
+* **Compounded dependencies**:
+  An immediate disadvantage of this
+  seems to be that even to use a single function (e.g.
+  `cotmatrix`), compiling and linking against
+  `igl.cpp` will require linking to all of `libigl`'s
+  dependencies (`OpenGL`, `GLUT`,
+  `AntTweakBar`, `BLAS`). However, because all
+  depencies other than Eigen should be encapsulated between
+  `#ifndef` guards (e.g. `#ifndef IGL_NO_OPENGL`, it
+  is possible to ignore certain functions that have such dependencies.</li>
+  <li><strong>Long compile:</strong> Compiling `igl.cpp` takes a long time and isn't easily parallelized (no `make -j12` equivalent).</li>
+  </ul>
+
+Here's a tiny test example using `igl.h` and `igl.cpp`. Save the following in `test.cpp`:
+
+    #include <igl.h>
+    #include <Eigen/Core>
+
+    int main(int argc, char * argv[])
+    {
+    Eigen::MatrixXd V;
+    Eigen::MatrixXi F;
+    return (argc>=2 &amp;&amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
+    }
+
+Then compile `igl.cpp` with:
+
+    g++ -o igl.o -c igl.cpp -I/opt/local/include/eigen3 -DIGL_NO_OPENGL -DIGL_NO_ANTTWEAKBAR
+
+Notice that we're using `-DIGL_NO_OPENGL -DIGL_NO_ANTTWEAKBAR` to disable any libigl dependencies on OpenGL and AntTweakBar.
+
+Now compile `test.cpp` with:
+
+    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
+
+Try running it with:
+
+    ./test path/to/mesh.obj
+
+
+The following bash one-liner will find all source files that contain the string `OpenGL` but don't contain and `IGL_NO_OPENGL` guard:
+
+    grep OpenGL `grep -L IGL_NO_OPENGL include/igl/*`
+
+### Optional ###
+- OpenGL (disable with `IGL_NO_OPENGL`)
+    * OpenGL >= 4 (enable with `IGL_OPENGL_4`)
+- AntTweakBar  (disable with `IGL_NO_ANTTWEAKBAR`) Last tested 1.16 (see
+  `libigl/external/AntTweakBar`)
+- GLEW  Windows and Linux
+- OpenMP
+- libpng  libiglpng extra only
+- Mosek  libiglmosek extra only
+- Matlab  libiglmatlab extra only
+- boost  libiglboost, libiglcgal extra only
+- SSE/AVX  libiglsvd3x3 extra only
+- CGAL  libiglcgal extra only
+    * boost
+    * gmp
+    * mpfr
+- CoMiSo libcomiso extra only
+
+### Optional (included in external/) ###
+- TetGen  libigltetgen extra only
+- Embree  libiglembree extra only
+- tinyxml2  libiglxml extra only
+- glfw libviewer extra only
+- LIM  liblim extra only

+ 472 - 0
build/index.html

@@ -0,0 +1,472 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="utf-8"/>
+	<title>libigl</title>
+	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
+	<link type="text/css" rel="stylesheet" href="../tutorial/style.css"/>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
+<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
+<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
+<script>hljs.initHighlightingOnLoad();</script>
+</head>
+<body>
+
+<h1 id="compilinglibiglasastaticlibrary">Compiling libigl as a static library</h1>
+
+<blockquote>
+<p>Warning: compiling libigl as a static library is considerably more difficult
+than using it as a header-only library (see <code>../README.md</code> instead). Do it
+only if you are experienced with C++ and you want to improve your compilation
+times.</p>
+</blockquote>
+
+<p>Libigl is developed most often on Mac OS X, though has current users in Linux
+and Windows.</p>
+
+<h3 id="linuxmacosxcygwin">Linux/Mac OS X/Cygwin</h3>
+
+<p>Libigl may also be compiled to a static library. This is advantageous when
+building a project with libigl, since when used as an header-only library can
+slow down compile times.</p>
+
+<p>To build the entire libigl library producing <code>lib/libigl.a</code>, issue:</p>
+
+<pre><code>cd build
+make lib
+</code></pre>
+
+<p>You may need to edit <code>Makefile.conf</code> accordingly. Best to give yourself an
+<code>IGL_USERNAME</code> and add a custom install suite for yourself. Then you can enable
+appropriate extras.</p>
+
+<h4 id="extras">Extras</h4>
+
+<p>Once you&#8217;ve set up an <code>IGL_USERNAME</code> and enabled extras within Makefile.conf.
+You can build the extra libraries (into <code>lib/ligiglpng.a</code>, <code>lib/libiglmatlab.a</code>,
+<code>lib/libigltetgen.a</code>, <code>lib/libiglmosek.a</code>, etc.) by issuing:</p>
+
+<pre><code>cd build
+make extras
+</code></pre>
+
+<h4 id="examples">Examples</h4>
+
+<p>You can make a slew of examples by issuing:</p>
+
+<pre><code>cd build
+make examples
+</code></pre>
+
+<h4 id="external">External</h4>
+
+<p>Finally there are a number of external libraries that we include in
+<code>./external/</code> because they are either difficult to obtain or they have been
+patched for easier use with libigl. Please see the respective readmes in those
+directories.</p>
+
+<h5 id="installinganttweakbar">Installing AntTweakBar</h5>
+
+<p>To build the a static AntTweakBar library on Mac OS X issue:</p>
+
+<pre><code>cd external/AntTweakBar/src
+make -f Makefile.osx.igl
+</code></pre>
+
+<h5 id="installingtetgen">Installing Tetgen</h5>
+
+<p>To build the tetgen library and executable on Mac OS X issue:</p>
+
+<pre><code>cd external/tetgen
+make clean
+rm -f obj/*.o
+make -f Makefile.igl tetgen
+rm -f obj/*.o
+make -f Makefile.igl tetlib
+</code></pre>
+
+<h5 id="installingmedit">Installing medit</h5>
+
+<p>To build the igl version of the medit executable on Mac OS X issue:</p>
+
+<pre><code>cd external/medit
+make -C libmesh
+make -f Makefile.igl medit
+</code></pre>
+
+<h5 id="installingembree2.0">Installing Embree 2.0</h5>
+
+<p>To build the embree library and executables on Mac OS X issue:</p>
+
+<pre><code>cd external/embree
+mkdir build
+cd build
+cmake ..
+# Or using a different compiler
+#cmake .. -DCMAKE_C_COMPILER=/opt/local/bin/gcc -DCMAKE_CXX_COMPILER=/opt/local/bin/g++
+make
+# Could also install embree to your root, but libigl examples don't expect
+# this
+#sudo make install
+</code></pre>
+
+<h5 id="installingtinyxml2">Installing tinyxml2</h5>
+
+<p>To build the a static tinyxml2 library on Mac OS X issue:</p>
+
+<pre><code>cd external/tinyxml2
+cmake .
+make
+</code></pre>
+
+<h5 id="installingyimg">Installing YImg</h5>
+
+<p>To build the a static YImg library on Mac OS X issue:</p>
+
+<pre><code>cd external/yimg
+make
+</code></pre>
+
+<p>You may need to install libpng. Systems with X11 might find this already
+installed at <code>/usr/X11/lib</code>.</p>
+
+<h3 id="windowsexperimental">Windows (Experimental)</h3>
+
+<p>To build a static library (.lib) on windows, open Visual Studio 2010.</p>
+
+<ul>
+<li>New &gt; Project &#8230;</li>
+<li>Visual C++ &gt; Win32</li>
+<li>Win32 Console Application</li>
+<li>Name: libiglVisualStudio</li>
+<li>Uncheck &#8220;Create directory for solution&#8221;</li>
+<li>Then hit OK, and then Next</li>
+<li>Check &#8220;Static Library&#8221;</li>
+<li>Uncheck &#8220;Precompiled headers&#8221;</li>
+<li>Add all include/igl/*.cpp to the sources directory</li>
+<li>Add all include/igl/*.h to the headers directory</li>
+<li>Open Project &gt; libigl Properties&#8230;</li>
+<li>Add the path to eigen3 to the include paths</li>
+<li>Change the target name to libigl</li>
+<li>Build and pray (this should create libigl.lib</li>
+</ul>
+
+<p><a href="http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx">Source</a></p>
+
+<h2 id="examples">Examples</h2>
+
+<p>To get started, we advise that you take a look at a few examples:</p>
+
+<pre><code>./examples/hello-world/
+
+./examples/meshio/
+
+./examples/basic-topology/
+
+./examples/ReAntTweakBar/
+</code></pre>
+
+<h2 id="extras">Extras</h2>
+
+<p>Libigl compartmentalizes dependences via its organization into a <em>main</em> libigl
+library and &#8220;extras.&#8221;</p>
+
+<h3 id="bbw">bbw</h3>
+
+<p>This library extra contains functions for computing Bounded Biharmonic Weights, can
+be used with and without the <a href="#mosek">mosek</a> extra via the <code>IGL_NO_MOSEK</code>
+macro.</p>
+
+<h3 id="boost">boost</h3>
+
+<p>This library extra utilizes the graph functions in the boost library for find
+connected components and performing breadth-first traversals.</p>
+
+<h3 id="cgal">cgal</h3>
+
+<p>This library extra utilizes CGAL&#8217;s efficient and exact intersection and
+proximity queries.</p>
+
+<h3 id="embree">embree</h3>
+
+<p>This library extra utilizes embree&#8217;s efficient ray tracing queries.</p>
+
+<h3 id="matlab">matlab</h3>
+
+<p>This library extra provides support for reading and writing <code>.mat</code> workspace
+files, interfacing with Matlab at run time and compiling mex functions.</p>
+
+<h3 id="mosek">mosek</h3>
+
+<p>This library extra utilizes mosek&#8217;s efficient interior-point solver for
+quadratic programs.</p>
+
+<h3 id="png">png</h3>
+
+<p>This library extra uses <code>libpng</code> and <code>YImage</code> to read and write <code>.png</code> files.</p>
+
+<h3 id="svd3x3">svd3x3</h3>
+
+<p>This library extra implements &#8220;as-rigid-as-possible&#8221; (ARAP) deformation
+techniques using the fast singular value decomposition routines
+written specifically for 3x3 matrices to use <code>SSE</code> intrinsics. This extra can
+still be compiled without sse support and support should be determined
+automatically at compile time via the <code>__SSE__</code> macro.</p>
+
+<h3 id="tetgen">tetgen</h3>
+
+<p>This library extra provides a simplified wrapper to the tetgen 3d tetrahedral meshing
+library.</p>
+
+<h3 id="viewer">viewer</h3>
+
+<p>This library extra utilizes glfw and glew to open an opengl context and launch
+a simple mesh viewer.</p>
+
+<h3 id="xml">xml</h3>
+
+<p>This library extra utilizes tinyxml2 to read and write serialized classes
+containing Eigen matrices and other standard simple data-structures.</p>
+
+<h2 id="development">Development</h2>
+
+<p>Further documentation for developers is listed in
+<a href="../style_guidelines.html">style_guidelines.html</a>.</p>
+
+<h2 id="license">License</h2>
+
+<p>See <code>LICENSE.txt</code></p>
+
+<h2 id="zipping">Zipping</h2>
+
+<p>Zip this directory without .git litter and binaries using:</p>
+
+<pre><code>git archive -prefix=libigl/ -o libigl.zip master
+</code></pre>
+
+<h2 id="explicitspecializationoftemplatedfunctions">Explicit specialization of templated functions</h2>
+
+<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</p>
+
+<pre><code>#ifdef IGL_STATIC_LIBRARY
+</code></pre>
+
+<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&#8217;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:
+&quot;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;)&quot;, referenced from:
+uniform_sample(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, int, double, Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt;&amp;)in Skinning.o
+&quot;Eigen::SparseMatrix&lt;double, 0, int&gt; igl::cat&lt;Eigen::SparseMatrix&lt;double, 0, int&gt; &gt;(int, Eigen::SparseMatrix&lt;double, 0, int&gt; const&amp;, Eigen::SparseMatrix&lt;double, 0, int&gt; const&amp;)&quot;, referenced from:
+covariance_scatter_matrix(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, ArapEnergy, Eigen::SparseMatrix&lt;double, 0, int&gt;&amp;)in arap_dof.o
+arap_rhs(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, ArapEnergy, Eigen::SparseMatrix&lt;double, 0, int&gt;&amp;)in arap_dof.o
+</code></pre>
+
+<p>This looks like a mess, but luckily we don&#8217;t really need to read it
+all. Just copy the first part in quotes</p>
+
+<pre><code>Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;)
+</code></pre>
+
+<p>, then append it
+to the list of explicit template specializations at the end of
+<code>cat.cpp</code> after the word
+<strong>template</strong> and followed by a semi-colon.
+Like this:</p>
+
+<pre><code>#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;);
+#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>
+
+<p><code>It may be useful to check that you code compiles with
+no errors first using the headers-only version to be sure that all errors are from missing template
+specializations.</code></p>
+
+<p>If you&#8217;re using make then the following command will
+reveal each missing symbol on its own line:</p>
+
+<pre><code>make 2&gt;&amp;1 | grep &quot;referenced from&quot; | sed -e &quot;s/, referenced from.*//&quot;
+</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&#8217;s error messages.
+Repeat this process until convergence:</p>
+
+<pre><code>cd /to/your/project
+make 2&gt;$LIBIGL/make.err
+cd $LIBIGL
+cat make.err | ./autoexplicit.sh
+make clean
+make
+</code></pre>
+
+<h3 id="benefitsofstaticlibrary">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 or optimized</strong>: The IGL static
+library may be compiled in debug mode or optimized release mode
+regardless of whether one&#8217;s project is being optimized or
+debugged.</li>
+</ul>
+
+<h3 id="drawbacksofstaticlibrary">Drawbacks of static library</h3>
+
+<ul>
+<li><strong>Hard to use templates</strong>: Special
+care</a> (by the developers of the library) needs to be taken when
+exposing templated functions.</li>
+</ul>
+
+<h1 id="compressed.h.cpppair">Compressed .h/.cpp pair</h1>
+
+<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>
+
+<p>Alternatively, you can also compress everything into a single header file:</p>
+
+<pre><code>scripts/compress.sh igl.h
+</code></pre>
+
+<h3 id="benefitsofcompressed.h.cpppair">Benefits of compressed .h/.cpp pair</h3>
+
+<ul>
+<li><strong>Easy incorporation</strong>: This can be easily incorporated
+ into external projects.</li>
+</ul>
+
+<h3 id="drawbacksofcompressed.h.cpppair">Drawbacks of compressed .h/.cpp pair</h3>
+
+<ul>
+<li><p><strong>Hard to debug/edit</strong>: The compressed files are
+ automatically generated. They&#8217;re huge and should not be edited. Thus
+ debugging and editting are near impossible.</p></li>
+<li><p><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>&#8217;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&#8217;t easily parallelized (no <code>make -j12</code> equivalent).</li>
+ </ul></p></li>
+</ul>
+
+<p>Here&#8217;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 &lt;igl.h&gt;
+#include &lt;Eigen/Core&gt;
+
+int main(int argc, char * argv[])
+{
+Eigen::MatrixXd V;
+Eigen::MatrixXi F;
+return (argc&gt;=2 &amp;amp;&amp;amp; igl::read_triangle_mesh(argv[1],V,F)?0:1);
+}
+</code></pre>
+
+<p>Then compile <code>igl.cpp</code> with:</p>
+
+<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&#8217;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:</p>
+
+<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&#8217;t contain and <code>IGL_NO_OPENGL</code> guard:</p>
+
+<pre><code>grep OpenGL `grep -L IGL_NO_OPENGL include/igl/*`
+</code></pre>
+
+<h3 id="optional">Optional</h3>
+
+<ul>
+<li>OpenGL (disable with <code>IGL_NO_OPENGL</code>)
+
+<ul>
+<li>OpenGL &gt;= 4 (enable with <code>IGL_OPENGL_4</code>)</li>
+</ul></li>
+<li>AntTweakBar (disable with <code>IGL_NO_ANTTWEAKBAR</code>) Last tested 1.16 (see
+ <code>libigl/external/AntTweakBar</code>)</li>
+<li>GLEW Windows and Linux</li>
+<li>OpenMP</li>
+<li>libpng libiglpng extra only</li>
+<li>Mosek libiglmosek extra only</li>
+<li>Matlab libiglmatlab extra only</li>
+<li>boost libiglboost, libiglcgal extra only</li>
+<li>SSE/AVX libiglsvd3x3 extra only</li>
+<li>CGAL libiglcgal extra only
+
+<ul>
+<li>boost</li>
+<li>gmp</li>
+<li>mpfr</li>
+</ul></li>
+<li>CoMiSo libcomiso extra only</li>
+</ul>
+
+<h3 id="optionalincludedinexternal">Optional (included in external/)</h3>
+
+<ul>
+<li>TetGen libigltetgen extra only</li>
+<li>Embree libiglembree extra only</li>
+<li>tinyxml2 libiglxml extra only</li>
+<li>glfw libviewer extra only</li>
+<li>LIM liblim extra only</li>
+</ul>
+
+</body>
+</html>

+ 1 - 0
examples/multi-viewport/example.cpp

@@ -49,6 +49,7 @@ int width,height;
 igl::Camera down_camera;
 bool trackball_on = false;
 int down_mouse_x,down_mouse_y,move_x,move_y;
+int down_vp;
 // Position of light
 float light_pos[4] = {0.1,0.1,-0.9,0};
 // Vertex positions, normals, colors and centroid

+ 3 - 1
examples/principal_curvature/curvature.cpp

@@ -1,4 +1,6 @@
-
+// This example is broken. It secretly uses classes from inside
+// principal_curvature.cpp not the api provided in the header
+// principal_curvature.h
 #undef IGL_STATIC_LIBRARY
 #include <igl/principal_curvature.h>
 #include <igl/read_triangle_mesh.h>

+ 41 - 11
examples/skeleton-posing/example.cpp

@@ -106,7 +106,7 @@ bool is_rotating = false;
 bool centroid_is_visible = true;
 int down_x,down_y;
 igl::Camera down_camera;
-std::string output_prefix;
+std::string output_weights_filename,output_pose_prefix;
 
 struct CameraAnimation
 {
@@ -594,13 +594,13 @@ void redo()
   }
 }
 
-bool save()
+bool save_pose()
 {
   using namespace std;
   using namespace igl;
   using namespace Eigen;
   string output_filename;
-  next_filename(output_prefix,4,".dmat",output_filename);
+  next_filename(output_pose_prefix,4,".dmat",output_filename);
   MatrixXd T;
   forward_kinematics(C,BE,P,s.mouse.rotations(),T);
   if(writeDMAT(output_filename,T))
@@ -614,6 +614,23 @@ bool save()
   }
 }
 
+bool save_weights()
+{
+  using namespace std;
+  using namespace igl;
+  using namespace Eigen;
+  if(writeDMAT(output_weights_filename,W))
+  {
+    cout<<GREENGIN("Current weights written to "+
+      output_weights_filename+".")<<endl;
+    return true;
+  }else
+  {
+    cout<<REDRUM("Writing to "+output_weights_filename+" failed.")<<endl;
+    return false;
+  }
+}
+
 void key(unsigned char key, int mouse_x, int mouse_y)
 {
   using namespace std;
@@ -660,7 +677,13 @@ void key(unsigned char key, int mouse_x, int mouse_y)
     case 'S':
     case 's':
     {
-      save();
+      save_pose();
+      break;
+    }
+    case 'W':
+    case 'w':
+    {
+      save_weights();
       break;
     }
     case 'z':
@@ -848,11 +871,11 @@ int main(int argc, char * argv[])
   string filename = "../shared/cheburashka.off";
   string skel_filename = "../shared/cheburashka.tgf";
   string weights_filename = "";
-  output_prefix = "";
+  output_pose_prefix = "";
   switch(argc)
   {
     case 5:
-      output_prefix = argv[4];
+      output_pose_prefix = argv[4];
       //fall through
     case 4:
       weights_filename = argv[3];
@@ -872,9 +895,10 @@ int main(int argc, char * argv[])
   cout<<"⌥ +[Click] and [drag]  Rotate secene."<<endl;
   cout<<"⌫                      Delete selected node(s) and incident bones."<<endl;
   cout<<"D,d                    Deselect all."<<endl;
-  cout<<"S,s                    Save current pose."<<endl;
   cout<<"R                      Reset selected rotation."<<endl;
   cout<<"r                      Reset all rotations."<<endl;
+  cout<<"S,s                    Save current pose."<<endl;
+  cout<<"W,w                    Save current weights."<<endl;
   cout<<"Z,z                    Snap to canonical view."<<endl;
   cout<<"⌘ Z                    Undo."<<endl;
   cout<<"⇧ ⌘ Z                  Redo."<<endl;
@@ -883,15 +907,21 @@ int main(int argc, char * argv[])
   string dir,_1,_2,name;
   read_triangle_mesh(filename,V,F,dir,_1,_2,name);
 
-  if(output_prefix.size() == 0)
+  if(output_weights_filename.size() == 0)
+  {
+    output_weights_filename = dir+"/"+name+"-weights.dmat";
+  }
+  if(output_pose_prefix.size() == 0)
   {
-    output_prefix = dir+"/"+name+"-pose-";
+    output_pose_prefix = dir+"/"+name+"-pose-";
   }
 
   {
     string output_filename;
-    next_filename(output_prefix,4,".dmat",output_filename);
-    cout<<BLUEGIN("Output set to start with "<<output_filename)<<endl;
+    next_filename(output_pose_prefix,4,".dmat",output_filename);
+    cout<<BLUEGIN("Output weights set to start with "<<
+      output_weights_filename)<<endl;
+    cout<<BLUEGIN("Output poses set to start with "<<output_filename)<<endl;
   }
 
   // Read in skeleton and precompute hierarchy

+ 2 - 2
include/igl/WindingNumberTree.h

@@ -170,7 +170,7 @@ inline void igl::WindingNumberTree<Point>::set_mesh(
   // Q: Would we gain even more by remove almost exactly duplicate vertices?
   Eigen::MatrixXi SF,SVI,SVJ;
   igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
-  triangle_fan(exterior_edges(F),cap);
+  triangle_fan(igl::exterior_edges(F),cap);
   V = SV;
 }
 
@@ -183,7 +183,7 @@ inline igl::WindingNumberTree<Point>::WindingNumberTree(
   V(parent.V),
   SV(),
   F(_F),
-  cap(triangle_fan(exterior_edges(_F)))
+  cap(triangle_fan(igl::exterior_edges(_F)))
 {
 }
 

+ 1 - 1
include/igl/all_pairs_distances.cpp

@@ -23,7 +23,7 @@ IGL_INLINE void igl::all_pairs_distances(
   {
     for(int j=0;j<U.rows();j++)
     {
-      D(i,j) = (V.row(i)-U.row(j)).array().pow(2).sum();
+      D(i,j) = (V.row(i)-U.row(j)).squaredNorm();
       if(!squared)
       {
         D(i,j) = sqrt(D(i,j));

+ 1 - 1
include/igl/boundary_conditions.cpp

@@ -53,7 +53,7 @@ IGL_INLINE bool igl::boundary_conditions(
       // double sqrd = (V.row(i)-pos).array().pow(2).sum();
       // Must first store in temporary
       VectorXd vi = V.row(i);
-      double sqrd = (vi-pos).array().pow(2).sum();
+      double sqrd = (vi-pos).squaredNorm();
       if(sqrd <= FLOAT_EPS)
       {
         //cout<<"sum((["<<

+ 12 - 4
include/igl/cgal/SelfIntersectMesh.h

@@ -405,7 +405,9 @@ inline igl::SelfIntersectMesh<
   // Use map for *all* faces
   map<typename CDT_plus_2::Vertex_handle,Index> v2i;
   // Loop over offending triangles
-  for(Index o = 0;o<(Index)offending.size();o++)
+  const size_t noff = offending.size();
+# pragma omp parallel for if (noff>1000)
+  for(Index o = 0;o<(Index)noff;o++)
   {
     // index in F
     const Index f = offending[o];
@@ -439,6 +441,7 @@ inline igl::SelfIntersectMesh<
           assert(T[f].vertex(i) == P[o].to_3d(vit->point()));
 #endif
           // For first three, use original index in F
+#   pragma omp critical
           v2i[vit] = F(f,i);
         }else
         {
@@ -480,6 +483,7 @@ inline igl::SelfIntersectMesh<
                 if(vit_point_3 == P[no].to_3d(uit->point()))
                 {
                   assert(v2i.count(uit) == 1);
+#   pragma omp critical
                   v2i[vit] = v2i[uit];
                   found = true;
                 }
@@ -488,9 +492,12 @@ inline igl::SelfIntersectMesh<
           }
           if(!found)
           {
-            v2i[vit] = V.rows()+NV_count;
-            NV.push_back(vit_point_3);
-            NV_count++;
+#   pragma omp critical
+            {
+              v2i[vit] = V.rows()+NV_count;
+              NV.push_back(vit_point_3);
+              NV_count++;
+            }
           }
         }
         i++;
@@ -500,6 +507,7 @@ inline igl::SelfIntersectMesh<
       Index i = 0;
       // Resize to fit new number of triangles
       NF[o].resize(cdt[o].number_of_faces(),3);
+#   pragma omp atomic
       NF_count+=NF[o].rows();
       // Append new faces to NF
       for(

+ 0 - 2
include/igl/cgal/intersect_other.cpp

@@ -32,8 +32,6 @@ IGL_INLINE void igl::intersect_other(
   typedef CGAL::Triangle_3<Kernel> Triangle_3; 
   typedef CGAL::Plane_3<Kernel>    Plane_3;
   typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3; 
-  typedef CGAL::Polyhedron_3<Kernel> Polyhedron_3; 
-  typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron_3; 
   // 2D Primitives
   typedef CGAL::Point_2<Kernel>    Point_2;
   typedef CGAL::Segment_2<Kernel>  Segment_2; 

+ 6 - 0
include/igl/cgal/point_mesh_squared_distance.cpp

@@ -45,6 +45,7 @@ IGL_INLINE void igl::point_mesh_squared_distance_precompute(
   using namespace std;
 
   typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+  typedef CGAL::Point_3<Kernel> Point_3; 
   typedef typename std::vector<Triangle_3>::iterator Iterator;
   typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
   typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
@@ -59,6 +60,11 @@ IGL_INLINE void igl::point_mesh_squared_distance_precompute(
   tree.clear();
   tree.insert(T.begin(),T.end());
   tree.accelerate_distance_queries();
+  // accelerate_distance_queries doesn't seem actually to do _all_ of the
+  // precomputation. the tree (despite being const) will still do more
+  // precomputation and reorganizing on the first call of `closest_point` or
+  // `closest_point_and_primitive`. Therefor, call it once here.
+  tree.closest_point_and_primitive(Point_3(0,0,0));
 }
 
 template <typename Kernel>

+ 2 - 1
include/igl/cgal/signed_distance.cpp

@@ -9,6 +9,7 @@
 #include "../per_vertex_normals.h"
 #include "../per_edge_normals.h"
 #include "../per_face_normals.h"
+#include "../get_seconds.h"
 #include "point_mesh_squared_distance.h"
 
 
@@ -62,7 +63,7 @@ IGL_INLINE void igl::signed_distance(
       per_face_normals(V,F,FN);
       per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE,FN,VN);
       per_edge_normals(
-        V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,EN,E,EMAP);
+        V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,FN,EN,E,EMAP);
       N.resize(P.rows(),3);
       break;
   }

+ 5 - 0
include/igl/doublearea.cpp

@@ -124,6 +124,11 @@ IGL_INLINE void igl::doublearea(
   assert(s.rows() == m);
   // resize output
   dblA.resize(l.rows(),1);
+  // Minimum number of iterms per openmp thread
+  #ifndef IGL_OMP_MIN_VALUE
+  #  define IGL_OMP_MIN_VALUE 1000
+  #endif
+  #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
   for(int i = 0;i<m;i++)
   {
     //// Heron's formula for area

+ 18 - 12
include/igl/edge_lengths.cpp

@@ -15,6 +15,11 @@ IGL_INLINE void igl::edge_lengths(
   Eigen::PlainObjectBase<DerivedL>& L)
 {
   using namespace std;
+  const int m = F.rows();
+  // Minimum number of iterms per openmp thread
+#ifndef IGL_OMP_MIN_VALUE
+#  define IGL_OMP_MIN_VALUE 1000
+#endif
   switch(F.cols())
   {
     case 2:
@@ -28,29 +33,30 @@ IGL_INLINE void igl::edge_lengths(
     }
     case 3:
     {
-      L.resize(F.rows(),3);
+      L.resize(m,3);
       // loop over faces
-      for(int i = 0;i<F.rows();i++)
+      #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
+      for(int i = 0;i<m;i++)
       {
-        L(i,0) = sqrt((V.row(F(i,1))-V.row(F(i,2))).array().pow(2).sum());
-        L(i,1) = sqrt((V.row(F(i,2))-V.row(F(i,0))).array().pow(2).sum());
-        L(i,2) = sqrt((V.row(F(i,0))-V.row(F(i,1))).array().pow(2).sum());
+        L(i,0) = (V.row(F(i,1))-V.row(F(i,2))).norm();
+        L(i,1) = (V.row(F(i,2))-V.row(F(i,0))).norm();
+        L(i,2) = (V.row(F(i,0))-V.row(F(i,1))).norm();
       }
       break;
     }
     case 4:
     {
-      const int m = F.rows();
       L.resize(m,6);
       // loop over faces
+      #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
       for(int i = 0;i<m;i++)
       {
-        L(i,0) = sqrt((V.row(F(i,3))-V.row(F(i,0))).array().pow(2).sum());
-        L(i,1) = sqrt((V.row(F(i,3))-V.row(F(i,1))).array().pow(2).sum());
-        L(i,2) = sqrt((V.row(F(i,3))-V.row(F(i,2))).array().pow(2).sum());
-        L(i,3) = sqrt((V.row(F(i,1))-V.row(F(i,2))).array().pow(2).sum());
-        L(i,4) = sqrt((V.row(F(i,2))-V.row(F(i,0))).array().pow(2).sum());
-        L(i,5) = sqrt((V.row(F(i,0))-V.row(F(i,1))).array().pow(2).sum());
+        L(i,0) = (V.row(F(i,3))-V.row(F(i,0))).norm();
+        L(i,1) = (V.row(F(i,3))-V.row(F(i,1))).norm();
+        L(i,2) = (V.row(F(i,3))-V.row(F(i,2))).norm();
+        L(i,3) = (V.row(F(i,1))-V.row(F(i,2))).norm();
+        L(i,4) = (V.row(F(i,2))-V.row(F(i,0))).norm();
+        L(i,5) = (V.row(F(i,0))-V.row(F(i,1))).norm();
       }
       break;
     }

+ 43 - 55
include/igl/exterior_edges.cpp

@@ -1,9 +1,12 @@
 #include "exterior_edges.h"
 #include "all_edges.h"
+#include "sort.h"
+#include "unique.h"
 
 #include <cassert>
 #include <unordered_map>
 #include <utility>
+#include <iostream>
 
 //template <typename T> inline int sgn(T val) {
 //      return (T(0) < val) - (val < T(0));
@@ -38,68 +41,53 @@ IGL_INLINE void igl::exterior_edges(
   using namespace Eigen;
   using namespace std;
   assert(F.cols() == 3);
-  MatrixXi all_E;
+  const size_t m = F.rows();
+  MatrixXi all_E,sall_E,sort_order;
+  // Sort each edge by index
   all_edges(F,all_E);
-  long int n = F.maxCoeff()+1;
-  int m = F.minCoeff();
-  const auto & compress = [n,m](const int i, const int j)->long int
+  sort(all_E,2,true,sall_E,sort_order);
+  // Find unique edges
+  MatrixXi uE;
+  VectorXi IA,EMAP;
+  unique_rows(sall_E,uE,IA,EMAP);
+  VectorXi counts = VectorXi::Zero(uE.rows());
+  for(size_t a = 0;a<3*m;a++)
   {
-    return n*(i-m)+(j-m);
-  };
-  const auto & decompress = [n,m](const long int l,int & i, int & j)
-  {
-    i = (l / n) + m;
-    j = (l % n) + m;
-  };
-
-  // Count occurances looking only at pairs (i,j) where i<j, so we count and
-  // edge i-->j as +1 and j-->i as -1
-  unordered_map<long int,int> C;
-  // Loop over edges
-  for(int e = 0;e<all_E.rows();e++)
-  {
-    int i = all_E(e,0);
-    int j = all_E(e,1);
-    if(i<j)
-    {
-      // Forward direction --> +1
-      C[compress(i,j)]++;
-    }else
-    {
-      // Backward direction --> -1
-      C[compress(j,i)]--;
-    }
+    counts(EMAP(a)) += (sort_order(a)==0?1:-1);
   }
-  // Q: Why mod off factors of 2? +1/-1 already takes care of interior edges?
-  //// Mod off any factors of 2
-  //for_each(C.begin(),C.end(),mod2);
-  //int zeros = (int) count(C.begin(),C.end(),Compare(0));
-  //E.resize(C.size() - zeros,2);
-  E.resize(all_E.rows(),all_E.cols());
-  int e = 0;
-  // Find all edges with -1 or 1 occurances, flipping direction for -1
-  for(const auto & cit : C)
+
+  E.resize(all_E.rows(),2);
   {
-    int i,j;
-    if(cit.second > 0)
-    {
-      decompress(cit.first,i,j);
-    } else if(cit.second < 0)
-    {
-      decompress(cit.first,j,i);
-    } else if(cit.second == 0)
-    {
-      continue;
-    }
-    for(int k = 0;k<abs(cit.second);k++)
+    int e = 0;
+    const size_t nue = uE.rows();
+    // Append each unique edge with a non-zero amount of signed occurances
+    for(size_t ue = 0; ue<nue; ue++)
     {
-      E(e,0) = i;
-      E(e,1) = j;
-      e++;
+      const int count = counts(ue);
+      size_t i,j;
+      if(count == 0)
+      {
+        continue;
+      }else if(count < 0)
+      {
+        i = uE(ue,1);
+        j = uE(ue,0);
+      }else if(count > 0)
+      {
+        i = uE(ue,0);
+        j = uE(ue,1);
+      }
+      // Append edge for every repeated entry
+      const int abs_count = abs(count);
+      for(size_t k = 0;k<abs_count;k++)
+      {
+        E(e,0) = i;
+        E(e,1) = j;
+        e++;
+      }
     }
+    E.conservativeResize(e,2);
   }
-  E.conservativeResize(e,2);
-  assert(e == E.rows());
 }
 
 IGL_INLINE Eigen::MatrixXi igl::exterior_edges( const Eigen::MatrixXi & F)

+ 1 - 1
include/igl/exterior_edges.h

@@ -17,7 +17,7 @@ namespace igl
     const Eigen::MatrixXi & F,
     Eigen::MatrixXi & E);
   // Inline version
-  Eigen::MatrixXi exterior_edges( const Eigen::MatrixXi & F);
+  IGL_INLINE Eigen::MatrixXi exterior_edges( const Eigen::MatrixXi & F);
 }
 #ifndef IGL_STATIC_LIBRARY
 #  include "exterior_edges.cpp"

+ 16 - 3
include/igl/facet_components.cpp

@@ -18,10 +18,12 @@ IGL_INLINE void igl::facet_components(
 
 template <
   typename TTIndex, 
-  typename DerivedC>
+  typename DerivedC,
+  typename Derivedcounts>
 IGL_INLINE void igl::facet_components(
   const std::vector<std::vector<std::vector<TTIndex > > > & TT,
-  Eigen::PlainObjectBase<DerivedC> & C)
+  Eigen::PlainObjectBase<DerivedC> & C,
+  Eigen::PlainObjectBase<Derivedcounts> & counts)
 {
   using namespace std;
   using namespace igl;
@@ -30,12 +32,14 @@ IGL_INLINE void igl::facet_components(
   C.resize(m,1);
   vector<bool> seen(m,false);
   Index id = 0;
+  vector<Index> vcounts;
   for(Index g = 0;g<m;g++)
   {
     if(seen[g])
     {
       continue;
     }
+    vcounts.push_back(0);
     queue<Index> Q;
     Q.push(g);
     while(!Q.empty())
@@ -47,6 +51,7 @@ IGL_INLINE void igl::facet_components(
         continue;
       }
       seen[f] = true;
+      vcounts[id]++;
       C(f,0) = id;
       // Face f's neighbor lists opposite opposite each corner
       for(const auto & c : TT[f])
@@ -63,9 +68,17 @@ IGL_INLINE void igl::facet_components(
     }
     id++;
   }
+  assert(id == vcounts.size());
+  const size_t ncc = vcounts.size();
+  assert(C.maxCoeff()+1 == ncc);
+  counts.resize(ncc,1);
+  for(size_t i = 0;i<ncc;i++)
+  {
+    counts(i) = vcounts[i];
+  }
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
-template void igl::facet_components<long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+template void igl::facet_components<long, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 #endif

+ 4 - 2
include/igl/facet_components.h

@@ -22,10 +22,12 @@ namespace igl
   //   C  #F list of connected component ids
   template <
     typename TTIndex, 
-    typename DerivedC>
+    typename DerivedC,
+    typename Derivedcounts>
   IGL_INLINE void facet_components(
     const std::vector<std::vector<std::vector<TTIndex > > > & TT,
-    Eigen::PlainObjectBase<DerivedC> & C);
+    Eigen::PlainObjectBase<DerivedC> & C,
+    Eigen::PlainObjectBase<Derivedcounts> & counts);
 }
 #ifndef IGL_STATIC_LIBRARY
 #  include "facet_components.cpp"

+ 25 - 7
include/igl/internal_angles.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "internal_angles.h"
 #include "edge_lengths.h"
+#include "get_seconds.h"
 
 template <typename DerivedV, typename DerivedF, typename DerivedK>
 IGL_INLINE void igl::internal_angles(
@@ -15,6 +16,7 @@ IGL_INLINE void igl::internal_angles(
   Eigen::PlainObjectBase<DerivedK> & K)
 {
   using namespace Eigen;
+  using namespace std;
   // Edge lengths
   Matrix<
     typename DerivedV::Scalar,
@@ -23,7 +25,7 @@ IGL_INLINE void igl::internal_angles(
   edge_lengths(V,F,L);
 
   assert(F.cols() == 3 && "F should contain triangles");
-  return internal_angles(L,K);
+  internal_angles(L,K);
 }
 
 template <typename DerivedL, typename DerivedK>
@@ -32,13 +34,29 @@ IGL_INLINE void igl::internal_angles(
   Eigen::PlainObjectBase<DerivedK> & K)
 {
   assert(L.cols() == 3 && "Edge-lengths should come from triangles");
-  K.resize(L.rows(),L.cols());
-  for(int d = 0;d<3;d++)
+  const size_t m = L.rows();
+  K.resize(m,3);
+  //for(int d = 0;d<3;d++)
+  //{
+  //  const auto & s1 = L.col(d).array();
+  //  const auto & s2 = L.col((d+1)%3).array();
+  //  const auto & s3 = L.col((d+2)%3).array();
+  //  K.col(d) = ((s3.square() + s2.square() - s1.square())/(2.*s3*s2)).acos();
+  //}
+  // Minimum number of iterms per openmp thread
+  #ifndef IGL_OMP_MIN_VALUE
+  #  define IGL_OMP_MIN_VALUE 1000
+  #endif
+  #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
+  for(int f = 0;f<m;f++)
   {
-    const auto & s1 = L.col(d).array();
-    const auto & s2 = L.col((d+1)%3).array();
-    const auto & s3 = L.col((d+2)%3).array();
-    K.col(d) = ((s3.square() + s2.square() - s1.square())/(2.*s3*s2)).acos();
+    for(int d = 0;d<3;d++)
+    {
+      const auto & s1 = L(f,d);
+      const auto & s2 = L(f,(d+1)%3);
+      const auto & s3 = L(f,(d+2)%3);
+      K(f,d) = acos((s3*s3 + s2*s2 - s1*s1)/(2.*s3*s2));
+    }
   }
 }
 

+ 3 - 3
include/igl/massmatrix.cpp

@@ -47,9 +47,9 @@ IGL_INLINE void igl::massmatrix(
     // loop over faces
     for(int i = 0;i<m;i++)
     {
-      l(i,0) = sqrt((V.row(F(i,1))-V.row(F(i,2))).array().pow(2).sum());
-      l(i,1) = sqrt((V.row(F(i,2))-V.row(F(i,0))).array().pow(2).sum());
-      l(i,2) = sqrt((V.row(F(i,0))-V.row(F(i,1))).array().pow(2).sum());
+      l(i,0) = (V.row(F(i,1))-V.row(F(i,2))).norm();
+      l(i,1) = (V.row(F(i,2))-V.row(F(i,0))).norm();
+      l(i,2) = (V.row(F(i,0))-V.row(F(i,1))).norm();
     }
     // semiperimeters
     Matrix<Scalar,Dynamic,1> s = l.rowwise().sum()*0.5;

+ 200 - 130
include/igl/outer_hull.cpp

@@ -1,9 +1,10 @@
 #include "outer_hull.h"
 #include "outer_facet.h"
 #include "facet_components.h"
-
+#include "winding_number.h"
 #include "triangle_triangle_adjacency.h"
 #include "unique_edge_map.h"
+#include "barycenter.h"
 #include "per_face_normals.h"
 #include "all_edges.h"
 #include "colon.h"
@@ -33,10 +34,10 @@ IGL_INLINE void igl::outer_hull(
   using namespace igl;
   typedef typename DerivedF::Index Index;
   Matrix<Index,DerivedF::RowsAtCompileTime,1> C;
+  typedef Matrix<typename DerivedV::Scalar,Dynamic,DerivedV::ColsAtCompileTime> MatrixXV;
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
-  typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
   const Index m = F.rows();
 
   typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
@@ -48,8 +49,10 @@ IGL_INLINE void igl::outer_hull(
 
   vector<vector<vector<Index > > > TT,_1;
   triangle_triangle_adjacency(E,EMAP,uE2E,false,TT,_1);
-  facet_components(TT,C);
-  const Index ncc = C.maxCoeff()+1;
+  VectorXI counts;
+  facet_components(TT,C,counts);
+  assert(C.maxCoeff()+1 == counts.rows());
+  const size_t ncc = counts.rows();
   G.resize(0,F.cols());
   J.resize(0,1);
   flip.setConstant(m,1,false);
@@ -64,162 +67,229 @@ IGL_INLINE void igl::outer_hull(
   vector<bool> EH(3*m,false);
   vector<MatrixXG> vG(ncc);
   vector<MatrixXJ> vJ(ncc);
+  vector<MatrixXJ> vIM(ncc);
+  for(size_t id = 0;id<ncc;id++)
+  {
+    vIM[id].resize(counts[id],1);
+  }
+  // current index into each IM
+  vector<size_t> g(ncc,0);
+  // place order of each face in its respective component
+  for(Index f = 0;f<m;f++)
+  {
+    vIM[C(f)](g[C(f)]++) = f;
+  }
 
-  // Total size of G (and J)
-  size_t nG = 0;
-  // This is O( (n+m) * nnc) !
-  for(Index id = 0;id<ncc;id++)
+  // assumes that "resolve" has handled any coplanar cases correctly and nearly
+  // coplanar cases can be sorted based on barycenter.
+  MatrixXV BC;
+  barycenter(V,F,BC);
+
+  for(Index id = 0;id<(Index)ncc;id++)
   {
-    // Determine number of facets in component id
-    Index num_id = 0;
-    for(Index f = 0;f<m;f++)
+    auto & IM = vIM[id];
+    // starting face that's guaranteed to be on the outer hull and in this
+    // component
+    int f;
+    bool f_flip;
+    outer_facet(V,F,N,IM,f,f_flip);
+    int FHcount = 0;
+    // Q contains list of face edges to continue traversing upong
+    queue<int> Q;
+    Q.push(f+0*m);
+    Q.push(f+1*m);
+    Q.push(f+2*m);
+    flip[f] = f_flip;
+    while(!Q.empty())
     {
-      if(C(f) == id)
+      // face-edge
+      const int e = Q.front();
+      Q.pop();
+      // face
+      const int f = e%m;
+      // corner
+      const int c = e/m;
+      // Should never see edge again...
+      if(EH[e] == true)
       {
-        num_id++;
+        continue;
       }
-    }
-    //MatrixXF Fc(num_id,F.cols());
-    MatrixXJ IM(num_id,1);
-    if(C.maxCoeff() == 0)
-    {
-      assert(num_id == F.rows());
-      //Fc = F;
-      IM = MatrixXJ::LinSpaced(F.rows(),0,F.rows()-1);
-    }else
-    {
-      int g = 0;
-      for(Index f = 0;f<m;f++)
+      EH[e] = true;
+      // first time seeing face
+      if(!FH[f])
       {
-        if(C(f) == id)
-        {
-          //Fc.row(g) = F.row(f);
-          IM(g) = f;
-          g++;
-        }
+        FH[f] = true;
+        FHcount++;
       }
-    }
-    {
-      // starting face that's guaranteed to be on the outer hull and in this
-      // component
-      int f;
-      bool f_flip;
-      outer_facet(V,F,N,IM,f,f_flip);
-      // Q contains list of face edges to continue traversing upong
-      queue<int> Q;
-      Q.push(f+0*m);
-      Q.push(f+1*m);
-      Q.push(f+2*m);
-      flip[f] = f_flip;
-      int FHcount = 0;
-      while(!Q.empty())
+      // find overlapping face-edges
+      const auto & neighbors = uE2E[EMAP(e)];
+      const auto & fN = (flip[f]?-1.:1.)*N.row(f);
+      // source of edge according to f
+      const int fs = flip[f]?F(f,(c+2)%3):F(f,(c+1)%3);
+      // destination of edge according to f
+      const int fd = flip[f]?F(f,(c+1)%3):F(f,(c+2)%3);
+      const auto & eV = (V.row(fd)-V.row(fs)).normalized();
+      // Loop over and find max dihedral angle
+      typename DerivedV::Scalar max_di = -1;
+      int max_ne = -1;
+      typename Eigen::Matrix< typename DerivedV::Scalar, 1, 3> max_nN;
+      for(const auto & ne : neighbors)
       {
-        // face-edge
-        const int e = Q.front();
-        Q.pop();
-        // face
-        const int f = e%m;
-        // corner
-        const int c = e/m;
-        // Should never see edge again...
-        if(EH[e] == true)
+        const int nf = ne%m;
+        if(nf == f)
         {
           continue;
         }
-        EH[e] = true;
-        // first time seeing face
-        if(!FH[f])
+        const int nc = ne/m;
+        // are faces consistently oriented
+        //const int ns = F(nf,(nc+1)%3);
+        const int nd = F(nf,(nc+2)%3);
+        const bool cons = (flip[f]?fd:fs) == nd;
+        const auto & nN = (cons? (flip[f]?-1:1.) : (flip[f]?1.:-1.) )*N.row(nf);
+        const auto & ndi = M_PI - atan2( fN.cross(nN).dot(eV), fN.dot(nN));
+        if(ndi>=max_di)
+        {
+          max_ne = ne;
+          max_di = ndi;
+          max_nN = nN;
+        }
+      }
+      if(max_ne>=0)
+      {
+        const int nf = max_ne%m;
+        const int nc = max_ne/m;
+        const int nd = F(nf,(nc+2)%3);
+        const bool cons = (flip[f]?fd:fs) == nd;
+        flip[nf] = (cons ? flip[f] : !flip[f]);
+        const int ne1 = nf+((nc+1)%3)*m;
+        const int ne2 = nf+((nc+2)%3)*m;
+        if(!EH[ne1])
         {
-          FH[f] = true;
-          FHcount++;
+          Q.push(ne1);
         }
-        // find overlapping face-edges
-        const auto & neighbors = uE2E[EMAP(e)];
-        const auto & fN = (flip[f]?-1.:1.)*N.row(f);
-        // source of edge according to f
-        const int fs = flip[f]?F(f,(c+2)%3):F(f,(c+1)%3);
-        // destination of edge according to f
-        const int fd = flip[f]?F(f,(c+1)%3):F(f,(c+2)%3);
-        const auto & eV = (V.row(fd)-V.row(fs)).normalized();
-        // Loop over and find max dihedral angle
-        typename DerivedV::Scalar max_di = -1;
-        int max_ne = -1;
-        typename Eigen::Matrix< typename DerivedV::Scalar, 1, 3> max_nN;
-        for(const auto & ne : neighbors)
+        if(!EH[ne2])
         {
-          const int nf = ne%m;
-          if(nf == f)
-          {
-            continue;
-          }
-          const int nc = ne/m;
-          // are faces consistently oriented
-          //const int ns = F(nf,(nc+1)%3);
-          const int nd = F(nf,(nc+2)%3);
-          const bool cons = (flip[f]?fd:fs) == nd;
-          const auto & nN = (cons? (flip[f]?-1:1.) : (flip[f]?1.:-1.) )*N.row(nf);
-          const auto & ndi = M_PI - atan2( fN.cross(nN).dot(eV), fN.dot(nN));
-          if(ndi>=max_di)
-          {
-            max_ne = ne;
-            max_di = ndi;
-            max_nN = nN;
-          }
+          Q.push(ne2);
         }
-        if(max_ne>=0)
+      }
+    }
+    
+    {
+      vG[id].resize(FHcount,3);
+      vJ[id].resize(FHcount,1);
+      //nG += FHcount;
+      size_t h = 0;
+      assert(counts(id) == IM.rows());
+      for(int i = 0;i<counts(id);i++)
+      {
+        const size_t f = IM(i);
+        //if(f_flip)
+        //{
+        //  flip[f] = !flip[f];
+        //}
+        if(FH[f])
         {
-          const int nf = max_ne%m;
-          const int nc = max_ne/m;
-          const int nd = F(nf,(nc+2)%3);
-          const bool cons = (flip[f]?fd:fs) == nd;
-          flip[nf] = (cons ? flip[f] : !flip[f]);
-          const int ne1 = nf+((nc+1)%3)*m;
-          const int ne2 = nf+((nc+2)%3)*m;
-          if(!EH[ne1])
-          {
-            Q.push(ne1);
-          }
-          if(!EH[ne2])
-          {
-            Q.push(ne2);
-          }
+          vG[id].row(h) = (flip[f]?F.row(f).reverse().eval():F.row(f));
+          vJ[id](h,0) = f;
+          h++;
         }
       }
-      
+      assert(h == FHcount);
+    }
+  }
+
+  // Is A inside B? Assuming A and B are consistently oriented but closed and
+  // non-intersecting.
+  const auto & is_component_inside_other = [](
+    const Eigen::PlainObjectBase<DerivedV> & V,
+    const MatrixXV & BC,
+    const MatrixXG & A,
+    const MatrixXJ & AJ,
+    const MatrixXG & B)->bool
+  {
+    const auto & bounding_box = [](
+      const Eigen::PlainObjectBase<DerivedV> & V,
+      const MatrixXG & F)->
+      MatrixXV
+    {
+      MatrixXV BB(2,3);
+      BB<<
+         1e26,1e26,1e26,
+        -1e26,-1e26,-1e26;
+      const size_t m = F.rows();
+      for(size_t f = 0;f<m;f++)
       {
-        vG[id].resize(FHcount,3);
-        vJ[id].resize(FHcount,1);
-        nG += FHcount;
-        size_t h = 0;
-        for(int i = 0;i<num_id;i++)
+        for(size_t c = 0;c<3;c++)
         {
-          const size_t f = IM(i);
-          //if(f_flip)
-          //{
-          //  flip[f] = !flip[f];
-          //}
-          if(FH[f])
-          {
-            vG[id].row(h) = (flip[f]?F.row(f).reverse().eval():F.row(f));
-            vJ[id](h,0) = f;
-            h++;
-          }
+          const auto & vfc = V.row(F(f,c));
+          BB.row(0) = BB.row(0).array().min(vfc.array()).eval();
+          BB.row(1) = BB.row(1).array().max(vfc.array()).eval();
         }
-        assert(h == FHcount);
       }
+      return BB;
+    };
+    // A lot of the time we're dealing with unrelated, distant components: cull
+    // them.
+    MatrixXV ABB = bounding_box(V,A);
+    MatrixXV BBB = bounding_box(V,B);
+    if( (BBB.row(0)-ABB.row(1)).maxCoeff()>0  ||
+        (ABB.row(0)-BBB.row(1)).maxCoeff()>0 )
+    {
+      // bounding boxes do not overlap
+      return false;
+    }
+    ////////////////////////////////////////////////////////////////////////
+    // POTENTIAL ROBUSTNESS WEAK AREA
+    ////////////////////////////////////////////////////////////////////////
+    //
+    // q could be so close (<~1e-16) to B that the winding number is not a robust way to
+    // determine inside/outsideness. We could try to find a _better_ q which is
+    // farther away, but couldn't they all be bad?
+    MatrixXV q = BC.row(AJ(1));
+    // In a perfect world, it's enough to test a single point.
+    double w;
+    winding_number_3(
+      V.data(),V.rows(),
+      B.data(),B.rows(),
+      q.data(),1,&w);
+    return fabs(w)>0.5;
+  };
+
+  // Reject components which are completely inside other components
+  vector<bool> keep(ncc,true);
+  size_t nG = 0;
+  // This is O( ncc * ncc * m)
+  for(size_t id = 0;id<ncc;id++)
+  {
+    for(size_t oid = 0;oid<ncc;oid++)
+    {
+      if(id == oid)
+      {
+        continue;
+      }
+      keep[id] = keep[id] && 
+        !is_component_inside_other(V,BC,vG[id],vJ[id],vG[oid]);
+    }
+    if(keep[id])
+    {
+      nG += vJ[id].rows();
     }
   }
+
   // collect G and J across components
   G.resize(nG,3);
   J.resize(nG,1);
   {
     size_t off = 0;
-    for(Index id = 0;id<ncc;id++)
+    for(Index id = 0;id<(Index)ncc;id++)
     {
-      assert(vG[id].rows() == vJ[id].rows());
-      G.block(off,0,vG[id].rows(),vG[id].cols()) = vG[id];
-      J.block(off,0,vJ[id].rows(),vJ[id].cols()) = vJ[id];
-      off += vG[id].rows();
+      if(keep[id])
+      {
+        assert(vG[id].rows() == vJ[id].rows());
+        G.block(off,0,vG[id].rows(),vG[id].cols()) = vG[id];
+        J.block(off,0,vJ[id].rows(),vJ[id].cols()) = vJ[id];
+        off += vG[id].rows();
+      }
     }
   }
 }

+ 11 - 5
include/igl/per_edge_normals.cpp

@@ -1,6 +1,7 @@
 #include "all_edges.h"
 #include "doublearea.h"
 #include "per_edge_normals.h"
+#include "get_seconds.h"
 #include "per_face_normals.h"
 #include "unique_simplices.h"
 #include <vector>
@@ -36,11 +37,11 @@ IGL_INLINE void igl::per_edge_normals(
   // now sort(allE,2) == E(EMAP,:), that is, if EMAP(i) = j, then E.row(j) is
   // the undirected edge corresponding to the directed edge allE.row(i).
 
-  Eigen::VectorXd W(F.rows());
+  Eigen::VectorXd W;
   switch(weighting)
   {
     case PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM:
-      W.setConstant(1.);
+      // Do nothing
       break;
     default:
       assert(false && "Unknown weighting type");
@@ -52,15 +53,20 @@ IGL_INLINE void igl::per_edge_normals(
     }
   }
 
-  N.setConstant(E.rows(),3,0);
+  N.setZero(E.rows(),3);
   for(int f = 0;f<m;f++)
   {
     for(int c = 0;c<3;c++)
     {
-      N.row(EMAP(f+c*m)) += W(f) * FN.row(f);
+      if(weighting == PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM)
+      {
+        N.row(EMAP(f+c*m)) += FN.row(f);
+      }else
+      {
+        N.row(EMAP(f+c*m)) += W(f) * FN.row(f);
+      }
     }
   }
-  N.rowwise().normalize();
 }
 
 template <

+ 2 - 0
include/igl/per_vertex_normals.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "per_vertex_normals.h"
 
+#include "get_seconds.h"
 #include "per_face_normals.h"
 #include "doublearea.h"
 #include "internal_angles.h"
@@ -40,6 +41,7 @@ IGL_INLINE void igl::per_vertex_normals(
   const Eigen::PlainObjectBase<DerivedFN>& FN,
   Eigen::PlainObjectBase<DerivedN> & N)
 {
+  using namespace std;
   // Resize for output
   N.setZero(V.rows(),3);
 

+ 0 - 3
include/igl/principal_curvature.h

@@ -11,9 +11,6 @@
 
 #include <Eigen/Geometry>
 #include <Eigen/Dense>
-#include <vector>
-#include <stdio.h>
-#include <map>
 
 #include <igl/igl_inline.h>
 #include <igl/cotmatrix.h>

+ 2 - 2
include/igl/project_to_line.cpp

@@ -33,7 +33,7 @@ IGL_INLINE void igl::project_to_line(
   int np  = P.rows();
   // vector from source to destination
   MatL DmS = D-S;
-  double v_sqrlen = (double)(DmS.array().pow(2).sum());
+  double v_sqrlen = (double)(DmS.squaredNorm());
   assert(v_sqrlen != 0);
   // resize output
   t.resize(np,1);
@@ -48,7 +48,7 @@ IGL_INLINE void igl::project_to_line(
     t(i) = -(DmS.array()*SmPi.array()).sum() / v_sqrlen;
     // P projected onto line
     MatL projP = (1-t(i))*S + t(i)*D;
-    sqrD(i) = (Pi-projP).array().pow(2).sum();
+    sqrD(i) = (Pi-projP).squaredNorm();
   }
 }
 

+ 4 - 0
include/igl/sortrows.cpp

@@ -6,6 +6,7 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can 
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "sortrows.h"
+#include "get_seconds.h"
 
 #include "SortableRow.h"
 #include "sort.h"
@@ -55,6 +56,9 @@ IGL_INLINE void igl::sortrows(
   Eigen::PlainObjectBase<DerivedX>& Y,
   Eigen::PlainObjectBase<DerivedIX>& IX)
 {
+  // This is already 2x faster than matlab's builtin `sortrows`. I have tried
+  // implementing a "multiple-pass" sort on each column, but see no performance
+  // improvement.
   using namespace std;
   using namespace Eigen;
   using namespace igl;

+ 1 - 0
include/igl/unique.cpp

@@ -12,6 +12,7 @@
 #include "sortrows.h"
 #include "list_to_matrix.h"
 #include "matrix_to_list.h"
+#include "get_seconds.h"
 
 #include <algorithm>
 #include <iostream>

+ 2 - 2
include/igl/unique_edge_map.h

@@ -1,5 +1,5 @@
-#ifndef IGL_EXTERIOR_EDGES_H
-#define IGL_EXTERIOR_EDGES_H
+#ifndef IGL_UNIQUE_EDGE_MAP_H
+#define IGL_UNIQUE_EDGE_MAP_H
 #include "igl_inline.h"
 #include <Eigen/Dense>
 #include <vector>

+ 9 - 1
include/igl/unique_simplices.cpp

@@ -8,6 +8,7 @@
 #include "unique_simplices.h"
 #include "sort.h"
 #include "unique.h"
+#include "get_seconds.h"
 
 template <
   typename DerivedF,
@@ -22,6 +23,7 @@ IGL_INLINE void igl::unique_simplices(
 {
   using namespace Eigen;
   using namespace igl;
+  using namespace std;
   // Sort each face
   MatrixXi sortF, unusedI;
   igl::sort(F,2,true,sortF,unusedI);
@@ -29,8 +31,14 @@ IGL_INLINE void igl::unique_simplices(
   MatrixXi C;
   igl::unique_rows(sortF,C,IA,IC);
   FF.resize(IA.size(),F.cols());
+  const size_t mff = FF.rows();
+  // Minimum number of iterms per openmp thread
+  #ifndef IGL_OMP_MIN_VALUE
+  #  define IGL_OMP_MIN_VALUE 1000
+  #endif
+  #pragma omp parallel for if (mff>IGL_OMP_MIN_VALUE)
   // Copy into output
-  for(int i = 0;i<IA.rows();i++)
+  for(size_t i = 0;i<mff;i++)
   {
     FF.row(i) = F.row(IA(i));
   }

+ 9 - 9
include/igl/winding_number.h

@@ -39,15 +39,15 @@ namespace igl
     const double * O,
     const int no,
     double * S);
-  // Only one evaluation origin
-  template <typename DerivedF>
-  IGL_INLINE void winding_number_3(
-    const double * V,
-    const int n,
-    const DerivedF * F,
-    const int m,
-    const double * O,
-    double * S);
+  //// Only one evaluation origin
+  //template <typename DerivedF>
+  //IGL_INLINE void winding_number_3(
+  //  const double * V,
+  //  const int n,
+  //  const DerivedF * F,
+  //  const int m,
+  //  const double * O,
+  //  double * S);
   // 2d
   template <typename DerivedF>
   IGL_INLINE void winding_number_2(

+ 64 - 505
index.html

@@ -12,35 +12,43 @@
 </head>
 <body>
 
-<h1 id="libigl-asimplecgeometryprocessinglibrary">libigl - A simple c++ geometry processing library</h1>
+<h1 id="libigl-asimplecgeometryprocessinglibrary">libigl - A simple C++ geometry processing library</h1>
 
 <figure>
 <img src="tutorial/images/libigl-logo.jpg" alt="" />
 <figcaption></figcaption></figure>
 
-<p><a href="http://libigl.github.io/libigl/">http://libigl.github.io/libigl/</a>
-<a href="https://github.com/libigl/libigl/">https://github.com/libigl/libigl/</a></p>
+<p><a href="https://github.com/libigl/libigl/">https://github.com/libigl/libigl/</a></p>
 
-<p>Copyright 2014 - Alec Jacobson, Daniele Panozzo, Olga Diamanti, Kenshi
-Takayama, Leo Sacht, Wenzel Jacob, etc.</p>
+<p>libigl is a simple C++ geometry processing library. We have a wide
+functionality including construction of sparse discrete differential geometry
+operators and finite-elements matrices such as the contangent Laplacian and
+diagonalized mass matrix, simple facet and edge-based topology data structures,
+mesh-viewing utilities for OpenGL and GLSL, and many core functions for matrix
+manipulation which make <a href="http://eigen.tuxfamily.org">Eigen</a> feel a lot more
+like MATLAB.</p>
 
-<p>Libigl is first and foremost a <em>header</em> library. Each header file should
-contain a single function. This function may have multiple overloads and
-prototypes. All functions should use the <code>igl::</code> namespace and should adhere to
-the conventions and styles listed in the <a href="style_guidelines.html">style
-guidelines</a>.</p>
+<p>It is first and foremost a header library. Each header file contains a single
+function. Most are tailored to operate on a generic triangle mesh stored in an
+n-by&#8211;3 matrix of vertex positions V and an m-by&#8211;3 matrix of triangle indices F.
+The library may also be <a href="build/">compiled</a> into a statically linked
+library, for faster compile times with your projects.</p>
 
-<blockquote>
-<p><strong>New:</strong> As of 1 July 2014, we have released libigl as beta version 1.0.
-There are a number of changes we collected for this release to minimize
-confusion and changes to how you use libigl. See <a href="#version1.0changes">Version 1.0
-Changes</a>.</p>
-</blockquote>
+<p>We use the <a href="http://eigen.tuxfamily.org">Eigen</a> library heavily in our code. Our
+group prototypes a lot in MATLAB, and we have a useful <a href="matlab-to-eigen.html">conversion
+table</a> from
+MATLAB to libigl/Eigen.</p>
+
+<h1 id="tutorial">Tutorial</h1>
+
+<p>As of version 1.0, libigl includes an introductory
+<a href="tutorial/tutorial.html">tutorial</a> that covers
+its basic functionalities.</p>
 
 <h2 id="installation">Installation</h2>
 
 <p>Libigl is a <em>header</em> library. You do <strong>not</strong> need to build anything to install.
-Simple add <code>igl/</code> to your include path and include relevant headers. Here&#8217;s a
+Simply add <code>igl/</code> to your include path and include relevant headers. Here is a
 small &#8220;Hello, World&#8221; program:</p>
 
 <pre><code class="cpp">#include &lt;igl/cotmatrix.h&gt;
@@ -64,8 +72,8 @@ int main()
 }
 </code></pre>
 
-<p>If you save this in <code>hello.cpp</code>, then on <code>gcc</code> with Eigen installed via
-macports for example you could compile this with:</p>
+<p>If you save this in <code>hello.cpp</code>, then you could compile this with (assuming
+Eigen is installed in /opt/local/include/eigen3):</p>
 
 <pre><code class="bash">gcc -I/opt/local/include/eigen3 -I./igl/ hello.cpp -o hello
 </code></pre>
@@ -79,504 +87,34 @@ macports for example you could compile this with:</p>
  0.5 -0.5
 </code></pre>
 
-<h2 id="tutorial">Tutorial</h2>
-
-<p>As of version 1.0, libigl includes an introductory
-<a href="http://libigl.github.io/libigl/tutorial/tutorial.html">tutorial</a> that covers
-its basic functionalities.</p>
-
 <h2 id="dependencies">Dependencies</h2>
 
-<ul>
-<li>Eigen3 Last tested with Eigen Version 3.2</li>
-</ul>
-
-<h3 id="optional">Optional</h3>
-
-<ul>
-<li>OpenGL (disable with <code>IGL_NO_OPENGL</code>)
-
-<ul>
-<li>OpenGL &gt;= 4 (enable with <code>IGL_OPENGL_4</code>)</li>
-</ul></li>
-<li>AntTweakBar (disable with <code>IGL_NO_ANTTWEAKBAR</code>) Last tested 1.16 (see
- <code>libigl/external/AntTweakBar</code>)</li>
-<li>GLEW Windows and Linux</li>
-<li>OpenMP</li>
-<li>libpng libiglpng extra only</li>
-<li>Mosek libiglmosek extra only</li>
-<li>Matlab libiglmatlab extra only</li>
-<li>boost libiglboost, libiglcgal extra only</li>
-<li>SSE/AVX libiglsvd3x3 extra only</li>
-<li>CGAL libiglcgal extra only
-
-<ul>
-<li>boost</li>
-<li>gmp</li>
-<li>mpfr</li>
-</ul></li>
-<li>CoMiSo libcomiso extra only</li>
-</ul>
-
-<h3 id="optionalincludedinexternal">Optional (included in external/)</h3>
-
-<ul>
-<li>TetGen libigltetgen extra only</li>
-<li>Embree libiglembree extra only</li>
-<li>tinyxml2 libiglxml extra only</li>
-<li>glfw libviewer extra only</li>
-<li>LIM liblim extra only</li>
-</ul>
-
-<h2 id="headeronly">Header only</h2>
-
-<p>Libigl is designed to work &#8220;out-of-the-box&#8221; as a headers only library. To
-include libigl in your project. You need only include the libigl/include/
-directory in your include path. To
-compile a hello-word example.cpp:</p>
-
-<pre><code>#include &lt;Eigen/Dense&gt;
-#include &lt;igl/readOBJ.h&gt;
-#include &lt;iostream&gt;
-int main(int argc, char * argv[])
-{
-  if(argc&gt;1)
-  {
-    Eigen::MatrixXd V;
-    Eigen::MatrixXi F;
-    igl::readOBJ(argv[1],V,F);
-    std::cout&lt;&lt;&quot;Hello, mesh with &quot;&lt;&lt;V.rows()&lt;&lt;&quot; vertices!&quot;&lt;&lt;std::endl;
-  }else{
-    std::cout&lt;&lt;&quot;Hello, world!&quot;&lt;&lt;std::endl;
-  }
-  return 0;
-}
-</code></pre>
-
-<p>using gcc (replacing appropriate paths):</p>
-
-<pre><code>g++ -I/usr/local/igl/libigl/include \
-  -I/opt/local/include/eigen3 example.cpp -o example
-</code></pre>
-
-<p>Then run this example with:</p>
-
-<pre><code>./example examples/shared/TinyTorus.obj
-</code></pre>
-
-<h2 id="compilationasastaticlibrary">Compilation as a static library</h2>
-
-<p>Libigl is developed most often on Mac OS X, though has current users in Linux
-and Windows.</p>
-
-<h3 id="linuxmacosxcygwin">Linux/Mac OS X/Cygwin</h3>
-
-<p>Libigl may also be compiled to a static library. This is advantageous when
-building a project with libigl, since when used as an header-only library can
-slow down compile times.</p>
-
-<p>To build the entire libigl library producing lib/libigl.a, issue:</p>
-
-<pre><code>cd build
-make lib
-</code></pre>
-
-<p>You may need to edit Makefile.conf accordingly. Best to give yourself an
-<code>IGL_USERNAME</code> and add a custom install suite for yourself. Then you can enable
-appropriate extras.</p>
-
-<h4 id="extras">Extras</h4>
-
-<p>Once you&#8217;ve set up an <code>IGL_USERNAME</code> and enabled extras within Makefile.conf.
-You can build the extra libraries (into lib/ligiglpng.a, lib/libiglmatlab.a,
-lib/libigltetgen.a, lib/libiglmosek.a, etc.) by issuing:</p>
-
-<pre><code>cd build
-make extras
-</code></pre>
-
-<h4 id="examples">Examples</h4>
-
-<p>You can make a slew of examples by issuing:</p>
-
-<pre><code>cd build
-make examples
-</code></pre>
-
-<h4 id="external">External</h4>
-
-<p>Finally there are a number of external libraries that we include in
-./external/ because they are either difficult to obtain or they have been
-patched for easier use with libigl. Please see the respective readmes in
-those directories.</p>
-
-<h5 id="installinganttweakbar">Installing AntTweakBar</h5>
-
-<p>To build the a static AntTweakBar library on Mac OS X issue:</p>
-
-<pre><code>cd external/AntTweakBar/src
-make -f Makefile.osx.igl
-</code></pre>
-
-<h5 id="installingtetgen">Installing Tetgen</h5>
-
-<p>To build the tetgen library and executable on Mac OS X issue:</p>
-
-<pre><code>cd external/tetgen
-make clean
-rm -f obj/*.o
-make -f Makefile.igl tetgen
-rm -f obj/*.o
-make -f Makefile.igl tetlib
-</code></pre>
-
-<h5 id="installingmedit">Installing medit</h5>
-
-<p>To build the igl version of the medit executable on Mac OS X issue:</p>
-
-<pre><code>cd external/medit
-make -C libmesh
-make -f Makefile.igl medit
-</code></pre>
-
-<h5 id="installingembree2.0">Installing Embree 2.0</h5>
-
-<p>To build the embree library and executables on Mac OS X issue:</p>
-
-<pre><code>cd external/embree
-mkdir build
-cd build
-cmake ..
-# Or using a different compiler
-#cmake .. -DCMAKE_C_COMPILER=/opt/local/bin/gcc -DCMAKE_CXX_COMPILER=/opt/local/bin/g++
-make
-# Could also install embree to your root, but libigl examples don't expect
-# this
-#sudo make install
-</code></pre>
-
-<h5 id="installingtinyxml2">Installing tinyxml2</h5>
-
-<p>To build the a static tinyxml2 library on Mac OS X issue:</p>
+<p>Dependencies are on a per-include basis and the majority of the functions in
+libigl depends only on the <a href="http://eigen.tuxfamily.org">Eigen</a> library.</p>
 
-<pre><code>cd external/tinyxml2
-cmake .
-make
-</code></pre>
-
-<h5 id="installingyimg">Installing YImg</h5>
-
-<p>To build the a static YImg library on Mac OS X issue:</p>
-
-<pre><code>cd external/yimg
-make
-</code></pre>
-
-<p>You may need to install libpng. Systems with X11 might find this already
-installed at <code>/usr/X11/lib</code>.</p>
-
-<h3 id="windowsexperimental">Windows (Experimental)</h3>
-
-<p>To build a static library (.lib) on windows, open Visual Studio 2010.</p>
-
-<ul>
-<li>New &gt; Project &#8230;</li>
-<li>Visual C++ &gt; Win32</li>
-<li>Win32 Console Application</li>
-<li>Name: libiglVisualStudio</li>
-<li>Uncheck &#8220;Create directory for solution&#8221;</li>
-<li>Then hit OK, and then Next</li>
-<li>Check &#8220;Static Library&#8221;</li>
-<li>Uncheck &#8220;Precompiled headers&#8221;</li>
-<li>Add all include/igl/*.cpp to the sources directory</li>
-<li>Add all include/igl/*.h to the headers directory</li>
-<li>Open Project &gt; libigl Properties&#8230;</li>
-<li>Add the path to eigen3 to the include paths</li>
-<li>Change the target name to libigl</li>
-<li>Build and pray (this should create libigl.lib</li>
-</ul>
-
-<p><a href="http://msdn.microsoft.com/en-us/library/ms235627(v=vs.80).aspx">Source</a></p>
-
-<h2 id="examples">Examples</h2>
-
-<p>To get started, we advise that you take a look at a few examples:</p>
-
-<pre><code>./examples/hello-world/
-
-./examples/meshio/
-
-./examples/basic-topology/
-
-./examples/ReAntTweakBar/
-</code></pre>
-
-<h2 id="extras">Extras</h2>
-
-<p>Libigl compartmentalizes dependences via its organization into a <em>main</em> libigl
-library and &#8220;extras.&#8221;</p>
-
-<h3 id="bbw">bbw</h3>
-
-<p>This library extra contains functions for computing Bounded Biharmonic Weights, can
-be used with and without the <a href="#mosek">mosek</a> extra via the <code>IGL_NO_MOSEK</code>
-macro.</p>
-
-<h3 id="boost">boost</h3>
-
-<p>This library extra utilizes the graph functions in the boost library for find
-connected components and performing breadth-first traversals.</p>
-
-<h3 id="cgal">cgal</h3>
-
-<p>This library extra utilizes CGAL&#8217;s efficient and exact intersection and
-proximity queries.</p>
-
-<h3 id="embree">embree</h3>
-
-<p>This library extra utilizes embree&#8217;s efficient ray tracing queries.</p>
-
-<h3 id="matlab">matlab</h3>
+<p>For more information see our <a href="tutorial/tutorial.html">tutorial</a>.</p>
 
-<p>This library extra provides support for reading and writing <code>.mat</code> workspace
-files, interfacing with Matlab at run time and compiling mex functions.</p>
+<h1 id="download">Download</h1>
 
-<h3 id="mosek">mosek</h3>
+<p>You can keep up to date by cloning a read-only copy of our GitHub
+<a href="https://github.com/libigl">repository</a>.</p>
 
-<p>This library extra utilizes mosek&#8217;s efficient interior-point solver for
-quadratic programs.</p>
+<h2 id="howtocontribute">How to contribute</h2>
 
-<h3 id="png">png</h3>
-
-<p>This library extra uses <code>libpng</code> and <code>YImage</code> to read and write <code>.png</code> files.</p>
-
-<h3 id="svd3x3">svd3x3</h3>
-
-<p>This library extra implements &#8220;as-rigid-as-possible&#8221; (ARAP) deformation
-techniques using the fast singular value decomposition routines
-written specifically for 3x3 matrices to use <code>SSE</code> intrinsics. This extra can
-still be compiled without sse support and support should be determined
-automatically at compile time via the <code>__SSE__</code> macro.</p>
-
-<h3 id="tetgen">tetgen</h3>
-
-<p>This library extra provides a simplified wrapper to the tetgen 3d tetrahedral meshing
-library.</p>
-
-<h3 id="viewer">viewer</h3>
-
-<p>This library extra utilizes glfw and glew to open an opengl context and launch
-a simple mesh viewer.</p>
-
-<h3 id="xml">xml</h3>
-
-<p>This library extra utilizes tinyxml2 to read and write serialized classes
-containing Eigen matrices and other standard simple data-structures.</p>
-
-<h2 id="development">Development</h2>
-
-<p>Further documentation for developers is listed in tutorial.html,
-style_guidelines.html</p>
+<p>If you are interested in joining development, please fork the repository and
+submit a <a href="https://help.github.com/articles/using-pull-requests/">pull request</a>
+with your changes.</p>
 
 <h2 id="license">License</h2>
 
-<p>See <code>LICENSE.txt</code></p>
+<p>libigl is primarily <a href="http://www.mozilla.org/MPL/2.0/">MPL2</a> licensed
+(<a href="http://www.mozilla.org/MPL/2.0/FAQ.html">FAQ</a>). Some files contain
+third-party code under other licenses. We&#8217;re currently in the processes of
+identifying these and marking appropriately.</p>
 
-<h2 id="zipping">Zipping</h2>
-
-<p>Zip this directory without .git litter and binaries using:</p>
-
-<pre><code>git archive -prefix=libigl/ -o libigl.zip master
-</code></pre>
+<h2 id="attribution">Attribution</h2>
 
-<h2 id="version1.0changes">Version 1.0 Changes</h2>
-
-<p>Our beta release marks our confidence that this library can be used outside of
-casual experimenting. To maintain order, we have made a few changes which
-current users should read and adapt their code accordingly.</p>
-
-<h3 id="renamedfunctions">Renamed functions</h3>
-
-<p>The following table lists functions which have changed name as of version
-1.0.0:</p>
-
-<table>
-<colgroup>
-<col style="text-align:left;"/>
-<col style="text-align:left;"/>
-</colgroup>
-
-<thead>
-<tr>
-	<th style="text-align:left;">Old</th>
-	<th style="text-align:left;">New</th>
-</tr>
-</thead>
-
-<tbody>
-<tr>
-	<td style="text-align:left;"><code>igl::add_barycenter</code></td>
-	<td style="text-align:left;"><code>igl::false_barycentric_subdivision</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::areamatrix</code></td>
-	<td style="text-align:left;"><code>igl::vector_area_matrix</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::barycentric2global</code></td>
-	<td style="text-align:left;"><code>igl::barycentric_to_global</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::boundary_faces</code></td>
-	<td style="text-align:left;"><code>igl::boundary_facets</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::boundary_vertices_sorted</code></td>
-	<td style="text-align:left;"><code>igl::boundary_loop</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::cotangent</code></td>
-	<td style="text-align:left;"><code>igl::cotmatrix_entries</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::edgetopology</code></td>
-	<td style="text-align:left;"><code>igl::edge_topology</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::gradMat</code></td>
-	<td style="text-align:left;"><code>igl::grad</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::is_manifold</code></td>
-	<td style="text-align:left;"><code>igl::is_edge_manifold</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::mexStream</code></td>
-	<td style="text-align:left;"><code>igl::MexStream</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::moveFV</code></td>
-	<td style="text-align:left;"><code>igl::average_onto_vertices</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::moveVF</code></td>
-	<td style="text-align:left;"><code>igl::average_onto_faces</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::plot_vector</code></td>
-	<td style="text-align:left;"><code>igl::print_vector</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::pos</code></td>
-	<td style="text-align:left;"><code>igl::HalfEdgeIterator</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::plane_project</code></td>
-	<td style="text-align:left;"><code>igl::project_isometrically_to_plane</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::project_points_mesh</code></td>
-	<td style="text-align:left;"><code>igl::line_mesh_intersection</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::read</code></td>
-	<td style="text-align:left;"><code>igl::read_triangle_mesh</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::removeDuplicates.cpp</code></td>
-	<td style="text-align:left;"><code>igl::remove_duplicates</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::removeUnreferenced</code></td>
-	<td style="text-align:left;"><code>igl::remove_unreferenced</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::tt</code></td>
-	<td style="text-align:left;"><code>igl::triangle_triangle_adjacency</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::vf</code></td>
-	<td style="text-align:left;"><code>igl::vertex_triangle_adjacency</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::write</code></td>
-	<td style="text-align:left;"><code>igl::write_triangle_mesh</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::manifold_patches</code></td>
-	<td style="text-align:left;"><code>igl::orientable_patches</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::selfintersect</code></td>
-	<td style="text-align:left;"><code>igl::remesh_self_intersections</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::project_mesh</code></td>
-	<td style="text-align:left;"><code>igl::line_mesh_intersection</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::triangulate</code></td>
-	<td style="text-align:left;"><code>igl::polygon_mesh_to_triangle_mesh</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::is_manifold</code></td>
-	<td style="text-align:left;"><code>igl::is_edge_manifold</code></td>
-</tr>
-<tr>
-	<td style="text-align:left;"><code>igl::triangle_wrapper</code></td>
-	<td style="text-align:left;"><code>igl::triangulate</code></td>
-</tr>
-</tbody>
-</table>
-
-<h3 id="miscellaneous">Miscellaneous</h3>
-
-<ul>
-<li>To match interfaces provided by (all) other quadratic optimization
- libraries, <code>igl::min_quad_with_fixed</code> and <code>igl::active_set</code> now expect as
- input twice the quadratic coefficients matrix, i.e. the Hessian. For
- example, <code>igl::min_quad_with_fixed(H,B,...)</code> minimizes <span class="math">\(\frac{1}{2}x^T H
-   x+x^T B\)</span>.</li>
-<li>We have inverted the <code>IGL_HEADER_ONLY</code> macro to <code>IGL_STATIC_LIBRARY</code>. To
- compile using libigl as a header-only library, simply include headers and
- libigl in the header search path. To link to libigl, you must define the
- <code>IGL_STATIC_LIBRARY</code> macro at compile time and link to the <code>libigl*.a</code>
- libraries.</li>
-<li>Building libigl as a static library is now more organized. There is a
- <code>build/</code> directory with Makefiles for the main library (<code>Makefile</code>) and each
- dependency (e.g. <code>Makefile_mosek</code> for <code>libiglmosek.a</code>)</li>
-<li><code>igl::polar_svd</code> now always returns a rotation in <code>R</code>, never a reflection.
- This mirrors the behavior of <code>igl::polar_svd3x3</code>. Consequently the <code>T</code>
- part may have negative skews.</li>
-<li>We have organized the static</li>
-<li>The previous <code>igl::grad</code> function, which computed the per-triangle gradient
- of a per-vertex scalar function has been replaced. Now <code>igl::grad</code> computes
- the linear operator (previous computed using <code>igl::gradMat</code>). The gradient
- values can still be recovered by multiplying the operator against the scalar
- field as a vector and reshaping to have gradients per row.</li>
-<li><code>MASSMATRIX_*</code> has become <code>MASSMATRIX_TYPE_*</code></li>
-<li>The function <code>igl::project_normals</code>, which cast a line for each vertex of
- mesh <em>A</em> in the normal direction and found the closest intersection along
- these lines with mesh <em>B</em>, has been removed.</li>
-</ul>
-
-<h2 id="contact">Contact</h2>
-
-<p>Libigl is a group endeavor led by Alec Jacobson and Daniele Panozzo. Please
-contact <a href="&#109;&#97;&#105;&#108;&#x74;&#111;&#x3a;&#x61;&#x6c;&#101;&#x63;&#x6a;&#x61;&#x63;&#111;&#98;&#115;&#111;&#110;&#64;&#103;&#109;&#x61;&#105;&#108;&#x2e;&#x63;&#x6f;&#x6d;">&#97;&#x6c;&#x65;&#99;&#106;&#97;&#x63;&#111;&#x62;&#x73;&#x6f;&#110;&#x40;&#103;&#x6d;&#x61;&#105;&#x6c;&#x2e;&#x63;&#x6f;&#x6d;</a> if you have
-questions or comments. We are happy to get feedback! Enjoy!</p>
-
-<p>If you&#8217;re using libigl in your projects, quickly <a href="&#x6d;&#97;&#x69;&#x6c;&#116;&#x6f;&#x3a;&#97;&#x6c;&#101;&#x63;&#106;&#97;&#x63;&#x6f;&#98;&#115;&#x6f;&#x6e;&#64;&#103;&#x6d;&#97;&#105;&#108;&#x2e;&#x63;&#111;&#x6d;">&#x64;&#x72;&#111;&#112; &#117;&#x73; &#x61;
-&#x6e;&#x6f;&#116;&#101;</a>. Tell us who you are and what you&#8217;re using
-it for. This helps us apply for funding and justify spending time maintaining
-this.</p>
-
-<p>If you find bugs or have problems please use our <a href="https://github.com/libigl/libigl/issues">github issue tracking
-page</a>.</p>
-
-<h2 id="academiccitation">Academic citation</h2>
-
-<p>If you use libigl in your research projects, please cite the papers we
+<p>If you use libigl in your academic projects, please cite the papers we
 implement as appropriate. To cite the library in general, you could use this
 BibTeX entry:</p>
 
@@ -588,5 +126,26 @@ BibTeX entry:</p>
 }
 </code></pre>
 
+<h1 id="contact">Contact</h1>
+
+<p>Libigl is a group endeavor led by <a href="http://www.cs.columbia.edu/~jacobson/">Alec
+Jacobson</a> and <a href="http://www.inf.ethz.ch/personal/dpanozzo/">Daniele
+Panozzo</a>. Please <a href="&#109;&#97;&#105;&#108;&#x74;&#111;&#x3a;&#x61;&#x6c;&#101;&#x63;&#x6a;&#x61;&#x63;&#111;&#98;&#115;&#111;&#110;&#64;&#103;&#109;&#x61;&#105;&#108;&#x2e;&#x63;&#x6f;&#x6d;&#44;&#x64;&#x61;&#110;&#105;&#101;&#x6c;&#101;&#x2e;&#x70;&#x61;&#110;&#x6f;&#122;&#x7a;&#x6f;&#64;&#x67;&#x6d;&#x61;&#x69;&#x6c;&#x2e;&#99;&#x6f;&#x6d;">&#99;&#x6f;&#x6e;&#116;&#x61;&#99;&#x74;
+&#117;&#115;</a> if you have
+questions or comments. We are happy to get feedback!</p>
+
+<p>If you&#8217;re using libigl in your projects, quickly <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#x6f;&#58;&#97;&#x6c;&#101;&#99;&#106;&#x61;&#x63;&#111;&#x62;&#x73;&#x6f;&#110;&#64;&#103;&#x6d;&#x61;&#x69;&#x6c;&#46;&#99;&#x6f;&#x6d;&#x2c;&#100;&#x61;&#110;&#105;&#x65;&#108;&#x65;&#x2e;&#112;&#97;&#x6e;&#111;&#x7a;&#x7a;&#x6f;&#x40;&#103;&#109;&#x61;&#105;&#x6c;&#x2e;&#x63;&#111;&#109;">&#x64;&#x72;&#111;&#112; &#x75;&#x73; &#97;
+&#110;&#111;&#116;&#101;</a>. Tell us who you
+are and what you&#8217;re using it for. This helps us apply for funding and justify
+spending time maintaining this.</p>
+
+<p>If you find bugs or have problems please use our <a href="https://github.com/libigl/libigl/issues">github issue tracking
+page</a>.</p>
+
+<h3 id="copyright">Copyright</h3>
+
+<p>2014 Alec Jacobson, Daniele Panozzo, Olga Diamanti, Kenshi
+Takayama, Leo Sacht, Wenzel Jacob, Nico Pietroni, Amir Vaxman</p>
+
 </body>
 </html>

+ 30 - 0
scripts/update_gh-pages.sh

@@ -0,0 +1,30 @@
+#!/bin/bash
+# Usage: cd $LIBIGL; scripts/update_gh-pages.sh
+set -o xtrace
+git pull && git checkout gh-pages && git rebase master && git pull
+HEADER="title: libigl
+author: Alec Jacobson and Daniele Panozzo and others
+css: tutorial/style.css
+html header:   <script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
+<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
+<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
+<script>hljs.initHighlightingOnLoad();</script>
+
+"
+echo "$HEADER" \
+  | cat - README.md | multimarkdown -o index.html && \
+  git commit -m "update index.html to match README.md" README.md index.html
+HEADER="title: libigl
+author: Alec Jacobson and Daniele Panozzo and others
+css: ../tutorial/style.css
+html header:   <script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
+<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
+<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
+<script>hljs.initHighlightingOnLoad();</script>
+
+"
+echo "$HEADER" \
+  | cat - build/README.md | multimarkdown -o build/index.html && \
+  git commit -m "update index.html to match README.md" build/README.md \
+  build/index.html
+git push origin gh-pages && git checkout master && git merge gh-pages && git push

+ 0 - 416
tutorial.html

@@ -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 &lt;igl/some_other_igl_function.h&gt;
-#ifdef IGL_STATIC_LIBRARY
-#  define IGL_HEADER_ONLY
-#  define IGL_HEADER_ONLY_WAS_NOT_DEFINED
-#endif
-#include &lt;igl/igl_function_to_inline.h&gt;
-#ifndef IGL_STATIC_LIBRARY_WAS_NOT_DEFINED
-#  undef IGL_HEADER_ONLY
-#endif
-#include &lt;igl/yet_another_igl_function.h&gt;
-...
-      </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&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&)</span>", referenced from:
-      uniform_sample(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&, int, double, Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt;&)in Skinning.o
-  "Eigen::SparseMatrix&lt;double, 0, int&gt; igl::cat&lt;Eigen::SparseMatrix&lt;double, 0, int&gt; &gt;(int, Eigen::SparseMatrix&lt;double, 0, int&gt; const&, Eigen::SparseMatrix&lt;double, 0, int&gt; const&)", referenced from:
-      covariance_scatter_matrix(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&, ArapEnergy, Eigen::SparseMatrix&lt;double, 0, int&gt;&)in arap_dof.o
-      arap_rhs(Eigen::Matrix&lt;double, -1, -1, 0, -1, -1&gt; const&, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&, ArapEnergy, Eigen::SparseMatrix&lt;double, 0, int&gt;&)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&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; 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&gt;&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&gt;$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 &lt;igl.h&gt;
-#include &lt;Eigen/Core&gt;
-
-int main(int argc, char * argv[])
-{
-  Eigen::MatrixXd V;
-  Eigen::MatrixXi F;
-  return (argc&gt;=2 &amp;&amp; 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 &lt;OpenGL/gl.h&gt;
-#elif defined(_WIN32)
-#    define NOMINMAX
-#    include &lt;Windows.h&gt;
-#    undef NOMINMAX
-#    include &lt;GL/glew.h&gt;
-#    include &lt;GL/gl.h&gt;
-#else
-#  define GL_GLEXT_PROTOTYPES
-#  include &lt;GL/gl.h&gt;
-#  include &lt;GL/glext.h&gt;
-#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 &lt;igl/some_function.h&gt;
-      </code></pre>
-      <p>
-      libigl headers of extras can then be included using:
-      </p>
-      <pre><code>
-#include &lt;igl/extra/some_extra_function.h&gt;
-      </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>

+ 6 - 1
tutorial/403_BoundedBiharmonicWeights/main.cpp

@@ -1,8 +1,13 @@
-// Don't use static library for this example because of Mosek complications
+// If you don't have mosek installed and don't want to install it. Then
+// uncomment the following six lines.  Don't use static library for this
+// example because of Mosek complications
+//
 //#define IGL_NO_MOSEK
 //#ifdef IGL_NO_MOSEK
+//#ifdef IGL_STATIC_LIBRARY
 //#undef IGL_STATIC_LIBRARY
 //#endif
+//#endif
 #include <igl/boundary_conditions.h>
 #include <igl/colon.h>
 #include <igl/column_to_quats.h>

+ 1 - 1
tutorial/tutorial.html.REMOVED.git-id

@@ -1 +1 @@
-bb9c175cf9dfae345668e73bfd5220e21b28ae0e
+a30fd5f786682eb951f8170826b3b3212240db31

+ 1 - 1
tutorial/tutorial.md.REMOVED.git-id

@@ -1 +1 @@
-a7312d6b030f9fcaa361629f047902a139d01d1e
+227bf977c70fc9d17fb2b2823c0818e6205893d2