readMSH.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // high level interface for MshLoader
  2. //
  3. // Copyright (C) 2020 Vladimir Fonov <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla
  6. // Public License v. 2.0. If a copy of the MPL was not distributed
  7. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "readMSH.h"
  9. #include "MshLoader.h"
  10. #include <iostream>
  11. template <
  12. typename DerivedX,
  13. typename DerivedTri,
  14. typename DerivedTet,
  15. typename DerivedTriTag,
  16. typename DerivedTetTag,
  17. typename MatrixXF,
  18. typename MatrixTriF,
  19. typename MatrixTetF
  20. >
  21. IGL_INLINE bool igl::readMSH(
  22. const std::string &msh,
  23. Eigen::PlainObjectBase<DerivedX> &X,
  24. Eigen::PlainObjectBase<DerivedTri> &Tri,
  25. Eigen::PlainObjectBase<DerivedTet> &Tet,
  26. Eigen::PlainObjectBase<DerivedTriTag> &TriTag,
  27. Eigen::PlainObjectBase<DerivedTetTag> &TetTag,
  28. std::vector<std::string> &XFields,
  29. std::vector<MatrixXF> &XF,
  30. std::vector<std::string> &EFields,
  31. std::vector<MatrixTriF> &TriF,
  32. std::vector<MatrixTetF> &TetF)
  33. {
  34. try
  35. {
  36. igl::MshLoader _loader(msh);
  37. const int USETAG = 1;
  38. #ifdef IGL_READMESH_DEBUG
  39. std::cout<<"readMSH:Total number of nodes:" << _loader.get_nodes().size()<<std::endl;
  40. std::cout<<"readMSH:Total number of elements:" << _loader.get_elements().size()<<std::endl;
  41. std::cout<<"readMSH:Node fields:" << std::endl;
  42. for(auto i=std::begin(_loader.get_node_fields_names()); i!=std::end(_loader.get_node_fields_names()); i++)
  43. {
  44. std::cout << i->c_str() << ":" << _loader.get_node_fields()[i-std::begin(_loader.get_node_fields_names())].size() << std::endl;
  45. }
  46. std::cout << "readMSH:Element fields:" << std::endl;
  47. for(auto i=std::begin(_loader.get_element_fields_names()); i!=std::end(_loader.get_element_fields_names()); i++)
  48. {
  49. std::cout << i->c_str() << ":" << _loader.get_element_fields()[i-std::begin(_loader.get_element_fields_names())].size() << std::endl;
  50. }
  51. if(_loader.is_element_map_identity())
  52. std::cout<<"readMSH:Element ids map is identity"<<std::endl;
  53. else
  54. std::cout<<"readMSH:Element ids map is NOT identity"<<std::endl;
  55. #endif
  56. // convert nodes
  57. // hadrcoded for 3D
  58. Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
  59. node_map( _loader.get_nodes().data(), _loader.get_nodes().size()/3, 3 );
  60. X = node_map;
  61. XFields = _loader.get_element_fields_names();
  62. XF.resize(_loader.get_node_fields().size());
  63. XFields = _loader.get_node_fields_names();
  64. for(size_t i=0;i<_loader.get_node_fields().size();++i)
  65. {
  66. Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
  67. field_map( _loader.get_node_fields()[i].data(),
  68. _loader.get_node_fields()[i].size()/_loader.get_node_fields_components()[i],
  69. _loader.get_node_fields_components()[i] );
  70. XF[i] = field_map;
  71. }
  72. // calculate number of elements
  73. std::map<int,int> element_counts;
  74. for(auto i:_loader.get_elements_types())
  75. {
  76. auto j=element_counts.insert({i,1});
  77. if(!j.second) (*j.first).second+=1;
  78. }
  79. #ifdef IGL_READMESH_DEBUG
  80. std::cout<<"ReadMSH: elements found"<<std::endl;
  81. for(auto i:element_counts)
  82. std::cout<<"\t"<<i.first<<":"<<i.second<<std::endl;
  83. #endif
  84. int n_tri_el=0;
  85. int n_tet_el=0;
  86. auto n_tri_el_=element_counts.find(igl::MshLoader::ELEMENT_TRI);
  87. auto n_tet_el_=element_counts.find(igl::MshLoader::ELEMENT_TET);
  88. if(n_tri_el_!=std::end(element_counts))
  89. n_tri_el=n_tri_el_->second;
  90. if(n_tet_el_!=std::end(element_counts))
  91. n_tet_el=n_tet_el_->second;
  92. Tri.resize(n_tri_el,3);
  93. Tet.resize(n_tet_el,4);
  94. TriTag.resize(n_tri_el);
  95. TetTag.resize(n_tet_el);
  96. size_t el_start = 0;
  97. TriF.resize(_loader.get_element_fields().size());
  98. TetF.resize(_loader.get_element_fields().size());
  99. for(size_t i=0;i<_loader.get_element_fields().size();++i)
  100. {
  101. TriF[i].resize(n_tri_el,_loader.get_element_fields_components()[i]);
  102. TetF[i].resize(n_tet_el,_loader.get_element_fields_components()[i]);
  103. }
  104. EFields = _loader.get_element_fields_names();
  105. int i_tri = 0;
  106. int i_tet = 0;
  107. for(size_t i=0;i<_loader.get_elements_lengths().size();++i)
  108. {
  109. if(_loader.get_elements_types()[i]==MshLoader::ELEMENT_TRI )
  110. {
  111. assert(_loader.get_elements_lengths()[i]==3);
  112. Tri(i_tri, 0) = _loader.get_elements()[el_start ];
  113. Tri(i_tri, 1) = _loader.get_elements()[el_start+1];
  114. Tri(i_tri, 2) = _loader.get_elements()[el_start+2];
  115. TriTag(i_tri) = _loader.get_elements_tags()[1][i];
  116. for(size_t j=0;j<_loader.get_element_fields().size();++j)
  117. for(size_t k=0;k<_loader.get_element_fields_components()[j];++k)
  118. TriF[j](i_tri,k) = _loader.get_element_fields()[j][_loader.get_element_fields_components()[j]*i+k];
  119. ++i_tri;
  120. } else if(_loader.get_elements_types()[i]==MshLoader::ELEMENT_TET ) {
  121. assert(_loader.get_elements_lengths()[i]==4);
  122. Tet(i_tet, 0) = _loader.get_elements()[el_start ];
  123. Tet(i_tet, 1) = _loader.get_elements()[el_start+1];
  124. Tet(i_tet, 2) = _loader.get_elements()[el_start+2];
  125. Tet(i_tet, 3) = _loader.get_elements()[el_start+3];
  126. TetTag(i_tet) = _loader.get_elements_tags()[USETAG][i];
  127. for(size_t j=0;j<_loader.get_element_fields().size();++j)
  128. for(size_t k=0;k<_loader.get_element_fields_components()[j];++k)
  129. TetF[j](i_tet,k) = _loader.get_element_fields()[j][_loader.get_element_fields_components()[j]*i+k];
  130. ++i_tet;
  131. } else {
  132. // else: it's unsupported type of the element, ignore for now
  133. std::cerr<<"readMSH: unsupported element type: "<<_loader.get_elements_types()[i] <<
  134. ", length: "<< _loader.get_elements_lengths()[i] <<std::endl;
  135. }
  136. el_start += _loader.get_elements_lengths()[i];
  137. }
  138. assert(i_tet == n_tet_el);
  139. assert(i_tri == n_tri_el);
  140. } catch(const std::exception& e) {
  141. std::cerr << e.what() << std::endl;
  142. return false;
  143. }
  144. return true;
  145. }
  146. template <int EigenMatrixOptions>
  147. IGL_INLINE bool igl::readMSH(
  148. const std::string &msh,
  149. Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &X,
  150. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &Tri,
  151. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &Tet,
  152. Eigen::VectorXi &TriTag,
  153. Eigen::VectorXi &TetTag)
  154. {
  155. std::vector<std::string> XFields;
  156. std::vector<std::string> EFields;
  157. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> XF;
  158. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TriF;
  159. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TetF;
  160. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  161. }
  162. template <int EigenMatrixOptions>
  163. IGL_INLINE bool igl::readMSH(
  164. const std::string &msh,
  165. Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &X,
  166. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &Tri,
  167. Eigen::VectorXi &TriTag)
  168. {
  169. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> Tet;
  170. Eigen::VectorXi TetTag;
  171. std::vector<std::string> XFields;
  172. std::vector<std::string> EFields;
  173. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> XF;
  174. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TriF;
  175. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TetF;
  176. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  177. }
  178. template <int EigenMatrixOptions>
  179. IGL_INLINE bool igl::readMSH(
  180. const std::string &msh,
  181. Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &X,
  182. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> &Tri)
  183. {
  184. Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions> Tet;
  185. Eigen::VectorXi TetTag;
  186. Eigen::VectorXi TriTag;
  187. std::vector<std::string> XFields;
  188. std::vector<std::string> EFields;
  189. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> XF;
  190. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TriF;
  191. std::vector<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,EigenMatrixOptions>> TetF;
  192. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  193. }
  194. #ifdef IGL_STATIC_LIBRARY
  195. // Explicit template instantiation
  196. template bool igl::readMSH<0>(std::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
  197. template bool igl::readMSH<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>>(std::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, std::vector<Eigen::Matrix<double, -1, -1, 1, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 1, -1, -1>>>&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, std::vector<Eigen::Matrix<double, -1, -1, 1, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 1, -1, -1>>>&, std::vector<Eigen::Matrix<double, -1, -1, 1, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 1, -1, -1>>>&);
  198. #endif