ソースを参照

replaced buggy readOBJ with wrapper to vector of vectors readobj

Former-commit-id: 9a21c90435c1f97973097de331e9ac5d0ebd75c8
jalec 13 年 前
コミット
84e0ce7b52
6 ファイル変更249 行追加37 行削除
  1. 15 2
      examples/meshio/example.cpp
  2. 67 0
      list_to_matrix.h
  3. 33 0
      max_size.h
  4. 39 0
      min_size.h
  5. 31 35
      readOBJ.h
  6. 64 0
      rows_to_matrix.h

+ 15 - 2
examples/meshio/example.cpp

@@ -2,9 +2,14 @@
 
 #include <cstdio>
 #include <vector>
+#include <algorithm>
+#include <functional>
+
+#include <Eigen/Dense>
 
 using namespace igl;
 using namespace std;
+using namespace Eigen;
 
 // Template:
 //   T  type that can be safely cast to float
@@ -30,8 +35,8 @@ int main(int argc, char * argv[])
     printf("USAGE:\n  ./example [path_1] [path_2] ... [path_n]\n");
     return 1;
   }
-  std::vector<std::vector<double> > V,TC,N;
-  std::vector<std::vector<int> > F,FTC,FN;
+  vector<std::vector<double> > V,TC,N;
+  vector<std::vector<int> > F,FTC,FN;
   // loop over arguments
   for(int i = 1; i < argc; i++)
   {
@@ -46,6 +51,14 @@ int main(int argc, char * argv[])
     cout<<"F=[";  print_vector_of_vectors_as_floats(F);  cout<<"];"<<endl;
     cout<<"FTC=[";print_vector_of_vectors_as_floats(FTC);cout<<"];"<<endl;
     cout<<"FN=["; print_vector_of_vectors_as_floats(FN); cout<<"];"<<endl;
+    // Eigen (V,F) style
+    MatrixXd EV;
+    MatrixXi EF;
+    readOBJ(argv[i],EV,EF);
+    cout<<"EV=["<<EV<<"];"<<endl;
+    cout<<"EF=["<<EF<<"];"<<endl;
   }
+
+
   return 0;
 }

+ 67 - 0
list_to_matrix.h

@@ -0,0 +1,67 @@
+#ifndef IGL_LIST_TO_MATRIX_H
+#define IGL_LIST_TO_MATRIX_H
+#include <vector>
+namespace igl
+{
+  // Convert a list (std::vector) of row vectors of the same length to a matrix
+  // Template: 
+  //   T  type that can be safely cast to type in Mat via '='
+  //   Mat  Matrix type, must implement:
+  //     .resize(m,n)
+  //     .row(i) = Row
+  // Inputs:
+  //   V  a m-long list of vectors of size n
+  // Outputs:
+  //   M  an m by n matrix
+  // Returns true on success, false on errors
+  template <typename T, class Mat>
+  bool list_to_matrix(const std::vector<std::vector<T > > & V,Mat & M);
+}
+
+// Implementation
+#include <cassert>
+#include <cstdio>
+
+#include "max_size.h"
+#include "min_size.h"
+#define VERBOSE
+#include "verbose.h"
+
+template <typename T, class Mat>
+bool igl::list_to_matrix(const std::vector<std::vector<T > > & V,Mat & M)
+{
+  // number of columns
+  int m = V.size();
+  verbose("m = %d\n",m);
+  if(m == 0)
+  {
+    fprintf(stderr,"Error: list_to_matrix() list is empty()\n");
+    return false;
+  }
+  // number of rows
+  int n = igl::min_size(V);
+  verbose("min = %d\n",igl::min_size(V));
+  verbose("max = %d\n",igl::max_size(V));
+  if(n != igl::max_size(V))
+  {
+    fprintf(stderr,"Error: list_to_matrix()"
+      " list elements are not all the same size\n");
+    return false;
+  }
+  assert(n != -1);
+  // Resize output
+  M.resize(m,n);
+
+  // Loop over rows
+  for(int i = 0;i<m;i++)
+  {
+    // Loop over cols
+    for(int j = 0;j<n;j++)
+    {
+      M(i,j) = V[i][j];
+    }
+  }
+
+  return true;
+}
+#endif

+ 33 - 0
max_size.h

@@ -0,0 +1,33 @@
+#ifndef IGL_MAX_SIZE_H
+#define IGL_MAX_SIZE_H
+#include <vector>
+
+namespace igl
+{
+  // Determine max size of lists in a vector
+  // Template:
+  //   T  some list type object that implements .size()
+  // Inputs:
+  //   V  vector of list types T
+  // Returns max .size() found in V, returns -1 if V is empty
+  template <typename T>
+  inline int max_size(const std::vector<T> & V);
+}
+
+// implementation 
+
+template <typename T>
+inline int igl::max_size(const std::vector<T> & V)
+{
+  int max_size = -1;
+  for(
+    typename std::vector<T>::const_iterator iter = V.begin();
+    iter != V.end(); 
+    iter++)
+  {
+    int size = (int)iter->size();
+    max_size = (max_size > size ? max_size : size);
+  }
+  return max_size;
+}
+#endif

+ 39 - 0
min_size.h

@@ -0,0 +1,39 @@
+#ifndef IGL_MIN_SIZE_H
+#define IGL_MIN_SIZE_H
+#include <vector>
+
+namespace igl
+{
+  // Determine min size of lists in a vector
+  // Template:
+  //   T  some list type object that implements .size()
+  // Inputs:
+  //   V  vector of list types T
+  // Returns min .size() found in V, returns -1 if V is empty
+  template <typename T>
+  inline int min_size(const std::vector<T> & V);
+}
+
+// implementation 
+
+template <typename T>
+inline int igl::min_size(const std::vector<T> & V)
+{
+  int min_size = -1;
+  for(
+    typename std::vector<T>::const_iterator iter = V.begin();
+    iter != V.end(); 
+    iter++)
+  {
+    int size = (int)iter->size();
+    // have to handle base case
+    if(min_size == -1)
+    {
+      min_size = size;
+    }else{
+      min_size = (min_size < size ? min_size : size);
+    }
+  }
+  return min_size;
+}
+#endif

+ 31 - 35
readOBJ.h

@@ -59,49 +59,45 @@ namespace igl
 }
 
 // Implementation
+#include "list_to_matrix.h"
+
 #include <iostream>
 #include <fstream>
 
 inline bool igl::readOBJ(const std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
 {
-  std::ifstream s(str.c_str());
-  if (s.is_open() == false)
+  std::vector<std::vector<double> > vV,vTC,vN;
+  std::vector<std::vector<int> > vF,vFTC,vFN;
+  bool success = igl::readOBJ(str,vV,vTC,vN,vF,vFTC,vFN);
+  if(!success)
   {
-    fprintf (stderr, "readOBJ(): could not open file %s", str.c_str());
+    // readOBJ(str,vV,vTC,vN,vF,vFTC,vFN) should have already printed an error
+    // message to stderr
     return false;
   }
-    std::vector<Eigen::Vector3d> Vtemp;
-    std::vector<Eigen::Vector3i> Ftemp;
-    char buf[1000];
-    while(!s.eof())
-    {
-        s.getline(buf, 1000);
-        if (buf[0] == 'v') // vertex coordinates found
-        {
-            char v;
-            double v1,v2,v3;
-            sscanf(buf, "%c %lf %lf %lf",&v,&v1,&v2,&v3);
-            Vtemp.push_back(Eigen::Vector3d(v1,v2,v3));
-        }
-        else if (buf[0] == 'f') // face description found
-        {
-            char v;
-            int v1,v2,v3;
-            sscanf(buf, "%c %d %d %d",&v,&v1,&v2,&v3);
-            Ftemp.push_back(Eigen::Vector3i(v1-1,v2-1,v3-1));
-        }
-    }
-    s.close();
-    
-    V = Eigen::MatrixXd(Vtemp.size(),3);
-    for(int i=0;i<V.rows();++i)
-        V.row(i) = Vtemp[i];
-    
-    F = Eigen::MatrixXi(Ftemp.size(),3);
-    for(int i=0;i<F.rows();++i)
-        F.row(i) = Ftemp[i];
-
-    return true;
+  bool V_rect = igl::list_to_matrix(vV,V);
+  if(!V_rect)
+  {
+    // igl::list_to_matrix(vV,V) already printed error message to std err
+    return false;
+  }
+  bool F_rect = igl::list_to_matrix(vF,F);
+  if(!F_rect)
+  {
+    // 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;
+  }
+  return true;
 }
 
 template <typename Scalar, typename Index>

+ 64 - 0
rows_to_matrix.h

@@ -0,0 +1,64 @@
+#ifndef IGL_ROWS_TO_MATRIX_H
+#define IGL_ROWS_TO_MATRIX_H
+#include <vector>
+namespace igl
+{
+  // Convert a list (std::vector) of row vectors of the same length to a matrix
+  // Template: 
+  //   Row  row vector type, must implement:
+  //     .size()
+  //   Mat  Matrix type, must implement:
+  //     .resize(m,n)
+  //     .row(i) = Row
+  // Inputs:
+  //   V  a m-long list of vectors of size n
+  // Outputs:
+  //   M  an m by n matrix
+  // Returns true on success, false on errors
+  template <class Row, class Mat>
+  bool rows_to_matrix(const std::vector<Row> & V,Mat & M);
+}
+
+// Implementation
+#include <cassert>
+#include <cstdio>
+
+#include "max_size.h"
+#include "min_size.h"
+
+template <class Row, class Mat>
+bool igl::rows_to_matrix(const std::vector<Row> & V,Mat & M)
+{
+  // number of columns
+  int m = V.size();
+  if(m == 0)
+  {
+    fprintf(stderr,"Error: list_to_matrix() list is empty()\n");
+    return false;
+  }
+  // number of rows
+  int n = igl::min_size(V);
+  if(n != igl::max_size(V))
+  {
+    fprintf(stderr,"Error: list_to_matrix()"
+      " list elements are not all the same size\n");
+    return false;
+  }
+  assert(n != -1);
+  // Resize output
+  M.resize(m,n);
+
+  // Loop over rows
+  int i = 0;
+  typename std::vector<Row>::const_iterator iter = V.begin();
+  while(iter != V.end())
+  {
+    M.row(i) = V[i];
+    // increment index and iterator
+    i++;
+    iter++;
+  }
+
+  return true;
+}
+#endif