readMESH.h 7.5 KB

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