Эх сурвалжийг харах

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

Former-commit-id: 2214167e8eb77172847cc296aeaa0710d0bac30e
Oded Stein 7 жил өмнө
parent
commit
5f0f6f002d
100 өөрчлөгдсөн 1796 нэмэгдсэн , 607 устгасан
  1. 0 2
      ACKNOWLEDGEMENTS
  2. 5 2
      README.md
  3. 0 15
      exclude.lst
  4. 192 90
      include/igl/AABB.cpp
  5. 78 35
      include/igl/AABB.h
  6. 76 70
      include/igl/WindingNumberAABB.h
  7. 119 119
      include/igl/WindingNumberTree.h
  8. 1 1
      include/igl/angle_bound_frame_fields.cpp
  9. 10 0
      include/igl/barycenter.cpp
  10. 4 0
      include/igl/barycentric_coordinates.cpp
  11. 1 1
      include/igl/collapse_edge.h
  12. 2 0
      include/igl/copyleft/cgal/assign.cpp
  13. 2 0
      include/igl/copyleft/cgal/closest_facet.cpp
  14. 2 0
      include/igl/copyleft/cgal/extract_cells.cpp
  15. 9 1
      include/igl/copyleft/cgal/mesh_boolean.cpp
  16. 4 0
      include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp
  17. 3 1
      include/igl/copyleft/cgal/minkowski_sum.cpp
  18. 4 0
      include/igl/copyleft/cgal/order_facets_around_edge.cpp
  19. 1 0
      include/igl/copyleft/cgal/outer_element.cpp
  20. 4 0
      include/igl/copyleft/cgal/outer_facet.cpp
  21. 2 0
      include/igl/copyleft/cgal/propagate_winding_numbers.cpp
  22. 5 1
      include/igl/copyleft/cgal/remesh_intersections.cpp
  23. 2 0
      include/igl/copyleft/cgal/remesh_self_intersections.cpp
  24. 1 0
      include/igl/copyleft/cgal/remove_unreferenced.cpp
  25. 1 1
      include/igl/copyleft/cgal/signed_distance_isosurface.cpp
  26. 2 0
      include/igl/copyleft/cgal/submesh_aabb_tree.cpp
  27. 0 3
      include/igl/copyleft/cgal/unique.cpp
  28. 18 0
      include/igl/copyleft/cgal/unique_rows.cpp
  29. 27 19
      include/igl/copyleft/marching_cubes.cpp
  30. 8 4
      include/igl/copyleft/marching_cubes.h
  31. 22 4
      include/igl/copyleft/offset_surface.cpp
  32. 2 1
      include/igl/copyleft/offset_surface.h
  33. 8 0
      include/igl/decimate.cpp
  34. 8 2
      include/igl/dirname.cpp
  35. 19 6
      include/igl/doublearea.cpp
  36. 6 0
      include/igl/edge_lengths.cpp
  37. 10 6
      include/igl/edge_topology.h
  38. 1 0
      include/igl/embree/EmbreeIntersector.h
  39. 1 1
      include/igl/exterior_edges.cpp
  40. 2 0
      include/igl/extract_manifold_patches.cpp
  41. 17 4
      include/igl/flood_fill.cpp
  42. 4 1
      include/igl/flood_fill.h
  43. 13 5
      include/igl/grid.cpp
  44. 64 0
      include/igl/grid_search.cpp
  45. 42 0
      include/igl/grid_search.h
  46. 4 0
      include/igl/internal_angles.cpp
  47. 1 1
      include/igl/is_boundary_edge.cpp
  48. 1 0
      include/igl/ismember.cpp
  49. 2 0
      include/igl/list_to_matrix.cpp
  50. 1 0
      include/igl/matlab/prepare_lhs.cpp
  51. 4 0
      include/igl/matrix_to_list.cpp
  52. 12 2
      include/igl/median.cpp
  53. 3 1
      include/igl/median.h
  54. 1 1
      include/igl/orientable_patches.cpp
  55. 2 1
      include/igl/oriented_facets.cpp
  56. 3 0
      include/igl/parallel_for.h
  57. 2 0
      include/igl/parula.cpp
  58. 4 0
      include/igl/per_edge_normals.cpp
  59. 6 0
      include/igl/per_face_normals.cpp
  60. 2 1
      include/igl/per_vertex_normals.cpp
  61. 7 4
      include/igl/piecewise_constant_winding_number.cpp
  62. 3 3
      include/igl/piecewise_constant_winding_number.h
  63. 14 0
      include/igl/point_simplex_squared_distance.cpp
  64. 6 0
      include/igl/project_to_line.cpp
  65. 6 0
      include/igl/project_to_line_segment.cpp
  66. 33 2
      include/igl/pseudonormal_test.cpp
  67. 174 0
      include/igl/pso.cpp
  68. 59 0
      include/igl/pso.h
  69. 8 0
      include/igl/qslim.cpp
  70. 36 0
      include/igl/random_search.cpp
  71. 42 0
      include/igl/random_search.h
  72. 2 0
      include/igl/readMESH.cpp
  73. 8 10
      include/igl/readOBJ.cpp
  74. 2 0
      include/igl/read_triangle_mesh.cpp
  75. 4 1
      include/igl/remove_duplicate_vertices.cpp
  76. 3 0
      include/igl/remove_unreferenced.cpp
  77. 3 0
      include/igl/resolve_duplicated_faces.cpp
  78. 4 0
      include/igl/round.cpp
  79. 68 0
      include/igl/signed_angle.cpp
  80. 27 0
      include/igl/signed_angle.h
  81. 109 44
      include/igl/signed_distance.cpp
  82. 25 3
      include/igl/signed_distance.h
  83. 6 0
      include/igl/slice.cpp
  84. 77 0
      include/igl/solid_angle.cpp
  85. 29 0
      include/igl/solid_angle.h
  86. 2 0
      include/igl/sort.cpp
  87. 4 0
      include/igl/sortrows.cpp
  88. 5 0
      include/igl/squared_edge_lengths.cpp
  89. 2 2
      include/igl/triangle/triangulate.cpp
  90. 1 0
      include/igl/triangle_triangle_adjacency.cpp
  91. 7 10
      include/igl/triangle_triangle_adjacency.h
  92. 10 89
      include/igl/unique.cpp
  93. 0 18
      include/igl/unique.h
  94. 2 0
      include/igl/unique_edge_map.cpp
  95. 1 1
      include/igl/unique_edge_map.h
  96. 98 0
      include/igl/unique_rows.cpp
  97. 41 0
      include/igl/unique_rows.h
  98. 3 1
      include/igl/unique_simplices.cpp
  99. 1 1
      include/igl/unzip_corners.cpp
  100. 14 16
      include/igl/vector_area_matrix.cpp

+ 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)

+ 5 - 2
README.md

@@ -207,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

+ 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
     };

+ 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

+ 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)
   {

+ 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

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

@@ -49,6 +49,8 @@ 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> >&);

+ 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

+ 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> >&);

+ 9 - 1
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> >&);

+ 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&);

+ 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

+ 5 - 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>
@@ -470,6 +470,10 @@ 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> >&);

+ 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:

+ 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

+ 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
+

+ 27 - 19
include/igl/copyleft/marching_cubes.cpp

@@ -53,7 +53,7 @@ private:
 };
 
 
-template <typename DerivedV1, typename DerivedV2, typename DerivedF>
+template <typename Derivedvalues, typename Derivedpoints,typename Derivedvertices, typename DerivedF>
 class MarchingCubes
 {
   typedef std::map<EdgeKey, unsigned>  MyMap;
@@ -61,12 +61,12 @@ class MarchingCubes
 
 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 +181,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 +196,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 +220,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 +240,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,

+ 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,

+ 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/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)

+ 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>

+ 2 - 0
include/igl/extract_manifold_patches.cpp

@@ -93,6 +93,8 @@ 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 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> >&);

+ 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"

+ 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

+ 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 <

+ 1 - 0
include/igl/ismember.cpp

@@ -11,6 +11,7 @@
 #include "sort.h"
 #include "sortrows.h"
 #include "unique.h"
+#include "unique_rows.h"
 
 template <
   typename DerivedA,

+ 2 - 0
include/igl/list_to_matrix.cpp

@@ -119,6 +119,8 @@ IGL_INLINE bool igl::list_to_matrix(const std::vector<T > & V,Eigen::PlainObject
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::list_to_matrix<double, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
 // generated by autoexplicit.sh
 // generated by autoexplicit.sh
 template bool igl::list_to_matrix<long, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 1 - 0
include/igl/matlab/prepare_lhs.cpp

@@ -95,4 +95,5 @@ template void igl::matlab::prepare_lhs_logical<Eigen::Matrix<bool, -1, 1, 0, -1,
 template void igl::matlab::prepare_lhs_index<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, mxArray_tag**);
 template void igl::matlab::prepare_lhs_double<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, mxArray_tag**);
 template void igl::matlab::prepare_lhs_double<Eigen::Matrix<int, 1, -1, 1, 1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, 1, -1, 1, 1, -1> > const&, mxArray_tag**);
+template void igl::matlab::prepare_lhs_double<Eigen::Matrix<int, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, mxArray_tag**);
 #endif

+ 4 - 0
include/igl/matrix_to_list.cpp

@@ -56,6 +56,10 @@ IGL_INLINE std::vector<typename DerivedM::Scalar > igl::matrix_to_list(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::matrix_to_list<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true> >(Eigen::DenseBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true> > const&, std::vector<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true>::Scalar, std::allocator<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true>::Scalar> >&);
+// generated by autoexplicit.sh
+template void igl::matrix_to_list<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> >(Eigen::DenseBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> > const&, std::vector<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true>::Scalar, std::allocator<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true>::Scalar> >&);
+// generated by autoexplicit.sh
 template void igl::matrix_to_list<Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<Eigen::Matrix<int, -1, 2, 0, -1, 2>::Scalar, std::allocator<Eigen::Matrix<int, -1, 2, 0, -1, 2>::Scalar> >&);
 // generated by autoexplicit.sh
 template std::vector<Eigen::Matrix<double, -1, 1, 0, -1, 1>::Scalar, std::allocator<Eigen::Matrix<double, -1, 1, 0, -1, 1>::Scalar> > igl::matrix_to_list<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&);

+ 12 - 2
include/igl/median.cpp

@@ -11,14 +11,16 @@
 #include <vector>
 #include <algorithm>
 
-IGL_INLINE bool igl::median(const Eigen::VectorXd & V, double & m)
+template <typename DerivedV, typename mType>
+IGL_INLINE bool igl::median(
+  const Eigen::MatrixBase<DerivedV> & V, mType & m)
 {
   using namespace std;
   if(V.size() == 0)
   {
     return false;
   }
-  vector<double> vV;
+  vector<typename DerivedV::Scalar> vV;
   matrix_to_list(V,vV);
   // http://stackoverflow.com/a/1719155/148668
   size_t n = vV.size()/2;
@@ -33,3 +35,11 @@ IGL_INLINE bool igl::median(const Eigen::VectorXd & V, double & m)
   }
   return true;
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template bool igl::median<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true>, float>(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true> > const&, float&);
+// generated by autoexplicit.sh
+template bool igl::median<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true>, double>(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> > const&, double&);
+#endif

+ 3 - 1
include/igl/median.h

@@ -18,7 +18,9 @@ namespace igl
   // Outputs:
   //   m  median of those values
   // Returns true on success, false on failure
-  IGL_INLINE bool median(const Eigen::VectorXd & V, double & m);
+  template <typename DerivedV, typename mType>
+  IGL_INLINE bool median(
+    const Eigen::MatrixBase<DerivedV> & V, mType & m);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 1 - 1
include/igl/orientable_patches.cpp

@@ -8,7 +8,7 @@
 #include "orientable_patches.h"
 #include "components.h"
 #include "sort.h"
-#include "unique.h"
+#include "unique_rows.h"
 #include <vector>
 #include <iostream>
 

+ 2 - 1
include/igl/oriented_facets.cpp

@@ -46,10 +46,11 @@ IGL_INLINE void igl::oriented_facets(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::oriented_facets<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::oriented_facets<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> >&);
 template void igl::oriented_facets<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
 template void igl::oriented_facets<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::oriented_facets<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::oriented_facets<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
 #endif
-

+ 3 - 0
include/igl/parallel_for.h

@@ -10,6 +10,9 @@
 #include "igl_inline.h"
 #include <functional>
 
+//#warning "Defining IGL_PARALLEL_FOR_FORCE_SERIAL"
+//#define IGL_PARALLEL_FOR_FORCE_SERIAL
+
 namespace igl
 {
   // PARALLEL_FOR Functional implementation of a basic, open-mp style, parallel

+ 2 - 0
include/igl/parula.cpp

@@ -68,6 +68,8 @@ IGL_INLINE void igl::parula(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::parula<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> >&);
+// generated by autoexplicit.sh
 template void igl::parula<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> >&);
 template void igl::parula<double>(double, double*);
 template void igl::parula<double>(double, double&, double&, double&);

+ 4 - 0
include/igl/per_edge_normals.cpp

@@ -115,6 +115,10 @@ IGL_INLINE void igl::per_edge_normals(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::per_edge_normals<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<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -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&, igl::PerEdgeNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -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> >&);
+// generated by autoexplicit.sh
+template void igl::per_edge_normals<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::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -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&, igl::PerEdgeNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -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> >&);
+// generated by autoexplicit.sh
 template void igl::per_edge_normals<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, 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::PerEdgeNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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> >&);
 template void igl::per_edge_normals<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::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 void igl::per_edge_normals<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::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::PerEdgeNormalsWeightingType, 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<int, -1, 1, 0, -1, 1> >&);

+ 6 - 0
include/igl/per_face_normals.cpp

@@ -105,6 +105,12 @@ IGL_INLINE void igl::per_face_normals_stable(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::per_face_normals<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::per_face_normals<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > 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::per_face_normals<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> >&);
 template void igl::per_face_normals<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::per_face_normals<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::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> >&);
 template void igl::per_face_normals<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> >&);

+ 2 - 1
include/igl/per_vertex_normals.cpp

@@ -121,7 +121,8 @@ IGL_INLINE void igl::per_vertex_normals(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-// generated by autoexplicit.sh
+template void igl::per_vertex_normals<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<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&, igl::PerVertexNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+template void igl::per_vertex_normals<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::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&, igl::PerVertexNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
 template void igl::per_vertex_normals<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&, igl::PerVertexNormalsWeightingType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::per_vertex_normals<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::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> >&);
 template void igl::per_vertex_normals<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::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&, igl::PerVertexNormalsWeightingType, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);

+ 7 - 4
include/igl/piecewise_constant_winding_number.cpp

@@ -13,8 +13,8 @@ template <
   typename DeriveduE,
   typename uE2EType>
 IGL_INLINE bool igl::piecewise_constant_winding_number(
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  const Eigen::PlainObjectBase<DeriveduE>& uE,
+  const Eigen::MatrixBase<DerivedF>& F,
+  const Eigen::MatrixBase<DeriveduE>& uE,
   const std::vector<std::vector<uE2EType> >& uE2E)
 {
   const size_t num_faces = F.rows();
@@ -60,7 +60,7 @@ IGL_INLINE bool igl::piecewise_constant_winding_number(
 }
 template <typename DerivedF>
 IGL_INLINE bool igl::piecewise_constant_winding_number(
-  const Eigen::PlainObjectBase<DerivedF>& F)
+  const Eigen::MatrixBase<DerivedF>& F)
 {
   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> E, uE;
   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> EMAP;
@@ -70,5 +70,8 @@ IGL_INLINE bool igl::piecewise_constant_winding_number(
 }
 
 #ifdef IGL_STATIC_LIBRARY
-template bool igl::piecewise_constant_winding_number<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long>(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&);
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template bool igl::piecewise_constant_winding_number<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<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&);
+template bool igl::piecewise_constant_winding_number<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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&);
 #endif

+ 3 - 3
include/igl/piecewise_constant_winding_number.h

@@ -36,12 +36,12 @@ namespace igl
     typename DeriveduE,
     typename uE2EType>
   IGL_INLINE bool piecewise_constant_winding_number(
-    const Eigen::PlainObjectBase<DerivedF>& F,
-    const Eigen::PlainObjectBase<DeriveduE>& uE,
+    const Eigen::MatrixBase<DerivedF>& F,
+    const Eigen::MatrixBase<DeriveduE>& uE,
     const std::vector<std::vector<uE2EType> >& uE2E);
   template <typename DerivedF>
   IGL_INLINE bool piecewise_constant_winding_number(
-    const Eigen::PlainObjectBase<DerivedF>& F);
+    const Eigen::MatrixBase<DerivedF>& F);
 }
 #ifndef IGL_STATIC_LIBRARY
 #  include "piecewise_constant_winding_number.cpp"

+ 14 - 0
include/igl/point_simplex_squared_distance.cpp

@@ -154,8 +154,22 @@ IGL_INLINE void igl::point_simplex_squared_distance(
   point_simplex_squared_distance<DIM>( p, V, Ele, primitive, sqr_d, c, b );
 }
 
+namespace igl
+{
+  template <> IGL_INLINE void point_simplex_squared_distance<2>(Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, float&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) {assert(false);};
+  template <> IGL_INLINE void point_simplex_squared_distance<2>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) {assert(false);};
+  template <> IGL_INLINE void point_simplex_squared_distance<2>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > 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<int, -1, 3, 1, -1, 3>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) {assert(false);};
+}
+
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::point_simplex_squared_distance<3, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, float, 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, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, float&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+// generated by autoexplicit.sh
+// generated by autoexplicit.sh
+template void igl::point_simplex_squared_distance<3, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, float, 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<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, float&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::point_simplex_squared_distance<3, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, float, 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<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, float&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
 template void igl::point_simplex_squared_distance<3, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 template void igl::point_simplex_squared_distance<2, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&);
 template void igl::point_simplex_squared_distance<3, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);

+ 6 - 0
include/igl/project_to_line.cpp

@@ -121,6 +121,12 @@ IGL_INLINE void igl::project_to_line(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::project_to_line<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<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(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::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::project_to_line<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, 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<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::project_to_line<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::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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::project_to_line<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::project_to_line<Eigen::Block<Eigen::Matrix<double, -1, 2, 0, -1, 2> const, -1, -1, false>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, 2, 0, -1, 2> const, -1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);

+ 6 - 0
include/igl/project_to_line_segment.cpp

@@ -44,6 +44,12 @@ IGL_INLINE void igl::project_to_line_segment(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::project_to_line_segment<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<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(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::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::project_to_line_segment<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, 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<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::project_to_line_segment<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::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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::project_to_line_segment<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
 template void igl::project_to_line_segment<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, 1, 0, 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<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
 #endif

+ 33 - 2
include/igl/pseudonormal_test.cpp

@@ -153,8 +153,11 @@ IGL_INLINE void igl::pseudonormal_test(
   const auto & qc = q-c;
   const double len = (V.row(E(e,1))-V.row(E(e,0))).norm();
   // barycentric coordinates
+  // this .head() nonsense is for "ridiculus" templates instantiations that AABB
+  // needs to compile
   Eigen::Matrix<Scalar,1,2>
     b((c-V.row(E(e,1))).norm()/len,(c-V.row(E(e,0))).norm()/len);
+    //b((c-V.row(E(e,1)).head(c.size())).norm()/len,(c-V.row(E(e,0)).head(c.size())).norm()/len);
   // Determine which normal to use
   const double epsilon = 1e-12;
   const int type = (b.array()<=epsilon).template cast<int>().sum();
@@ -180,12 +183,40 @@ IGL_INLINE void igl::pseudonormal_test(
   s = (qc.dot(n) >= 0 ? 1. : -1.);
 }
 
+// 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
+namespace igl
+{
+  template <> IGL_INLINE void pseudonormal_test(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&){assert(false);};
+  template <> IGL_INLINE void pseudonormal_test(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&){assert(false);};
+  template <> IGL_INLINE void pseudonormal_test(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&){assert(false);};
+  template <> IGL_INLINE void pseudonormal_test(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&){assert(false);};
+  template <> IGL_INLINE void pseudonormal_test(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&) {assert(false);};
+}
+
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template void igl::pseudonormal_test<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::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 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::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&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+template void igl::pseudonormal_test<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<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, float, Eigen::Matrix<float, 1, 3, 1, 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::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+// generated by autoexplicit.sh
 // generated by autoexplicit.sh
-template void igl::pseudonormal_test<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 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, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 // generated by autoexplicit.sh
+// generated by autoexplicit.sh
+template void igl::pseudonormal_test<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::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, -1, 1, 1, -1>, float, Eigen::Matrix<float, 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::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::pseudonormal_test<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, 1, 2, 1, 1, 2>, Eigen::Matrix<float, 1, -1, 1, 1, -1>, float, Eigen::Matrix<float, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&);
+template void igl::pseudonormal_test<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&);
+// generated by autoexplicit.sh
+template void igl::pseudonormal_test<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, double, Eigen::Matrix<double, 1, 3, 1, 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, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::pseudonormal_test<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&);
+// generated by autoexplicit.sh
+template void igl::pseudonormal_test<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 1, -1, false>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 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, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 1, -1, false> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+//template void igl::pseudonormal_test<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::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, 1, 2, 1, 1, 2>, Eigen::Matrix<float, 1, 2, 1, 1, 2>, float, Eigen::Matrix<float, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> >&);
+template void igl::pseudonormal_test<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::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, float, Eigen::Matrix<float, 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::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&, float&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
+template void igl::pseudonormal_test<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::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 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::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&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+template void igl::pseudonormal_test<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 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, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 template void igl::pseudonormal_test<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::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(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, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, double&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&);
 #endif

+ 174 - 0
include/igl/pso.cpp

@@ -0,0 +1,174 @@
+#include "pso.h"
+#include <cassert>
+#include <Eigen/StdVector>
+#include <vector>
+#include <iostream>
+
+template <
+  typename Scalar, 
+  typename DerivedX,
+  typename DerivedLB, 
+  typename DerivedUB>
+IGL_INLINE Scalar igl::pso(
+  const std::function< Scalar (DerivedX &) > f,
+  const Eigen::MatrixBase<DerivedLB> & LB,
+  const Eigen::MatrixBase<DerivedUB> & UB,
+  const int max_iters,
+  const int population,
+  DerivedX & X)
+{
+  const Eigen::Array<bool,Eigen::Dynamic,1> P =
+    Eigen::Array<bool,Eigen::Dynamic,1>::Zero(LB.size(),1);
+  return igl::pso(f,LB,UB,P,max_iters,population,X);
+}
+
+template <
+  typename Scalar, 
+  typename DerivedX,
+  typename DerivedLB, 
+  typename DerivedUB,
+  typename DerivedP>
+IGL_INLINE Scalar igl::pso(
+  const std::function< Scalar (DerivedX &) > f,
+  const Eigen::MatrixBase<DerivedLB> & LB,
+  const Eigen::MatrixBase<DerivedUB> & UB,
+  const Eigen::DenseBase<DerivedP> & P,
+  const int max_iters,
+  const int population,
+  DerivedX & X)
+{
+  const int dim = LB.size();
+  assert(UB.size() == dim && "UB should match LB size");
+  assert(P.size() == dim && "P should match LB size");
+  typedef std::vector<DerivedX,Eigen::aligned_allocator<DerivedX> > VectorList;
+  VectorList position(population);
+  VectorList best_position(population);
+  VectorList velocity(population);
+  Eigen::Matrix<Scalar,Eigen::Dynamic,1> best_f(population);
+  // https://en.wikipedia.org/wiki/Particle_swarm_optimization#Algorithm
+  //
+  // g → X
+  // p_i → best[i]
+  // v_i → velocity[i]
+  // x_i → position[i]
+  Scalar min_f = std::numeric_limits<Scalar>::max();
+  for(int p=0;p<population;p++)
+  {
+    {
+      const DerivedX R = DerivedX::Random(dim).array()*0.5+0.5;
+      position[p] = LB.array() + R.array()*(UB-LB).array();
+    }
+    best_f[p] = f(position[p]);
+    best_position[p] = position[p];
+    if(best_f[p] < min_f)
+    {
+      min_f = best_f[p];
+      X = best_position[p];
+    }
+    {
+      const DerivedX R = DerivedX::Random(dim);
+      velocity[p] = (UB-LB).array() * R.array();
+    }
+  }
+
+  int iter = 0;
+  Scalar omega = 0.98;
+  Scalar phi_p = 0.01;
+  Scalar phi_g = 0.01;
+  while(true)
+  {
+    //if(iter % 10 == 0)
+    //{
+    //  std::cout<<iter<<":"<<std::endl;
+    //  for(int p=0;p<population;p++)
+    //  {
+    //    std::cout<<"  "<<best_f[p]<<", "<<best_position[p]<<std::endl;
+    //  }
+    //  std::cout<<std::endl;
+    //}
+
+    for(int p=0;p<population;p++)
+    {
+      const DerivedX R_p = DerivedX::Random(dim).array()*0.5+0.5;
+      const DerivedX R_g = DerivedX::Random(dim).array()*0.5+0.5;
+      velocity[p] = 
+        omega * velocity[p].array() +
+        phi_p * R_p.array() *(best_position[p] - position[p]).array() + 
+        phi_g * R_g.array() *(               X - position[p]).array();
+      position[p] += velocity[p];
+      // Clamp to bounds
+      for(int d = 0;d<dim;d++)
+      {
+//#define IGL_PSO_REFLECTION
+#ifdef IGL_PSO_REFLECTION
+        assert(!P(d));
+        // Reflect velocities if exceeding bounds
+        if(position[p](d) < LB(d))
+        {
+          position[p](d) = LB(d);
+          if(velocity[p](d) < 0.0) velocity[p](d) *= -1.0;
+        }
+        if(position[p](d) > UB(d))
+        {
+          position[p](d) = UB(d);
+          if(velocity[p](d) > 0.0) velocity[p](d) *= -1.0;
+        }
+#else
+//#warning "trying no bounds on periodic"
+//        // TODO: I'm not sure this is the right thing to do/enough. The
+//        // velocities could be weird. Suppose the current "best" value is ε and
+//        // the value is -ε and the "periodic bounds" [0,2π]. Moding will send
+//        // the value to 2π-ε but the "velocity" term will now be huge pointing
+//        // all the way from 2π-ε to ε.
+//        //
+//        // Q: Would it be enough to try (all combinations) of ±(UB-LB) before
+//        // computing velocities to "best"s? In the example above, instead of
+//        //
+//        //     v += best - p = ε - (2π-ε) = -2π+2ε
+//        //
+//        // you'd use
+//        //
+//        //     v +=  / argmin  |b - p|            \  - p = (ε+2π)-(2π-ε) = 2ε
+//        //          |                              |
+//        //           \ b∈{best, best+2π, best-2π} /
+//        //
+//        // Though, for multivariate b,p,v this would seem to explode
+//        // combinatorially.
+//        //
+//        // Maybe periodic things just shouldn't be bounded and we hope that the
+//        // forces toward the current minima "regularize" them away from insane
+//        // values.
+//        if(P(d))
+//        {
+//          position[p](d) = std::fmod(position[p](d)-LB(d),UB(d)-LB(d))+LB(d);
+//        }else
+//        {
+//          position[p](d) = std::max(LB(d),std::min(UB(d),position[p](d)));
+//        }
+        position[p](d) = std::max(LB(d),std::min(UB(d),position[p](d)));
+#endif
+      }
+      const Scalar fp = f(position[p]);
+      if(fp<best_f[p])
+      {
+        best_f[p] = fp;
+        best_position[p] = position[p];
+        if(best_f[p] < min_f)
+        {
+          min_f = best_f[p];
+          X = best_position[p];
+        }
+      }
+    }
+    iter++;
+    if(iter>=max_iters)
+    {
+      break;
+    }
+  }
+  return min_f;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+template float igl::pso<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> >(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&, int, int, Eigen::Matrix<float, 1, -1, 1, 1, -1>&);
+#endif

+ 59 - 0
include/igl/pso.h

@@ -0,0 +1,59 @@
+#ifndef IGL_PSO_H
+#define IGL_PSO_H
+#include <igl/igl_inline.h>
+#include <Eigen/Core>
+#include <functional>
+
+namespace igl
+{
+  // Solve the problem:
+  //
+  //   minimize f(x)
+  //   subject to lb ≤ x ≤ ub 
+  // 
+  // by particle swarm optimization (PSO).
+  //
+  // Inputs:
+  //   f  function that evaluates the objective for a given "particle" location
+  //   LB  #X vector of lower bounds 
+  //   UB  #X vector of upper bounds 
+  //   max_iters  maximum number of iterations
+  //   population  number of particles in swarm
+  // Outputs:
+  //   X  best particle seen so far
+  // Returns objective corresponding to best particle seen so far
+  template <
+    typename Scalar, 
+    typename DerivedX,
+    typename DerivedLB, 
+    typename DerivedUB>
+  IGL_INLINE Scalar pso(
+    const std::function< Scalar (DerivedX &) > f,
+    const Eigen::MatrixBase<DerivedLB> & LB,
+    const Eigen::MatrixBase<DerivedUB> & UB,
+    const int max_iters,
+    const int population,
+    DerivedX & X);
+  // Inputs:
+  //   P  whether each DOF is periodic
+  template <
+    typename Scalar, 
+    typename DerivedX,
+    typename DerivedLB, 
+    typename DerivedUB,
+    typename DerivedP>
+  IGL_INLINE Scalar pso(
+    const std::function< Scalar (DerivedX &) > f,
+    const Eigen::MatrixBase<DerivedLB> & LB,
+    const Eigen::MatrixBase<DerivedUB> & UB,
+    const Eigen::DenseBase<DerivedP> & P,
+    const int max_iters,
+    const int population,
+    DerivedX & X);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "pso.cpp"
+#endif
+
+#endif

+ 8 - 0
include/igl/qslim.cpp

@@ -11,6 +11,7 @@
 #include "connect_boundary_to_infinity.h"
 #include "decimate.h"
 #include "edge_flaps.h"
+#include "is_edge_manifold.h"
 #include "max_faces_stopping_condition.h"
 #include "per_vertex_point_to_plane_quadrics.h"
 #include "qslim_optimal_collapse_edge_callbacks.h"
@@ -39,6 +40,13 @@ IGL_INLINE bool igl::qslim(
   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;
+  }
   Eigen::VectorXi EMAP;
   Eigen::MatrixXi E,EF,EI;
   edge_flaps(FO,E,EMAP,EF,EI);

+ 36 - 0
include/igl/random_search.cpp

@@ -0,0 +1,36 @@
+#include "random_search.h"
+#include <iostream>
+#include <cassert>
+
+template <
+  typename Scalar, 
+  typename DerivedX, 
+  typename DerivedLB, 
+  typename DerivedUB>
+IGL_INLINE Scalar igl::random_search(
+  const std::function< Scalar (DerivedX &) > f,
+  const Eigen::MatrixBase<DerivedLB> & LB,
+  const Eigen::MatrixBase<DerivedUB> & UB,
+  const int iters,
+  DerivedX & X)
+{
+  Scalar min_f = std::numeric_limits<Scalar>::max();
+  const int dim = LB.size();
+  assert(UB.size() == dim && "UB should match LB size");
+  for(int iter = 0;iter<iters;iter++)
+  {
+    const DerivedX R = DerivedX::Random(dim).array()*0.5+0.5;
+    DerivedX Xr = LB.array() + R.array()*(UB-LB).array();
+    const Scalar fr = f(Xr);
+    if(fr<min_f)
+    {
+      min_f = fr;
+      X = Xr;
+    }
+  }
+  return min_f;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+template float igl::random_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> >(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&, int, Eigen::Matrix<float, 1, -1, 1, 1, -1>&);
+#endif

+ 42 - 0
include/igl/random_search.h

@@ -0,0 +1,42 @@
+#ifndef IGL_RANDOM_SEARCH_H
+#define IGL_RANDOM_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 uniform random search.
+  //
+  // Inputs:
+  //   f  function to minimize
+  //   LB  #X vector of finite lower bounds
+  //   UB  #X vector of finite upper bounds
+  //   iters  number of iterations
+  // Outputs:
+  //   X  #X optimal parameter vector
+  // Returns f(X)
+  //
+  template <
+    typename Scalar, 
+    typename DerivedX, 
+    typename DerivedLB, 
+    typename DerivedUB>
+  IGL_INLINE Scalar random_search(
+    const std::function< Scalar (DerivedX &) > f,
+    const Eigen::MatrixBase<DerivedLB> & LB,
+    const Eigen::MatrixBase<DerivedUB> & UB,
+    const int iters,
+    DerivedX & X);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "random_search.cpp"
+#endif
+
+#endif
+

+ 2 - 0
include/igl/readMESH.cpp

@@ -489,6 +489,8 @@ IGL_INLINE bool igl::readMESH(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::readMESH<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(FILE*, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
 template bool igl::readMESH<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(FILE*, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
 // generated by autoexplicit.sh
 template bool igl::readMESH<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -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> >&);

+ 8 - 10
include/igl/readOBJ.cpp

@@ -14,6 +14,8 @@
 #include <iostream>
 #include <cstdio>
 #include <fstream>
+#include <sstream>
+#include <iterator>
 
 template <typename Scalar, typename Index>
 IGL_INLINE bool igl::readOBJ(
@@ -77,22 +79,18 @@ IGL_INLINE bool igl::readOBJ(
       char * l = &line[strlen(type)];
       if(type == v)
       {
-        double x[4];
-        int count =
-        sscanf(l,"%lf %lf %lf %lf\n",&x[0],&x[1],&x[2],&x[3]);
-        if(count != 3 && count != 4)
+        std::istringstream ls(&line[1]);
+        std::vector<Scalar > vertex{ std::istream_iterator<Scalar >(ls), std::istream_iterator<Scalar >() };
+
+        if (vertex.size() < 3)
         {
           fprintf(stderr,
-                  "Error: readOBJ() vertex on line %d should have 3 or 4 coordinates",
+                  "Error: readOBJ() vertex on line %d should have at least 3 coordinates",
                   line_no);
           fclose(obj_file);
           return false;
         }
-        std::vector<Scalar > vertex(count);
-        for(int i = 0;i<count;i++)
-        {
-          vertex[i] = x[i];
-        }
+      
         V.push_back(vertex);
       }else if(type == vn)
       {

+ 2 - 0
include/igl/read_triangle_mesh.cpp

@@ -168,6 +168,8 @@ IGL_INLINE bool igl::read_triangle_mesh(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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 bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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 bool igl::read_triangle_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 4 - 1
include/igl/remove_duplicate_vertices.cpp

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "remove_duplicate_vertices.h"
 #include "round.h"
-#include "unique.h"
+#include "unique_rows.h"
 #include "colon.h"
 #include "slice.h"
 #include <functional>
@@ -68,6 +68,9 @@ IGL_INLINE void igl::remove_duplicate_vertices(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::remove_duplicate_vertices<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::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<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, double, Eigen::PlainObjectBase<Eigen::Matrix<float, -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> >&);
+// generated by autoexplicit.sh
+template void igl::remove_duplicate_vertices<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<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<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, double, Eigen::PlainObjectBase<Eigen::Matrix<float, -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::remove_duplicate_vertices<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -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<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -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::remove_duplicate_vertices<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double, 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> >&);
 template void igl::remove_duplicate_vertices<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, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, 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&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -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, 3, 0, -1, 3> >&);

+ 3 - 0
include/igl/remove_unreferenced.cpp

@@ -100,6 +100,9 @@ IGL_INLINE void igl::remove_unreferenced(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::remove_unreferenced<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, 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<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > 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
+// generated by autoexplicit.sh
 // generated by autoexplicit.sh
 template void igl::remove_unreferenced<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -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<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, 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

+ 3 - 0
include/igl/resolve_duplicated_faces.cpp

@@ -84,6 +84,9 @@ IGL_INLINE void igl::resolve_duplicated_faces(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::resolve_duplicated_faces<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, 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, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::resolve_duplicated_faces<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<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::resolve_duplicated_faces<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template void igl::resolve_duplicated_faces<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<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> >&);

+ 4 - 0
include/igl/round.cpp

@@ -36,6 +36,10 @@ IGL_INLINE void igl::round(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::round<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::round<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
+// generated by autoexplicit.sh
 template void igl::round<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);
 template void igl::round<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<double, -1, -1, 0, -1, -1> >&);
 template void igl::round<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);

+ 68 - 0
include/igl/signed_angle.cpp

@@ -0,0 +1,68 @@
+#include "signed_angle.h"
+#include "PI.h"
+#include <cmath>
+
+template <
+  typename DerivedA,
+  typename DerivedB,
+  typename DerivedP>
+IGL_INLINE typename DerivedA::Scalar igl::signed_angle(
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedP> & P)
+{
+  typedef typename DerivedA::Scalar SType;
+  // Gather vectors to source and destination
+  SType o2A[2];
+  SType o2B[2];
+  // and lengths
+  SType o2Al = 0;
+  SType o2Bl = 0;
+  for(int i = 0;i<2;i++)
+  {
+    o2A[i] = P(i) - A(i);
+    o2B[i] = P(i) - B(i);
+    o2Al += o2A[i]*o2A[i];
+    o2Bl += o2B[i]*o2B[i];
+  }
+  o2Al = sqrt(o2Al);
+  o2Bl = sqrt(o2Bl);
+  // Normalize
+  for(int i = 0;i<2;i++)
+  {
+    // Matlab crashes on NaN
+    if(o2Al!=0)
+    {
+      o2A[i] /= o2Al;
+    }
+    if(o2Bl!=0)
+    {
+      o2B[i] /= o2Bl;
+    }
+  }
+  return
+    -atan2(o2B[0]*o2A[1]-o2B[1]*o2A[0],o2B[0]*o2A[0]+o2B[1]*o2A[1])/
+    (2.*igl::PI);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::signed_angle<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>::Scalar igl::signed_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>::Scalar igl::signed_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::signed_angle<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::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&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::signed_angle<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, 3, 1, 0, 3, 1> >(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::Matrix<double, 3, 1, 0, 3, 1> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::signed_angle<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::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::Matrix<double, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::signed_angle<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, 2, 1, 1, 2> >(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::Matrix<double, 1, 2, 1, 1, 2> > const&);
+#ifdef WIN32
+template float igl::signed_angle<class Eigen::Block<class Eigen::Matrix<float,-1,3,1,-1,3> const ,1,3,1>,class Eigen::Block<class Eigen::Matrix<float,-1,3,1,-1,3> const ,1,3,1>,class Eigen::Matrix<float,1,2,1,1,2> >(class Eigen::MatrixBase<class Eigen::Block<class Eigen::Matrix<float,-1,3,1,-1,3> const ,1,3,1> > const &,class Eigen::MatrixBase<class Eigen::Block<class Eigen::Matrix<float,-1,3,1,-1,3> const ,1,3,1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<float,1,2,1,1,2> > const &);
+template float igl::signed_angle<class Eigen::Block<class Eigen::Matrix<float,-1,3,0,-1,3> const ,1,3,0>,class Eigen::Block<class Eigen::Matrix<float,-1,3,0,-1,3> const ,1,3,0>,class Eigen::Matrix<float,1,2,1,1,2> >(class Eigen::MatrixBase<class Eigen::Block<class Eigen::Matrix<float,-1,3,0,-1,3> const ,1,3,0> > const &,class Eigen::MatrixBase<class Eigen::Block<class Eigen::Matrix<float,-1,3,0,-1,3> const ,1,3,0> > const &,class Eigen::MatrixBase<class Eigen::Matrix<float,1,2,1,1,2> > const &);
+#endif
+#endif

+ 27 - 0
include/igl/signed_angle.h

@@ -0,0 +1,27 @@
+#ifndef IGL_SIGNED_ANGLE_H
+#define IGL_SIGNED_ANGLE_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Compute the signed angle subtended by the oriented 3d triangle (A,B,C) at some point P
+  // 
+  // Inputs:
+  //   A  2D position of corner 
+  //   B  2D position of corner 
+  //   P  2D position of query point
+  //   returns signed angle
+  template <
+    typename DerivedA,
+    typename DerivedB,
+    typename DerivedP>
+  IGL_INLINE typename DerivedA::Scalar signed_angle(
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedP> & P);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "signed_angle.cpp"
+#endif
+#endif
+

+ 109 - 44
include/igl/signed_distance.cpp

@@ -8,6 +8,7 @@
 #include "signed_distance.h"
 #include "get_seconds.h"
 #include "per_edge_normals.h"
+#include "parallel_for.h"
 #include "per_face_normals.h"
 #include "per_vertex_normals.h"
 #include "point_mesh_squared_distance.h"
@@ -27,6 +28,8 @@ IGL_INLINE void igl::signed_distance(
   const Eigen::MatrixBase<DerivedV> & V,
   const Eigen::MatrixBase<DerivedF> & F,
   const SignedDistanceType sign_type,
+  const typename DerivedV::Scalar lower_bound,
+  const typename DerivedV::Scalar upper_bound,
   Eigen::PlainObjectBase<DerivedS> & S,
   Eigen::PlainObjectBase<DerivedI> & I,
   Eigen::PlainObjectBase<DerivedC> & C,
@@ -62,7 +65,7 @@ IGL_INLINE void igl::signed_distance(
   Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> FN,VN,EN;
   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> E;
   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> EMAP;
-  WindingNumberAABB<RowVector3S > hier3;
+  WindingNumberAABB<RowVector3S,DerivedV,DerivedF> hier3;
   switch(sign_type)
   {
     default:
@@ -98,7 +101,7 @@ IGL_INLINE void igl::signed_distance(
           break;
         case 2:
           FN.resize(F.rows(),2);
-          VN = MatrixXd::Zero(V.rows(),2);
+          VN = DerivedV::Zero(V.rows(),2);
           for(int e = 0;e<F.rows();e++)
           {
             // rotate edge vector
@@ -116,11 +119,20 @@ IGL_INLINE void igl::signed_distance(
       N.resize(P.rows(),dim);
       break;
   }
+  //
+  // convert to bounds on (unsiged) squared distances
+  typedef typename DerivedV::Scalar Scalar; 
+  const Scalar max_abs = std::max(std::abs(lower_bound),std::abs(upper_bound));
+  const Scalar up_sqr_d = std::pow(max_abs,2.0);
+  const Scalar low_sqr_d = 
+    std::pow(std::max(max_abs-(upper_bound-lower_bound),(Scalar)0.0),2.0);
 
   S.resize(P.rows(),1);
   I.resize(P.rows(),1);
   C.resize(P.rows(),dim);
-  for(int p = 0;p<P.rows();p++)
+
+  parallel_for(P.rows(),[&](const int p)
+  //for(int p = 0;p<P.rows();p++)
   {
     RowVector3S q3;
     Eigen::Matrix<typename DerivedV::Scalar,1,2>  q2;
@@ -128,50 +140,95 @@ IGL_INLINE void igl::signed_distance(
     {
       default:
       case 3:
-        q3 = P.row(p);
+        q3.head(P.row(p).size()) = P.row(p);
         break;
       case 2:
-        q2 = P.row(p);
+        q2 = P.row(p).head(2);
         break;
     }
-    double s,sqrd;
+    typename DerivedV::Scalar s=1,sqrd=0;
     Eigen::Matrix<typename DerivedV::Scalar,1,Eigen::Dynamic>  c;
     RowVector3S c3;
     Eigen::Matrix<typename DerivedV::Scalar,1,2>  c2;
     int i=-1;
-    switch(sign_type)
+    // in all cases compute squared unsiged distances
+    sqrd = dim==3?
+      tree3.squared_distance(V,F,q3,low_sqr_d,up_sqr_d,i,c3):
+      tree2.squared_distance(V,F,q2,low_sqr_d,up_sqr_d,i,c2);
+    if(sqrd >= up_sqr_d || sqrd <= low_sqr_d)
     {
-      default:
-        assert(false && "Unknown SignedDistanceType");
-      case SIGNED_DISTANCE_TYPE_UNSIGNED:
-        s = 1.;
-        sqrd = dim==3?
-          tree3.squared_distance(V,F,q3,i,c3):
-          tree2.squared_distance(V,F,q2,i,c2);
-        break;
-      case SIGNED_DISTANCE_TYPE_DEFAULT:
-      case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
-        dim==3 ? 
-          signed_distance_winding_number(tree3,V,F,hier3,q3,s,sqrd,i,c3):
-          signed_distance_winding_number(tree2,V,F,q2,s,sqrd,i,c2);
-        break;
-      case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
+      // Out of bounds gets a nan (nans on grids can be flood filled later using
+      // igl::flood_fill)
+      S(p) = std::numeric_limits<double>::quiet_NaN();
+      I(p) = F.rows()+1;
+      C.row(p).setConstant(0);
+    }else
+    {
+      // Determine sign
+      switch(sign_type)
       {
-        RowVector3S n3;
-        Eigen::Matrix<typename DerivedV::Scalar,1,2>  n2;
-        dim==3 ?
-          signed_distance_pseudonormal(tree3,V,F,FN,VN,EN,EMAP,q3,s,sqrd,i,c3,n3):
-          signed_distance_pseudonormal(tree2,V,F,FN,VN,q2,s,sqrd,i,c2,n2);
-        Eigen::Matrix<typename DerivedV::Scalar,1,Eigen::Dynamic>  n;
-        (dim==3 ? n = n3 : n = n2);
-        N.row(p) = n;
-        break;
+        default:
+          assert(false && "Unknown SignedDistanceType");
+        case SIGNED_DISTANCE_TYPE_UNSIGNED:
+          break;
+        case SIGNED_DISTANCE_TYPE_DEFAULT:
+        case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
+        {
+          Scalar w = 0;
+          if(dim == 3)
+          {
+            s = 1.-2.*hier3.winding_number(q3.transpose());
+          }else
+          {
+            assert(!V.derived().IsRowMajor);
+            assert(!F.derived().IsRowMajor);
+            s = 1.-2.*winding_number(V,F,q2);
+          }
+          break;
+        }
+        case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
+        {
+          RowVector3S n3;
+          Eigen::Matrix<typename DerivedV::Scalar,1,2>  n2;
+          dim==3 ?
+            pseudonormal_test(V,F,FN,VN,EN,EMAP,q3,i,c3,s,n3):
+            pseudonormal_test(V,E,EN,VN,q2,i,c2,s,n2);
+          Eigen::Matrix<typename DerivedV::Scalar,1,Eigen::Dynamic>  n;
+          (dim==3 ? n = n3 : n = n2);
+          N.row(p) = n;
+          break;
+        }
       }
+      I(p) = i;
+      S(p) = s*sqrt(sqrd);
+      C.row(p) = (dim==3 ? c=c3 : c=c2);
     }
-    I(p) = i;
-    S(p) = s*sqrt(sqrd);
-    C.row(p) = (dim==3 ? c=c3 : c=c2);
   }
+  ,10000);
+}
+
+template <
+  typename DerivedP,
+  typename DerivedV,
+  typename DerivedF,
+  typename DerivedS,
+  typename DerivedI,
+  typename DerivedC,
+  typename DerivedN>
+IGL_INLINE void igl::signed_distance(
+  const Eigen::MatrixBase<DerivedP> & P,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedF> & F,
+  const SignedDistanceType sign_type,
+  Eigen::PlainObjectBase<DerivedS> & S,
+  Eigen::PlainObjectBase<DerivedI> & I,
+  Eigen::PlainObjectBase<DerivedC> & C,
+  Eigen::PlainObjectBase<DerivedN> & N)
+{
+  typedef typename DerivedV::Scalar Scalar;
+  Scalar lower = std::numeric_limits<Scalar>::min();
+  Scalar upper = std::numeric_limits<Scalar>::max();
+  return signed_distance(P,V,F,sign_type,lower,upper,S,I,C,N);
 }
 
 
@@ -232,7 +289,7 @@ IGL_INLINE void igl::signed_distance_pseudonormal(
   I.resize(np,1);
   N.resize(np,3);
   C.resize(np,3);
-  typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
+  typedef typename AABB<DerivedV,3>::RowVectorDIMS RowVector3S;
 # pragma omp parallel for if(np>1000)
   for(size_t p = 0;p<np;p++)
   {
@@ -276,8 +333,12 @@ IGL_INLINE void igl::signed_distance_pseudonormal(
 {
   using namespace Eigen;
   using namespace std;
-  typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
-  sqrd = tree.squared_distance(V,F,RowVector3S(q),i,(RowVector3S&)c);
+  //typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
+  // Alec: Why was this constructor around q necessary?
+  //sqrd = tree.squared_distance(V,F,RowVector3S(q),i,(RowVector3S&)c);
+  // Alec: Why was this constructor around c necessary?
+  //sqrd = tree.squared_distance(V,F,q,i,(RowVector3S&)c);
+  sqrd = tree.squared_distance(V,F,q,i,c);
   pseudonormal_test(V,F,FN,VN,EN,EMAP,q,i,c,s,n);
 }
 
@@ -318,7 +379,7 @@ IGL_INLINE typename DerivedV::Scalar igl::signed_distance_winding_number(
   const AABB<DerivedV,3> & tree,
   const Eigen::MatrixBase<DerivedV> & V,
   const Eigen::MatrixBase<DerivedF> & F,
-  const igl::WindingNumberAABB<Derivedq> & hier,
+  const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
   const Eigen::MatrixBase<Derivedq> & q)
 {
   typedef typename DerivedV::Scalar Scalar;
@@ -340,7 +401,7 @@ IGL_INLINE void igl::signed_distance_winding_number(
   const AABB<DerivedV,3> & tree,
   const Eigen::MatrixBase<DerivedV> & V,
   const Eigen::MatrixBase<DerivedF> & F,
-  const igl::WindingNumberAABB<Derivedq> & hier,
+  const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
   const Eigen::MatrixBase<Derivedq> & q,
   Scalar & s,
   Scalar & sqrd,
@@ -362,7 +423,7 @@ template <
   typename Scalar,
   typename Derivedc>
 IGL_INLINE void igl::signed_distance_winding_number(
-  const AABB<Eigen::MatrixXd,2> & tree,
+  const AABB<DerivedV,2> & tree,
   const Eigen::MatrixBase<DerivedV> & V,
   const Eigen::MatrixBase<DerivedF> & F,
   const Eigen::MatrixBase<Derivedq> & q,
@@ -380,17 +441,21 @@ IGL_INLINE void igl::signed_distance_winding_number(
   // colmajor order
   assert(!V.derived().IsRowMajor);
   assert(!F.derived().IsRowMajor);
-  winding_number_2(V.derived().data(), V.rows(), F.derived().data(), F.rows(), q.derived().data(), 1, &w);
-  s = 1.-2.*w;
+  s = 1.-2.*winding_number(V,F,q);
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::signed_distance<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::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -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<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::SignedDistanceType, Eigen::Matrix<float, -1, 3, 0, -1, 3>::Scalar, Eigen::Matrix<float, -1, 3, 0, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::signed_distance<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::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -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<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::SignedDistanceType, Eigen::Matrix<float, -1, 3, 1, -1, 3>::Scalar, Eigen::Matrix<float, -1, 3, 1, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+template void igl::signed_distance<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::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::SignedDistanceType, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
 template void igl::signed_distance_pseudonormal<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::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, 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<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
-template void igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 template void igl::signed_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::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(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&, igl::SignedDistanceType, 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, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_pseudonormal<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::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, 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<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&);
-template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
 template void igl::signed_distance_pseudonormal<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<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::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<int, -1, -1, 0, -1, -1> > const&, igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> 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<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::signed_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::Matrix<int, -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<int, -1, -1, 0, -1, -1> > const&, igl::SignedDistanceType, 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<double, -1, -1, 0, -1, -1> >&);
+template void igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
+template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
 #endif

+ 25 - 3
include/igl/signed_distance.h

@@ -32,6 +32,8 @@ namespace igl
   //   F  #F by ss list of triangle indices, ss should be 3 unless sign_type ==
   //     SIGNED_DISTANCE_TYPE_UNSIGNED
   //   sign_type  method for computing distance _sign_ S
+  //   lower_bound  lower bound of distances needed {std::numeric_limits::min}
+  //   upper_bound  lower bound of distances needed {std::numeric_limits::max}
   // Outputs:
   //   S  #P list of smallest signed distances
   //   I  #P list of facet indices corresponding to smallest distances
@@ -41,6 +43,26 @@ namespace igl
   //
   // Known bugs: This only computes distances to triangles. So unreferenced
   // vertices and degenerate triangles are ignored.
+  template <
+    typename DerivedP,
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedS,
+    typename DerivedI,
+    typename DerivedC,
+    typename DerivedN>
+  IGL_INLINE void signed_distance(
+    const Eigen::MatrixBase<DerivedP> & P,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const SignedDistanceType sign_type,
+    const typename DerivedV::Scalar lower_bound,
+    const typename DerivedV::Scalar upper_bound,
+    Eigen::PlainObjectBase<DerivedS> & S,
+    Eigen::PlainObjectBase<DerivedI> & I,
+    Eigen::PlainObjectBase<DerivedC> & C,
+    Eigen::PlainObjectBase<DerivedN> & N);
+  // Default bounds
   template <
     typename DerivedP,
     typename DerivedV,
@@ -177,7 +199,7 @@ namespace igl
     const AABB<DerivedV,3> & tree,
     const Eigen::MatrixBase<DerivedV> & V,
     const Eigen::MatrixBase<DerivedF> & F,
-    const igl::WindingNumberAABB<Derivedq> & hier,
+    const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
     const Eigen::MatrixBase<Derivedq> & q);
   // Outputs:
   //   s  sign
@@ -193,7 +215,7 @@ namespace igl
     const AABB<DerivedV,3> & tree,
     const Eigen::MatrixBase<DerivedV> & V,
     const Eigen::MatrixBase<DerivedF> & F,
-    const igl::WindingNumberAABB<Derivedq> & hier,
+    const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
     const Eigen::MatrixBase<Derivedq> & q,
     Scalar & s,
     Scalar & sqrd,
@@ -206,7 +228,7 @@ namespace igl
     typename Scalar,
     typename Derivedc>
   IGL_INLINE void signed_distance_winding_number(
-    const AABB<Eigen::MatrixXd,2> & tree,
+    const AABB<DerivedV,2> & tree,
     const Eigen::MatrixBase<DerivedV> & V,
     const Eigen::MatrixBase<DerivedF> & F,
     const Eigen::MatrixBase<Derivedq> & q,

+ 6 - 0
include/igl/slice.cpp

@@ -248,6 +248,12 @@ IGL_INLINE DerivedX igl::slice(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::slice<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::DenseBase<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::slice<Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::slice<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::slice<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, int);
 // generated by autoexplicit.sh
 template void igl::slice<Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);

+ 77 - 0
include/igl/solid_angle.cpp

@@ -0,0 +1,77 @@
+#include "solid_angle.h"
+#include "PI.h"
+#include <cmath>
+
+template <
+  typename DerivedA,
+  typename DerivedB,
+  typename DerivedC,
+  typename DerivedP>
+IGL_INLINE typename DerivedA::Scalar igl::solid_angle(
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedC> & C,
+  const Eigen::MatrixBase<DerivedP> & P)
+{
+  typedef typename DerivedA::Scalar SType;
+  // Gather vectors to corners
+  Eigen::Matrix<SType,3,3> v;
+  // Don't use this since it will freak out for templates with != 3 size
+  //v<< (A-P),(B-P),(C-P);
+  for(int d = 0;d<3;d++)
+  {
+    v(0,d) = A(d)-P(d);
+    v(1,d) = B(d)-P(d);
+    v(2,d) = C(d)-P(d);
+  }
+  Eigen::Matrix<SType,1,3> vl = v.rowwise().norm();
+  //printf("\n");
+  // Compute determinant
+  SType detf = 
+    v(0,0)*v(1,1)*v(2,2)+
+    v(1,0)*v(2,1)*v(0,2)+
+    v(2,0)*v(0,1)*v(1,2)-
+    v(2,0)*v(1,1)*v(0,2)-
+    v(1,0)*v(0,1)*v(2,2)-
+    v(0,0)*v(2,1)*v(1,2);
+  // Compute pairwise dotproducts
+  Eigen::Matrix<SType,1,3> dp;
+  dp(0) = v(1,0)*v(2,0);
+  dp(0) += v(1,1)*v(2,1);
+  dp(0) += v(1,2)*v(2,2);
+  dp(1) = v(2,0)*v(0,0);
+  dp(1) += v(2,1)*v(0,1);
+  dp(1) += v(2,2)*v(0,2);
+  dp(2) = v(0,0)*v(1,0);
+  dp(2) += v(0,1)*v(1,1);
+  dp(2) += v(0,2)*v(1,2);
+  // Compute winding number
+  // Only divide by TWO_PI instead of 4*pi because there was a 2 out front
+  return atan2(detf,
+    vl(0)*vl(1)*vl(2) + 
+    dp(0)*vl(0) +
+    dp(1)*vl(1) +
+    dp(2)*vl(2)) / (2.*igl::PI);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::solid_angle<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>::Scalar igl::solid_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>::Scalar igl::solid_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true>, Eigen::Matrix<float, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 1, -1, 3> const, 1, 3, true> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>::Scalar igl::solid_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>::Scalar igl::solid_angle<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false>, Eigen::Matrix<float, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, 3, 0, -1, 3> const, 1, 3, false> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 2, 1, 1, 2> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::solid_angle<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::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> >(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::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::solid_angle<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, 3, 1, 0, 3, 1> >(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::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::solid_angle<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::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::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&);
+// generated by autoexplicit.sh
+template Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false>::Scalar igl::solid_angle<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, 2, 1, 1, 2> >(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::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&);
+#endif

+ 29 - 0
include/igl/solid_angle.h

@@ -0,0 +1,29 @@
+#ifndef IGL_SOLID_ANGLE_H
+#define IGL_SOLID_ANGLE_H
+#include "igl_inline.h"
+#include <Eigen/Dense>
+namespace igl
+{
+  // Compute the signed solid angle subtended by the oriented 3d triangle (A,B,C) at some point P
+  // 
+  // Inputs:
+  //   A  3D position of corner 
+  //   B  3D position of corner 
+  //   C  3D position of corner 
+  //   P  3D position of query point
+  // Returns signed solid angle
+  template <
+    typename DerivedA,
+    typename DerivedB,
+    typename DerivedC,
+    typename DerivedP>
+  IGL_INLINE typename DerivedA::Scalar solid_angle(
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedC> & C,
+    const Eigen::MatrixBase<DerivedP> & P);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "solid_angle.cpp"
+#endif
+#endif

+ 2 - 0
include/igl/sort.cpp

@@ -316,6 +316,8 @@ if(!ascending)
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::sort<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::DenseBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, int, bool, 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::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 // generated by autoexplicit.sh
 template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 4 - 0
include/igl/sortrows.cpp

@@ -108,6 +108,10 @@ IGL_INLINE void igl::sortrows(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::sortrows<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::sortrows<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::sortrows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::sortrows<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 5 - 0
include/igl/squared_edge_lengths.cpp

@@ -73,6 +73,10 @@ IGL_INLINE void igl::squared_edge_lengths(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::squared_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::squared_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::squared_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::squared_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> >&);
@@ -98,4 +102,5 @@ template void igl::squared_edge_lengths<Eigen::Matrix<float, -1, 3, 1, -1, 3>, E
 template void igl::squared_edge_lengths<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -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<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
 template void igl::squared_edge_lengths<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(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, 3, 0, -1, 3> >&);
 template void igl::squared_edge_lengths<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::squared_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> >&);
 #endif

+ 2 - 2
include/igl/triangle/triangulate.cpp

@@ -109,8 +109,8 @@ IGL_INLINE void igl::triangle::triangulate(
   }
 
   in.numberofpointattributes = 0;
-  in.pointmarkerlist = (int*)calloc(VM.size(),sizeof(int));
-  for(unsigned i=0;i<VM.rows();++i) in.pointmarkerlist[i] = VM.size()?VM(i):1;
+  in.pointmarkerlist = (int*)calloc(V.size(),sizeof(int)) ;
+  for(unsigned i=0;i<V.rows();++i) in.pointmarkerlist[i] = VM.size()?VM(i):1;
 
   in.trianglelist = NULL;
   in.numberoftriangles = 0;

+ 1 - 0
include/igl/triangle_triangle_adjacency.cpp

@@ -218,4 +218,5 @@ template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 2, 0, -1,
 template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, int, int>(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&, bool, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
 template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&);
+template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
 #endif

+ 7 - 10
include/igl/triangle_triangle_adjacency.h

@@ -16,19 +16,16 @@ namespace igl
   // Constructs the triangle-triangle adjacency matrix for a given
   // mesh (V,F).
   //
-  // Templates:
-  //   Scalar derived type of eigen matrix for V (e.g. derived from
-  //     MatrixXd)
-  //   Index  derived type of eigen matrix for F (e.g. derived from
-  //     MatrixXi)
   // Inputs:
   //   F  #F by simplex_size list of mesh faces (must be triangles)
   // Outputs:
-  //   TT   #F by #3 adjacent matrix, the element i,j is the id of the triangle adjacent to the j edge of triangle i
-  //   TTi  #F by #3 adjacent matrix, the element i,j is the id of edge of the triangle TT(i,j) that is adjacent with triangle i
-  // NOTE: the first edge of a triangle is [0,1] the second [1,2] and the third [2,3].
-  //       this convention is DIFFERENT from cotmatrix_entries.h
-  // Known bug: this should not need to take V as input.
+  //   TT   #F by #3 adjacent matrix, the element i,j is the id of the triangle
+  //        adjacent to the j edge of triangle i
+  //   TTi  #F by #3 adjacent matrix, the element i,j is the id of edge of the
+  //        triangle TT(i,j) that is adjacent with triangle i
+  //
+  // NOTE: the first edge of a triangle is [0,1] the second [1,2] and the third
+  //       [2,3].  this convention is DIFFERENT from cotmatrix_entries.h
   template <typename DerivedF, typename DerivedTT, typename DerivedTTi>
   IGL_INLINE void triangle_triangle_adjacency(
     const Eigen::PlainObjectBase<DerivedF>& F,

+ 10 - 89
include/igl/unique.cpp

@@ -198,101 +198,22 @@ IGL_INLINE void igl::unique(
 //   }
 // }
 
-template <typename DerivedA, typename DerivedIA, typename DerivedIC>
-IGL_INLINE void igl::unique_rows(
-  const Eigen::DenseBase<DerivedA>& A,
-  Eigen::PlainObjectBase<DerivedA>& C,
-  Eigen::PlainObjectBase<DerivedIA>& IA,
-  Eigen::PlainObjectBase<DerivedIC>& IC)
-{
-  using namespace std;
-  using namespace Eigen;
-  VectorXi IM;
-  DerivedA sortA;
-  sortrows(A,true,sortA,IM);
-
-
-  const int num_rows = sortA.rows();
-  const int num_cols = sortA.cols();
-  vector<int> vIA(num_rows);
-  for(int i=0;i<num_rows;i++)
-  {
-    vIA[i] = i;
-  }
-
-  auto index_equal = [&sortA, &num_cols](const size_t i, const size_t j) {
-    for (size_t c=0; c<num_cols; c++) {
-      if (sortA(i,c) != sortA(j,c))
-        return false;
-    }
-    return true;
-  };
-  vIA.erase(
-    std::unique(
-    vIA.begin(),
-    vIA.end(),
-    index_equal
-    ),vIA.end());
-
-  IC.resize(A.rows(),1);
-  {
-    int j = 0;
-    for(int i = 0;i<num_rows;i++)
-    {
-      if(sortA.row(vIA[j]) != sortA.row(i))
-      {
-        j++;
-      }
-      IC(IM(i,0),0) = j;
-    }
-  }
-  const int unique_rows = vIA.size();
-  C.resize(unique_rows,A.cols());
-  IA.resize(unique_rows,1);
-  // Reindex IA according to IM
-  for(int i = 0;i<unique_rows;i++)
-  {
-    IA(i,0) = IM(vIA[i],0);
-    C.row(i) = A.row(IA(i,0));
-  }
-}
-
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-// generated by autoexplicit.sh
-template void igl::unique<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::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, 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::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
-template void igl::unique_rows<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<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::DenseBase<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<int, -1, -1, 0, -1, -1> >&);
-template void igl::unique_rows<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<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::DenseBase<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<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<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::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, 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> >&);
-template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
-template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&);
-template void igl::unique<long>(std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
-template void igl::unique_rows<Eigen::Matrix<double, -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<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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 void igl::unique_rows<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::unique<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::unique<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<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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<int, -1, -1, 0, -1, -1> >&);
-template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::unique<double>(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> >&);
 template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::unique_rows<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique<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::DenseBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
-
-#ifdef WIN32
-template void __cdecl igl::unique_rows<class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> >(class Eigen::DenseBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &);
-#endif
-
-template void igl::unique_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<Eigen::Matrix<double, -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<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<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<long, -1, 1, 0, -1, 1> >&);
-template void igl::unique_rows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+template void igl::unique<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::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, 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::unique<double>(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> >&);
+template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&);
+template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
+template void igl::unique<long>(std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
 #endif

+ 0 - 18
include/igl/unique.h

@@ -49,24 +49,6 @@ namespace igl
   IGL_INLINE void unique(
       const Eigen::DenseBase<DerivedA> & A,
       Eigen::PlainObjectBase<DerivedC> & C);
-  // Act like matlab's [C,IA,IC] = unique(X,'rows')
-  //
-  // Templates:
-  //   DerivedA derived scalar type, e.g. MatrixXi or MatrixXd
-  //   DerivedIA derived integer type, e.g. MatrixXi
-  //   DerivedIC derived integer type, e.g. MatrixXi
-  // Inputs:
-  //   A  m by n matrix whose entries are to unique'd according to rows
-  // Outputs:
-  //   C  #C vector of unique rows in A
-  //   IA  #C index vector so that C = A(IA,:);
-  //   IC  #A index vector so that A = C(IC,:);
-  template <typename DerivedA, typename DerivedIA, typename DerivedIC>
-  IGL_INLINE void unique_rows(
-    const Eigen::DenseBase<DerivedA>& A,
-    Eigen::PlainObjectBase<DerivedA>& C,
-    Eigen::PlainObjectBase<DerivedIA>& IA,
-    Eigen::PlainObjectBase<DerivedIC>& IC);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 2 - 0
include/igl/unique_edge_map.cpp

@@ -46,6 +46,8 @@ IGL_INLINE void igl::unique_edge_map(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::unique_edge_map<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::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, 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> >&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > >&);
+// generated by autoexplicit.sh
 template void igl::unique_edge_map<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>, int>(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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
 // generated by autoexplicit.sh
 template void igl::unique_edge_map<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::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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > >&);

+ 1 - 1
include/igl/unique_edge_map.h

@@ -12,7 +12,7 @@
 #include <vector>
 namespace igl
 {
-  // Constuct relationships between facet "half"-(or rather "viewed")-edges E
+  // Construct relationships between facet "half"-(or rather "viewed")-edges E
   // to unique edges of the mesh seen as a graph.
   //
   // Inputs:

+ 98 - 0
include/igl/unique_rows.cpp

@@ -0,0 +1,98 @@
+// 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 "sortrows.h"
+
+#include <algorithm>
+#include <iostream>
+#include <map>
+
+
+template <typename DerivedA, typename DerivedC, typename DerivedIA, typename DerivedIC>
+IGL_INLINE void igl::unique_rows(
+  const Eigen::DenseBase<DerivedA>& A,
+  Eigen::PlainObjectBase<DerivedC>& C,
+  Eigen::PlainObjectBase<DerivedIA>& IA,
+  Eigen::PlainObjectBase<DerivedIC>& IC)
+{
+  using namespace std;
+  using namespace Eigen;
+  VectorXi IM;
+  DerivedA sortA;
+  sortrows(A,true,sortA,IM);
+
+
+  const int num_rows = sortA.rows();
+  const int num_cols = sortA.cols();
+  vector<int> vIA(num_rows);
+  for(int i=0;i<num_rows;i++)
+  {
+    vIA[i] = i;
+  }
+
+  auto index_equal = [&sortA, &num_cols](const size_t i, const size_t j) {
+    for (size_t c=0; c<num_cols; c++) {
+      if (sortA(i,c) != sortA(j,c))
+        return false;
+    }
+    return true;
+  };
+  vIA.erase(
+    std::unique(
+    vIA.begin(),
+    vIA.end(),
+    index_equal
+    ),vIA.end());
+
+  IC.resize(A.rows(),1);
+  {
+    int j = 0;
+    for(int i = 0;i<num_rows;i++)
+    {
+      if(sortA.row(vIA[j]) != sortA.row(i))
+      {
+        j++;
+      }
+      IC(IM(i,0),0) = j;
+    }
+  }
+  const int unique_rows = vIA.size();
+  C.resize(unique_rows,A.cols());
+  IA.resize(unique_rows,1);
+  // Reindex IA according to IM
+  for(int i = 0;i<unique_rows;i++)
+  {
+    IA(i,0) = IM(vIA[i],0);
+    C.row(i) = A.row(IA(i,0));
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::unique_rows<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<int,-1,-1,0,-1,-1> >(Eigen::DenseBase<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<int,-1,-1,0,-1,-1> >&);
+template void igl::unique_rows<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<int,-1,1,0,-1,1> >(Eigen::DenseBase<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<int,-1,1,0,-1,1> >&);
+template void igl::unique_rows<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<long,-1,1,0,-1,1> >(Eigen::DenseBase<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<long,-1,1,0,-1,1> >&);
+template void igl::unique_rows<Eigen::Matrix<double,-1,-1,1,-1,-1>,Eigen::Matrix<double,-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<double,-1,-1,1,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double,-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<double,-1,3,0,-1,3>,Eigen::Matrix<double,-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<double,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double,-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 void igl::unique_rows<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<long,-1,1,0,-1,1>,Eigen::Matrix<long,-1,1,0,-1,1> >(Eigen::DenseBase<Eigen::Matrix<double,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,3,0,-1,3> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&);
+template void igl::unique_rows<Eigen::Matrix<float,-1,3,0,-1,3>,Eigen::Matrix<float,-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<float,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<float,-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<float,-1,3,0,-1,3>,Eigen::Matrix<float,-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<float,-1,3,0,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<float,-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 void igl::unique_rows<Eigen::Matrix<float,-1,3,1,-1,3>,Eigen::Matrix<float,-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<float,-1,3,1,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<float,-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<float,-1,3,1,-1,3>,Eigen::Matrix<float,-1,3,1,-1,3>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1> >(Eigen::DenseBase<Eigen::Matrix<float,-1,3,1,-1,3> > const&,Eigen::PlainObjectBase<Eigen::Matrix<float,-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> >&);
+template void igl::unique_rows<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::DenseBase<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> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
+template void igl::unique_rows<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::DenseBase<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> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&);
+template void igl::unique_rows<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::DenseBase<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> >&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,1,0,-1,1> >&);
+template void igl::unique_rows<Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<long,-1,1,0,-1,1>,Eigen::Matrix<long,-1,1,0,-1,1> >(Eigen::DenseBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&);
+template void igl::unique_rows<Eigen::Matrix<int,-1,2,0,-1,2>,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::DenseBase<Eigen::Matrix<int,-1,2,0,-1,2> > const&,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> >&);
+template void igl::unique_rows<Eigen::Matrix<int,-1,2,0,-1,2>,Eigen::Matrix<int,-1,2,0,-1,2>,Eigen::Matrix<long,-1,1,0,-1,1>,Eigen::Matrix<long,-1,1,0,-1,1> >(Eigen::DenseBase<Eigen::Matrix<int,-1,2,0,-1,2> > const&,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,2,0,-1,2> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&,Eigen::PlainObjectBase<Eigen::Matrix<long,-1,1,0,-1,1> >&);
+#ifdef WIN32
+template void igl::unique_rows<class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> >(class Eigen::DenseBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &);
+template void igl::unique_rows<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::DenseBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
+#endif
+#endif

+ 41 - 0
include/igl/unique_rows.h

@@ -0,0 +1,41 @@
+// 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_UNIQUE_ROWS_H
+#define IGL_UNIQUE_ROWS_H
+#include "igl_inline.h"
+
+#include <vector>
+#include <Eigen/Core>
+namespace igl
+{
+  // Act like matlab's [C,IA,IC] = unique(X,'rows')
+  //
+  // Templates:
+  //   DerivedA derived scalar type, e.g. MatrixXi or MatrixXd
+  //   DerivedIA derived integer type, e.g. MatrixXi
+  //   DerivedIC derived integer type, e.g. MatrixXi
+  // Inputs:
+  //   A  m by n matrix whose entries are to unique'd according to rows
+  // Outputs:
+  //   C  #C vector of unique rows in A
+  //   IA  #C index vector so that C = A(IA,:);
+  //   IC  #A index vector so that A = C(IC,:);
+  template <typename DerivedA, typename DerivedC, typename DerivedIA, typename DerivedIC>
+  IGL_INLINE void unique_rows(
+    const Eigen::DenseBase<DerivedA>& A,
+    Eigen::PlainObjectBase<DerivedC>& C,
+    Eigen::PlainObjectBase<DerivedIA>& IA,
+    Eigen::PlainObjectBase<DerivedIC>& IC);
+
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "unique_rows.cpp"
+#endif
+
+#endif

+ 3 - 1
include/igl/unique_simplices.cpp

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "unique_simplices.h"
 #include "sort.h"
-#include "unique.h"
+#include "unique_rows.h"
 #include "parallel_for.h"
 
 template <
@@ -47,6 +47,8 @@ IGL_INLINE void igl::unique_simplices(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::unique_simplices<Eigen::Matrix<int, -1, 3, 1, -1, 3>, 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<int, -1, 3, 1, -1, 3> > const&, 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> >&);
 template void igl::unique_simplices<Eigen::Matrix<int, -1, 2, 0, -1, 2>, 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<int, -1, 2, 0, -1, 2> > const&, 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> >&);
 template void igl::unique_simplices<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<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique_simplices<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);

+ 1 - 1
include/igl/unzip_corners.cpp

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "unzip_corners.h"
 
-#include "unique.h"
+#include "unique_rows.h"
 #include "slice.h"
 
 template < typename DerivedA, typename DerivedU, typename DerivedG, typename DerivedJ >

+ 14 - 16
include/igl/vector_area_matrix.cpp

@@ -26,28 +26,26 @@ IGL_INLINE void igl::vector_area_matrix(
   // number of vertices
   const int n = F.maxCoeff()+1;
 
-	SparseMatrix<Scalar> aux (n * 2, n * 2);
-	SparseMatrix<Scalar> auxT(n * 2, n * 2);
-
-	vector<Triplet<Scalar> > auxTripletList;
-	vector<Triplet<Scalar> > auxTTripletList;
-
   MatrixXi E;
   boundary_facets(F,E);
 
-	for(int k = 0; k < E.rows(); k++)
+  //Prepare a vector of triplets to set the matrix
+  vector<Triplet<Scalar> > tripletList;
+  tripletList.reserve(4*E.rows());
+
+  for(int k = 0; k < E.rows(); k++)
   {
 		int i = E(k,0);
 		int j = E(k,1);
-		auxTripletList.push_back(Triplet<Scalar>(i+n, j, -0.5));
-		auxTripletList.push_back(Triplet<Scalar>(i, j+n, 0.5));
-		auxTTripletList.push_back(Triplet<Scalar>(j, i+n, -0.5));
-		auxTTripletList.push_back(Triplet<Scalar>(j+n, i, 0.5));
-	}
-
-	aux.setFromTriplets(auxTripletList.begin(), auxTripletList.end());
-	auxT.setFromTriplets(auxTTripletList.begin(), auxTTripletList.end());
-	A = (aux + auxT)*0.5;
+        tripletList.push_back(Triplet<Scalar>(i+n, j, -0.25));
+        tripletList.push_back(Triplet<Scalar>(j, i+n, -0.25));
+        tripletList.push_back(Triplet<Scalar>(i, j+n, 0.25));
+        tripletList.push_back(Triplet<Scalar>(j+n, i, 0.25));
+  }
+
+  //Set A from triplets (Eigen will sum triplets with same coordinates)
+  A.resize(n * 2, n * 2);
+  A.setFromTriplets(tripletList.begin(), tripletList.end());
 }
 
 #ifdef IGL_STATIC_LIBRARY

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно