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

btter file formats, readNODE

Former-commit-id: 3ab67463bd681302a27e380b7255821b6d5f0946
Alec Jacobson (jalec 12 жил өмнө
parent
commit
dc620a9324

+ 19 - 3
file-formats/index.html

@@ -15,9 +15,25 @@
     <li><a href="http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf#page=33">.mesh</a> Medit's triangle surface mesh + tetrahedral volume mesh file format, see page 33, section 7.2.1</li>
     <li><i>.poly</i> Piecewise-linear complex. This format comes in many similar but importantly different flavors: 
       <a href="https://www.cs.cmu.edu/~quake/triangle.poly.html">triangle's</a>, <a href="http://tetgen.berlios.de/fformats.poly.html">tetgen's</a>, <a href="http://sparse-meshing.com/svr/0.2.1/format-poly.html">pyramid/SVR's</a></li>
-    <li><a href=? class=missing>.node</a></li>
-    <li><a href=? class=missing>.ele</a></li>
-    <li><a href=? class=missing>.face</a></li>
+    <li><i>.node</i> List of points (vertices). Described indentically (upto
+        accepted dimensions, use of attributes and boundary markers) by <a
+    href="https://www.cs.cmu.edu/~quake/triangle.node.html">Triangle</a>, <a
+    href=http://tetgen.berlios.de/fformats.node.html>TetGen</a>, and <a
+    href=http://www.cs.berkeley.edu/~jrs/stellar/#fileformats>Stellar</a>.
+    </li>
+    <li><i>.ele</i> Element (triangle or tet) list. This format comes in similar flavors: <a
+    href=http://tetgen.berlios.de/fformats.ele.html>tetgen's</a>, <a
+    href=http://www.cs.berkeley.edu/~jrs/stellar/#fileformats>stellar's</a>,
+    and <a href=https://www.cs.cmu.edu/~quake/triangle.ele.html>triangle's</a>.
+    The formats of TetGen and stellar are identical upto conventions on index
+    ordering and number of allowed attributes (unverified).</li>
+    <li><a href=http://tetgen.berlios.de/fformats.face.html class=missing>.face</a> TetGen's file format for simplicial facets.</li>
+    <li><a href=http://en.wikipedia.org/wiki/Truevision_TGA>.tga</a> Truevision TGA or TARGA image file format. IGLLIB supports only very basic reading and writing RGB/RGBA files without colormaps and (unverified) run-length compression.</li>
+    <li><a
+    href=https://en.wikipedia.org/wiki/Portable_Network_Graphics>.png</a>
+    Portable Network Graphics image file. IGLLIB (in the libiglpng extra)
+  supports png image files via the <a href=https://github.com/yig/yimg>yimg</a>
+  library. Alpha channels and compression are suppported.</li>
   </ul>
   </body>
 </html>

+ 3 - 4
include/igl/readMESH.cpp

@@ -220,17 +220,16 @@ IGL_INLINE bool igl::readMESH(
 
 template <typename DerivedV, typename DerivedF, typename DerivedT>
 IGL_INLINE bool igl::readMESH(
-  const std::string str,
+  const std::string mesh_file_name,
   Eigen::PlainObjectBase<DerivedV>& V,
   Eigen::PlainObjectBase<DerivedT>& T,
   Eigen::PlainObjectBase<DerivedF>& F)
 {
   std::vector<std::vector<double> > vV,vT,vF;
-  bool success = igl::readMESH(str,vV,vT,vF);
+  bool success = igl::readMESH(mesh_file_name,vV,vT,vF);
   if(!success)
   {
-    // readOBJ(str,vV,vTC,vN,vF,vFTC,vFN) should have already printed an error
-    // message to stderr
+    // readMESH already printed error message to std err
     return false;
   }
   bool V_rect = igl::list_to_matrix(vV,V);

+ 1 - 1
include/igl/readMESH.h

@@ -35,7 +35,7 @@ namespace igl
   //   F  eigen int matrix #F by 3
   template <typename DerivedV, typename DerivedF, typename DerivedT>
   IGL_INLINE bool readMESH(
-    const std::string str,
+    const std::string mesh_file_name,
     Eigen::PlainObjectBase<DerivedV>& V,
     Eigen::PlainObjectBase<DerivedT>& T,
     Eigen::PlainObjectBase<DerivedF>& F);

+ 155 - 0
include/igl/readNODE.cpp

@@ -0,0 +1,155 @@
+#include "readNODE.h"
+#include "matrix_to_list.h"
+#include <iostream>
+
+template <typename Scalar, typename Index>
+IGL_INLINE bool readNODE(
+  const std::string node_file_name,
+  std::vector<std::vector<Scalar > > & V,
+  std::vector<std::vector<Index > > & I)
+{
+  // TODO: should be templated
+  Eigen::MatrixXd mV;
+  Eigen::MatrixXi mI;
+  if(igl::readNODE(node_file_name,mV,mI))
+  {
+    matrix_to_list(mV,V);
+    matrix_to_list(mI,I);
+    return true;
+  }else
+  {
+    return false;
+  }
+}
+
+template <typename DerivedV, typename DerivedI>
+IGL_INLINE bool igl::readNODE(
+  const std::string node_file_name,
+  Eigen::PlainObjectBase<DerivedV>& V,
+  Eigen::PlainObjectBase<DerivedI>& I)
+{
+  using namespace std;
+  using namespace igl;
+  FILE * node_file = fopen(node_file_name.c_str(),"r");
+  if(NULL==node_file)
+  {
+    fprintf(stderr,"readNODE: IOError: %s could not be opened...\n",
+      node_file_name.c_str());
+    return false;
+  }
+#ifndef LINE_MAX
+#  define LINE_MAX 2048
+#endif
+  char line[LINE_MAX];
+  bool still_comments;
+
+  // eat comments at beginning of file
+  still_comments= true;
+  while(still_comments)
+  {
+    fgets(line,LINE_MAX,node_file);
+    still_comments = (line[0] == '#' || line[0] == '\n');
+  }
+
+  // Read header
+  // n  number of points
+  // dim  dimension
+  // num_attr  number of attributes
+  // num_bm  number of boundary markers
+  int n,dim,num_attr,num_bm;
+  int head_count = sscanf(line,"%d %d %d %d", &n, &dim, &num_attr, &num_bm);
+  if(head_count!=4)
+  {
+    fprintf(stderr,"readNODE: Error: incorrect header in %s...\n",
+      node_file_name.c_str());
+    fclose(node_file);
+    return false;
+  }
+  if(num_attr)
+  {
+    fprintf(stderr,"readNODE: Error: %d attributes found in %s. "
+      "Attributes are not supported...\n",
+      num_attr,
+      node_file_name.c_str());
+    fclose(node_file);
+    return false;
+  }
+  // Just quietly ignore boundary markers
+  //if(num_bm)
+  //{
+  //  fprintf(stderr,"readNODE: Warning: %d boundary markers found in %s. "
+  //    "Boundary markers are ignored...\n",
+  //    num_bm,
+  //    node_file_name.c_str());
+  //}
+
+  // resize output
+  V.resize(n,dim);
+  I.resize(n,1);
+
+  int line_no = 0;
+  int p = 0;
+  while (fgets(line, LINE_MAX, node_file) != NULL) 
+  {
+    line_no++;
+    // Skip comments and blank lines
+    if(line[0] == '#' || line[0] == '\n')
+    {
+      continue;
+    }
+    char * l = line;
+    int offset;
+
+    if(sscanf(l,"%d%n",&I(p),&offset) != 1)
+    {
+      fprintf(stderr,"readNODE Error: bad index (%d) in %s...\n",
+        line_no,
+        node_file_name.c_str());
+      fclose(node_file);
+      return false;
+    }
+    // adjust offset
+    l += offset;
+
+    // Read coordinates
+    for(int d = 0;d<dim;d++)
+    {
+      if(sscanf(l,"%lf%n",&V(p,d),&offset) != 1)
+      {
+        fprintf(stderr,"readNODE Error: bad coordinates (%d) in %s...\n",
+          line_no,
+          node_file_name.c_str());
+        fclose(node_file);
+        return false;
+      }
+      // adjust offset
+      l += offset;
+    }
+    // Read boundary markers
+    for(int b = 0;b<num_bm;b++)
+    {
+      int dummy;
+      if(sscanf(l,"%d%n",&dummy,&offset) != 1)
+      {
+        fprintf(stderr,"readNODE Error: bad boundary markers (%d) in %s...\n",
+          line_no,
+          node_file_name.c_str());
+        fclose(node_file);
+        return false;
+      }
+      // adjust offset
+      l += offset;
+    }
+    p++;
+  }
+
+  assert(p == V.rows());
+
+  fclose(node_file);
+  return true;
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit template specialization
+template bool igl::readNODE<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> >&);
+#endif

+ 43 - 0
include/igl/readNODE.h

@@ -0,0 +1,43 @@
+#ifndef IGL_READNODE_H
+#define IGL_READNODE_H
+#include "igl_inline.h"
+
+#include <string>
+#include <vector>
+#include <Eigen/Core>
+
+namespace igl
+{
+  // load a list of points from a .node file
+  //
+  // 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)
+  // Input:
+  //   node_file_name  path of .node file
+  // Outputs:
+  //   V  double matrix of vertex positions  #V by dim
+  //   I  list of indices (first tells whether 0 or 1 indexed)
+  template <typename Scalar, typename Index>
+  IGL_INLINE bool readNODE(
+    const std::string node_file_name,
+    std::vector<std::vector<Scalar > > & V,
+    std::vector<std::vector<Index > > & I);
+
+  // Input:
+  //   node_file_name  path of .node file
+  // Outputs:
+  //   V  eigen double matrix #V by dim
+  template <typename DerivedV, typename DerivedI>
+  IGL_INLINE bool readNODE(
+    const std::string node_file_name,
+    Eigen::PlainObjectBase<DerivedV>& V,
+    Eigen::PlainObjectBase<DerivedI>& I);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "readNODE.cpp"
+#endif
+
+#endif

+ 6 - 5
include/igl/removeUnreferenced.cpp

@@ -2,11 +2,11 @@
 
 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)
+  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
@@ -46,6 +46,7 @@ IGL_INLINE void igl::removeUnreferenced(
   
   // Apply I on F
       
+  // Why is this also removing combinatorially degenerate faces?
   count = 0;
   for (int i =0; i<F.rows(); ++i)
   {

+ 8 - 6
include/igl/removeUnreferenced.h

@@ -19,14 +19,16 @@ namespace igl
   //
   // Output:
   // NV, NF: new mesh without unreferenced vertices
-  
+  //
+  // Known bugs:
+  //   Also removes combinatorially degenerate faces in NF
   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);
+    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);
   
 }
 

+ 1 - 0
todos.txt

@@ -12,3 +12,4 @@
 - clean up mvc.h
 - clean up orth.h
 - fix bugs in examples/Core/example2.cpp
+- replace generic names read.h/write.h with something like read_poly_mesh.h