Browse Source

merge

Former-commit-id: 9bc806413242e75600cd12537ad87eb38784fd41
Alec Jacobson 7 years ago
parent
commit
3b3d439db5
100 changed files with 3658 additions and 517 deletions
  1. 2 1
      .appveyor.yml
  2. 2 0
      .gitignore
  3. 3 3
      .gitmodules
  4. 7 2
      .travis.yml
  5. 0 2
      ACKNOWLEDGEMENTS
  6. 21 16
      README.md
  7. 62 0
      coding-guidelines.html
  8. 42 0
      coding-guidelines.md
  9. 0 15
      exclude.lst
  10. 192 90
      include/igl/AABB.cpp
  11. 78 35
      include/igl/AABB.h
  12. 3 3
      include/igl/HalfEdgeIterator.h
  13. 8 2
      include/igl/ViewerData.cpp
  14. 6 6
      include/igl/ViewerData.h
  15. 76 70
      include/igl/WindingNumberAABB.h
  16. 119 119
      include/igl/WindingNumberTree.h
  17. 0 1
      include/igl/ambient_occlusion.cpp
  18. 1 1
      include/igl/angle_bound_frame_fields.cpp
  19. 5 4
      include/igl/avg_edge_length.cpp
  20. 2 2
      include/igl/avg_edge_length.h
  21. 10 0
      include/igl/barycenter.cpp
  22. 4 0
      include/igl/barycentric_coordinates.cpp
  23. 1 1
      include/igl/collapse_edge.h
  24. 1 0
      include/igl/colon.cpp
  25. 1462 0
      include/igl/colormap.cpp
  26. 77 0
      include/igl/colormap.h
  27. 4 4
      include/igl/copyleft/cgal/CGAL_includes.hpp
  28. 4 0
      include/igl/copyleft/cgal/assign.cpp
  29. 2 0
      include/igl/copyleft/cgal/closest_facet.cpp
  30. 72 0
      include/igl/copyleft/cgal/convex_hull.cpp
  31. 56 0
      include/igl/copyleft/cgal/convex_hull.h
  32. 2 0
      include/igl/copyleft/cgal/extract_cells.cpp
  33. 39 0
      include/igl/copyleft/cgal/hausdorff.cpp
  34. 62 0
      include/igl/copyleft/cgal/hausdorff.h
  35. 13 13
      include/igl/copyleft/cgal/insert_into_cdt.cpp
  36. 8 7
      include/igl/copyleft/cgal/insert_into_cdt.h
  37. 1 0
      include/igl/copyleft/cgal/intersect_other.cpp
  38. 15 0
      include/igl/copyleft/cgal/list_to_matrix.cpp
  39. 11 2
      include/igl/copyleft/cgal/mesh_boolean.cpp
  40. 4 0
      include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp
  41. 3 1
      include/igl/copyleft/cgal/minkowski_sum.cpp
  42. 4 0
      include/igl/copyleft/cgal/order_facets_around_edge.cpp
  43. 1 0
      include/igl/copyleft/cgal/outer_element.cpp
  44. 4 0
      include/igl/copyleft/cgal/outer_facet.cpp
  45. 1 0
      include/igl/copyleft/cgal/point_mesh_squared_distance.cpp
  46. 6 0
      include/igl/copyleft/cgal/point_solid_signed_squared_distance.cpp
  47. 2 0
      include/igl/copyleft/cgal/points_inside_component.cpp
  48. 9 4
      include/igl/copyleft/cgal/polyhedron_to_mesh.cpp
  49. 6 3
      include/igl/copyleft/cgal/polyhedron_to_mesh.h
  50. 8 8
      include/igl/copyleft/cgal/projected_cdt.cpp
  51. 6 5
      include/igl/copyleft/cgal/projected_cdt.h
  52. 2 0
      include/igl/copyleft/cgal/propagate_winding_numbers.cpp
  53. 9 1
      include/igl/copyleft/cgal/remesh_intersections.cpp
  54. 2 0
      include/igl/copyleft/cgal/remesh_self_intersections.cpp
  55. 1 0
      include/igl/copyleft/cgal/remove_unreferenced.cpp
  56. 1 1
      include/igl/copyleft/cgal/signed_distance_isosurface.cpp
  57. 15 0
      include/igl/copyleft/cgal/slice_mask.cpp
  58. 2 0
      include/igl/copyleft/cgal/submesh_aabb_tree.cpp
  59. 12 0
      include/igl/copyleft/cgal/trim_with_solid.cpp
  60. 0 3
      include/igl/copyleft/cgal/unique.cpp
  61. 18 0
      include/igl/copyleft/cgal/unique_rows.cpp
  62. 180 0
      include/igl/copyleft/cgal/wire_mesh.cpp
  63. 48 0
      include/igl/copyleft/cgal/wire_mesh.h
  64. 46 35
      include/igl/copyleft/marching_cubes.cpp
  65. 8 4
      include/igl/copyleft/marching_cubes.h
  66. 22 4
      include/igl/copyleft/offset_surface.cpp
  67. 2 1
      include/igl/copyleft/offset_surface.h
  68. 5 5
      include/igl/cut_mesh.cpp
  69. 1 0
      include/igl/cut_mesh_from_singularities.cpp
  70. 8 0
      include/igl/decimate.cpp
  71. 1 1
      include/igl/dfs.cpp
  72. 8 2
      include/igl/dirname.cpp
  73. 19 6
      include/igl/doublearea.cpp
  74. 6 0
      include/igl/edge_lengths.cpp
  75. 10 6
      include/igl/edge_topology.h
  76. 1 0
      include/igl/edges.cpp
  77. 2 2
      include/igl/eigs.cpp
  78. 1 0
      include/igl/embree/EmbreeIntersector.h
  79. 69 0
      include/igl/embree/shape_diameter_function.cpp
  80. 60 0
      include/igl/embree/shape_diameter_function.h
  81. 1 1
      include/igl/exterior_edges.cpp
  82. 6 1
      include/igl/extract_manifold_patches.cpp
  83. 1 0
      include/igl/find_cross_field_singularities.cpp
  84. 17 4
      include/igl/flood_fill.cpp
  85. 4 1
      include/igl/flood_fill.h
  86. 1 1
      include/igl/grad.cpp
  87. 13 5
      include/igl/grid.cpp
  88. 64 0
      include/igl/grid_search.cpp
  89. 42 0
      include/igl/grid_search.h
  90. 48 0
      include/igl/hausdorff.cpp
  91. 23 0
      include/igl/hausdorff.h
  92. 60 0
      include/igl/hessian.cpp
  93. 47 0
      include/igl/hessian.h
  94. 64 0
      include/igl/hessian_energy.cpp
  95. 45 0
      include/igl/hessian_energy.h
  96. 4 0
      include/igl/internal_angles.cpp
  97. 1 1
      include/igl/is_boundary_edge.cpp
  98. 11 8
      include/igl/ismember.cpp
  99. 4 4
      include/igl/ismember.h
  100. 116 0
      include/igl/isolines.cpp

+ 2 - 1
.appveyor.yml

@@ -6,6 +6,7 @@ branches:
   only:
     - master
     - alecjacobson
+    - cmake
 install:
   - git submodule update --init --recursive
   - cinstall: python
@@ -14,7 +15,7 @@ build_script:
   - cd c:\projects\libigl\tutorial
   - mkdir build
   - cd build
-  - cmake -D "LIBIGL_USE_STATIC_LIBRARY=ON" -G "Visual Studio 14 2015 Win64" ../
+  - cmake -D "LIBIGL_USE_STATIC_LIBRARY=ON" -D "LIBIGL_WITH_ANTTWEAKBAR=OFF" -G "Visual Studio 14 2015 Win64" ../
 #  - cmake -G "Visual Studio 14 2015 Win64" ../
   - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 #  - set MSBuildOptions=/v:m /p:Configuration=Release /logger:%MSBuildLogger%

+ 2 - 0
.gitignore

@@ -96,3 +96,5 @@ python/build4
 python/scripts/generated
 python/builddebug
 tutorial/.idea
+python/buildstatic
+tutorial/cmake-build-debug

+ 3 - 3
.gitmodules

@@ -1,8 +1,8 @@
 [submodule "external/nanogui"]
 	path = external/nanogui
-url=https://github.com/libigl/nanogui.git
-        fetchRecursiveSubmodules = true
-        ignore = dirty
+	url=https://github.com/libigl/nanogui.git
+	fetchRecursiveSubmodules = true
+	ignore = dirty
 [submodule "external/embree"]
 	path = external/embree
 	url = https://github.com/embree/embree.git

+ 7 - 2
.travis.yml

@@ -1,5 +1,6 @@
 language: cpp
 sudo: false
+dist: precise
 matrix:
   include:
     - os: linux
@@ -13,11 +14,13 @@ matrix:
         - cd build
         - cmake -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_C_COMPILER=gcc-4.8 -DLIBIGL_WITH_EMBREE=OFF -DLIBIGL_USE_STATIC_LIBRARY=ON ../
         - make -j 2
+        - cd ../tutorial
+        - python3 101_FileIO.py || { cd ../; mkdir build2; cd build2; cmake -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_C_COMPILER=gcc-4.8 -DLIBIGL_WITH_EMBREE=OFF -DLIBIGL_USE_STATIC_LIBRARY=ON - DCHECK_UNDEFINED=ON ../; make -j 2; }
         - cd ../../
         - cd tutorial
         - mkdir build
         - cd build
-        - cmake -DLIBIGL_USE_STATIC_LIBRARY=ON -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_C_COMPILER=gcc-4.8 ../
+        - cmake -DLIBIGL_USE_STATIC_LIBRARY=ON  -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_C_COMPILER=gcc-4.8 -DLIBIGL_WITH_EMBREE=OFF ../
         - make -j 2
       addons:
         apt:
@@ -54,9 +57,11 @@ matrix:
         - cd build
         - cmake ../
         - make -j 2
+        - cd ../tutorial
+        - python 101_FileIO.py
         - cd ../../
         - cd tutorial
         - mkdir build
         - cd build
-        - cmake -DLIBIGL_USE_STATIC_LIBRARY=ON ../
+        - cmake -DLIBIGL_USE_STATIC_LIBRARY=ON -DLIBIGL_WITH_NANOGUI=ON ../
         - make -j 2

+ 0 - 2
ACKNOWLEDGEMENTS

@@ -1,2 +0,0 @@
-Qiong Wu (pointing out compilation errors in Windows)
-Gaurav Bharaj (pointing out bug in remove_duplicate_vertices.cpp)

+ 21 - 16
README.md

@@ -43,10 +43,14 @@ and Windows with Visual Studio 2015 Community Edition.
 As of version 1.0, libigl includes an introductory
 [tutorial](http://libigl.github.io/libigl/tutorial/tutorial.html) that covers many functionalities.
 
-## libigl example project
+## libigl Example Project
 
 We provide a [blank project example](https://github.com/libigl/libigl-example-project) showing how to use libigl and cmake. Feel free and encouraged to copy or fork this project as a way of starting a new personal project using libigl.
 
+## Coding Guidelines and Tips
+
+libigl follows strict coding guidelines, please take a look [here](http://libigl.github.io/libigl/style-guidelines.html) before submitting your pull requests. We also have a set of [general coding tips](http://libigl.github.io/libigl/coding-guidelines.html) on how to code a geometry processing research project.
+
 ## Installation
 
 Libigl is a **header-only** library. You do **not** need to build anything to
@@ -98,18 +102,18 @@ libigl depends only on the [Eigen](http://eigen.tuxfamily.org) library.
 
 For more information see our [tutorial](tutorial/tutorial.html).
 
-### Optional dependencies
+### Optional Dependencies
 
 Libigl compartmentalizes its **optional** dependences via its directory
 organization in the `include/` folder. All header files located _directly_ in
 the `include/igl/` folder have only stl and Eigen as dependencies. For example,
-all of the headers that depend on CGAL are located in `include/igl/cgal`. For a
-full list of _optional_ dependencies check `optional/CMakeLists.txt`.
+all of the headers that depend on CGAL are located in `include/igl/copyleft/cgal`.
+For a full list of _optional_ dependencies check `optional/CMakeLists.txt`.
 
-### GCC and the optional CGAL dependency
-The `include/igl/cgal/*.h` headers depend on CGAL. It has come to our attention
-that CGAL does not work properly with GCC 4.8. To the best of our knowledge,
-GCC 4.7 and clang will work correctly.
+### GCC and the Optional CGAL Dependency
+The `include/igl/copyleft/cgal/*.h` headers depend on CGAL. It has come to
+our attention that CGAL does not work properly with GCC 4.8. To the best of
+our knowledge, GCC 4.7 and clang will work correctly.
 
 ### OpenMP and Windows
 Some of our functions will take advantage of OpenMP if available. However, it
@@ -162,16 +166,16 @@ git pull
 git submodule update --recursive
 ```
 
-## Unit testing
+## Unit Testing
 
 Libigl maintains [separate
 repository](https://github.com/libigl/libigl-unit-tests) for unit testing.
 
-## How to contribute
+## How to Contribute
 
 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.
+with your changes. libigl follows strict coding guidelines, please take a look at our  [style guidelines](style-guidelines.html) before submitting your pull requests.
 
 ## License
 libigl is primarily [MPL2](http://www.mozilla.org/MPL/2.0/) licensed
@@ -203,9 +207,12 @@ few labs/companies/institutions using libigl:
  - [Electronic Arts, Inc](http://www.ea.com)
  - [Epic Games](https://epicgames.com)
  - [Google Research](https://research.google.com)
- - [Mesh](http://meshconsultants.ca/), consultants, Canada
- - [Pixar Research](http://graphics.pixar.com/research/)
+ - [Industrial Light and Magic](http://ilm.com)
+ - [Mesh consultants](http://meshconsultants.ca/), Canada
+ - [Microsoft Research](https://www.microsoft.com/en-us/research/)
+ - [Pixar](http://graphics.pixar.com/research/)
  - [Spine by Esoteric Software](http://esotericsoftware.com/) is an animation tool dedicated to 2D characters.
+ - [vvvv toolkit](http://vvvv.org) a multipurpose tookit
  - Columbia University, [Columbia Computer Graphics Group](http://www.cs.columbia.edu/cg/), USA
  - [Cornell University](http://www.graphics.cornell.edu/), USA
  - [Czech Technical University in Prague](http://dcgi.felk.cvut.cz/), Czech
@@ -255,8 +262,6 @@ If you find bugs or have problems please use our [github issue tracking
 page](https://github.com/libigl/libigl/issues).
 
 ## Copyright
-2016 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
-Zhou, Sebastian Koch, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
-Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.
+2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan Zhou, Sebastian Koch, Jeremie Dumas, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.
 
 Please see individual files for appropriate copyright notices.

+ 62 - 0
coding-guidelines.html

@@ -0,0 +1,62 @@
+<!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="libiglcodingtipsakahowtocodeasiggraphproject">Libigl Coding Tips (aka &#8220;How to code a SIGGRAPH project&#8221;)</h1>
+
+<p>This is a short list of coding tips that will greatly reduce your pain and suffering before (and after) the SIGGRAPH deadline.</p>
+
+<h3 id="1.serializeitall">1. Serialize it all</h3>
+
+<p>The entire state of your application should be serializable, i.e. It should be possible to save it into a binary file and reload it at any point. This drastically simplifies debugging, since you can serialize just before a crash happens and debug from that point without running your complete algorithm again. Serializing all results shown in the paper&#8217;s figures enables quicker editing iterations before (and after) the deadline. It also allows you to share your results with others that wish to compare with your method. An additional tip is to serialize the state of the application on the window close event and automatically reload it when you launch it again.</p>
+
+<h3 id="2.alwaysassert">2. Always assert</h3>
+
+<p>Even if you know what you are doing, always assert, you will be surprised. Assertion is a powerful but underused feature available in all programming languages. It is essential for writing research code since often you will have to implement algorithms that turns out to not be doing what you expect: in these cases it is important to know if the algorithm is flawed or if there is a bug in your implementation. Discarding a good idea because of a coding bug is frustrating and unfortunately common. Assertion is an ideal way to reduce the chances of introducing bugs in your code and, differently from unit testing, requires a very minor programming effort. You should use them extensively.</p>
+
+<h3 id="3.ploteverything">3. Plot everything</h3>
+
+<p>If you can visually plot the results or some intermediate steps of your algorithm, do it, even if you think your implementation is correct! It is a lot easier to find bugs or to get an intuition on an algorithm by looking at a plot than by looking at the code.</p>
+
+<h3 id="4.ifthecompilationtimeafteracodechangeismorethanfivesecondsyouaredoingitwrong">4. If the compilation time after a code change is more than five seconds, you are doing it wrong</h3>
+
+<p>You will change your code hundreds of times every day for months. Let&#8217;s say that you will change it a hundred times a day (which is a very conservative estimate): if the compilation takes one minute, you will waste almost two hours every day, just waiting! What is even worse, is that since it is only 1&#8211;2 minutes at a time, it will not even be sufficient to prepare a coffee. Spend the hour or two that is needed to get your code to compile in a few seconds, you will benefit from it in the same day already, and the time saved over an entire project will be gigantic.</p>
+
+<h3 id="5.commitoftenandwithameaningfuldescription">5. Commit often (and with a meaningful description)</h3>
+
+<p>Use a distributed version control system (git,hg), and keep the repository on a remote host. Commit often and put meaningful comments. This will serve you as an emergency backup and it will always allow you to have a running version of your code whenever your advisor is passing by and asking to see some results. She will be impressed and you will not have to quickly fix your build with your boss breathing down your neck.</p>
+
+<h3 id="6.dependenciesareevilavoidthem">6. Dependencies are evil, avoid them</h3>
+
+<p>Keep your code simple and with minimal external dependencies. Spending a day or two to code something from scratch while avoiding to use third party code is usually an investment that pays off. The more code you have in your algorithm that is not written by you, the harder debugging becomes. In particular, refrain from building your entire project on code that you do not understand to avoid bad surprises just before the deadline. If you must use code written by others, spend the time that is needed to fully understand what it does, and link it statically so that it will be easy to place breakpoints inside it.</p>
+
+<h3 id="7.globalvariablesarenotevilusethem">7. Global variables are not evil, use them</h3>
+
+<p>Global variables are often extremely useful &#8212; if you think you need one, use it. They are indeed dangerous for large projects, but you are not coding one of those, you are coding a prototype to test a research idea. I suggest to keep one single copy of your entire application state in a global variable (or a singleton class) that can be serialized (see tip 1). This variable should include everything rendered on screen and all the temporary data produced by your algorithm. This will allow you to easily access all the data in your project for plotting or debugging purposes.</p>
+
+<h3 id="8.prototypefirst">8. Prototype first</h3>
+
+<p>Don’t preemptively optimize and try to quickly write code that is clean and correct. It is common to try multiple different approaches to solve a new problem before finding the right one. This means that the majority of the code that you will write will not be used at the end of the project. While you should still write high-quality and bug-free code to make sure that your results is correct, you definitely do not want to spend time optimizing it before you are sure that is the right approach. In particular, it is helpful to learn a good prototyping language (Python, matlab) and use it for the early stages of the project and switch to (or mix it with) c++ only after finding a promising direction.</p>
+
+<h3 id="9.avoidexplicitpointers">9. Avoid explicit pointers</h3>
+
+<p>Do yourself a favor, do not use explicit pointers. If you use a language that supports explicit pointers, use them only if you really have to. And even in that case, keep them isolated in a single file and be very careful with them. Writing data inside another variable by accident might not trigger a crash, and simply produce strange artifacts that might convince you that a promising research direction does not work, while the problem lies in a nasty bug in your code. There is no reason to take that risk during prototyping, just avoid them and leave them for the end of the project in case they become necessary to optimize your code.</p>
+
+<h3 id="10.ifyourprogramcrashesfixitnow">10. If your program crashes, fix it now!</h3>
+
+<p>If your program crashes, don&#8217;t close your eyes and move on. Try to make it happen again, debug it and fix it immediately. These bugs are a nightmare to find, and the more code you add on top of a bug will just make it harder to find. If you don&#8217;t fix it, due to Murphy&#8217;s law, it will start to be problematic only a few days before the deadline and you will have no time to fix it at that point.</p>
+
+<p><em>Daniele Panozzo</em></p>
+
+</body>
+</html>

+ 42 - 0
coding-guidelines.md

@@ -0,0 +1,42 @@
+# Libigl Coding Tips (aka "How to code a SIGGRAPH project")
+
+This is a short list of coding tips that will greatly reduce your pain and suffering before (and after) the SIGGRAPH deadline.
+
+
+### 1. Serialize it all
+The entire state of your application should be serializable, i.e. It should be possible to save it into a binary file and reload it at any point. This drastically simplifies debugging, since you can serialize just before a crash happens and debug from that point without running your complete algorithm again. Serializing all results shown in the paper's figures enables quicker editing iterations before (and after) the deadline. It also allows you to share your results with others that wish to compare with your method. An additional tip is to serialize the state of the application on the window close event and automatically reload it when you launch it again.
+
+### 2. Always assert
+Even if you know what you are doing, always assert, you will be surprised. Assertion is a powerful but underused feature available in all programming languages. It is essential for writing research code since often you will have to implement algorithms that turns out to not be doing what you expect: in these cases it is important to know if the algorithm is flawed or if there is a bug in your implementation. Discarding a good idea  because of a coding bug is frustrating and unfortunately common. Assertion is an ideal way to reduce the chances of introducing bugs in your code and, differently from unit testing, requires a very minor programming effort. You should use them extensively.
+
+### 3. Plot everything
+
+If you can visually plot the results or some intermediate steps of your algorithm, do it, even if you think your implementation is correct! It is a lot easier to find bugs or to get an intuition on an algorithm by looking at a plot than by looking at the code.
+
+### 4. If the compilation time after a code change is more than five seconds, you are doing it wrong
+
+You will change your code hundreds of times every day for months. Let's say that you will change it a hundred times a day (which is a  very conservative estimate): if the compilation takes one minute, you will waste almost two hours every day, just waiting! What is even worse, is that since it is only 1-2 minutes at a time, it will not even be sufficient to prepare a coffee. Spend the hour or two that is needed to get your code to compile in a few seconds, you will benefit from it in the same day already, and the time saved over an entire project will be gigantic.
+
+### 5. Commit often (and with a meaningful description)
+
+Use a distributed version control system (git,hg), and keep the repository on a remote host. Commit often and put meaningful comments. This will serve you as an emergency backup and it will always allow you to have a running version of your code whenever your advisor is passing by and asking to see some results. She will be impressed and you will not have to quickly fix your build with your boss breathing down your neck.
+
+### 6. Dependencies are evil, avoid them
+
+Keep your code simple and with minimal external dependencies. Spending a day or two to code something from scratch while avoiding to use third party code is usually an investment that pays off. The more code you have in your algorithm that is not written by you, the harder debugging becomes. In particular, refrain from building your entire project on code that you do not understand to avoid bad surprises just before the deadline. If you must use code written by others, spend the time that is needed to fully understand what it does, and link it statically so that it will be easy to place breakpoints inside it.
+
+### 7. Global variables are not evil, use them
+
+Global variables are often extremely useful --- if you think you need one, use it. They are indeed dangerous for large projects, but you are not coding one of those, you are coding a prototype to test a research idea. I suggest to keep one single copy of your entire application state in a global variable (or a singleton class) that can be serialized (see tip 1). This variable should include everything rendered on screen and all the temporary data produced by your algorithm. This will allow you to easily access all the data in your project for plotting or debugging purposes.
+
+### 8. Prototype first
+Don’t preemptively optimize and try to quickly write code that is clean and correct. It is common to try multiple different approaches to solve a new problem before finding the right one. This means that the majority of the code that you will write will not be used at the end of the project. While you should still write high-quality and bug-free code to make sure that your results is correct, you definitely do not want to spend time optimizing it before you are sure that is the right approach. In particular, it is helpful to learn a good prototyping language (Python, matlab) and use it for the early stages of the project and switch to (or mix it with) c++ only after finding a promising direction.
+
+### 9. Avoid explicit pointers
+Do yourself a favor, do not use explicit pointers. If you use a language that supports explicit pointers, use them only if you really have to. And even in that case, keep them isolated in a single file and be very careful with them. Writing data inside another variable by accident might not trigger a crash, and simply produce strange artifacts that might convince you that a promising research direction does not work, while the problem lies in a nasty bug in your code. There is no reason to take that risk during prototyping, just avoid them and leave them for the end of the project in case they become necessary to optimize your code.
+
+### 10. If your program crashes, fix it now!
+
+If your program crashes, don't close your eyes and move on. Try to make it happen again, debug it and fix it immediately. These bugs are a nightmare to find, and the more code you add on top of a bug will just make it harder to find. If you don't fix it, due to Murphy's law, it will start to be problematic only a few days before the deadline and you will have no time to fix it at that point.
+
+_Daniele Panozzo_

+ 0 - 15
exclude.lst

@@ -1,15 +0,0 @@
-../libigl/exclude.lst
-../libigl/external/SuperLU*
-../libigl/exclude.lst*
-*.hg*
-*.git*
-*.svn*
-*.DS_Store
-*.un~
-*.swp
-*.swo
-../libigl/obj/*
-*.o
-*.a
-*.lib
-*.bb

+ 192 - 90
include/igl/AABB.cpp

@@ -8,7 +8,6 @@
 #include "AABB.h"
 #include "EPS.h"
 #include "barycenter.h"
-#include "barycentric_coordinates.h"
 #include "colon.h"
 #include "doublearea.h"
 #include "point_simplex_squared_distance.h"
@@ -25,13 +24,13 @@
 #include <stack>
 
 template <typename DerivedV, int DIM>
-  template <typename Derivedbb_mins, typename Derivedbb_maxs>
+template <typename DerivedEle, typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
     const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixXi & Ele, 
+    const Eigen::MatrixBase<DerivedEle> & Ele, 
     const Eigen::MatrixBase<Derivedbb_mins> & bb_mins,
     const Eigen::MatrixBase<Derivedbb_maxs> & bb_maxs,
-    const Eigen::VectorXi & elements,
+    const Eigen::MatrixBase<Derivedelements> & elements,
     const int i)
 {
   using namespace std;
@@ -89,10 +88,11 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
   }
 }
 
-  template <typename DerivedV, int DIM>
+template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 void igl::AABB<DerivedV,DIM>::init(
     const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixXi & Ele)
+    const Eigen::MatrixBase<DerivedEle> & Ele)
 {
   using namespace Eigen;
   // deinit will be immediately called...
@@ -100,11 +100,15 @@ void igl::AABB<DerivedV,DIM>::init(
 }
 
   template <typename DerivedV, int DIM>
+template <
+  typename DerivedEle,
+  typename DerivedSI,
+  typename DerivedI>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::init(
     const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixXi & Ele, 
-    const Eigen::MatrixXi & SI,
-    const Eigen::VectorXi & I)
+    const Eigen::MatrixBase<DerivedEle> & Ele, 
+    const Eigen::MatrixBase<DerivedSI> & SI,
+    const Eigen::MatrixBase<DerivedI> & I)
 {
   using namespace Eigen;
   using namespace std;
@@ -197,10 +201,10 @@ IGL_INLINE bool igl::AABB<DerivedV,DIM>::is_leaf() const
 }
 
 template <typename DerivedV, int DIM>
-template <typename Derivedq>
+template <typename DerivedEle, typename Derivedq>
 IGL_INLINE std::vector<int> igl::AABB<DerivedV,DIM>::find(
     const Eigen::MatrixBase<DerivedV> & V,
-    const Eigen::MatrixXi & Ele, 
+    const Eigen::MatrixBase<DerivedEle> & Ele, 
     const Eigen::MatrixBase<Derivedq> & q,
     const bool first) const
 {
@@ -307,11 +311,11 @@ IGL_INLINE int igl::AABB<DerivedV,DIM>::subtree_size() const
 
 
 template <typename DerivedV, int DIM>
-template <typename Derivedbb_mins, typename Derivedbb_maxs>
+template <typename Derivedbb_mins, typename Derivedbb_maxs, typename Derivedelements>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::serialize(
     Eigen::PlainObjectBase<Derivedbb_mins> & bb_mins,
     Eigen::PlainObjectBase<Derivedbb_maxs> & bb_maxs,
-    Eigen::VectorXi & elements,
+    Eigen::PlainObjectBase<Derivedelements> & elements,
     const int i) const
 {
   using namespace std;
@@ -340,31 +344,39 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::serialize(
 }
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar 
 igl::AABB<DerivedV,DIM>::squared_distance(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & p,
   int & i,
-  RowVectorDIMS & c) const
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
 {
   return squared_distance(V,Ele,p,std::numeric_limits<Scalar>::infinity(),i,c);
 }
 
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar 
 igl::AABB<DerivedV,DIM>::squared_distance(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & p,
-  Scalar min_sqr_d,
+  Scalar low_sqr_d,
+  Scalar up_sqr_d,
   int & i,
-  RowVectorDIMS & c) const
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
 {
   using namespace Eigen;
   using namespace std;
-  Scalar sqr_d = min_sqr_d;
+  //assert(low_sqr_d <= up_sqr_d);
+  if(low_sqr_d > up_sqr_d)
+  {
+    return low_sqr_d;
+  }
+  Scalar sqr_d = up_sqr_d;
   //assert(DIM == 3 && "Code has only been tested for DIM == 3");
   assert((Ele.cols() == 3 || Ele.cols() == 2 || Ele.cols() == 1)
     && "Code has only been tested for simplex sizes 3,2,1");
@@ -372,7 +384,7 @@ igl::AABB<DerivedV,DIM>::squared_distance(
   assert(m_primitive==-1 || (m_left == NULL && m_right == NULL));
   if(is_leaf())
   {
-    leaf_squared_distance(V,Ele,p,sqr_d,i,c);
+    leaf_squared_distance(V,Ele,p,low_sqr_d,sqr_d,i,c);
   }else
   {
     bool looked_left = false;
@@ -381,16 +393,17 @@ igl::AABB<DerivedV,DIM>::squared_distance(
     {
       int i_left;
       RowVectorDIMS c_left = c;
-      Scalar sqr_d_left = m_left->squared_distance(V,Ele,p,sqr_d,i_left,c_left);
+      Scalar sqr_d_left = 
+        m_left->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_left,c_left);
       this->set_min(p,sqr_d_left,i_left,c_left,sqr_d,i,c);
       looked_left = true;
     };
     const auto & look_right = [&]()
     {
       int i_right;
-      RowVectorDIMS c_right = c;
+      Eigen::PlainObjectBase<RowVectorDIMS> c_right = c;
       Scalar sqr_d_right = 
-        m_right->squared_distance(V,Ele,p,sqr_d,i_right,c_right);
+        m_right->squared_distance(V,Ele,p,low_sqr_d,sqr_d,i_right,c_right);
       this->set_min(p,sqr_d_right,i_right,c_right,sqr_d,i,c);
       looked_right = true;
     };
@@ -405,27 +418,27 @@ igl::AABB<DerivedV,DIM>::squared_distance(
       look_right();
     }
     // if haven't looked left and could be less than current min, then look
-    Scalar left_min_sqr_d = 
+    Scalar left_up_sqr_d = 
       m_left->m_box.squaredExteriorDistance(p.transpose());
-    Scalar right_min_sqr_d = 
+    Scalar right_up_sqr_d = 
       m_right->m_box.squaredExteriorDistance(p.transpose());
-    if(left_min_sqr_d < right_min_sqr_d)
+    if(left_up_sqr_d < right_up_sqr_d)
     {
-      if(!looked_left && left_min_sqr_d<sqr_d)
+      if(!looked_left && left_up_sqr_d<sqr_d)
       {
         look_left();
       }
-      if( !looked_right && right_min_sqr_d<sqr_d)
+      if( !looked_right && right_up_sqr_d<sqr_d)
       {
         look_right();
       }
     }else
     {
-      if( !looked_right && right_min_sqr_d<sqr_d)
+      if( !looked_right && right_up_sqr_d<sqr_d)
       {
         look_right();
       }
-      if(!looked_left && left_min_sqr_d<sqr_d)
+      if(!looked_left && left_up_sqr_d<sqr_d)
       {
         look_left();
       }
@@ -434,15 +447,30 @@ igl::AABB<DerivedV,DIM>::squared_distance(
   return sqr_d;
 }
 
+template <typename DerivedV, int DIM>
+template <typename DerivedEle>
+IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar 
+igl::AABB<DerivedV,DIM>::squared_distance(
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
+  const RowVectorDIMS & p,
+  Scalar up_sqr_d,
+  int & i,
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
+{
+  return squared_distance(V,Ele,p,0.0,up_sqr_d,i,c);
+}
+
 template <typename DerivedV, int DIM>
 template <
+  typename DerivedEle,
   typename DerivedP, 
   typename DerivedsqrD, 
   typename DerivedI, 
   typename DerivedC>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const Eigen::MatrixBase<DerivedP> & P,
   Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
   Eigen::PlainObjectBase<DerivedI> & I,
@@ -466,16 +494,18 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
 
 template <typename DerivedV, int DIM>
 template < 
+  typename DerivedEle,
   typename Derivedother_V,
+  typename Derivedother_Ele,
   typename DerivedsqrD, 
   typename DerivedI, 
   typename DerivedC>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const AABB<Derivedother_V,DIM> & other,
   const Eigen::MatrixBase<Derivedother_V> & other_V,
-  const Eigen::MatrixXi & other_Ele, 
+  const Eigen::MatrixBase<Derivedother_Ele> & other_Ele, 
   Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
   Eigen::PlainObjectBase<DerivedI> & I,
   Eigen::PlainObjectBase<DerivedC> & C) const
@@ -492,25 +522,27 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::squared_distance(
 
   // This holds a conservative estimate of max(sqr_D) where sqr_D is the
   // current best minimum squared distance for all points in this subtree
-  double min_sqr_d = std::numeric_limits<double>::infinity();
+  double up_sqr_d = std::numeric_limits<double>::infinity();
   squared_distance_helper(
-    V,Ele,&other,other_V,other_Ele,min_sqr_d,sqrD,I,C);
+    V,Ele,&other,other_V,other_Ele,0,up_sqr_d,sqrD,I,C);
 }
 
 template <typename DerivedV, int DIM>
 template < 
+  typename DerivedEle,
   typename Derivedother_V,
+  typename Derivedother_Ele,
   typename DerivedsqrD, 
   typename DerivedI, 
   typename DerivedC>
 IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar 
   igl::AABB<DerivedV,DIM>::squared_distance_helper(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const AABB<Derivedother_V,DIM> * other,
   const Eigen::MatrixBase<Derivedother_V> & other_V,
-  const Eigen::MatrixXi & other_Ele, 
-  const Scalar /*min_sqr_d*/,
+  const Eigen::MatrixBase<Derivedother_Ele> & other_Ele, 
+  const Scalar /*up_sqr_d*/,
   Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
   Eigen::PlainObjectBase<DerivedI> & I,
   Eigen::PlainObjectBase<DerivedC> & C) const
@@ -534,7 +566,7 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
     I(    other->m_primitive) = i;
     C.row(other->m_primitive) = c;
     //cout<<"leaf: "<<sqr_d<<endl;
-    //other->m_max_sqr_d = sqr_d;
+    //other->m_low_sqr_d = sqr_d;
     return sqr_d;
   }
 
@@ -548,7 +580,7 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
     sqrD( other->m_primitive) = sqr_d;
     I(    other->m_primitive) = i;
     C.row(other->m_primitive) = c;
-    //other->m_max_sqr_d = sqr_d;
+    //other->m_low_sqr_d = sqr_d;
     return sqr_d;
   }
 
@@ -563,7 +595,7 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
 
   if(this->is_leaf())
   {
-    //if(min_squared_distance(this,other) < other->m_max_sqr_d)
+    //if(min_squared_distance(this,other) < other->m_low_sqr_d)
     if(true)
     {
       this->squared_distance_helper(
@@ -575,12 +607,12 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
       // This is never reached...
     }
     //// we know other is not a leaf
-    //other->m_max_sqr_d = std::max(other->m_left->m_max_sqr_d,other->m_right->m_max_sqr_d);
+    //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
     return 0;
   }
 
   // FORCE DOWN TO OTHER LEAF EVAL
-  //if(min_squared_distance(this,other) < other->m_max_sqr_d)
+  //if(min_squared_distance(this,other) < other->m_low_sqr_d)
   if(true)
   {
     if(true)
@@ -601,7 +633,7 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
     // this is never reached ... :-(
   }
   //// we know other is not a leaf
-  //other->m_max_sqr_d = std::max(other->m_left->m_max_sqr_d,other->m_right->m_max_sqr_d);
+  //other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
 
   return 0;
 #if 0 // False
@@ -655,90 +687,97 @@ IGL_INLINE typename igl::AABB<DerivedV,DIM>::Scalar
 
   //const std::function<Scalar(
   //  const AABB<Derivedother_V,DIM> * other)
-  //    > max_sqr_d = [&sqrD,&max_sqr_d](const AABB<Derivedother_V,DIM> * other)->Scalar
+  //    > low_sqr_d = [&sqrD,&low_sqr_d](const AABB<Derivedother_V,DIM> * other)->Scalar
   //  {
   //    if(other->is_leaf())
   //    {
   //      return sqrD(other->m_primitive);
   //    }else
   //    {
-  //      return std::max(max_sqr_d(other->m_left),max_sqr_d(other->m_right));
+  //      return std::max(low_sqr_d(other->m_left),low_sqr_d(other->m_right));
   //    }
   //  };
 
   //// Potentially recurse on all pairs, if minimum distance is less than running
   //// bound
-  //Eigen::Matrix<Scalar,Eigen::Dynamic,1> other_max_sqr_d =
-  //  Eigen::Matrix<Scalar,Eigen::Dynamic,1>::Constant(other_list.size(),1,min_sqr_d);
+  //Eigen::Matrix<Scalar,Eigen::Dynamic,1> other_low_sqr_d =
+  //  Eigen::Matrix<Scalar,Eigen::Dynamic,1>::Constant(other_list.size(),1,up_sqr_d);
   for(size_t child = 0;child<other_list.size();child++)
   {
     auto other_tree = other_list[child];
 
-    Eigen::Matrix<Scalar,Eigen::Dynamic,1> this_max_sqr_d(this_list.size(),1);
+    Eigen::Matrix<Scalar,Eigen::Dynamic,1> this_low_sqr_d(this_list.size(),1);
     for(size_t t = 0;t<this_list.size();t++)
     {
       const auto this_tree = this_list[t];
-      this_max_sqr_d(t) = max_squared_distance(this_tree,other_tree);
+      this_low_sqr_d(t) = max_squared_distance(this_tree,other_tree);
     }
     if(this_list.size() ==2 &&
-      ( this_max_sqr_d(0) > this_max_sqr_d(1))
+      ( this_low_sqr_d(0) > this_low_sqr_d(1))
       )
     {
       std::swap(this_list[0],this_list[1]);
-      //std::swap(this_max_sqr_d(0),this_max_sqr_d(1));
+      //std::swap(this_low_sqr_d(0),this_low_sqr_d(1));
     }
-    const Scalar sqr_d = this_max_sqr_d.minCoeff();
+    const Scalar sqr_d = this_low_sqr_d.minCoeff();
 
 
     for(size_t t = 0;t<this_list.size();t++)
     {
       const auto this_tree = this_list[t];
 
-      //const auto mm = max_sqr_d(other_tree);
-      //const Scalar mc = other_max_sqr_d(child);
+      //const auto mm = low_sqr_d(other_tree);
+      //const Scalar mc = other_low_sqr_d(child);
       //assert(mc == mm);
       // Only look left/right in this_list if can possible decrease somebody's
       // distance in this_tree.
       const Scalar min_this_other = min_squared_distance(this_tree,other_tree); 
       if(
           min_this_other < sqr_d && 
-          min_this_other < other_tree->m_max_sqr_d)
+          min_this_other < other_tree->m_low_sqr_d)
       {
-        //cout<<"before: "<<other_max_sqr_d(child)<<endl;
-        //other_max_sqr_d(child) = std::min(
-        //  other_max_sqr_d(child),
+        //cout<<"before: "<<other_low_sqr_d(child)<<endl;
+        //other_low_sqr_d(child) = std::min(
+        //  other_low_sqr_d(child),
         //  this_tree->squared_distance_helper(
-        //    V,Ele,other_tree,other_V,other_Ele,other_max_sqr_d(child),sqrD,I,C));
-        //cout<<"after: "<<other_max_sqr_d(child)<<endl;
+        //    V,Ele,other_tree,other_V,other_Ele,other_low_sqr_d(child),sqrD,I,C));
+        //cout<<"after: "<<other_low_sqr_d(child)<<endl;
           this_tree->squared_distance_helper(
             V,Ele,other_tree,other_V,other_Ele,0,sqrD,I,C);
       }
     }
   }
-  //const Scalar ret = other_max_sqr_d.maxCoeff();
-  //const auto mm = max_sqr_d(other);
+  //const Scalar ret = other_low_sqr_d.maxCoeff();
+  //const auto mm = low_sqr_d(other);
   //assert(mm == ret);
   //cout<<"non-leaf: "<<ret<<endl;
   //return ret;
   if(!other->is_leaf())
   {
-    other->m_max_sqr_d = std::max(other->m_left->m_max_sqr_d,other->m_right->m_max_sqr_d);
+    other->m_low_sqr_d = std::max(other->m_left->m_low_sqr_d,other->m_right->m_low_sqr_d);
   }
   return 0;
 #endif
 }
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & p,
+  const Scalar low_sqr_d,
   Scalar & sqr_d,
   int & i,
-  RowVectorDIMS & c) const
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
 {
   using namespace Eigen;
   using namespace std;
+  if(low_sqr_d > sqr_d)
+  {
+    sqr_d = low_sqr_d;
+    return;
+  }
   RowVectorDIMS c_candidate;
   Scalar sqr_d_candidate;
   igl::point_simplex_squared_distance<DIM>(
@@ -746,6 +785,19 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
   set_min(p,sqr_d_candidate,m_primitive,c_candidate,sqr_d,i,c);
 }
 
+template <typename DerivedV, int DIM>
+template <typename DerivedEle>
+IGL_INLINE void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
+  const RowVectorDIMS & p,
+  Scalar & sqr_d,
+  int & i,
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
+{
+  return leaf_squared_distance(V,Ele,p,0,sqr_d,i,c);
+}
+
 
 template <typename DerivedV, int DIM>
 IGL_INLINE void igl::AABB<DerivedV,DIM>::set_min(
@@ -759,13 +811,14 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::set_min(
   const RowVectorDIMS & c_candidate,
   Scalar & sqr_d,
   int & i,
-  RowVectorDIMS & c) const
+  Eigen::PlainObjectBase<RowVectorDIMS> & c) const
 {
 #ifndef NDEBUG
   //std::cout<<matlab_format(c_candidate,"c_candidate")<<std::endl;
-  const Scalar pc_norm = (p-c_candidate).squaredNorm();
-  const Scalar diff = fabs(sqr_d_candidate - pc_norm);
-  assert(diff<=1e-10 && "distance should match norm of difference");
+  //// This doesn't quite make sense to check with bounds
+  // const Scalar pc_norm = (p-c_candidate).squaredNorm();
+  // const Scalar diff = fabs(sqr_d_candidate - pc_norm);
+  // assert(diff<=1e-10 && "distance should match norm of difference");
 #endif
   if(sqr_d_candidate < sqr_d)
   {
@@ -777,10 +830,11 @@ IGL_INLINE void igl::AABB<DerivedV,DIM>::set_min(
 
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE bool 
 igl::AABB<DerivedV,DIM>::intersect_ray(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & origin,
   const RowVectorDIMS & dir,
   std::vector<igl::Hit> & hits) const
@@ -819,10 +873,11 @@ igl::AABB<DerivedV,DIM>::intersect_ray(
 }
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE bool 
 igl::AABB<DerivedV,DIM>::intersect_ray(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & origin,
   const RowVectorDIMS & dir,
   igl::Hit & hit) const
@@ -876,10 +931,11 @@ igl::AABB<DerivedV,DIM>::intersect_ray(
 }
 
 template <typename DerivedV, int DIM>
+template <typename DerivedEle>
 IGL_INLINE bool 
 igl::AABB<DerivedV,DIM>::intersect_ray(
   const Eigen::MatrixBase<DerivedV> & V,
-  const Eigen::MatrixXi & Ele, 
+  const Eigen::MatrixBase<DerivedEle> & Ele, 
   const RowVectorDIMS & origin,
   const RowVectorDIMS & dir,
   const Scalar _min_t,
@@ -943,23 +999,69 @@ igl::AABB<DerivedV,DIM>::intersect_ray(
   return left_ret || right_ret;
 }
 
+// This is a bullshit template because AABB annoyingly needs templates for bad
+// combinations of 3D V with DIM=2 AABB
+// 
+// _Define_ as a no-op rather than monkeying around with the proper code above
+//
+// Meanwhile, GCC seems to have a bug. Let's see if GCC likes using explicit
+// namespace block instead. https://stackoverflow.com/a/25594681/148668
+namespace igl
+{
+  template<> template<> IGL_INLINE float AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
+  template<> template<> IGL_INLINE float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
+  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 2>::init (Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&) { assert(false);};
+  template<> template<> IGL_INLINE double AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
+  template<> template<> IGL_INLINE double igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::squared_distance( Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
+  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 2>::init (Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&) { assert(false);};
+  template<> template<> IGL_INLINE void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 2>::init(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&) {assert(false);};
+  template<> template<> IGL_INLINE float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 2>::squared_distance(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 2, 1, 1, 2> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) const { assert(false);return -1;};
+}
+
+
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, int);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, int) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, int);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, int) const;
-
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::Matrix<double, 1, 2, 1, 1, 2>&) const;
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::Matrix<double, 1, 3, 1, 1, 3>&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&);
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
+// generated by autoexplicit.sh
+// generated by autoexplicit.sh
+template float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
+// generated by autoexplicit.sh
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
+// generated by autoexplicit.sh
+template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
+// generated by autoexplicit.sh
+template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
+// generated by autoexplicit.sh
+template float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+// generated by autoexplicit.sh
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+// generated by autoexplicit.sh
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
 #endif

+ 78 - 35
include/igl/AABB.h

@@ -36,12 +36,12 @@ public:
       Eigen::AlignedBox<Scalar,DIM> m_box;
       // -1 non-leaf
       int m_primitive;
-      //Scalar m_max_sqr_d;
+      //Scalar m_low_sqr_d;
       //int m_depth;
       AABB():
         m_left(NULL), m_right(NULL),
         m_box(), m_primitive(-1)
-        //m_max_sqr_d(std::numeric_limits<double>::infinity()),
+        //m_low_sqr_d(std::numeric_limits<double>::infinity()),
         //m_depth(0)
     {}
       // http://stackoverflow.com/a/3279550/148668
@@ -50,7 +50,7 @@ public:
         m_right(other.m_right ? new AABB(*other.m_right) : NULL),
         m_box(other.m_box),
         m_primitive(other.m_primitive)
-        //m_max_sqr_d(other.m_max_sqr_d),
+        //m_low_sqr_d(other.m_low_sqr_d),
         //m_depth(std::max(
         //   m_left ? m_left->m_depth + 1 : 0,
         //   m_right ? m_right->m_depth + 1 : 0))
@@ -65,7 +65,7 @@ public:
         swap(first.m_right,second.m_right);
         swap(first.m_box,second.m_box);
         swap(first.m_primitive,second.m_primitive);
-        //swap(first.m_max_sqr_d,second.m_max_sqr_d);
+        //swap(first.m_low_sqr_d,second.m_low_sqr_d);
         //swap(first.m_depth,second.m_depth);
       }
       // Pass-by-value (aka copy)
@@ -105,18 +105,23 @@ public:
       //   bb_maxs  max_tree by dim list of bounding box max corner positions
       //   elements  max_tree list of element or (not leaf id) indices into Ele
       //   i  recursive call index {0}
-      template <typename Derivedbb_mins, typename Derivedbb_maxs>
+      template <
+        typename DerivedEle, 
+        typename Derivedbb_mins, 
+        typename Derivedbb_maxs,
+        typename Derivedelements>
         IGL_INLINE void init(
             const Eigen::MatrixBase<DerivedV> & V,
-            const Eigen::MatrixXi & Ele, 
+            const Eigen::MatrixBase<DerivedEle> & Ele, 
             const Eigen::MatrixBase<Derivedbb_mins> & bb_mins,
             const Eigen::MatrixBase<Derivedbb_maxs> & bb_maxs,
-            const Eigen::VectorXi & elements,
+            const Eigen::MatrixBase<Derivedelements> & elements,
             const int i = 0);
       // Wrapper for root with empty serialization
+      template <typename DerivedEle>
       IGL_INLINE void init(
           const Eigen::MatrixBase<DerivedV> & V,
-          const Eigen::MatrixXi & Ele);
+          const Eigen::MatrixBase<DerivedEle> & Ele);
       // Build an Axis-Aligned Bounding Box tree for a given mesh.
       //
       // Inputs:
@@ -129,11 +134,12 @@ public:
       //   I  #I list of indices into Ele of elements to include (for recursive
       //     calls)
       // 
+      template <typename DerivedEle, typename DerivedSI, typename DerivedI>
       IGL_INLINE void init(
           const Eigen::MatrixBase<DerivedV> & V,
-          const Eigen::MatrixXi & Ele, 
-          const Eigen::MatrixXi & SI,
-          const Eigen::VectorXi & I);
+          const Eigen::MatrixBase<DerivedEle> & Ele, 
+          const Eigen::MatrixBase<DerivedSI> & SI,
+          const Eigen::MatrixBase<DerivedI>& I);
       // Return whether at leaf node
       IGL_INLINE bool is_leaf() const;
       // Find the indices of elements containing given point: this makes sense
@@ -148,10 +154,10 @@ public:
       //   first  whether to only return first element containing q
       // Returns:
       //   list of indices of elements containing q
-      template <typename Derivedq>
+      template <typename DerivedEle, typename Derivedq>
       IGL_INLINE std::vector<int> find(
           const Eigen::MatrixBase<DerivedV> & V,
-          const Eigen::MatrixXi & Ele, 
+          const Eigen::MatrixBase<DerivedEle> & Ele, 
           const Eigen::MatrixBase<Derivedq> & q,
           const bool first=false) const;
 
@@ -166,11 +172,14 @@ public:
       //   bb_maxs  max_tree by dim list of bounding box max corner positions
       //   elements  max_tree list of element or (not leaf id) indices into Ele
       //   i  recursive call index into these arrays {0}
-      template <typename Derivedbb_mins, typename Derivedbb_maxs>
+      template <
+        typename Derivedbb_mins, 
+        typename Derivedbb_maxs,
+        typename Derivedelements>
         IGL_INLINE void serialize(
             Eigen::PlainObjectBase<Derivedbb_mins> & bb_mins,
             Eigen::PlainObjectBase<Derivedbb_maxs> & bb_maxs,
-            Eigen::VectorXi & elements,
+            Eigen::PlainObjectBase<Derivedelements> & elements,
             const int i = 0) const;
       // Compute squared distance to a query point
       //
@@ -185,12 +194,13 @@ public:
       //
       // Known bugs: currently assumes Elements are triangles regardless of
       // dimension.
+      template <typename DerivedEle>
       IGL_INLINE Scalar squared_distance(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & p,
         int & i,
-        RowVectorDIMS & c) const;
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
 //private:
       // Compute squared distance to a query point
       //
@@ -198,41 +208,58 @@ public:
       //   V  #V by dim list of vertex positions
       //   Ele  #Ele by dim list of simplex indices
       //   p  dim-long query point 
-      //   min_sqr_d  current minimum squared distance (only consider distances
-      //     less than this), see output.
+      //   low_sqr_d  lower bound on squared distance, specified maximum squared
+      //     distance 
+      //   up_sqr_d  current upper bounded on squared distance, current minimum
+      //     squared distance (only consider distances less than this), see
+      //     output.
       // Outputs:
-      //   min_sqr_d  updated current minimum squared distance
+      //   up_sqr_d  updated current minimum squared distance
       //   i  facet index corresponding to smallest distances
       //   c  closest point
       // Returns squared distance
       //
       // Known bugs: currently assumes Elements are triangles regardless of
       // dimension.
+      template <typename DerivedEle>
+      IGL_INLINE Scalar squared_distance(
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
+        const RowVectorDIMS & p,
+        const Scalar low_sqr_d,
+        const Scalar up_sqr_d,
+        int & i,
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
+      // Default low_sqr_d
+      template <typename DerivedEle>
       IGL_INLINE Scalar squared_distance(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & p,
-        const Scalar min_sqr_d,
+        const Scalar up_sqr_d,
         int & i,
-        RowVectorDIMS & c) const;
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
       // All hits
+      template <typename DerivedEle>
       IGL_INLINE bool intersect_ray(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & origin,
         const RowVectorDIMS & dir,
         std::vector<igl::Hit> & hits) const;
       // First hit
+      template <typename DerivedEle>
       IGL_INLINE bool intersect_ray(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & origin,
         const RowVectorDIMS & dir,
         igl::Hit & hit) const;
 //private:
+      template <typename DerivedEle>
       IGL_INLINE bool intersect_ray(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & origin,
         const RowVectorDIMS & dir,
         const Scalar min_t,
@@ -253,13 +280,14 @@ public:
       //   I  #P list of indices into Ele of closest primitives
       //   C  #P by dim list of closest points
       template <
+        typename DerivedEle,
         typename DerivedP, 
         typename DerivedsqrD, 
         typename DerivedI, 
         typename DerivedC>
       IGL_INLINE void squared_distance(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const Eigen::MatrixBase<DerivedP> & P,
         Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
         Eigen::PlainObjectBase<DerivedI> & I,
@@ -281,32 +309,36 @@ public:
       //   I  #P list of indices into Ele of closest primitives
       //   C  #P by dim list of closest points
       template < 
+        typename DerivedEle,
         typename Derivedother_V,
+        typename Derivedother_Ele,
         typename DerivedsqrD, 
         typename DerivedI, 
         typename DerivedC>
       IGL_INLINE void squared_distance(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const AABB<Derivedother_V,DIM> & other,
         const Eigen::MatrixBase<Derivedother_V> & other_V,
-        const Eigen::MatrixXi & other_Ele, 
+        const Eigen::MatrixBase<Derivedother_Ele> & other_Ele, 
         Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
         Eigen::PlainObjectBase<DerivedI> & I,
         Eigen::PlainObjectBase<DerivedC> & C) const;
 private:
       template < 
+        typename DerivedEle,
         typename Derivedother_V,
+        typename Derivedother_Ele,
         typename DerivedsqrD, 
         typename DerivedI, 
         typename DerivedC>
       IGL_INLINE Scalar squared_distance_helper(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const AABB<Derivedother_V,DIM> * other,
         const Eigen::MatrixBase<Derivedother_V> & other_V,
-        const Eigen::MatrixXi & other_Ele, 
-        const Scalar min_sqr_d,
+        const Eigen::MatrixBase<Derivedother_Ele>& other_Ele, 
+        const Scalar up_sqr_d,
         Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
         Eigen::PlainObjectBase<DerivedI> & I,
         Eigen::PlainObjectBase<DerivedC> & C) const;
@@ -325,13 +357,24 @@ private:
       //     primitive
       //   i  possibly updated index into Ele of closest point
       //   c  dim-long possibly updated closest point
+      template <typename DerivedEle>
+      IGL_INLINE void leaf_squared_distance(
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
+        const RowVectorDIMS & p,
+        const Scalar low_sqr_d,
+        Scalar & sqr_d,
+        int & i,
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
+      // Default low_sqr_d
+      template <typename DerivedEle>
       IGL_INLINE void leaf_squared_distance(
         const Eigen::MatrixBase<DerivedV> & V,
-        const Eigen::MatrixXi & Ele, 
+        const Eigen::MatrixBase<DerivedEle> & Ele, 
         const RowVectorDIMS & p,
         Scalar & sqr_d,
         int & i,
-        RowVectorDIMS & c) const;
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
       // If new distance (sqr_d_candidate) is less than current distance
       // (sqr_d), then update this distance and its associated values
       // _in-place_:
@@ -356,7 +399,7 @@ private:
         const RowVectorDIMS & c_candidate,
         Scalar & sqr_d,
         int & i,
-        RowVectorDIMS & c) const;
+        Eigen::PlainObjectBase<RowVectorDIMS> & c) const;
 public:
       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     };

+ 3 - 3
include/igl/HalfEdgeIterator.h

@@ -100,9 +100,9 @@ namespace igl
     bool reverse;
 
     // All the same type? This is likely to break.
-    const DerivedF & F;
-    const DerivedFF & FF;
-    const DerivedFFi & FFi;
+    const Eigen::PlainObjectBase<DerivedF> & F;
+    const Eigen::PlainObjectBase<DerivedFF> & FF;
+    const Eigen::PlainObjectBase<DerivedFFi> & FFi;
   };
 
 }

+ 8 - 2
include/igl/ViewerData.cpp

@@ -346,7 +346,10 @@ IGL_INLINE void igl::ViewerData::compute_normals()
   dirty |= DIRTY_NORMAL;
 }
 
-IGL_INLINE void igl::ViewerData::uniform_colors(Eigen::Vector3d ambient, Eigen::Vector3d diffuse, Eigen::Vector3d specular)
+IGL_INLINE void igl::ViewerData::uniform_colors(
+  const Eigen::Vector3d& ambient, 
+  const Eigen::Vector3d& diffuse, 
+  const Eigen::Vector3d& specular)
 {
   Eigen::Vector4d ambient4;
   Eigen::Vector4d diffuse4;
@@ -359,7 +362,10 @@ IGL_INLINE void igl::ViewerData::uniform_colors(Eigen::Vector3d ambient, Eigen::
   uniform_colors(ambient4,diffuse4,specular4);
 }
 
-IGL_INLINE void igl::ViewerData::uniform_colors(Eigen::Vector4d ambient, Eigen::Vector4d diffuse, Eigen::Vector4d specular)
+IGL_INLINE void igl::ViewerData::uniform_colors(
+  const Eigen::Vector4d& ambient, 
+  const Eigen::Vector4d& diffuse, 
+  const Eigen::Vector4d& specular)
 {
   V_material_ambient.resize(V.rows(),4);
   V_material_diffuse.resize(V.rows(),4);

+ 6 - 6
include/igl/ViewerData.h

@@ -122,15 +122,15 @@ public:
 
   // Assigns uniform colors to all faces/vertices
   IGL_INLINE void uniform_colors(
-    Eigen::Vector3d ambient,
-    Eigen::Vector3d diffuse,
-    Eigen::Vector3d specular);
+    const Eigen::Vector3d& diffuse,
+    const Eigen::Vector3d& ambient,
+    const Eigen::Vector3d& specular);
 
   // Assigns uniform colors to all faces/vertices
   IGL_INLINE void uniform_colors(
-    Eigen::Vector4d ambient,
-    Eigen::Vector4d diffuse,
-    Eigen::Vector4d specular);
+    const Eigen::Vector4d& ambient,
+    const Eigen::Vector4d& diffuse,
+    const Eigen::Vector4d& specular);
 
   // Generates a default grid texture
   IGL_INLINE void grid_texture();

+ 76 - 70
include/igl/WindingNumberAABB.h

@@ -16,13 +16,16 @@
 
 namespace igl
 {
-  template <typename Point>
-  class WindingNumberAABB : public WindingNumberTree<Point>
+  template <
+    typename Point,
+    typename DerivedV, 
+    typename DerivedF >
+  class WindingNumberAABB : public WindingNumberTree<Point,DerivedV,DerivedF>
   {
     protected:
       Point min_corner;
       Point max_corner;
-      double total_positive_area;
+      typename DerivedV::Scalar total_positive_area;
     public: 
       enum SplitMethod
       {
@@ -32,26 +35,26 @@ namespace igl
       } split_method;
     public:
       inline WindingNumberAABB():
-        total_positive_area(std::numeric_limits<double>::infinity()),
+        total_positive_area(std::numeric_limits<typename DerivedV::Scalar>::infinity()),
         split_method(MEDIAN_ON_LONGEST_AXIS)
       {}
       inline WindingNumberAABB(
-        const Eigen::MatrixXd & V,
-        const Eigen::MatrixXi & F);
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedF> & F);
       inline WindingNumberAABB(
-        const WindingNumberTree<Point> & parent,
-        const Eigen::MatrixXi & F);
+        const WindingNumberTree<Point,DerivedV,DerivedF> & parent,
+        const Eigen::MatrixBase<DerivedF> & F);
       // Initialize some things
       inline void set_mesh(
-        const Eigen::MatrixXd & V,
-        const Eigen::MatrixXi & F);
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedF> & F);
       inline void init();
       inline bool inside(const Point & p) const;
       inline virtual void grow();
       // Compute min and max corners
       inline void compute_min_max_corners();
-      inline double max_abs_winding_number(const Point & p) const;
-      inline double max_simple_abs_winding_number(const Point & p) const;
+      inline typename DerivedV::Scalar max_abs_winding_number(const Point & p) const;
+      inline typename DerivedV::Scalar max_simple_abs_winding_number(const Point & p) const;
   };
 }
 
@@ -74,55 +77,57 @@ namespace igl
 #  define WindingNumberAABB_MIN_F 100
 #endif
 
-template <typename Point>
-inline void igl::WindingNumberAABB<Point>::set_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F)
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberAABB<Point,DerivedV,DerivedF>::set_mesh(
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F)
 {
-  igl::WindingNumberTree<Point>::set_mesh(V,F);
+  igl::WindingNumberTree<Point,DerivedV,DerivedF>::set_mesh(V,F);
   init();
 }
 
-template <typename Point>
-inline void igl::WindingNumberAABB<Point>::init()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberAABB<Point,DerivedV,DerivedF>::init()
 {
   using namespace Eigen;
   assert(max_corner.size() == 3);
   assert(min_corner.size() == 3);
   compute_min_max_corners();
-  VectorXd dblA;
+  Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,1> dblA;
   doublearea(this->getV(),this->getF(),dblA);
   total_positive_area = dblA.sum()/2.0;
 }
 
-template <typename Point>
-inline igl::WindingNumberAABB<Point>::WindingNumberAABB(
-  const Eigen::MatrixXd & V,
-  const Eigen::MatrixXi & F):
-  WindingNumberTree<Point>(V,F),
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberAABB<Point,DerivedV,DerivedF>::WindingNumberAABB(
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedF> & F):
+  WindingNumberTree<Point,DerivedV,DerivedF>(V,F),
   min_corner(),
   max_corner(),
-  total_positive_area(std::numeric_limits<double>::infinity()),
+  total_positive_area(
+    std::numeric_limits<typename DerivedV::Scalar>::infinity()),
   split_method(MEDIAN_ON_LONGEST_AXIS)
 {
   init();
 }
 
-template <typename Point>
-inline igl::WindingNumberAABB<Point>::WindingNumberAABB(
-  const WindingNumberTree<Point> & parent,
-  const Eigen::MatrixXi & F):
-  WindingNumberTree<Point>(parent,F),
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberAABB<Point,DerivedV,DerivedF>::WindingNumberAABB(
+  const WindingNumberTree<Point,DerivedV,DerivedF> & parent,
+  const Eigen::MatrixBase<DerivedF> & F):
+  WindingNumberTree<Point,DerivedV,DerivedF>(parent,F),
   min_corner(),
   max_corner(),
-  total_positive_area(std::numeric_limits<double>::infinity()),
+  total_positive_area(
+    std::numeric_limits<typename DerivedV::Scalar>::infinity()),
   split_method(MEDIAN_ON_LONGEST_AXIS)
 {
   init();
 }
 
-template <typename Point>
-inline void igl::WindingNumberAABB<Point>::grow()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberAABB<Point,DerivedV,DerivedF>::grow()
 {
   using namespace std;
   using namespace Eigen;
@@ -143,7 +148,8 @@ inline void igl::WindingNumberAABB<Point>::grow()
 
   // Compute longest direction
   int max_d = -1;
-  double max_len = -numeric_limits<double>::infinity();
+  typename DerivedV::Scalar max_len = 
+    -numeric_limits<typename DerivedV::Scalar>::infinity();
   for(int d = 0;d<min_corner.size();d++)
   {
     if( (max_corner[d] - min_corner[d]) > max_len )
@@ -153,13 +159,13 @@ inline void igl::WindingNumberAABB<Point>::grow()
     }
   }
   // Compute facet barycenters
-  MatrixXd BC;
+  Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,Eigen::Dynamic> BC;
   barycenter(this->getV(),this->getF(),BC);
 
 
   // Blerg, why is selecting rows so difficult
 
-  double split_value;
+  typename DerivedV::Scalar split_value;
   // Split in longest direction
   switch(split_method)
   {
@@ -196,8 +202,8 @@ inline void igl::WindingNumberAABB<Point>::grow()
     return;
   }
   assert(lefts+rights == this->getF().rows());
-  MatrixXi leftF(lefts,  this->getF().cols());
-  MatrixXi rightF(rights,this->getF().cols());
+  DerivedF leftF(lefts,  this->getF().cols());
+  DerivedF rightF(rights,this->getF().cols());
   int left_i = 0;
   int right_i = 0;
   for(int i = 0;i<this->getF().rows();i++)
@@ -216,16 +222,18 @@ inline void igl::WindingNumberAABB<Point>::grow()
   assert(right_i == rightF.rows());
   assert(left_i == leftF.rows());
   // Finally actually grow children and Recursively grow
-  WindingNumberAABB<Point> * leftWindingNumberAABB = new WindingNumberAABB<Point>(*this,leftF);
+  WindingNumberAABB<Point,DerivedV,DerivedF> * leftWindingNumberAABB = 
+    new WindingNumberAABB<Point,DerivedV,DerivedF>(*this,leftF);
   leftWindingNumberAABB->grow();
   this->children.push_back(leftWindingNumberAABB);
-  WindingNumberAABB<Point> * rightWindingNumberAABB = new WindingNumberAABB<Point>(*this,rightF);
+  WindingNumberAABB<Point,DerivedV,DerivedF> * rightWindingNumberAABB = 
+    new WindingNumberAABB<Point,DerivedV,DerivedF>(*this,rightF);
   rightWindingNumberAABB->grow();
   this->children.push_back(rightWindingNumberAABB);
 }
 
-template <typename Point>
-inline bool igl::WindingNumberAABB<Point>::inside(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline bool igl::WindingNumberAABB<Point,DerivedV,DerivedF>::inside(const Point & p) const
 {
   assert(p.size() == max_corner.size());
   assert(p.size() == min_corner.size());
@@ -242,15 +250,15 @@ inline bool igl::WindingNumberAABB<Point>::inside(const Point & p) const
   return true;
 }
 
-template <typename Point>
-inline void igl::WindingNumberAABB<Point>::compute_min_max_corners()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberAABB<Point,DerivedV,DerivedF>::compute_min_max_corners()
 {
   using namespace std;
   // initialize corners
   for(int d = 0;d<min_corner.size();d++)
   {
-    min_corner[d] =  numeric_limits<double>::infinity();
-    max_corner[d] = -numeric_limits<double>::infinity();
+    min_corner[d] =  numeric_limits<typename Point::Scalar>::infinity();
+    max_corner[d] = -numeric_limits<typename Point::Scalar>::infinity();
   }
 
   this->center = Point(0,0,0);
@@ -285,36 +293,45 @@ inline void igl::WindingNumberAABB<Point>::compute_min_max_corners()
   this->radius = (max_corner-min_corner).norm()/2.0;
 }
 
-template <typename Point>
-inline double igl::WindingNumberAABB<Point>::max_abs_winding_number(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar
+igl::WindingNumberAABB<Point,DerivedV,DerivedF>::max_abs_winding_number(const Point & p) const
 {
   using namespace std;
   // Only valid if not inside
   if(inside(p))
   {
-    return numeric_limits<double>::infinity();
+    return numeric_limits<typename DerivedV::Scalar>::infinity();
   }
   // Q: we know the total positive area so what's the most this could project
   // to? Remember it could be layered in the same direction.
-  return numeric_limits<double>::infinity();
+  return numeric_limits<typename DerivedV::Scalar>::infinity();
 }
 
-template <typename Point>
-inline double igl::WindingNumberAABB<Point>::max_simple_abs_winding_number(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+  igl::WindingNumberAABB<Point,DerivedV,DerivedF>::max_simple_abs_winding_number(
+  const Point & p) const
 {
   using namespace std;
   using namespace Eigen;
   // Only valid if not inside
   if(inside(p))
   {
-    return numeric_limits<double>::infinity();
+    return numeric_limits<typename DerivedV::Scalar>::infinity();
   }
   // Max simple is the same as sum of positive winding number contributions of
   // bounding box
 
   // begin precomputation
   //MatrixXd BV((int)pow(2,3),3);
-  MatrixXd BV((int)(1<<3),3);
+  typedef
+    Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,Eigen::Dynamic>
+    MatrixXS;
+  typedef
+    Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,Eigen::Dynamic>
+    MatrixXF;
+  MatrixXS BV((int)(1<<3),3);
   BV <<
     min_corner[0],min_corner[1],min_corner[2],
     min_corner[0],min_corner[1],max_corner[2],
@@ -324,7 +341,7 @@ inline double igl::WindingNumberAABB<Point>::max_simple_abs_winding_number(const
     max_corner[0],min_corner[1],max_corner[2],
     max_corner[0],max_corner[1],min_corner[2],
     max_corner[0],max_corner[1],max_corner[2];
-  MatrixXi BF(2*2*3,3);
+  MatrixXF BF(2*2*3,3);
   BF <<
     0,6,4,
     0,2,6,
@@ -338,12 +355,12 @@ inline double igl::WindingNumberAABB<Point>::max_simple_abs_winding_number(const
     0,5,1,
     1,5,7,
     1,7,3;
-  MatrixXd BFN;
+  MatrixXS BFN;
   per_face_normals(BV,BF,BFN);
   // end of precomputation
 
   // Only keep those with positive dot products
-  MatrixXi PBF(BF.rows(),BF.cols());
+  MatrixXF PBF(BF.rows(),BF.cols());
   int pbfi = 0;
   Point p2c = 0.5*(min_corner+max_corner)-p;
   for(int i = 0;i<BFN.rows();i++)
@@ -354,18 +371,7 @@ inline double igl::WindingNumberAABB<Point>::max_simple_abs_winding_number(const
     }
   }
   PBF.conservativeResize(pbfi,PBF.cols());
-  double w = numeric_limits<double>::infinity();
-  igl::winding_number_3(
-    BV.data(),
-    BV.rows(),
-    PBF.data(),
-    PBF.rows(),
-    p.data(),
-    1,
-    &w);
-  return w;
+  return igl::winding_number(BV,PBF,p);
 }
 
-//// Explicit instanciation
-//template class igl::WindingNumberAABB<Eigen::Vector3d >;
 #endif

+ 119 - 119
include/igl/WindingNumberTree.h

@@ -14,61 +14,71 @@
 
 namespace igl
 {
-  // This is only need to fill in references, it should never actually be touched
-  // and shouldn't cause race conditions. (This is a hack, but I think it's "safe")
-  static Eigen::MatrixXd dummyV;
   // Space partitioning tree for computing winding number hierarchically.
   //
   // Templates:
   //   Point  type for points in space, e.g. Eigen::Vector3d
-  template <typename Point>
+  template <
+    typename Point,
+    typename DerivedV, 
+    typename DerivedF >
   class WindingNumberTree
   {
     public:
       // Method to use (see enum above)
       //static double min_max_w;
       static std::map< 
-        std::pair<const WindingNumberTree*,const WindingNumberTree*>, double>
+        std::pair<const WindingNumberTree*,const WindingNumberTree*>, 
+        typename DerivedV::Scalar>
           cached;
+      // This is only need to fill in references, it should never actually be touched
+      // and shouldn't cause race conditions. (This is a hack, but I think it's "safe")
+      static DerivedV dummyV;
     protected:
       WindingNumberMethod method;
       const WindingNumberTree * parent;
       std::list<WindingNumberTree * > children;
+      typedef 
+        Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,Eigen::Dynamic>
+        MatrixXS;
+      typedef 
+        Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,Eigen::Dynamic>
+        MatrixXF;
       //// List of boundary edges (recall edges are vertices in 2d)
       //const Eigen::MatrixXi boundary;
       // Base mesh vertices
-      Eigen::MatrixXd & V;
+      DerivedV & V;
       // Base mesh vertices with duplicates removed
-      Eigen::MatrixXd SV;
+      MatrixXS SV;
       // Facets in this bounding volume
-      Eigen::MatrixXi F;
+      MatrixXF F;
       // Tesselated boundary curve
-      Eigen::MatrixXi cap;
+      MatrixXF cap;
       // Upper Bound on radius of enclosing ball
-      double radius;
+      typename DerivedV::Scalar radius;
       // (Approximate) center (of mass)
       Point center;
     public:
       inline WindingNumberTree();
       // For root
       inline WindingNumberTree(
-        const Eigen::MatrixXd & V,
-        const Eigen::MatrixXi & F);
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedF> & F);
       // For chilluns 
       inline WindingNumberTree(
-        const WindingNumberTree<Point> & parent,
-        const Eigen::MatrixXi & F);
+        const WindingNumberTree<Point,DerivedV,DerivedF> & parent,
+        const Eigen::MatrixBase<DerivedF> & F);
       inline virtual ~WindingNumberTree();
       inline void delete_children();
       inline virtual void set_mesh(
-        const Eigen::MatrixXd & V,
-        const Eigen::MatrixXi & F);
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedF> & F);
       // Set method
       inline void set_method( const WindingNumberMethod & m);
     public:
-      inline const Eigen::MatrixXd & getV() const;
-      inline const Eigen::MatrixXi & getF() const;
-      inline const Eigen::MatrixXi & getcap() const;
+      inline const DerivedV & getV() const;
+      inline const MatrixXF & getF() const;
+      inline const MatrixXF & getcap() const;
       // Grow the Tree recursively
       inline virtual void grow();
       // Determine whether a given point is inside the bounding 
@@ -83,12 +93,12 @@ namespace igl
       // Inputs:
       //   p  query point 
       // Returns winding number 
-      inline double winding_number(const Point & p) const;
+      inline typename DerivedV::Scalar winding_number(const Point & p) const;
       // Same as above, but always computes winding number using exact method
       // (sum over every facet)
-      inline double winding_number_all(const Point & p) const;
+      inline typename DerivedV::Scalar winding_number_all(const Point & p) const;
       // Same as above, but always computes using sum over tesslated boundary
-      inline double winding_number_boundary(const Point & p) const;
+      inline typename DerivedV::Scalar winding_number_boundary(const Point & p) const;
       //// Same as winding_number above, but if max_simple_abs_winding_number is
       //// less than some threshold min_max_w just return 0 (colloquially the "fast
       //// multipole method)
@@ -111,10 +121,10 @@ namespace igl
       // Inputs:
       //   p  query point 
       // Returns max winding number of 
-      inline virtual double max_abs_winding_number(const Point & p) const; 
+      inline virtual typename DerivedV::Scalar max_abs_winding_number(const Point & p) const; 
       // Same as above, but stronger assumptions on (V,F). Assumes (V,F) is a
       // simple polyhedron
-      inline virtual double max_simple_abs_winding_number(const Point & p) const;
+      inline virtual typename DerivedV::Scalar max_simple_abs_winding_number(const Point & p) const;
       // Compute or read cached winding number for point p with respect to mesh
       // in bounding box, recursing according to approximation criteria
       //
@@ -122,7 +132,7 @@ namespace igl
       //   p  query point 
       //   that  WindingNumberTree containing mesh w.r.t. which we're computing w.n.
       // Returns cached winding number
-      inline virtual double cached_winding_number(const WindingNumberTree & that, const Point & p) const;
+      inline virtual typename DerivedV::Scalar cached_winding_number(const WindingNumberTree & that, const Point & p) const;
   };
 }
 
@@ -139,64 +149,64 @@ namespace igl
 #include <iostream>
 #include <limits>
 
-//template <typename Point>
-//WindingNumberMethod WindingNumberTree<Point>::method = EXACT_WINDING_NUMBER_METHOD;
-//template <typename Point>
-//double WindingNumberTree<Point>::min_max_w = 0;
-template <typename Point>
-std::map< std::pair<const igl::WindingNumberTree<Point>*,const igl::WindingNumberTree<Point>*>, double>
-  igl::WindingNumberTree<Point>::cached;
+//template <typename Point, typename DerivedV, typename DerivedF>
+//WindingNumberMethod WindingNumberTree<Point,DerivedV,DerivedF>::method = EXACT_WINDING_NUMBER_METHOD;
+//template <typename Point, typename DerivedV, typename DerivedF>
+//double WindingNumberTree<Point,DerivedV,DerivedF>::min_max_w = 0;
+template <typename Point, typename DerivedV, typename DerivedF>
+std::map< std::pair<const igl::WindingNumberTree<Point,DerivedV,DerivedF>*,const igl::WindingNumberTree<Point,DerivedV,DerivedF>*>, typename DerivedV::Scalar>
+  igl::WindingNumberTree<Point,DerivedV,DerivedF>::cached;
 
-template <typename Point>
-inline igl::WindingNumberTree<Point>::WindingNumberTree():
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberTree<Point,DerivedV,DerivedF>::WindingNumberTree():
   method(EXACT_WINDING_NUMBER_METHOD),
   parent(NULL),
-  V(igl::dummyV),
+  V(dummyV),
   SV(),
   F(),
   //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))
   cap(),
-  radius(std::numeric_limits<double>::infinity()),
+  radius(std::numeric_limits<typename DerivedV::Scalar>::infinity()),
   center(0,0,0)
 {
 }
 
-template <typename Point>
-inline igl::WindingNumberTree<Point>::WindingNumberTree(
-  const Eigen::MatrixXd & _V,
-  const Eigen::MatrixXi & _F):
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberTree<Point,DerivedV,DerivedF>::WindingNumberTree(
+  const Eigen::MatrixBase<DerivedV> & _V,
+  const Eigen::MatrixBase<DerivedF> & _F):
   method(EXACT_WINDING_NUMBER_METHOD),
   parent(NULL),
-  V(igl::dummyV),
+  V(dummyV),
   SV(),
   F(),
   //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))
   cap(),
-  radius(std::numeric_limits<double>::infinity()),
+  radius(std::numeric_limits<typename DerivedV::Scalar>::infinity()),
   center(0,0,0)
 {
   set_mesh(_V,_F);
 }
 
-template <typename Point>
-inline void igl::WindingNumberTree<Point>::set_mesh(
-    const Eigen::MatrixXd & _V,
-    const Eigen::MatrixXi & _F)
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberTree<Point,DerivedV,DerivedF>::set_mesh(
+    const Eigen::MatrixBase<DerivedV> & _V,
+    const Eigen::MatrixBase<DerivedF> & _F)
 {
   using namespace std;
   // Remove any exactly duplicate vertices
   // Q: Can this ever increase the complexity of the boundary?
   // Q: Would we gain even more by remove almost exactly duplicate vertices?
-  Eigen::MatrixXi SF,SVI,SVJ;
+  MatrixXF SF,SVI,SVJ;
   igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
   triangle_fan(igl::exterior_edges(F),cap);
   V = SV;
 }
 
-template <typename Point>
-inline igl::WindingNumberTree<Point>::WindingNumberTree(
-  const igl::WindingNumberTree<Point> & parent,
-  const Eigen::MatrixXi & _F):
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberTree<Point,DerivedV,DerivedF>::WindingNumberTree(
+  const igl::WindingNumberTree<Point,DerivedV,DerivedF> & parent,
+  const Eigen::MatrixBase<DerivedF> & _F):
   method(parent.method),
   parent(&parent),
   V(parent.V),
@@ -206,18 +216,18 @@ inline igl::WindingNumberTree<Point>::WindingNumberTree(
 {
 }
 
-template <typename Point>
-inline igl::WindingNumberTree<Point>::~WindingNumberTree()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline igl::WindingNumberTree<Point,DerivedV,DerivedF>::~WindingNumberTree()
 {
   delete_children();
 }
 
-template <typename Point>
-inline void igl::WindingNumberTree<Point>::delete_children()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberTree<Point,DerivedV,DerivedF>::delete_children()
 {
   using namespace std;
   // Delete children
-  typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
+  typename list<WindingNumberTree<Point,DerivedV,DerivedF>* >::iterator cit = children.begin();
   while(cit != children.end())
   {
     // clear the memory of this item
@@ -227,8 +237,8 @@ inline void igl::WindingNumberTree<Point>::delete_children()
   }
 }
       
-template <typename Point>
-inline void igl::WindingNumberTree<Point>::set_method(const WindingNumberMethod & m)
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberTree<Point,DerivedV,DerivedF>::set_method(const WindingNumberMethod & m)
 {
   this->method = m;
   for(auto child : children)
@@ -237,39 +247,42 @@ inline void igl::WindingNumberTree<Point>::set_method(const WindingNumberMethod
   }
 }
 
-template <typename Point>
-inline const Eigen::MatrixXd & igl::WindingNumberTree<Point>::getV() const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline const DerivedV & igl::WindingNumberTree<Point,DerivedV,DerivedF>::getV() const
 {
   return V;
 }
 
-template <typename Point>
-inline const Eigen::MatrixXi & igl::WindingNumberTree<Point>::getF() const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline const typename igl::WindingNumberTree<Point,DerivedV,DerivedF>::MatrixXF& 
+  igl::WindingNumberTree<Point,DerivedV,DerivedF>::getF() const
 {
   return F;
 }
 
-template <typename Point>
-inline const Eigen::MatrixXi & igl::WindingNumberTree<Point>::getcap() const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline const typename igl::WindingNumberTree<Point,DerivedV,DerivedF>::MatrixXF& 
+  igl::WindingNumberTree<Point,DerivedV,DerivedF>::getcap() const
 {
   return cap;
 }
 
-template <typename Point>
-inline void igl::WindingNumberTree<Point>::grow()
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberTree<Point,DerivedV,DerivedF>::grow()
 {
   // Don't grow
   return;
 }
 
-template <typename Point>
-inline bool igl::WindingNumberTree<Point>::inside(const Point & /*p*/) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline bool igl::WindingNumberTree<Point,DerivedV,DerivedF>::inside(const Point & /*p*/) const
 {
   return true;
 }
 
-template <typename Point>
-inline double igl::WindingNumberTree<Point>::winding_number(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+igl::WindingNumberTree<Point,DerivedV,DerivedF>::winding_number(const Point & p) const
 {
   using namespace std;
   //cout<<"+"<<boundary.rows();
@@ -280,9 +293,9 @@ inline double igl::WindingNumberTree<Point>::winding_number(const Point & p) con
     if(children.size()>0)
     {
       // Recurse on each child and accumulate
-      double sum = 0;
+      typename DerivedV::Scalar sum = 0;
       for(
-        typename list<WindingNumberTree<Point>* >::const_iterator cit = children.begin();
+        typename list<WindingNumberTree<Point,DerivedV,DerivedF>* >::const_iterator cit = children.begin();
         cit != children.end();
         cit++)
       {
@@ -320,7 +333,7 @@ inline double igl::WindingNumberTree<Point>::winding_number(const Point & p) con
           return winding_number_boundary(p);
         case APPROX_SIMPLE_WINDING_NUMBER_METHOD:
         {
-          double dist = (p-center).norm();
+          typename DerivedV::Scalar dist = (p-center).norm();
           // Radius is already an overestimate of inside
           if(dist>1.0*radius)
           {
@@ -345,42 +358,24 @@ inline double igl::WindingNumberTree<Point>::winding_number(const Point & p) con
   return 0;
 }
 
-template <typename Point>
-inline double igl::WindingNumberTree<Point>::winding_number_all(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+  igl::WindingNumberTree<Point,DerivedV,DerivedF>::winding_number_all(const Point & p) const
 {
-  double w = 0;
-  igl::winding_number_3(
-    V.data(),
-    V.rows(),
-    F.data(),
-    F.rows(),
-    p.data(),
-    1,
-    &w);
-  return w;
+  return igl::winding_number(V,F,p);
 }
 
-template <typename Point>
-inline double igl::WindingNumberTree<Point>::winding_number_boundary(const Point & p) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+igl::WindingNumberTree<Point,DerivedV,DerivedF>::winding_number_boundary(const Point & p) const
 {
   using namespace Eigen;
   using namespace std;
-
-  double w = 0;
-  // `cap` is already flipped inside out, so we don't need to flip sign of w
-  igl::winding_number_3(
-    V.data(),
-    V.rows(),
-    cap.data(),
-    cap.rows(),
-    &p[0],
-    1,
-    &w);
-  return w;
+  return igl::winding_number(V,cap,p);
 }
 
-//template <typename Point>
-//inline double igl::WindingNumberTree<Point>::winding_number_approx_simple(
+//template <typename Point, typename DerivedV, typename DerivedF>
+//inline double igl::WindingNumberTree<Point,DerivedV,DerivedF>::winding_number_approx_simple(
 //  const Point & p, 
 //  const double min_max_w)
 //{
@@ -395,15 +390,15 @@ inline double igl::WindingNumberTree<Point>::winding_number_boundary(const Point
 //  }
 //}
 
-template <typename Point>
-inline void igl::WindingNumberTree<Point>::print(const char * tab)
+template <typename Point, typename DerivedV, typename DerivedF>
+inline void igl::WindingNumberTree<Point,DerivedV,DerivedF>::print(const char * tab)
 {
   using namespace std;
   // Print all facets
   cout<<tab<<"["<<endl<<F<<endl<<"]";
   // Print children
   for(
-      typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
+      typename list<WindingNumberTree<Point,DerivedV,DerivedF>* >::iterator cit = children.begin();
       cit != children.end();
       cit++)
   {
@@ -412,25 +407,26 @@ inline void igl::WindingNumberTree<Point>::print(const char * tab)
   }
 }
 
-template <typename Point>
-inline double 
-igl::WindingNumberTree<Point>::max_abs_winding_number(const Point & /*p*/) const
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+igl::WindingNumberTree<Point,DerivedV,DerivedF>::max_abs_winding_number(const Point & /*p*/) const
 {
-  return std::numeric_limits<double>::infinity();
+  return std::numeric_limits<typename DerivedV::Scalar>::infinity();
 }
 
-template <typename Point>
-inline double 
-igl::WindingNumberTree<Point>::max_simple_abs_winding_number(
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+igl::WindingNumberTree<Point,DerivedV,DerivedF>::max_simple_abs_winding_number(
   const Point & /*p*/) const
 {
   using namespace std;
-  return numeric_limits<double>::infinity();
+  return numeric_limits<typename DerivedV::Scalar>::infinity();
 }
 
-template <typename Point>
-inline double igl::WindingNumberTree<Point>::cached_winding_number(
-  const igl::WindingNumberTree<Point> & that,
+template <typename Point, typename DerivedV, typename DerivedF>
+inline typename DerivedV::Scalar 
+igl::WindingNumberTree<Point,DerivedV,DerivedF>::cached_winding_number(
+  const igl::WindingNumberTree<Point,DerivedV,DerivedF> & that,
   const Point & p) const
 {
   using namespace std;
@@ -454,7 +450,7 @@ inline double igl::WindingNumberTree<Point>::cached_winding_number(
   bool is_far = this->radius<that.radius;
   if(is_far)
   {
-    double a = atan2(
+    typename DerivedV::Scalar a = atan2(
       that.radius - this->radius,
       (that.center - this->center).norm());
     assert(a>0);
@@ -479,7 +475,7 @@ inline double igl::WindingNumberTree<Point>::cached_winding_number(
   }else
   {
     for(
-      typename list<WindingNumberTree<Point>* >::const_iterator cit = children.begin();
+      typename list<WindingNumberTree<Point,DerivedV,DerivedF>* >::const_iterator cit = children.begin();
       cit != children.end();
       cit++)
     {
@@ -497,7 +493,11 @@ inline double igl::WindingNumberTree<Point>::cached_winding_number(
   return 0;
 }
 
-// Explicit instanciation
-//template class igl::WindingNumberTree<Eigen::Vector3d >;
+// Explicit instanciation of static variable
+template <
+  typename Point,
+  typename DerivedV, 
+  typename DerivedF >
+DerivedV igl::WindingNumberTree<Point,DerivedV,DerivedF>::dummyV;
 
 #endif

+ 0 - 1
include/igl/ambient_occlusion.cpp

@@ -34,7 +34,6 @@ IGL_INLINE void igl::ambient_occlusion(
   const int n = P.rows();
   // Resize output
   S.resize(n,1);
-  VectorXi hits = VectorXi::Zero(n,1);
   // Embree seems to be parallel when constructing but not when tracing rays
   const MatrixXf D = random_dir_stratified(num_samples).cast<float>();
 

+ 1 - 1
include/igl/angle_bound_frame_fields.cpp

@@ -154,7 +154,7 @@ precomputeInteriorEdges()
   // Flag border edges
   numInteriorEdges = 0;
   isBorderEdge.setZero(numE,1);
-  indFullToInterior = -1.*Eigen::VectorXi::Ones(numE,1);
+  indFullToInterior = Eigen::VectorXi::Constant(numE,-1);
 
   for(unsigned i=0; i<numE; ++i)
   {

+ 5 - 4
include/igl/avg_edge_length.cpp

@@ -11,12 +11,13 @@
 
 template <typename DerivedV, typename DerivedF>
 IGL_INLINE double igl::avg_edge_length(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F)
+  const Eigen::MatrixBase<DerivedV>& V,
+  const Eigen::MatrixBase<DerivedF>& F)
 {
   double avg = 0;
   long int count = 0;
 
+  // Augh. Technically this is double counting interior edges...
   for (unsigned i=0;i<F.rows();++i)
   {
     for (unsigned j=0;j<F.cols();++j)
@@ -32,7 +33,7 @@ IGL_INLINE double igl::avg_edge_length(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
+template double igl::avg_edge_length<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+template double igl::avg_edge_length<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
 // generated by autoexplicit.sh
 #endif

+ 2 - 2
include/igl/avg_edge_length.h

@@ -29,8 +29,8 @@ namespace igl
   // See also: adjacency_matrix
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE double avg_edge_length(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F);
+    const Eigen::MatrixBase<DerivedV>& V,
+    const Eigen::MatrixBase<DerivedF>& F);
 
 }
 

+ 10 - 0
include/igl/barycenter.cpp

@@ -33,6 +33,16 @@ IGL_INLINE void igl::barycenter(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
+template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);

+ 4 - 0
include/igl/barycentric_coordinates.cpp

@@ -101,6 +101,10 @@ IGL_INLINE void igl::barycentric_coordinates(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::barycentric_coordinates<Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+template void igl::barycentric_coordinates<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
 template void igl::barycentric_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 template void igl::barycentric_coordinates<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);

+ 1 - 1
include/igl/collapse_edge.h

@@ -13,7 +13,7 @@
 #include <set>
 namespace igl
 {
-  // Assumes (V,F) is a closed manifold mesh (except for previouslly collapsed
+  // Assumes (V,F) is a closed manifold mesh (except for previously collapsed
   // faces which should be set to: 
   // [IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL].
   // Collapses exactly two faces and exactly 3 edges from E (e and one side of

+ 1 - 0
include/igl/colon.cpp

@@ -58,6 +58,7 @@ template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -1, 1,
 template void igl::colon<int, double, double, double>(int, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
 template void igl::colon<double, double, double>(double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
 template void igl::colon<double, double, double, double>(double, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+template void igl::colon<int, int, long>(int, int, Eigen::Matrix<long, -1, 1, 0, -1, 1>&);
 #ifdef WIN32
 template void igl::colon<int, long long,long>(int, long long, class Eigen::Matrix<long,-1,1,0,-1,1> &);
 #endif

+ 1462 - 0
include/igl/colormap.cpp

@@ -0,0 +1,1462 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Joe Graus <jgraus@gmu.edu>, Alec Jacobson <alecjacobson@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "colormap.h"
+
+// One of the new matplotlib colormaps by Nathaniel J.Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing.
+// Released under the CC0 license / public domain dedication
+
+static double inferno_cm[256][3] = {
+	{ 0.001462, 0.000466, 0.013866 },
+	{ 0.002267, 0.001270, 0.018570 },
+	{ 0.003299, 0.002249, 0.024239 },
+	{ 0.004547, 0.003392, 0.030909 },
+	{ 0.006006, 0.004692, 0.038558 },
+	{ 0.007676, 0.006136, 0.046836 },
+	{ 0.009561, 0.007713, 0.055143 },
+	{ 0.011663, 0.009417, 0.063460 },
+	{ 0.013995, 0.011225, 0.071862 },
+	{ 0.016561, 0.013136, 0.080282 },
+	{ 0.019373, 0.015133, 0.088767 },
+	{ 0.022447, 0.017199, 0.097327 },
+	{ 0.025793, 0.019331, 0.105930 },
+	{ 0.029432, 0.021503, 0.114621 },
+	{ 0.033385, 0.023702, 0.123397 },
+	{ 0.037668, 0.025921, 0.132232 },
+	{ 0.042253, 0.028139, 0.141141 },
+	{ 0.046915, 0.030324, 0.150164 },
+	{ 0.051644, 0.032474, 0.159254 },
+	{ 0.056449, 0.034569, 0.168414 },
+	{ 0.061340, 0.036590, 0.177642 },
+	{ 0.066331, 0.038504, 0.186962 },
+	{ 0.071429, 0.040294, 0.196354 },
+	{ 0.076637, 0.041905, 0.205799 },
+	{ 0.081962, 0.043328, 0.215289 },
+	{ 0.087411, 0.044556, 0.224813 },
+	{ 0.092990, 0.045583, 0.234358 },
+	{ 0.098702, 0.046402, 0.243904 },
+	{ 0.104551, 0.047008, 0.253430 },
+	{ 0.110536, 0.047399, 0.262912 },
+	{ 0.116656, 0.047574, 0.272321 },
+	{ 0.122908, 0.047536, 0.281624 },
+	{ 0.129285, 0.047293, 0.290788 },
+	{ 0.135778, 0.046856, 0.299776 },
+	{ 0.142378, 0.046242, 0.308553 },
+	{ 0.149073, 0.045468, 0.317085 },
+	{ 0.155850, 0.044559, 0.325338 },
+	{ 0.162689, 0.043554, 0.333277 },
+	{ 0.169575, 0.042489, 0.340874 },
+	{ 0.176493, 0.041402, 0.348111 },
+	{ 0.183429, 0.040329, 0.354971 },
+	{ 0.190367, 0.039309, 0.361447 },
+	{ 0.197297, 0.038400, 0.367535 },
+	{ 0.204209, 0.037632, 0.373238 },
+	{ 0.211095, 0.037030, 0.378563 },
+	{ 0.217949, 0.036615, 0.383522 },
+	{ 0.224763, 0.036405, 0.388129 },
+	{ 0.231538, 0.036405, 0.392400 },
+	{ 0.238273, 0.036621, 0.396353 },
+	{ 0.244967, 0.037055, 0.400007 },
+	{ 0.251620, 0.037705, 0.403378 },
+	{ 0.258234, 0.038571, 0.406485 },
+	{ 0.264810, 0.039647, 0.409345 },
+	{ 0.271347, 0.040922, 0.411976 },
+	{ 0.277850, 0.042353, 0.414392 },
+	{ 0.284321, 0.043933, 0.416608 },
+	{ 0.290763, 0.045644, 0.418637 },
+	{ 0.297178, 0.047470, 0.420491 },
+	{ 0.303568, 0.049396, 0.422182 },
+	{ 0.309935, 0.051407, 0.423721 },
+	{ 0.316282, 0.053490, 0.425116 },
+	{ 0.322610, 0.055634, 0.426377 },
+	{ 0.328921, 0.057827, 0.427511 },
+	{ 0.335217, 0.060060, 0.428524 },
+	{ 0.341500, 0.062325, 0.429425 },
+	{ 0.347771, 0.064616, 0.430217 },
+	{ 0.354032, 0.066925, 0.430906 },
+	{ 0.360284, 0.069247, 0.431497 },
+	{ 0.366529, 0.071579, 0.431994 },
+	{ 0.372768, 0.073915, 0.432400 },
+	{ 0.379001, 0.076253, 0.432719 },
+	{ 0.385228, 0.078591, 0.432955 },
+	{ 0.391453, 0.080927, 0.433109 },
+	{ 0.397674, 0.083257, 0.433183 },
+	{ 0.403894, 0.085580, 0.433179 },
+	{ 0.410113, 0.087896, 0.433098 },
+	{ 0.416331, 0.090203, 0.432943 },
+	{ 0.422549, 0.092501, 0.432714 },
+	{ 0.428768, 0.094790, 0.432412 },
+	{ 0.434987, 0.097069, 0.432039 },
+	{ 0.441207, 0.099338, 0.431594 },
+	{ 0.447428, 0.101597, 0.431080 },
+	{ 0.453651, 0.103848, 0.430498 },
+	{ 0.459875, 0.106089, 0.429846 },
+	{ 0.466100, 0.108322, 0.429125 },
+	{ 0.472328, 0.110547, 0.428334 },
+	{ 0.478558, 0.112764, 0.427475 },
+	{ 0.484789, 0.114974, 0.426548 },
+	{ 0.491022, 0.117179, 0.425552 },
+	{ 0.497257, 0.119379, 0.424488 },
+	{ 0.503493, 0.121575, 0.423356 },
+	{ 0.509730, 0.123769, 0.422156 },
+	{ 0.515967, 0.125960, 0.420887 },
+	{ 0.522206, 0.128150, 0.419549 },
+	{ 0.528444, 0.130341, 0.418142 },
+	{ 0.534683, 0.132534, 0.416667 },
+	{ 0.540920, 0.134729, 0.415123 },
+	{ 0.547157, 0.136929, 0.413511 },
+	{ 0.553392, 0.139134, 0.411829 },
+	{ 0.559624, 0.141346, 0.410078 },
+	{ 0.565854, 0.143567, 0.408258 },
+	{ 0.572081, 0.145797, 0.406369 },
+	{ 0.578304, 0.148039, 0.404411 },
+	{ 0.584521, 0.150294, 0.402385 },
+	{ 0.590734, 0.152563, 0.400290 },
+	{ 0.596940, 0.154848, 0.398125 },
+	{ 0.603139, 0.157151, 0.395891 },
+	{ 0.609330, 0.159474, 0.393589 },
+	{ 0.615513, 0.161817, 0.391219 },
+	{ 0.621685, 0.164184, 0.388781 },
+	{ 0.627847, 0.166575, 0.386276 },
+	{ 0.633998, 0.168992, 0.383704 },
+	{ 0.640135, 0.171438, 0.381065 },
+	{ 0.646260, 0.173914, 0.378359 },
+	{ 0.652369, 0.176421, 0.375586 },
+	{ 0.658463, 0.178962, 0.372748 },
+	{ 0.664540, 0.181539, 0.369846 },
+	{ 0.670599, 0.184153, 0.366879 },
+	{ 0.676638, 0.186807, 0.363849 },
+	{ 0.682656, 0.189501, 0.360757 },
+	{ 0.688653, 0.192239, 0.357603 },
+	{ 0.694627, 0.195021, 0.354388 },
+	{ 0.700576, 0.197851, 0.351113 },
+	{ 0.706500, 0.200728, 0.347777 },
+	{ 0.712396, 0.203656, 0.344383 },
+	{ 0.718264, 0.206636, 0.340931 },
+	{ 0.724103, 0.209670, 0.337424 },
+	{ 0.729909, 0.212759, 0.333861 },
+	{ 0.735683, 0.215906, 0.330245 },
+	{ 0.741423, 0.219112, 0.326576 },
+	{ 0.747127, 0.222378, 0.322856 },
+	{ 0.752794, 0.225706, 0.319085 },
+	{ 0.758422, 0.229097, 0.315266 },
+	{ 0.764010, 0.232554, 0.311399 },
+	{ 0.769556, 0.236077, 0.307485 },
+	{ 0.775059, 0.239667, 0.303526 },
+	{ 0.780517, 0.243327, 0.299523 },
+	{ 0.785929, 0.247056, 0.295477 },
+	{ 0.791293, 0.250856, 0.291390 },
+	{ 0.796607, 0.254728, 0.287264 },
+	{ 0.801871, 0.258674, 0.283099 },
+	{ 0.807082, 0.262692, 0.278898 },
+	{ 0.812239, 0.266786, 0.274661 },
+	{ 0.817341, 0.270954, 0.270390 },
+	{ 0.822386, 0.275197, 0.266085 },
+	{ 0.827372, 0.279517, 0.261750 },
+	{ 0.832299, 0.283913, 0.257383 },
+	{ 0.837165, 0.288385, 0.252988 },
+	{ 0.841969, 0.292933, 0.248564 },
+	{ 0.846709, 0.297559, 0.244113 },
+	{ 0.851384, 0.302260, 0.239636 },
+	{ 0.855992, 0.307038, 0.235133 },
+	{ 0.860533, 0.311892, 0.230606 },
+	{ 0.865006, 0.316822, 0.226055 },
+	{ 0.869409, 0.321827, 0.221482 },
+	{ 0.873741, 0.326906, 0.216886 },
+	{ 0.878001, 0.332060, 0.212268 },
+	{ 0.882188, 0.337287, 0.207628 },
+	{ 0.886302, 0.342586, 0.202968 },
+	{ 0.890341, 0.347957, 0.198286 },
+	{ 0.894305, 0.353399, 0.193584 },
+	{ 0.898192, 0.358911, 0.188860 },
+	{ 0.902003, 0.364492, 0.184116 },
+	{ 0.905735, 0.370140, 0.179350 },
+	{ 0.909390, 0.375856, 0.174563 },
+	{ 0.912966, 0.381636, 0.169755 },
+	{ 0.916462, 0.387481, 0.164924 },
+	{ 0.919879, 0.393389, 0.160070 },
+	{ 0.923215, 0.399359, 0.155193 },
+	{ 0.926470, 0.405389, 0.150292 },
+	{ 0.929644, 0.411479, 0.145367 },
+	{ 0.932737, 0.417627, 0.140417 },
+	{ 0.935747, 0.423831, 0.135440 },
+	{ 0.938675, 0.430091, 0.130438 },
+	{ 0.941521, 0.436405, 0.125409 },
+	{ 0.944285, 0.442772, 0.120354 },
+	{ 0.946965, 0.449191, 0.115272 },
+	{ 0.949562, 0.455660, 0.110164 },
+	{ 0.952075, 0.462178, 0.105031 },
+	{ 0.954506, 0.468744, 0.099874 },
+	{ 0.956852, 0.475356, 0.094695 },
+	{ 0.959114, 0.482014, 0.089499 },
+	{ 0.961293, 0.488716, 0.084289 },
+	{ 0.963387, 0.495462, 0.079073 },
+	{ 0.965397, 0.502249, 0.073859 },
+	{ 0.967322, 0.509078, 0.068659 },
+	{ 0.969163, 0.515946, 0.063488 },
+	{ 0.970919, 0.522853, 0.058367 },
+	{ 0.972590, 0.529798, 0.053324 },
+	{ 0.974176, 0.536780, 0.048392 },
+	{ 0.975677, 0.543798, 0.043618 },
+	{ 0.977092, 0.550850, 0.039050 },
+	{ 0.978422, 0.557937, 0.034931 },
+	{ 0.979666, 0.565057, 0.031409 },
+	{ 0.980824, 0.572209, 0.028508 },
+	{ 0.981895, 0.579392, 0.026250 },
+	{ 0.982881, 0.586606, 0.024661 },
+	{ 0.983779, 0.593849, 0.023770 },
+	{ 0.984591, 0.601122, 0.023606 },
+	{ 0.985315, 0.608422, 0.024202 },
+	{ 0.985952, 0.615750, 0.025592 },
+	{ 0.986502, 0.623105, 0.027814 },
+	{ 0.986964, 0.630485, 0.030908 },
+	{ 0.987337, 0.637890, 0.034916 },
+	{ 0.987622, 0.645320, 0.039886 },
+	{ 0.987819, 0.652773, 0.045581 },
+	{ 0.987926, 0.660250, 0.051750 },
+	{ 0.987945, 0.667748, 0.058329 },
+	{ 0.987874, 0.675267, 0.065257 },
+	{ 0.987714, 0.682807, 0.072489 },
+	{ 0.987464, 0.690366, 0.079990 },
+	{ 0.987124, 0.697944, 0.087731 },
+	{ 0.986694, 0.705540, 0.095694 },
+	{ 0.986175, 0.713153, 0.103863 },
+	{ 0.985566, 0.720782, 0.112229 },
+	{ 0.984865, 0.728427, 0.120785 },
+	{ 0.984075, 0.736087, 0.129527 },
+	{ 0.983196, 0.743758, 0.138453 },
+	{ 0.982228, 0.751442, 0.147565 },
+	{ 0.981173, 0.759135, 0.156863 },
+	{ 0.980032, 0.766837, 0.166353 },
+	{ 0.978806, 0.774545, 0.176037 },
+	{ 0.977497, 0.782258, 0.185923 },
+	{ 0.976108, 0.789974, 0.196018 },
+	{ 0.974638, 0.797692, 0.206332 },
+	{ 0.973088, 0.805409, 0.216877 },
+	{ 0.971468, 0.813122, 0.227658 },
+	{ 0.969783, 0.820825, 0.238686 },
+	{ 0.968041, 0.828515, 0.249972 },
+	{ 0.966243, 0.836191, 0.261534 },
+	{ 0.964394, 0.843848, 0.273391 },
+	{ 0.962517, 0.851476, 0.285546 },
+	{ 0.960626, 0.859069, 0.298010 },
+	{ 0.958720, 0.866624, 0.310820 },
+	{ 0.956834, 0.874129, 0.323974 },
+	{ 0.954997, 0.881569, 0.337475 },
+	{ 0.953215, 0.888942, 0.351369 },
+	{ 0.951546, 0.896226, 0.365627 },
+	{ 0.950018, 0.903409, 0.380271 },
+	{ 0.948683, 0.910473, 0.395289 },
+	{ 0.947594, 0.917399, 0.410665 },
+	{ 0.946809, 0.924168, 0.426373 },
+	{ 0.946392, 0.930761, 0.442367 },
+	{ 0.946403, 0.937159, 0.458592 },
+	{ 0.946903, 0.943348, 0.474970 },
+	{ 0.947937, 0.949318, 0.491426 },
+	{ 0.949545, 0.955063, 0.507860 },
+	{ 0.951740, 0.960587, 0.524203 },
+	{ 0.954529, 0.965896, 0.540361 },
+	{ 0.957896, 0.971003, 0.556275 },
+	{ 0.961812, 0.975924, 0.571925 },
+	{ 0.966249, 0.980678, 0.587206 },
+	{ 0.971162, 0.985282, 0.602154 },
+	{ 0.976511, 0.989753, 0.616760 },
+	{ 0.982257, 0.994109, 0.631017 },
+	{ 0.988362, 0.998364, 0.644924 }
+};
+
+static double magma_cm[256][3] = {
+	{ 0.001462, 0.000466, 0.013866 },
+	{ 0.002258, 0.001295, 0.018331 },
+	{ 0.003279, 0.002305, 0.023708 },
+	{ 0.004512, 0.003490, 0.029965 },
+	{ 0.005950, 0.004843, 0.037130 },
+	{ 0.007588, 0.006356, 0.044973 },
+	{ 0.009426, 0.008022, 0.052844 },
+	{ 0.011465, 0.009828, 0.060750 },
+	{ 0.013708, 0.011771, 0.068667 },
+	{ 0.016156, 0.013840, 0.076603 },
+	{ 0.018815, 0.016026, 0.084584 },
+	{ 0.021692, 0.018320, 0.092610 },
+	{ 0.024792, 0.020715, 0.100676 },
+	{ 0.028123, 0.023201, 0.108787 },
+	{ 0.031696, 0.025765, 0.116965 },
+	{ 0.035520, 0.028397, 0.125209 },
+	{ 0.039608, 0.031090, 0.133515 },
+	{ 0.043830, 0.033830, 0.141886 },
+	{ 0.048062, 0.036607, 0.150327 },
+	{ 0.052320, 0.039407, 0.158841 },
+	{ 0.056615, 0.042160, 0.167446 },
+	{ 0.060949, 0.044794, 0.176129 },
+	{ 0.065330, 0.047318, 0.184892 },
+	{ 0.069764, 0.049726, 0.193735 },
+	{ 0.074257, 0.052017, 0.202660 },
+	{ 0.078815, 0.054184, 0.211667 },
+	{ 0.083446, 0.056225, 0.220755 },
+	{ 0.088155, 0.058133, 0.229922 },
+	{ 0.092949, 0.059904, 0.239164 },
+	{ 0.097833, 0.061531, 0.248477 },
+	{ 0.102815, 0.063010, 0.257854 },
+	{ 0.107899, 0.064335, 0.267289 },
+	{ 0.113094, 0.065492, 0.276784 },
+	{ 0.118405, 0.066479, 0.286321 },
+	{ 0.123833, 0.067295, 0.295879 },
+	{ 0.129380, 0.067935, 0.305443 },
+	{ 0.135053, 0.068391, 0.315000 },
+	{ 0.140858, 0.068654, 0.324538 },
+	{ 0.146785, 0.068738, 0.334011 },
+	{ 0.152839, 0.068637, 0.343404 },
+	{ 0.159018, 0.068354, 0.352688 },
+	{ 0.165308, 0.067911, 0.361816 },
+	{ 0.171713, 0.067305, 0.370771 },
+	{ 0.178212, 0.066576, 0.379497 },
+	{ 0.184801, 0.065732, 0.387973 },
+	{ 0.191460, 0.064818, 0.396152 },
+	{ 0.198177, 0.063862, 0.404009 },
+	{ 0.204935, 0.062907, 0.411514 },
+	{ 0.211718, 0.061992, 0.418647 },
+	{ 0.218512, 0.061158, 0.425392 },
+	{ 0.225302, 0.060445, 0.431742 },
+	{ 0.232077, 0.059889, 0.437695 },
+	{ 0.238826, 0.059517, 0.443256 },
+	{ 0.245543, 0.059352, 0.448436 },
+	{ 0.252220, 0.059415, 0.453248 },
+	{ 0.258857, 0.059706, 0.457710 },
+	{ 0.265447, 0.060237, 0.461840 },
+	{ 0.271994, 0.060994, 0.465660 },
+	{ 0.278493, 0.061978, 0.469190 },
+	{ 0.284951, 0.063168, 0.472451 },
+	{ 0.291366, 0.064553, 0.475462 },
+	{ 0.297740, 0.066117, 0.478243 },
+	{ 0.304081, 0.067835, 0.480812 },
+	{ 0.310382, 0.069702, 0.483186 },
+	{ 0.316654, 0.071690, 0.485380 },
+	{ 0.322899, 0.073782, 0.487408 },
+	{ 0.329114, 0.075972, 0.489287 },
+	{ 0.335308, 0.078236, 0.491024 },
+	{ 0.341482, 0.080564, 0.492631 },
+	{ 0.347636, 0.082946, 0.494121 },
+	{ 0.353773, 0.085373, 0.495501 },
+	{ 0.359898, 0.087831, 0.496778 },
+	{ 0.366012, 0.090314, 0.497960 },
+	{ 0.372116, 0.092816, 0.499053 },
+	{ 0.378211, 0.095332, 0.500067 },
+	{ 0.384299, 0.097855, 0.501002 },
+	{ 0.390384, 0.100379, 0.501864 },
+	{ 0.396467, 0.102902, 0.502658 },
+	{ 0.402548, 0.105420, 0.503386 },
+	{ 0.408629, 0.107930, 0.504052 },
+	{ 0.414709, 0.110431, 0.504662 },
+	{ 0.420791, 0.112920, 0.505215 },
+	{ 0.426877, 0.115395, 0.505714 },
+	{ 0.432967, 0.117855, 0.506160 },
+	{ 0.439062, 0.120298, 0.506555 },
+	{ 0.445163, 0.122724, 0.506901 },
+	{ 0.451271, 0.125132, 0.507198 },
+	{ 0.457386, 0.127522, 0.507448 },
+	{ 0.463508, 0.129893, 0.507652 },
+	{ 0.469640, 0.132245, 0.507809 },
+	{ 0.475780, 0.134577, 0.507921 },
+	{ 0.481929, 0.136891, 0.507989 },
+	{ 0.488088, 0.139186, 0.508011 },
+	{ 0.494258, 0.141462, 0.507988 },
+	{ 0.500438, 0.143719, 0.507920 },
+	{ 0.506629, 0.145958, 0.507806 },
+	{ 0.512831, 0.148179, 0.507648 },
+	{ 0.519045, 0.150383, 0.507443 },
+	{ 0.525270, 0.152569, 0.507192 },
+	{ 0.531507, 0.154739, 0.506895 },
+	{ 0.537755, 0.156894, 0.506551 },
+	{ 0.544015, 0.159033, 0.506159 },
+	{ 0.550287, 0.161158, 0.505719 },
+	{ 0.556571, 0.163269, 0.505230 },
+	{ 0.562866, 0.165368, 0.504692 },
+	{ 0.569172, 0.167454, 0.504105 },
+	{ 0.575490, 0.169530, 0.503466 },
+	{ 0.581819, 0.171596, 0.502777 },
+	{ 0.588158, 0.173652, 0.502035 },
+	{ 0.594508, 0.175701, 0.501241 },
+	{ 0.600868, 0.177743, 0.500394 },
+	{ 0.607238, 0.179779, 0.499492 },
+	{ 0.613617, 0.181811, 0.498536 },
+	{ 0.620005, 0.183840, 0.497524 },
+	{ 0.626401, 0.185867, 0.496456 },
+	{ 0.632805, 0.187893, 0.495332 },
+	{ 0.639216, 0.189921, 0.494150 },
+	{ 0.645633, 0.191952, 0.492910 },
+	{ 0.652056, 0.193986, 0.491611 },
+	{ 0.658483, 0.196027, 0.490253 },
+	{ 0.664915, 0.198075, 0.488836 },
+	{ 0.671349, 0.200133, 0.487358 },
+	{ 0.677786, 0.202203, 0.485819 },
+	{ 0.684224, 0.204286, 0.484219 },
+	{ 0.690661, 0.206384, 0.482558 },
+	{ 0.697098, 0.208501, 0.480835 },
+	{ 0.703532, 0.210638, 0.479049 },
+	{ 0.709962, 0.212797, 0.477201 },
+	{ 0.716387, 0.214982, 0.475290 },
+	{ 0.722805, 0.217194, 0.473316 },
+	{ 0.729216, 0.219437, 0.471279 },
+	{ 0.735616, 0.221713, 0.469180 },
+	{ 0.742004, 0.224025, 0.467018 },
+	{ 0.748378, 0.226377, 0.464794 },
+	{ 0.754737, 0.228772, 0.462509 },
+	{ 0.761077, 0.231214, 0.460162 },
+	{ 0.767398, 0.233705, 0.457755 },
+	{ 0.773695, 0.236249, 0.455289 },
+	{ 0.779968, 0.238851, 0.452765 },
+	{ 0.786212, 0.241514, 0.450184 },
+	{ 0.792427, 0.244242, 0.447543 },
+	{ 0.798608, 0.247040, 0.444848 },
+	{ 0.804752, 0.249911, 0.442102 },
+	{ 0.810855, 0.252861, 0.439305 },
+	{ 0.816914, 0.255895, 0.436461 },
+	{ 0.822926, 0.259016, 0.433573 },
+	{ 0.828886, 0.262229, 0.430644 },
+	{ 0.834791, 0.265540, 0.427671 },
+	{ 0.840636, 0.268953, 0.424666 },
+	{ 0.846416, 0.272473, 0.421631 },
+	{ 0.852126, 0.276106, 0.418573 },
+	{ 0.857763, 0.279857, 0.415496 },
+	{ 0.863320, 0.283729, 0.412403 },
+	{ 0.868793, 0.287728, 0.409303 },
+	{ 0.874176, 0.291859, 0.406205 },
+	{ 0.879464, 0.296125, 0.403118 },
+	{ 0.884651, 0.300530, 0.400047 },
+	{ 0.889731, 0.305079, 0.397002 },
+	{ 0.894700, 0.309773, 0.393995 },
+	{ 0.899552, 0.314616, 0.391037 },
+	{ 0.904281, 0.319610, 0.388137 },
+	{ 0.908884, 0.324755, 0.385308 },
+	{ 0.913354, 0.330052, 0.382563 },
+	{ 0.917689, 0.335500, 0.379915 },
+	{ 0.921884, 0.341098, 0.377376 },
+	{ 0.925937, 0.346844, 0.374959 },
+	{ 0.929845, 0.352734, 0.372677 },
+	{ 0.933606, 0.358764, 0.370541 },
+	{ 0.937221, 0.364929, 0.368567 },
+	{ 0.940687, 0.371224, 0.366762 },
+	{ 0.944006, 0.377643, 0.365136 },
+	{ 0.947180, 0.384178, 0.363701 },
+	{ 0.950210, 0.390820, 0.362468 },
+	{ 0.953099, 0.397563, 0.361438 },
+	{ 0.955849, 0.404400, 0.360619 },
+	{ 0.958464, 0.411324, 0.360014 },
+	{ 0.960949, 0.418323, 0.359630 },
+	{ 0.963310, 0.425390, 0.359469 },
+	{ 0.965549, 0.432519, 0.359529 },
+	{ 0.967671, 0.439703, 0.359810 },
+	{ 0.969680, 0.446936, 0.360311 },
+	{ 0.971582, 0.454210, 0.361030 },
+	{ 0.973381, 0.461520, 0.361965 },
+	{ 0.975082, 0.468861, 0.363111 },
+	{ 0.976690, 0.476226, 0.364466 },
+	{ 0.978210, 0.483612, 0.366025 },
+	{ 0.979645, 0.491014, 0.367783 },
+	{ 0.981000, 0.498428, 0.369734 },
+	{ 0.982279, 0.505851, 0.371874 },
+	{ 0.983485, 0.513280, 0.374198 },
+	{ 0.984622, 0.520713, 0.376698 },
+	{ 0.985693, 0.528148, 0.379371 },
+	{ 0.986700, 0.535582, 0.382210 },
+	{ 0.987646, 0.543015, 0.385210 },
+	{ 0.988533, 0.550446, 0.388365 },
+	{ 0.989363, 0.557873, 0.391671 },
+	{ 0.990138, 0.565296, 0.395122 },
+	{ 0.990871, 0.572706, 0.398714 },
+	{ 0.991558, 0.580107, 0.402441 },
+	{ 0.992196, 0.587502, 0.406299 },
+	{ 0.992785, 0.594891, 0.410283 },
+	{ 0.993326, 0.602275, 0.414390 },
+	{ 0.993834, 0.609644, 0.418613 },
+	{ 0.994309, 0.616999, 0.422950 },
+	{ 0.994738, 0.624350, 0.427397 },
+	{ 0.995122, 0.631696, 0.431951 },
+	{ 0.995480, 0.639027, 0.436607 },
+	{ 0.995810, 0.646344, 0.441361 },
+	{ 0.996096, 0.653659, 0.446213 },
+	{ 0.996341, 0.660969, 0.451160 },
+	{ 0.996580, 0.668256, 0.456192 },
+	{ 0.996775, 0.675541, 0.461314 },
+	{ 0.996925, 0.682828, 0.466526 },
+	{ 0.997077, 0.690088, 0.471811 },
+	{ 0.997186, 0.697349, 0.477182 },
+	{ 0.997254, 0.704611, 0.482635 },
+	{ 0.997325, 0.711848, 0.488154 },
+	{ 0.997351, 0.719089, 0.493755 },
+	{ 0.997351, 0.726324, 0.499428 },
+	{ 0.997341, 0.733545, 0.505167 },
+	{ 0.997285, 0.740772, 0.510983 },
+	{ 0.997228, 0.747981, 0.516859 },
+	{ 0.997138, 0.755190, 0.522806 },
+	{ 0.997019, 0.762398, 0.528821 },
+	{ 0.996898, 0.769591, 0.534892 },
+	{ 0.996727, 0.776795, 0.541039 },
+	{ 0.996571, 0.783977, 0.547233 },
+	{ 0.996369, 0.791167, 0.553499 },
+	{ 0.996162, 0.798348, 0.559820 },
+	{ 0.995932, 0.805527, 0.566202 },
+	{ 0.995680, 0.812706, 0.572645 },
+	{ 0.995424, 0.819875, 0.579140 },
+	{ 0.995131, 0.827052, 0.585701 },
+	{ 0.994851, 0.834213, 0.592307 },
+	{ 0.994524, 0.841387, 0.598983 },
+	{ 0.994222, 0.848540, 0.605696 },
+	{ 0.993866, 0.855711, 0.612482 },
+	{ 0.993545, 0.862859, 0.619299 },
+	{ 0.993170, 0.870024, 0.626189 },
+	{ 0.992831, 0.877168, 0.633109 },
+	{ 0.992440, 0.884330, 0.640099 },
+	{ 0.992089, 0.891470, 0.647116 },
+	{ 0.991688, 0.898627, 0.654202 },
+	{ 0.991332, 0.905763, 0.661309 },
+	{ 0.990930, 0.912915, 0.668481 },
+	{ 0.990570, 0.920049, 0.675675 },
+	{ 0.990175, 0.927196, 0.682926 },
+	{ 0.989815, 0.934329, 0.690198 },
+	{ 0.989434, 0.941470, 0.697519 },
+	{ 0.989077, 0.948604, 0.704863 },
+	{ 0.988717, 0.955742, 0.712242 },
+	{ 0.988367, 0.962878, 0.719649 },
+	{ 0.988033, 0.970012, 0.727077 },
+	{ 0.987691, 0.977154, 0.734536 },
+	{ 0.987387, 0.984288, 0.742002 },
+	{ 0.987053, 0.991438, 0.749504 }
+};
+
+static double plasma_cm[256][3] = {
+	{ 0.050383, 0.029803, 0.527975 },
+	{ 0.063536, 0.028426, 0.533124 },
+	{ 0.075353, 0.027206, 0.538007 },
+	{ 0.086222, 0.026125, 0.542658 },
+	{ 0.096379, 0.025165, 0.547103 },
+	{ 0.105980, 0.024309, 0.551368 },
+	{ 0.115124, 0.023556, 0.555468 },
+	{ 0.123903, 0.022878, 0.559423 },
+	{ 0.132381, 0.022258, 0.563250 },
+	{ 0.140603, 0.021687, 0.566959 },
+	{ 0.148607, 0.021154, 0.570562 },
+	{ 0.156421, 0.020651, 0.574065 },
+	{ 0.164070, 0.020171, 0.577478 },
+	{ 0.171574, 0.019706, 0.580806 },
+	{ 0.178950, 0.019252, 0.584054 },
+	{ 0.186213, 0.018803, 0.587228 },
+	{ 0.193374, 0.018354, 0.590330 },
+	{ 0.200445, 0.017902, 0.593364 },
+	{ 0.207435, 0.017442, 0.596333 },
+	{ 0.214350, 0.016973, 0.599239 },
+	{ 0.221197, 0.016497, 0.602083 },
+	{ 0.227983, 0.016007, 0.604867 },
+	{ 0.234715, 0.015502, 0.607592 },
+	{ 0.241396, 0.014979, 0.610259 },
+	{ 0.248032, 0.014439, 0.612868 },
+	{ 0.254627, 0.013882, 0.615419 },
+	{ 0.261183, 0.013308, 0.617911 },
+	{ 0.267703, 0.012716, 0.620346 },
+	{ 0.274191, 0.012109, 0.622722 },
+	{ 0.280648, 0.011488, 0.625038 },
+	{ 0.287076, 0.010855, 0.627295 },
+	{ 0.293478, 0.010213, 0.629490 },
+	{ 0.299855, 0.009561, 0.631624 },
+	{ 0.306210, 0.008902, 0.633694 },
+	{ 0.312543, 0.008239, 0.635700 },
+	{ 0.318856, 0.007576, 0.637640 },
+	{ 0.325150, 0.006915, 0.639512 },
+	{ 0.331426, 0.006261, 0.641316 },
+	{ 0.337683, 0.005618, 0.643049 },
+	{ 0.343925, 0.004991, 0.644710 },
+	{ 0.350150, 0.004382, 0.646298 },
+	{ 0.356359, 0.003798, 0.647810 },
+	{ 0.362553, 0.003243, 0.649245 },
+	{ 0.368733, 0.002724, 0.650601 },
+	{ 0.374897, 0.002245, 0.651876 },
+	{ 0.381047, 0.001814, 0.653068 },
+	{ 0.387183, 0.001434, 0.654177 },
+	{ 0.393304, 0.001114, 0.655199 },
+	{ 0.399411, 0.000859, 0.656133 },
+	{ 0.405503, 0.000678, 0.656977 },
+	{ 0.411580, 0.000577, 0.657730 },
+	{ 0.417642, 0.000564, 0.658390 },
+	{ 0.423689, 0.000646, 0.658956 },
+	{ 0.429719, 0.000831, 0.659425 },
+	{ 0.435734, 0.001127, 0.659797 },
+	{ 0.441732, 0.001540, 0.660069 },
+	{ 0.447714, 0.002080, 0.660240 },
+	{ 0.453677, 0.002755, 0.660310 },
+	{ 0.459623, 0.003574, 0.660277 },
+	{ 0.465550, 0.004545, 0.660139 },
+	{ 0.471457, 0.005678, 0.659897 },
+	{ 0.477344, 0.006980, 0.659549 },
+	{ 0.483210, 0.008460, 0.659095 },
+	{ 0.489055, 0.010127, 0.658534 },
+	{ 0.494877, 0.011990, 0.657865 },
+	{ 0.500678, 0.014055, 0.657088 },
+	{ 0.506454, 0.016333, 0.656202 },
+	{ 0.512206, 0.018833, 0.655209 },
+	{ 0.517933, 0.021563, 0.654109 },
+	{ 0.523633, 0.024532, 0.652901 },
+	{ 0.529306, 0.027747, 0.651586 },
+	{ 0.534952, 0.031217, 0.650165 },
+	{ 0.540570, 0.034950, 0.648640 },
+	{ 0.546157, 0.038954, 0.647010 },
+	{ 0.551715, 0.043136, 0.645277 },
+	{ 0.557243, 0.047331, 0.643443 },
+	{ 0.562738, 0.051545, 0.641509 },
+	{ 0.568201, 0.055778, 0.639477 },
+	{ 0.573632, 0.060028, 0.637349 },
+	{ 0.579029, 0.064296, 0.635126 },
+	{ 0.584391, 0.068579, 0.632812 },
+	{ 0.589719, 0.072878, 0.630408 },
+	{ 0.595011, 0.077190, 0.627917 },
+	{ 0.600266, 0.081516, 0.625342 },
+	{ 0.605485, 0.085854, 0.622686 },
+	{ 0.610667, 0.090204, 0.619951 },
+	{ 0.615812, 0.094564, 0.617140 },
+	{ 0.620919, 0.098934, 0.614257 },
+	{ 0.625987, 0.103312, 0.611305 },
+	{ 0.631017, 0.107699, 0.608287 },
+	{ 0.636008, 0.112092, 0.605205 },
+	{ 0.640959, 0.116492, 0.602065 },
+	{ 0.645872, 0.120898, 0.598867 },
+	{ 0.650746, 0.125309, 0.595617 },
+	{ 0.655580, 0.129725, 0.592317 },
+	{ 0.660374, 0.134144, 0.588971 },
+	{ 0.665129, 0.138566, 0.585582 },
+	{ 0.669845, 0.142992, 0.582154 },
+	{ 0.674522, 0.147419, 0.578688 },
+	{ 0.679160, 0.151848, 0.575189 },
+	{ 0.683758, 0.156278, 0.571660 },
+	{ 0.688318, 0.160709, 0.568103 },
+	{ 0.692840, 0.165141, 0.564522 },
+	{ 0.697324, 0.169573, 0.560919 },
+	{ 0.701769, 0.174005, 0.557296 },
+	{ 0.706178, 0.178437, 0.553657 },
+	{ 0.710549, 0.182868, 0.550004 },
+	{ 0.714883, 0.187299, 0.546338 },
+	{ 0.719181, 0.191729, 0.542663 },
+	{ 0.723444, 0.196158, 0.538981 },
+	{ 0.727670, 0.200586, 0.535293 },
+	{ 0.731862, 0.205013, 0.531601 },
+	{ 0.736019, 0.209439, 0.527908 },
+	{ 0.740143, 0.213864, 0.524216 },
+	{ 0.744232, 0.218288, 0.520524 },
+	{ 0.748289, 0.222711, 0.516834 },
+	{ 0.752312, 0.227133, 0.513149 },
+	{ 0.756304, 0.231555, 0.509468 },
+	{ 0.760264, 0.235976, 0.505794 },
+	{ 0.764193, 0.240396, 0.502126 },
+	{ 0.768090, 0.244817, 0.498465 },
+	{ 0.771958, 0.249237, 0.494813 },
+	{ 0.775796, 0.253658, 0.491171 },
+	{ 0.779604, 0.258078, 0.487539 },
+	{ 0.783383, 0.262500, 0.483918 },
+	{ 0.787133, 0.266922, 0.480307 },
+	{ 0.790855, 0.271345, 0.476706 },
+	{ 0.794549, 0.275770, 0.473117 },
+	{ 0.798216, 0.280197, 0.469538 },
+	{ 0.801855, 0.284626, 0.465971 },
+	{ 0.805467, 0.289057, 0.462415 },
+	{ 0.809052, 0.293491, 0.458870 },
+	{ 0.812612, 0.297928, 0.455338 },
+	{ 0.816144, 0.302368, 0.451816 },
+	{ 0.819651, 0.306812, 0.448306 },
+	{ 0.823132, 0.311261, 0.444806 },
+	{ 0.826588, 0.315714, 0.441316 },
+	{ 0.830018, 0.320172, 0.437836 },
+	{ 0.833422, 0.324635, 0.434366 },
+	{ 0.836801, 0.329105, 0.430905 },
+	{ 0.840155, 0.333580, 0.427455 },
+	{ 0.843484, 0.338062, 0.424013 },
+	{ 0.846788, 0.342551, 0.420579 },
+	{ 0.850066, 0.347048, 0.417153 },
+	{ 0.853319, 0.351553, 0.413734 },
+	{ 0.856547, 0.356066, 0.410322 },
+	{ 0.859750, 0.360588, 0.406917 },
+	{ 0.862927, 0.365119, 0.403519 },
+	{ 0.866078, 0.369660, 0.400126 },
+	{ 0.869203, 0.374212, 0.396738 },
+	{ 0.872303, 0.378774, 0.393355 },
+	{ 0.875376, 0.383347, 0.389976 },
+	{ 0.878423, 0.387932, 0.386600 },
+	{ 0.881443, 0.392529, 0.383229 },
+	{ 0.884436, 0.397139, 0.379860 },
+	{ 0.887402, 0.401762, 0.376494 },
+	{ 0.890340, 0.406398, 0.373130 },
+	{ 0.893250, 0.411048, 0.369768 },
+	{ 0.896131, 0.415712, 0.366407 },
+	{ 0.898984, 0.420392, 0.363047 },
+	{ 0.901807, 0.425087, 0.359688 },
+	{ 0.904601, 0.429797, 0.356329 },
+	{ 0.907365, 0.434524, 0.352970 },
+	{ 0.910098, 0.439268, 0.349610 },
+	{ 0.912800, 0.444029, 0.346251 },
+	{ 0.915471, 0.448807, 0.342890 },
+	{ 0.918109, 0.453603, 0.339529 },
+	{ 0.920714, 0.458417, 0.336166 },
+	{ 0.923287, 0.463251, 0.332801 },
+	{ 0.925825, 0.468103, 0.329435 },
+	{ 0.928329, 0.472975, 0.326067 },
+	{ 0.930798, 0.477867, 0.322697 },
+	{ 0.933232, 0.482780, 0.319325 },
+	{ 0.935630, 0.487712, 0.315952 },
+	{ 0.937990, 0.492667, 0.312575 },
+	{ 0.940313, 0.497642, 0.309197 },
+	{ 0.942598, 0.502639, 0.305816 },
+	{ 0.944844, 0.507658, 0.302433 },
+	{ 0.947051, 0.512699, 0.299049 },
+	{ 0.949217, 0.517763, 0.295662 },
+	{ 0.951344, 0.522850, 0.292275 },
+	{ 0.953428, 0.527960, 0.288883 },
+	{ 0.955470, 0.533093, 0.285490 },
+	{ 0.957469, 0.538250, 0.282096 },
+	{ 0.959424, 0.543431, 0.278701 },
+	{ 0.961336, 0.548636, 0.275305 },
+	{ 0.963203, 0.553865, 0.271909 },
+	{ 0.965024, 0.559118, 0.268513 },
+	{ 0.966798, 0.564396, 0.265118 },
+	{ 0.968526, 0.569700, 0.261721 },
+	{ 0.970205, 0.575028, 0.258325 },
+	{ 0.971835, 0.580382, 0.254931 },
+	{ 0.973416, 0.585761, 0.251540 },
+	{ 0.974947, 0.591165, 0.248151 },
+	{ 0.976428, 0.596595, 0.244767 },
+	{ 0.977856, 0.602051, 0.241387 },
+	{ 0.979233, 0.607532, 0.238013 },
+	{ 0.980556, 0.613039, 0.234646 },
+	{ 0.981826, 0.618572, 0.231287 },
+	{ 0.983041, 0.624131, 0.227937 },
+	{ 0.984199, 0.629718, 0.224595 },
+	{ 0.985301, 0.635330, 0.221265 },
+	{ 0.986345, 0.640969, 0.217948 },
+	{ 0.987332, 0.646633, 0.214648 },
+	{ 0.988260, 0.652325, 0.211364 },
+	{ 0.989128, 0.658043, 0.208100 },
+	{ 0.989935, 0.663787, 0.204859 },
+	{ 0.990681, 0.669558, 0.201642 },
+	{ 0.991365, 0.675355, 0.198453 },
+	{ 0.991985, 0.681179, 0.195295 },
+	{ 0.992541, 0.687030, 0.192170 },
+	{ 0.993032, 0.692907, 0.189084 },
+	{ 0.993456, 0.698810, 0.186041 },
+	{ 0.993814, 0.704741, 0.183043 },
+	{ 0.994103, 0.710698, 0.180097 },
+	{ 0.994324, 0.716681, 0.177208 },
+	{ 0.994474, 0.722691, 0.174381 },
+	{ 0.994553, 0.728728, 0.171622 },
+	{ 0.994561, 0.734791, 0.168938 },
+	{ 0.994495, 0.740880, 0.166335 },
+	{ 0.994355, 0.746995, 0.163821 },
+	{ 0.994141, 0.753137, 0.161404 },
+	{ 0.993851, 0.759304, 0.159092 },
+	{ 0.993482, 0.765499, 0.156891 },
+	{ 0.993033, 0.771720, 0.154808 },
+	{ 0.992505, 0.777967, 0.152855 },
+	{ 0.991897, 0.784239, 0.151042 },
+	{ 0.991209, 0.790537, 0.149377 },
+	{ 0.990439, 0.796859, 0.147870 },
+	{ 0.989587, 0.803205, 0.146529 },
+	{ 0.988648, 0.809579, 0.145357 },
+	{ 0.987621, 0.815978, 0.144363 },
+	{ 0.986509, 0.822401, 0.143557 },
+	{ 0.985314, 0.828846, 0.142945 },
+	{ 0.984031, 0.835315, 0.142528 },
+	{ 0.982653, 0.841812, 0.142303 },
+	{ 0.981190, 0.848329, 0.142279 },
+	{ 0.979644, 0.854866, 0.142453 },
+	{ 0.977995, 0.861432, 0.142808 },
+	{ 0.976265, 0.868016, 0.143351 },
+	{ 0.974443, 0.874622, 0.144061 },
+	{ 0.972530, 0.881250, 0.144923 },
+	{ 0.970533, 0.887896, 0.145919 },
+	{ 0.968443, 0.894564, 0.147014 },
+	{ 0.966271, 0.901249, 0.148180 },
+	{ 0.964021, 0.907950, 0.149370 },
+	{ 0.961681, 0.914672, 0.150520 },
+	{ 0.959276, 0.921407, 0.151566 },
+	{ 0.956808, 0.928152, 0.152409 },
+	{ 0.954287, 0.934908, 0.152921 },
+	{ 0.951726, 0.941671, 0.152925 },
+	{ 0.949151, 0.948435, 0.152178 },
+	{ 0.946602, 0.955190, 0.150328 },
+	{ 0.944152, 0.961916, 0.146861 },
+	{ 0.941896, 0.968590, 0.140956 },
+	{ 0.940015, 0.975158, 0.131326 }
+};
+
+static double viridis_cm[256][3] = {
+	{ 0.267004, 0.004874, 0.329415 },
+	{ 0.268510, 0.009605, 0.335427 },
+	{ 0.269944, 0.014625, 0.341379 },
+	{ 0.271305, 0.019942, 0.347269 },
+	{ 0.272594, 0.025563, 0.353093 },
+	{ 0.273809, 0.031497, 0.358853 },
+	{ 0.274952, 0.037752, 0.364543 },
+	{ 0.276022, 0.044167, 0.370164 },
+	{ 0.277018, 0.050344, 0.375715 },
+	{ 0.277941, 0.056324, 0.381191 },
+	{ 0.278791, 0.062145, 0.386592 },
+	{ 0.279566, 0.067836, 0.391917 },
+	{ 0.280267, 0.073417, 0.397163 },
+	{ 0.280894, 0.078907, 0.402329 },
+	{ 0.281446, 0.084320, 0.407414 },
+	{ 0.281924, 0.089666, 0.412415 },
+	{ 0.282327, 0.094955, 0.417331 },
+	{ 0.282656, 0.100196, 0.422160 },
+	{ 0.282910, 0.105393, 0.426902 },
+	{ 0.283091, 0.110553, 0.431554 },
+	{ 0.283197, 0.115680, 0.436115 },
+	{ 0.283229, 0.120777, 0.440584 },
+	{ 0.283187, 0.125848, 0.444960 },
+	{ 0.283072, 0.130895, 0.449241 },
+	{ 0.282884, 0.135920, 0.453427 },
+	{ 0.282623, 0.140926, 0.457517 },
+	{ 0.282290, 0.145912, 0.461510 },
+	{ 0.281887, 0.150881, 0.465405 },
+	{ 0.281412, 0.155834, 0.469201 },
+	{ 0.280868, 0.160771, 0.472899 },
+	{ 0.280255, 0.165693, 0.476498 },
+	{ 0.279574, 0.170599, 0.479997 },
+	{ 0.278826, 0.175490, 0.483397 },
+	{ 0.278012, 0.180367, 0.486697 },
+	{ 0.277134, 0.185228, 0.489898 },
+	{ 0.276194, 0.190074, 0.493001 },
+	{ 0.275191, 0.194905, 0.496005 },
+	{ 0.274128, 0.199721, 0.498911 },
+	{ 0.273006, 0.204520, 0.501721 },
+	{ 0.271828, 0.209303, 0.504434 },
+	{ 0.270595, 0.214069, 0.507052 },
+	{ 0.269308, 0.218818, 0.509577 },
+	{ 0.267968, 0.223549, 0.512008 },
+	{ 0.266580, 0.228262, 0.514349 },
+	{ 0.265145, 0.232956, 0.516599 },
+	{ 0.263663, 0.237631, 0.518762 },
+	{ 0.262138, 0.242286, 0.520837 },
+	{ 0.260571, 0.246922, 0.522828 },
+	{ 0.258965, 0.251537, 0.524736 },
+	{ 0.257322, 0.256130, 0.526563 },
+	{ 0.255645, 0.260703, 0.528312 },
+	{ 0.253935, 0.265254, 0.529983 },
+	{ 0.252194, 0.269783, 0.531579 },
+	{ 0.250425, 0.274290, 0.533103 },
+	{ 0.248629, 0.278775, 0.534556 },
+	{ 0.246811, 0.283237, 0.535941 },
+	{ 0.244972, 0.287675, 0.537260 },
+	{ 0.243113, 0.292092, 0.538516 },
+	{ 0.241237, 0.296485, 0.539709 },
+	{ 0.239346, 0.300855, 0.540844 },
+	{ 0.237441, 0.305202, 0.541921 },
+	{ 0.235526, 0.309527, 0.542944 },
+	{ 0.233603, 0.313828, 0.543914 },
+	{ 0.231674, 0.318106, 0.544834 },
+	{ 0.229739, 0.322361, 0.545706 },
+	{ 0.227802, 0.326594, 0.546532 },
+	{ 0.225863, 0.330805, 0.547314 },
+	{ 0.223925, 0.334994, 0.548053 },
+	{ 0.221989, 0.339161, 0.548752 },
+	{ 0.220057, 0.343307, 0.549413 },
+	{ 0.218130, 0.347432, 0.550038 },
+	{ 0.216210, 0.351535, 0.550627 },
+	{ 0.214298, 0.355619, 0.551184 },
+	{ 0.212395, 0.359683, 0.551710 },
+	{ 0.210503, 0.363727, 0.552206 },
+	{ 0.208623, 0.367752, 0.552675 },
+	{ 0.206756, 0.371758, 0.553117 },
+	{ 0.204903, 0.375746, 0.553533 },
+	{ 0.203063, 0.379716, 0.553925 },
+	{ 0.201239, 0.383670, 0.554294 },
+	{ 0.199430, 0.387607, 0.554642 },
+	{ 0.197636, 0.391528, 0.554969 },
+	{ 0.195860, 0.395433, 0.555276 },
+	{ 0.194100, 0.399323, 0.555565 },
+	{ 0.192357, 0.403199, 0.555836 },
+	{ 0.190631, 0.407061, 0.556089 },
+	{ 0.188923, 0.410910, 0.556326 },
+	{ 0.187231, 0.414746, 0.556547 },
+	{ 0.185556, 0.418570, 0.556753 },
+	{ 0.183898, 0.422383, 0.556944 },
+	{ 0.182256, 0.426184, 0.557120 },
+	{ 0.180629, 0.429975, 0.557282 },
+	{ 0.179019, 0.433756, 0.557430 },
+	{ 0.177423, 0.437527, 0.557565 },
+	{ 0.175841, 0.441290, 0.557685 },
+	{ 0.174274, 0.445044, 0.557792 },
+	{ 0.172719, 0.448791, 0.557885 },
+	{ 0.171176, 0.452530, 0.557965 },
+	{ 0.169646, 0.456262, 0.558030 },
+	{ 0.168126, 0.459988, 0.558082 },
+	{ 0.166617, 0.463708, 0.558119 },
+	{ 0.165117, 0.467423, 0.558141 },
+	{ 0.163625, 0.471133, 0.558148 },
+	{ 0.162142, 0.474838, 0.558140 },
+	{ 0.160665, 0.478540, 0.558115 },
+	{ 0.159194, 0.482237, 0.558073 },
+	{ 0.157729, 0.485932, 0.558013 },
+	{ 0.156270, 0.489624, 0.557936 },
+	{ 0.154815, 0.493313, 0.557840 },
+	{ 0.153364, 0.497000, 0.557724 },
+	{ 0.151918, 0.500685, 0.557587 },
+	{ 0.150476, 0.504369, 0.557430 },
+	{ 0.149039, 0.508051, 0.557250 },
+	{ 0.147607, 0.511733, 0.557049 },
+	{ 0.146180, 0.515413, 0.556823 },
+	{ 0.144759, 0.519093, 0.556572 },
+	{ 0.143343, 0.522773, 0.556295 },
+	{ 0.141935, 0.526453, 0.555991 },
+	{ 0.140536, 0.530132, 0.555659 },
+	{ 0.139147, 0.533812, 0.555298 },
+	{ 0.137770, 0.537492, 0.554906 },
+	{ 0.136408, 0.541173, 0.554483 },
+	{ 0.135066, 0.544853, 0.554029 },
+	{ 0.133743, 0.548535, 0.553541 },
+	{ 0.132444, 0.552216, 0.553018 },
+	{ 0.131172, 0.555899, 0.552459 },
+	{ 0.129933, 0.559582, 0.551864 },
+	{ 0.128729, 0.563265, 0.551229 },
+	{ 0.127568, 0.566949, 0.550556 },
+	{ 0.126453, 0.570633, 0.549841 },
+	{ 0.125394, 0.574318, 0.549086 },
+	{ 0.124395, 0.578002, 0.548287 },
+	{ 0.123463, 0.581687, 0.547445 },
+	{ 0.122606, 0.585371, 0.546557 },
+	{ 0.121831, 0.589055, 0.545623 },
+	{ 0.121148, 0.592739, 0.544641 },
+	{ 0.120565, 0.596422, 0.543611 },
+	{ 0.120092, 0.600104, 0.542530 },
+	{ 0.119738, 0.603785, 0.541400 },
+	{ 0.119512, 0.607464, 0.540218 },
+	{ 0.119423, 0.611141, 0.538982 },
+	{ 0.119483, 0.614817, 0.537692 },
+	{ 0.119699, 0.618490, 0.536347 },
+	{ 0.120081, 0.622161, 0.534946 },
+	{ 0.120638, 0.625828, 0.533488 },
+	{ 0.121380, 0.629492, 0.531973 },
+	{ 0.122312, 0.633153, 0.530398 },
+	{ 0.123444, 0.636809, 0.528763 },
+	{ 0.124780, 0.640461, 0.527068 },
+	{ 0.126326, 0.644107, 0.525311 },
+	{ 0.128087, 0.647749, 0.523491 },
+	{ 0.130067, 0.651384, 0.521608 },
+	{ 0.132268, 0.655014, 0.519661 },
+	{ 0.134692, 0.658636, 0.517649 },
+	{ 0.137339, 0.662252, 0.515571 },
+	{ 0.140210, 0.665859, 0.513427 },
+	{ 0.143303, 0.669459, 0.511215 },
+	{ 0.146616, 0.673050, 0.508936 },
+	{ 0.150148, 0.676631, 0.506589 },
+	{ 0.153894, 0.680203, 0.504172 },
+	{ 0.157851, 0.683765, 0.501686 },
+	{ 0.162016, 0.687316, 0.499129 },
+	{ 0.166383, 0.690856, 0.496502 },
+	{ 0.170948, 0.694384, 0.493803 },
+	{ 0.175707, 0.697900, 0.491033 },
+	{ 0.180653, 0.701402, 0.488189 },
+	{ 0.185783, 0.704891, 0.485273 },
+	{ 0.191090, 0.708366, 0.482284 },
+	{ 0.196571, 0.711827, 0.479221 },
+	{ 0.202219, 0.715272, 0.476084 },
+	{ 0.208030, 0.718701, 0.472873 },
+	{ 0.214000, 0.722114, 0.469588 },
+	{ 0.220124, 0.725509, 0.466226 },
+	{ 0.226397, 0.728888, 0.462789 },
+	{ 0.232815, 0.732247, 0.459277 },
+	{ 0.239374, 0.735588, 0.455688 },
+	{ 0.246070, 0.738910, 0.452024 },
+	{ 0.252899, 0.742211, 0.448284 },
+	{ 0.259857, 0.745492, 0.444467 },
+	{ 0.266941, 0.748751, 0.440573 },
+	{ 0.274149, 0.751988, 0.436601 },
+	{ 0.281477, 0.755203, 0.432552 },
+	{ 0.288921, 0.758394, 0.428426 },
+	{ 0.296479, 0.761561, 0.424223 },
+	{ 0.304148, 0.764704, 0.419943 },
+	{ 0.311925, 0.767822, 0.415586 },
+	{ 0.319809, 0.770914, 0.411152 },
+	{ 0.327796, 0.773980, 0.406640 },
+	{ 0.335885, 0.777018, 0.402049 },
+	{ 0.344074, 0.780029, 0.397381 },
+	{ 0.352360, 0.783011, 0.392636 },
+	{ 0.360741, 0.785964, 0.387814 },
+	{ 0.369214, 0.788888, 0.382914 },
+	{ 0.377779, 0.791781, 0.377939 },
+	{ 0.386433, 0.794644, 0.372886 },
+	{ 0.395174, 0.797475, 0.367757 },
+	{ 0.404001, 0.800275, 0.362552 },
+	{ 0.412913, 0.803041, 0.357269 },
+	{ 0.421908, 0.805774, 0.351910 },
+	{ 0.430983, 0.808473, 0.346476 },
+	{ 0.440137, 0.811138, 0.340967 },
+	{ 0.449368, 0.813768, 0.335384 },
+	{ 0.458674, 0.816363, 0.329727 },
+	{ 0.468053, 0.818921, 0.323998 },
+	{ 0.477504, 0.821444, 0.318195 },
+	{ 0.487026, 0.823929, 0.312321 },
+	{ 0.496615, 0.826376, 0.306377 },
+	{ 0.506271, 0.828786, 0.300362 },
+	{ 0.515992, 0.831158, 0.294279 },
+	{ 0.525776, 0.833491, 0.288127 },
+	{ 0.535621, 0.835785, 0.281908 },
+	{ 0.545524, 0.838039, 0.275626 },
+	{ 0.555484, 0.840254, 0.269281 },
+	{ 0.565498, 0.842430, 0.262877 },
+	{ 0.575563, 0.844566, 0.256415 },
+	{ 0.585678, 0.846661, 0.249897 },
+	{ 0.595839, 0.848717, 0.243329 },
+	{ 0.606045, 0.850733, 0.236712 },
+	{ 0.616293, 0.852709, 0.230052 },
+	{ 0.626579, 0.854645, 0.223353 },
+	{ 0.636902, 0.856542, 0.216620 },
+	{ 0.647257, 0.858400, 0.209861 },
+	{ 0.657642, 0.860219, 0.203082 },
+	{ 0.668054, 0.861999, 0.196293 },
+	{ 0.678489, 0.863742, 0.189503 },
+	{ 0.688944, 0.865448, 0.182725 },
+	{ 0.699415, 0.867117, 0.175971 },
+	{ 0.709898, 0.868751, 0.169257 },
+	{ 0.720391, 0.870350, 0.162603 },
+	{ 0.730889, 0.871916, 0.156029 },
+	{ 0.741388, 0.873449, 0.149561 },
+	{ 0.751884, 0.874951, 0.143228 },
+	{ 0.762373, 0.876424, 0.137064 },
+	{ 0.772852, 0.877868, 0.131109 },
+	{ 0.783315, 0.879285, 0.125405 },
+	{ 0.793760, 0.880678, 0.120005 },
+	{ 0.804182, 0.882046, 0.114965 },
+	{ 0.814576, 0.883393, 0.110347 },
+	{ 0.824940, 0.884720, 0.106217 },
+	{ 0.835270, 0.886029, 0.102646 },
+	{ 0.845561, 0.887322, 0.099702 },
+	{ 0.855810, 0.888601, 0.097452 },
+	{ 0.866013, 0.889868, 0.095953 },
+	{ 0.876168, 0.891125, 0.095250 },
+	{ 0.886271, 0.892374, 0.095374 },
+	{ 0.896320, 0.893616, 0.096335 },
+	{ 0.906311, 0.894855, 0.098125 },
+	{ 0.916242, 0.896091, 0.100717 },
+	{ 0.926106, 0.897330, 0.104071 },
+	{ 0.935904, 0.898570, 0.108131 },
+	{ 0.945636, 0.899815, 0.112838 },
+	{ 0.955300, 0.901065, 0.118128 },
+	{ 0.964894, 0.902323, 0.123941 },
+	{ 0.974417, 0.903590, 0.130215 },
+	{ 0.983868, 0.904867, 0.136897 },
+	{ 0.993248, 0.906157, 0.143936 }
+};
+
+static double parula_cm[256][3] = {
+	{ 0.2081, 0.1663, 0.5292 },
+	{ 0.2091, 0.1721, 0.5411 },
+	{ 0.2101, 0.1779, 0.553	 },
+	{ 0.2109, 0.1837, 0.565	 },
+	{ 0.2116, 0.1895, 0.5771 },
+	{ 0.2121, 0.1954, 0.5892 },
+	{ 0.2124, 0.2013, 0.6013 },
+	{ 0.2125, 0.2072, 0.6135 },
+	{ 0.2123, 0.2132, 0.6258 },
+	{ 0.2118, 0.2192, 0.6381 },
+	{ 0.2111, 0.2253, 0.6505 },
+	{ 0.2099, 0.2315, 0.6629 },
+	{ 0.2084, 0.2377, 0.6753 },
+	{ 0.2063, 0.244, 0.6878	 },
+	{ 0.2038, 0.2503, 0.7003 },
+	{ 0.2006, 0.2568, 0.7129 },
+	{ 0.1968, 0.2632, 0.7255 },
+	{ 0.1921, 0.2698, 0.7381 },
+	{ 0.1867, 0.2764, 0.7507 },
+	{ 0.1802, 0.2832, 0.7634 },
+	{ 0.1728, 0.2902, 0.7762 },
+	{ 0.1641, 0.2975, 0.789	 },
+	{ 0.1541, 0.3052, 0.8017 },
+	{ 0.1427, 0.3132, 0.8145 },
+	{ 0.1295, 0.3217, 0.8269 },
+	{ 0.1147, 0.3306, 0.8387 },
+	{ 0.0986, 0.3397, 0.8495 },
+	{ 0.0816, 0.3486, 0.8588 },
+	{ 0.0646, 0.3572, 0.8664 },
+	{ 0.0482, 0.3651, 0.8722 },
+	{ 0.0329, 0.3724, 0.8765 },
+	{ 0.0213, 0.3792, 0.8796 },
+	{ 0.0136, 0.3853, 0.8815 },
+	{ 0.0086, 0.3911, 0.8827 },
+	{ 0.006,  0.3965, 0.8833 },
+	{ 0.0051, 0.4017, 0.8834 },
+	{ 0.0054, 0.4066, 0.8831 },
+	{ 0.0067, 0.4113, 0.8825 },
+	{ 0.0089, 0.4159, 0.8816 },
+	{ 0.0116, 0.4203, 0.8805 },
+	{ 0.0148, 0.4246, 0.8793 },
+	{ 0.0184, 0.4288, 0.8779 },
+	{ 0.0223, 0.4329, 0.8763 },
+	{ 0.0264, 0.437, 0.8747	 },
+	{ 0.0306, 0.441, 0.8729	 },
+	{ 0.0349, 0.4449, 0.8711 },
+	{ 0.0394, 0.4488, 0.8692 },
+	{ 0.0437, 0.4526, 0.8672 },
+	{ 0.0477, 0.4564, 0.8652 },
+	{ 0.0514, 0.4602, 0.8632 },
+	{ 0.0549, 0.464, 0.8611	 },
+	{ 0.0582, 0.4677, 0.8589 },
+	{ 0.0612, 0.4714, 0.8568 },
+	{ 0.064,  0.4751, 0.8546 },
+	{ 0.0666, 0.4788, 0.8525 },
+	{ 0.0689, 0.4825, 0.8503 },
+	{ 0.071,  0.4862, 0.8481 },
+	{ 0.0729, 0.4899, 0.846	 },
+	{ 0.0746, 0.4937, 0.8439 },
+	{ 0.0761, 0.4974, 0.8418 },
+	{ 0.0773, 0.5012, 0.8398 },
+	{ 0.0782, 0.5051, 0.8378 },
+	{ 0.0789, 0.5089, 0.8359 },
+	{ 0.0794, 0.5129, 0.8341 },
+	{ 0.0795, 0.5169, 0.8324 },
+	{ 0.0793, 0.521, 0.8308	 },
+	{ 0.0788, 0.5251, 0.8293 },
+	{ 0.0778, 0.5295, 0.828	 },
+	{ 0.0764, 0.5339, 0.827	 },
+	{ 0.0746, 0.5384, 0.8261 },
+	{ 0.0724, 0.5431, 0.8253 },
+	{ 0.0698, 0.5479, 0.8247 },
+	{ 0.0668, 0.5527, 0.8243 },
+	{ 0.0636, 0.5577, 0.8239 },
+	{ 0.06,   0.5627, 0.8237 },
+	{ 0.0562, 0.5677, 0.8234 },
+	{ 0.0523, 0.5727, 0.8231 },
+	{ 0.0484, 0.5777, 0.8228 },
+	{ 0.0445, 0.5826, 0.8223 },
+	{ 0.0408, 0.5874, 0.8217 },
+	{ 0.0372, 0.5922, 0.8209 },
+	{ 0.0342, 0.5968, 0.8198 },
+	{ 0.0317, 0.6012, 0.8186 },
+	{ 0.0296, 0.6055, 0.8171 },
+	{ 0.0279, 0.6097, 0.8154 },
+	{ 0.0265, 0.6137, 0.8135 },
+	{ 0.0255, 0.6176, 0.8114 },
+	{ 0.0248, 0.6214, 0.8091 },
+	{ 0.0243, 0.625, 0.8066	 },
+	{ 0.0239, 0.6285, 0.8039 },
+	{ 0.0237, 0.6319, 0.801	 },
+	{ 0.0235, 0.6352, 0.798	 },
+	{ 0.0233, 0.6384, 0.7948 },
+	{ 0.0231, 0.6415, 0.7916 },
+	{ 0.023,  0.6445, 0.7881 },
+	{ 0.0229, 0.6474, 0.7846 },
+	{ 0.0227, 0.6503, 0.781, },
+	{ 0.0227, 0.6531, 0.7773 },
+	{ 0.0232, 0.6558, 0.7735 },
+	{ 0.0238, 0.6585, 0.7696 },
+	{ 0.0246, 0.6611, 0.7656 },
+	{ 0.0263, 0.6637, 0.7615 },
+	{ 0.0282, 0.6663, 0.7574 },
+	{ 0.0306, 0.6688, 0.7532 },
+	{ 0.0338, 0.6712, 0.749	 },
+	{ 0.0373, 0.6737, 0.7446 },
+	{ 0.0418, 0.6761, 0.7402 },
+	{ 0.0467, 0.6784, 0.7358 },
+	{ 0.0516, 0.6808, 0.7313 },
+	{ 0.0574, 0.6831, 0.7267 },
+	{ 0.0629, 0.6854, 0.7221 },
+	{ 0.0692, 0.6877, 0.7173 },
+	{ 0.0755, 0.6899, 0.7126 },
+	{ 0.082,  0.6921, 0.7078 },
+	{ 0.0889, 0.6943, 0.7029 },
+	{ 0.0956, 0.6965, 0.6979 },
+	{ 0.1031, 0.6986, 0.6929 },
+	{ 0.1104, 0.7007, 0.6878 },
+	{ 0.118,  0.7028, 0.6827 },
+	{ 0.1258, 0.7049, 0.6775 },
+	{ 0.1335, 0.7069, 0.6723 },
+	{ 0.1418, 0.7089, 0.6669 },
+	{ 0.1499, 0.7109, 0.6616 },
+	{ 0.1585, 0.7129, 0.6561 },
+	{ 0.1671, 0.7148, 0.6507 },
+	{ 0.1758, 0.7168, 0.6451 },
+	{ 0.1849, 0.7186, 0.6395 },
+	{ 0.1938, 0.7205, 0.6338 },
+	{ 0.2033, 0.7223, 0.6281 },
+	{ 0.2128, 0.7241, 0.6223 },
+	{ 0.2224, 0.7259, 0.6165 },
+	{ 0.2324, 0.7275, 0.6107 },
+	{ 0.2423, 0.7292, 0.6048 },
+	{ 0.2527, 0.7308, 0.5988 },
+	{ 0.2631, 0.7324, 0.5929 },
+	{ 0.2735, 0.7339, 0.5869 },
+	{ 0.2845, 0.7354, 0.5809 },
+	{ 0.2953, 0.7368, 0.5749 },
+	{ 0.3064, 0.7381, 0.5689 },
+	{ 0.3177, 0.7394, 0.563	 },
+	{ 0.3289, 0.7406, 0.557	 },
+	{ 0.3405, 0.7417, 0.5512 },
+	{ 0.352,  0.7428, 0.5453 },
+	{ 0.3635, 0.7438, 0.5396 },
+	{ 0.3753, 0.7446, 0.5339 },
+	{ 0.3869, 0.7454, 0.5283 },
+	{ 0.3986, 0.7461, 0.5229 },
+	{ 0.4103, 0.7467, 0.5175 },
+	{ 0.4218, 0.7473, 0.5123 },
+	{ 0.4334, 0.7477, 0.5072 },
+	{ 0.4447, 0.7482, 0.5021 },
+	{ 0.4561, 0.7485, 0.4972 },
+	{ 0.4672, 0.7487, 0.4924 },
+	{ 0.4783, 0.7489, 0.4877 },
+	{ 0.4892, 0.7491, 0.4831 },
+	{ 0.5,    0.7491, 0.4786 },
+	{ 0.5106, 0.7492, 0.4741 },
+	{ 0.5212, 0.7492, 0.4698 },
+	{ 0.5315, 0.7491, 0.4655 },
+	{ 0.5418, 0.749, 0.4613	 },
+	{ 0.5519, 0.7489, 0.4571 },
+	{ 0.5619, 0.7487, 0.4531 },
+	{ 0.5718, 0.7485, 0.449	 },
+	{ 0.5816, 0.7482, 0.4451 },
+	{ 0.5913, 0.7479, 0.4412 },
+	{ 0.6009, 0.7476, 0.4374 },
+	{ 0.6103, 0.7473, 0.4335 },
+	{ 0.6197, 0.7469, 0.4298 },
+	{ 0.629,  0.7465, 0.4261 },
+	{ 0.6382, 0.746, 0.4224	 },
+	{ 0.6473, 0.7456, 0.4188 },
+	{ 0.6564, 0.7451, 0.4152 },
+	{ 0.6653, 0.7446, 0.4116 },
+	{ 0.6742, 0.7441, 0.4081 },
+	{ 0.683,  0.7435, 0.4046 },
+	{ 0.6918, 0.743, 0.4011	 },
+	{ 0.7004, 0.7424, 0.3976 },
+	{ 0.7091, 0.7418, 0.3942 },
+	{ 0.7176, 0.7412, 0.3908 },
+	{ 0.7261, 0.7405, 0.3874 },
+	{ 0.7346, 0.7399, 0.384	 },
+	{ 0.743,  0.7392, 0.3806 },
+	{ 0.7513, 0.7385, 0.3773 },
+	{ 0.7596, 0.7378, 0.3739 },
+	{ 0.7679, 0.7372, 0.3706 },
+	{ 0.7761, 0.7364, 0.3673 },
+	{ 0.7843, 0.7357, 0.3639 },
+	{ 0.7924, 0.735, 0.3606	 },
+	{ 0.8005, 0.7343, 0.3573 },
+	{ 0.8085, 0.7336, 0.3539 },
+	{ 0.8166, 0.7329, 0.3506 },
+	{ 0.8246, 0.7322, 0.3472 },
+	{ 0.8325, 0.7315, 0.3438 },
+	{ 0.8405, 0.7308, 0.3404 },
+	{ 0.8484, 0.7301, 0.337	 },
+	{ 0.8563, 0.7294, 0.3336 },
+	{ 0.8642, 0.7288, 0.33 	 },
+	{ 0.872,  0.7282, 0.3265 },
+	{ 0.8798, 0.7276, 0.3229 },
+	{ 0.8877, 0.7271, 0.3193 },
+	{ 0.8954, 0.7266, 0.3156 },
+	{ 0.9032, 0.7262, 0.3117 },
+	{ 0.911,  0.7259, 0.3078 },
+	{ 0.9187, 0.7256, 0.3038 },
+	{ 0.9264, 0.7256, 0.2996 },
+	{ 0.9341, 0.7256, 0.2953 },
+	{ 0.9417, 0.7259, 0.2907 },
+	{ 0.9493, 0.7264, 0.2859 },
+	{ 0.9567, 0.7273, 0.2808 },
+	{ 0.9639, 0.7285, 0.2754 },
+	{ 0.9708, 0.7303, 0.2696 },
+	{ 0.9773, 0.7326, 0.2634 },
+	{ 0.9831, 0.7355, 0.257	 },
+	{ 0.9882, 0.739, 0.2504	 },
+	{ 0.9922, 0.7431, 0.2437 },
+	{ 0.9952, 0.7476, 0.2373 },
+	{ 0.9973, 0.7524, 0.231	 },
+	{ 0.9986, 0.7573, 0.2251 },
+	{ 0.9991, 0.7624, 0.2195 },
+	{ 0.999,  0.7675, 0.2141 },
+	{ 0.9985, 0.7726, 0.209	 },
+	{ 0.9976, 0.7778, 0.2042 },
+	{ 0.9964, 0.7829, 0.1995 },
+	{ 0.995,  0.788, 0.1949	 },
+	{ 0.9933, 0.7931, 0.1905 },
+	{ 0.9914, 0.7981, 0.1863 },
+	{ 0.9894, 0.8032, 0.1821 },
+	{ 0.9873, 0.8083, 0.178	 },
+	{ 0.9851, 0.8133, 0.174	 },
+	{ 0.9828, 0.8184, 0.17 	 },
+	{ 0.9805, 0.8235, 0.1661 },
+	{ 0.9782, 0.8286, 0.1622 },
+	{ 0.9759, 0.8337, 0.1583 },
+	{ 0.9736, 0.8389, 0.1544 },
+	{ 0.9713, 0.8441, 0.1505 },
+	{ 0.9692, 0.8494, 0.1465 },
+	{ 0.9672, 0.8548, 0.1425 },
+	{ 0.9654, 0.8603, 0.1385 },
+	{ 0.9638, 0.8659, 0.1343 },
+	{ 0.9623, 0.8716, 0.1301 },
+	{ 0.9611, 0.8774, 0.1258 },
+	{ 0.96,   0.8834, 0.1215 },
+	{ 0.9593, 0.8895, 0.1171 },
+	{ 0.9588, 0.8958, 0.1126 },
+	{ 0.9586, 0.9022, 0.1082 },
+	{ 0.9587, 0.9088, 0.1036 },
+	{ 0.9591, 0.9155, 0.099	 },
+	{ 0.9599, 0.9225, 0.0944 },
+	{ 0.961,  0.9296, 0.0897 },
+	{ 0.9624, 0.9368, 0.085	 },
+	{ 0.9641, 0.9443, 0.0802 },
+	{ 0.9662, 0.9518, 0.0753 },
+	{ 0.9685, 0.9595, 0.0703 },
+	{ 0.971,  0.9673, 0.0651 },
+	{ 0.9736, 0.9752, 0.0597 },
+	{ 0.9763, 0.9831, 0.0538 }
+};
+
+template <typename T>
+static IGL_INLINE void cm_jet(const T x_in, T & r, T & g, T & b)
+{
+	// Only important if the number of colors is small. In which case the rest is
+	// still wrong anyway
+	// x = linspace(0,1,jj)' * (1-1/jj) + 1/jj;
+	//
+	const double rone = 0.8;
+	const double gone = 1.0;
+	const double bone = 1.0;
+	T x = x_in;
+	x = (x_in<0 ? 0 : (x>1 ? 1 : x));
+
+	if (x<1. / 8.)
+	{
+		r = 0;
+		g = 0;
+		b = bone*(0.5 + (x) / (1. / 8.)*0.5);
+	} else if (x<3. / 8.)
+	{
+		r = 0;
+		g = gone*(x - 1. / 8.) / (3. / 8. - 1. / 8.);
+		b = bone;
+	} else if (x<5. / 8.)
+	{
+		r = rone*(x - 3. / 8.) / (5. / 8. - 3. / 8.);
+		g = gone;
+		b = (bone - (x - 3. / 8.) / (5. / 8. - 3. / 8.));
+	} else if (x<7. / 8.)
+	{
+		r = rone;
+		g = (gone - (x - 5. / 8.) / (7. / 8. - 5. / 8.));
+		b = 0;
+	} else
+	{
+		r = (rone - (x - 7. / 8.) / (1. - 7. / 8.)*0.5);
+		g = 0;
+		b = 0;
+	}
+}
+
+template <typename T>
+static IGL_INLINE void color_from_palette(const T x_in, T & r, T & g, T & b, double palette[256][3])
+{
+	static const unsigned int pal = 256;
+	const T zero = 0.0;
+	const T one = 1.0;
+	T x_in_clamped = static_cast<T>(std::max(zero, std::min(one, x_in)));
+
+	// simple rgb lerp from palette
+	unsigned int least = std::floor(x_in_clamped * static_cast<T>(pal - 1));
+	unsigned int most = std::ceil(x_in_clamped * static_cast<T>(pal - 1));
+
+	T _r[2] = { static_cast<T>(palette[least][0]), static_cast<T>(palette[most][0]) };
+	T _g[2] = { static_cast<T>(palette[least][1]), static_cast<T>(palette[most][1]) };
+	T _b[2] = { static_cast<T>(palette[least][2]), static_cast<T>(palette[most][2]) };
+
+	T t = std::max(zero, std::min(one, static_cast<T>(fmod(x_in_clamped * static_cast<T>(pal), one))));
+
+	r = std::max(zero, std::min(one, (one - t) * _r[0] + t * _r[1]));
+	g = std::max(zero, std::min(one, (one - t) * _g[0] + t * _g[1]));
+	b = std::max(zero, std::min(one, (one - t) * _b[0] + t * _b[1]));
+}
+
+template <typename T>
+IGL_INLINE void igl::colormap(const T x, T * rgb, ColorMapType cm)
+{
+  return colormap(x,rgb[0],rgb[1],rgb[2],cm);
+}
+
+template <typename T>
+IGL_INLINE void igl::colormap(const T x_in, T & r, T & g, T & b, ColorMapType cm)
+{
+	switch (cm) {
+		case CM_INFERNO: {
+			color_from_palette(x_in, r, g, b, inferno_cm);
+			break;
+		}
+		case CM_JET: {
+			cm_jet(x_in, r, g, b);
+			break;
+		}
+		case CM_MAGMA: {
+			color_from_palette(x_in, r, g, b, magma_cm);
+			break;
+		}
+		case CM_PARULA: {
+			color_from_palette(x_in, r, g, b, parula_cm);
+			break;
+		}
+		case CM_PLASMA: {
+			color_from_palette(x_in, r, g, b, plasma_cm);
+			break;
+		}
+		case CM_VIRIDIS: {
+			color_from_palette(x_in, r, g, b, viridis_cm);
+			break;
+		}
+		default: {
+			throw std::invalid_argument("igl::colormap(): Selected colormap is unsupported!");
+			break;
+		}
+	}
+}
+
+template <typename DerivedZ, typename DerivedC>
+IGL_INLINE void igl::colormap(
+  const Eigen::PlainObjectBase<DerivedZ> & Z,
+  const bool normalize,
+  Eigen::PlainObjectBase<DerivedC> & C,
+  ColorMapType cm)
+{
+  const double min_z = normalize ? Z.minCoeff() : 0;
+  const double max_z = normalize ? Z.maxCoeff() : -1;
+  return colormap(Z, min_z, max_z, C, cm);
+}
+
+template <typename DerivedZ, typename DerivedC>
+IGL_INLINE void igl::colormap(
+  const Eigen::PlainObjectBase<DerivedZ> & Z,
+  const double min_z,
+  const double max_z,
+  Eigen::PlainObjectBase<DerivedC> & C,
+  ColorMapType cm)
+{
+  C.resize(Z.rows(),3);
+  double denom = (max_z - min_z);
+  denom = (denom == 0) ? 1 : denom;
+  for(int r = 0; r < Z.rows(); ++r) {
+	colormap(
+      (typename DerivedC::Scalar)((-min_z + Z(r,0)) / denom),
+      C(r,0),
+      C(r,1),
+      C(r,2),
+	  cm);
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::colormap<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<double>(double, double*, ColorMapType cm);
+template void igl::colormap<double>(double, double&, double&, double&, ColorMapType cm);
+template void igl::colormap<float>(float, float*, ColorMapType cm);
+template void igl::colormap<Eigen::Array<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Array<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<float>(float, float&, float&, float&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+template void igl::colormap<Eigen::Array<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Array<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, ColorMapType cm);
+#endif

+ 77 - 0
include/igl/colormap.h

@@ -0,0 +1,77 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2017 Joe Graus <jgraus@gmu.edu>, Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// 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/.
+
+#ifndef IGL_COLORMAP_H
+#define IGL_COLORMAP_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+
+namespace igl {
+  // Colormap selector -- an interface to supported colormaps within igl
+  //
+  // Inputs:
+  //   m  number of colors 
+  //   cm colormap enum
+  // Outputs:
+  //   J  m by list of RGB colors between 0 and 1
+  //
+  // Wrapper for directly computing [r,g,b] values of the selected colormap for a given factor f between
+  // 0 and 1
+  //
+  // Inputs:
+  //   f  factor determining color value as if 0 was min and 1 was max
+  //   c  colormap enum
+  // Outputs:
+  //   r  red value
+  //   g  green value
+  //   b  blue value
+
+  enum ColorMapType
+  {
+	CM_INFERNO = 0,
+	CM_JET = 1,
+	CM_MAGMA = 2,
+	CM_PARULA = 3,
+	CM_PLASMA = 4,
+	CM_VIRIDIS = 5
+  };
+
+  template <typename T>
+  IGL_INLINE void colormap(const T f, T * rgb, ColorMapType cm);
+  template <typename T>
+  IGL_INLINE void colormap(const T f, T & r, T & g, T & b, ColorMapType cm);
+  // Inputs:
+  //   Z  #Z list of factors
+  //   normalize  whether to normalize Z to be tightly between [0,1]
+  //   cm selected colormap palette to interpolate from
+  // Outputs:
+  //   C  #C by 3 list of rgb colors
+  template <typename DerivedZ, typename DerivedC>
+  IGL_INLINE void colormap(
+    const Eigen::PlainObjectBase<DerivedZ> & Z,
+    const bool normalize,
+    Eigen::PlainObjectBase<DerivedC> & C,
+	ColorMapType cm);
+  // Inputs:
+  //   min_z  value at black
+  //   max_z  value at yellow
+  template <typename DerivedZ, typename DerivedC>
+  IGL_INLINE void colormap(
+    const Eigen::PlainObjectBase<DerivedZ> & Z,
+    const double min_Z,
+    const double max_Z,
+    Eigen::PlainObjectBase<DerivedC> & C,
+	ColorMapType cm);
+};
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "colormap.cpp"
+#endif
+
+#endif

+ 4 - 4
include/igl/copyleft/cgal/CGAL_includes.hpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// 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/.
 #ifndef IGL_CGAL_INCLUDES_H
 #define IGL_CGAL_INCLUDES_H

+ 4 - 0
include/igl/copyleft/cgal/assign.cpp

@@ -49,6 +49,10 @@ igl::copyleft::cgal::assign(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>,  Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&);

+ 2 - 0
include/igl/copyleft/cgal/closest_facet.cpp

@@ -492,6 +492,8 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 72 - 0
include/igl/copyleft/cgal/convex_hull.cpp

@@ -0,0 +1,72 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "convex_hull.h"
+#include "../../ismember.h"
+#include "polyhedron_to_mesh.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/Surface_mesh.h>
+#include <CGAL/convex_hull_3.h>
+#include <vector>
+
+template <
+  typename DerivedV,
+  typename DerivedW,
+  typename DerivedG>
+IGL_INLINE void igl::copyleft::cgal::convex_hull(
+  const Eigen::MatrixBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedW> & W,
+  Eigen::PlainObjectBase<DerivedG> & G)
+{
+  typedef CGAL::Exact_predicates_inexact_constructions_kernel      K;
+  typedef K::Point_3                                              Point_3;
+  //typedef CGAL::Delaunay_triangulation_3<K>                       Delaunay;
+  //typedef Delaunay::Vertex_handle                                 Vertex_handle;
+  //typedef CGAL::Surface_mesh<Point_3>                             Surface_mesh;
+  typedef CGAL::Polyhedron_3<K>                             Polyhedron_3;
+  std::vector<Point_3> points(V.rows());
+  for(int i = 0;i<V.rows();i++)
+  {
+    points[i] = Point_3(V(i,0),V(i,1),V(i,2));
+  }
+  Polyhedron_3 poly;
+  CGAL::convex_hull_3(points.begin(),points.end(),poly);
+  assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
+  polyhedron_to_mesh(poly,W,G);
+}
+
+template <
+  typename DerivedV,
+  typename DerivedF>
+IGL_INLINE void igl::copyleft::cgal::convex_hull(
+  const Eigen::MatrixBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedF> & F)
+{
+  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> W;
+  Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> G;
+  convex_hull(V,W,G);
+  // This is a lazy way to reindex into the original mesh
+  Eigen::Matrix<bool,Eigen::Dynamic,1> I;
+  Eigen::VectorXi J;
+  igl::ismember_rows(W,V,I,J);
+  assert(I.all() && "Should find all W in V");
+  F.resizeLike(G);
+  for(int f = 0;f<G.rows();f++)
+  {
+    for(int c = 0;c<3;c++)
+    {
+      F(f,c) = J(G(f,c));
+    }
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+#endif

+ 56 - 0
include/igl/copyleft/cgal/convex_hull.h

@@ -0,0 +1,56 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// 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/.
+#ifndef IGL_COPYLEFT_CGAL_CONVEX_HULL_H
+#define IGL_COPYLEFT_CGAL_CONVEX_HULL_H
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+
+namespace igl
+{
+  namespace copyleft
+  {
+    namespace cgal
+    {
+      // Given a set of points (V), compute the convex hull as a triangle mesh (W,G)
+      // 
+      // Inputs:
+      //   V  #V by 3 list of input points
+      // Outputs:
+      //   W  #W by 3 list of convex hull points
+      //   G  #G by 3 list of triangle indices into W
+      template <
+        typename DerivedV,
+        typename DerivedW,
+        typename DerivedG>
+      IGL_INLINE void convex_hull(
+        const Eigen::MatrixBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedW> & W,
+        Eigen::PlainObjectBase<DerivedG> & G);
+      // Given a set of points (V), compute the convex hull as a triangle mesh (F)
+      // over input vertex set (V)
+      // 
+      // Inputs:
+      //   V  #V by 3 list of input points
+      // Outputs:
+      //   F  #F by 3 list of triangle indices into V
+      //
+      template <
+        typename DerivedV,
+        typename DerivedF>
+      IGL_INLINE void convex_hull(
+        const Eigen::MatrixBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedF> & F);
+    }
+  }
+}
+  
+#ifndef IGL_STATIC_LIBRARY
+#  include "convex_hull.cpp"
+#endif
+
+#endif 

+ 2 - 0
include/igl/copyleft/cgal/extract_cells.cpp

@@ -533,6 +533,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells_single_component(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 39 - 0
include/igl/copyleft/cgal/hausdorff.cpp

@@ -0,0 +1,39 @@
+#include "hausdorff.h"
+#include "../../hausdorff.h"
+#include <functional>
+
+template <
+  typename DerivedV,
+  typename Kernel,
+  typename Scalar>
+IGL_INLINE void igl::copyleft::cgal::hausdorff(
+  const Eigen::MatrixBase<DerivedV>& V,
+  const CGAL::AABB_tree<
+    CGAL::AABB_traits<Kernel, 
+      CGAL::AABB_triangle_primitive<Kernel, 
+        typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
+      >
+    >
+  > & treeB,
+  const std::vector<CGAL::Triangle_3<Kernel> > & /*TB*/,
+  Scalar & l,
+  Scalar & u)
+{
+  // Not sure why using `auto` here doesn't work with the `hausdorff` function
+  // parameter but explicitly naming the type does...
+  const std::function<double(const double &,const double &,const double &)> 
+    dist_to_B = [&treeB](
+    const double & x, const double & y, const double & z)->double
+  {
+    CGAL::Point_3<Kernel> query(x,y,z);
+    typename CGAL::AABB_tree<
+      CGAL::AABB_traits<Kernel, 
+        CGAL::AABB_triangle_primitive<Kernel, 
+          typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
+        >
+      >
+    >::Point_and_primitive_id pp = treeB.closest_point_and_primitive(query);
+    return std::sqrt((query-pp.first).squared_length());
+  };
+  return igl::hausdorff(V,dist_to_B,l,u);
+}

+ 62 - 0
include/igl/copyleft/cgal/hausdorff.h

@@ -0,0 +1,62 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// 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/.
+#ifndef IGL_COPYLEFT_CGAL_HAUSDORFF_H
+#define IGL_COPYLEFT_CGAL_HAUSDORFF_H
+#include "../../igl_inline.h"
+
+#include <Eigen/Dense>
+#include "CGAL_includes.hpp"
+#include <vector>
+
+namespace igl 
+{
+  namespace copyleft
+  {
+    namespace cgal
+    {
+      // Compute lower and upper bounds (l,u) on the Hausdorff distance between a triangle
+      // (V) and a pointset (e.g., mesh, triangle soup) given by a distance function
+      // handle (dist_to_B).
+      //
+      // Inputs:
+      //   V   3 by 3 list of corner positions so that V.row(i) is the position of the
+      //     ith corner
+      //   treeB  CGAL's AABB tree containing triangle soup (VB,FB)
+      //   TB  list of CGAL triangles in order of FB (for determining which was found
+      //     in computation)
+      // Outputs:
+      //   l  lower bound on Hausdorff distance 
+      //   u  upper bound on Hausdorff distance
+      //
+      template <
+        typename DerivedV,
+        typename Kernel,
+        typename Scalar>
+      IGL_INLINE void hausdorff(
+        const Eigen::MatrixBase<DerivedV>& V,
+        const CGAL::AABB_tree<
+          CGAL::AABB_traits<Kernel, 
+            CGAL::AABB_triangle_primitive<Kernel, 
+              typename std::vector<CGAL::Triangle_3<Kernel> >::iterator
+            >
+          >
+        > & treeB,
+        const std::vector<CGAL::Triangle_3<Kernel> > & TB,
+        Scalar & l,
+        Scalar & u);
+    }
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "hausdorff.cpp"
+#endif
+
+#endif
+
+

+ 13 - 13
include/igl/copyleft/cgal/insert_into_cdt.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2016 Alec Jacobson
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "insert_into_cdt.h"
 #include <CGAL/Point_3.h>
@@ -22,30 +22,30 @@ IGL_INLINE void igl::copyleft::cgal::insert_into_cdt(
         CGAL::Constrained_triangulation_face_base_2< Kernel>
       >,
       CGAL::Exact_intersections_tag
-    > 
-  > 
+    >
+  >
   & cdt)
 {
   typedef CGAL::Point_3<Kernel>    Point_3;
-  typedef CGAL::Segment_3<Kernel>  Segment_3; 
-  typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+  typedef CGAL::Segment_3<Kernel>  Segment_3;
+  typedef CGAL::Triangle_3<Kernel> Triangle_3;
 
-  if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj)) 
+  if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj))
   {
     // Add segment constraint
     cdt.insert_constraint( P.to_2d(iseg->vertex(0)),P.to_2d(iseg->vertex(1)));
-  }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj)) 
+  }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj))
   {
     // Add point
     cdt.insert(P.to_2d(*ipoint));
-  } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj)) 
+  } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
   {
     // Add 3 segment constraints
     cdt.insert_constraint( P.to_2d(itri->vertex(0)),P.to_2d(itri->vertex(1)));
     cdt.insert_constraint( P.to_2d(itri->vertex(1)),P.to_2d(itri->vertex(2)));
     cdt.insert_constraint( P.to_2d(itri->vertex(2)),P.to_2d(itri->vertex(0)));
-  } else if(const std::vector<Point_3 > *polyp = 
-      CGAL::object_cast< std::vector<Point_3 > >(&obj)) 
+  } else if(const std::vector<Point_3 > *polyp =
+      CGAL::object_cast< std::vector<Point_3 > >(&obj))
   {
     const std::vector<Point_3 > & poly = *polyp;
     const size_t m = poly.size();

+ 8 - 7
include/igl/copyleft/cgal/insert_into_cdt.h

@@ -1,14 +1,15 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2016 Alec Jacobson
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// 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/.
 #ifndef IGL_COPYLEFT_CGAL_INSERT_INTO_CDT_H
 #define IGL_COPYLEFT_CGAL_INSERT_INTO_CDT_H
 #include "../../igl_inline.h"
 
+#include <CGAL/double.h> // Workaround https://github.com/CGAL/cgal/issues/2182 with CGAL 4.10-1
 #include <CGAL/Plane_3.h>
 #include <CGAL/Constrained_Delaunay_triangulation_2.h>
 #include <CGAL/Constrained_triangulation_plus_2.h>
@@ -33,7 +34,7 @@ namespace igl
       //   cdt  current CDT, see output
       // Outputs:
       //   cdt  CDT updated to contain constraints for the given object
-      // 
+      //
       template <typename Kernel>
       IGL_INLINE void insert_into_cdt(
         const CGAL::Object & obj,
@@ -46,8 +47,8 @@ namespace igl
               CGAL::Constrained_triangulation_face_base_2< Kernel>
             >,
             CGAL::Exact_intersections_tag
-          > 
-        > 
+          >
+        >
         & cdt);
     }
   }

+ 1 - 0
include/igl/copyleft/cgal/intersect_other.cpp

@@ -284,5 +284,6 @@ IGL_INLINE bool igl::copyleft::cgal::intersect_other(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<double, -1, -1, 0, -1, -1>,   Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>,   Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1,   -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,   igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 15 - 0
include/igl/copyleft/cgal/list_to_matrix.cpp

@@ -0,0 +1,15 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "../../list_to_matrix.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#ifdef IGL_STATIC_LIBRARY
+#undef IGL_STATIC_LIBRARY
+#include "../../list_to_matrix.cpp"
+template bool igl::list_to_matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>   >(std::vector<std::vector<CGAL::Lazy_exact_nt<CGAL::Gmpq>,   std::allocator<CGAL::Lazy_exact_nt<CGAL::Gmpq> > >,   std::allocator<std::vector<CGAL::Lazy_exact_nt<CGAL::Gmpq>,   std::allocator<CGAL::Lazy_exact_nt<CGAL::Gmpq> > > > > const&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> >&);
+#endif

+ 11 - 2
include/igl/copyleft/cgal/mesh_boolean.cpp

@@ -114,7 +114,11 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
     for(int d = 0;d<3;d++) VV(VA.rows()+b,d) = VB(b,d);
   }
   FF.block(0, 0, FA.rows(), 3) = FA;
-  FF.block(FA.rows(), 0, FB.rows(), 3) = FB.array() + VA.rows();
+  // Eigen struggles to assign nothing to nothing and will assert if FB is empty
+  if(FB.rows() > 0)
+  {
+    FF.block(FA.rows(), 0, FB.rows(), 3) = FB.array() + VA.rows();
+  }
   return mesh_boolean(VV,FF,sizes,wind_num_op,keep,VC,FC,J);
 }
 
@@ -428,6 +432,10 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
@@ -437,10 +445,11 @@ template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_n
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, std::function<int (Eigen::Matrix<int, 1, -1, 1, 1, -1>)> const&, std::function<int (int, int)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 4 - 0
include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp

@@ -48,6 +48,10 @@ IGL_INLINE void igl::copyleft::cgal::mesh_to_cgal_triangle_list(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);

+ 3 - 1
include/igl/copyleft/cgal/minkowski_sum.cpp

@@ -11,7 +11,7 @@
 #include "../../slice.h"
 #include "../../slice_mask.h"
 #include "../../LinSpaced.h"
-#include "../../unique.h"
+#include "../../unique_rows.h"
 #include "../../get_seconds.h"
 #include "../../edges.h"
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@@ -381,6 +381,8 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::minkowski_sum<
   Eigen::Matrix<float, -1, 3, 1, -1, 3>, 
   Eigen::Matrix<int, -1, 3, 1, -1, 3>, 

+ 4 - 0
include/igl/copyleft/cgal/order_facets_around_edge.cpp

@@ -401,6 +401,10 @@ void igl::copyleft::cgal::order_facets_around_edge(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);

+ 1 - 0
include/igl/copyleft/cgal/outer_element.cpp

@@ -217,4 +217,5 @@ template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, -1, 1, -
 template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 #endif

+ 4 - 0
include/igl/copyleft/cgal/outer_facet.cpp

@@ -150,6 +150,10 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long&, bool&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long&, bool&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);

+ 1 - 0
include/igl/copyleft/cgal/point_mesh_squared_distance.cpp

@@ -134,4 +134,5 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>,   Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1,   -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0, -1, 1>,   Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>   >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0,   -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>   > const&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1,   0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 6 - 0
include/igl/copyleft/cgal/point_solid_signed_squared_distance.cpp

@@ -48,3 +48,9 @@ IGL_INLINE void igl::copyleft::cgal::point_solid_signed_squared_distance(
     }
   }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void   igl::copyleft::cgal::point_solid_signed_squared_distance<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>,   -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int,   -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0,   -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>,   -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1,   -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0,   -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1,   0, -1, 1> >&);
+#endif

+ 2 - 0
include/igl/copyleft/cgal/points_inside_component.cpp

@@ -339,6 +339,8 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<double, -1,   -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>,   Eigen::Array<bool, -1, 1, 0, -1, 1>   >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1>   >&);
 template void igl::copyleft::cgal::points_inside_component< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<   int, -1, -1, 0, -1, -1>, Eigen::Matrix<   int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<   int, -1, -1, 0, -1, -1> > ( Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> >&);
 template void igl::copyleft::cgal::points_inside_component< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<   int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<   int, -1, -1, 0, -1, -1> > ( Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<   int, -1, -1, 0, -1, -1> >&);
 template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 9 - 4
include/igl/copyleft/cgal/polyhedron_to_mesh.cpp

@@ -8,11 +8,14 @@
 #include "polyhedron_to_mesh.h"
 #include <CGAL/Polyhedron_3.h>
 
-template <typename Polyhedron>
+template <
+  typename Polyhedron,
+  typename DerivedV,
+  typename DerivedF>
 IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
   const Polyhedron & poly,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F)
+  Eigen::PlainObjectBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedF> & F)
 {
   using namespace std;
   V.resize(poly.size_of_vertices(),3);
@@ -59,6 +62,8 @@ IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 #include <CGAL/Simple_cartesian.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
-template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
+template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0,-1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0,-1, -1> >&);
 #endif

+ 6 - 3
include/igl/copyleft/cgal/polyhedron_to_mesh.h

@@ -25,11 +25,14 @@ namespace igl
       // Outputs:
       //   V  #V by 3 list of vertex positions
       //   F  #F by 3 list of triangle indices
-      template <typename Polyhedron>
+      template <
+        typename Polyhedron,
+        typename DerivedV,
+        typename DerivedF>
       IGL_INLINE void polyhedron_to_mesh(
         const Polyhedron & poly,
-        Eigen::MatrixXd & V,
-        Eigen::MatrixXi & F);
+        Eigen::PlainObjectBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedF> & F);
     }
   }
 }

+ 8 - 8
include/igl/copyleft/cgal/projected_cdt.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2016 Alec Jacobson
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "projected_cdt.h"
 #include "insert_into_cdt.h"
@@ -29,8 +29,8 @@ IGL_INLINE void igl::copyleft::cgal::projected_cdt(
   size_t count=0;
   for (
     auto itr = cdt.finite_vertices_begin();
-    itr != cdt.finite_vertices_end(); 
-    itr++) 
+    itr != cdt.finite_vertices_end();
+    itr++)
   {
     vertices.push_back(P.to_3d(itr->point()));
     v2i[itr] = count;
@@ -39,10 +39,10 @@ IGL_INLINE void igl::copyleft::cgal::projected_cdt(
   // Read off faces and store index triples
   for (
     auto itr = cdt.finite_faces_begin();
-    itr != cdt.finite_faces_end(); 
+    itr != cdt.finite_faces_end();
     itr++)
   {
-    faces.push_back( 
+    faces.push_back(
       { v2i[itr->vertex(0)], v2i[itr->vertex(1)], v2i[itr->vertex(2)] });
   }
 }

+ 6 - 5
include/igl/copyleft/cgal/projected_cdt.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2016 Alec Jacobson
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// 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/.
 #ifndef IGL_COPYLEFT_CGAL_PROJECTED_CDT_H
 #define IGL_COPYLEFT_CGAL_PROJECTED_CDT_H
@@ -11,6 +11,7 @@
 #include <Eigen/Core>
 #include <CGAL/Plane_3.h>
 #include <CGAL/Point_3.h>
+#include <CGAL/Object.h>
 #include <vector>
 namespace igl
 {
@@ -32,7 +33,7 @@ namespace igl
       // Outputs:
       //   vertices  list of vertices of the CDT mesh _back on the 3D plane_
       //   faces  list of list of triangle indices into vertices
-      //   
+      //
       template <typename Kernel, typename Index>
       IGL_INLINE void projected_cdt(
         const std::vector<CGAL::Object> & objects,

+ 2 - 0
include/igl/copyleft/cgal/propagate_winding_numbers.cpp

@@ -312,6 +312,8 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 9 - 1
include/igl/copyleft/cgal/remesh_intersections.cpp

@@ -11,7 +11,7 @@
 #include "projected_cdt.h"
 #include "../../get_seconds.h"
 #include "../../LinSpaced.h"
-#include "../../unique.h"
+#include "../../unique_rows.h"
 
 #include <vector>
 #include <map>
@@ -469,6 +469,13 @@ IGL_INLINE void igl::copyleft::cgal::remesh_intersections(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<double, -1, -1,   0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>,   Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>,   Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double,   -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0,   -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>,   std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&,   std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1,   0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1,   -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int,   -1, -1, 0, -1, -1>::Index const,   std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1,   0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
@@ -503,4 +510,5 @@ template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<double, -1, -1,   0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck,   Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>,   Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>,   Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double,   -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0,   -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>,   std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&,   std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1,   0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1,   -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int,   -1, -1, 0, -1, -1>::Index const,   std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index,   CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1,   0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,   Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 2 - 0
include/igl/copyleft/cgal/remesh_self_intersections.cpp

@@ -83,6 +83,8 @@ IGL_INLINE void igl::copyleft::cgal::remesh_self_intersections(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 1 - 0
include/igl/copyleft/cgal/remove_unreferenced.cpp

@@ -16,4 +16,5 @@ template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::G
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 1
include/igl/copyleft/cgal/signed_distance_isosurface.cpp

@@ -58,7 +58,7 @@ IGL_INLINE bool igl::copyleft::cgal::signed_distance_isosurface(
   Eigen::MatrixXd FN,VN,EN;
   Eigen::MatrixXi E;
   Eigen::VectorXi EMAP;
-  WindingNumberAABB<Eigen::Vector3d> hier;
+  WindingNumberAABB< Eigen::Vector3d, Eigen::MatrixXd, Eigen::MatrixXi > hier;
   switch(sign_type)
   {
     default:

+ 15 - 0
include/igl/copyleft/cgal/slice_mask.cpp

@@ -0,0 +1,15 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "../../slice_mask.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#ifdef IGL_STATIC_LIBRARY
+#undef IGL_STATIC_LIBRARY
+#include "../../slice_mask.cpp"
+template void igl::slice_mask<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0,   -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>   >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0,   -1, 3> > const&, Eigen::Array<bool, -1, 1, 0, -1, 1> const&, int,   Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3,   0, -1, 3> >&);
+#endif

+ 2 - 0
include/igl/copyleft/cgal/submesh_aabb_tree.cpp

@@ -51,6 +51,8 @@ IGL_INLINE void igl::copyleft::cgal::submesh_aabb_tree(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::submesh_aabb_tree<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > >&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >&, std::vector<bool, std::allocator<bool> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::submesh_aabb_tree<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > >&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >&, std::vector<bool, std::allocator<bool> >&);
 template void igl::copyleft::cgal::submesh_aabb_tree<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > >&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >&, std::vector<bool, std::allocator<bool> >&);
 #endif

+ 12 - 0
include/igl/copyleft/cgal/trim_with_solid.cpp

@@ -91,3 +91,15 @@ IGL_INLINE void igl::copyleft::cgal::trim_with_solid(
   assign(V,Vd);
 }
 
+
+#ifdef IGL_STATIC_LIBRARY
+template void igl::copyleft::cgal::trim_with_solid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1,
+  -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0,
+  -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>
+  >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int,
+  -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,
+  Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1,
+  -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,
+  Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1,
+  1> >&);
+#endif

+ 0 - 3
include/igl/copyleft/cgal/unique.cpp

@@ -11,7 +11,4 @@
 #ifdef IGL_STATIC_LIBRARY
 #undef IGL_STATIC_LIBRARY
 #include "../../unique.cpp"
-template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 18 - 0
include/igl/copyleft/cgal/unique_rows.cpp

@@ -0,0 +1,18 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "../../unique_rows.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#ifdef IGL_STATIC_LIBRARY
+#undef IGL_STATIC_LIBRARY
+#include "../../unique_rows.cpp"
+template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif
+

+ 180 - 0
include/igl/copyleft/cgal/wire_mesh.cpp

@@ -0,0 +1,180 @@
+#include "wire_mesh.h"
+
+#include "../../list_to_matrix.h"
+#include "../../slice.h"
+#include "convex_hull.h"
+#include "mesh_boolean.h"
+#include <Eigen/Geometry>
+#include <vector>
+
+template <
+  typename DerivedWV,
+  typename DerivedWE,
+  typename DerivedV,
+  typename DerivedF,
+  typename DerivedJ>
+IGL_INLINE void igl::copyleft::cgal::wire_mesh(
+  const Eigen::MatrixBase<DerivedWV> & WV,
+  const Eigen::MatrixBase<DerivedWE> & WE,
+  const double th,
+  const int poly_size,
+  Eigen::PlainObjectBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedF> & F,
+  Eigen::PlainObjectBase<DerivedJ> & J)
+{
+
+  typedef typename DerivedWV::Scalar Scalar;
+  // Canonical polygon to place at each endpoint
+  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
+  MatrixX3S PV(poly_size,3);
+  for(int p =0;p<PV.rows();p++)
+  {
+    const Scalar phi = (Scalar(p)/Scalar(PV.rows()))*2.*M_PI;
+    PV(p,0) = 0.5*cos(phi);
+    PV(p,1) = 0.5*sin(phi);
+    PV(p,2) = 0;
+  }
+
+  V.resize(WV.rows() + PV.rows() * 2 * WE.rows(),3);
+  V.topLeftCorner(WV.rows(),3) = WV;
+  // Signed adjacency list
+  std::vector<std::vector<std::pair<int,int> > > A(WV.rows());
+  // Inputs:
+  //   e  index of edge
+  //   c  index of endpoint [0,1]
+  //   p  index of polygon vertex
+  // Returns index of corresponding vertex in V
+  const auto index = 
+    [&PV,&WV](const int e, const int c, const int p)->int
+  {
+    return WV.rows() + e*2*PV.rows() + PV.rows()*c + p;
+  };
+  const auto unindex = 
+    [&PV,&WV](int v, int & e, int & c, int & p)
+  {
+    assert(v>=WV.rows());
+    v = v-WV.rows();
+    e = v/(2*PV.rows());
+    v = v-e*(2*PV.rows());
+    c = v/(PV.rows());
+    v = v-c*(PV.rows());
+    p = v;
+  };
+  // loop over all edges
+  for(int e = 0;e<WE.rows();e++)
+  {
+    // Fill in adjacency list as we go
+    A[WE(e,0)].emplace_back(e,0);
+    A[WE(e,1)].emplace_back(e,1);
+    typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
+    const RowVector3S ev = WV.row(WE(e,1))-WV.row(WE(e,0));
+    const RowVector3S uv = ev.normalized();
+    Eigen::Quaternion<Scalar> q;
+    q = q.FromTwoVectors(RowVector3S(0,0,1),uv);
+    // loop over polygon vertices
+    for(int p = 0;p<PV.rows();p++)
+    {
+      RowVector3S qp = q*(PV.row(p)*th);
+      // loop over endpoints
+      for(int c = 0;c<2;c++)
+      {
+        // Move to endpoint, offset by factor of thickness
+        V.row(index(e,c,p)) = 
+          qp+WV.row(WE(e,c)) + 1.*th*Scalar(1-2*c)*uv;
+      }
+    }
+  }
+
+  std::vector<std::vector<typename DerivedF::Index> > vF;
+  std::vector<int> vJ;
+  const auto append_hull = 
+    [&V,&vF,&vJ,&unindex,&WV](const Eigen::VectorXi & I, const int j)
+  {
+    MatrixX3S Vv;
+    igl::slice(V,I,1,Vv);
+    Eigen::MatrixXi Fv;
+    convex_hull(Vv,Fv);
+    for(int f = 0;f<Fv.rows();f++)
+    {
+      const Eigen::Array<int,1,3> face(I(Fv(f,0)), I(Fv(f,1)), I(Fv(f,2)));
+      //const bool on_vertex = (face<WV.rows()).any();
+      //if(!on_vertex)
+      //{
+      //  // This correctly prunes fcaes on the "caps" of convex hulls around
+      //  // edges, but for convex hulls around vertices this will only work if
+      //  // the incoming edges are not overlapping.
+      //  //
+      //  // Q: For convex hulls around vertices, is the correct thing to do:
+      //  // check if all corners of face lie *on or _outside_* of plane of "cap"?
+      //  // 
+      //  // H: Maybe, but if there's an intersection then the boundary of the
+      //  // incoming convex hulls around edges is still not going to match up
+      //  // with the boundary on the convex hull around the vertices.
+      //  //
+      //  // Might have to bite the bullet and always call self-union.
+      //  bool all_same = true;
+      //  int e0,c0,p0;
+      //  unindex(face(0),e0,c0,p0);
+      //  for(int i = 1;i<3;i++)
+      //  {
+      //    int ei,ci,pi;
+      //    unindex(face(i),ei,ci,pi);
+      //    all_same = all_same && (e0==ei && c0==ci);
+      //  }
+      //  if(all_same)
+      //  {
+      //    // don't add this face
+      //    continue;
+      //  }
+      //}
+      vF.push_back( { face(0),face(1),face(2)});
+      vJ.push_back(j);
+    }
+  };
+  // loop over each vertex
+  for(int v = 0;v<WV.rows();v++)
+  {
+    // Gather together this vertex and the polygon vertices of all incident
+    // edges
+    Eigen::VectorXi I(1+A[v].size()*PV.rows());
+    // This vertex
+    I(0) = v;
+    for(int n = 0;n<A[v].size();n++)
+    {
+      for(int p = 0;p<PV.rows();p++)
+      {
+        const int e = A[v][n].first;
+        const int c = A[v][n].second;
+        I(1+n*PV.rows()+p) = index(e,c,p);
+      }
+    }
+    append_hull(I,v);
+  }
+  // loop over each edge
+  for(int e = 0;e<WE.rows();e++)
+  {
+    // Gether together polygon vertices of both endpoints
+    Eigen::VectorXi I(PV.rows()*2);
+    for(int c = 0;c<2;c++)
+    {
+      for(int p = 0;p<PV.rows();p++)
+      {
+        I(c*PV.rows()+p) = index(e,c,p);
+      }
+    }
+    append_hull(I,WV.rows()+e);
+  }
+
+  list_to_matrix(vF,F);
+  // Self-union to clean up 
+  igl::copyleft::cgal::mesh_boolean(
+    Eigen::MatrixXd(V),Eigen::MatrixXi(F),Eigen::MatrixXd(),Eigen::MatrixXi(),
+    "union",
+    V,F,J);
+  for(int j=0;j<J.size();j++) J(j) = vJ[J(j)];
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation 
+template void igl::copyleft::cgal::wire_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif

+ 48 - 0
include/igl/copyleft/cgal/wire_mesh.h

@@ -0,0 +1,48 @@
+#ifndef IGL_COPYLEFT_CGAL_WIRE_MESH_H
+#define IGL_COPYLEFT_CGAL_WIRE_MESH_H
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  namespace copyleft
+  {
+    // Construct a "wire" or "wireframe" or "strut" surface mesh, given a
+    // one-dimensional network of straight edges.
+    //
+    // Inputs:
+    //   WV  #WV by 3 list of vertex positions
+    //   WE  #WE by 2 list of edge indices into WV
+    //   th  diameter thickness of wire 
+    //   poly_size  number of sides on each wire (e.g., 4 would produce wires by
+    //     connecting rectangular prisms).
+    // Outputs:
+    //   V  #V by 3 list of output vertices
+    //   F  #F by 3 list of output triangle indices into V
+    //   J  #F list of indices into [0,#WV+#WE) revealing "birth simplex" of
+    //     output faces J(j) < #WV means the face corresponds to the J(j)th
+    //     vertex in WV. J(j) >= #WV means the face corresponds to the
+    //     (J(j)-#WV)th edge in WE.
+    namespace cgal
+    {
+      template <
+        typename DerivedWV,
+        typename DerivedWE,
+        typename DerivedV,
+        typename DerivedF,
+        typename DerivedJ>
+      IGL_INLINE void wire_mesh(
+        const Eigen::MatrixBase<DerivedWV> & WV,
+        const Eigen::MatrixBase<DerivedWE> & WE,
+        const double th,
+        const int poly_size,
+        Eigen::PlainObjectBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedF> & F,
+        Eigen::PlainObjectBase<DerivedJ> & J);
+    }
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "wire_mesh.cpp"
+#endif
+#endif

+ 46 - 35
include/igl/copyleft/marching_cubes.cpp

@@ -25,48 +25,51 @@
 
 #include "marching_cubes.h"
 #include "marching_cubes_tables.h"
-#include <map>
+
+#include <unordered_map>
+
 
 extern const int edgeTable[256];
 extern const int triTable[256][2][17];
 extern const int polyTable[8][16];
 
-class EdgeKey
+struct EdgeKey
 {
-public:
-
-  EdgeKey(unsigned i0, unsigned i1) {
-    if (i0 < i1)  { i0_ = i0;  i1_ = i1; }
-    else            { i0_ = i1;  i1_ = i0; }
-  }
+  EdgeKey(unsigned i0, unsigned i1) : i0_(i0), i1_(i1) {}
 
-  bool operator<(const EdgeKey& _rhs) const
+  bool operator==(const EdgeKey& _rhs) const
   {
-    if (i0_ != _rhs.i0_)
-      return (i0_ < _rhs.i0_);
-    else
-      return (i1_ < _rhs.i1_);
+    return i0_ == _rhs.i0_ && i1_ == _rhs.i1_;
   }
 
-private:
   unsigned i0_, i1_;
 };
 
+struct EdgeHash
+{
+    std::size_t operator()(const EdgeKey& key) const {
+        std::size_t seed = 0;
+        seed ^= key.i0_ + 0x9e3779b9 + (seed<<6) + (seed>>2); // Copied from boost::hash_combine
+        seed ^= key.i1_ + 0x9e3779b9 + (seed<<6) + (seed>>2);
+        return std::hash<std::size_t>()(seed);
+    }
+};
+
 
-template <typename DerivedV1, typename DerivedV2, typename DerivedF>
+template <typename Derivedvalues, typename Derivedpoints,typename Derivedvertices, typename DerivedF>
 class MarchingCubes
 {
-  typedef std::map<EdgeKey, unsigned>  MyMap;
-  typedef typename MyMap::const_iterator   MyMapIterator;
+  typedef std::unordered_map<EdgeKey, unsigned, EdgeHash> MyMap;
+  typedef typename MyMap::const_iterator                  MyMapIterator;
 
 public:
   MarchingCubes(
-                const Eigen::PlainObjectBase<DerivedV1> &values,
-                const Eigen::PlainObjectBase<DerivedV2> &points,
+                const Eigen::PlainObjectBase<Derivedvalues> &values,
+                const Eigen::PlainObjectBase<Derivedpoints> &points,
                 const unsigned x_res,
                 const unsigned y_res,
                 const unsigned z_res,
-                Eigen::PlainObjectBase<DerivedV2> &vertices,
+                Eigen::PlainObjectBase<Derivedvertices> &vertices,
                 Eigen::PlainObjectBase<DerivedF> &faces)
   {
     assert(values.cols() == 1);
@@ -181,11 +184,11 @@ public:
 
   };
 
-  static typename DerivedF::Scalar  add_vertex(const Eigen::PlainObjectBase<DerivedV1> &values,
-                                               const Eigen::PlainObjectBase<DerivedV2> &points,
+  static typename DerivedF::Scalar  add_vertex(const Eigen::PlainObjectBase<Derivedvalues> &values,
+                                               const Eigen::PlainObjectBase<Derivedpoints> &points,
                                                unsigned int i0,
                                                unsigned int i1,
-                                               Eigen::PlainObjectBase<DerivedV2> &vertices,
+                                               Eigen::PlainObjectBase<Derivedvertices> &vertices,
                                                int &num_vertices,
                                                MyMap &edge2vertex)
   {
@@ -196,19 +199,19 @@ public:
     ;
 
     // generate new vertex
-    const Eigen::Matrix<typename DerivedV2::Scalar, 1, 3> & p0 = points.row(i0);
-    const Eigen::Matrix<typename DerivedV2::Scalar, 1, 3> & p1 = points.row(i1);
+    const Eigen::Matrix<typename Derivedpoints::Scalar, 1, 3> & p0 = points.row(i0);
+    const Eigen::Matrix<typename Derivedpoints::Scalar, 1, 3> & p1 = points.row(i1);
 
-    typename DerivedV1::Scalar s0 = fabs(values[i0]);
-    typename DerivedV1::Scalar s1 = fabs(values[i1]);
-    typename DerivedV1::Scalar t  = s0 / (s0+s1);
+    typename Derivedvalues::Scalar s0 = fabs(values[i0]);
+    typename Derivedvalues::Scalar s1 = fabs(values[i1]);
+    typename Derivedvalues::Scalar t  = s0 / (s0+s1);
 
 
     num_vertices++;
     if (num_vertices > vertices.rows())
       vertices.conservativeResize(vertices.rows()+10000, Eigen::NoChange);
 
-    vertices.row(num_vertices-1)  = (1.0f-t)*p0 + t*p1;
+    vertices.row(num_vertices-1)  = ((1.0f-t)*p0 + t*p1).template cast<typename Derivedvertices::Scalar>();
     edge2vertex[EdgeKey(i0, i1)] = num_vertices-1;
 
     return num_vertices-1;
@@ -220,17 +223,17 @@ public:
 };
 
 
-template <typename DerivedV1, typename DerivedV2, typename DerivedF>
+template <typename Derivedvalues, typename Derivedpoints, typename Derivedvertices, typename DerivedF>
 IGL_INLINE void igl::copyleft::marching_cubes(
-  const Eigen::PlainObjectBase<DerivedV1> &values,
-  const Eigen::PlainObjectBase<DerivedV2> &points,
+  const Eigen::PlainObjectBase<Derivedvalues> &values,
+  const Eigen::PlainObjectBase<Derivedpoints> &points,
   const unsigned x_res,
   const unsigned y_res,
   const unsigned z_res,
-  Eigen::PlainObjectBase<DerivedV2> &vertices,
+  Eigen::PlainObjectBase<Derivedvertices> &vertices,
   Eigen::PlainObjectBase<DerivedF> &faces)
 {
-  MarchingCubes<DerivedV1, DerivedV2, DerivedF> mc(values,
+  MarchingCubes<Derivedvalues, Derivedpoints, Derivedvertices, DerivedF> mc(values,
                                        points,
                                        x_res,
                                        y_res,
@@ -240,5 +243,13 @@ IGL_INLINE void igl::copyleft::marching_cubes(
 }
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
+template void igl::copyleft::marching_cubes< Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 8 - 4
include/igl/copyleft/marching_cubes.h

@@ -38,14 +38,18 @@ namespace igl
     //   vertices  #V by 3 list of mesh vertex positions
     //   faces  #F by 3 list of mesh triangle indices
     //
-    template <typename DerivedV1, typename DerivedV2, typename DerivedF>
+    template <
+      typename Derivedvalues, 
+      typename Derivedpoints, 
+      typename Derivedvertices, 
+      typename DerivedF>
       IGL_INLINE void marching_cubes(
-        const Eigen::PlainObjectBase<DerivedV1> &values,
-        const Eigen::PlainObjectBase<DerivedV2> &points,
+        const Eigen::PlainObjectBase<Derivedvalues> &values,
+        const Eigen::PlainObjectBase<Derivedpoints> &points,
         const unsigned x_res,
         const unsigned y_res,
         const unsigned z_res,
-        Eigen::PlainObjectBase<DerivedV2> &vertices,
+        Eigen::PlainObjectBase<Derivedvertices> &vertices,
         Eigen::PlainObjectBase<DerivedF> &faces);
   }
 }

+ 22 - 4
include/igl/copyleft/offset_surface.cpp

@@ -1,6 +1,8 @@
 #include "offset_surface.h"
 #include "marching_cubes.h"
 #include "../voxel_grid.h"
+#include "../signed_distance.h"
+#include "../flood_fill.h"
 #include <cassert>
 #include <iostream>
 
@@ -22,12 +24,13 @@ void igl::copyleft::offset_surface(
   const SignedDistanceType & signed_distance_type,
   Eigen::PlainObjectBase<DerivedSV> & SV,
   Eigen::PlainObjectBase<DerivedSF> & SF,
-  Eigen::PlainObjectBase<DerivedGV> & GV,
+  Eigen::PlainObjectBase<DerivedGV> &   GV,
   Eigen::PlainObjectBase<Derivedside> & side,
   Eigen::PlainObjectBase<DerivedS> & S)
 {
+  typedef typename DerivedV::Scalar Scalar;
+  typedef typename DerivedF::Scalar Index;
   {
-    typedef typename DerivedV::Scalar Scalar;
     Eigen::AlignedBox<Scalar,3> box;
     typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
     assert(V.cols() == 3 && "V must contain positions in 3D");
@@ -37,17 +40,32 @@ void igl::copyleft::offset_surface(
     box.extend(max_ext.transpose());
     igl::voxel_grid(box,s,1,GV,side);
   }
+
+  const Scalar h = 
+    (GV.col(0).maxCoeff()-GV.col(0).minCoeff())/((Scalar)(side(0)-1));
+  const Scalar lower_bound = isolevel-sqrt(3.0)*h;
+  const Scalar upper_bound = isolevel+sqrt(3.0)*h;
   {
-    Eigen::VectorXi I;
+    Eigen::Matrix<Index,Eigen::Dynamic,1> I;
     Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> C,N;
     igl::signed_distance(
-      GV,V,F,signed_distance_type,S,I,C,N);
+      GV,V,F,signed_distance_type,lower_bound,upper_bound,S,I,C,N);
   }
+  igl::flood_fill(side,S);
+  
   DerivedS SS = S.array()-isolevel;
   igl::copyleft::marching_cubes(SS,GV,side(0),side(1),side(2),SV,SF);
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::offset_surface<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, float, int, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, float, int, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::offset_surface<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, float, int, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, float, int, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::offset_surface<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double, int, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::offset_surface<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, float, int, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, float, int, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::offset_surface<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double, int, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 #endif

+ 2 - 1
include/igl/copyleft/offset_surface.h

@@ -23,7 +23,8 @@ namespace igl
     //   SF  #SF by 3 list of output mesh triangle indices into SV
     //   GV  #GV=side(0)*side(1)*side(2) by 3 list of grid cell centers
     //   side  list of number of grid cells in x, y, and z directions
-    //   S  #GV by 3 list of signed distance values
+    //   S  #GV by 3 list of signed distance values _near_ `isolevel` ("far"
+    //     from `isolevel` these values are incorrect)
     //
     template <
       typename DerivedV,

+ 5 - 5
include/igl/cut_mesh.cpp

@@ -23,16 +23,16 @@ namespace igl {
   public:
     // Input
     //mesh
-    const DerivedV &V;
-    const DerivedF &F;
+    const Eigen::PlainObjectBase<DerivedV> &V;
+    const Eigen::PlainObjectBase<DerivedF> &F;
     // TT is the same type as TTi? This is likely to break at some point
-    const DerivedTT &TT;
-    const DerivedTT &TTi;
+    const Eigen::PlainObjectBase<DerivedTT> &TT;
+    const Eigen::PlainObjectBase<DerivedTT> &TTi;
     const std::vector<std::vector<VFType> >& VF;
     const std::vector<std::vector<VFType> >& VFi;
     const std::vector<bool> &V_border; // bool
     //edges to cut
-    const DerivedC &Handle_Seams; // 3 bool
+    const Eigen::PlainObjectBase<DerivedC> &Handle_Seams; // 3 bool
 
     // total number of scalar variables
     int num_scalar_variables;

+ 1 - 0
include/igl/cut_mesh_from_singularities.cpp

@@ -201,4 +201,5 @@ template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
+template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 #endif

+ 8 - 0
include/igl/decimate.cpp

@@ -8,6 +8,7 @@
 #include "decimate.h"
 #include "collapse_edge.h"
 #include "edge_flaps.h"
+#include "is_edge_manifold.h"
 #include "remove_unreferenced.h"
 #include "slice_mask.h"
 #include "slice.h"
@@ -33,6 +34,13 @@ IGL_INLINE bool igl::decimate(
   DerivedV VO;
   DerivedF FO;
   igl::connect_boundary_to_infinity(V,F,VO,FO);
+  // decimate will not work correctly on non-edge-manifold meshes. By extension
+  // this includes meshes with non-manifold vertices on the boundary since these
+  // will create a non-manifold edge when connected to infinity.
+  if(!is_edge_manifold(FO))
+  {
+    return false;
+  }
   bool ret = decimate(
     VO,
     FO,

+ 1 - 1
include/igl/dfs.cpp

@@ -56,5 +56,5 @@ IGL_INLINE void igl::dfs(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template void igl::dfs<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::dfs<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, const size_t, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 8 - 2
include/igl/dirname.cpp

@@ -16,11 +16,16 @@ IGL_INLINE std::string igl::dirname(const std::string & path)
   {
     return std::string("");
   }
+#if defined (WIN32)
+  char del('\\');
+#else
+  char del('/');
+#endif
   // http://stackoverflow.com/questions/5077693/dirnamephp-similar-function-in-c
   std::string::const_reverse_iterator last_slash =
     std::find(
       path.rbegin(), 
-      path.rend(), '/');
+      path.rend(),del);
   if( last_slash == path.rend() )
   {
     // No slashes found
@@ -28,7 +33,7 @@ IGL_INLINE std::string igl::dirname(const std::string & path)
   }else if(1 == (last_slash.base() - path.begin()))
   {
     // Slash is first char
-    return std::string("/");
+    return std::string(&del);
   }else if(path.end() == last_slash.base() )
   {
     // Slash is last char
@@ -38,3 +43,4 @@ IGL_INLINE std::string igl::dirname(const std::string & path)
   return std::string(path.begin(),last_slash.base()-1);
 }
 
+

+ 19 - 6
include/igl/doublearea.cpp

@@ -31,7 +31,8 @@ IGL_INLINE void igl::doublearea(
 
   // Projected area helper
   const auto & proj_doublearea =
-    [&V,&F](const int x, const int y, const int f)->double
+    [&V,&F](const int x, const int y, const int f)
+    ->typename DerivedV::Scalar
   {
     auto rx = V(F(f,0),x)-V(F(f,2),x);
     auto sx = V(F(f,1),x)-V(F(f,2),x);
@@ -49,7 +50,7 @@ IGL_INLINE void igl::doublearea(
       {
         for(int d = 0;d<3;d++)
         {
-          double dblAd = proj_doublearea(d,(d+1)%3,f);
+          const auto dblAd = proj_doublearea(d,(d+1)%3,f);
           dblA(f) += dblAd*dblAd;
         }
       }
@@ -96,16 +97,18 @@ IGL_INLINE void igl::doublearea(
       // For 2d compute signed area
       const auto & R = A-C;
       const auto & S = B-C;
-      D = R.col(0).array()*S.col(1).array() - R.col(1).array()*S.col(0).array();
+      D = (R.col(0).array()*S.col(1).array() - 
+          R.col(1).array()*S.col(0).array()).template cast<
+        typename DerivedD::Scalar>();
       break;
     }
     default:
     {
       Eigen::Matrix<typename DerivedD::Scalar,DerivedD::RowsAtCompileTime,3>
         uL(A.rows(),3);
-      uL.col(0) = (B-C).rowwise().norm();
-      uL.col(1) = (C-A).rowwise().norm();
-      uL.col(2) = (A-B).rowwise().norm();
+      uL.col(0) = ((B-C).rowwise().norm()).template cast<typename DerivedD::Scalar>();
+      uL.col(1) = ((C-A).rowwise().norm()).template cast<typename DerivedD::Scalar>();
+      uL.col(2) = ((A-B).rowwise().norm()).template cast<typename DerivedD::Scalar>();
       doublearea(uL,D);
     }
   }
@@ -229,6 +232,16 @@ IGL_INLINE void igl::doublearea_quad(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::doublearea<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+template void igl::doublearea<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
 template void igl::doublearea<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::doublearea<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::doublearea<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);

+ 6 - 0
include/igl/edge_lengths.cpp

@@ -22,6 +22,12 @@ IGL_INLINE void igl::edge_lengths(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::edge_lengths<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::edge_lengths<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::edge_lengths<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
 template void igl::edge_lengths<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 6, 0, -1, 6> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 6, 0, -1, 6> >&);
 // generated by autoexplicit.sh
 template void igl::edge_lengths<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);

+ 10 - 6
include/igl/edge_topology.h

@@ -18,18 +18,22 @@ namespace igl
   // Initialize Edges and their topological relations (assumes an edge-manifold
   // mesh)
   //
-  // Output:
-  // EV  : #Ex2, Stores the edge description as pair of indices to vertices
-  // FE : #Fx3, Stores the Triangle-Edge relation
-  // EF : #Ex2: Stores the Edge-Triangle relation
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions (unused)
+  //   F  #F by 3 list of triangle indices into V
+  // Outputs:
+  //   EV  #Ex2 matrix storing the edge description as pair of indices to
+  //       vertices
+  //   FE  #Fx3 matrix storing the Triangle-Edge relation
+  //   EF  #Ex2 matrix storing the Edge-Triangle relation
   //
   // TODO: This seems to be a inferior duplicate of edge_flaps.h:
   //   - unused input parameter V
   //   - roughly 2x slower than edge_flaps
   //   - outputs less information: edge_flaps reveals corner opposite edge
   //   - FE uses non-standard and ambiguous order: FE(f,c) is merely an edge
-  //     incident on corner c of face f. In contrast, edge_flaps's EMAP(f,c) reveals
-  //     the edge _opposite_ corner c of face f
+  //     incident on corner c of face f. In contrast, edge_flaps's EMAP(f,c)
+  //     reveals the edge _opposite_ corner c of face f
 template <typename DerivedV, typename DerivedF>
   IGL_INLINE void edge_topology(
     const Eigen::PlainObjectBase<DerivedV>& V,

+ 1 - 0
include/igl/edges.cpp

@@ -42,4 +42,5 @@ IGL_INLINE void igl::edges(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 2 - 2
include/igl/eigs.cpp

@@ -169,8 +169,8 @@ IGL_INLINE bool igl::eigs(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template bool igl::eigs<double, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&, unsigned long, igl::EigsType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template bool igl::eigs<double, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&, const size_t, igl::EigsType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 #ifdef WIN32
-template bool igl::eigs<double, double, Eigen::Matrix<double,-1,-1,0,-1,-1>, Eigen::Matrix<double,-1,1,0,-1,1> >(Eigen::SparseMatrix<double,0,int> const &,Eigen::SparseMatrix<double,0,int> const &,unsigned long long, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix<double,-1,-1,0,-1,-1> > &, Eigen::PlainObjectBase<Eigen::Matrix<double,-1,1,0,-1,1> > &);
+template bool igl::eigs<double, double, Eigen::Matrix<double,-1,-1,0,-1,-1>, Eigen::Matrix<double,-1,1,0,-1,1> >(Eigen::SparseMatrix<double,0,int> const &,Eigen::SparseMatrix<double,0,int> const &, const size_t, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix<double,-1,-1,0,-1,-1> > &, Eigen::PlainObjectBase<Eigen::Matrix<double,-1,1,0,-1,1> > &);
 #endif
 #endif

+ 1 - 0
include/igl/embree/EmbreeIntersector.h

@@ -412,6 +412,7 @@ inline bool igl::embree::EmbreeIntersector::intersectBeam(
   if((intersectRay(origin,direction,hit,tnear,tfar,mask) && (hit.gid == geoId || geoId == -1)))
   {
     bestHit = hit;
+    hasHit = true;
   }
 
   // sample points around actual ray (conservative hitcheck)

+ 69 - 0
include/igl/embree/shape_diameter_function.cpp

@@ -0,0 +1,69 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "shape_diameter_function.h"
+#include "../shape_diameter_function.h"
+#include "EmbreeIntersector.h"
+#include "../Hit.h"
+
+template <
+  typename DerivedP,
+  typename DerivedN,
+  typename DerivedS >
+IGL_INLINE void igl::embree::shape_diameter_function(
+  const igl::embree::EmbreeIntersector & ei,
+  const Eigen::PlainObjectBase<DerivedP> & P,
+  const Eigen::PlainObjectBase<DerivedN> & N,
+  const int num_samples,
+  Eigen::PlainObjectBase<DerivedS> & S)
+{
+  const auto & shoot_ray = [&ei](
+    const Eigen::Vector3f& s,
+    const Eigen::Vector3f& dir)->double
+  {
+    igl::Hit hit;
+    const float tnear = 1e-4f;
+    if(ei.intersectRay(s,dir,hit,tnear))
+    {
+      return hit.t;
+    }else
+    {
+      return std::numeric_limits<double>::infinity();
+    }
+  };
+  return igl::shape_diameter_function(shoot_ray,P,N,num_samples,S);
+}
+
+template <
+  typename DerivedV,
+  typename DerivedF,
+  typename DerivedP,
+  typename DerivedN,
+  typename DerivedS >
+IGL_INLINE void igl::embree::shape_diameter_function(
+  const Eigen::PlainObjectBase<DerivedV> & V,
+  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::PlainObjectBase<DerivedP> & P,
+  const Eigen::PlainObjectBase<DerivedN> & N,
+  const int num_samples,
+  Eigen::PlainObjectBase<DerivedS> & S)
+{
+  using namespace Eigen;
+  EmbreeIntersector ei;
+  ei.init(V.template cast<float>(),F.template cast<int>());
+  shape_diameter_function(ei,P,N,num_samples,S);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::embree::shape_diameter_function<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::embree::shape_diameter_function<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::embree::shape_diameter_function<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::embree::shape_diameter_function<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::embree::shape_diameter_function<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif
+

+ 60 - 0
include/igl/embree/shape_diameter_function.h

@@ -0,0 +1,60 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// 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/.
+#ifndef IGL_EMBREE_SHAPE_DIAMETER_FUNCTION_H
+#define IGL_EMBREE_SHAPE_DIAMETER_FUNCTION_H
+#include "../igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  namespace embree
+  {
+    // Forward define
+    class EmbreeIntersector;
+    // Compute shape diamter function per given point
+    //
+    // Inputs:
+    //    ei  EmbreeIntersector containing (V,F)
+    //    P  #P by 3 list of origin points
+    //    N  #P by 3 list of origin normals
+    // Outputs:
+    //    S  #P list of shape diamater function values between bounding box
+    //    diagonal (perfect sphere) and 0 (perfect needle hook)
+    //
+    template <
+      typename DerivedP,
+      typename DerivedN,
+      typename DerivedS >
+    IGL_INLINE void shape_diameter_function(
+      const EmbreeIntersector & ei,
+      const Eigen::PlainObjectBase<DerivedP> & P,
+      const Eigen::PlainObjectBase<DerivedN> & N,
+      const int num_samples,
+      Eigen::PlainObjectBase<DerivedS> & S);
+    // Wrapper which builds new EmbreeIntersector for (V,F). That's expensive so
+    // avoid this if repeatedly calling.
+    template <
+      typename DerivedV,
+      typename DerivedF,
+      typename DerivedP,
+      typename DerivedN,
+      typename DerivedS >
+    IGL_INLINE void shape_diameter_function(
+      const Eigen::PlainObjectBase<DerivedV> & V,
+      const Eigen::PlainObjectBase<DerivedF> & F,
+      const Eigen::PlainObjectBase<DerivedP> & P,
+      const Eigen::PlainObjectBase<DerivedN> & N,
+      const int num_samples,
+      Eigen::PlainObjectBase<DerivedS> & S);
+  }
+};
+#ifndef IGL_STATIC_LIBRARY
+#  include "shape_diameter_function.cpp"
+#endif
+
+#endif
+

+ 1 - 1
include/igl/exterior_edges.cpp

@@ -8,7 +8,7 @@
 #include "exterior_edges.h"
 #include "oriented_facets.h"
 #include "sort.h"
-#include "unique.h"
+#include "unique_rows.h"
 
 #include <cassert>
 #include <unordered_map>

+ 6 - 1
include/igl/extract_manifold_patches.cpp

@@ -91,7 +91,12 @@ IGL_INLINE size_t igl::extract_manifold_patches(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template unsigned long igl::extract_manifold_patches<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template unsigned long igl::extract_manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>,   Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #ifndef WIN32
-template unsigned long igl::extract_manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template size_t igl::extract_manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 1 - 0
include/igl/find_cross_field_singularities.cpp

@@ -82,4 +82,5 @@ Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
 template void igl::find_cross_field_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::find_cross_field_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, bool);
 template void igl::find_cross_field_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::find_cross_field_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 17 - 4
include/igl/flood_fill.cpp

@@ -8,12 +8,14 @@
 #include "flood_fill.h"
 #include <limits>
 
+template <typename Derivedres, typename DerivedS>
 IGL_INLINE void igl::flood_fill(
-  const Eigen::RowVector3i & res,
-  Eigen::VectorXd & S)
+  const Eigen::MatrixBase<Derivedres>& res, 
+  Eigen::PlainObjectBase<DerivedS> & S)
 {
   using namespace Eigen;
   using namespace std;
+  typedef typename DerivedS::Scalar Scalar;
   const auto flood = [&res,&S] (
      const int xi, 
      const int yi, 
@@ -21,7 +23,7 @@ IGL_INLINE void igl::flood_fill(
      const int signed_xi, 
      const int signed_yi, 
      const int signed_zi,
-     const double s)
+     const Scalar s)
     {
       // flood fill this value back on this row
       for(int bxi = xi;signed_xi<--bxi;)
@@ -49,7 +51,7 @@ IGL_INLINE void igl::flood_fill(
       }
     };
   int signed_zi = -1;
-  double s = numeric_limits<double>::quiet_NaN();
+  Scalar s = numeric_limits<Scalar>::quiet_NaN();
   for(int zi = 0;zi<res(2);zi++)
   {
     int signed_yi = -1;
@@ -86,3 +88,14 @@ IGL_INLINE void igl::flood_fill(
     }
   }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::flood_fill<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::flood_fill<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::flood_fill<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::flood_fill<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
+#endif

+ 4 - 1
include/igl/flood_fill.h

@@ -22,7 +22,10 @@ namespace igl
   //     output
   // Outputs:
   //   S  flood fill data in place
-  IGL_INLINE void flood_fill(const Eigen::RowVector3i& res, Eigen::VectorXd& S);
+  template <typename Derivedres, typename DerivedS>
+  IGL_INLINE void flood_fill(
+    const Eigen::MatrixBase<Derivedres>& res, 
+    Eigen::PlainObjectBase<DerivedS> & S);
 }
 #ifndef IGL_STATIC_LIBRARY
 #  include "flood_fill.cpp"

+ 1 - 1
include/igl/grad.cpp

@@ -139,7 +139,7 @@ IGL_INLINE void grad_tri(const Eigen::PlainObjectBase<DerivedV>&V,
     // This does correct l2 norm of rows, so that it contains #F list of twice
     // triangle areas
     double dblA = std::sqrt(n.dot(n));
-    Eigen::Matrix<typename DerivedV::Scalar, 1, 3> u;
+    Eigen::Matrix<typename DerivedV::Scalar, 1, 3> u(0,0,1);
     if (!uniform) {
       // now normalize normals to get unit normals
       u = n / dblA;

+ 13 - 5
include/igl/grid.cpp

@@ -15,19 +15,21 @@ IGL_INLINE void igl::grid(
   Eigen::PlainObjectBase<DerivedGV> & GV)
 {
   using namespace Eigen;
+  typedef typename DerivedGV::Scalar Scalar;
   GV.resize(res(0)*res(1)*res(2),3);
   for(int zi = 0;zi<res(2);zi++)
   {
     const auto lerp = 
-      [&](const double di, const int d)->double{return di/(double)(res(d)-1);};
-    const double z = lerp(zi,2);
+      [&](const Scalar di, const int d)->Scalar{return di/(Scalar)(res(d)-1);};
+    const Scalar z = lerp(zi,2);
     for(int yi = 0;yi<res(1);yi++)
     {
-      const double y = lerp(yi,1);
+      const Scalar y = lerp(yi,1);
       for(int xi = 0;xi<res(0);xi++)
       {
-        const double x = lerp(xi,0);
-        GV.row(xi+res(0)*(yi + res(1)*zi)) = RowVector3d(x,y,z);
+        const Scalar x = lerp(xi,0);
+        GV.row(xi+res(0)*(yi + res(1)*zi)) = 
+          Eigen::Matrix<Scalar,1,3>(x,y,z);
       }
     }
   }
@@ -37,5 +39,11 @@ IGL_INLINE void igl::grid(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::grid<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::grid<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::grid<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::grid<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
 template void igl::grid<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 64 - 0
include/igl/grid_search.cpp

@@ -0,0 +1,64 @@
+#include "grid_search.h"
+#include <iostream>
+#include <cassert>
+
+template <
+  typename Scalar, 
+  typename DerivedX, 
+  typename DerivedLB, 
+  typename DerivedUB, 
+  typename DerivedI>
+IGL_INLINE Scalar igl::grid_search(
+  const std::function< Scalar (DerivedX &) > f,
+  const Eigen::MatrixBase<DerivedLB> & LB,
+  const Eigen::MatrixBase<DerivedUB> & UB,
+  const Eigen::MatrixBase<DerivedI> & I,
+  DerivedX & X)
+{
+  Scalar fval = std::numeric_limits<Scalar>::max();
+  const int dim = LB.size();
+  assert(UB.size() == dim && "UB should match LB size");
+  assert(I.size() == dim && "I should match LB size");
+  X.resize(dim);
+
+  // Working X value
+  DerivedX Xrun(dim);
+  std::function<void(const int, DerivedX &)> looper;
+  int calls = 0;
+  looper = [&](
+    const int d,
+    DerivedX & Xrun)
+  {
+    assert(d < dim);
+    Eigen::Matrix<Scalar,Eigen::Dynamic,1> vals = 
+      Eigen::Matrix<Scalar,Eigen::Dynamic,1>::LinSpaced(I(d),LB(d),UB(d));
+    for(int c = 0;c<I(d);c++)
+    {
+      Xrun(d) = vals(c);
+      if(d+1 < dim)
+      {
+        looper(d+1,Xrun);
+      }else
+      {
+        //std::cout<<"call: "<<calls<<std::endl;
+        // Base case
+        const Scalar val = f(Xrun);
+        calls++;
+        if(val < fval)
+        {
+          fval = val;
+          X = Xrun;
+          std::cout<<calls<<": "<<fval<<" | "<<X<<std::endl;
+        }
+      }
+    }
+  };
+  looper(0,Xrun);
+
+  return fval;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+template double igl::grid_search<double, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<int, 1, 3, 1, 1, 3> >(std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3>&)>, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3>&);
+template float igl::grid_search<float, Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<int, 1, -1, 1, 1, -1> >(std::function<float (Eigen::Matrix<float, 1, -1, 1, 1, -1>&)>, Eigen::MatrixBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 1, -1, 1, 1, -1> > const&, Eigen::Matrix<float, 1, -1, 1, 1, -1>&);
+#endif

+ 42 - 0
include/igl/grid_search.h

@@ -0,0 +1,42 @@
+#ifndef IGL_GRID_SEARCH_H
+#define IGL_GRID_SEARCH_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <functional>
+namespace igl
+{
+  // Solve the problem:
+  //
+  //   minimize f(x)
+  //   subject to lb ≤ x ≤ ub 
+  // 
+  // by exhaustive grid search.
+  //
+  // Inputs:
+  //   f  function to minimize
+  //   LB  #X vector of finite lower bounds
+  //   UB  #X vector of finite upper bounds
+  //   I  #X vector of number of steps for each variable
+  // Outputs:
+  //   X  #X optimal parameter vector
+  // Returns f(X)
+  //
+  template <
+    typename Scalar, 
+    typename DerivedX, 
+    typename DerivedLB, 
+    typename DerivedUB, 
+    typename DerivedI>
+  IGL_INLINE Scalar grid_search(
+    const std::function< Scalar (DerivedX &) > f,
+    const Eigen::MatrixBase<DerivedLB> & LB,
+    const Eigen::MatrixBase<DerivedUB> & UB,
+    const Eigen::MatrixBase<DerivedI> & I,
+    DerivedX & X);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "grid_search.cpp"
+#endif
+
+#endif

+ 48 - 0
include/igl/hausdorff.cpp

@@ -36,6 +36,54 @@ IGL_INLINE void igl::hausdorff(
   d = sqrt(std::max(dba,dab));
 }
 
+template <
+  typename DerivedV,
+  typename Scalar>
+IGL_INLINE void igl::hausdorff(
+  const Eigen::MatrixBase<DerivedV>& V,
+  const std::function<Scalar(const Scalar &,const Scalar &, const Scalar &)> & dist_to_B,
+  Scalar & l,
+  Scalar & u)
+{
+  // e  3-long vector of opposite edge lengths
+  Eigen::Matrix<typename DerivedV::Scalar,1,3> e;
+  // Maximum edge length
+  Scalar e_max = 0;
+  for(int i=0;i<3;i++)
+  {
+    e(i) = (V.row((i+1)%3)-V.row((i+2)%3)).norm();
+    e_max = std::max(e_max,e(i));
+  }
+  // Semiperimeter
+  const Scalar s = (e(0)+e(1)+e(2))*0.5;
+  // Area
+  const Scalar A = sqrt(s*(s-e(0))*(s-e(1))*(s-e(2)));
+  // Circumradius
+  const Scalar R = e(0)*e(1)*e(2)/(4.*A);
+  // inradius
+  const Scalar r = A/s;
+  // Initialize lower bound to ∞
+  l = std::numeric_limits<Scalar>::infinity();
+  // d  3-long vector of distance from each corner to B
+  Eigen::Matrix<typename DerivedV::Scalar,1,3> d;
+  Scalar u1 = std::numeric_limits<Scalar>::infinity();
+  Scalar u2 = 0;
+  for(int i=0;i<3;i++)
+  {
+    d(i) = dist_to_B(V(i,0),V(i,1),V(i,2));
+    // Lower bound is simply the max over vertex distances
+    l = std::max(d(i),l);
+    // u1 is the minimum of corner distances + maximum adjacent edge 
+    u1 = std::min(u1,d(i) + std::max(e((i+1)%3),e((i+2)%3)));
+    // u2 first takes the maximum over corner distances
+    u2 = std::max(u2,d(i));
+  }
+  // u2 is the distance from the circumcenter/midpoint of obtuse edge plus the
+  // largest corner distance 
+  u2 += (s-r>2.*R ? R : 0.5*e_max);
+  u = std::min(u1,u2);
+}
+
 #ifdef IGL_STATIC_LIBRARY
 template void igl::hausdorff<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double&);
 #endif

+ 23 - 0
include/igl/hausdorff.h

@@ -10,6 +10,7 @@
 #include "igl_inline.h"
 
 #include <Eigen/Dense>
+#include <functional>
 
 namespace igl 
 {
@@ -50,6 +51,28 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedVB> & VB, 
     const Eigen::PlainObjectBase<DerivedFB> & FB,
     Scalar & d);
+  // Compute lower and upper bounds (l,u) on the Hausdorff distance between a triangle
+  // (V) and a pointset (e.g., mesh, triangle soup) given by a distance function
+  // handle (dist_to_B).
+  //
+  // Inputs:
+  //   V   3 by 3 list of corner positions so that V.row(i) is the position of the
+  //     ith corner
+  //   dist_to_B  function taking the x,y,z coordinate of a query position and
+  //     outputing the closest-point distance to some point-set B
+  // Outputs:
+  //   l  lower bound on Hausdorff distance 
+  //   u  upper bound on Hausdorff distance
+  //
+  template <
+    typename DerivedV,
+    typename Scalar>
+  IGL_INLINE void hausdorff(
+    const Eigen::MatrixBase<DerivedV>& V,
+    const std::function<
+      Scalar(const Scalar &,const Scalar &, const Scalar &)> & dist_to_B,
+    Scalar & l,
+    Scalar & u);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 60 - 0
include/igl/hessian.cpp

@@ -0,0 +1,60 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//  and Oded Stein <oded.stein@columbia.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "hessian.h"
+#include <vector>
+
+#include "grad.h"
+#include "igl/doublearea.h"
+#include "igl/repdiag.h"
+
+
+
+template <typename DerivedV, typename DerivedF, typename Scalar>
+IGL_INLINE void igl::hessian(
+                             const Eigen::MatrixBase<DerivedV> & V,
+                             const Eigen::MatrixBase<DerivedF> & F,
+                             Eigen::SparseMatrix<Scalar>& H)
+{
+    typedef typename DerivedV::Scalar denseScalar;
+    typedef typename Eigen::Matrix<denseScalar, Eigen::Dynamic, 1> VecXd;
+    typedef typename Eigen::SparseMatrix<Scalar> SparseMat;
+    typedef typename Eigen::DiagonalMatrix
+                       <Scalar, Eigen::Dynamic, Eigen::Dynamic> DiagMat;
+    
+    int dim = V.cols();
+    assert((dim==2 || dim==3) &&
+           "The dimension of the vertices should be 2 or 3");
+    
+    //Construct the combined gradient matric
+    SparseMat G;
+    igl::grad(Eigen::PlainObjectBase<DerivedV>(V),
+              Eigen::PlainObjectBase<DerivedF>(F),
+              G, false);
+    SparseMat GG(F.rows(), dim*V.rows());
+    GG.reserve(G.nonZeros());
+    for(int i=0; i<dim; ++i)
+        GG.middleCols(i*G.cols(),G.cols()) = G.middleRows(i*F.rows(),F.rows());
+    SparseMat D;
+    igl::repdiag(GG,dim,D);
+    
+    //Compute area matrix
+    VecXd areas;
+    igl::doublearea(V, F, areas);
+    DiagMat A = (0.5*areas).replicate(dim,1).asDiagonal();
+    
+    //Compute FEM Hessian
+    H = D.transpose()*A*G;
+}
+
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::hessian<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
+#endif

+ 47 - 0
include/igl/hessian.h

@@ -0,0 +1,47 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//  and Oded Stein <oded.stein@columbia.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// 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/.
+
+#ifndef IGL_FEM_HESSIAN_H
+#define IGL_FEM_HESSIAN_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+
+namespace igl
+{
+    // Constructs the finite element Hessian matrix
+    // as described in https://arxiv.org/abs/1707.04348,
+    // Natural Boundary Conditions for Smoothing in Geometry Processing
+    // (Oded Stein, Eitan Grinspun, Max Wardetzky, Alec Jacobson)
+    // The interior vertices are NOT set to zero yet.
+    //
+    // Inputs:
+    //   V  #V by dim list of mesh vertex positions
+    //   F  #F by 3 list of mesh faces (must be triangles)
+    // Outputs:
+    //   H  #V by #V Hessian energy matrix, each column i
+    //     corresponding to V(i,:)
+    //
+    //
+    //
+    template <typename DerivedV, typename DerivedF, typename Scalar>
+    IGL_INLINE void hessian(
+                            const Eigen::MatrixBase<DerivedV> & V,
+                            const Eigen::MatrixBase<DerivedF> & F,
+                            Eigen::SparseMatrix<Scalar>& H);
+    
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "hessian.cpp"
+#endif
+
+#endif

+ 64 - 0
include/igl/hessian_energy.cpp

@@ -0,0 +1,64 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//   and Oded Stein <oded.stein@columbia.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "hessian_energy.h"
+#include <vector>
+
+#include "hessian.h"
+#include "massmatrix.h"
+#include "boundary_loop.h"
+
+
+template <typename DerivedV, typename DerivedF, typename Scalar>
+IGL_INLINE void igl::hessian_energy(
+                                    const Eigen::MatrixBase<DerivedV> & V,
+                                    const Eigen::MatrixBase<DerivedF> & F,
+                                    Eigen::SparseMatrix<Scalar>& Q)
+{
+    typedef typename DerivedV::Scalar denseScalar;
+    typedef typename Eigen::Matrix<denseScalar, Eigen::Dynamic, 1> VecXd;
+    typedef typename Eigen::SparseMatrix<Scalar> SparseMat;
+    typedef typename Eigen::DiagonalMatrix
+                       <Scalar, Eigen::Dynamic, Eigen::Dynamic> DiagMat;
+    
+    int dim = V.cols();
+    assert((dim==2 || dim==3) &&
+           "The dimension of the vertices should be 2 or 3");
+    
+    SparseMat M;
+    igl::massmatrix(V,F,igl::MASSMATRIX_TYPE_VORONOI,M);
+    
+    //Kill non-interior DOFs
+    VecXd Mint = M.diagonal();
+    std::vector<std::vector<int> > bdryLoop;
+    igl::boundary_loop(Eigen::PlainObjectBase<DerivedF>(F),bdryLoop);
+    for(const std::vector<int>& loop : bdryLoop)
+        for(const int& bdryVert : loop)
+            Mint(bdryVert) = 0.;
+    
+    //Invert Mint
+    for(int i=0; i<Mint.rows(); ++i)
+        if(Mint(i) > 0)
+            Mint(i) = 1./Mint(i);
+    
+    //Repeat Mint to form diaginal matrix
+    DiagMat stackedMinv = Mint.replicate(dim*dim,1).asDiagonal();
+    
+    //Compute squared Hessian
+    SparseMat H;
+    igl::hessian(V,F,H);
+    Q = H.transpose()*stackedMinv*H;
+    
+}
+
+
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::hessian_energy<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
+#endif

+ 45 - 0
include/igl/hessian_energy.h

@@ -0,0 +1,45 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
+//  and Oded Stein <oded.stein@columbia.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// 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/.
+#ifndef IGL_HESSIAN_ENERGY_H
+#define IGL_HESSIAN_ENERGY_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+
+namespace igl
+{
+    // Constructs the Hessian energy matrix using mixed FEM
+    // as described in https://arxiv.org/abs/1707.04348
+    // Natural Boundary Conditions for Smoothing in Geometry Processing
+    // (Oded Stein, Eitan Grinspun, Max Wardetzky, Alec Jacobson)
+    //
+    // Inputs:
+    //   V  #V by dim list of mesh vertex positions
+    //   F  #F by 3 list of mesh faces (must be triangles)
+    // Outputs:
+    //   Q  #V by #V Hessian energy matrix, each row/column i
+    //     corresponding to V(i,:)
+    //
+    //
+    //
+    template <typename DerivedV, typename DerivedF, typename Scalar>
+    IGL_INLINE void hessian_energy(
+                                   const Eigen::MatrixBase<DerivedV> & V,
+                                   const Eigen::MatrixBase<DerivedF> & F,
+                                   Eigen::SparseMatrix<Scalar>& Q);
+    
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "hessian_energy.cpp"
+#endif
+
+#endif

+ 4 - 0
include/igl/internal_angles.cpp

@@ -116,6 +116,10 @@ IGL_INLINE void igl::internal_angles_using_edge_lengths(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::internal_angles<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::internal_angles<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
 template void igl::internal_angles<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
 template void igl::internal_angles<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::internal_angles<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);

+ 1 - 1
include/igl/is_boundary_edge.cpp

@@ -6,7 +6,7 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can 
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "is_boundary_edge.h"
-#include "unique.h"
+#include "unique_rows.h"
 #include "sort.h"
 
 template <

+ 11 - 8
include/igl/ismember.cpp

@@ -11,6 +11,7 @@
 #include "sort.h"
 #include "sortrows.h"
 #include "unique.h"
+#include "unique_rows.h"
 
 template <
   typename DerivedA,
@@ -18,8 +19,8 @@ template <
   typename DerivedIA,
   typename DerivedLOCB>
 IGL_INLINE void igl::ismember(
-  const Eigen::PlainObjectBase<DerivedA> & A,
-  const Eigen::PlainObjectBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
   Eigen::PlainObjectBase<DerivedIA> & IA,
   Eigen::PlainObjectBase<DerivedLOCB> & LOCB)
 {
@@ -42,8 +43,8 @@ IGL_INLINE void igl::ismember(
   // Get rid of any duplicates
   typedef Matrix<typename DerivedA::Scalar,Dynamic,1> VectorA;
   typedef Matrix<typename DerivedB::Scalar,Dynamic,1> VectorB;
-  const VectorA vA(Eigen::Map<const VectorA>(A.data(), A.cols()*A.rows(),1));
-  const VectorB vB(Eigen::Map<const VectorB>(B.data(), B.cols()*B.rows(),1));
+  const VectorA vA(Eigen::Map<const VectorA>(DerivedA(A).data(), A.cols()*A.rows(),1));
+  const VectorB vB(Eigen::Map<const VectorB>(DerivedB(B).data(), B.cols()*B.rows(),1));
   VectorA uA;
   VectorB uB;
   Eigen::Matrix<typename DerivedA::Index,Dynamic,1> uIA,uIuA,uIB,uIuB;
@@ -97,8 +98,8 @@ template <
   typename DerivedIA,
   typename DerivedLOCB>
 IGL_INLINE void igl::ismember_rows(
-  const Eigen::PlainObjectBase<DerivedA> & A,
-  const Eigen::PlainObjectBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
   Eigen::PlainObjectBase<DerivedIA> & IA,
   Eigen::PlainObjectBase<DerivedLOCB> & LOCB)
 {
@@ -174,6 +175,8 @@ IGL_INLINE void igl::ismember_rows(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::ismember<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::ismember_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::ismember_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 4 - 4
include/igl/ismember.h

@@ -28,8 +28,8 @@ namespace igl
     typename DerivedIA,
     typename DerivedLOCB>
   IGL_INLINE void ismember(
-    const Eigen::PlainObjectBase<DerivedA> & A,
-    const Eigen::PlainObjectBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
     Eigen::PlainObjectBase<DerivedIA> & IA,
     Eigen::PlainObjectBase<DerivedLOCB> & LOCB);
   template <
@@ -38,8 +38,8 @@ namespace igl
     typename DerivedIA,
     typename DerivedLOCB>
   IGL_INLINE void ismember_rows(
-    const Eigen::PlainObjectBase<DerivedA> & A,
-    const Eigen::PlainObjectBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
     Eigen::PlainObjectBase<DerivedIA> & IA,
     Eigen::PlainObjectBase<DerivedLOCB> & LOCB);
 

+ 116 - 0
include/igl/isolines.cpp

@@ -0,0 +1,116 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2017 Oded Stein <oded.stein@columbia.edu>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#include "isolines.h"
+
+#include <vector>
+#include <array>
+#include <iostream>
+
+#include "remove_duplicate_vertices.h"
+
+
+template <typename DerivedV,
+typename DerivedF,
+typename DerivedZ,
+typename DerivedIsoV,
+typename DerivedIsoE>
+IGL_INLINE void igl::isolines(
+                              const Eigen::MatrixBase<DerivedV>& V,
+                              const Eigen::MatrixBase<DerivedF>& F,
+                              const Eigen::MatrixBase<DerivedZ>& z,
+                              const int n,
+                              Eigen::PlainObjectBase<DerivedIsoV>& isoV,
+                              Eigen::PlainObjectBase<DerivedIsoE>& isoE)
+{
+    //Constants
+    const int dim = V.cols();
+    assert(dim==2 || dim==3);
+    const int nVerts = V.rows();
+    assert(z.rows() == nVerts &&
+           "There must be as many function entries as vertices");
+    const int nFaces = F.rows();
+    const int np1 = n+1;
+    const double min = z.minCoeff(), max = z.maxCoeff();
+    
+    
+    //Following http://www.alecjacobson.com/weblog/?p=2529
+    typedef typename DerivedZ::Scalar Scalar;
+    typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> Vec;
+    Vec iso(np1);
+    for(int i=0; i<np1; ++i)
+        iso(i) = Scalar(i)/Scalar(n)*(max-min) + min;
+    
+    typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Matrix;
+    std::array<Matrix,3> t{{Matrix(nFaces, np1),
+        Matrix(nFaces, np1), Matrix(nFaces, np1)}};
+    for(int i=0; i<nFaces; ++i) {
+        for(int k=0; k<3; ++k) {
+            const Scalar z1=z(F(i,k)), z2=z(F(i,(k+1)%3));
+            for(int j=0; j<np1; ++j) {
+                t[k](i,j) = (iso(j)-z1) / (z2-z1);
+                if(t[k](i,j)<0 || t[k](i,j)>1)
+                    t[k](i,j) = std::numeric_limits<Scalar>::quiet_NaN();
+            }
+        }
+    }
+    
+    std::array<std::vector<int>,3> Fij, Iij;
+    for(int i=0; i<nFaces; ++i) {
+        for(int j=0; j<np1; ++j) {
+            for(int k=0; k<3; ++k) {
+                const int kp1=(k+1)%3, kp2=(k+2)%3;
+                if(std::isfinite(t[kp1](i,j)) && std::isfinite(t[kp2](i,j))) {
+                    Fij[k].push_back(i);
+                    Iij[k].push_back(j);
+                }
+            }
+        }
+    }
+    
+    const int K = Fij[0].size()+Fij[1].size()+Fij[2].size();
+    isoV.resize(2*K, dim);
+    int b = 0;
+    for(int k=0; k<3; ++k) {
+        const int kp1=(k+1)%3, kp2=(k+2)%3;
+        for(int i=0; i<Fij[k].size(); ++i) {
+            isoV.row(b+i) = (1.-t[kp1](Fij[k][i],Iij[k][i]))*
+            V.row(F(Fij[k][i],kp1)) +
+            t[kp1](Fij[k][i],Iij[k][i])*V.row(F(Fij[k][i],kp2));
+            isoV.row(K+b+i) = (1.-t[kp2](Fij[k][i],Iij[k][i]))*
+            V.row(F(Fij[k][i],kp2)) +
+            t[kp2](Fij[k][i],Iij[k][i])*V.row(F(Fij[k][i],k));
+        }
+        b += Fij[k].size();
+    }
+    
+    isoE.resize(K,2);
+    for(int i=0; i<K; ++i)
+        isoE.row(i) << i, K+i;
+    
+    
+    //Remove double entries
+    typedef typename DerivedIsoV::Scalar LScalar;
+    typedef typename DerivedIsoE::Scalar LInt;
+    typedef Eigen::Matrix<LInt, Eigen::Dynamic, 1> LIVec;
+    typedef Eigen::Matrix<LScalar, Eigen::Dynamic, Eigen::Dynamic> LMat;
+    typedef Eigen::Matrix<LInt, Eigen::Dynamic, Eigen::Dynamic> LIMat;
+    LIVec dummy1, dummy2;
+    igl::remove_duplicate_vertices(LMat(isoV), LIMat(isoE),
+                                   2.2204e-15, isoV, dummy1, dummy2, isoE);
+    
+}
+
+
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::isolines<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, int const, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &);
+#endif
+

Some files were not shown because too many files changed in this diff