瀏覽代碼

templated face matrix data type

Former-commit-id: 9c055710ebe5633a137902c7723e5fe75c73517b
dolga 13 年之前
父節點
當前提交
d255c7a574
共有 19 個文件被更改,包括 152 次插入57 次删除
  1. 5 0
      Makefile
  2. 1 0
      adjacency_list.cpp
  3. 1 1
      adjacency_list.h
  4. 2 2
      grad.cpp
  5. 2 2
      grad.h
  6. 3 3
      is_border_vertex.cpp
  7. 3 2
      is_border_vertex.h
  8. 3 2
      is_manifold.cpp
  9. 3 2
      is_manifold.h
  10. 60 1
      matlabinterface.h
  11. 2 2
      moveFV.cpp
  12. 2 2
      moveFV.h
  13. 7 6
      pos.h
  14. 11 5
      removeDuplicates.cpp
  15. 8 2
      removeDuplicates.h
  16. 10 5
      removeUnreferenced.cpp
  17. 7 2
      removeUnreferenced.h
  18. 12 10
      tt.cpp
  19. 10 8
      tt.h

+ 5 - 0
Makefile

@@ -22,6 +22,11 @@ debug: CFLAGS += -g -Wall -Werror
 EIGEN3_INC=-I/usr/local/include/eigen3 -I/usr/local/include/eigen3/unsupported
 INC+=$(EIGEN3_INC)
 
+# AntTweakBar dependency
+MY_INC=-I/opt/local/include -I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
+INC+=$(MY_INC)
+
+
 ## OpenGL dependency
 #LIB+=-framework OpenGL
 #LIB+=-framework GLUT

+ 1 - 0
adjacency_list.cpp

@@ -1,6 +1,7 @@
 #include "adjacency_list.h"
 
 #include "verbose.h"
+#include <algorithm>
 
 template <typename T, typename M>
 IGL_INLINE void igl::adjacency_list(

+ 1 - 1
adjacency_list.h

@@ -5,7 +5,7 @@
 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #include <Eigen/Dense>
 #include <Eigen/Sparse>
-//#include <plot_vector.h>
+#include <vector>
 namespace igl 
 {
   // Constructs the graph adjacency list of a given mesh (V,F)

+ 2 - 2
grad.cpp

@@ -1,8 +1,8 @@
 #include "grad.h"
 
-template <typename T>
+template <typename T, typename S>
 IGL_INLINE void igl::grad(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-  const Eigen::MatrixXi &F,
+  const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
   const Eigen::Matrix<T, Eigen::Dynamic, 1>&X,
   Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &G )
 {

+ 2 - 2
grad.h

@@ -33,9 +33,9 @@ namespace igl {
   // i, and A is the area of triangle (i,j,k). ^R90 represent a rotation of 
   // 90 degrees
   //
-  template <typename T>
+  template <typename T, typename S>
   IGL_INLINE void grad(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-    const Eigen::MatrixXi &F,
+    const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
     const Eigen::Matrix<T, Eigen::Dynamic, 1>&X,
     Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &G );
 }

+ 3 - 3
is_border_vertex.cpp

@@ -3,10 +3,10 @@
 
 #include "tt.h"
 
-template<typename T>
-IGL_INLINE std::vector<bool> igl::is_border_vertex(const T& V, const Eigen::MatrixXi& F)
+template<typename T, typename S>
+IGL_INLINE std::vector<bool> igl::is_border_vertex(const T& V, const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>& F)
 {
-  Eigen::MatrixXi FF;
+  Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> FF;
   igl::tt(V,F,FF);
   std::vector<bool> ret(V.rows());
   for(int i=0; i<ret.size();++i)

+ 3 - 2
is_border_vertex.h

@@ -12,8 +12,9 @@
 
 namespace igl 
 {
-  template<typename T>
-  IGL_INLINE std::vector<bool> is_border_vertex(const T& V, const Eigen::MatrixXi& F);
+  template<typename T, typename S>
+  IGL_INLINE std::vector<bool> is_border_vertex(const T& V,
+                                                const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>& F);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 3 - 2
is_manifold.cpp

@@ -2,8 +2,9 @@
 
 #include <algorithm>
 
-template<typename T>
-IGL_INLINE bool igl::is_manifold(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F)
+template<typename T, typename S>
+IGL_INLINE bool igl::is_manifold(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V,
+                                 const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>& F)
   {
     std::vector<std::vector<int> > TTT;
     for(int f=0;f<F.rows();++f)

+ 3 - 2
is_manifold.h

@@ -18,8 +18,9 @@ namespace igl
   //
   // Known Bugs:
   //  Does not check for non-manifold vertices
-  template<typename T>
-  IGL_INLINE bool is_manifold(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F);
+  template<typename T, typename S>
+  IGL_INLINE bool is_manifold(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V,
+                              const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>& F);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 60 - 1
matlabinterface.h

@@ -12,7 +12,7 @@
 
 // MAC ONLY:
 // Add to the environment variables:
-// DYLD_LIBRARY_PATH = /Applications/MATLAB_R2011a.app/bin/maci64
+// DYLD_LIBRARY_PATH =  
 // PATH = /opt/local/bin:/opt/local/sbin:/Applications/MATLAB_R2011a.app/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
 
 #ifndef IGL_MATLAB_INTERFACE_H
@@ -47,6 +47,9 @@ namespace igl
   // Send a matrix to MATLAB
   inline void mlsetmatrix(Engine** engine, std::string name, const Eigen::MatrixXi& M);
   
+  // Send a matrix to MATLAB
+  inline void mlsetmatrix(Engine** mlengine, std::string name, const Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M);
+  
   // Receive a matrix from MATLAB
   inline void mlgetmatrix(Engine** engine, std::string name, Eigen::MatrixXd& M);
   
@@ -56,6 +59,9 @@ namespace igl
   // Receive a matrix from MATLAB
   inline void mlgetmatrix(Engine** engine, std::string name, Eigen::MatrixXi& M);
   
+  // Receive a matrix from MATLAB
+  inline void mlgetmatrix(Engine** mlengine, std::string name, Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M);
+
   // Send a single scalar to MATLAB
   inline void mlsetscalar(Engine** engine, std::string name, double s);
   
@@ -137,6 +143,24 @@ inline void igl::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::M
   mxDestroyArray(A);
 }
 
+// Send a matrix to MATLAB
+inline void igl::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M)
+{
+  if (*mlengine == 0)
+    mlinit(mlengine);
+  
+  mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
+  double *pM = mxGetPr(A);
+  
+  int c = 0;
+  for(int j=0; j<M.cols();++j)
+    for(int i=0; i<M.rows();++i)
+      pM[c++] = double(M(i,j))+1;
+  
+  engPutVariable(*mlengine, name.c_str(), A);
+  mxDestroyArray(A);
+}
+
 // Receive a matrix from MATLAB
 inline void igl::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixXd& M)
 {
@@ -238,6 +262,41 @@ inline void igl::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixX
   mxDestroyArray(ary);
 }
 
+// Receive a matrix from MATLAB
+inline void igl::mlgetmatrix(Engine** mlengine, std::string name, Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M)
+{
+  if (*mlengine == 0)
+    mlinit(mlengine);
+  
+  unsigned long m = 0;
+  unsigned long n = 0;
+  std::vector<double> t;
+  
+  mxArray *ary = engGetVariable(*mlengine, name.c_str());
+  if (ary == NULL)
+  {
+    m = 0;
+    n = 0;
+    M = Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >(0,0);
+  }
+  else
+  {
+    m = mxGetM(ary);
+    n = mxGetN(ary);
+    M = Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >(m,n);
+    
+    double *pM = mxGetPr(ary);
+    
+    int c = 0;
+    for(int j=0; j<M.cols();++j)
+      for(int i=0; i<M.rows();++i)
+        M(i,j) = (unsigned int)(pM[c++])-1;
+  }
+  
+  mxDestroyArray(ary);
+}
+
+
 // Send a single scalar to MATLAB
 inline void igl::mlsetscalar(Engine** mlengine, std::string name, double s)
 {

+ 2 - 2
moveFV.cpp

@@ -1,8 +1,8 @@
 #include "moveFV.h"
 
-template <typename T>
+template <typename T, typename I>
 IGL_INLINE void igl::moveFV(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-            const Eigen::MatrixXi &F,
+            const Eigen::Matrix<I, Eigen::Dynamic, Eigen::Dynamic> &F,
             const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &S,
             Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &SV)
 {

+ 2 - 2
moveFV.h

@@ -22,9 +22,9 @@ namespace igl
   // 
   // Output:
   // SV: scalar field defined on vertices
-  template <typename T>
+  template <typename T, typename I>
   IGL_INLINE void moveFV(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
-              const Eigen::MatrixXi &F,
+              const Eigen::Matrix<I, Eigen::Dynamic, Eigen::Dynamic> &F,
               const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &S,
               Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &SV);
 }

+ 7 - 6
pos.h

@@ -13,13 +13,14 @@
 namespace igl 
 {
   // Pos - Fake halfedge for fast and easy navigation on triangle meshes with VT and TT adj
+template <typename S>
   class Pos
   {
   public:
     // Init the pos by specifying Face,Edge Index and Orientation
-    Pos(const Eigen::MatrixXi* F, 
-        Eigen::MatrixXi* FF, 
-        Eigen::MatrixXi* FFi, 
+    Pos(const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>* F, 
+        Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>* FF, 
+        Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>* FFi, 
         int fi,
         int ei,
         bool reverse = false
@@ -113,9 +114,9 @@ namespace igl
     int ei;
     bool reverse;
     
-    const Eigen::MatrixXi*     F;
-    Eigen::MatrixXi*     FF;
-    Eigen::MatrixXi*     FFi;
+    const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>*     F;
+    Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>*     FF;
+    Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>*     FFi;
   };
   
 }

+ 11 - 5
removeDuplicates.cpp

@@ -1,14 +1,20 @@
 #include "removeDuplicates.h"
 #include <vector>
 
-template <typename T>
-IGL_INLINE void igl::removeDuplicates(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I, const double epsilon)
+template <typename T, typename S>
+IGL_INLINE void igl::removeDuplicates(
+                                 const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+                                 const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
+                                 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+                                 Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
+                                 Eigen::Matrix<S, Eigen::Dynamic, 1> &I,
+                                 const double epsilon)
 {
   using namespace std;
   //// build collapse map
   int n = V.rows();
   
-  I = Eigen::VectorXi (n);
+  I = Eigen::Matrix<S, Eigen::Dynamic, 1>(n);
   I[0] = 0;
   
   bool *VISITED = new bool[n];
@@ -40,8 +46,8 @@ IGL_INLINE void igl::removeDuplicates(const Eigen::Matrix<T, Eigen::Dynamic, Eig
   NV.conservativeResize  (  count , Eigen::NoChange );
 
   count = 0;
-  std::vector<int> face;
-  NF = Eigen::MatrixXi(F.rows(),F.cols());
+  std::vector<S> face;
+  NF = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>(F.rows(),F.cols());
   for (int i =0; i <F.rows(); ++i)
   {
     face.clear();

+ 8 - 2
removeDuplicates.h

@@ -23,8 +23,14 @@ namespace igl
   // Output:
   // NV, NF: new mesh without duplicate vertices
   
-  template <typename T>
-  IGL_INLINE void removeDuplicates(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I, const double epsilon = 2.2204e-15);
+  template <typename T, typename S>
+  IGL_INLINE void removeDuplicates(
+                                   const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+                                   const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
+                                   Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+                                   Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
+                                   Eigen::Matrix<S, Eigen::Dynamic, 1> &I,
+                                   const double epsilon = 2.2204e-15);
   
 }
 

+ 10 - 5
removeUnreferenced.cpp

@@ -1,11 +1,16 @@
 #include "removeUnreferenced.h"
 
-template <typename T>
-IGL_INLINE void igl::removeUnreferenced(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I)
+template <typename T, typename S>
+IGL_INLINE void igl::removeUnreferenced(
+                                   const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+                                   const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
+                                   Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+                                   Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
+                                   Eigen::Matrix<S, Eigen::Dynamic, 1> &I)
 {
 
   // Mark referenced vertices
-  Eigen::MatrixXi mark = Eigen::MatrixXi::Zero(V.rows(),1);
+  Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> mark = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>::Zero(V.rows(),1);
   
   for(int i=0; i<F.rows(); ++i)
   {
@@ -20,8 +25,8 @@ IGL_INLINE void igl::removeUnreferenced(const Eigen::Matrix<T, Eigen::Dynamic, E
   int newsize = mark.sum();
   
   NV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>(newsize,V.cols());
-  NF = Eigen::MatrixXi(F.rows(),F.cols());
-  I  = Eigen::MatrixXi(V.rows(),1);
+  NF = Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic>(F.rows(),F.cols());
+  I  = Eigen::Matrix<S, Eigen::Dynamic, 1>(V.rows(),1);
   
   // Do a pass on the marked vector and remove the unreferenced vertices
   int count = 0;

+ 7 - 2
removeUnreferenced.h

@@ -20,8 +20,13 @@ namespace igl
   // Output:
   // NV, NF: new mesh without unreferenced vertices
   
-  template <typename T>
-  IGL_INLINE void removeUnreferenced(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I);
+  template <typename T, typename S>
+  IGL_INLINE void removeUnreferenced(
+                                     const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
+                                     const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
+                                     Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
+                                     Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
+                                     Eigen::Matrix<S, Eigen::Dynamic, 1> &I);
   
 }
 

+ 12 - 10
tt.cpp

@@ -3,8 +3,8 @@
 #include "is_manifold.h"
 #include <algorithm>
 
-template<typename T> 
-IGL_INLINE void igl::tt_preprocess(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT)
+template<typename T, typename S> 
+IGL_INLINE void igl::tt_preprocess(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT)
 {
   for(int f=0;f<F.rows();++f)
     for (int i=0;i<3;++i)
@@ -22,9 +22,10 @@ IGL_INLINE void igl::tt_preprocess(const Eigen::Matrix<T, Eigen::Dynamic, Eigen:
 }
 
 // Extract the face adjacencies
-IGL_INLINE void igl::tt_extractTT(const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TT)
+template<typename S> 
+IGL_INLINE void igl::tt_extractTT(const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT)
 {
-  TT = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
+  TT = Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>::Constant((int)(F.rows()),3,-1);
   
   for(int i=1;i<(int)TTT.size();++i)
   {
@@ -39,9 +40,10 @@ IGL_INLINE void igl::tt_extractTT(const Eigen::MatrixXi& F, std::vector<std::vec
 }
 
 // Extract the face adjacencies indices (needed for fast traversal)
-IGL_INLINE void igl::tt_extractTTi(const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TTi)
+template<typename S> 
+IGL_INLINE void igl::tt_extractTTi(const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TTi)
 {
-  TTi = Eigen::MatrixXi::Constant((int)(F.rows()),3,-1);
+  TTi = Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>::Constant((int)(F.rows()),3,-1);
   
   for(int i=1;i<(int)TTT.size();++i)
   {
@@ -56,8 +58,8 @@ IGL_INLINE void igl::tt_extractTTi(const Eigen::MatrixXi& F, std::vector<std::ve
 }
 
 // Compute triangle-triangle adjacency
-template<typename T> 
-IGL_INLINE void igl::tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, Eigen::MatrixXi& TT)
+template<typename T, typename S> 
+IGL_INLINE void igl::tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT)
 {
   assert(igl::is_manifold(V,F));
   std::vector<std::vector<int> > TTT;
@@ -67,8 +69,8 @@ IGL_INLINE void igl::tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>&
 }
 
 // Compute triangle-triangle adjacency with indices
-template<typename T> 
-IGL_INLINE void igl::tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, Eigen::MatrixXi& TT, Eigen::MatrixXi& TTi)
+template<typename T, typename S> 
+IGL_INLINE void igl::tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TTi)
 {
   assert(igl::is_manifold(V,F));
   std::vector<std::vector<int> > TTT;

+ 10 - 8
tt.h

@@ -14,18 +14,20 @@
 namespace igl 
 {
   // Preprocessing
-  template<typename T> 
-  IGL_INLINE void tt_preprocess(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT);
+  template<typename T, typename S> 
+  IGL_INLINE void tt_preprocess(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT);
   // Extract the face adjacencies
-  IGL_INLINE void tt_extractTT(const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TT);
+  template<typename S> 
+  IGL_INLINE void tt_extractTT(const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT);
   // Extract the face adjacencies indices (needed for fast traversal)
-  IGL_INLINE void tt_extractTTi(const Eigen::MatrixXi& F, std::vector<std::vector<int> >& TTT, Eigen::MatrixXi& TTi);
+  template<typename S> 
+  IGL_INLINE void tt_extractTTi(const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, std::vector<std::vector<int> >& TTT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TTi);
   // Compute triangle-triangle adjacency
-  template<typename T> 
-  IGL_INLINE void tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, Eigen::MatrixXi& TT);
+  template<typename T, typename S> 
+  IGL_INLINE void tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT);
   // Compute triangle-triangle adjacency with indices
-  template<typename T> 
-  IGL_INLINE void tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::MatrixXi& F, Eigen::MatrixXi& TT, Eigen::MatrixXi& TTi);
+  template<typename T, typename S> 
+  IGL_INLINE void tt(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& V, const Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& F, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TT, Eigen::Matrix<S,Eigen::Dynamic, Eigen::Dynamic>& TTi);
 }
 
 #ifdef IGL_HEADER_ONLY