32 SmartPointer<Mesh<T>> mesh =
nullptr;
36#ifdef VIENNALS_USE_VTK
37 template <
class In,
class Out>
38 void addDataFromMesh(
const In &inData, Out outData)
const {
40 for (
unsigned i = 0; i < inData.getScalarDataSize(); ++i) {
41 vtkSmartPointer<vtkFloatArray> pointData =
42 vtkSmartPointer<vtkFloatArray>::New();
43 pointData->SetNumberOfComponents(1);
44 pointData->SetName(inData.getScalarDataLabel(i).c_str());
45 auto scalars = *(inData.getScalarData(i));
46 for (
unsigned j = 0; j < inData.getScalarData(i)->size(); ++j) {
47 pointData->InsertNextValue(scalars[j]);
49 outData->AddArray(pointData);
53 for (
unsigned i = 0; i < inData.getVectorDataSize(); ++i) {
54 vtkSmartPointer<vtkFloatArray> vectorData =
55 vtkSmartPointer<vtkFloatArray>::New();
56 vectorData->SetNumberOfComponents(3);
57 vectorData->SetName(inData.getVectorDataLabel(i).c_str());
58 auto vectors = *(inData.getVectorData(i));
59 for (
unsigned j = 0; j < inData.getVectorData(i)->size(); ++j) {
60 vectorData->InsertNextTuple3(vectors[j][0], vectors[j][1],
63 outData->AddArray(vectorData);
74 : mesh(passedMesh), fileName(passedFileName) {}
77 std::string passedFileName)
78 : mesh(passedMesh), fileFormat(passedFormat), fileName(passedFileName) {}
86 void setFileName(std::string passedFileName) { fileName = passedFileName; }
90 if (mesh ==
nullptr) {
92 .addWarning(
"No mesh was passed to VTKWriter. Not writing.")
97 if (fileName.empty()) {
99 .addWarning(
"No file name specified for VTKWriter. Not writing.")
105 auto dotPos = fileName.rfind(
'.');
106 if (dotPos == std::string::npos) {
109 auto ending = fileName.substr(dotPos);
110 if (ending ==
".vtk") {
112 }
else if (ending ==
".vtp") {
114 }
else if (ending ==
".vtu") {
117 Logger::getInstance()
118 .addWarning(
"No valid file format found based on the file ending "
119 "passed to VTKWriter. Not writing.")
127 switch (fileFormat) {
129 writeVTKLegacy(fileName);
131#ifdef VIENNALS_USE_VTK
141 Logger::getInstance()
142 .addWarning(
"VTKWriter was built without VTK support. Falling back "
145 writeVTKLegacy(fileName);
149 Logger::getInstance()
150 .addWarning(
"No valid file format set for VTKWriter. Not writing.")
156#ifdef VIENNALS_USE_VTK
157 void writeVTP(std::string filename)
const {
158 if (mesh ==
nullptr) {
159 Logger::getInstance()
160 .addWarning(
"No mesh was passed to VTKWriter.")
165 if (filename.find(
".vtp") != filename.size() - 4)
167 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
170 vtkSmartPointer<vtkPoints> polyPoints = vtkSmartPointer<vtkPoints>::New();
171 for (
auto it = mesh->getNodes().begin(); it != mesh->getNodes().end();
173 polyPoints->InsertNextPoint((*it)[0], (*it)[1], (*it)[2]);
175 polyData->SetPoints(polyPoints);
178 if (
mesh->vertices.size() > 0) {
179 vtkSmartPointer<vtkCellArray> polyCells =
180 vtkSmartPointer<vtkCellArray>::New();
181 for (
auto it =
mesh->vertices.begin(); it !=
mesh->vertices.end(); ++it) {
182 polyCells->InsertNextCell(1);
183 polyCells->InsertCellPoint((*it)[0]);
185 polyData->SetVerts(polyCells);
189 if (
mesh->lines.size() > 0) {
190 vtkSmartPointer<vtkCellArray> polyCells =
191 vtkSmartPointer<vtkCellArray>::New();
192 for (
auto it =
mesh->lines.begin(); it !=
mesh->lines.end(); ++it) {
193 polyCells->InsertNextCell(2);
194 for (
unsigned i = 0; i < 2; ++i) {
195 polyCells->InsertCellPoint((*it)[i]);
198 polyData->SetLines(polyCells);
202 if (
mesh->triangles.size() > 0) {
203 vtkSmartPointer<vtkCellArray> polyCells =
204 vtkSmartPointer<vtkCellArray>::New();
205 for (
auto it =
mesh->triangles.begin(); it !=
mesh->triangles.end();
207 polyCells->InsertNextCell(3);
208 for (
unsigned i = 0; i < 3; ++i) {
209 polyCells->InsertCellPoint((*it)[i]);
212 polyData->SetPolys(polyCells);
215 addDataFromMesh(
mesh->pointData, polyData->GetPointData());
216 addDataFromMesh(
mesh->cellData, polyData->GetCellData());
218 vtkSmartPointer<vtkXMLPolyDataWriter> pwriter =
219 vtkSmartPointer<vtkXMLPolyDataWriter>::New();
220 pwriter->SetFileName(filename.c_str());
221 pwriter->SetInputData(polyData);
225 void writeVTU(std::string filename)
const {
226 if (mesh ==
nullptr) {
227 Logger::getInstance()
228 .addWarning(
"No mesh was passed to VTKWriter.")
233 if (filename.find(
".vtu") != filename.size() - 4)
236 vtkSmartPointer<vtkUnstructuredGrid> uGrid =
237 vtkSmartPointer<vtkUnstructuredGrid>::New();
240 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
241 for (
auto it =
mesh->getNodes().begin(); it !=
mesh->getNodes().end();
243 points->InsertNextPoint((*it)[0], (*it)[1], (*it)[2]);
245 uGrid->SetPoints(points);
248 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
249 std::vector<int> cellTypes;
250 cellTypes.reserve(
mesh->vertices.size() +
mesh->lines.size() +
251 mesh->triangles.size() +
mesh->tetras.size() +
255 if (
mesh->vertices.size() > 0) {
256 for (
auto it =
mesh->vertices.begin(); it !=
mesh->vertices.end(); ++it) {
257 cells->InsertNextCell(1);
258 cells->InsertCellPoint((*it)[0]);
259 cellTypes.push_back(1);
264 if (
mesh->lines.size() > 0) {
265 for (
auto it =
mesh->lines.begin(); it !=
mesh->lines.end(); ++it) {
266 cells->InsertNextCell(2);
267 for (
unsigned i = 0; i < 2; ++i) {
268 cells->InsertCellPoint((*it)[i]);
270 cellTypes.push_back(3);
275 if (
mesh->triangles.size() > 0) {
276 for (
auto it =
mesh->triangles.begin(); it !=
mesh->triangles.end();
278 cells->InsertNextCell(3);
279 for (
unsigned i = 0; i < 3; ++i) {
280 cells->InsertCellPoint((*it)[i]);
282 cellTypes.push_back(5);
287 if (
mesh->tetras.size() > 0) {
288 for (
auto it =
mesh->tetras.begin(); it !=
mesh->tetras.end(); ++it) {
289 cells->InsertNextCell(4);
290 for (
unsigned i = 0; i < 4; ++i) {
291 cells->InsertCellPoint((*it)[i]);
293 cellTypes.push_back(10);
298 if (
mesh->hexas.size() > 0) {
299 for (
auto it =
mesh->hexas.begin(); it !=
mesh->hexas.end(); ++it) {
300 cells->InsertNextCell(8);
301 for (
unsigned i = 0; i < 8; ++i) {
302 cells->InsertCellPoint((*it)[i]);
304 cellTypes.push_back(12);
309 uGrid->SetCells(&(cellTypes[0]), cells);
311 addDataFromMesh(
mesh->pointData, uGrid->GetPointData());
312 addDataFromMesh(
mesh->cellData, uGrid->GetCellData());
341 vtkSmartPointer<vtkXMLUnstructuredGridWriter> owriter =
342 vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
343 owriter->SetFileName(filename.c_str());
344 owriter->SetInputData(uGrid);
350 void writeVTKLegacy(std::string filename) {
351 if (mesh ==
nullptr) {
352 Logger::getInstance()
353 .addWarning(
"No mesh was passed to VTKWriter.")
358 std::ofstream f(filename.c_str());
360 f <<
"# vtk DataFile Version 2.0" << std::endl;
361 f << ((!
mesh->lines.empty()) ? 2 : 3) <<
"D Surface" << std::endl;
362 f <<
"ASCII" << std::endl;
363 f <<
"DATASET UNSTRUCTURED_GRID" << std::endl;
364 f <<
"POINTS " <<
mesh->nodes.size() <<
" float" << std::endl;
367 for (
unsigned int i = 0; i <
mesh->nodes.size(); i++) {
368 for (
int j = 0; j < 3; j++)
369 f <<
static_cast<float>(
mesh->nodes[i][j]) <<
" ";
373 const unsigned numberOfCells =
mesh->vertices.size() +
mesh->lines.size() +
374 mesh->triangles.size() +
375 mesh->tetras.size() +
mesh->hexas.size();
376 const unsigned cellDataSize =
377 2 *
mesh->vertices.size() + 3 *
mesh->lines.size() +
378 4 *
mesh->triangles.size() + 5 *
mesh->tetras.size() +
379 9 *
mesh->hexas.size();
381 f <<
"CELLS " << numberOfCells <<
" " << cellDataSize << std::endl;
384 for (
unsigned int i = 0; i <
mesh->vertices.size(); i++) {
385 f << 1 <<
" " <<
mesh->vertices[i][0] << std::endl;
387 for (
unsigned int i = 0; i <
mesh->lines.size(); i++) {
389 for (
int j = 0; j < 2; j++)
390 f <<
mesh->lines[i][j] <<
" ";
394 for (
unsigned int i = 0; i <
mesh->triangles.size(); i++) {
396 for (
int j = 0; j < 3; j++)
397 f <<
mesh->triangles[i][j] <<
" ";
401 for (
unsigned int i = 0; i <
mesh->tetras.size(); i++) {
403 for (
int j = 0; j < 4; j++)
404 f <<
mesh->tetras[i][j] <<
" ";
408 for (
unsigned int i = 0; i <
mesh->hexas.size(); i++) {
410 for (
int j = 0; j < 8; j++)
411 f <<
mesh->hexas[i][j] <<
" ";
415 f <<
"CELL_TYPES " << numberOfCells << std::endl;
416 for (
unsigned i = 0; i <
mesh->vertices.size(); ++i)
419 for (
unsigned i = 0; i <
mesh->lines.size(); ++i)
422 for (
unsigned i = 0; i <
mesh->triangles.size(); ++i)
425 for (
unsigned i = 0; i <
mesh->tetras.size(); ++i)
426 f << 10 << std::endl;
428 for (
unsigned i = 0; i <
mesh->hexas.size(); ++i)
429 f << 12 << std::endl;
432 if (
mesh->pointData.getScalarDataSize() ||
433 mesh->pointData.getVectorDataSize()) {
434 Logger::getInstance()
435 .addWarning(
"Point data output not supported for legacy VTK output. "
436 "Point data is ignored.")
441 if (
mesh->cellData.getScalarDataSize()) {
442 f <<
"CELL_DATA " <<
mesh->cellData.getScalarData(0)->size() << std::endl;
443 for (
unsigned i = 0; i <
mesh->cellData.getScalarDataSize(); ++i) {
444 auto scalars = *(
mesh->cellData.getScalarData(i));
445 f <<
"SCALARS " <<
mesh->cellData.getScalarDataLabel(i) <<
" float"
447 f <<
"LOOKUP_TABLE default" << std::endl;
448 for (
unsigned j = 0; j < scalars.size(); ++j) {
449 f << ((std::abs(scalars[j]) < 1e-6) ? 0.0 : scalars[j]) << std::endl;
455 if (
mesh->cellData.getVectorDataSize()) {
456 if (!
mesh->cellData.getScalarDataSize())
457 f <<
"CELL_DATA " <<
mesh->cellData.getVectorData(0)->size()
459 for (
unsigned i = 0; i <
mesh->cellData.getVectorDataSize(); ++i) {
460 auto vectors = *(
mesh->cellData.getVectorData(i));
461 f <<
"VECTORS " <<
mesh->cellData.getVectorDataLabel(i) <<
" float"
463 for (
unsigned j = 0; j < vectors.size(); ++j) {
464 for (
unsigned k = 0; k < 3; ++k) {
465 f << vectors[j][k] <<
" ";