readMSH.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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. IGL_INLINE bool igl::readMSH(const std::string &msh,
  12. Eigen::MatrixXd &X,
  13. Eigen::MatrixXi &Tri,
  14. Eigen::MatrixXi &Tet,
  15. Eigen::VectorXi &TriTag,
  16. Eigen::VectorXi &TetTag,
  17. std::vector<std::string> &XFields,
  18. std::vector<Eigen::MatrixXd> &XF,
  19. std::vector<std::string> &EFields,
  20. std::vector<Eigen::MatrixXd> &TriF,
  21. std::vector<Eigen::MatrixXd> &TetF
  22. )
  23. {
  24. try
  25. {
  26. igl::MshLoader _loader(msh);
  27. const int USETAG = 1;
  28. #ifndef NDEBUG
  29. std::cout<<"readMSH:Total number of nodes:" << _loader.get_nodes().size()<<std::endl;
  30. std::cout<<"readMSH:Total number of elements:" << _loader.get_elements().size()<<std::endl;
  31. std::cout<<"readMSH:Node fields:" << std::endl;
  32. for(auto i=std::begin(_loader.get_node_fields_names()); i!=std::end(_loader.get_node_fields_names()); i++)
  33. {
  34. std::cout << i->c_str() << ":" << _loader.get_node_fields()[i-std::begin(_loader.get_node_fields_names())].size() << std::endl;
  35. }
  36. std::cout << "readMSH:Element fields:" << std::endl;
  37. for(auto i=std::begin(_loader.get_element_fields_names()); i!=std::end(_loader.get_element_fields_names()); i++)
  38. {
  39. std::cout << i->c_str() << ":" << _loader.get_element_fields()[i-std::begin(_loader.get_element_fields_names())].size() << std::endl;
  40. }
  41. if(_loader.is_element_map_identity())
  42. std::cout<<"readMSH:Element ids map is identity"<<std::endl;
  43. else
  44. std::cout<<"readMSH:Element ids map is NOT identity"<<std::endl;
  45. #endif
  46. // convert nodes
  47. // hadrcoded for 3D
  48. Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
  49. node_map( _loader.get_nodes().data(), _loader.get_nodes().size()/3, 3 );
  50. X = node_map;
  51. XFields = _loader.get_element_fields_names();
  52. XF.resize(_loader.get_node_fields().size());
  53. XFields = _loader.get_node_fields_names();
  54. for(size_t i=0;i<_loader.get_node_fields().size();++i)
  55. {
  56. Eigen::Map< const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
  57. field_map( _loader.get_node_fields()[i].data(),
  58. _loader.get_node_fields()[i].size()/_loader.get_node_fields_components()[i],
  59. _loader.get_node_fields_components()[i] );
  60. XF[i] = field_map;
  61. }
  62. // calculate number of elements
  63. std::map<int,int> element_counts;
  64. for(auto i:_loader.get_elements_types())
  65. {
  66. auto j=element_counts.insert({i,1});
  67. if(!j.second) (*j.first).second+=1;
  68. }
  69. #ifndef NDEBUG
  70. std::cout<<"ReadMSH: elements found"<<std::endl;
  71. for(auto i:element_counts)
  72. std::cout<<"\t"<<i.first<<":"<<i.second<<std::endl;
  73. #endif
  74. int n_tri_el=0;
  75. int n_tet_el=0;
  76. auto n_tri_el_=element_counts.find(igl::MshLoader::ELEMENT_TRI);
  77. auto n_tet_el_=element_counts.find(igl::MshLoader::ELEMENT_TET);
  78. if(n_tri_el_!=std::end(element_counts))
  79. n_tri_el=n_tri_el_->second;
  80. if(n_tet_el_!=std::end(element_counts))
  81. n_tet_el=n_tet_el_->second;
  82. Tri.resize(n_tri_el,3);
  83. Tet.resize(n_tet_el,4);
  84. TriTag.resize(n_tri_el);
  85. TetTag.resize(n_tet_el);
  86. size_t el_start = 0;
  87. TriF.resize(_loader.get_element_fields().size());
  88. TetF.resize(_loader.get_element_fields().size());
  89. for(size_t i=0;i<_loader.get_element_fields().size();++i)
  90. {
  91. TriF[i].resize(n_tri_el,_loader.get_element_fields_components()[i]);
  92. TetF[i].resize(n_tet_el,_loader.get_element_fields_components()[i]);
  93. }
  94. EFields = _loader.get_element_fields_names();
  95. int i_tri = 0;
  96. int i_tet = 0;
  97. for(size_t i=0;i<_loader.get_elements_lengths().size();++i)
  98. {
  99. if(_loader.get_elements_types()[i]==MshLoader::ELEMENT_TRI )
  100. {
  101. assert(_loader.get_elements_lengths()[i]==3);
  102. Tri(i_tri, 0) = _loader.get_elements()[el_start ];
  103. Tri(i_tri, 1) = _loader.get_elements()[el_start+1];
  104. Tri(i_tri, 2) = _loader.get_elements()[el_start+2];
  105. TriTag(i_tri) = _loader.get_elements_tags()[1][i];
  106. for(size_t j=0;j<_loader.get_element_fields().size();++j)
  107. for(size_t k=0;k<_loader.get_element_fields_components()[j];++k)
  108. TriF[j](i_tri,k) = _loader.get_element_fields()[j][_loader.get_element_fields_components()[j]*i+k];
  109. ++i_tri;
  110. } else if(_loader.get_elements_types()[i]==MshLoader::ELEMENT_TET ) {
  111. assert(_loader.get_elements_lengths()[i]==4);
  112. Tet(i_tet, 0) = _loader.get_elements()[el_start ];
  113. Tet(i_tet, 1) = _loader.get_elements()[el_start+1];
  114. Tet(i_tet, 2) = _loader.get_elements()[el_start+2];
  115. Tet(i_tet, 3) = _loader.get_elements()[el_start+3];
  116. TetTag(i_tet) = _loader.get_elements_tags()[USETAG][i];
  117. for(size_t j=0;j<_loader.get_element_fields().size();++j)
  118. for(size_t k=0;k<_loader.get_element_fields_components()[j];++k)
  119. TetF[j](i_tet,k) = _loader.get_element_fields()[j][_loader.get_element_fields_components()[j]*i+k];
  120. ++i_tet;
  121. } else {
  122. // else: it's unsupported type of the element, ignore for now
  123. std::cerr<<"readMSH: unsupported element type: "<<_loader.get_elements_types()[i] <<
  124. ", length: "<< _loader.get_elements_lengths()[i] <<std::endl;
  125. }
  126. el_start += _loader.get_elements_lengths()[i];
  127. }
  128. assert(i_tet == n_tet_el);
  129. assert(i_tri == n_tri_el);
  130. } catch(const std::exception& e) {
  131. std::cerr << e.what() << std::endl;
  132. return false;
  133. }
  134. return true;
  135. }
  136. IGL_INLINE bool igl::readMSH(const std::string &msh,
  137. Eigen::MatrixXd &X,
  138. Eigen::MatrixXi &Tri,
  139. Eigen::MatrixXi &Tet,
  140. Eigen::VectorXi &TriTag,
  141. Eigen::VectorXi &TetTag
  142. )
  143. {
  144. std::vector<std::string> XFields;
  145. std::vector<Eigen::MatrixXd> XF;
  146. std::vector<std::string> EFields;
  147. std::vector<Eigen::MatrixXd> TriF;
  148. std::vector<Eigen::MatrixXd> TetF;
  149. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  150. }
  151. IGL_INLINE bool igl::readMSH(const std::string &msh,
  152. Eigen::MatrixXd &X,
  153. Eigen::MatrixXi &Tri,
  154. Eigen::VectorXi &TriTag
  155. )
  156. {
  157. Eigen::MatrixXi Tet;
  158. Eigen::VectorXi TetTag;
  159. std::vector<std::string> XFields;
  160. std::vector<Eigen::MatrixXd> XF;
  161. std::vector<std::string> EFields;
  162. std::vector<Eigen::MatrixXd> TriF;
  163. std::vector<Eigen::MatrixXd> TetF;
  164. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  165. }
  166. IGL_INLINE bool igl::readMSH(const std::string &msh,
  167. Eigen::MatrixXd &X,
  168. Eigen::MatrixXi &Tri
  169. )
  170. {
  171. Eigen::MatrixXi Tet;
  172. Eigen::VectorXi TetTag;
  173. Eigen::VectorXi TriTag;
  174. std::vector<std::string> XFields;
  175. std::vector<Eigen::MatrixXd> XF;
  176. std::vector<std::string> EFields;
  177. std::vector<Eigen::MatrixXd> TriF;
  178. std::vector<Eigen::MatrixXd> TetF;
  179. return igl::readMSH(msh,X,Tri,Tet,TriTag,TetTag,XFields,XF,EFields,TriF,TetF);
  180. }