NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
vtkMesh.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #include "Drivers/TransferDriver.H"
30 #include "Mesh/vtkMesh.H"
31 
32 #include <sstream>
33 
34 #include <vtkAppendFilter.h>
35 #include <vtkCellData.h>
36 #include <vtkCellIterator.h>
37 #include <vtkCellTypes.h>
38 #include <vtkDataSetReader.h>
39 #include <vtkDataSetSurfaceFilter.h>
40 #include <vtkDoubleArray.h>
41 #include <vtkExtractEdges.h>
42 #include <vtkFieldData.h>
43 #include <vtkGenericCell.h>
44 #include <vtkGenericDataObjectReader.h>
45 #include <vtkImageData.h>
46 #include <vtkPointData.h>
47 #include <vtkRectilinearGrid.h>
48 #include <vtkSTLReader.h>
49 #include <vtkSTLWriter.h>
50 #include <vtkStructuredGrid.h>
51 #include <vtkTriangleFilter.h>
52 #include <vtkUnstructuredGridWriter.h>
53 #include <vtkXMLImageDataReader.h>
54 #include <vtkXMLImageDataWriter.h>
55 #include <vtkXMLPolyDataReader.h>
56 #include <vtkXMLPolyDataWriter.h>
57 #include <vtkXMLRectilinearGridReader.h>
58 #include <vtkXMLRectilinearGridWriter.h>
59 #include <vtkXMLStructuredGridReader.h>
60 #include <vtkXMLStructuredGridWriter.h>
61 #include <vtkXMLUnstructuredGridReader.h>
62 #include <vtkXMLUnstructuredGridWriter.h>
63 #include <vtkXMLWriter.h>
64 #include <vtksys/SystemTools.hxx>
65 
66 #include "AuxiliaryFunctions.H"
67 
68 using nemAux::operator*; // for vector multiplication.
69 using nemAux::operator+; // for vector addition.
70 
71 void vtkMesh::write(const std::string &fname) const {
72  if (!dataSet) {
73  std::cout << "No dataSet to write!" << std::endl;
74  exit(1);
75  }
76 
77  std::string extension = nemAux::find_ext(fname);
78 
79  if (extension == ".vtp")
80  writeVTFile<vtkXMLPolyDataWriter>(fname, dataSet);
81  else if (extension == ".vts")
82  writeVTFile<vtkXMLStructuredGridWriter>(fname, dataSet);
83  else if (extension == ".vtr")
84  writeVTFile<vtkXMLRectilinearGridWriter>(fname, dataSet);
85  else if (extension == ".vti")
86  writeVTFile<vtkXMLImageDataWriter>(fname, dataSet);
87  else if (extension == ".stl")
88  writeVTFile<vtkSTLWriter>(fname, dataSet); // ascii stl
89  else if (extension == ".vtk")
90  writeVTFile<vtkUnstructuredGridWriter>(fname,
91  dataSet); // legacy vtk writer
92  else {
93  std::string fname_tmp = nemAux::trim_fname(fname, ".vtu");
94  // default is vtu
95  writeVTFile<vtkXMLUnstructuredGridWriter>(fname_tmp, dataSet);
96  }
97 }
98 
99 vtkMesh::vtkMesh(vtkSmartPointer<vtkDataSet> dataSet_tmp,
100  const std::string &fname) {
101  if (dataSet_tmp) {
102  dataSet = dataSet_tmp;
103  filename = fname;
104  numCells = dataSet->GetNumberOfCells();
105  numPoints = dataSet->GetNumberOfPoints();
106  std::cout << "vtkMesh constructed" << std::endl;
107  } else {
108  std::cerr << "Nothing to copy!" << std::endl;
109  exit(1);
110  }
111 }
112 
113 vtkMesh::vtkMesh(const std::vector<double> &xCrds,
114  const std::vector<double> &yCrds,
115  const std::vector<double> &zCrds,
116  const std::vector<nemId_t> &elemConn, const int cellType,
117  const std::string &newname) {
118  if (!(xCrds.size() == yCrds.size() && xCrds.size() == zCrds.size())) {
119  std::cerr << "Length of coordinate arrays must match!" << std::endl;
120  exit(1);
121  }
122 
123  // point to be pushed into dataSet
124  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
125  // declare vtk dataset
126  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp =
128  numPoints = xCrds.size();
129  // allocate size for vtk point container
130  points->SetNumberOfPoints(numPoints);
131  for (nemId_t i = 0; i < numPoints; ++i)
132  points->SetPoint(i, xCrds[i], yCrds[i], zCrds[i]);
133 
134  // add points to vtk mesh data structure
135  dataSet_tmp->SetPoints(points);
136  switch (cellType) {
137  case VTK_TETRA: {
138  numCells = elemConn.size() / 4;
139  dataSet_tmp->Allocate(numCells);
140  for (nemId_t i = 0; i < numCells; ++i) {
141  vtkSmartPointer<vtkIdList> elmConn = vtkSmartPointer<vtkIdList>::New();
142  elmConn->SetNumberOfIds(4);
143  for (nemId_t j = 0; j < 4; ++j) elmConn->SetId(j, elemConn[i * 4 + j]);
144  dataSet_tmp->InsertNextCell(VTK_TETRA, elmConn);
145  }
146  break;
147  }
148  case VTK_TRIANGLE: {
149  numCells = elemConn.size() / 3;
150  dataSet_tmp->Allocate(numCells);
151  for (nemId_t i = 0; i < numCells; ++i) {
152  vtkSmartPointer<vtkIdList> elmConn = vtkSmartPointer<vtkIdList>::New();
153  elmConn->SetNumberOfIds(3);
154  for (nemId_t j = 0; j < 3; ++j) elmConn->SetId(j, elemConn[i * 3 + j]);
155  dataSet_tmp->InsertNextCell(VTK_TRIANGLE, elmConn);
156  }
157  break;
158  }
159  default: {
160  std::cout << "Unknown element type " << cellType << std::endl;
161  exit(1);
162  }
163  }
164  filename = newname;
165  dataSet = dataSet_tmp;
166  std::cout << "vtkMesh constructed" << std::endl;
167 }
168 
169 vtkMesh::vtkMesh(const std::string &fname) {
170  bool degenerate(false);
171  std::string extension = vtksys::SystemTools::GetFilenameLastExtension(fname);
172  // Dispatch based on the file extension
173  if (extension == ".vtu")
174  dataSet.TakeReference(
175  ReadAnXMLOrSTLFile<vtkXMLUnstructuredGridReader>(fname));
176  else if (extension == ".vtp")
177  dataSet.TakeReference(ReadAnXMLOrSTLFile<vtkXMLPolyDataReader>(fname));
178  else if (extension == ".vts")
179  dataSet.TakeReference(
180  ReadAnXMLOrSTLFile<vtkXMLStructuredGridReader>(fname));
181  else if (extension == ".vtr")
182  dataSet.TakeReference(
183  ReadAnXMLOrSTLFile<vtkXMLRectilinearGridReader>(fname));
184  else if (extension == ".vti")
185  dataSet.TakeReference(ReadAnXMLOrSTLFile<vtkXMLImageDataReader>(fname));
186  else if (extension == ".stl")
187  dataSet.TakeReference(ReadAnXMLOrSTLFile<vtkSTLReader>(fname));
188  else if (extension == ".vtk") {
189  // if vtk is produced by MFEM, it's probably degenerate (i.e. point
190  // duplicity) in this case, we use a different reader to correct duplicity
191  // and transfer the data attributes read by the regular legacy reader using
192  // the transfer methods in meshBase
193  std::ifstream meshStream(fname);
194  if (!meshStream.good()) {
195  std::cout << "Error opening file " << fname << std::endl;
196  exit(1);
197  }
198  std::string line;
199  getline(meshStream, line);
200  getline(meshStream, line);
201  meshStream.close();
202  if (line.find("MFEM") != std::string::npos) {
203  degenerate = true;
204  dataSet = vtkDataSet::SafeDownCast(ReadDegenerateVTKFile(fname));
205  setFileName(fname);
206  numCells = dataSet->GetNumberOfCells();
207  numPoints = dataSet->GetNumberOfPoints();
208  vtkMesh *vtkMesh_tmp = new vtkMesh(
209  vtkDataSet::SafeDownCast(ReadALegacyVTKFile(fname)), fname);
210  // vtkMesh_tmp.transfer(this, "Consistent Interpolation");
212  vtkMesh_tmp, this, "Consistent Interpolation");
213  transfer->run(vtkMesh_tmp->getNewArrayNames());
214  std::cout << "vtkMesh constructed" << std::endl;
215  } else {
216  // reading legacy formated vtk files
217  vtkSmartPointer<vtkGenericDataObjectReader> reader =
219  // vtkSmartPointer<vtkDataSetReader> reader =
220  // vtkSmartPointer<vtkDataSetReader>::New();
221  reader->SetFileName(fname.c_str());
222  reader->Update();
223  reader->GetOutput()->Register(reader);
224  // obtaining dataset
225  dataSet.TakeReference(vtkDataSet::SafeDownCast(reader->GetOutput()));
226  }
227  } else {
228  std::cerr << "Unknown extension: " << extension << std::endl;
229  exit(1);
230  }
231 
232  if (!dataSet) {
233  std::cout << "Error populating dataSet" << std::endl;
234  exit(1);
235  }
236 
237  if (!degenerate) {
238  setFileName(fname);
239  std::cout << "vtkMesh constructed" << std::endl;
240  numCells = dataSet->GetNumberOfCells();
241  numPoints = dataSet->GetNumberOfPoints();
242  }
243 }
244 
245 vtkMesh::vtkMesh(const std::string &fname1, const std::string &fname2) {
246  std::string ext_in = vtksys::SystemTools::GetFilenameLastExtension(fname1);
247  std::string ext_out = vtksys::SystemTools::GetFilenameLastExtension(fname2);
248 
249  // sanity check
250  if (!(ext_in == ".vtu" && ext_out == ".stl")) {
251  std::cerr
252  << "vtkMesh: Currently only support conversion between vtu and stl."
253  << std::endl;
254  exit(1);
255  }
256 
257  vtkSmartPointer<vtkXMLUnstructuredGridReader> reader =
259  reader->SetFileName(fname1.c_str());
260  reader->Update();
261  reader->GetOutput()->Register(reader);
262 
263  // obtaining dataset
264  dataSet.TakeReference(vtkDataSet::SafeDownCast(reader->GetOutput()));
265  if (!dataSet) {
266  std::cout << "Error populating dataSet" << std::endl;
267  exit(1);
268  }
269  setFileName(fname1);
270  std::cout << "vtkMesh constructed" << std::endl;
271  numCells = dataSet->GetNumberOfCells();
272  numPoints = dataSet->GetNumberOfPoints();
273 
274  // skinn to the surface
275  vtkSmartPointer<vtkDataSetSurfaceFilter> surfFilt =
277  surfFilt->SetInputConnection(reader->GetOutputPort());
278  surfFilt->Update();
279 
280  // triangulate the surface
281  vtkSmartPointer<vtkTriangleFilter> triFilt =
283  triFilt->SetInputConnection(surfFilt->GetOutputPort());
284  triFilt->Update();
285 
286  // write to stl file
287  vtkSmartPointer<vtkSTLWriter> stlWriter =
289  stlWriter->SetFileName(fname2.c_str());
290  stlWriter->SetInputConnection(triFilt->GetOutputPort());
291  stlWriter->Write();
292 }
293 
294 bool readLegacyVTKHeader(const std::string &line) {
295  if (line.find("DATASET") != -1) {
296  if (line.find("UNSTRUCTURED_GRID") == std::string::npos) {
297  std::cerr << "Reading a " << line << " is not supported" << std::endl;
298  exit(1);
299  }
300  return true;
301  }
302  return false;
303 }
304 
305 bool readLegacyVTKFieldData(std::istream &meshStream, std::string &line,
306  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp) {
307  if (line.find("FIELD") != std::string::npos) {
308  if (getline(meshStream, line)) {
309  std::string arrname, type;
310  int numComponent;
311  nemId_t numTuple;
312  std::stringstream ss;
313  ss.str(line);
314  ss >> arrname >> numComponent >> numTuple >> type;
315  vtkSmartPointer<vtkDoubleArray> arr =
317  arr->SetName(arrname.c_str());
318  arr->SetNumberOfComponents(numComponent);
319  arr->SetNumberOfTuples(numTuple);
320  getline(meshStream, line);
321  ss.str(line);
322  double val;
323  for (int i = 0; i < numTuple; ++i) {
324  ss >> val;
325  arr->InsertTuple(i, &val);
326  }
327  dataSet_tmp->GetFieldData()->AddArray(arr);
328  return true;
329  }
330  }
331  return false;
332 }
333 
334 bool readLegacyVTKPoints(std::istream &meshStream, std::string &line,
335  nemId_t &numPoints, vtkSmartPointer<vtkPoints> points,
336  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp) {
337  if (line.find("POINTS") != std::string::npos) {
338  std::istringstream ss(line);
339  std::string tmp;
340  ss >> tmp >> numPoints;
341  points->SetNumberOfPoints(numPoints);
342  double point[3];
343  nemId_t i = 0;
344  while (getline(meshStream, line) && i < numPoints) {
345  if (!line.empty()) {
346  std::istringstream ss(line);
347  ss >> point[0] >> point[1] >> point[2];
348  points->SetPoint(i, point);
349  ++i;
350  }
351  }
352  dataSet_tmp->SetPoints(points);
353  return true;
354  }
355  return false;
356 }
357 
358 bool readLegacyVTKCells(std::istream &meshStream, std::string &line,
359  nemId_t &numCells,
360  std::vector<vtkSmartPointer<vtkIdList>> &vtkCellIds,
361  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp) {
362  if (line.find("CELLS") != std::string::npos) {
363  std::istringstream ss(line);
364  std::string tmp;
365  ss >> tmp >> numCells;
366  vtkCellIds.resize(numCells);
367  // get cells
368  nemId_t i = 0;
369  while (i < numCells && getline(meshStream, line)) {
370  if (!line.empty()) {
371  std::istringstream ss(line);
372  nemId_t numId;
373  nemId_t id;
374  ss >> numId;
375  vtkCellIds[i] = vtkSmartPointer<vtkIdList>::New();
376  vtkCellIds[i]->SetNumberOfIds(numId);
377  for (nemId_t j = 0; j < numId; ++j) {
378  ss >> id;
379  vtkCellIds[i]->SetId(j, id);
380  }
381  ++i;
382  }
383  }
384  // get cell types
385  while (getline(meshStream, line)) {
386  if (line.find("CELL_TYPES") != std::string::npos) {
387  dataSet_tmp->Allocate(numCells);
388  i = 0;
389  while (i < numCells && getline(meshStream, line)) {
390  if (!line.empty()) {
391  std::istringstream ss(line);
392  int cellType;
393  ss >> cellType;
394  dataSet_tmp->InsertNextCell(cellType, vtkCellIds[i]);
395  ++i;
396  }
397  }
398  break;
399  }
400  }
401  return true;
402  }
403  return false;
404 }
405 
406 bool readLegacyVTKData(std::ifstream &meshStream, std::string &line,
407  const nemId_t numTuple, const bool pointOrCell,
408  bool &hasPointOrCell,
409  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp) {
410  // determines whether more than one point or cell array in dataSet
411  bool inProgress(true);
412  // while there is a cell or point array to be read
413  while (inProgress) {
414  int numComponent(0);
415  std::string line, attribute, name, type;
416  vtkSmartPointer<vtkDoubleArray> arr =
418  while (getline(meshStream, line)) {
419  if (!line.empty()) {
420  if (line.find("LOOKUP_TABLE default") != std::string::npos) break;
421 
422  size_t hasScalar = line.find("SCALARS");
423  size_t hasVector = line.find("VECTORS");
424  size_t hasNormal = line.find("NORMALS");
425  if (hasScalar == std::string::npos && hasVector == std::string::npos &&
426  hasNormal == std::string::npos) {
427  std::cerr << "attribute type in " << line << " not supported"
428  << std::endl;
429  exit(1);
430  } else {
431  std::istringstream ss(line);
432  ss >> attribute >> name >> type >> numComponent;
433  if (hasScalar != std::string::npos)
434  numComponent =
435  numComponent > 4 || numComponent < 1 ? 1 : numComponent;
436  else if (hasVector != std::string::npos ||
437  hasNormal != std::string::npos)
438  numComponent = 3;
439  arr->SetName(name.c_str());
440  arr->SetNumberOfComponents(numComponent);
441  arr->SetNumberOfTuples(numTuple);
442  // std::cout << arr->GetName() << " " << arr->GetNumberOfComponents()
443  // << " " << arr->GetNumberOfTuples() << std::endl;
444  break;
445  }
446  }
447  }
448 
449  nemId_t i = 0;
450  while (i < numTuple && getline(meshStream, line)) {
451  if (!line.empty() && line.find("LOOKUP") == std::string::npos) {
452  std::istringstream ss(line);
453  // double vals[numComponent];
454  std::vector<double> vals;
455  vals.resize(numComponent, 0.);
456 
457  for (int j = 0; j < numComponent; ++j) ss >> vals[j];
458  arr->InsertTuple(i, vals.data());
459  ++i;
460  }
461  }
462 
463  if (pointOrCell)
464  dataSet_tmp->GetPointData()->AddArray(arr);
465  else
466  dataSet_tmp->GetCellData()->AddArray(arr);
467 
468  bool moreData(false);
469  std::streampos curr = meshStream.tellg();
470  while (getline(meshStream, line)) {
471  // if point data encountered while looking for more cell data, we know we
472  // read all cell data
473  if (line.find("POINT_DATA") != std::string::npos && !pointOrCell) {
474  curr = meshStream.tellg();
475  hasPointOrCell = true;
476  break;
477  }
478  // if cell data encountered while looking for more point data, we know we
479  // read all point data
480  if (line.find("CELL_DATA") != std::string::npos && pointOrCell) {
481  hasPointOrCell = true;
482  curr = meshStream.tellg();
483  break;
484  }
485  // if the previous two conditions are not met and this one is,
486  // we know we have more than one point/cell data array
487  if (line.find("SCALARS") != std::string::npos ||
488  line.find("VECTORS") != std::string::npos ||
489  line.find("NORMALS") != std::string::npos) {
490  moreData = true;
491  break;
492  }
493  }
494 
495  meshStream.seekg(curr);
496 
497  if (!moreData) inProgress = false;
498  }
499  return true;
500 }
501 
502 vtkSmartPointer<vtkUnstructuredGrid> ReadALegacyVTKFile(
503  const std::string &fileName) {
504  std::ifstream meshStream;
505  meshStream.open(fileName, std::ifstream::in);
506  if (!meshStream.good()) {
507  std::cerr << "Could not open file " << fileName << std::endl;
508  exit(1);
509  }
510 
511  // declare points to be pushed into dataSet_tmp
512  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
513  // declare vector of cell ids to be pushed into dataSet_tmp
514  std::vector<vtkSmartPointer<vtkIdList>> vtkCellIds;
515  // declare dataSet_tmp which will be associated to output vtkMesh
516  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp =
518  nemId_t numPoints(0), numCells(0);
519  bool readHeader(false), readPoints(false), readCells(false),
520  readFieldData(false), readCellData(false), readPointData(false),
521  cellDataFirst(false), pointDataFirst(false), hasPointData(false),
522  hasCellData(false);
523  std::string line;
524 
525  while (getline(meshStream, line)) {
526  if (!readHeader)
527  if ((readHeader = readLegacyVTKHeader(line)))
528  std::cout << "read header" << std::endl;
529 
530  if (!readFieldData)
531  if ((readFieldData =
532  readLegacyVTKFieldData(meshStream, line, dataSet_tmp)))
533  std::cout << "read field data" << std::endl;
534 
535  if (!readPoints)
536  if ((readPoints = readLegacyVTKPoints(meshStream, line, numPoints, points,
537  dataSet_tmp)))
538  std::cout << "read points" << std::endl;
539 
540  if (!readCells)
541  if ((readCells = readLegacyVTKCells(meshStream, line, numCells,
542  vtkCellIds, dataSet_tmp)))
543  std::cout << "read cells" << std::endl;
544 
545  // call functions based on which data appears first in file
546  if (!readCellData && !readPointData) {
547  cellDataFirst =
548  line.find("CELL_DATA") != std::string::npos && !pointDataFirst;
549  pointDataFirst =
550  line.find("POINT_DATA") != std::string::npos && !cellDataFirst;
551  }
552 
553  // read cell data then point data if it exists
554  if (cellDataFirst) {
555  if (!readCellData) // boolean telling us if there is point data
556  if ((readCellData = readLegacyVTKData(meshStream, line, numCells, false,
557  hasPointData, dataSet_tmp)))
558  std::cout << "read cell data" << std::endl;
559 
560  if (!readPointData && hasPointData)
561  if ((readPointData = readLegacyVTKData(meshStream, line, numPoints,
562  true, hasCellData, dataSet_tmp)))
563  std::cout << "read point data" << std::endl;
564  }
565  // read point data and then cell data if it exists
566  else if (pointDataFirst) {
567  if (!readPointData)
568  if ((readPointData = readLegacyVTKData(meshStream, line, numPoints,
569  true, hasCellData, dataSet_tmp)))
570  std::cout << "read point data" << std::endl;
571 
572  if (!readCellData && hasCellData)
573  if ((readCellData = readLegacyVTKData(meshStream, line, numCells, false,
574  hasPointData, dataSet_tmp)))
575  std::cout << "read cell data" << std::endl;
576  }
577  }
578  return dataSet_tmp;
579 }
580 
581 vtkSmartPointer<vtkUnstructuredGrid> ReadDegenerateVTKFile(
582  const std::string &fileName) {
583  std::ifstream meshStream(fileName);
584  if (!meshStream.good()) {
585  std::cerr << "Error opening file " << fileName << std::endl;
586  exit(1);
587  }
588 
589  std::string line;
590  std::map<std::vector<double>, int> point_map;
591  std::map<int, int> duplicate_point_map;
592  std::pair<std::map<std::vector<double>, int>::iterator, bool> point_ret;
593  int numPoints;
594  int numCells;
595  int cellListSize;
596  std::vector<vtkSmartPointer<vtkIdList>> vtkCellIds;
597  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp =
599  while (getline(meshStream, line)) {
600  if (line.find("POINTS") != std::string::npos) {
601  std::istringstream ss(line);
602  std::string tmp;
603  ss >> tmp >> numPoints;
604  std::vector<double> point(3);
605  int pntId = 0;
606  int realPntId = 0;
607  while (getline(meshStream, line) && pntId < numPoints) {
608  if (!line.empty()) {
609  std::istringstream ss(line);
610  ss >> point[0] >> point[1] >> point[2];
611  point_ret = point_map.insert(
612  std::pair<std::vector<double>, int>(point, realPntId));
613  if (point_ret.second) ++realPntId;
614  duplicate_point_map.insert(
615  std::pair<int, int>(pntId, point_ret.first->second));
616  ++pntId;
617  }
618  }
619  }
620 
621  if (line.find("CELLS") != std::string::npos) {
622  std::istringstream ss(line);
623  std::string tmp;
624  ss >> tmp >> numCells >> cellListSize;
625  int cellId = 0;
626  // int realCellId = 0;
627  vtkCellIds.resize(numCells);
628  while (cellId < numCells && getline(meshStream, line)) {
629  if (!line.empty()) {
630  std::istringstream ss(line);
631  int numId;
632  int id;
633  ss >> numId;
634  vtkCellIds[cellId] = vtkSmartPointer<vtkIdList>::New();
635  vtkCellIds[cellId]->SetNumberOfIds(numId);
636  // cells[cellId].resize(numId);
637  for (int j = 0; j < numId; ++j) {
638  ss >> id;
639  vtkCellIds[cellId]->SetId(j, duplicate_point_map[id]);
640  // cells[cellId][j] = duplicate_point_map[id];
641  }
642  ++cellId;
643  }
644  }
645  // get cell types
646  while (getline(meshStream, line)) {
647  if (line.find("CELL_TYPES") != std::string::npos) {
648  dataSet_tmp->Allocate(numCells);
649  cellId = 0;
650  // cellTypes.resize(numCells);
651  while (cellId < numCells && getline(meshStream, line)) {
652  if (!line.empty()) {
653  std::istringstream ss(line);
654  int cellType;
655  ss >> cellType;
656  // cellTypes[cellId] = cellType;
657  dataSet_tmp->InsertNextCell(cellType, vtkCellIds[cellId]);
658  ++cellId;
659  }
660  }
661  break;
662  }
663  }
664  }
665  }
666 
667  std::multimap<int, std::vector<double>> flipped = nemAux::flip_map(point_map);
668  auto flip_it = flipped.begin();
669 
670  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
671  points->SetNumberOfPoints(point_map.size());
672  int pnt = 0;
673  while (flip_it != flipped.end()) {
674  points->SetPoint(pnt, flip_it->second.data());
675  ++flip_it;
676  ++pnt;
677  }
678  dataSet_tmp->SetPoints(points);
679  return dataSet_tmp;
680 }
681 
682 // get point with id
683 std::vector<double> vtkMesh::getPoint(nemId_t id) const {
684  double coords[3];
685  dataSet->GetPoint(id, coords);
686  std::vector<double> result(coords, coords + 3);
687  return result;
688 }
689 
690 // get 3 vectors with x,y and z coords
691 std::vector<std::vector<double>> vtkMesh::getVertCrds() const {
692  std::vector<std::vector<double>> comp_crds(3);
693  for (int i = 0; i < 3; ++i) comp_crds[i].resize(numPoints);
694 
695  double coords[3];
696  for (nemId_t i = 0; i < numPoints; ++i) {
697  dataSet->GetPoint(i, coords);
698  comp_crds[0][i] = coords[0];
699  comp_crds[1][i] = coords[1];
700  comp_crds[2][i] = coords[2];
701  }
702  return comp_crds;
703 }
704 
705 // get cell with id : returns point indices and respective coordinates
706 std::map<nemId_t, std::vector<double>> vtkMesh::getCell(nemId_t id) const {
707  if (id < numCells) {
708  std::map<nemId_t, std::vector<double>> cell;
709  vtkSmartPointer<vtkIdList> point_ids = vtkSmartPointer<vtkIdList>::New();
710  point_ids = dataSet->GetCell(id)->GetPointIds();
711  nemId_t num_ids = point_ids->GetNumberOfIds();
712  for (nemId_t i = 0; i < num_ids; ++i) {
713  nemId_t pntId = point_ids->GetId(i);
714  std::vector<double> coord = getPoint(pntId);
715  cell.insert(std::pair<nemId_t, std::vector<double>>(pntId, coord));
716  }
717  return cell;
718  } else {
719  std::cerr << "Cell ID is out of range!" << std::endl;
720  exit(1);
721  }
722 }
723 
724 std::vector<std::vector<double>> vtkMesh::getCellVec(nemId_t id) const {
725  if (id < numCells) {
726  std::vector<std::vector<double>> cell;
727  vtkSmartPointer<vtkIdList> point_ids = vtkSmartPointer<vtkIdList>::New();
728  point_ids = dataSet->GetCell(id)->GetPointIds();
729  nemId_t num_ids = point_ids->GetNumberOfIds();
730  cell.resize(num_ids);
731  for (nemId_t i = 0; i < num_ids; ++i) {
732  nemId_t pntId = point_ids->GetId(i);
733  cell[i] = getPoint(pntId);
734  }
735  return cell;
736  } else {
737  std::cerr << "Cell ID is out of range!" << std::endl;
738  exit(1);
739  }
740 }
741 
742 void vtkMesh::inspectEdges(const std::string &ofname) const {
743  std::ofstream outputStream(ofname);
744  if (!outputStream.good()) {
745  std::cerr << "error opening " << ofname << std::endl;
746  exit(1);
747  }
748 
749  vtkSmartPointer<vtkExtractEdges> extractEdges =
751  extractEdges->SetInputData(dataSet);
752  extractEdges->Update();
753 
754  vtkSmartPointer<vtkGenericCell> genCell =
756  for (nemId_t i = 0; i < extractEdges->GetOutput()->GetNumberOfCells(); ++i) {
757  extractEdges->GetOutput()->GetCell(i, genCell);
758  vtkPoints *points = genCell->GetPoints();
759  double p1[3], p2[3];
760  points->GetPoint(0, p1);
761  points->GetPoint(1, p2);
762  double len = sqrt(pow(p1[0] - p2[0], 2) + pow(p1[1] - p2[1], 2) +
763  pow(p1[2] - p2[2], 2));
764  outputStream << len << std::endl;
765  }
766 }
767 
768 std::vector<nemId_t> vtkMesh::getConnectivities() const {
769  std::vector<nemId_t> connectivities;
770  vtkSmartPointer<vtkCellIterator> it =
771  vtkSmartPointer<vtkCellIterator>::Take(dataSet->NewCellIterator());
772  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
773  vtkSmartPointer<vtkIdList> pointIds = it->GetPointIds();
774  for (nemId_t i = 0; i < pointIds->GetNumberOfIds(); ++i)
775  connectivities.push_back(pointIds->GetId(i));
776  }
777  return connectivities;
778 }
779 
780 void vtkMesh::report() const {
781  if (!dataSet) {
782  std::cout << "dataSet has not been populated!" << std::endl;
783  exit(1);
784  }
785 
786  using CellContainer = std::map<int, nemId_t>;
787  // Generate a report
788  std::cout << "Processing the dataset generated from " << filename << std::endl
789  << " dataset contains a " << dataSet->GetClassName() << " that has "
790  << numCells << " cells and " << numPoints << " points."
791  << std::endl;
792 
793  CellContainer cellMap;
794  for (nemId_t i = 0; i < numCells; i++) cellMap[dataSet->GetCellType(i)]++;
795 
796  CellContainer::const_iterator it = cellMap.begin();
797  while (it != cellMap.end()) {
798  std::cout << "\tCell type "
799  << vtkCellTypes::GetClassNameFromTypeId(it->first) << " occurs "
800  << it->second << " times." << std::endl;
801  ++it;
802  }
803 
804  // Now check for point data
805  vtkPointData *pd = dataSet->GetPointData();
806  if (pd) {
807  std::cout << " contains point data with " << pd->GetNumberOfArrays()
808  << " arrays." << std::endl;
809  for (int i = 0; i < pd->GetNumberOfArrays(); ++i) {
810  std::cout << "\tArray " << i << " is named "
811  << (pd->GetArrayName(i) ? pd->GetArrayName(i) : "NULL");
812  vtkDataArray *da = pd->GetArray(i);
813  std::cout << " with " << da->GetNumberOfTuples() << " values. "
814  << std::endl;
815  }
816  }
817 
818  // Now check for cell data
819  vtkCellData *cd = dataSet->GetCellData();
820  if (cd) {
821  std::cout << " contains cell data with " << cd->GetNumberOfArrays()
822  << " arrays." << std::endl;
823  for (int i = 0; i < cd->GetNumberOfArrays(); ++i) {
824  std::cout << "\tArray " << i << " is named "
825  << (cd->GetArrayName(i) ? cd->GetArrayName(i) : "NULL");
826  vtkDataArray *da = cd->GetArray(i);
827  std::cout << " with " << da->GetNumberOfTuples() << " values. "
828  << std::endl;
829  }
830  }
831 
832  // Now check for field data
833  if (dataSet->GetFieldData()) {
834  std::cout << " contains field data with "
835  << dataSet->GetFieldData()->GetNumberOfArrays() << " arrays."
836  << std::endl;
837  for (int i = 0; i < dataSet->GetFieldData()->GetNumberOfArrays(); ++i) {
838  std::cout << "\tArray " << i << " is named "
839  << dataSet->GetFieldData()->GetArray(i)->GetName();
840  vtkDataArray *da = dataSet->GetFieldData()->GetArray(i);
841  std::cout << " with " << da->GetNumberOfTuples() << " values. "
842  << std::endl;
843  }
844  }
845 }
846 
847 vtkSmartPointer<vtkDataSet> vtkMesh::extractSurface() {
848  // extract surface polygons
849  vtkSmartPointer<vtkDataSetSurfaceFilter> surfFilt =
851  surfFilt->SetInputData(dataSet);
852  surfFilt->Update();
853 
854  // triangulate the surface
855  vtkSmartPointer<vtkTriangleFilter> triFilt =
857  triFilt->SetInputData(surfFilt->GetOutput());
858  triFilt->Update();
859 
860  return triFilt->GetOutput();
861 }
862 
863 // get diameter of circumsphere of each cell
864 std::vector<double> vtkMesh::getCellLengths() const {
865  std::vector<double> result;
866  result.resize(getNumberOfCells());
867  for (nemId_t i = 0; i < getNumberOfCells(); ++i)
868  result[i] = std::sqrt(dataSet->GetCell(i)->GetLength2());
869 
870  return result;
871 }
872 
873 // get center of a cell
874 std::vector<double> vtkMesh::getCellCenter(nemId_t cellID) const {
875  std::vector<double> center(3, 0.0);
876  std::vector<std::vector<double>> cell = getCellVec(cellID);
877 
878  for (const auto &i : cell) center = center + i;
879  return 1. / cell.size() * center;
880 }
881 
882 // returns the cell type
883 int vtkMesh::getCellType() const { return dataSet->GetCellType(0); }
884 
885 // set point data
886 void vtkMesh::setPointDataArray(const std::string &name,
887  const std::vector<double> &data) {
888  vtkSmartPointer<vtkDoubleArray> da = vtkSmartPointer<vtkDoubleArray>::New();
889  da->SetName(name.c_str());
890  da->SetNumberOfComponents(1);
891  for (nemId_t i = 0; i < numPoints; i++) da->InsertNextTuple1(data[i]);
892  dataSet->GetPointData()->AddArray(da);
893 }
894 
895 // set point data (numComponents per point determined by dim of data[0]
896 void vtkMesh::setPointDataArray(const std::string &name,
897  const std::vector<std::vector<double>> &data) {
898  vtkSmartPointer<vtkDoubleArray> da = vtkSmartPointer<vtkDoubleArray>::New();
899  da->SetName(name.c_str());
900  da->SetNumberOfComponents(data[0].size());
901  for (nemId_t i = 0; i < numPoints; i++) da->InsertNextTuple(data[i].data());
902  dataSet->GetPointData()->AddArray(da);
903  // dataSet->GetPointData()->SetActiveScalars(name);
904  // dataSet->GetPointData()->SetScalars(da);
905 }
906 
907 void vtkMesh::getPointDataArray(const std::string &name,
908  std::vector<double> &data) {
909  int idx;
910  vtkSmartPointer<vtkDataArray> pd =
911  dataSet->GetPointData()->GetArray(name.c_str(), idx);
912  if (idx != -1) {
913  if (pd->GetNumberOfComponents() > 1) {
914  std::cerr << __func__
915  << " is only suitable for scalar data, i.e. 1 component"
916  << std::endl;
917  exit(1);
918  }
919  data.resize(pd->GetNumberOfTuples());
920  double x[1];
921  for (nemId_t i = 0; i < pd->GetNumberOfTuples(); ++i) {
922  pd->GetTuple(i, x);
923  data[i] = x[0];
924  }
925  } else {
926  std::cerr << "could not find data with name " << name << std::endl;
927  exit(1);
928  }
929 }
930 
931 void vtkMesh::getPointDataArray(int arrayId, std::vector<double> &data) {
932  if (arrayId < dataSet->GetPointData()->GetNumberOfArrays()) {
933  vtkSmartPointer<vtkDataArray> pd =
934  dataSet->GetPointData()->GetArray(arrayId);
935  if (pd->GetNumberOfComponents() > 1) {
936  std::cerr << __func__
937  << " is only suitable for scalar data, i.e. 1 component"
938  << std::endl;
939  exit(1);
940  }
941  data.resize(pd->GetNumberOfTuples());
942  double x[1];
943  for (nemId_t i = 0; i < pd->GetNumberOfTuples(); ++i) {
944  pd->GetTuple(i, x);
945  data[i] = x[0];
946  }
947  } else {
948  std::cerr << "arrayId exceeds number of point data arrays " << std::endl;
949  exit(1);
950  }
951 }
952 
953 int vtkMesh::getCellDataIdx(const std::string &name) {
954  // check physical group exist and obtain id
955  int idx;
956  dataSet->GetCellData()->GetArray(name.c_str(), idx);
957  return idx;
958 }
959 
960 void vtkMesh::getCellDataArray(const std::string &name,
961  std::vector<double> &data) {
962  int idx;
963  vtkSmartPointer<vtkDataArray> cd =
964  dataSet->GetCellData()->GetArray(name.c_str(), idx);
965  if (idx != -1) {
966  if (cd->GetNumberOfComponents() > 1) {
967  std::cerr << __func__
968  << " is only suitable for scalar data, i.e. 1 component"
969  << std::endl;
970  exit(1);
971  }
972  data.resize(cd->GetNumberOfTuples());
973  double x[1];
974  for (nemId_t i = 0; i < cd->GetNumberOfTuples(); ++i) {
975  cd->GetTuple(i, x);
976  data[i] = x[0];
977  }
978  } else {
979  std::cerr << "could not find data with name " << name << std::endl;
980  exit(1);
981  }
982 }
983 
984 void vtkMesh::getCellDataArray(int arrayId, std::vector<double> &data) {
985  if (arrayId < dataSet->GetCellData()->GetNumberOfArrays()) {
986  vtkSmartPointer<vtkDataArray> cd =
987  dataSet->GetCellData()->GetArray(arrayId);
988  if (cd->GetNumberOfComponents() > 1) {
989  std::cerr << __func__
990  << " is only suitable for scalar data, i.e. 1 component"
991  << std::endl;
992  exit(1);
993  }
994  data.resize(cd->GetNumberOfTuples());
995  double x[1];
996  for (nemId_t i = 0; i < cd->GetNumberOfTuples(); ++i) {
997  cd->GetTuple(i, x);
998  data[i] = x[0];
999  }
1000  } else {
1001  std::cerr << "arrayId exceeds number of cell data arrays " << std::endl;
1002  exit(1);
1003  }
1004 }
1005 
1006 // set cell data (numComponents per cell determined by dim of data[0])
1007 void vtkMesh::setCellDataArray(const std::string &name,
1008  const std::vector<std::vector<double>> &data) {
1009  vtkSmartPointer<vtkDoubleArray> da = vtkSmartPointer<vtkDoubleArray>::New();
1010  da->SetName(name.c_str());
1011  da->SetNumberOfComponents(data[0].size());
1012  for (nemId_t i = 0; i < numCells; i++) da->InsertNextTuple(data[i].data());
1013  dataSet->GetCellData()->AddArray(da);
1014  // dataSet->GetCellData()->SetActiveScalars(name);
1015  // dataSet->GetCellData()->SetScalars(da);
1016 }
1017 
1018 void vtkMesh::setCellDataArray(const std::string &name,
1019  const std::vector<double> &data) {
1020  vtkSmartPointer<vtkDoubleArray> da = vtkSmartPointer<vtkDoubleArray>::New();
1021  da->SetName(name.c_str());
1022  da->SetNumberOfComponents(1);
1023  for (nemId_t i = 0; i < numCells; i++) da->InsertNextTuple1(data[i]);
1024  dataSet->GetCellData()->AddArray(da);
1025  // dataSet->GetCellData()->SetActiveScalars(name);
1026  // dataSet->GetCellData()->SetScalars(da);
1027 }
1028 
1029 // remove point data with given id from dataSet if it exists
1030 void vtkMesh::unsetPointDataArray(int arrayID) {
1031  dataSet->GetPointData()->RemoveArray(arrayID);
1032 }
1033 
1034 void vtkMesh::unsetPointDataArray(const std::string &name) {
1035  dataSet->GetPointData()->RemoveArray(name.c_str());
1036 }
1037 
1038 // remove cell data with given id from dataSet if it exists
1039 void vtkMesh::unsetCellDataArray(int arrayID) {
1040  dataSet->GetCellData()->RemoveArray(arrayID);
1041 }
1042 
1043 void vtkMesh::unsetCellDataArray(const std::string &name) {
1044  dataSet->GetCellData()->RemoveArray(name.c_str());
1045 }
1046 
1047 // remove field data with given id from dataSet
1048 void vtkMesh::unsetFieldDataArray(const std::string &name) {
1049  dataSet->GetFieldData()->RemoveArray(name.c_str());
1050 }
1051 
1052 // Merges new dataset with existing dataset
1053 void vtkMesh::merge(vtkSmartPointer<vtkDataSet> dataSet_new) {
1054  vtkSmartPointer<vtkAppendFilter> appendFilter =
1056  appendFilter->AddInputData(dataSet);
1057  appendFilter->AddInputData(dataSet_new);
1058  appendFilter->MergePointsOn();
1059  appendFilter->Update();
1060  dataSet = appendFilter->GetOutput();
1061 
1062  numCells = dataSet->GetNumberOfCells();
1063  numPoints = dataSet->GetNumberOfPoints();
1064 }
1065 
1066 /*
1067 void addLegacyVTKData(vtkDataArray *arr, const std::string &type,
1068  const bool pointOrCell,
1069  vtkSmartPointer<vtkUnstructuredGrid> dataSet_tmp) {
1070  // casting to appropriate type array
1071  if (!type.compare("unsigned_int")) {
1072  vtkUnsignedIntArray *typedArr = vtkUnsignedIntArray::SafeDownCast(arr);
1073  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1074  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1075  } else if (!type.compare("int")) {
1076  std::cout << "in type arr" << std::endl;
1077  vtkIntArray *typedArr = vtkIntArray::SafeDownCast(arr);
1078  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1079  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1080  } else if (!type.compare("unsigned_long")) {
1081  vtkUnsignedLongArray *typedArr = vtkUnsignedLongArray::SafeDownCast(arr);
1082  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1083  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1084  } else if (!type.compare("long")) {
1085  vtkLongArray *typedArr = vtkLongArray::SafeDownCast(arr);
1086  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1087  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1088  } else if (!type.compare("float")) {
1089  vtkFloatArray *typedArr = vtkFloatArray::SafeDownCast(arr);
1090  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1091  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1092  } else if (!type.compare("double")) {
1093  vtkDoubleArray *typedArr = vtkDoubleArray::SafeDownCast(arr);
1094  pointOrCell ? dataSet_tmp->GetPointData()->AddArray(typedArr)
1095  : dataSet_tmp->GetCellData()->AddArray(typedArr);
1096  }
1097 }
1098 */
void unsetCellDataArray(int arrayID) override
delete array with id from dataSet&#39;s cell data
Definition: vtkMesh.C:1039
void setPointDataArray(const std::string &name, const std::vector< std::vector< double >> &data) override
register data to dataSet&#39;s point data
Definition: vtkMesh.C:896
vtkSmartPointer< vtkDataSet > extractSurface() override
extract the surface mesh
Definition: vtkMesh.C:847
void getCellDataArray(const std::string &name, std::vector< double > &data) override
<>
Definition: vtkMesh.C:960
std::map< nemId_t, std::vector< double > > getCell(nemId_t id) const override
get cell with id
Definition: vtkMesh.C:706
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
nemId_t numPoints
number of points in mesh
Definition: meshBase.H:714
void unsetFieldDataArray(const std::string &name) override
delete array with id from dataSet&#39;s field data
Definition: vtkMesh.C:1048
std::multimap< B, A > flip_map(const std::map< A, B > &src)
void setFileName(const std::string &fname)
set the file name.
Definition: meshBase.H:675
bool readLegacyVTKCells(std::istream &meshStream, std::string &line, nemId_t &numCells, std::vector< vtkSmartPointer< vtkIdList >> &vtkCellIds, vtkSmartPointer< vtkUnstructuredGrid > dataSet_tmp)
Definition: vtkMesh.C:358
vtkSmartPointer< vtkDataSet > dataSet
mesh points, topology and data
Definition: meshBase.H:722
void inspectEdges(const std::string &ofname) const override
get edge lengths of dataSet
Definition: vtkMesh.C:742
bool readLegacyVTKPoints(std::istream &meshStream, std::string &line, nemId_t &numPoints, vtkSmartPointer< vtkPoints > points, vtkSmartPointer< vtkUnstructuredGrid > dataSet_tmp)
Definition: vtkMesh.C:334
std::size_t nemId_t
Definition: meshBase.H:51
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
int getCellDataIdx(const std::string &name) override
<>
Definition: vtkMesh.C:953
std::vector< std::vector< double > > getVertCrds() const override
get 3 vecs with x,y and z coords
Definition: vtkMesh.C:691
void getPointDataArray(const std::string &name, std::vector< double > &data) override
get scalar point or cell data array.
Definition: vtkMesh.C:907
std::string find_ext(const std::string &fname)
nemId_t numCells
number of cells in mesh
Definition: meshBase.H:718
void setCellDataArray(const std::string &name, const std::vector< std::vector< double >> &data) override
register data to dataSet&#39;s cell data
Definition: vtkMesh.C:1007
int getCellType() const override
get cell type as an integer assumes all elements are the same type
Definition: vtkMesh.C:883
vtkSmartPointer< vtkUnstructuredGrid > ReadALegacyVTKFile(const std::string &fileName)
Definition: vtkMesh.C:502
std::string trim_fname(const std::string &name, const std::string &ext)
bool readLegacyVTKHeader(const std::string &line)
Definition: vtkMesh.C:294
std::vector< double > getPoint(nemId_t id) const override
get point with id
Definition: vtkMesh.C:683
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
std::vector< std::vector< double > > getCellVec(nemId_t id) const override
get vector of coords of cell with id
Definition: vtkMesh.C:724
VTKCellType cellType
Definition: inpGeoMesh.C:129
std::vector< nemId_t > getConnectivities() const override
get connectivities.
Definition: vtkMesh.C:768
std::vector< vtkIdType > points
points given by id in .inp file
Definition: inpGeoMesh.C:133
std::string filename
name of mesh file
Definition: meshBase.H:726
void unsetPointDataArray(int arrayID) override
delete array with id from dataSet&#39;s point data
Definition: vtkMesh.C:1030
std::vector< double > getCellCenter(nemId_t cellID) const override
get center of a cell
Definition: vtkMesh.C:874
bool readLegacyVTKFieldData(std::istream &meshStream, std::string &line, vtkSmartPointer< vtkUnstructuredGrid > dataSet_tmp)
Definition: vtkMesh.C:305
vtkMesh()=default
void merge(vtkSmartPointer< vtkDataSet > dataSet_new)
Definition: vtkMesh.C:1053
std::vector< std::string > getNewArrayNames()
get new array names for use in transfer
Definition: meshBase.H:698
static std::shared_ptr< TransferBase > CreateTransferObject(meshBase *srcmsh, meshBase *trgmsh, const std::string &method)
bool readLegacyVTKData(std::ifstream &meshStream, std::string &line, const nemId_t numTuple, const bool pointOrCell, bool &hasPointOrCell, vtkSmartPointer< vtkUnstructuredGrid > dataSet_tmp)
Definition: vtkMesh.C:406
vtkSmartPointer< vtkUnstructuredGrid > ReadDegenerateVTKFile(const std::string &fileName)
Definition: vtkMesh.C:581
nemId_t getNumberOfCells() const
return the number of cells
Definition: meshBase.H:550
std::vector< double > getCellLengths() const override
get diameter of circumsphere of each cell
Definition: vtkMesh.C:864
void report() const override
generate a report of the mesh
Definition: vtkMesh.C:780
void write() const override
write the mesh to file named after the private var &#39;filename&#39;.
Definition: vtkMesh.H:152