33 SmartPointer<Mesh<T>> mesh =
nullptr;
37#ifdef VIENNALS_USE_VTK
38 template <
class In,
class Out>
39 void addDataFromMesh(
const In &inData, Out outData)
const {
41 for (
unsigned i = 0; i < inData.getScalarDataSize(); ++i) {
42 vtkSmartPointer<vtkFloatArray> pointData =
43 vtkSmartPointer<vtkFloatArray>::New();
44 pointData->SetNumberOfComponents(1);
45 pointData->SetName(inData.getScalarDataLabel(i).c_str());
46 auto scalars = *(inData.getScalarData(i));
47 for (
unsigned j = 0; j < inData.getScalarData(i)->size(); ++j) {
48 pointData->InsertNextValue(scalars[j]);
50 outData->AddArray(pointData);
54 for (
unsigned i = 0; i < inData.getVectorDataSize(); ++i) {
55 vtkSmartPointer<vtkFloatArray> vectorData =
56 vtkSmartPointer<vtkFloatArray>::New();
57 vectorData->SetNumberOfComponents(3);
58 vectorData->SetName(inData.getVectorDataLabel(i).c_str());
59 auto vectors = *(inData.getVectorData(i));
60 for (
unsigned j = 0; j < inData.getVectorData(i)->size(); ++j) {
61 vectorData->InsertNextTuple3(vectors[j][0], vectors[j][1],
64 outData->AddArray(vectorData);
75 : mesh(passedMesh), fileName(std::move(passedFileName)) {}
78 std::string passedFileName)
79 : mesh(passedMesh), fileFormat(passedFormat),
80 fileName(std::move(passedFileName)) {}
89 fileName = std::move(passedFileName);
94 if (mesh ==
nullptr) {
96 .addWarning(
"No mesh was passed to VTKWriter. Not writing.")
101 if (fileName.empty()) {
102 Logger::getInstance()
103 .addWarning(
"No file name specified for VTKWriter. Not writing.")
109 auto dotPos = fileName.rfind(
'.');
110 if (dotPos == std::string::npos) {
113 auto ending = fileName.substr(dotPos);
114 if (ending ==
".vtk") {
116 }
else if (ending ==
".vtp") {
118 }
else if (ending ==
".vtu") {
121 Logger::getInstance()
122 .addWarning(
"No valid file format found based on the file ending "
123 "passed to VTKWriter. Not writing.")
131 switch (fileFormat) {
133 writeVTKLegacy(fileName);
135#ifdef VIENNALS_USE_VTK
145 Logger::getInstance()
146 .addWarning(
"VTKWriter was built without VTK support. Falling back "
149 writeVTKLegacy(fileName);
153 Logger::getInstance()
154 .addWarning(
"No valid file format set for VTKWriter. Not writing.")
160#ifdef VIENNALS_USE_VTK
161 void writeVTP(std::string filename)
const {
162 if (mesh ==
nullptr) {
163 Logger::getInstance()
164 .addWarning(
"No mesh was passed to VTKWriter.")
169 if (filename.find(
".vtp") != filename.size() - 4)
171 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
174 vtkSmartPointer<vtkPoints> polyPoints = vtkSmartPointer<vtkPoints>::New();
175 for (
auto it = mesh->getNodes().begin(); it != mesh->getNodes().end();
177 polyPoints->InsertNextPoint((*it)[0], (*it)[1], (*it)[2]);
179 polyData->SetPoints(polyPoints);
182 if (mesh->vertices.size() > 0) {
183 vtkSmartPointer<vtkCellArray> polyCells =
184 vtkSmartPointer<vtkCellArray>::New();
185 for (
auto it = mesh->vertices.begin(); it != mesh->vertices.end(); ++it) {
186 polyCells->InsertNextCell(1);
187 polyCells->InsertCellPoint((*it)[0]);
189 polyData->SetVerts(polyCells);
193 if (mesh->lines.size() > 0) {
194 vtkSmartPointer<vtkCellArray> polyCells =
195 vtkSmartPointer<vtkCellArray>::New();
196 for (
auto it = mesh->lines.begin(); it != mesh->lines.end(); ++it) {
197 polyCells->InsertNextCell(2);
198 for (
unsigned i = 0; i < 2; ++i) {
199 polyCells->InsertCellPoint((*it)[i]);
202 polyData->SetLines(polyCells);
206 if (mesh->triangles.size() > 0) {
207 vtkSmartPointer<vtkCellArray> polyCells =
208 vtkSmartPointer<vtkCellArray>::New();
209 for (
auto it = mesh->triangles.begin(); it != mesh->triangles.end();
211 polyCells->InsertNextCell(3);
212 for (
unsigned i = 0; i < 3; ++i) {
213 polyCells->InsertCellPoint((*it)[i]);
216 polyData->SetPolys(polyCells);
219 addDataFromMesh(mesh->pointData, polyData->GetPointData());
220 addDataFromMesh(mesh->cellData, polyData->GetCellData());
222 vtkSmartPointer<vtkXMLPolyDataWriter> pwriter =
223 vtkSmartPointer<vtkXMLPolyDataWriter>::New();
224 pwriter->SetFileName(filename.c_str());
225 pwriter->SetInputData(polyData);
229 void writeVTU(std::string filename)
const {
230 if (mesh ==
nullptr) {
231 Logger::getInstance()
232 .addWarning(
"No mesh was passed to VTKWriter.")
237 if (filename.find(
".vtu") != filename.size() - 4)
240 vtkSmartPointer<vtkUnstructuredGrid> uGrid =
241 vtkSmartPointer<vtkUnstructuredGrid>::New();
244 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
245 for (
auto it = mesh->getNodes().begin(); it != mesh->getNodes().end();
247 points->InsertNextPoint((*it)[0], (*it)[1], (*it)[2]);
249 uGrid->SetPoints(points);
252 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
253 std::vector<int> cellTypes;
254 cellTypes.reserve(mesh->vertices.size() + mesh->lines.size() +
255 mesh->triangles.size() + mesh->tetras.size() +
259 if (mesh->vertices.size() > 0) {
260 for (
auto it = mesh->vertices.begin(); it != mesh->vertices.end(); ++it) {
261 cells->InsertNextCell(1);
262 cells->InsertCellPoint((*it)[0]);
263 cellTypes.push_back(1);
268 if (mesh->lines.size() > 0) {
269 for (
auto it = mesh->lines.begin(); it != mesh->lines.end(); ++it) {
270 cells->InsertNextCell(2);
271 for (
unsigned i = 0; i < 2; ++i) {
272 cells->InsertCellPoint((*it)[i]);
274 cellTypes.push_back(3);
279 if (mesh->triangles.size() > 0) {
280 for (
auto it = mesh->triangles.begin(); it != mesh->triangles.end();
282 cells->InsertNextCell(3);
283 for (
unsigned i = 0; i < 3; ++i) {
284 cells->InsertCellPoint((*it)[i]);
286 cellTypes.push_back(5);
291 if (mesh->tetras.size() > 0) {
292 for (
auto it = mesh->tetras.begin(); it != mesh->tetras.end(); ++it) {
293 cells->InsertNextCell(4);
294 for (
unsigned i = 0; i < 4; ++i) {
295 cells->InsertCellPoint((*it)[i]);
297 cellTypes.push_back(10);
302 if (mesh->hexas.size() > 0) {
303 for (
auto it = mesh->hexas.begin(); it != mesh->hexas.end(); ++it) {
304 cells->InsertNextCell(8);
305 for (
unsigned i = 0; i < 8; ++i) {
306 cells->InsertCellPoint((*it)[i]);
308 cellTypes.push_back(12);
313 uGrid->SetCells(&(cellTypes[0]), cells);
315 addDataFromMesh(mesh->pointData, uGrid->GetPointData());
316 addDataFromMesh(mesh->cellData, uGrid->GetCellData());
345 vtkSmartPointer<vtkXMLUnstructuredGridWriter> owriter =
346 vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
347 owriter->SetFileName(filename.c_str());
348 owriter->SetInputData(uGrid);
354 void writeVTKLegacy(
const std::string &filename) {
355 if (mesh ==
nullptr) {
356 Logger::getInstance()
357 .addWarning(
"No mesh was passed to VTKWriter.")
362 std::ofstream f(filename.c_str());
364 f <<
"# vtk DataFile Version 2.0" << std::endl;
365 f << ((!mesh->lines.empty()) ? 2 : 3) <<
"D Surface" << std::endl;
366 f <<
"ASCII" << std::endl;
367 f <<
"DATASET UNSTRUCTURED_GRID" << std::endl;
368 f <<
"POINTS " << mesh->nodes.size() <<
" float" << std::endl;
371 for (
unsigned int i = 0; i < mesh->nodes.size(); i++) {
372 for (
int j = 0; j < 3; j++)
373 f <<
static_cast<float>(mesh->nodes[i][j]) <<
" ";
377 const unsigned numberOfCells = mesh->vertices.size() + mesh->lines.size() +
378 mesh->triangles.size() +
379 mesh->tetras.size() + mesh->hexas.size();
380 const unsigned cellDataSize =
381 2 * mesh->vertices.size() + 3 * mesh->lines.size() +
382 4 * mesh->triangles.size() + 5 * mesh->tetras.size() +
383 9 * mesh->hexas.size();
385 f <<
"CELLS " << numberOfCells <<
" " << cellDataSize << std::endl;
388 for (
unsigned int i = 0; i < mesh->vertices.size(); i++) {
389 f << 1 <<
" " << mesh->vertices[i][0] << std::endl;
391 for (
unsigned int i = 0; i < mesh->lines.size(); i++) {
393 for (
int j = 0; j < 2; j++)
394 f << mesh->lines[i][j] <<
" ";
398 for (
unsigned int i = 0; i < mesh->triangles.size(); i++) {
400 for (
int j = 0; j < 3; j++)
401 f << mesh->triangles[i][j] <<
" ";
405 for (
unsigned int i = 0; i < mesh->tetras.size(); i++) {
407 for (
int j = 0; j < 4; j++)
408 f << mesh->tetras[i][j] <<
" ";
412 for (
unsigned int i = 0; i < mesh->hexas.size(); i++) {
414 for (
int j = 0; j < 8; j++)
415 f << mesh->hexas[i][j] <<
" ";
419 f <<
"CELL_TYPES " << numberOfCells << std::endl;
420 for (
unsigned i = 0; i < mesh->vertices.size(); ++i)
423 for (
unsigned i = 0; i < mesh->lines.size(); ++i)
426 for (
unsigned i = 0; i < mesh->triangles.size(); ++i)
429 for (
unsigned i = 0; i < mesh->tetras.size(); ++i)
430 f << 10 << std::endl;
432 for (
unsigned i = 0; i < mesh->hexas.size(); ++i)
433 f << 12 << std::endl;
436 if (mesh->pointData.getScalarDataSize() ||
437 mesh->pointData.getVectorDataSize()) {
438 Logger::getInstance()
439 .addWarning(
"Point data output not supported for legacy VTK output. "
440 "Point data is ignored.")
445 if (mesh->cellData.getScalarDataSize()) {
446 f <<
"CELL_DATA " << mesh->cellData.getScalarData(0)->size() << std::endl;
447 for (
unsigned i = 0; i < mesh->cellData.getScalarDataSize(); ++i) {
448 auto scalars = *(mesh->cellData.getScalarData(i));
449 f <<
"SCALARS " << mesh->cellData.getScalarDataLabel(i) <<
" float"
451 f <<
"LOOKUP_TABLE default" << std::endl;
452 for (
unsigned j = 0; j < scalars.size(); ++j) {
453 f << ((std::abs(scalars[j]) < 1e-6) ? 0.0 : scalars[j]) << std::endl;
459 if (mesh->cellData.getVectorDataSize()) {
460 if (!mesh->cellData.getScalarDataSize())
461 f <<
"CELL_DATA " << mesh->cellData.getVectorData(0)->size()
463 for (
unsigned i = 0; i < mesh->cellData.getVectorDataSize(); ++i) {
464 auto vectors = *(mesh->cellData.getVectorData(i));
465 f <<
"VECTORS " << mesh->cellData.getVectorDataLabel(i) <<
" float"
467 for (
unsigned j = 0; j < vectors.size(); ++j) {
468 for (
unsigned k = 0; k < 3; ++k) {
469 f << vectors[j][k] <<
" ";