readMESH.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. int number_of_vertices;
  100. if(1 != fscanf(mesh_file," %d",&number_of_vertices) || number_of_vertices > 1000000000)
  101. {
  102. fprintf(stderr,"Error: expecting number of vertices less than 10^9...\n");
  103. fclose(mesh_file);
  104. return false;
  105. }
  106. // allocate space for vertices
  107. V.resize(number_of_vertices,vector<Scalar>(3,0));
  108. int extra;
  109. for(int i = 0;i<number_of_vertices;i++)
  110. {
  111. double x,y,z;
  112. if(4 != fscanf(mesh_file," %lg %lg %lg %d",&x,&y,&z,&extra))
  113. {
  114. fprintf(stderr,"Error: expecting vertex position...\n");
  115. fclose(mesh_file);
  116. return false;
  117. }
  118. V[i][0] = x;
  119. V[i][1] = y;
  120. V[i][2] = z;
  121. }
  122. // eat comments
  123. still_comments= true;
  124. while(still_comments)
  125. {
  126. fgets(line,LINE_MAX,mesh_file);
  127. still_comments = (line[0] == '#' || line[0] == '\n');
  128. }
  129. sscanf(line," %s",str);
  130. // check that sixth word is Triangles
  131. if(0!=strcmp(str,"Triangles"))
  132. {
  133. fprintf(stderr,"Error: sixth word should be Triangles not %s\n",str);
  134. fclose(mesh_file);
  135. return false;
  136. }
  137. int number_of_triangles;
  138. if(1 != fscanf(mesh_file," %d",&number_of_triangles))
  139. {
  140. fprintf(stderr,"Error: expecting number of triangles...\n");
  141. fclose(mesh_file);
  142. return false;
  143. }
  144. // allocate space for triangles
  145. F.resize(number_of_triangles,vector<Index>(3));
  146. // triangle indices
  147. int tri[3];
  148. for(int i = 0;i<number_of_triangles;i++)
  149. {
  150. if(4 != fscanf(mesh_file," %d %d %d %d",&tri[0],&tri[1],&tri[2],&extra))
  151. {
  152. printf("Error: expecting triangle indices...\n");
  153. return false;
  154. }
  155. for(int j = 0;j<3;j++)
  156. {
  157. F[i][j] = tri[j]-1;
  158. }
  159. }
  160. // eat comments
  161. still_comments= true;
  162. while(still_comments)
  163. {
  164. fgets(line,LINE_MAX,mesh_file);
  165. still_comments = (line[0] == '#' || line[0] == '\n');
  166. }
  167. sscanf(line," %s",str);
  168. // check that sixth word is Triangles
  169. if(0!=strcmp(str,"Tetrahedra"))
  170. {
  171. fprintf(stderr,"Error: seventh word should be Tetrahedra not %s\n",str);
  172. fclose(mesh_file);
  173. return false;
  174. }
  175. int number_of_tetrahedra;
  176. if(1 != fscanf(mesh_file," %d",&number_of_tetrahedra))
  177. {
  178. fprintf(stderr,"Error: expecting number of tetrahedra...\n");
  179. fclose(mesh_file);
  180. return false;
  181. }
  182. // allocate space for tetrahedra
  183. T.resize(number_of_tetrahedra,vector<Index>(4));
  184. // tet indices
  185. int a,b,c,d;
  186. for(int i = 0;i<number_of_tetrahedra;i++)
  187. {
  188. if(5 != fscanf(mesh_file," %d %d %d %d %d",&a,&b,&c,&d,&extra))
  189. {
  190. fprintf(stderr,"Error: expecting tetrahedra indices...\n");
  191. fclose(mesh_file);
  192. return false;
  193. }
  194. T[i][0] = a-1;
  195. T[i][1] = b-1;
  196. T[i][2] = c-1;
  197. T[i][3] = d-1;
  198. }
  199. fclose(mesh_file);
  200. return true;
  201. }
  202. #include <Eigen/Core>
  203. #include "list_to_matrix.h"
  204. template <typename DerivedV, typename DerivedF, typename DerivedT>
  205. IGL_INLINE bool igl::readMESH(
  206. const std::string mesh_file_name,
  207. Eigen::PlainObjectBase<DerivedV>& V,
  208. Eigen::PlainObjectBase<DerivedT>& T,
  209. Eigen::PlainObjectBase<DerivedF>& F)
  210. {
  211. using namespace std;
  212. using namespace igl;
  213. FILE * mesh_file = fopen(mesh_file_name.c_str(),"r");
  214. if(NULL==mesh_file)
  215. {
  216. fprintf(stderr,"IOError: %s could not be opened...",mesh_file_name.c_str());
  217. return false;
  218. }
  219. #ifndef LINE_MAX
  220. # define LINE_MAX 2048
  221. #endif
  222. char line[LINE_MAX];
  223. bool still_comments;
  224. // eat comments at beginning of file
  225. still_comments= true;
  226. while(still_comments)
  227. {
  228. fgets(line,LINE_MAX,mesh_file);
  229. still_comments = (line[0] == '#' || line[0] == '\n');
  230. }
  231. char str[LINE_MAX];
  232. sscanf(line," %s",str);
  233. // check that first word is MeshVersionFormatted
  234. if(0!=strcmp(str,"MeshVersionFormatted"))
  235. {
  236. fprintf(stderr,
  237. "Error: first word should be MeshVersionFormatted not %s\n",str);
  238. fclose(mesh_file);
  239. return false;
  240. }
  241. int one = -1;
  242. if(2 != sscanf(line,"%s %d",str,&one))
  243. {
  244. // 1 appears on next line?
  245. fscanf(mesh_file," %d",&one);
  246. }
  247. if(one != 1)
  248. {
  249. fprintf(stderr,"Error: second word should be 1 not %d\n",one);
  250. fclose(mesh_file);
  251. return false;
  252. }
  253. // eat comments
  254. still_comments= true;
  255. while(still_comments)
  256. {
  257. fgets(line,LINE_MAX,mesh_file);
  258. still_comments = (line[0] == '#' || line[0] == '\n');
  259. }
  260. sscanf(line," %s",str);
  261. // check that third word is Dimension
  262. if(0!=strcmp(str,"Dimension"))
  263. {
  264. fprintf(stderr,"Error: third word should be Dimension not %s\n",str);
  265. fclose(mesh_file);
  266. return false;
  267. }
  268. int three = -1;
  269. if(2 != sscanf(line,"%s %d",str,&three))
  270. {
  271. // 1 appears on next line?
  272. fscanf(mesh_file," %d",&three);
  273. }
  274. if(three != 3)
  275. {
  276. fprintf(stderr,"Error: only Dimension 3 supported not %d\n",three);
  277. fclose(mesh_file);
  278. return false;
  279. }
  280. // eat comments
  281. still_comments= true;
  282. while(still_comments)
  283. {
  284. fgets(line,LINE_MAX,mesh_file);
  285. still_comments = (line[0] == '#' || line[0] == '\n');
  286. }
  287. sscanf(line," %s",str);
  288. // check that fifth word is Vertices
  289. if(0!=strcmp(str,"Vertices"))
  290. {
  291. fprintf(stderr,"Error: fifth word should be Vertices not %s\n",str);
  292. fclose(mesh_file);
  293. return false;
  294. }
  295. //fgets(line,LINE_MAX,mesh_file);
  296. int number_of_vertices;
  297. if(1 != fscanf(mesh_file," %d",&number_of_vertices) || number_of_vertices > 1000000000)
  298. {
  299. fprintf(stderr,"Error: expecting number of vertices less than 10^9...\n");
  300. fclose(mesh_file);
  301. return false;
  302. }
  303. // allocate space for vertices
  304. V.resize(number_of_vertices,3);
  305. int extra;
  306. for(int i = 0;i<number_of_vertices;i++)
  307. {
  308. double x,y,z;
  309. if(4 != fscanf(mesh_file," %lg %lg %lg %d",&x,&y,&z,&extra))
  310. {
  311. fprintf(stderr,"Error: expecting vertex position...\n");
  312. fclose(mesh_file);
  313. return false;
  314. }
  315. V(i,0) = x;
  316. V(i,1) = y;
  317. V(i,2) = z;
  318. }
  319. // eat comments
  320. still_comments= true;
  321. while(still_comments)
  322. {
  323. fgets(line,LINE_MAX,mesh_file);
  324. still_comments = (line[0] == '#' || line[0] == '\n');
  325. }
  326. sscanf(line," %s",str);
  327. // check that sixth word is Triangles
  328. if(0!=strcmp(str,"Triangles"))
  329. {
  330. fprintf(stderr,"Error: sixth word should be Triangles not %s\n",str);
  331. fclose(mesh_file);
  332. return false;
  333. }
  334. int number_of_triangles;
  335. if(1 != fscanf(mesh_file," %d",&number_of_triangles))
  336. {
  337. fprintf(stderr,"Error: expecting number of triangles...\n");
  338. fclose(mesh_file);
  339. return false;
  340. }
  341. // allocate space for triangles
  342. F.resize(number_of_triangles,3);
  343. // triangle indices
  344. int tri[3];
  345. for(int i = 0;i<number_of_triangles;i++)
  346. {
  347. if(4 != fscanf(mesh_file," %d %d %d %d",&tri[0],&tri[1],&tri[2],&extra))
  348. {
  349. printf("Error: expecting triangle indices...\n");
  350. return false;
  351. }
  352. for(int j = 0;j<3;j++)
  353. {
  354. F(i,j) = tri[j]-1;
  355. }
  356. }
  357. // eat comments
  358. still_comments= true;
  359. while(still_comments)
  360. {
  361. fgets(line,LINE_MAX,mesh_file);
  362. still_comments = (line[0] == '#' || line[0] == '\n');
  363. }
  364. sscanf(line," %s",str);
  365. // check that sixth word is Triangles
  366. if(0!=strcmp(str,"Tetrahedra"))
  367. {
  368. fprintf(stderr,"Error: seventh word should be Tetrahedra not %s\n",str);
  369. fclose(mesh_file);
  370. return false;
  371. }
  372. int number_of_tetrahedra;
  373. if(1 != fscanf(mesh_file," %d",&number_of_tetrahedra))
  374. {
  375. fprintf(stderr,"Error: expecting number of tetrahedra...\n");
  376. fclose(mesh_file);
  377. return false;
  378. }
  379. // allocate space for tetrahedra
  380. T.resize(number_of_tetrahedra,4);
  381. // tet indices
  382. int a,b,c,d;
  383. for(int i = 0;i<number_of_tetrahedra;i++)
  384. {
  385. if(5 != fscanf(mesh_file," %d %d %d %d %d",&a,&b,&c,&d,&extra))
  386. {
  387. fprintf(stderr,"Error: expecting tetrahedra indices...\n");
  388. fclose(mesh_file);
  389. return false;
  390. }
  391. T(i,0) = a-1;
  392. T(i,1) = b-1;
  393. T(i,2) = c-1;
  394. T(i,3) = d-1;
  395. }
  396. fclose(mesh_file);
  397. return true;
  398. }
  399. //{
  400. // std::vector<std::vector<double> > vV,vT,vF;
  401. // bool success = igl::readMESH(mesh_file_name,vV,vT,vF);
  402. // if(!success)
  403. // {
  404. // // readMESH already printed error message to std err
  405. // return false;
  406. // }
  407. // bool V_rect = igl::list_to_matrix(vV,V);
  408. // if(!V_rect)
  409. // {
  410. // // igl::list_to_matrix(vV,V) already printed error message to std err
  411. // return false;
  412. // }
  413. // bool T_rect = igl::list_to_matrix(vT,T);
  414. // if(!T_rect)
  415. // {
  416. // // igl::list_to_matrix(vT,T) already printed error message to std err
  417. // return false;
  418. // }
  419. // bool F_rect = igl::list_to_matrix(vF,F);
  420. // if(!F_rect)
  421. // {
  422. // // igl::list_to_matrix(vF,F) already printed error message to std err
  423. // return false;
  424. // }
  425. // assert(V.cols() == 3);
  426. // assert(T.cols() == 4);
  427. // assert(F.cols() == 3);
  428. // return true;
  429. //}
  430. #ifndef IGL_HEADER_ONLY
  431. // Explicit template specialization
  432. // generated by autoexplicit.sh
  433. 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> >&);
  434. #endif