80 MeshData data{Eigen::MatrixXd(), Eigen::MatrixXi()};
83 std::string extension = std::filesystem::path(path).extension().string();
84 std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
85 if (extension ==
".msh")
87 else if (extension ==
".hybrid")
98 const std::string vertices_path = child_path(path,
"vertices");
99 const std::string cells_path = child_path(path,
"cells");
105 if ((dimension != 2 && dimension != 3) || vertices.cols() != dimension)
107 if (vertices.rows() == 0 || cells.rows() == 0 || cells.cols() < 3)
109 if (cells.minCoeff() < -1 || cells.maxCoeff() >= vertices.rows())
112 data =
MeshData(std::move(vertices), std::move(cells));
116 if (ordered != 0 && ordered != 1)
118 data.elements_are_ordered = ordered != 0;
121 const std::string body_ids_path = child_path(path,
"body_ids");
124 const std::string geometry_ids_path = child_path(path,
"geometry_ids");
127 const std::string node_ids_path = child_path(path,
"node_ids");
130 const std::string boundary_ids_path = child_path(path,
"boundary_ids");
131 const std::string boundary_elements_path = child_path(path,
"boundary_elements");
139 data.boundary_elements.resize(elements.rows());
140 for (
int i = 0; i < elements.rows(); ++i)
142 bool found_padding =
false;
143 for (
int j = 0; j < elements.cols(); ++j)
145 const int vertex = elements(i, j);
148 found_padding =
true;
151 if (vertex < 0 || found_padding)
153 data.boundary_elements[i].push_back(vertex);
158 const std::string higher_nodes_path = child_path(path,
"higher_order_nodes");
159 const std::string higher_connectivity_path = child_path(path,
"higher_order_connectivity");
160 const std::string higher_offsets_path = child_path(path,
"higher_order_offsets");
167 data.higher_order_connectivity = unpack_connectivity(
173 const std::string weights_path = child_path(path,
"higher_order_weights");
174 const std::string weight_offsets_path = child_path(path,
"higher_order_weight_offsets");
180 data.higher_order_weights = unpack_weights(
185 const std::string faces_path = child_path(path,
"faces");
186 const std::string face_offsets_path = child_path(path,
"face_offsets");
187 const std::string cell_faces_path = child_path(path,
"cell_faces");
188 const std::string cell_face_offsets_path = child_path(path,
"cell_face_offsets");
196 for (
const std::string &required : {
197 faces_path, face_offsets_path, cell_faces_path, cell_face_offsets_path,
198 child_path(path,
"cell_face_orientations"), child_path(path,
"cell_is_hex"),
199 child_path(path,
"cell_kernel_points")})
202 data.faces = unpack_connectivity(
206 data.cell_faces = unpack_connectivity(
209 data.cell_face_orientations = unpack_connectivity(
213 if (std::any_of(cell_is_hex.begin(), cell_is_hex.end(), [](
const int value) { return value != 0 && value != 1; }))
215 data.cell_is_hex.assign(cell_is_hex.begin(), cell_is_hex.end());
229 std::string extension = std::filesystem::path(path).extension().string();
230 std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
231 if (extension ==
".msh")
233 else if (extension ==
".obj")
241 const std::string vertices_path = child_path(path,
"vertices");
247 const std::string points_path = child_path(path,
"points");
251 result.
points = Eigen::Map<const Eigen::VectorXi>(values.data(), values.size());
253 const std::string edges_path = child_path(path,
"edges");
256 const std::string faces_path = child_path(path,
"faces");
259 const auto valid = [&](
const Eigen::MatrixXi &elements) {
260 return elements.size() == 0 || (elements.minCoeff() >= 0 && elements.maxCoeff() < result.
vertices.rows());
263 || !valid(result.
edges) || !valid(result.
faces))