readOFF.cpp 4.1 KB

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