readMESH.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include "readMESH.h"
  2. #include <cstdio>
  3. #include "verbose.h"
  4. template <typename Scalar, typename Index>
  5. IGL_INLINE bool igl::readMESH(
  6. const std::string mesh_file_name,
  7. std::vector<std::vector<Scalar > > & V,
  8. std::vector<std::vector<Index > > & T,
  9. std::vector<std::vector<Index > > & F)
  10. {
  11. using namespace std;
  12. using namespace igl;
  13. FILE * mesh_file = fopen(mesh_file_name.c_str(),"r");
  14. if(NULL==mesh_file)
  15. {
  16. fprintf(stderr,"IOError: %s could not be opened...",mesh_file_name.c_str());
  17. return false;
  18. }
  19. #ifndef LINE_MAX
  20. # define LINE_MAX 2048
  21. #endif
  22. char line[LINE_MAX];
  23. bool still_comments;
  24. V.clear();
  25. T.clear();
  26. F.clear();
  27. // eat comments at beginning of file
  28. still_comments= true;
  29. while(still_comments)
  30. {
  31. fgets(line,LINE_MAX,mesh_file);
  32. still_comments = (line[0] == '#' || line[0] == '\n');
  33. }
  34. char str[LINE_MAX];
  35. sscanf(line," %s",str);
  36. // check that first word is MeshVersionFormatted
  37. if(0!=strcmp(str,"MeshVersionFormatted"))
  38. {
  39. fprintf(stderr,
  40. "Error: first word should be MeshVersionFormatted not %s\n",str);
  41. fclose(mesh_file);
  42. return false;
  43. }
  44. int one = -1;
  45. if(2 != sscanf(line,"%s %d",str,&one))
  46. {
  47. // 1 appears on next line?
  48. fscanf(mesh_file," %d",&one);
  49. }
  50. if(one != 1)
  51. {
  52. fprintf(stderr,"Error: second word should be 1 not %d\n",one);
  53. fclose(mesh_file);
  54. return false;
  55. }
  56. // eat comments
  57. still_comments= true;
  58. while(still_comments)
  59. {
  60. fgets(line,LINE_MAX,mesh_file);
  61. still_comments = (line[0] == '#' || line[0] == '\n');
  62. }
  63. sscanf(line," %s",str);
  64. // check that third word is Dimension
  65. if(0!=strcmp(str,"Dimension"))
  66. {
  67. fprintf(stderr,"Error: third word should be Dimension not %s\n",str);
  68. fclose(mesh_file);
  69. return false;
  70. }
  71. int three = -1;
  72. if(2 != sscanf(line,"%s %d",str,&three))
  73. {
  74. // 1 appears on next line?
  75. fscanf(mesh_file," %d",&three);
  76. }
  77. if(three != 3)
  78. {
  79. fprintf(stderr,"Error: only Dimension 3 supported not %d\n",three);
  80. fclose(mesh_file);
  81. return false;
  82. }
  83. // eat comments
  84. still_comments= true;
  85. while(still_comments)
  86. {
  87. fgets(line,LINE_MAX,mesh_file);
  88. still_comments = (line[0] == '#' || line[0] == '\n');
  89. }
  90. sscanf(line," %s",str);
  91. // check that fifth word is Vertices
  92. if(0!=strcmp(str,"Vertices"))
  93. {
  94. fprintf(stderr,"Error: fifth word should be Vertices not %s\n",str);
  95. fclose(mesh_file);
  96. return false;
  97. }
  98. //fgets(line,LINE_MAX,mesh_file);
  99. #ifdef __APPLE__
  100. size_t number_of_vertices;
  101. #else
  102. int number_of_vertices;
  103. #endif
  104. if(1 != fscanf(mesh_file," %ld",&number_of_vertices) || number_of_vertices > 1000000000)
  105. {
  106. fprintf(stderr,"Error: expecting number of vertices less than 10^9...\n");
  107. fclose(mesh_file);
  108. return false;
  109. }
  110. // allocate space for vertices
  111. V.resize(number_of_vertices,vector<Scalar>(3,0));
  112. #ifdef __APPLE__
  113. size_t extra;
  114. #else
  115. int extra;
  116. #endif
  117. for(size_t i = 0;i<number_of_vertices;i++)
  118. {
  119. double x,y,z;
  120. if(4 != fscanf(mesh_file," %lg %lg %lg %ld",&x,&y,&z,&extra))
  121. {
  122. fprintf(stderr,"Error: expecting vertex position...\n");
  123. fclose(mesh_file);
  124. return false;
  125. }
  126. V[i][0] = x;
  127. V[i][1] = y;
  128. V[i][2] = z;
  129. }
  130. // eat comments
  131. still_comments= true;
  132. while(still_comments)
  133. {
  134. fgets(line,LINE_MAX,mesh_file);
  135. still_comments = (line[0] == '#' || line[0] == '\n');
  136. }
  137. sscanf(line," %s",str);
  138. // check that sixth word is Triangles
  139. if(0!=strcmp(str,"Triangles"))
  140. {
  141. fprintf(stderr,"Error: sixth word should be Triangles not %s\n",str);
  142. fclose(mesh_file);
  143. return false;
  144. }
  145. #ifdef __APPLE__
  146. size_t number_of_triangles;
  147. #else
  148. int number_of_triangles;
  149. #endif
  150. if(1 != fscanf(mesh_file," %ld",&number_of_triangles))
  151. {
  152. fprintf(stderr,"Error: expecting number of triangles...\n");
  153. fclose(mesh_file);
  154. return false;
  155. }
  156. // allocate space for triangles
  157. F.resize(number_of_triangles,vector<Index>(3));
  158. // triangle indices
  159. #ifdef __APPLE__
  160. size_t tri[3];
  161. #else
  162. int tri[3];
  163. #endif
  164. for(size_t i = 0;i<number_of_triangles;i++)
  165. {
  166. if(4 != fscanf(mesh_file," %ld %ld %ld %ld",&tri[0],&tri[1],&tri[2],&extra))
  167. {
  168. printf("Error: expecting triangle indices...\n");
  169. return false;
  170. }
  171. for(size_t j = 0;j<3;j++)
  172. {
  173. F[i][j] = tri[j]-1;
  174. }
  175. }
  176. // eat comments
  177. still_comments= true;
  178. while(still_comments)
  179. {
  180. fgets(line,LINE_MAX,mesh_file);
  181. still_comments = (line[0] == '#' || line[0] == '\n');
  182. }
  183. sscanf(line," %s",str);
  184. // check that sixth word is Triangles
  185. if(0!=strcmp(str,"Tetrahedra"))
  186. {
  187. fprintf(stderr,"Error: seventh word should be Tetrahedra not %s\n",str);
  188. fclose(mesh_file);
  189. return false;
  190. }
  191. #ifdef __APPLE__
  192. size_t number_of_tetrahedra;
  193. #else
  194. int number_of_tetrahedra;
  195. #endif
  196. if(1 != fscanf(mesh_file," %ld",&number_of_tetrahedra))
  197. {
  198. fprintf(stderr,"Error: expecting number of tetrahedra...\n");
  199. fclose(mesh_file);
  200. return false;
  201. }
  202. // allocate space for tetrahedra
  203. T.resize(number_of_tetrahedra,vector<Index>(4));
  204. // tet indices
  205. #ifdef __APPLE__
  206. size_t a,b,c,d;
  207. #else
  208. int a,b,c,d;
  209. #endif
  210. for(size_t i = 0;i<number_of_tetrahedra;i++)
  211. {
  212. if(5 != fscanf(mesh_file," %ld %ld %ld %ld %ld",&a,&b,&c,&d,&extra))
  213. {
  214. fprintf(stderr,"Error: expecting tetrahedra indices...\n");
  215. fclose(mesh_file);
  216. return false;
  217. }
  218. T[i][0] = a-1;
  219. T[i][1] = b-1;
  220. T[i][2] = c-1;
  221. T[i][3] = d-1;
  222. }
  223. fclose(mesh_file);
  224. return true;
  225. }
  226. #include <Eigen/Core>
  227. #include "list_to_matrix.h"
  228. template <typename DerivedV, typename DerivedF, typename DerivedT>
  229. IGL_INLINE bool igl::readMESH(
  230. const std::string str,
  231. Eigen::PlainObjectBase<DerivedV>& V,
  232. Eigen::PlainObjectBase<DerivedT>& T,
  233. Eigen::PlainObjectBase<DerivedF>& F)
  234. {
  235. std::vector<std::vector<double> > vV,vT,vF;
  236. bool success = igl::readMESH(str,vV,vT,vF);
  237. if(!success)
  238. {
  239. // readOBJ(str,vV,vTC,vN,vF,vFTC,vFN) should have already printed an error
  240. // message to stderr
  241. return false;
  242. }
  243. bool V_rect = igl::list_to_matrix(vV,V);
  244. if(!V_rect)
  245. {
  246. // igl::list_to_matrix(vV,V) already printed error message to std err
  247. return false;
  248. }
  249. bool T_rect = igl::list_to_matrix(vT,T);
  250. if(!T_rect)
  251. {
  252. // igl::list_to_matrix(vT,T) already printed error message to std err
  253. return false;
  254. }
  255. bool F_rect = igl::list_to_matrix(vF,F);
  256. if(!F_rect)
  257. {
  258. // igl::list_to_matrix(vF,F) already printed error message to std err
  259. return false;
  260. }
  261. assert(V.cols() == 3);
  262. assert(T.cols() == 4);
  263. assert(F.cols() == 3);
  264. return true;
  265. }
  266. #ifndef IGL_HEADER_ONLY
  267. // Explicit template specialization
  268. // generated by autoexplicit.sh
  269. 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> >&);
  270. #endif