readOFF.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "readOFF.h"
  2. template <typename Scalar, typename Index>
  3. IGL_INLINE bool igl::readOFF(
  4. const std::string off_file_name,
  5. std::vector<std::vector<Scalar > > & V,
  6. std::vector<std::vector<Index > > & F)
  7. {
  8. FILE * off_file = fopen(off_file_name.c_str(),"r");
  9. if(NULL==off_file)
  10. {
  11. printf("IOError: %s could not be opened...",off_file_name.c_str());
  12. return false;
  13. }
  14. V.clear();
  15. F.clear();
  16. // First line is always OFF
  17. char header[1000];
  18. const std::string OFF("OFF");
  19. const std::string NOFF("NOFF");
  20. if(!fscanf(off_file,"%s\n",header)==1
  21. || !(OFF == header || NOFF == header))
  22. {
  23. printf("Error: %s's first line should be OFF or NOFF not %s...",off_file_name.c_str(),header);
  24. fclose(off_file);
  25. return false;
  26. }
  27. bool has_normals = NOFF==header;
  28. // Second line is #vertices #faces #edges
  29. int number_of_vertices;
  30. int number_of_faces;
  31. int number_of_edges;
  32. char tic_tac_toe;
  33. char line[1000];
  34. bool still_comments = true;
  35. while(still_comments)
  36. {
  37. fgets(line,1000,off_file);
  38. still_comments = line[0] == '#';
  39. }
  40. sscanf(line,"%d %d %d",&number_of_vertices,&number_of_faces,&number_of_edges);
  41. V.resize(number_of_vertices);
  42. F.resize(number_of_faces);
  43. //printf("%s %d %d %d\n",(has_normals ? "NOFF" : "OFF"),number_of_vertices,number_of_faces,number_of_edges);
  44. // Read vertices
  45. for(int i = 0;i<number_of_vertices;)
  46. {
  47. float x,y,z,nx,ny,nz;
  48. if((has_normals && fscanf(off_file, "%g %g %g %g %g %g\n",&x,&y,&z,&nx,&ny,&nz)==6) ||
  49. (!has_normals && fscanf(off_file, "%g %g %g\n",&x,&y,&z)==3))
  50. {
  51. std::vector<Scalar > vertex;
  52. vertex.resize(3);
  53. vertex[0] = x;
  54. vertex[1] = y;
  55. vertex[2] = z;
  56. V[i] = vertex;
  57. i++;
  58. }else if(
  59. fscanf(off_file,"%[#]",&tic_tac_toe)==1)
  60. {
  61. char comment[1000];
  62. fscanf(off_file,"%[^\n]",comment);
  63. }else
  64. {
  65. printf("Error: bad line in %s\n",off_file_name.c_str());
  66. fclose(off_file);
  67. return false;
  68. }
  69. }
  70. // Read faces
  71. for(int i = 0;i<number_of_faces;)
  72. {
  73. std::vector<Index > face;
  74. int valence;
  75. if(fscanf(off_file,"%d",&valence)==1)
  76. {
  77. face.resize(valence);
  78. for(int j = 0;j<valence;j++)
  79. {
  80. int index;
  81. if(j<valence-1)
  82. {
  83. fscanf(off_file,"%d",&index);
  84. }else{
  85. fscanf(off_file,"%d%*[^\n]",&index);
  86. }
  87. face[j] = index;
  88. }
  89. F[i] = face;
  90. i++;
  91. }else if(
  92. fscanf(off_file,"%[#]",&tic_tac_toe)==1)
  93. {
  94. char comment[1000];
  95. fscanf(off_file,"%[^\n]",comment);
  96. }else
  97. {
  98. printf("Error: bad line in %s\n",off_file_name.c_str());
  99. fclose(off_file);
  100. return false;
  101. }
  102. }
  103. fclose(off_file);
  104. return true;
  105. }
  106. template <typename DerivedV, typename DerivedF>
  107. IGL_INLINE bool igl::readOFF(
  108. const std::string str,
  109. Eigen::PlainObjectBase<DerivedV>& V,
  110. Eigen::PlainObjectBase<DerivedF>& F)
  111. {
  112. std::vector<std::vector<double> > vV;
  113. std::vector<std::vector<int> > vF;
  114. bool success = igl::readOFF(str,vV,vF);
  115. if(!success)
  116. {
  117. // readOFF(str,vV,vF) should have already printed an error
  118. // message to stderr
  119. return false;
  120. }
  121. bool V_rect = igl::list_to_matrix(vV,V);
  122. if(!V_rect)
  123. {
  124. // igl::list_to_matrix(vV,V) already printed error message to std err
  125. return false;
  126. }
  127. bool F_rect = igl::list_to_matrix(vF,F);
  128. if(!F_rect)
  129. {
  130. // igl::list_to_matrix(vF,F) already printed error message to std err
  131. return false;
  132. }
  133. return true;
  134. }