Coverage Report

Created: 2026-06-10 06:22

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