Browse Source

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

Conflicts:
	include/igl/barycenter.cpp

Former-commit-id: c155c57bacb36fa756f45ef86c9577ce7eb446ff
Olga Diamanti 10 years ago
parent
commit
cae8d73321
39 changed files with 1519 additions and 1533 deletions
  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)
 ![](tutorial/images/libigl-logo.jpg)
 
 
-<http://libigl.github.io/libigl/>
 <https://github.com/libigl/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.
 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:
 small "Hello, World" program:
 
 
 ```cpp
 ```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
 ```bash
 gcc -I/opt/local/include/eigen3 -I./igl/ hello.cpp -o hello
 gcc -I/opt/local/include/eigen3 -I./igl/ hello.cpp -o hello
@@ -64,344 +73,30 @@ Hello, mesh:
  0.5 -0.5
  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
 implement as appropriate. To cite the library in general, you could use this
 BibTeX entry:
 BibTeX entry:
 
 
@@ -413,3 +108,23 @@ BibTeX entry:
   year = {2014},
   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.2  Bug fix in winding number code
 1.0.1  Bug fixes and more CGAL support
 1.0.1  Bug fixes and more CGAL support
 1.0.0  Major beta release: many renames, tutorial, triangle wrapper, org. build
 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.6  Generalized Winding Numbers
 0.4.5  CGAL extra: mesh selfintersection
 0.4.5  CGAL extra: mesh selfintersection
 0.4.4  STL file format support
 0.4.4  STL file format support

+ 1 - 1
build/Makefile_cgal

@@ -26,7 +26,7 @@ INC+=$(EIGEN3_INC)
 # CGAL dependency
 # CGAL dependency
 CGAL=$(DEFAULT_PREFIX)
 CGAL=$(DEFAULT_PREFIX)
 CGAL_INC=-I$(CGAL)/include
 CGAL_INC=-I$(CGAL)/include
-CGAL_FLAGS=-frounding-math -fsignaling-nans 
+CGAL_FLAGS=-frounding-math -fsignaling-nans ${OPENMP}
 CFLAGS+=$(CGAL_FLAGS)
 CFLAGS+=$(CGAL_FLAGS)
 INC+=$(CGAL_INC)
 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;
 igl::Camera down_camera;
 bool trackball_on = false;
 bool trackball_on = false;
 int down_mouse_x,down_mouse_y,move_x,move_y;
 int down_mouse_x,down_mouse_y,move_x,move_y;
+int down_vp;
 // Position of light
 // Position of light
 float light_pos[4] = {0.1,0.1,-0.9,0};
 float light_pos[4] = {0.1,0.1,-0.9,0};
 // Vertex positions, normals, colors and centroid
 // 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
 #undef IGL_STATIC_LIBRARY
 #include <igl/principal_curvature.h>
 #include <igl/principal_curvature.h>
 #include <igl/read_triangle_mesh.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;
 bool centroid_is_visible = true;
 int down_x,down_y;
 int down_x,down_y;
 igl::Camera down_camera;
 igl::Camera down_camera;
-std::string output_prefix;
+std::string output_weights_filename,output_pose_prefix;
 
 
 struct CameraAnimation
 struct CameraAnimation
 {
 {
@@ -594,13 +594,13 @@ void redo()
   }
   }
 }
 }
 
 
-bool save()
+bool save_pose()
 {
 {
   using namespace std;
   using namespace std;
   using namespace igl;
   using namespace igl;
   using namespace Eigen;
   using namespace Eigen;
   string output_filename;
   string output_filename;
-  next_filename(output_prefix,4,".dmat",output_filename);
+  next_filename(output_pose_prefix,4,".dmat",output_filename);
   MatrixXd T;
   MatrixXd T;
   forward_kinematics(C,BE,P,s.mouse.rotations(),T);
   forward_kinematics(C,BE,P,s.mouse.rotations(),T);
   if(writeDMAT(output_filename,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)
 void key(unsigned char key, int mouse_x, int mouse_y)
 {
 {
   using namespace std;
   using namespace std;
@@ -660,7 +677,13 @@ void key(unsigned char key, int mouse_x, int mouse_y)
     case 'S':
     case 'S':
     case 's':
     case 's':
     {
     {
-      save();
+      save_pose();
+      break;
+    }
+    case 'W':
+    case 'w':
+    {
+      save_weights();
       break;
       break;
     }
     }
     case 'z':
     case 'z':
@@ -848,11 +871,11 @@ int main(int argc, char * argv[])
   string filename = "../shared/cheburashka.off";
   string filename = "../shared/cheburashka.off";
   string skel_filename = "../shared/cheburashka.tgf";
   string skel_filename = "../shared/cheburashka.tgf";
   string weights_filename = "";
   string weights_filename = "";
-  output_prefix = "";
+  output_pose_prefix = "";
   switch(argc)
   switch(argc)
   {
   {
     case 5:
     case 5:
-      output_prefix = argv[4];
+      output_pose_prefix = argv[4];
       //fall through
       //fall through
     case 4:
     case 4:
       weights_filename = argv[3];
       weights_filename = argv[3];
@@ -872,9 +895,10 @@ int main(int argc, char * argv[])
   cout<<"⌥ +[Click] and [drag]  Rotate secene."<<endl;
   cout<<"⌥ +[Click] and [drag]  Rotate secene."<<endl;
   cout<<"⌫                      Delete selected node(s) and incident bones."<<endl;
   cout<<"⌫                      Delete selected node(s) and incident bones."<<endl;
   cout<<"D,d                    Deselect all."<<endl;
   cout<<"D,d                    Deselect all."<<endl;
-  cout<<"S,s                    Save current pose."<<endl;
   cout<<"R                      Reset selected rotation."<<endl;
   cout<<"R                      Reset selected rotation."<<endl;
   cout<<"r                      Reset all rotations."<<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,z                    Snap to canonical view."<<endl;
   cout<<"⌘ Z                    Undo."<<endl;
   cout<<"⌘ Z                    Undo."<<endl;
   cout<<"⇧ ⌘ Z                  Redo."<<endl;
   cout<<"⇧ ⌘ Z                  Redo."<<endl;
@@ -883,15 +907,21 @@ int main(int argc, char * argv[])
   string dir,_1,_2,name;
   string dir,_1,_2,name;
   read_triangle_mesh(filename,V,F,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;
     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
   // 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?
   // Q: Would we gain even more by remove almost exactly duplicate vertices?
   Eigen::MatrixXi SF,SVI,SVJ;
   Eigen::MatrixXi SF,SVI,SVJ;
   igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
   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;
   V = SV;
 }
 }
 
 
@@ -183,7 +183,7 @@ inline igl::WindingNumberTree<Point>::WindingNumberTree(
   V(parent.V),
   V(parent.V),
   SV(),
   SV(),
   F(_F),
   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++)
     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)
       if(!squared)
       {
       {
         D(i,j) = sqrt(D(i,j));
         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();
       // double sqrd = (V.row(i)-pos).array().pow(2).sum();
       // Must first store in temporary
       // Must first store in temporary
       VectorXd vi = V.row(i);
       VectorXd vi = V.row(i);
-      double sqrd = (vi-pos).array().pow(2).sum();
+      double sqrd = (vi-pos).squaredNorm();
       if(sqrd <= FLOAT_EPS)
       if(sqrd <= FLOAT_EPS)
       {
       {
         //cout<<"sum((["<<
         //cout<<"sum((["<<

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

@@ -405,7 +405,9 @@ inline igl::SelfIntersectMesh<
   // Use map for *all* faces
   // Use map for *all* faces
   map<typename CDT_plus_2::Vertex_handle,Index> v2i;
   map<typename CDT_plus_2::Vertex_handle,Index> v2i;
   // Loop over offending triangles
   // 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
     // index in F
     const Index f = offending[o];
     const Index f = offending[o];
@@ -439,6 +441,7 @@ inline igl::SelfIntersectMesh<
           assert(T[f].vertex(i) == P[o].to_3d(vit->point()));
           assert(T[f].vertex(i) == P[o].to_3d(vit->point()));
 #endif
 #endif
           // For first three, use original index in F
           // For first three, use original index in F
+#   pragma omp critical
           v2i[vit] = F(f,i);
           v2i[vit] = F(f,i);
         }else
         }else
         {
         {
@@ -480,6 +483,7 @@ inline igl::SelfIntersectMesh<
                 if(vit_point_3 == P[no].to_3d(uit->point()))
                 if(vit_point_3 == P[no].to_3d(uit->point()))
                 {
                 {
                   assert(v2i.count(uit) == 1);
                   assert(v2i.count(uit) == 1);
+#   pragma omp critical
                   v2i[vit] = v2i[uit];
                   v2i[vit] = v2i[uit];
                   found = true;
                   found = true;
                 }
                 }
@@ -488,9 +492,12 @@ inline igl::SelfIntersectMesh<
           }
           }
           if(!found)
           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++;
         i++;
@@ -500,6 +507,7 @@ inline igl::SelfIntersectMesh<
       Index i = 0;
       Index i = 0;
       // Resize to fit new number of triangles
       // Resize to fit new number of triangles
       NF[o].resize(cdt[o].number_of_faces(),3);
       NF[o].resize(cdt[o].number_of_faces(),3);
+#   pragma omp atomic
       NF_count+=NF[o].rows();
       NF_count+=NF[o].rows();
       // Append new faces to NF
       // Append new faces to NF
       for(
       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::Triangle_3<Kernel> Triangle_3; 
   typedef CGAL::Plane_3<Kernel>    Plane_3;
   typedef CGAL::Plane_3<Kernel>    Plane_3;
   typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_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
   // 2D Primitives
   typedef CGAL::Point_2<Kernel>    Point_2;
   typedef CGAL::Point_2<Kernel>    Point_2;
   typedef CGAL::Segment_2<Kernel>  Segment_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;
   using namespace std;
 
 
   typedef CGAL::Triangle_3<Kernel> Triangle_3; 
   typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+  typedef CGAL::Point_3<Kernel> Point_3; 
   typedef typename std::vector<Triangle_3>::iterator Iterator;
   typedef typename std::vector<Triangle_3>::iterator Iterator;
   typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
   typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
   typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
   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.clear();
   tree.insert(T.begin(),T.end());
   tree.insert(T.begin(),T.end());
   tree.accelerate_distance_queries();
   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>
 template <typename Kernel>

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

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

+ 5 - 0
include/igl/doublearea.cpp

@@ -124,6 +124,11 @@ IGL_INLINE void igl::doublearea(
   assert(s.rows() == m);
   assert(s.rows() == m);
   // resize output
   // resize output
   dblA.resize(l.rows(),1);
   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++)
   for(int i = 0;i<m;i++)
   {
   {
     //// Heron's formula for area
     //// 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)
   Eigen::PlainObjectBase<DerivedL>& L)
 {
 {
   using namespace std;
   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())
   switch(F.cols())
   {
   {
     case 2:
     case 2:
@@ -28,29 +33,30 @@ IGL_INLINE void igl::edge_lengths(
     }
     }
     case 3:
     case 3:
     {
     {
-      L.resize(F.rows(),3);
+      L.resize(m,3);
       // loop over faces
       // 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;
       break;
     }
     }
     case 4:
     case 4:
     {
     {
-      const int m = F.rows();
       L.resize(m,6);
       L.resize(m,6);
       // loop over faces
       // loop over faces
+      #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
       for(int i = 0;i<m;i++)
       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;
       break;
     }
     }

+ 43 - 55
include/igl/exterior_edges.cpp

@@ -1,9 +1,12 @@
 #include "exterior_edges.h"
 #include "exterior_edges.h"
 #include "all_edges.h"
 #include "all_edges.h"
+#include "sort.h"
+#include "unique.h"
 
 
 #include <cassert>
 #include <cassert>
 #include <unordered_map>
 #include <unordered_map>
 #include <utility>
 #include <utility>
+#include <iostream>
 
 
 //template <typename T> inline int sgn(T val) {
 //template <typename T> inline int sgn(T val) {
 //      return (T(0) < val) - (val < T(0));
 //      return (T(0) < val) - (val < T(0));
@@ -38,68 +41,53 @@ IGL_INLINE void igl::exterior_edges(
   using namespace Eigen;
   using namespace Eigen;
   using namespace std;
   using namespace std;
   assert(F.cols() == 3);
   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);
   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)
 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,
     const Eigen::MatrixXi & F,
     Eigen::MatrixXi & E);
     Eigen::MatrixXi & E);
   // Inline version
   // Inline version
-  Eigen::MatrixXi exterior_edges( const Eigen::MatrixXi & F);
+  IGL_INLINE Eigen::MatrixXi exterior_edges( const Eigen::MatrixXi & F);
 }
 }
 #ifndef IGL_STATIC_LIBRARY
 #ifndef IGL_STATIC_LIBRARY
 #  include "exterior_edges.cpp"
 #  include "exterior_edges.cpp"

+ 16 - 3
include/igl/facet_components.cpp

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

+ 4 - 2
include/igl/facet_components.h

@@ -22,10 +22,12 @@ namespace igl
   //   C  #F list of connected component ids
   //   C  #F list of connected component ids
   template <
   template <
     typename TTIndex, 
     typename TTIndex, 
-    typename DerivedC>
+    typename DerivedC,
+    typename Derivedcounts>
   IGL_INLINE void facet_components(
   IGL_INLINE void facet_components(
     const std::vector<std::vector<std::vector<TTIndex > > > & TT,
     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
 #ifndef IGL_STATIC_LIBRARY
 #  include "facet_components.cpp"
 #  include "facet_components.cpp"

+ 25 - 7
include/igl/internal_angles.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "internal_angles.h"
 #include "internal_angles.h"
 #include "edge_lengths.h"
 #include "edge_lengths.h"
+#include "get_seconds.h"
 
 
 template <typename DerivedV, typename DerivedF, typename DerivedK>
 template <typename DerivedV, typename DerivedF, typename DerivedK>
 IGL_INLINE void igl::internal_angles(
 IGL_INLINE void igl::internal_angles(
@@ -15,6 +16,7 @@ IGL_INLINE void igl::internal_angles(
   Eigen::PlainObjectBase<DerivedK> & K)
   Eigen::PlainObjectBase<DerivedK> & K)
 {
 {
   using namespace Eigen;
   using namespace Eigen;
+  using namespace std;
   // Edge lengths
   // Edge lengths
   Matrix<
   Matrix<
     typename DerivedV::Scalar,
     typename DerivedV::Scalar,
@@ -23,7 +25,7 @@ IGL_INLINE void igl::internal_angles(
   edge_lengths(V,F,L);
   edge_lengths(V,F,L);
 
 
   assert(F.cols() == 3 && "F should contain triangles");
   assert(F.cols() == 3 && "F should contain triangles");
-  return internal_angles(L,K);
+  internal_angles(L,K);
 }
 }
 
 
 template <typename DerivedL, typename DerivedK>
 template <typename DerivedL, typename DerivedK>
@@ -32,13 +34,29 @@ IGL_INLINE void igl::internal_angles(
   Eigen::PlainObjectBase<DerivedK> & K)
   Eigen::PlainObjectBase<DerivedK> & K)
 {
 {
   assert(L.cols() == 3 && "Edge-lengths should come from triangles");
   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
     // loop over faces
     for(int i = 0;i<m;i++)
     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
     // semiperimeters
     Matrix<Scalar,Dynamic,1> s = l.rowwise().sum()*0.5;
     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_hull.h"
 #include "outer_facet.h"
 #include "outer_facet.h"
 #include "facet_components.h"
 #include "facet_components.h"
-
+#include "winding_number.h"
 #include "triangle_triangle_adjacency.h"
 #include "triangle_triangle_adjacency.h"
 #include "unique_edge_map.h"
 #include "unique_edge_map.h"
+#include "barycenter.h"
 #include "per_face_normals.h"
 #include "per_face_normals.h"
 #include "all_edges.h"
 #include "all_edges.h"
 #include "colon.h"
 #include "colon.h"
@@ -33,10 +34,10 @@ IGL_INLINE void igl::outer_hull(
   using namespace igl;
   using namespace igl;
   typedef typename DerivedF::Index Index;
   typedef typename DerivedF::Index Index;
   Matrix<Index,DerivedF::RowsAtCompileTime,1> C;
   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 DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
-  typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
   const Index m = F.rows();
   const Index m = F.rows();
 
 
   typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
   typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
@@ -48,8 +49,10 @@ IGL_INLINE void igl::outer_hull(
 
 
   vector<vector<vector<Index > > > TT,_1;
   vector<vector<vector<Index > > > TT,_1;
   triangle_triangle_adjacency(E,EMAP,uE2E,false,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());
   G.resize(0,F.cols());
   J.resize(0,1);
   J.resize(0,1);
   flip.setConstant(m,1,false);
   flip.setConstant(m,1,false);
@@ -64,162 +67,229 @@ IGL_INLINE void igl::outer_hull(
   vector<bool> EH(3*m,false);
   vector<bool> EH(3*m,false);
   vector<MatrixXG> vG(ncc);
   vector<MatrixXG> vG(ncc);
   vector<MatrixXJ> vJ(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;
           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
   // collect G and J across components
   G.resize(nG,3);
   G.resize(nG,3);
   J.resize(nG,1);
   J.resize(nG,1);
   {
   {
     size_t off = 0;
     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 "all_edges.h"
 #include "doublearea.h"
 #include "doublearea.h"
 #include "per_edge_normals.h"
 #include "per_edge_normals.h"
+#include "get_seconds.h"
 #include "per_face_normals.h"
 #include "per_face_normals.h"
 #include "unique_simplices.h"
 #include "unique_simplices.h"
 #include <vector>
 #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
   // 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).
   // the undirected edge corresponding to the directed edge allE.row(i).
 
 
-  Eigen::VectorXd W(F.rows());
+  Eigen::VectorXd W;
   switch(weighting)
   switch(weighting)
   {
   {
     case PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM:
     case PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM:
-      W.setConstant(1.);
+      // Do nothing
       break;
       break;
     default:
     default:
       assert(false && "Unknown weighting type");
       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 f = 0;f<m;f++)
   {
   {
     for(int c = 0;c<3;c++)
     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 <
 template <

+ 2 - 0
include/igl/per_vertex_normals.cpp

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

+ 0 - 3
include/igl/principal_curvature.h

@@ -11,9 +11,6 @@
 
 
 #include <Eigen/Geometry>
 #include <Eigen/Geometry>
 #include <Eigen/Dense>
 #include <Eigen/Dense>
-#include <vector>
-#include <stdio.h>
-#include <map>
 
 
 #include <igl/igl_inline.h>
 #include <igl/igl_inline.h>
 #include <igl/cotmatrix.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();
   int np  = P.rows();
   // vector from source to destination
   // vector from source to destination
   MatL DmS = D-S;
   MatL DmS = D-S;
-  double v_sqrlen = (double)(DmS.array().pow(2).sum());
+  double v_sqrlen = (double)(DmS.squaredNorm());
   assert(v_sqrlen != 0);
   assert(v_sqrlen != 0);
   // resize output
   // resize output
   t.resize(np,1);
   t.resize(np,1);
@@ -48,7 +48,7 @@ IGL_INLINE void igl::project_to_line(
     t(i) = -(DmS.array()*SmPi.array()).sum() / v_sqrlen;
     t(i) = -(DmS.array()*SmPi.array()).sum() / v_sqrlen;
     // P projected onto line
     // P projected onto line
     MatL projP = (1-t(i))*S + t(i)*D;
     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 
 // 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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "sortrows.h"
 #include "sortrows.h"
+#include "get_seconds.h"
 
 
 #include "SortableRow.h"
 #include "SortableRow.h"
 #include "sort.h"
 #include "sort.h"
@@ -55,6 +56,9 @@ IGL_INLINE void igl::sortrows(
   Eigen::PlainObjectBase<DerivedX>& Y,
   Eigen::PlainObjectBase<DerivedX>& Y,
   Eigen::PlainObjectBase<DerivedIX>& IX)
   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 std;
   using namespace Eigen;
   using namespace Eigen;
   using namespace igl;
   using namespace igl;

+ 1 - 0
include/igl/unique.cpp

@@ -12,6 +12,7 @@
 #include "sortrows.h"
 #include "sortrows.h"
 #include "list_to_matrix.h"
 #include "list_to_matrix.h"
 #include "matrix_to_list.h"
 #include "matrix_to_list.h"
+#include "get_seconds.h"
 
 
 #include <algorithm>
 #include <algorithm>
 #include <iostream>
 #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 "igl_inline.h"
 #include <Eigen/Dense>
 #include <Eigen/Dense>
 #include <vector>
 #include <vector>

+ 9 - 1
include/igl/unique_simplices.cpp

@@ -8,6 +8,7 @@
 #include "unique_simplices.h"
 #include "unique_simplices.h"
 #include "sort.h"
 #include "sort.h"
 #include "unique.h"
 #include "unique.h"
+#include "get_seconds.h"
 
 
 template <
 template <
   typename DerivedF,
   typename DerivedF,
@@ -22,6 +23,7 @@ IGL_INLINE void igl::unique_simplices(
 {
 {
   using namespace Eigen;
   using namespace Eigen;
   using namespace igl;
   using namespace igl;
+  using namespace std;
   // Sort each face
   // Sort each face
   MatrixXi sortF, unusedI;
   MatrixXi sortF, unusedI;
   igl::sort(F,2,true,sortF,unusedI);
   igl::sort(F,2,true,sortF,unusedI);
@@ -29,8 +31,14 @@ IGL_INLINE void igl::unique_simplices(
   MatrixXi C;
   MatrixXi C;
   igl::unique_rows(sortF,C,IA,IC);
   igl::unique_rows(sortF,C,IA,IC);
   FF.resize(IA.size(),F.cols());
   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
   // 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));
     FF.row(i) = F.row(IA(i));
   }
   }

+ 9 - 9
include/igl/winding_number.h

@@ -39,15 +39,15 @@ namespace igl
     const double * O,
     const double * O,
     const int no,
     const int no,
     double * S);
     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
   // 2d
   template <typename DerivedF>
   template <typename DerivedF>
   IGL_INLINE void winding_number_2(
   IGL_INLINE void winding_number_2(

+ 64 - 505
index.html

@@ -12,35 +12,43 @@
 </head>
 </head>
 <body>
 <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>
 <figure>
 <img src="tutorial/images/libigl-logo.jpg" alt="" />
 <img src="tutorial/images/libigl-logo.jpg" alt="" />
 <figcaption></figcaption></figure>
 <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>
 <h2 id="installation">Installation</h2>
 
 
 <p>Libigl is a <em>header</em> library. You do <strong>not</strong> need to build anything to install.
 <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>
 small &#8220;Hello, World&#8221; program:</p>
 
 
 <pre><code class="cpp">#include &lt;igl/cotmatrix.h&gt;
 <pre><code class="cpp">#include &lt;igl/cotmatrix.h&gt;
@@ -64,8 +72,8 @@ int main()
 }
 }
 </code></pre>
 </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
 <pre><code class="bash">gcc -I/opt/local/include/eigen3 -I./igl/ hello.cpp -o hello
 </code></pre>
 </code></pre>
@@ -79,504 +87,34 @@ macports for example you could compile this with:</p>
  0.5 -0.5
  0.5 -0.5
 </code></pre>
 </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>
 <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>
 <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
 implement as appropriate. To cite the library in general, you could use this
 BibTeX entry:</p>
 BibTeX entry:</p>
 
 
@@ -588,5 +126,26 @@ BibTeX entry:</p>
 }
 }
 </code></pre>
 </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>
 </body>
 </html>
 </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
 //#define IGL_NO_MOSEK
 //#ifdef IGL_NO_MOSEK
 //#ifdef IGL_NO_MOSEK
+//#ifdef IGL_STATIC_LIBRARY
 //#undef IGL_STATIC_LIBRARY
 //#undef IGL_STATIC_LIBRARY
 //#endif
 //#endif
+//#endif
 #include <igl/boundary_conditions.h>
 #include <igl/boundary_conditions.h>
 #include <igl/colon.h>
 #include <igl/colon.h>
 #include <igl/column_to_quats.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