read_triangle_mesh.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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 "readMSH.h"
  11. #include "readMESH.h"
  12. #include "readOBJ.h"
  13. #include "readOFF.h"
  14. #include "readSTL.h"
  15. #include "readPLY.h"
  16. #include "readWRL.h"
  17. #include "pathinfo.h"
  18. #include "boundary_facets.h"
  19. #include "polygon_mesh_to_triangle_mesh.h"
  20. #include <algorithm>
  21. #include <iostream>
  22. template <typename Scalar, typename Index>
  23. IGL_INLINE bool igl::read_triangle_mesh(
  24. const std::string str,
  25. std::vector<std::vector<Scalar> > & V,
  26. std::vector<std::vector<Index> > & F)
  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> > TC, 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. {
  61. std::string _1,_2,_3,_4;
  62. return read_triangle_mesh(str,V,F,_1,_2,_3,_4);
  63. }
  64. template <typename DerivedV, typename DerivedF>
  65. IGL_INLINE bool igl::read_triangle_mesh(
  66. const std::string filename,
  67. Eigen::PlainObjectBase<DerivedV>& V,
  68. Eigen::PlainObjectBase<DerivedF>& F,
  69. std::string & dir,
  70. std::string & base,
  71. std::string & ext,
  72. std::string & name)
  73. {
  74. using namespace std;
  75. using namespace Eigen;
  76. // dirname, basename, extension and filename
  77. pathinfo(filename,dir,base,ext,name);
  78. // Convert extension to lower case
  79. transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
  80. // readMSH requires filename
  81. if(ext == "msh")
  82. {
  83. // readMSH is not properly templated
  84. Eigen::MatrixXd mV;
  85. Eigen::MatrixXi mF,T;
  86. Eigen::VectorXi _1,_2;
  87. // *TetWild doesn't use Tri field...
  88. //bool res = readMSH(filename,mV,mF);
  89. bool res = readMSH(filename,mV,mF,T,_1,_2);
  90. V = mV.template cast<typename DerivedV::Scalar>();
  91. if(mF.rows() == 0 && T.rows() > 0)
  92. {
  93. boundary_facets(T,F);
  94. // outward facing
  95. F = F.rowwise().reverse().eval();
  96. }else
  97. {
  98. F = mF.template cast<typename DerivedF::Scalar>();
  99. }
  100. return res;
  101. }else
  102. {
  103. FILE * fp = fopen(filename.c_str(),"rb");
  104. if(NULL==fp)
  105. {
  106. fprintf(stderr,"IOError: %s could not be opened...\n",
  107. filename.c_str());
  108. return false;
  109. }
  110. return read_triangle_mesh(ext,fp,V,F);
  111. }
  112. }
  113. template <typename DerivedV, typename DerivedF>
  114. IGL_INLINE bool igl::read_triangle_mesh(
  115. const std::string & ext,
  116. FILE * fp,
  117. Eigen::PlainObjectBase<DerivedV>& V,
  118. Eigen::PlainObjectBase<DerivedF>& F)
  119. {
  120. using namespace std;
  121. using namespace Eigen;
  122. vector<vector<double > > vV,vN,vTC,vC;
  123. vector<vector<int > > vF,vFTC,vFN;
  124. vector<tuple<string, int, int>> FM;
  125. if(ext == "mesh")
  126. {
  127. // Convert extension to lower case
  128. MatrixXi T;
  129. if(!readMESH(fp,V,T,F))
  130. {
  131. return 1;
  132. }
  133. //if(F.size() > T.size() || F.size() == 0)
  134. {
  135. boundary_facets(T,F);
  136. // outward facing
  137. F = F.rowwise().reverse().eval();
  138. }
  139. }else if(ext == "obj")
  140. {
  141. if(!readOBJ(fp,vV,vTC,vN,vF,vFTC,vFN,FM))
  142. {
  143. return false;
  144. }
  145. // Annoyingly obj can store 4 coordinates, truncate to xyz for this generic
  146. // read_triangle_mesh
  147. for(auto & v : vV)
  148. {
  149. v.resize(std::min(v.size(),(size_t)3));
  150. }
  151. }else if(ext == "off")
  152. {
  153. if(!readOFF(fp,vV,vF,vN,vC))
  154. {
  155. return false;
  156. }
  157. }else if(ext == "ply")
  158. {
  159. return readPLY(fp, V, F);
  160. }else if(ext == "stl")
  161. {
  162. if(!readSTL(fp,vV,vF,vN))
  163. {
  164. return false;
  165. }
  166. }else if(ext == "wrl")
  167. {
  168. if(!readWRL(fp,vV,vF))
  169. {
  170. return false;
  171. }
  172. }else
  173. {
  174. cerr<<"Error: unknown extension: "<<ext<<endl;
  175. return false;
  176. }
  177. if(vV.size() > 0)
  178. {
  179. if(!list_to_matrix(vV,V))
  180. {
  181. return false;
  182. }
  183. polygon_mesh_to_triangle_mesh(vF,F);
  184. }
  185. return true;
  186. }
  187. #endif
  188. #ifdef IGL_STATIC_LIBRARY
  189. // Explicit template instantiation
  190. // generated by autoexplicit.sh
  191. 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> >&);
  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> >&, 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> >&);
  193. 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> >&);
  194. 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> >&);
  195. 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> >&);
  196. 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> >&, 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<float, -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<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  198. 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> >&);
  199. template bool igl::read_triangle_mesh<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(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, -1, 0, -1, -1> >&);
  200. 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> >&);
  201. 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> >&);
  202. 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> > > >&);
  203. #endif