MshLoader.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // based on MSH reader from PyMesh
  2. // Copyright (c) 2015 Qingnan Zhou <[email protected]>
  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. #ifndef IGL_MSH_LOADER_H
  9. #define IGL_MSH_LOADER_H
  10. #include "igl_inline.h"
  11. #include <fstream>
  12. #include <map>
  13. #include <string>
  14. #include <vector>
  15. #include <algorithm>
  16. namespace igl {
  17. /// Class for loading information from .msh file
  18. /// depends only on c++stl library
  19. class MshLoader {
  20. public:
  21. struct msh_struct {
  22. int tag,el_type;
  23. msh_struct(int _tag=0,int _type=0):
  24. tag(_tag),el_type(_type){}
  25. bool operator== (const msh_struct& a) const {
  26. return this->tag==a.tag &&
  27. this->el_type==a.el_type;
  28. }
  29. bool operator< (const msh_struct& a) const {
  30. return (this->tag*100+this->el_type) <
  31. (a.tag*100+a.el_type);
  32. }
  33. };
  34. typedef double Float;
  35. typedef std::vector<int> IndexVector;
  36. typedef std::vector<int> IntVector;
  37. typedef std::vector<Float> FloatVector;
  38. typedef std::vector<FloatVector> FloatField;
  39. typedef std::vector<IntVector> IntField;
  40. typedef std::vector<std::string> FieldNames;
  41. typedef std::multimap<msh_struct,int> StructIndex;
  42. typedef std::vector<msh_struct> StructVector;
  43. enum {ELEMENT_LINE=1, ELEMENT_TRI=2, ELEMENT_QUAD=3,
  44. ELEMENT_TET=4, ELEMENT_HEX=5, ELEMENT_PRISM=6,
  45. ELEMENT_PYRAMID=7,
  46. // 2nd order elements
  47. ELEMENT_LINE_2ND_ORDER=8, ELEMENT_TRI_2ND_ORDER=9,
  48. ELEMENT_QUAD_2ND_ORDER=10,ELEMENT_TET_2ND_ORDER=11,
  49. ELEMENT_HEX_2ND_ORDER=12, ELEMENT_PRISM_2ND_ORDER=13,
  50. ELEMENT_PYRAMID_2ND_ORDER=14,
  51. // other elements
  52. ELEMENT_POINT=15 };
  53. public:
  54. /// Load a .msh file from a given path
  55. /// @param[in] filename path to .msh
  56. MshLoader(const std::string &filename);
  57. public:
  58. // get nodes , x,y,z sequentially
  59. const FloatVector& get_nodes() const { return m_nodes; }
  60. // get elements , identifying nodes that create an element
  61. // variable length per element
  62. const IndexVector& get_elements() const { return m_elements; }
  63. // get element types
  64. const IntVector& get_elements_types() const { return m_elements_types; }
  65. // get element lengths
  66. const IntVector& get_elements_lengths() const { return m_elements_lengths; }
  67. // get element tags ( physical (0) and elementary (1) )
  68. const IntField& get_elements_tags() const { return m_elements_tags; }
  69. // get element IDs
  70. const IntVector& get_elements_ids() const { return m_elements_ids; }
  71. // get reverse index from node to element
  72. const IndexVector& get_elements_nodes_idx() const { return m_elements_nodes_idx; }
  73. // get fields assigned per node, all fields and components sequentially
  74. const FloatField& get_node_fields() const { return m_node_fields;}
  75. // get node field names,
  76. const FieldNames& get_node_fields_names() const { return m_node_fields_names;}
  77. // get number of node field components
  78. const IntVector& get_node_fields_components() const {return m_node_fields_components;}
  79. int get_node_field_components(size_t c) const
  80. {
  81. return m_node_fields_components[c];
  82. }
  83. // get fields assigned per element, all fields and components sequentially
  84. const FloatField& get_element_fields() const { return m_element_fields;}
  85. // get element field names
  86. const FieldNames& get_element_fields_names() const { return m_element_fields_names;}
  87. // get number of element field components
  88. const IntVector& get_element_fields_components() const {return m_element_fields_components;}
  89. int get_element_field_components(size_t c) const {
  90. return m_element_fields_components[c];
  91. }
  92. // check if field is present at node level
  93. bool is_node_field(const std::string& fieldname) const {
  94. return (std::find(std::begin(m_node_fields_names),
  95. std::end(m_node_fields_names),
  96. fieldname) != std::end(m_node_fields_names) );
  97. }
  98. // check if field is present at element level
  99. bool is_element_field(const std::string& fieldname) const {
  100. return (std::find(std::begin(m_element_fields_names),
  101. std::end(m_element_fields_names),
  102. fieldname) != std::end(m_node_fields_names) );
  103. }
  104. // check if all elements have ids assigned sequentially
  105. bool is_element_map_identity() const ;
  106. // create tag index
  107. // tag_column: ( physical (0) or elementary (1) ) specifying which tag to use
  108. void index_structures(int tag_column);
  109. // get tag index, call index_structure_tags first
  110. const StructIndex& get_structure_index() const
  111. {
  112. return m_structure_index;
  113. }
  114. // get size of a structure identified by tag and element type
  115. const StructIndex& get_structure_length() const
  116. {
  117. return m_structure_length;
  118. }
  119. //! get list of structures
  120. const StructVector& get_structures() const
  121. {
  122. return m_structures;
  123. }
  124. public:
  125. // helper function, calculate number of nodes associated with an element
  126. static int num_nodes_per_elem_type(int elem_type);
  127. private:
  128. void parse_nodes(std::ifstream& fin);
  129. void parse_elements(std::ifstream& fin);
  130. void parse_node_field(std::ifstream& fin);
  131. void parse_element_field(std::ifstream& fin);
  132. void parse_unknown_field(std::ifstream& fin,
  133. const std::string& fieldname);
  134. private:
  135. bool m_binary;
  136. size_t m_data_size;
  137. FloatVector m_nodes; // len x 3 vector
  138. IndexVector m_elements; // linear array for nodes corresponding to each element
  139. IndexVector m_elements_nodes_idx; // element indexes
  140. IntVector m_elements_ids; // element id's
  141. IntVector m_elements_types; // Element types
  142. IntVector m_elements_lengths; // Element lengths
  143. IntField m_elements_tags; // Element tags, currently 2xtags per element
  144. FloatField m_node_fields; // Float field defined at each node
  145. IntVector m_node_fields_components; // Number of components for node field
  146. FieldNames m_node_fields_names; // Node field name
  147. FloatField m_element_fields; // Float field defined at each element
  148. IntVector m_element_fields_components; // Number of components for element field
  149. FieldNames m_element_fields_names; // Element field name
  150. StructIndex m_structure_index; // index tag ids
  151. StructVector m_structures; // unique structures
  152. StructIndex m_structure_length; // length of structures with consistent element type
  153. };
  154. } //igl
  155. #ifndef IGL_STATIC_LIBRARY
  156. # include "MshLoader.cpp"
  157. #endif
  158. #endif //IGL_MSH_LOADER_H