1 // This file is part of libigl, a simple c++ geometry processing library.
2 //
3 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public License
6 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
7 // obtain one at http://mozilla.org/MPL/2.0/.
8 #include "readNODE.h"
9 #include "matrix_to_list.h"
10 #include <stdio.h>
11 
12 template <typename Scalar, typename Index>
readNODE(const std::string node_file_name,std::vector<std::vector<Scalar>> & V,std::vector<std::vector<Index>> & I)13 IGL_INLINE bool igl::readNODE(
14   const std::string node_file_name,
15   std::vector<std::vector<Scalar > > & V,
16   std::vector<std::vector<Index > > & I)
17 {
18   // TODO: should be templated
19   Eigen::MatrixXd mV;
20   Eigen::MatrixXi mI;
21   if(igl::readNODE(node_file_name,mV,mI))
22   {
23     matrix_to_list(mV,V);
24     matrix_to_list(mI,I);
25     return true;
26   }else
27   {
28     return false;
29   }
30 }
31 
32 template <typename DerivedV, typename DerivedI>
readNODE(const std::string node_file_name,Eigen::PlainObjectBase<DerivedV> & V,Eigen::PlainObjectBase<DerivedI> & I)33 IGL_INLINE bool igl::readNODE(
34   const std::string node_file_name,
35   Eigen::PlainObjectBase<DerivedV>& V,
36   Eigen::PlainObjectBase<DerivedI>& I)
37 {
38   using namespace std;
39   FILE * node_file = fopen(node_file_name.c_str(),"r");
40   if(NULL==node_file)
41   {
42     fprintf(stderr,"readNODE: IOError: %s could not be opened...\n",
43       node_file_name.c_str());
44     return false;
45   }
46 #ifndef LINE_MAX
47 #  define LINE_MAX 2048
48 #endif
49   char line[LINE_MAX];
50   bool still_comments;
51 
52   // eat comments at beginning of file
53   still_comments= true;
54   while(still_comments)
55   {
56     fgets(line,LINE_MAX,node_file);
57     still_comments = (line[0] == '#' || line[0] == '\n');
58   }
59 
60   // Read header
61   // n  number of points
62   // dim  dimension
63   // num_attr  number of attributes
64   // num_bm  number of boundary markers
65   int n,dim,num_attr,num_bm;
66   int head_count = sscanf(line,"%d %d %d %d", &n, &dim, &num_attr, &num_bm);
67   if(head_count!=4)
68   {
69     fprintf(stderr,"readNODE: Error: incorrect header in %s...\n",
70       node_file_name.c_str());
71     fclose(node_file);
72     return false;
73   }
74   if(num_attr)
75   {
76     fprintf(stderr,"readNODE: Error: %d attributes found in %s. "
77       "Attributes are not supported...\n",
78       num_attr,
79       node_file_name.c_str());
80     fclose(node_file);
81     return false;
82   }
83   // Just quietly ignore boundary markers
84   //if(num_bm)
85   //{
86   //  fprintf(stderr,"readNODE: Warning: %d boundary markers found in %s. "
87   //    "Boundary markers are ignored...\n",
88   //    num_bm,
89   //    node_file_name.c_str());
90   //}
91 
92   // resize output
93   V.resize(n,dim);
94   I.resize(n,1);
95 
96   int line_no = 0;
97   int p = 0;
98   while (fgets(line, LINE_MAX, node_file) != NULL)
99   {
100     line_no++;
101     // Skip comments and blank lines
102     if(line[0] == '#' || line[0] == '\n')
103     {
104       continue;
105     }
106     char * l = line;
107     int offset;
108 
109     if(sscanf(l,"%d%n",&I(p),&offset) != 1)
110     {
111       fprintf(stderr,"readNODE Error: bad index (%d) in %s...\n",
112         line_no,
113         node_file_name.c_str());
114       fclose(node_file);
115       return false;
116     }
117     // adjust offset
118     l += offset;
119 
120     // Read coordinates
121     for(int d = 0;d<dim;d++)
122     {
123       if(sscanf(l,"%lf%n",&V(p,d),&offset) != 1)
124       {
125         fprintf(stderr,"readNODE Error: bad coordinates (%d) in %s...\n",
126           line_no,
127           node_file_name.c_str());
128         fclose(node_file);
129         return false;
130       }
131       // adjust offset
132       l += offset;
133     }
134     // Read boundary markers
135     for(int b = 0;b<num_bm;b++)
136     {
137       int dummy;
138       if(sscanf(l,"%d%n",&dummy,&offset) != 1)
139       {
140         fprintf(stderr,"readNODE Error: bad boundary markers (%d) in %s...\n",
141           line_no,
142           node_file_name.c_str());
143         fclose(node_file);
144         return false;
145       }
146       // adjust offset
147       l += offset;
148     }
149     p++;
150   }
151 
152   assert(p == V.rows());
153 
154   fclose(node_file);
155   return true;
156 }
157 
158 #ifdef IGL_STATIC_LIBRARY
159 // Explicit template instantiation
160 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> >&);
161 #endif
162