Browse Source

next filename, draw quad meshes, template specializations,

Former-commit-id: 6811c3b307941175de2c41629da62cea3fca4a1d
Alec Jacobson 10 years ago
parent
commit
8e6f510b7b

+ 4 - 54
examples/skeleton-builder/example.cpp

@@ -1,15 +1,11 @@
 #include <igl/draw_skeleton_3d.h>
 #include <igl/draw_skeleton_vector_graphics.h>
 #include <igl/two_axis_valuator_fixed_up.h>
-#include <igl/readOBJ.h>
+#include <igl/read_triangle_mesh.h>
 #include <igl/readTGF.h>
 #include <igl/writeOBJ.h>
 #include <igl/writeOFF.h>
-#include <igl/readWRL.h>
 #include <igl/report_gl_error.h>
-#include <igl/polygon_mesh_to_triangle_mesh.h>
-#include <igl/readOFF.h>
-#include <igl/readMESH.h>
 #include <igl/draw_mesh.h>
 #include <igl/draw_floor.h>
 #include <igl/pathinfo.h>
@@ -1100,55 +1096,9 @@ int main(int argc, char * argv[])
   cout<<"⇧ ⌘ Z                  Redo."<<endl;
   cout<<"^C,ESC                 Exit (without saving)."<<endl;
 
-  // dirname, basename, extension and filename
-  string dir,base,ext,name;
-  pathinfo(filename,dir,base,ext,name);
-  // Convert extension to lower case
-  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-  vector<vector<double > > vV,vN,vTC;
-  vector<vector<int > > vF,vFTC,vFN;
-  if(ext == "obj")
-  {
-    // Convert extension to lower case
-    if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
-    {
-      return 1;
-    }
-  }else if(ext == "off")
-  {
-    // Convert extension to lower case
-    if(!igl::readOFF(filename,vV,vF,vN))
-    {
-      return 1;
-    }
-  }else if(ext == "wrl")
-  {
-    // Convert extension to lower case
-    if(!igl::readWRL(filename,vV,vF))
-    {
-      return 1;
-    }
-  //}else
-  //{
-  //  // Convert extension to lower case
-  //  MatrixXi T;
-  //  if(!igl::readMESH(filename,V,T,F))
-  //  {
-  //    return 1;
-  //  }
-  //  //if(F.size() > T.size() || F.size() == 0)
-  //  {
-  //    boundary_facets(T,F);
-  //  }
-  }
-  if(vV.size() > 0)
-  {
-    if(!list_to_matrix(vV,V))
-    {
-      return 1;
-    }
-    polygon_mesh_to_triangle_mesh(vF,F);
-  }
+  string dir,_1,_2,name;
+  read_triangle_mesh(filename,V,F,dir,_1,_2,name);
+
   if(output_filename.size() == 0)
   {
     output_filename = dir+"/"+name+".tgf";

+ 45 - 114
examples/skeleton-posing/example.cpp

@@ -1,51 +1,46 @@
+#include <igl/Camera.h>
+#include <igl/MouseController.h>
+#include <igl/REDRUM.h>
+#include <igl/ReAntTweakBar.h>
+#include <igl/STR.h>
+#include <igl/barycenter.h>
+#include <igl/bbw/bbw.h>
+#include <igl/bone_parents.h>
+#include <igl/boundary_conditions.h>
+#include <igl/boundary_facets.h>
+#include <igl/centroid.h>
+#include <igl/cgal/remesh_self_intersections.h>
+#include <igl/colon.h>
+#include <igl/draw_beach_ball.h>
+#include <igl/draw_floor.h>
+#include <igl/draw_mesh.h>
 #include <igl/draw_skeleton_3d.h>
 #include <igl/draw_skeleton_vector_graphics.h>
-#include <igl/two_axis_valuator_fixed_up.h>
-#include <igl/readOBJ.h>
-#include <igl/readTGF.h>
-#include <igl/writeOBJ.h>
-#include <igl/writeOFF.h>
-#include <igl/writeDMAT.h>
-#include <igl/readDMAT.h>
-#include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
-#include <igl/polygon_mesh_to_triangle_mesh.h>
-#include <igl/readOFF.h>
-#include <igl/readMESH.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_floor.h>
+#include <igl/forward_kinematics.h>
+#include <igl/get_seconds.h>
+#include <igl/lbs_matrix.h>
+#include <igl/material_colors.h>
+#include <igl/normalize_row_sums.h>
 #include <igl/pathinfo.h>
-#include <igl/list_to_matrix.h>
-#include <igl/quat_to_mat.h>
 #include <igl/per_face_normals.h>
-#include <igl/material_colors.h>
-#include <igl/trackball.h>
+#include <igl/quat_to_mat.h>
+#include <igl/readDMAT.h>
+#include <igl/readTGF.h>
+#include <igl/read_triangle_mesh.h>
+#include <igl/remove_unreferenced.h>
+#include <igl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
-#include <igl/REDRUM.h>
-#include <igl/Camera.h>
-#include <igl/ReAntTweakBar.h>
-#include <igl/get_seconds.h>
-#include <igl/forward_kinematics.h>
-#include <igl/boundary_conditions.h>
-#include <igl/lbs_matrix.h>
-#include <igl/colon.h>
-#include <igl/writeTGF.h>
-#include <igl/file_exists.h>
-#include <igl/MouseController.h>
-#include <igl/STR.h>
-#include <igl/bone_parents.h>
-#include <igl/cgal/remesh_self_intersections.h>
+#include <igl/tetgen/mesh_with_skeleton.h>
 #include <igl/tetgen/tetrahedralize.h>
-#include <igl/barycenter.h>
-#include <igl/remove_unreferenced.h>
-#include <igl/boundary_facets.h>
+#include <igl/trackball.h>
+#include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/winding_number.h>
-#include <igl/bbw/bbw.h>
-#include <igl/normalize_row_sums.h>
-#include <igl/centroid.h>
-#include <igl/tetgen/mesh_with_skeleton.h>
-#include <igl/draw_beach_ball.h>
+#include <igl/writeDMAT.h>
+#include <igl/writeOBJ.h>
+#include <igl/writeOFF.h>
+#include <igl/writeTGF.h>
+#include <igl/next_filename.h>
 
 #include <Eigen/Core>
 #include <Eigen/Geometry>
@@ -168,26 +163,6 @@ void TW_CALL get_rotation_type(void * value, void *clientData)
   *rt = rotation_type;
 }
 
-std::string next_filename(
-  const std::string & prefix, 
-  const int zeros,
-  const std::string & suffix)
-{
-  using namespace std;
-  using namespace igl;
-  // O(n)
-  int i = 0;
-  while(true)
-  {
-    string next = STR(prefix << setfill('0') << setw(zeros)<<i<<suffix);
-    if(!file_exists(next.c_str()))
-    {
-      return next;
-    }
-    i++;
-  }
-}
-
 void reshape(int width, int height)
 {
   ::width = width;
@@ -540,16 +515,16 @@ void mouse_drag(int mouse_x, int mouse_y)
       case ROTATION_TYPE_IGL_TRACKBALL:
       {
         // Rotate according to trackball
-        igl::trackball<double>(
+        igl::trackball(
           width,
           height,
           2.0,
-          down_camera.m_rotation_conj.coeffs().data(),
+          down_camera.m_rotation_conj,
           down_x,
           down_y,
           mouse_x,
           mouse_y,
-          q.coeffs().data());
+          q);
           break;
       }
       case ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP:
@@ -617,7 +592,8 @@ bool save()
   using namespace std;
   using namespace igl;
   using namespace Eigen;
-  string output_filename = next_filename(output_prefix,4,".dmat");
+  string output_filename;
+  next_filename(output_prefix,4,".dmat",output_filename);
   MatrixXd T;
   forward_kinematics(C,BE,P,s.mouse.rotations(),T);
   if(writeDMAT(output_filename,T))
@@ -861,62 +837,17 @@ int main(int argc, char * argv[])
   cout<<"⇧ ⌘ Z                  Redo."<<endl;
   cout<<"^C,ESC                 Exit (without saving)."<<endl;
 
-  // dirname, basename, extension and filename
-  string dir,base,ext,name;
-  pathinfo(filename,dir,base,ext,name);
-  // Convert extension to lower case
-  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-  vector<vector<double > > vV,vN,vTC;
-  vector<vector<int > > vF,vFTC,vFN;
-  if(ext == "obj")
-  {
-    // Convert extension to lower case
-    if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
-    {
-      return 1;
-    }
-  }else if(ext == "off")
-  {
-    // Convert extension to lower case
-    if(!igl::readOFF(filename,vV,vF,vN))
-    {
-      return 1;
-    }
-  }else if(ext == "wrl")
-  {
-    // Convert extension to lower case
-    if(!igl::readWRL(filename,vV,vF))
-    {
-      return 1;
-    }
-  //}else
-  //{
-  //  // Convert extension to lower case
-  //  MatrixXi T;
-  //  if(!igl::readMESH(filename,V,T,F))
-  //  {
-  //    return 1;
-  //  }
-  //  //if(F.size() > T.size() || F.size() == 0)
-  //  {
-  //    boundary_facets(T,F);
-  //  }
-  }
-  if(vV.size() > 0)
-  {
-    if(!list_to_matrix(vV,V))
-    {
-      return 1;
-    }
-    polygon_mesh_to_triangle_mesh(vF,F);
-  }
+  string dir,_1,_2,name;
+  read_triangle_mesh(filename,V,F,dir,_1,_2,name);
+
   if(output_prefix.size() == 0)
   {
     output_prefix = dir+"/"+name+"-pose-";
   }
 
   {
-    string output_filename = next_filename(output_prefix,4,".dmat");
+    string output_filename;
+    next_filename(output_prefix,4,".dmat",output_filename);
     cout<<BLUEGIN("Output set to start with "<<output_filename)<<endl;
   }
 

+ 1 - 0
include/igl/MouseController.h

@@ -80,6 +80,7 @@ namespace igl
       inline const VectorXb & selection() const{return m_selection;};
       //                          〃 m_is_selecting
       inline const bool & is_selecting() const{return m_is_selecting;}
+      inline const bool & is_widget_down() const{return m_widget.is_down();}
       //                          〃 m_rotations
       inline const RotationList & rotations() const{return m_rotations;}
       // Returns non-const reference to m_root_enabled

+ 2 - 1
include/igl/boundary_facets.cpp

@@ -133,9 +133,10 @@ Ret igl::boundary_facets(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
+// generated by autoexplicit.sh
+template void igl::boundary_facets<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::boundary_facets<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> >&);
 template void igl::boundary_facets<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
 //template Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > igl::boundary_facets(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
 template Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::boundary_facets<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&);
 #endif
-

+ 28 - 15
include/igl/draw_mesh.cpp

@@ -75,6 +75,7 @@ IGL_INLINE void igl::draw_mesh(
   using namespace std;
   using namespace Eigen;
   const int rF = F.rows();
+  const int cF = F.cols();
   const int cC = C.cols();
   const int rC = C.rows();
   const int cW = W.cols();
@@ -93,6 +94,9 @@ IGL_INLINE void igl::draw_mesh(
     assert(C.cols() == 3 || C.size() == 0);
     assert(N.cols() == 3 || N.size() == 0);
     assert(TC.cols() == 2 || TC.size() == 0);
+    assert(cF == 3 || cF == 4);
+    assert(TF.size() == 0 || TF.cols() == F.cols());
+    assert(NF.size() == 0 || NF.cols() == NF.cols());
   }
   if(W.size()>0)
   {
@@ -101,12 +105,21 @@ IGL_INLINE void igl::draw_mesh(
     assert(W.cols() == WI.cols());
   }
 
-  glBegin(GL_TRIANGLES);
+  switch(F.cols())
+  {
+    default:
+    case 3:
+      glBegin(GL_TRIANGLES);
+      break;
+    case 4:
+      glBegin(GL_QUADS);
+      break;
+  }
   // loop over faces
   for(int i = 0; i<rF;i++)
   {
     // loop over corners of triangle
-    for(int j = 0;j<3;j++)
+    for(int j = 0;j<cF;j++)
     {
 
       int tc = -1;
@@ -119,9 +132,9 @@ IGL_INLINE void igl::draw_mesh(
       }else if(rTC == rV)
       {
         tc = F(i,j);
-      }else if(rTC == rF*2)
+      }else if(rTC == rF*cF)
       {
-        tc = i*2 + j;
+        tc = i*cF + j;
       }else if(rTC == rF)
       {
         tc = i;
@@ -138,9 +151,9 @@ IGL_INLINE void igl::draw_mesh(
       }else if(rC == rV)
       {
         color = C.row(F(i,j));
-      }else if(rC == rF*3)
+      }else if(rC == rF*cF)
       {
-        color = C.row(i*3+j);
+        color = C.row(i*cF+j);
       }else if(rC == rF)
       {
         color = C.row(i);
@@ -152,19 +165,19 @@ IGL_INLINE void igl::draw_mesh(
       int n = -1;
       if(rNF != 0)
       {
-        n = NF(i,j);
-      } else if(rN == 1)
+        n = NF(i,j); // indexed normals
+      } else if(rN == 1) 
       {
-        n = 0;
-      }else if(rN == rV)
+        n = 0; // uniform normals
+      }else if(rN == rF)
       {
-        n = F(i,j);
-      }else if(rN == rF*2)
+        n = i; // face normals
+      }else if(rN == rV)
       {
-        n = i*2 + j;
-      }else if(rN == rF)
+        n = F(i,j); // vertex normals
+      }else if(rN == rF*cF)
       {
-        n = i;
+        n = i*cF + j; // corner normals
       }else
       {
         assert(N.size() == 0);

+ 1 - 1
include/igl/draw_skeleton_3d.h

@@ -41,6 +41,6 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedBE> & BE);
 };
 #ifndef IGL_STATIC_LIBRARY
-#  include "draw_skeleton_3d.h"
+#  include "draw_skeleton_3d.cpp"
 #endif
 #endif

+ 1 - 1
include/igl/draw_skeleton_vector_graphics.h

@@ -44,6 +44,6 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedT> & T);
 }
 #ifndef IGL_STATIC_LIBRARY
-#  include "draw_skeleton_vector_graphics.h"
+#  include "draw_skeleton_vector_graphics.cpp"
 #endif
 #endif 

+ 38 - 0
include/igl/next_filename.cpp

@@ -0,0 +1,38 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "next_filename.h"
+#include "STR.h"
+#include "file_exists.h"
+#include <cmath>
+#include <iomanip>
+
+bool igl::next_filename(
+  const std::string & prefix, 
+  const int zeros,
+  const std::string & suffix,
+  std::string & next)
+{
+  using namespace std;
+  // O(n), for huge lists could at least find bounds with exponential search
+  // and then narrow with binary search O(log(n))
+  int i = 0;
+  while(true)
+  {
+    next = STR(prefix << setfill('0') << setw(zeros)<<i<<suffix);
+    if(!file_exists(next.c_str()))
+    {
+      return true;
+    }
+    i++;
+    if(zeros > 0 && i >= pow(10,zeros))
+    {
+      return false;
+    }
+  }
+}
+

+ 36 - 0
include/igl/next_filename.h

@@ -0,0 +1,36 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_NEXT_FILENAME_H
+#define IGL_NEXT_FILENAME_H
+#include "igl_inline.h"
+#include <string>
+namespace igl
+{
+  // Find the file with the first filename of the form
+  // "prefix-%0[zeros]dsuffix"
+  // 
+  // Inputs:
+  //   prefix  path to containing dir and filename prefix
+  //   zeros number of leading zeros as if digit printed with printf
+  //   suffix  suffix of filename and extension
+  // Outputs:
+  //   next  path to next file
+  // Returns true if found, false if exceeding range in zeros
+  IGL_INLINE bool next_filename(
+    const std::string & prefix, 
+    const int zeros,
+    const std::string & suffix,
+    std::string & next);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "next_filename.cpp"
+#endif
+
+#endif
+

+ 14 - 1
include/igl/polygon_mesh_to_triangle_mesh.cpp

@@ -6,6 +6,7 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "polygon_mesh_to_triangle_mesh.h"
+#include "matrix_to_list.h"
 
 template <typename Index, typename DerivedF>
 IGL_INLINE void igl::polygon_mesh_to_triangle_mesh(
@@ -54,7 +55,19 @@ IGL_INLINE void igl::polygon_mesh_to_triangle_mesh(
 
 }
 
+template <typename DerivedP, typename DerivedF>
+IGL_INLINE void igl::polygon_mesh_to_triangle_mesh(
+  const Eigen::PlainObjectBase<DerivedP>& P,
+  Eigen::PlainObjectBase<DerivedF>& F)
+{
+  std::vector<std::vector<typename DerivedP::Scalar> > vP;
+  matrix_to_list(P,vP);
+  return polygon_mesh_to_triangle_mesh(vP,F);
+}
+
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
+// generated by autoexplicit.sh
+template void igl::polygon_mesh_to_triangle_mesh<int, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::polygon_mesh_to_triangle_mesh<int, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 4 - 0
include/igl/polygon_mesh_to_triangle_mesh.h

@@ -35,6 +35,10 @@ namespace igl
   IGL_INLINE void polygon_mesh_to_triangle_mesh(
     const std::vector<std::vector<Index> > & vF,
     Eigen::PlainObjectBase<DerivedF>& F);
+  template <typename DerivedP, typename DerivedF>
+  IGL_INLINE void polygon_mesh_to_triangle_mesh(
+    const Eigen::PlainObjectBase<DerivedP>& P,
+    Eigen::PlainObjectBase<DerivedF>& F);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 2 - 0
include/igl/readMESH.cpp

@@ -467,5 +467,7 @@ IGL_INLINE bool igl::readMESH(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // generated by autoexplicit.sh
+template bool igl::readMESH<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, 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, 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<double, -1, -1, 0, -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, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 11 - 10
include/igl/readOBJ.cpp

@@ -368,16 +368,17 @@ IGL_INLINE bool igl::readOBJ(
     // igl::list_to_matrix(vF,F) already printed error message to std err
     return false;
   }
-  // Legacy
-  if(F.cols() != 3)
-  {
-    fprintf(stderr,
-            "Error: readOBJ(filename,V,F) is meant for reading triangle-only"
-            " meshes. This mesh has faces all with size %d. See readOBJ.h for other"
-            " options.\n",
-            (int)F.cols());
-    return false;
-  }
+  // THIS IS ANNOYING, I WANT TO READ QUADS, Why not?
+  //// Legacy
+  //if(F.cols() != 3)
+  //{
+  //  fprintf(stderr,
+  //          "Error: readOBJ(filename,V,F) is meant for reading triangle-only"
+  //          " meshes. This mesh has faces all with size %d. See readOBJ.h for other"
+  //          " options.\n",
+  //          (int)F.cols());
+  //  return false;
+  //}
   return true;
 }
 

+ 4 - 1
include/igl/readSTL.cpp

@@ -214,6 +214,9 @@ close_true:
 }
 
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
+// generated by autoexplicit.sh
+template bool igl::readSTL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > 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<double, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template bool igl::readSTL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 75 - 11
include/igl/read_triangle_mesh.cpp

@@ -7,11 +7,18 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "read_triangle_mesh.h"
 
+#include <igl/list_to_matrix.h>
+#include <igl/readMESH.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
+#include <igl/readSTL.h>
+#include <igl/readWRL.h>
 #include <igl/pathinfo.h>
+#include <igl/boundary_facets.h>
+#include <igl/polygon_mesh_to_triangle_mesh.h>
 
 #include <cstdio>
+#include <algorithm>
 #include <iostream>
 
 
@@ -50,25 +57,82 @@ IGL_INLINE bool igl::read_triangle_mesh(
   Eigen::PlainObjectBase<DerivedV>& V,
   Eigen::PlainObjectBase<DerivedF>& F)
 {
-    const char* p;
-    for (p = str.c_str(); *p != '\0'; p++)
-        ;
-    while (*p != '.')
-        p--;
+  std::string _1,_2,_3,_4;
+  return read_triangle_mesh(str,V,F,_1,_2,_3,_4);
+}
+
+template <typename DerivedV, typename DerivedF>
+IGL_INLINE bool igl::read_triangle_mesh(
+  const std::string filename,
+  Eigen::PlainObjectBase<DerivedV>& V,
+  Eigen::PlainObjectBase<DerivedF>& F,
+  std::string & dir,
+  std::string & base,
+  std::string & ext,
+  std::string & name)
+{
+  using namespace std;
+  using namespace Eigen;
 
-    if (!strcmp(p, ".obj") || !strcmp(p, ".OBJ"))
+  // dirname, basename, extension and filename
+  pathinfo(filename,dir,base,ext,name);
+  // Convert extension to lower case
+  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
+  vector<vector<double > > vV,vN,vTC;
+  vector<vector<int > > vF,vFTC,vFN;
+  if(ext == "mesh")
+  {
+    // Convert extension to lower case
+    MatrixXi T;
+    if(!readMESH(filename,V,T,F))
+    {
+      return 1;
+    }
+    //if(F.size() > T.size() || F.size() == 0)
+    {
+      boundary_facets(T,F);
+    }
+  }else if(ext == "obj")
+  {
+    if(!readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
+    {
+      return false;
+    }
+  }else if(ext == "off")
+  {
+    if(!readOFF(filename,vV,vF,vN))
+    {
+      return false;
+    }
+  }else if(ext == "stl")
+  {
+    MatrixXd _;
+    if(!readSTL(filename,V,F,_))
     {
-        return igl::readOBJ(str,V,F);
-    }else if (!strcmp(p, ".off") || !strcmp(p, ".OFF"))
+      return false;
+    }
+  }else if(ext == "wrl")
+  {
+    if(!readWRL(filename,vV,vF))
     {
-        return igl::readOFF(str,V,F);
+      return false;
     }
-    else
+  }else
+  {
+    cerr<<"Error: unknown extension: "<<ext<<endl;
+    return false;
+  }
+  if(vV.size() > 0)
+  {
+    if(!list_to_matrix(vV,V))
     {
-      fprintf(stderr,"read_triangle_mesh() does not recognize extension: %s\n",p);
       return false;
     }
+    polygon_mesh_to_triangle_mesh(vF,F);
+  }
+  return true;
 }
+
 #endif
 
 #ifdef IGL_STATIC_LIBRARY

+ 14 - 1
include/igl/read_triangle_mesh.h

@@ -26,7 +26,6 @@ namespace igl
   //     to Scalar)
   //   Index  type for indices (will be read as int and cast to Index)
   // Inputs:
-  // Inputs:
   //   str  path to .obj/.off file
   // Outputs:
   //   V  eigen double matrix #V by 3
@@ -42,6 +41,20 @@ namespace igl
     const std::string str,
     Eigen::PlainObjectBase<DerivedV>& V,
     Eigen::PlainObjectBase<DerivedF>& F);
+  // Outputs:
+  //  dir  directory path (see pathinfo.h)
+  //  base  base name (see pathinfo.h)
+  //  ext  extension (see pathinfo.h)
+  //  name  filename (see pathinfo.h)
+  template <typename DerivedV, typename DerivedF>
+  IGL_INLINE bool read_triangle_mesh(
+    const std::string str,
+    Eigen::PlainObjectBase<DerivedV>& V,
+    Eigen::PlainObjectBase<DerivedF>& F,
+    std::string & dir,
+    std::string & base,
+    std::string & ext,
+    std::string & name);
 #endif
 }
 

+ 1 - 0
include/igl/winding_number.cpp

@@ -36,6 +36,7 @@ IGL_INLINE void igl::winding_number(
         Vector3d p = O.row(o);
         W(o) = hier.winding_number(p);
       }
+      break;
     }
     default: assert(false && "Bad simplex size"); break;
   }

+ 10 - 1
include/igl/writeOBJ.cpp

@@ -32,7 +32,16 @@ IGL_INLINE bool igl::writeOBJ(
   
   for(int i=0;i<(int)F.rows();++i)
   {
-    s << "f " << F(i,0)+1 << " " << F(i,1)+1 << " " << F(i,2)+1 << std::endl;
+    s << "f ";
+    for(int c =0;c<(int)F.cols();++c)
+    {
+      if(c>0)
+      {
+        s<<" ";
+      }
+      s<< F(i,c)+1;
+    }
+    s<<std::endl;
   }
   
   s.close();