31 SmartPointer<Mesh<T>> mesh =
nullptr;
34 std::unordered_map<std::string, std::vector<T>> metaData;
36 unsigned vtk_nodes_for_cell_type[15] = {0, 1, 0, 2, 0, 3, 0, 0,
40 void extractFieldData(vtkDataSet *data) {
41 vtkFieldData *fieldData = data->GetFieldData();
45 for (
int i = 0; i < fieldData->GetNumberOfArrays(); ++i) {
46 vtkDataArray *array = fieldData->GetArray(i);
50 const char *name = array->GetName();
54 int numTuples = array->GetNumberOfTuples();
55 int numComponents = array->GetNumberOfComponents();
57 std::vector<T> values;
58 values.reserve(numTuples * numComponents);
60 for (
int t = 0; t < numTuples; ++t) {
62 array->GetTuple(t, tuple);
63 for (
int c = 0; c < numComponents; ++c)
64 values.push_back(tuple[c]);
67 metaData[name] = std::move(values);
77 : mesh(passedMesh), fileName(std::move(passedFileName)) {}
80 std::string passedFileName)
81 : mesh(passedMesh), fileFormat(passedFormat),
82 fileName(std::move(passedFileName)) {}
92 fileName = std::move(passedFileName);
99 if (mesh ==
nullptr) {
100 Logger::getInstance()
101 .addError(
"No mesh was passed to VTKReader.")
106 if (fileName.empty()) {
107 Logger::getInstance()
108 .addError(
"No file name specified for VTKReader.")
114 auto dotPos = fileName.rfind(
'.');
115 if (dotPos == std::string::npos) {
116 Logger::getInstance()
117 .addError(
"No valid file format found based on the file ending "
118 "passed to VTKReader.")
122 auto ending = fileName.substr(dotPos);
123 if (ending ==
".vtk") {
125 }
else if (ending ==
".vtp") {
127 }
else if (ending ==
".vtu") {
130 Logger::getInstance()
131 .addError(
"No valid file format found based on the file ending "
132 "passed to VTKReader.")
139 switch (fileFormat) {
141 readVTKLegacy(fileName);
143#ifdef VIENNALS_USE_VTK
153 Logger::getInstance()
154 .addError(
"VTKReader was built without VTK support. Only VTK_LEGACY "
159 Logger::getInstance()
160 .addError(
"No valid file format set for VTKReader.")
166#ifdef VIENNALS_USE_VTK
167 void readVTP(
const std::string &filename) {
170 vtkSmartPointer<vtkXMLPolyDataReader> pReader =
171 vtkSmartPointer<vtkXMLPolyDataReader>::New();
172 pReader->SetFileName(filename.c_str());
175 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
176 polyData = pReader->GetOutput();
178 mesh->nodes.resize(polyData->GetNumberOfPoints());
179 for (
unsigned i = 0; i < mesh->nodes.size(); ++i) {
180 std::array<double, 3> coords{};
181 polyData->GetPoint(i, coords.data());
182 mesh->nodes[i] = coords;
185 vtkSmartPointer<vtkCellArray> cellArray =
186 vtkSmartPointer<vtkCellArray>::New();
189 mesh->vertices.reserve(polyData->GetNumberOfVerts());
190 cellArray = polyData->GetVerts();
191 cellArray->InitTraversal();
192 vtkIdList *pointList = vtkIdList::New();
193 while (cellArray->GetNextCell(pointList)) {
194 std::array<unsigned, 1> cell{};
195 cell[0] = pointList->GetId(0);
196 mesh->vertices.push_back(cell);
202 mesh->lines.reserve(polyData->GetNumberOfLines());
203 cellArray = polyData->GetLines();
204 cellArray->InitTraversal();
205 vtkIdList *pointList = vtkIdList::New();
206 while (cellArray->GetNextCell(pointList)) {
207 std::array<unsigned, 2> cell{};
208 for (
unsigned i = 0; i < 2; ++i) {
209 cell[i] = pointList->GetId(i);
211 mesh->lines.push_back(cell);
217 mesh->triangles.reserve(polyData->GetNumberOfPolys());
218 cellArray = polyData->GetPolys();
219 cellArray->InitTraversal();
220 vtkIdList *pointList = vtkIdList::New();
221 while (cellArray->GetNextCell(pointList)) {
222 std::array<unsigned, 3> cell{};
223 for (
unsigned i = 0; i < 3; ++i) {
224 cell[i] = pointList->GetId(i);
226 mesh->triangles.push_back(cell);
231 vtkSmartPointer<vtkPointData> pointData =
232 vtkSmartPointer<vtkPointData>::New();
233 pointData = polyData->GetPointData();
235 for (
int i = 0; i < static_cast<int>(pointData->GetNumberOfArrays()); ++i) {
236 if (vtkDataArray *dataArray = pointData->GetArray(i);
237 dataArray->GetNumberOfComponents() == 1) {
238 mesh->pointData.insertNextScalarData(
240 std::string(pointData->GetArrayName(i)));
241 auto &scalars = *(mesh->pointData.getScalarData(i));
242 scalars.resize(pointData->GetNumberOfTuples());
243 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
244 scalars[j] = dataArray->GetTuple1(j);
246 }
else if (dataArray->GetNumberOfComponents() == 3) {
247 mesh->pointData.insertNextVectorData(
249 std::string(pointData->GetArrayName(i)));
250 auto &vectors = *(mesh->pointData.getVectorData(i));
251 vectors.resize(pointData->GetNumberOfTuples());
252 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
253 std::array<double, 3> vector{};
254 dataArray->GetTuple(j, &(vector[0]));
261 vtkSmartPointer<vtkCellData> cellData = vtkSmartPointer<vtkCellData>::New();
262 cellData = polyData->GetCellData();
264 for (
int i = 0; i < cellData->GetNumberOfArrays(); ++i) {
265 vtkDataArray *dataArray = cellData->GetArray(i);
266 if (cellData->GetNumberOfComponents() == 1) {
267 mesh->cellData.insertNextScalarData(
269 std::string(cellData->GetArrayName(i)));
270 auto &scalars = *(mesh->cellData.getScalarData(i));
271 scalars.resize(cellData->GetNumberOfTuples());
272 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
273 scalars[j] = dataArray->GetTuple1(j);
275 }
else if (cellData->GetNumberOfComponents() == 3) {
276 mesh->cellData.insertNextVectorData(
278 std::string(cellData->GetArrayName(i)));
279 auto &vectors = *(mesh->cellData.getVectorData(i));
280 vectors.resize(cellData->GetNumberOfTuples());
281 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
282 std::array<double, 3> vector{};
283 dataArray->GetTuple(j, &(vector[0]));
290 extractFieldData(polyData);
293 void readVTU(
const std::string &filename) {
297 vtkSmartPointer<vtkXMLUnstructuredGridReader> greader =
298 vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();
299 greader->SetFileName(filename.c_str());
302 vtkSmartPointer<vtkUnstructuredGrid> ugrid =
303 vtkSmartPointer<vtkUnstructuredGrid>::New();
304 ugrid = greader->GetOutput();
307 mesh->nodes.resize(ugrid->GetNumberOfPoints());
308 for (
unsigned i = 0; i < mesh->nodes.size(); ++i) {
309 std::array<double, 3> coords{};
310 ugrid->GetPoint(i, &(coords[0]));
311 mesh->nodes[i] = coords;
315 for (
unsigned i = 0; i < ugrid->GetNumberOfCells(); ++i) {
316 vtkIdList *pointList = vtkIdList::New();
317 ugrid->GetCellPoints(i, pointList);
319 switch (ugrid->GetCellType(i)) {
322 std::array<unsigned, 1> vert{};
323 vert[0] = pointList->GetId(0);
324 mesh->vertices.push_back(vert);
328 std::array<unsigned, 2> elements{};
329 for (
unsigned j = 0; j < 2; ++j) {
330 elements[j] = pointList->GetId(j);
332 mesh->lines.push_back(elements);
336 std::array<unsigned, 3> elements{};
337 for (
unsigned j = 0; j < 3; ++j) {
338 elements[j] = pointList->GetId(j);
340 mesh->triangles.push_back(elements);
344 std::array<unsigned, 4> elements{};
345 for (
unsigned j = 0; j < 4; ++j) {
346 elements[j] = pointList->GetId(j);
348 mesh->tetras.push_back(elements);
352 std::array<unsigned, 8> elements{};
353 for (
unsigned j = 0; j < 8; ++j) {
354 elements[j] = pointList->GetId(j);
356 mesh->hexas.push_back(elements);
362 vtkSmartPointer<vtkPointData> pointData =
363 vtkSmartPointer<vtkPointData>::New();
364 pointData = ugrid->GetPointData();
366 for (
int i = 0; i < pointData->GetNumberOfArrays(); ++i) {
367 if (vtkDataArray *dataArray = pointData->GetArray(i);
368 dataArray->GetNumberOfComponents() == 1) {
369 mesh->pointData.insertNextScalarData(
371 std::string(pointData->GetArrayName(i)));
372 auto &scalars = *(mesh->pointData.getScalarData(i));
373 scalars.resize(pointData->GetNumberOfTuples());
374 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
375 scalars[j] = dataArray->GetTuple1(j);
377 }
else if (dataArray->GetNumberOfComponents() == 3) {
378 mesh->pointData.insertNextVectorData(
380 std::string(pointData->GetArrayName(i)));
381 auto &vectors = *(mesh->pointData.getVectorData(i));
382 vectors.resize(pointData->GetNumberOfTuples());
383 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
384 std::array<double, 3> vector{};
385 dataArray->GetTuple(j, &(vector[0]));
392 vtkSmartPointer<vtkCellData> cellData = vtkSmartPointer<vtkCellData>::New();
393 cellData = ugrid->GetCellData();
395 for (
int i = 0; i < static_cast<int>(cellData->GetNumberOfArrays()); ++i) {
396 vtkDataArray *dataArray = cellData->GetArray(i);
397 if (cellData->GetNumberOfComponents() == 1) {
398 mesh->cellData.insertNextScalarData(
400 std::string(cellData->GetArrayName(i)));
401 auto &scalars = *(mesh->cellData.getScalarData(i));
402 scalars.resize(cellData->GetNumberOfTuples());
403 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
404 scalars[j] = dataArray->GetTuple1(j);
406 }
else if (cellData->GetNumberOfComponents() == 3) {
407 mesh->cellData.insertNextVectorData(
409 std::string(cellData->GetArrayName(i)));
410 auto &vectors = *(mesh->cellData.getVectorData(i));
411 vectors.resize(cellData->GetNumberOfTuples());
412 for (
unsigned j = 0; j < dataArray->GetNumberOfTuples(); ++j) {
413 std::array<double, 3> vector{};
414 dataArray->GetTuple(j, &(vector[0]));
421 extractFieldData(ugrid);
426 void readVTKLegacy(
const std::string &filename) {
430 std::ifstream f(filename.c_str());
432 Logger::getInstance().addError(
"Could not open geometry file!");
436 while (std::getline(f, temp)) {
437 if (temp.find(
"DATASET") != std::string::npos)
440 if (temp.find(
"UNSTRUCTURED_GRID") == std::string::npos) {
441 Logger::getInstance().addError(
"DATASET is not an UNSTRUCTURED_GRID!");
445 while (std::getline(f, temp)) {
446 if (temp.find(
"POINTS") != std::string::npos)
449 int num_nodes = atoi(&temp[temp.find(
' ') + 1]);
451 mesh->nodes.resize(num_nodes);
453 for (
int i = 0; i < num_nodes; i++) {
456 for (
double &coord : coords)
458 for (
int j = 0; j < 3; j++) {
459 mesh->nodes[i][j] = coords[j];
471 while (std::getline(f, temp)) {
472 if (temp.find(
"CELLS") == 0)
476 int num_elems = atoi(&temp[temp.find(
' ') + 1]);
478 std::ifstream f_ct(filename.c_str());
483 while (std::getline(f_ct, temp)) {
484 if (temp.find(
"CELL_TYPES") == 0)
487 int num_cell_types = atoi(&temp[temp.find(
' ') + 1]);
489 if (num_elems != num_cell_types) {
490 Logger::getInstance().addError(
491 "Corrupt input geometry! Number of CELLS and CELL_TYPES "
495 bool is_material =
true;
497 while (std::getline(f_m, temp)) {
498 if (temp.find(
"CELL_DATA") != std::string::npos) {
499 std::getline(f_m, temp);
500 if ((temp.find(
"SCALARS material") != std::string::npos) ||
501 (temp.find(
"SCALARS Material") != std::string::npos)) {
502 std::getline(f_m, temp);
512 std::vector<VectorType<unsigned int, 4>> elements;
513 elements.reserve(num_elems);
515 std::vector<double> materials;
519 unsigned cell_material;
520 for (
int i = 0; i < num_elems; i++) {
524 f_m >> cell_material;
530 unsigned number_nodes = vtk_nodes_for_cell_type[cell_type];
531 if (number_nodes == elems_fake || number_nodes == 0) {
535 std::array<unsigned, 1> elem{};
537 mesh->template getElements<1>().push_back(elem);
538 materials.push_back(cell_material);
542 std::array<unsigned, 2> elem{};
543 for (
unsigned j = 0; j < number_nodes; ++j) {
546 mesh->template getElements<2>().push_back(elem);
547 materials.push_back(cell_material);
552 std::array<unsigned, 3> elem{};
553 for (
unsigned j = 0; j < number_nodes; ++j) {
556 mesh->template getElements<3>().push_back(elem);
557 materials.push_back(cell_material);
563 std::array<unsigned, 4> elem{};
564 for (
unsigned j = 0; j < number_nodes; ++j) {
567 mesh->template getElements<4>().push_back(elem);
568 materials.push_back(cell_material);
574 std::array<unsigned, 3> elem{};
575 for (
unsigned j = 0; j < 3; ++j) {
578 mesh->template getElements<3>().push_back(
580 materials.push_back(cell_material);
583 mesh->template getElements<3>().push_back(elem);
584 materials.push_back(cell_material);
589 std::ostringstream oss;
590 oss <<
"VTK Cell type " << cell_type
591 <<
" is not supported. Cell ignored..." << std::endl;
592 Logger::getInstance().addWarning(oss.str()).print();
595 std::ostringstream oss;
596 oss <<
"INVALID CELL TYPE! Expected number of nodes: " << number_nodes
597 <<
", Found number of nodes: " << elems_fake
598 <<
"; Ignoring element...";
599 Logger::getInstance().addError(oss.str());
601 f.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
605 mesh->cellData.insertNextScalarData(materials,
"Material");
608 int num_cell_data = 0;
609 while (std::getline(f, temp)) {
610 if (temp.find(
"CELL_DATA") != std::string::npos) {
611 num_cell_data = atoi(&temp[temp.find(
' ') + 1]);
615 std::cout <<
"Read cell data: " << num_cell_data << std::endl;
618 std::cout <<
"reading scalar data" << std::endl;
619 while (std::getline(f, temp)) {
620 if (temp.find(
"SCALARS") != std::string::npos)
627 std::string scalarDataName;
629 auto firstS = temp.find(
' ') + 1;
630 auto secondS = temp.find(
' ', firstS + 1);
631 scalarDataName = temp.substr(firstS, secondS - firstS);
633 std::vector<double> scalarData;
636 std::getline(f, temp);
637 if (temp !=
"LOOKUP_TABLE default") {
638 Logger::getInstance()
639 .addWarning(
"Wrong lookup table for VTKLegacy: " + temp)
644 for (
int i = 0; i < num_cell_data; ++i) {
647 scalarData.push_back(data);
650 mesh->cellData.insertNextScalarData(scalarData, scalarDataName);