7 #include "imstkMshMeshIO.h" 8 #include "imstkHexahedralMesh.h" 9 #include "imstkLineMesh.h" 10 #include "imstkSurfaceMesh.h" 11 #include "imstkTetrahedralMesh.h" 12 #include "imstkVecDataArray.h" 22 readToDelimiter(std::ifstream& file)
24 char next =
static_cast<char>(file.peek());
25 while (next ==
'\n' || next ==
' ' || next ==
'\t' || next ==
'\r')
28 next =
static_cast<char>(file.peek());
36 static std::shared_ptr<VecDataArray<int, N>>
37 toVecDataArray(
const std::vector<int>& vertIds)
39 const int cellCount =
static_cast<int>(vertIds.size() / N);
40 CHECK(vertIds.size() % N == 0) <<
"Failed to convert array stride not divisable";
41 std::shared_ptr<VecDataArray<int, N>> indicesPtr =
42 std::make_shared<VecDataArray<int, N>>(cellCount);
43 std::copy(vertIds.data(), vertIds.data() + cellCount * N,
44 std::dynamic_pointer_cast<DataArray<int>>(indicesPtr)->getPointer());
48 std::shared_ptr<PointSet>
55 std::shared_ptr<PointSet> results =
nullptr;
59 file.open(filePath, std::ios::binary | std::ios::in);
60 CHECK(file.is_open()) <<
"Failed to read file, ifstream failed to open " << filePath;
63 std::string bufferStr;
70 file >> version >> fileType >> dataSize;
71 CHECK(dataSize == 8) <<
"Failed to read file, data size must be 8 bytes";
72 CHECK(
sizeof(
int) == 4) <<
"Failed to read file, code must be compiled with int size 4 bytes";
74 const bool isBinary = (fileType == 1);
81 readToDelimiter(file);
82 file.read(reinterpret_cast<char*>(&oneFromBinary),
sizeof(
int));
83 CHECK(oneFromBinary == 1) <<
"Failed to read file, file saved with different endianness than this machine";
87 CHECK(bufferStr ==
"$EndMeshFormat") <<
"Failed to read file, invalid format";
89 CHECK(!file.fail()) <<
"Failed to read file, ifstream error";
91 std::shared_ptr<VecDataArray<double, 3>> verticesPtr =
nullptr;
96 CHECK(!file.fail()) <<
"Failed to read file, ifstream error";
98 if (bufferStr ==
"$Nodes")
104 verticesPtr = std::make_shared<VecDataArray<double, 3>>(nNodes);
106 std::vector<size_t> nodeIDs(nNodes);
111 size_t numBytes = (4 + 3 * dataSize) * nNodes;
112 std::vector<char> data(numBytes);
113 readToDelimiter(file);
114 file.read(data.data(), numBytes);
115 for (
int i = 0; i < nNodes; i++)
117 int id = *
reinterpret_cast<int*
>(&data[i * (4 + 3 * dataSize)]) - 1;
124 double* x =
reinterpret_cast<double*
>(&data[i * (4 + 3 * dataSize) + 4]);
125 std::copy(x, x + 3, &vertices[
id][0]);
130 for (
int i = 0; i < nNodes; i++)
134 file >>
id >> pos[0] >> pos[1] >> pos[2];
136 vertices[
id - 1] = pos;
141 CHECK(bufferStr ==
"$EndNodes") <<
"Failed to read file, invalid format";
143 else if (bufferStr ==
"$Elements")
145 std::array<int, 6> elemTypeToCount =
157 std::array<std::vector<int>, 6> elementVertIds;
161 CHECK(!file.fail()) <<
"Failed to read file, ifstream error";
162 readToDelimiter(file);
168 while (elemIter < numElements)
171 int elemType, numElems, numTags;
172 file.read((
char*)&elemType,
sizeof(
int));
173 file.read((
char*)&numElems,
sizeof(
int));
174 file.read((
char*)&numTags,
sizeof(
int));
176 CHECK(elemType > 0 && elemType < 6) <<
177 "Failed to read file, unsupported element type";
178 int vertexCount = elemTypeToCount[elemType];
179 std::vector<int>& elemVertIds = elementVertIds[elemType];
182 for (
int i = 0; i < numElems; i++)
185 file.read((
char*)&elementId,
sizeof(
int));
189 for (
int j = 0; j < numTags; j++)
192 file.read((
char*)&tag,
sizeof(
int));
196 for (
int j = 0; j < vertexCount; j++)
199 file.read((
char*)&vertId,
sizeof(
int));
200 elemVertIds.push_back(vertId - 1);
204 elemIter += numElems;
209 for (
int i = 0; i < numElements; i++)
212 int elemGroupId = -1;
215 file >> elemGroupId >> elemType >> numTags;
216 CHECK(elemType > 0 && elemType < 6) <<
217 "Failed to read file, unsupported element type";
219 int vertexCount = elemTypeToCount[elemType];
220 std::vector<int>& elemVertIds = elementVertIds[elemType];
223 for (
int j = 0; j < numTags; j++)
230 for (
int j = 0; j < vertexCount; j++)
234 elemVertIds.push_back(vertId - 1);
242 for (
int i = 0; i < 6; i++)
244 if (elementVertIds[i].size() > 0)
254 LOG(WARNING) <<
"MshMeshIO::read only supports homogenous types of elements, " <<
255 typeCount <<
" types of elements were found, choosing one";
260 auto mesh = std::make_shared<LineMesh>();
261 mesh->initialize(verticesPtr, toVecDataArray<2>(elementVertIds[typeToUse]));
264 else if (typeToUse == 2)
266 auto mesh = std::make_shared<SurfaceMesh>();
267 mesh->initialize(verticesPtr, toVecDataArray<3>(elementVertIds[typeToUse]));
270 else if (typeToUse == 4)
272 auto mesh = std::make_shared<TetrahedralMesh>();
273 mesh->initialize(verticesPtr, toVecDataArray<4>(elementVertIds[typeToUse]));
276 else if (typeToUse == 5)
278 auto mesh = std::make_shared<HexahedralMesh>();
279 mesh->initialize(verticesPtr, toVecDataArray<8>(elementVertIds[typeToUse]));
284 CHECK(bufferStr ==
"$EndElements") <<
"Failed to read file, invalid format";
static std::shared_ptr< PointSet > read(const std::string &filePath)
Read and generate a volumetric mesh given a external msh file.