read_triangle_mesh.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "read_triangle_mesh.h"
  9. #include "list_to_matrix.h"
  10. #include "readMESH.h"
  11. #include "readOBJ.h"
  12. #include "readOFF.h"
  13. #include "readSTL.h"
  14. #include "readPLY.h"
  15. #include "readWRL.h"
  16. #include "pathinfo.h"
  17. #include "boundary_facets.h"
  18. #include "polygon_mesh_to_triangle_mesh.h"
  19. #include <algorithm>
  20. #include <iostream>
  21. template <typename Scalar, typename Index>
  22. IGL_INLINE bool igl::read_triangle_mesh(
  23. const std::string str,
  24. std::vector<std::vector<Scalar> > & V,
  25. std::vector<std::vector<Index> > & F,
  26. std::vector<std::vector<Scalar> > & TC)
  27. {
  28. using namespace std;
  29. // dirname, basename, extension and filename
  30. string d,b,e,f;
  31. pathinfo(str,d,b,e,f);
  32. // Convert extension to lower case
  33. std::transform(e.begin(), e.end(), e.begin(), ::tolower);
  34. vector<vector<Scalar> > N, C;
  35. vector<vector<Index> > FTC, FN;
  36. if(e == "obj")
  37. {
  38. // Annoyingly obj can store 4 coordinates, truncate to xyz for this generic
  39. // read_triangle_mesh
  40. bool success = readOBJ(str,V,TC,N,F,FTC,FN);
  41. for(auto & v : V)
  42. {
  43. v.resize(std::min(v.size(),(size_t)3));
  44. }
  45. return success;
  46. }else if(e == "off")
  47. {
  48. return readOFF(str,V,F,N,C);
  49. }
  50. cerr<<"Error: "<<__FUNCTION__<<": "<<
  51. str<<" is not a recognized mesh file format."<<endl;
  52. return false;
  53. }
  54. #ifndef IGL_NO_EIGN
  55. template <typename DerivedV, typename DerivedF>
  56. IGL_INLINE bool igl::read_triangle_mesh(
  57. const std::string str,
  58. Eigen::PlainObjectBase<DerivedV>& V,
  59. Eigen::PlainObjectBase<DerivedF>& F,
  60. Eigen::PlainObjectBase<DerivedV>& TC)
  61. {
  62. std::string _1,_2,_3,_4;
  63. return read_triangle_mesh(str,V,F, TC, _1,_2,_3,_4);
  64. }
  65. template <typename DerivedV, typename DerivedF>
  66. IGL_INLINE bool igl::read_triangle_mesh(
  67. const std::string filename,
  68. Eigen::PlainObjectBase<DerivedV>& V,
  69. Eigen::PlainObjectBase<DerivedF>& F,
  70. Eigen::PlainObjectBase<DerivedV>& TC,
  71. std::string & dir,
  72. std::string & base,
  73. std::string & ext,
  74. std::string & name)
  75. {
  76. using namespace std;
  77. using namespace Eigen;
  78. // dirname, basename, extension and filename
  79. pathinfo(filename,dir,base,ext,name);
  80. // Convert extension to lower case
  81. transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
  82. FILE * fp = fopen(filename.c_str(),"rb");
  83. if(NULL==fp)
  84. {
  85. fprintf(stderr,"IOError: %s could not be opened...\n",
  86. filename.c_str());
  87. return false;
  88. }
  89. return read_triangle_mesh(ext,fp,V,F, TC);
  90. }
  91. template <typename DerivedV, typename DerivedF>
  92. IGL_INLINE bool igl::read_triangle_mesh(
  93. const std::string & ext,
  94. FILE * fp,
  95. Eigen::PlainObjectBase<DerivedV>& V,
  96. Eigen::PlainObjectBase<DerivedF>& F,
  97. Eigen::PlainObjectBase<DerivedV>& TC)
  98. {
  99. using namespace std;
  100. using namespace Eigen;
  101. vector<vector<double > > vV,vN,vC, vTC;
  102. vector<vector<int > > vF,vFTC,vFN, vTCI;
  103. if(ext == "mesh")
  104. {
  105. // Convert extension to lower case
  106. MatrixXi T;
  107. if(!readMESH(fp,V,T,F))
  108. {
  109. return 1;
  110. }
  111. //if(F.size() > T.size() || F.size() == 0)
  112. {
  113. boundary_facets(T,F);
  114. }
  115. }else if(ext == "obj")
  116. {
  117. if(!readOBJ(fp,vV,vTC,vN,vF,vFTC,vFN))
  118. {
  119. return false;
  120. }
  121. // Annoyingly obj can store 4 coordinates, truncate to xyz for this generic
  122. // read_triangle_mesh
  123. for(auto & v : vV)
  124. {
  125. v.resize(std::min(v.size(),(size_t)3));
  126. }
  127. }else if(ext == "off")
  128. {
  129. if(!readOFF(fp,vV,vF,vN,vC))
  130. {
  131. return false;
  132. }
  133. }else if(ext == "ply")
  134. {
  135. if(!readPLY(fp,vV,vF,vN,vTC))
  136. {
  137. return false;
  138. }
  139. }else if(ext == "stl")
  140. {
  141. if(!readSTL(fp,vV,vF,vN))
  142. {
  143. return false;
  144. }
  145. }else if(ext == "wrl")
  146. {
  147. if(!readWRL(fp,vV,vF, vTC, vTCI))
  148. {
  149. return false;
  150. }
  151. }else
  152. {
  153. cerr<<"Error: unknown extension: "<<ext<<endl;
  154. return false;
  155. }
  156. if(vV.size() > 0)
  157. {
  158. //fprintf(stdout,"#Vertices: %d\n", vV.size());
  159. if(!list_to_matrix(vV,V))
  160. {
  161. return false;
  162. }
  163. polygon_mesh_to_triangle_mesh(vF,F);
  164. if(ext == "wrl") {
  165. Eigen::PlainObjectBase<DerivedV> TexCoord;
  166. if(!list_to_matrix(vTC,TexCoord))
  167. {
  168. return false;
  169. }
  170. Eigen::PlainObjectBase<DerivedF> TexCoordIndex;
  171. polygon_mesh_to_triangle_mesh(vTCI,TexCoordIndex);
  172. TC.resize(V.rows(), 2);
  173. for(int i = 0; i < TexCoordIndex.rows(); i++) {
  174. for(int j = 0; j < TexCoordIndex.row(i).cols(); j++) {
  175. TC.row(F(i, j)) = TexCoord.row(TexCoordIndex(i, j));
  176. }
  177. }
  178. } else {
  179. if(!list_to_matrix(vTC,TC))
  180. {
  181. return false;
  182. }
  183. }
  184. }
  185. return true;
  186. }
  187. #endif
  188. #ifdef IGL_STATIC_LIBRARY
  189. // Explicit template instantiation
  190. template bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
  191. template bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
  192. template bool igl::read_triangle_mesh<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  193. template bool igl::read_triangle_mesh<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
  194. template bool igl::read_triangle_mesh<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&);
  195. template bool igl::read_triangle_mesh<Eigen::Matrix<double, -1, -1, 1, -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, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);
  196. template bool igl::read_triangle_mesh<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&);
  197. template bool igl::read_triangle_mesh<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(std::string, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  198. template bool igl::read_triangle_mesh<double, int>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
  199. template bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
  200. #endif