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

readWRL and triangulate

Former-commit-id: 360e6a800f37d854cb9a9618979cc03b17244878
Alec Jacobson (jalec 11 жил өмнө
parent
commit
a1f4cee040

+ 97 - 0
include/igl/readWRL.cpp

@@ -0,0 +1,97 @@
+#include "readWRL.h"
+#include <cstdio>
+
+template <typename Scalar, typename Index>
+IGL_INLINE bool igl::readWRL(
+  const std::string wrl_file_name,
+  std::vector<std::vector<Scalar > > & V,
+  std::vector<std::vector<Index > > & F)
+{
+  using namespace std;
+  FILE * wrl_file = fopen(wrl_file_name.c_str(),"r");
+  if(NULL==wrl_file)
+  {
+    printf("IOError: %s could not be opened...",wrl_file_name.c_str());
+    return false;
+  }
+
+  V.clear();
+  F.clear();
+
+  char line[1000];
+  // Read lines until seeing "point ["
+  // treat other lines in file as "comments"
+  bool still_comments = true;
+  string needle("point [");
+  string haystack;
+  while(still_comments)
+  {
+    fgets(line,1000,wrl_file);
+    haystack = string(line);
+    still_comments = string::npos == haystack.find(needle);
+  }
+
+  // read points in sets of 3
+  int floats_read = 3;
+  double x,y,z;
+  while(floats_read == 3)
+  {
+    floats_read = fscanf(wrl_file," %lf %lf %lf,",&x,&y,&z);
+    if(floats_read == 3)
+    {
+      vector<Scalar > point;
+      point.resize(3);
+      point[0] = x;
+      point[1] = y;
+      point[2] = z;
+      V.push_back(point);
+      //printf("(%g, %g, %g)\n",x,y,z);
+    }else if(floats_read != 0)
+    {
+      printf("ERROR: unrecognized format...\n");
+      return false;
+    }
+  }
+  // Read lines until seeing "coordIndex ["
+  // treat other lines in file as "comments"
+  still_comments = true;
+  needle = string("coordIndex [");
+  while(still_comments)
+  {
+    fgets(line,1000,wrl_file);
+    haystack = string(line);
+    still_comments = string::npos == haystack.find(needle);
+  }
+  // read F
+  int ints_read = 1;
+  while(ints_read > 0)
+  {
+    // read new face indices (until hit -1)
+    vector<Index > face;
+    while(true)
+    {
+      // indices are 0-indexed
+      int i;
+      ints_read = fscanf(wrl_file," %d,",&i);
+      if(ints_read > 0)
+      {
+        if(i>=0)
+        {
+          face.push_back(i);
+        }else
+        {
+          F.push_back(face);
+          break;
+        }
+      }else
+      {
+        break;
+      }
+    }
+  }
+
+
+
+  fclose(wrl_file);
+  return true;
+}

+ 36 - 0
include/igl/readWRL.h

@@ -0,0 +1,36 @@
+#ifndef IGL_READWRL_H
+#define IGL_READWRL_H
+#include "igl_inline.h"
+
+#include <string>
+#include <vector>
+
+namespace igl 
+{
+  // Read a mesh from an ascii wrl file, filling in vertex positions and face
+  // indices of the first model. Mesh may have faces of any number of degree
+  //
+  // Templates:
+  //   Scalar  type for positions and vectors (will be read as double and cast
+  //     to Scalar)
+  //   Index  type for indices (will be read as int and cast to Index)
+  // Inputs:
+  //  str  path to .wrl file
+  // Outputs:
+  //   V  double matrix of vertex positions  #V by 3
+  //   F  #F list of face indices into vertex positions
+  // Returns true on success, false on errors
+  template <typename Scalar, typename Index>
+  IGL_INLINE bool readWRL(
+    const std::string wrl_file_name, 
+    std::vector<std::vector<Scalar > > & V,
+    std::vector<std::vector<Index > > & F);
+
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "readWRL.cpp"
+#endif
+
+#endif
+

+ 53 - 0
include/igl/triangulate.cpp

@@ -0,0 +1,53 @@
+#include "triangulate.h"
+
+template <typename Index, typename DerivedF>
+IGL_INLINE void igl::triangulate(
+  const std::vector<std::vector<Index> > & vF,
+  Eigen::PlainObjectBase<DerivedF>& F)
+{
+  using namespace std;
+  using namespace Eigen;
+  int m = 0;
+  // estimate of size
+  for(typename vector<vector<Index > >::const_iterator fit = vF.begin();
+    fit!=vF.end();
+    fit++)
+  {
+    if(fit->size() >= 3)
+    {
+      m += fit->size() - 2;
+    }
+  }
+  // Resize output
+  F.resize(m,3);
+  {
+    int k = 0;
+    for(typename vector<vector<Index > >::const_iterator fit = vF.begin();
+      fit!=vF.end();
+      fit++)
+    {
+      if(fit->size() >= 3)
+      {
+        typename vector<Index >::const_iterator cit = fit->begin();
+        cit++;
+        typename vector<Index >::const_iterator pit = cit++;
+        for(;
+          cit!=fit->end();
+          cit++,pit++)
+        {
+          F(k,0) = *(fit->begin());
+          F(k,1) = *pit;
+          F(k,2) = *cit;
+          k++;
+        }
+      }
+    }
+    assert(k==m);
+  }
+
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit template instanciation
+template void igl::triangulate<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

+ 38 - 0
include/igl/triangulate.h

@@ -0,0 +1,38 @@
+#ifndef IGL_TRIANGULATE_H
+#define IGL_TRIANGULATE_H
+#include "igl_inline.h"
+
+#ifndef IGL_NO_EIGEN
+#  include <Eigen/Core>
+#endif
+#include <vector>
+
+namespace igl 
+{
+  // Triangulate a general polygonal mesh into a triangle mesh.
+  //
+  // Inputs:
+  //   vF  list of polygon index lists
+  // Outputs:
+  //   F  eigen int matrix #F by 3
+  //
+  // Example:
+  //   vector<vector<double > > vV;
+  //   vector<vector<int > > vF;
+  //   read("poly.obj",vV,vF);
+  //   MatrixXd V;
+  //   MatrixXi F;
+  //   list_to_matrix(vV,V);
+  //   triangulate(vF,F);
+  template <typename Index, typename DerivedF>
+  IGL_INLINE void triangulate(
+    const std::vector<std::vector<Index> > & vF,
+    Eigen::PlainObjectBase<DerivedF>& F);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "triangulate.cpp"
+#endif
+
+#endif
+