vtkUnstructuredReader.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2018-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "vtkUnstructuredReader.H"
30 #include "labelIOField.H"
31 #include "scalarIOField.H"
32 #include "stringIOList.H"
33 #include "cellModel.H"
34 #include "vectorIOField.H"
35 #include "triPointRef.H"
36 #include "stringOps.H"
37 
38 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(vtkUnstructuredReader, 1);
43 }
44 
45 const Foam::Enum
46 <
48 >
50 ({
51  { vtkDataType::VTK_INT, "int" },
52  // Not yet required: { vtkDataType::VTK_INT64, "vtktypeint64" },
53  { vtkDataType::VTK_UINT, "unsigned_int" },
54  { vtkDataType::VTK_LONG, "long" },
55  { vtkDataType::VTK_ULONG, "unsigned_long" },
56  { vtkDataType::VTK_FLOAT, "float" },
57  { vtkDataType::VTK_DOUBLE, "double" },
58  { vtkDataType::VTK_STRING, "string" },
59  { vtkDataType::VTK_ID, "vtkIdType" },
60 });
61 
62 
63 const Foam::Enum
64 <
66 >
68 ({
69  { vtkDataSetType::VTK_FIELD, "FIELD" },
70  { vtkDataSetType::VTK_SCALARS, "SCALARS" },
71  { vtkDataSetType::VTK_VECTORS, "VECTORS" },
72 });
73 
74 
75 const Foam::Enum
76 <
78 >
80 ({
81  { parseMode::NOMODE, "NOMODE" },
82  { parseMode::UNSTRUCTURED_GRID, "UNSTRUCTURED_GRID" },
83  { parseMode::POLYDATA, "POLYDATA" },
84  { parseMode::CELL_DATA, "CELL_DATA" },
85  { parseMode::POINT_DATA, "POINT_DATA" },
86 });
87 
88 
89 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
90 
91 namespace Foam
92 {
93 
94 // Read N elements into List
95 template<class T>
96 static inline void readBlock(Istream& is, const label n, List<T>& list)
97 {
98  list.resize(n);
99  for (T& val : list)
100  {
101  is >> val;
102  }
103 }
104 
105 } // End namespace Foam
106 
107 
108 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
109 
110 void Foam::vtkUnstructuredReader::warnUnhandledType
111 (
112  const Istream& is,
113  const label type,
114  labelHashSet& warningGiven
115 )
116 {
117  if (warningGiven.insert(type))
118  {
120  << "Skipping unknown cell type " << type << nl;
121  }
122 }
123 
124 
125 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
126 
127 void Foam::vtkUnstructuredReader::readOffsetsConnectivity
128 (
129  ISstream& is,
130  const char* entryName,
131  const label nOffsets,
132  labelList& offsets,
133  const label nConnectivity,
134  labelList& connectivity
135 )
136 {
137  token tok;
138 
139  is.read(tok);
140  if (!tok.isWord("OFFSETS"))
141  {
143  << "Expected OFFSETS for " << entryName
144  << ", found "
145  << tok.info() << nl
146  << exit(FatalIOError);
147  }
148  is.getLine(nullptr); // Consume rest of line
149  readBlock(is, nOffsets, offsets);
150 
151  is.read(tok);
152  if (!tok.isWord("CONNECTIVITY"))
153  {
155  << "Expected CONNECTIVITY for " << entryName
156  << ", found " << tok.info() << nl
157  << exit(FatalIOError);
158  }
159  is.getLine(nullptr); // Consume rest of line
160  readBlock(is, nConnectivity, connectivity);
161 }
162 
163 
164 void Foam::vtkUnstructuredReader::extractCells
165 (
166  const Istream& is,
167  const labelUList& cellTypes,
168  const labelUList& elemOffsets,
169  const labelUList& elemVerts
170 )
171 {
172  const cellModel& hex = cellModel::ref(cellModel::HEX);
173  const cellModel& prism = cellModel::ref(cellModel::PRISM);
174  const cellModel& pyr = cellModel::ref(cellModel::PYR);
175  const cellModel& tet = cellModel::ref(cellModel::TET);
176 
177  // Pass 0: sizing
178  label nCells = 0, nFaces = 0, nLines = 0;
179  forAll(cellTypes, elemi)
180  {
181  switch (cellTypes[elemi])
182  {
185  {
186  ++nLines;
187  }
188  break;
189 
193  {
194  ++nFaces;
195  }
196  break;
197 
202  {
203  ++nCells;
204  }
205  break;
206 
207  default:
208  break;
209  }
210  }
211 
212  label celli = cells_.size();
213  cells_.resize(celli + nCells);
214  cellMap_.resize(cells_.size(), -1);
215 
216  label facei = faces_.size();
217  faces_.resize(facei + nFaces);
218  faceMap_.resize(faces_.size(), -1);
219 
220  label linei = lines_.size();
221  lines_.resize(linei + nLines);
222  lineMap_.resize(lines_.size(), -1);
223 
224  // General scratch space for cell vertices
225  labelList cellPoints(16);
226 
227  label dataIndex = 0; // Addressing into vertices stream
228 
229  // To mark whether unhandled type has been visited.
230  labelHashSet warningGiven;
231 
232 
233  forAll(cellTypes, elemi)
234  {
235  // Vertices per element - from offsets or embedded size
236  const label nVerts =
237  (
238  elemOffsets.empty()
239  ? elemVerts[dataIndex++]
240  : (elemOffsets[elemi+1] - elemOffsets[elemi])
241  );
242 
243  // The addresseed vertices
244  const labelSubList verts(elemVerts, nVerts, dataIndex);
245  dataIndex += nVerts;
246 
247  switch (cellTypes[elemi])
248  {
250  {
251  warnUnhandledType(is, cellTypes[elemi], warningGiven);
252  if (nVerts != 1)
253  {
255  << "Expected size 1 for VTK_VERTEX, found "
256  << nVerts << nl
257  << exit(FatalIOError);
258  }
259  }
260  break;
261 
263  {
264  warnUnhandledType(is, cellTypes[elemi], warningGiven);
265  }
266  break;
267 
269  {
270  if (nVerts != 2)
271  {
273  << "Expected size 2 for VTK_LINE, found "
274  << nVerts << nl
275  << exit(FatalIOError);
276  }
277  lineMap_[linei] = elemi;
278 
279  // Same vertex ordering
280  lines_[linei++] = verts;
281  }
282  break;
283 
285  {
286  lineMap_[linei] = elemi;
287 
288  // Same vertex ordering
289  lines_[linei++] = verts;
290  }
291  break;
292 
294  {
295  if (nVerts != 3)
296  {
298  << "Expected size 3 for VTK_TRIANGLE, found "
299  << nVerts << nl
300  << exit(FatalIOError);
301  }
302  faceMap_[facei] = elemi;
303 
304  // Same vertex ordering
305  static_cast<labelList&>(faces_[facei++]) = verts;
306  }
307  break;
308 
310  {
311  if (nVerts != 4)
312  {
314  << "Expected size 4 for VTK_QUAD, found "
315  << nVerts << nl
316  << exit(FatalIOError);
317  }
318  faceMap_[facei] = elemi;
319 
320  // Same vertex ordering
321  static_cast<labelList&>(faces_[facei++]) = verts;
322  }
323  break;
324 
326  {
327  faceMap_[facei] = elemi;
328 
329  // Same vertex ordering
330  static_cast<labelList&>(faces_[facei++]) = verts;
331  }
332  break;
333 
335  {
336  if (nVerts != 4)
337  {
339  << "Expected size 4 for VTK_TETRA, found "
340  << nVerts << nl
341  << exit(FatalIOError);
342  }
343  cellMap_[celli] = elemi;
344 
345  // Same vertex ordering
346  cells_[celli++].reset(tet, verts, true);
347  }
348  break;
349 
351  {
352  if (nVerts != 5)
353  {
355  << "Expected size 5 for VTK_PYRAMID, found "
356  << nVerts << nl
357  << exit(FatalIOError);
358  }
359  cellMap_[celli] = elemi;
360 
361  // Same vertex ordering
362  cells_[celli++].reset(pyr, verts, true);
363  }
364  break;
365 
367  {
368  if (nVerts != 6)
369  {
371  << "Expected size 6 for VTK_WEDGE, found "
372  << nVerts << nl
373  << exit(FatalIOError);
374  }
375  cellMap_[celli] = elemi;
376 
377  // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5)
378  labelSubList shape(cellPoints, nVerts);
379  shape[0] = verts[0];
380  shape[2] = verts[1];
381  shape[1] = verts[2];
382  shape[3] = verts[3];
383  shape[5] = verts[4];
384  shape[4] = verts[5];
385 
386  cells_[celli++].reset(prism, shape, true);
387  }
388  break;
389 
391  {
392  if (nVerts != 8)
393  {
395  << "Expected size 8 for VTK_HEXAHEDRON, found "
396  << nVerts << nl
397  << exit(FatalIOError);
398  }
399  cellMap_[celli] = elemi;
400 
401  // Same vertex ordering
402  cells_[celli++].reset(hex, verts, true);
403  }
404  break;
405 
406  default:
407  {
408  warnUnhandledType(is, cellTypes[elemi], warningGiven);
409  }
410  break;
411  }
412  }
413 
414  DebugInfo
415  << "Read"
416  << " cells:" << celli
417  << " faces:" << facei
418  << " lines:" << linei
419  << nl;
420 
421  cells_.resize(celli);
422  cellMap_.resize(celli);
423 
424  faces_.resize(facei);
425  faceMap_.resize(facei);
426 
427  lines_.resize(linei);
428  lineMap_.resize(linei);
429 }
430 
431 
432 void Foam::vtkUnstructuredReader::readField
433 (
434  ISstream& inFile,
435  objectRegistry& obj,
436  const word& arrayName,
437  const word& dataType,
438  const label size
439 ) const
440 {
441  if (vtkDataTypeNames.found(dataType))
442  {
443  switch (vtkDataTypeNames[dataType])
444  {
445  case VTK_INT:
446  case VTK_INT64:
447  case VTK_UINT:
448  case VTK_LONG:
449  case VTK_ULONG:
450  case VTK_ID:
451  {
452  auto fieldVals = autoPtr<labelIOField>::New
453  (
454  IOobject(arrayName, "", obj),
455  size
456  );
457  readBlock(inFile, fieldVals().size(), fieldVals());
458  regIOobject::store(fieldVals);
459  }
460  break;
461 
462  case VTK_FLOAT:
463  case VTK_DOUBLE:
464  {
465  auto fieldVals = autoPtr<scalarIOField>::New
466  (
467  IOobject(arrayName, "", obj),
468  size
469  );
470  readBlock(inFile, fieldVals().size(), fieldVals());
471  regIOobject::store(fieldVals);
472  }
473  break;
474 
475  case VTK_STRING:
476  {
477  DebugInfo
478  << "Reading strings:" << size << nl;
479 
480  auto fieldVals = autoPtr<stringIOList>::New
481  (
482  IOobject(arrayName, "", obj),
483  size
484  );
485  // Consume current line.
486  inFile.getLine(fieldVals()[0]);
487 
488  // Read without parsing
489  for (string& s : fieldVals())
490  {
491  inFile.getLine(s);
492  }
493  regIOobject::store(fieldVals);
494  }
495  break;
496 
497  default:
498  {
499  IOWarningInFunction(inFile)
500  << "Unhandled type " << dataType << nl
501  << "Skipping " << size
502  << " words." << nl;
503  scalarField fieldVals;
504  readBlock(inFile, size, fieldVals);
505  }
506  break;
507  }
508  }
509  else
510  {
511  IOWarningInFunction(inFile)
512  << "Unhandled type " << dataType << nl
513  << "Skipping " << size
514  << " words." << nl;
515  scalarField fieldVals;
516  readBlock(inFile, size, fieldVals);
517  }
518 }
519 
520 
521 Foam::wordList Foam::vtkUnstructuredReader::readFieldArray
522 (
523  ISstream& inFile,
524  objectRegistry& obj,
525  const label wantedSize
526 ) const
527 {
528  DynamicList<word> fields;
529 
530  word dataName(inFile);
531 
532  DebugInfo
533  << "dataName:" << dataName << nl;
534 
535  label numArrays(readLabel(inFile));
536  if (debug)
537  {
538  Pout<< "numArrays:" << numArrays << nl;
539  }
540  for (label i = 0; i < numArrays; i++)
541  {
542  word arrayName(inFile);
543  label numComp(readLabel(inFile));
544  label numTuples(readLabel(inFile));
545  word dataType(inFile);
546 
547  DebugInfo
548  << "Reading field " << arrayName
549  << " of " << numTuples << " tuples of rank " << numComp << nl;
550 
551  if (wantedSize != -1 && numTuples != wantedSize)
552  {
553  FatalIOErrorInFunction(inFile)
554  << "Expected " << wantedSize << " tuples but only have "
555  << numTuples << nl
556  << exit(FatalIOError);
557  }
558 
559  readField
560  (
561  inFile,
562  obj,
563  arrayName,
564  dataType,
565  numTuples*numComp
566  );
567  fields.append(arrayName);
568  }
569  return fields.shrink();
570 }
571 
572 
573 Foam::objectRegistry& Foam::vtkUnstructuredReader::selectRegistry
574 (
575  const parseMode readMode
576 )
577 {
578  if (readMode == CELL_DATA)
579  {
580  return cellData_;
581  }
582  else if (readMode == POINT_DATA)
583  {
584  return pointData_;
585  }
586 
587  return otherData_;
588 }
589 
590 
591 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
592 
594 (
595  const objectRegistry& obr,
596  ISstream& is
597 )
598 :
599  version_(2.0),
600  cellData_(IOobject("cellData", obr)),
601  pointData_(IOobject("pointData", obr)),
602  otherData_(IOobject("otherData", obr))
603 {
604  read(is);
605 }
606 
607 
608 void Foam::vtkUnstructuredReader::read(ISstream& inFile)
609 {
610  inFile.getLine(header_);
611  DebugInfo<< "Header : " << header_ << nl;
612 
613  // Extract version number from "# vtk DataFile Version 5.1"
614  const auto split = stringOps::splitSpace(header_);
615  if (split.size() >= 4 && split[split.size() - 2] == "Version")
616  {
617  float ver(0);
618  if (readFloat(split[split.size() - 1], ver))
619  {
620  version_ = ver;
621  DebugInfo<< "Version : " << version_ << nl;
622  }
623  }
624 
625  inFile.getLine(title_);
626  DebugInfo<< "Title : " << title_ << nl;
627 
628  inFile.getLine(dataType_);
629  DebugInfo<< "dataType : " << dataType_ << nl;
630 
631  if (dataType_ == "BINARY")
632  {
633  FatalIOErrorInFunction(inFile)
634  << "Binary reading not supported" << nl
635  << exit(FatalIOError);
636  }
637 
638  parseMode readMode = NOMODE;
639  label wantedSize = -1;
640 
641 
642  // Intermediate storage for vertices of cells.
643  labelList cellOffsets, cellVerts;
644 
645  token tok;
646 
647  while (inFile.read(tok).good() && tok.isWord())
648  {
649  const word tag = tok.wordToken();
650 
651  DebugInfo
652  << "line:" << inFile.lineNumber()
653  << " tag:" << tag << nl;
654 
655  if (tag == "DATASET")
656  {
657  word geomType(inFile);
658  DebugInfo<< "geomType : " << geomType << nl;
659 
660  readMode = parseModeNames[geomType];
661  wantedSize = -1;
662  }
663  else if (tag == "POINTS")
664  {
665  const label nPoints(readLabel(inFile));
666  points_.resize(nPoints);
667 
668  DebugInfo
669  << "Reading " << nPoints << " coordinates" << nl;
670 
671  word primitiveTag(inFile);
672  if (primitiveTag != "float" && primitiveTag != "double")
673  {
674  FatalIOErrorInFunction(inFile)
675  << "Expected 'float' entry, found "
676  << primitiveTag << nl
677  << exit(FatalIOError);
678  }
679  for (point& p : points_)
680  {
681  inFile >> p.x() >> p.y() >> p.z();
682  }
683  }
684  else if (tag == "CELLS")
685  {
686  label nCells(readLabel(inFile));
687  const label nNumbers(readLabel(inFile));
688 
689  if (version_ < 5.0)
690  {
691  // VTK 4.2 and earlier (single-block)
692  DebugInfo
693  << "Reading " << nCells
694  << " cells/faces (single block)" << nl;
695 
696  cellOffsets.clear();
697  readBlock(inFile, nNumbers, cellVerts);
698  }
699  else
700  {
701  // VTK 5.0 and later (OFFSETS and CONNECTIVITY)
702 
703  const label nOffsets(nCells);
704  --nCells;
705 
706  DebugInfo
707  << "Reading offsets/connectivity for "
708  << nCells << " cells/faces" << nl;
709 
710  readOffsetsConnectivity
711  (
712  inFile,
713  "CELLS",
714  nOffsets, cellOffsets,
715  nNumbers, cellVerts
716  );
717  }
718  }
719  else if (tag == "CELL_TYPES")
720  {
721  const label nCellTypes(readLabel(inFile));
722 
724  readBlock(inFile, nCellTypes, cellTypes);
725 
726  if (!cellTypes.empty() && cellVerts.empty())
727  {
728  FatalIOErrorInFunction(inFile)
729  << "Found " << cellTypes.size()
730  << " cellTypes but no cells." << nl
731  << exit(FatalIOError);
732  }
733 
734  extractCells(inFile, cellTypes, cellOffsets, cellVerts);
735  cellOffsets.clear();
736  cellVerts.clear();
737  }
738  else if (tag == "LINES")
739  {
740  label nLines(readLabel(inFile));
741  const label nNumbers(readLabel(inFile));
742 
743  labelList elemOffsets, elemVerts;
744 
745  if (version_ < 5.0)
746  {
747  // VTK 4.2 and earlier (single-block)
748  DebugInfo
749  << "Reading " << nLines
750  << " lines (single block)" << nl;
751 
752  readBlock(inFile, nNumbers, elemVerts);
753  }
754  else
755  {
756  // VTK 5.0 and later (OFFSETS and CONNECTIVITY)
757 
758  const label nOffsets(nLines);
759  --nLines;
760 
761  DebugInfo
762  << "Reading offsets/connectivity for "
763  << nLines << " lines" << nl;
764 
765  readOffsetsConnectivity
766  (
767  inFile,
768  "LINES",
769  nOffsets, elemOffsets,
770  nNumbers, elemVerts
771  );
772  }
773 
774  // Append into lines
775  label linei = lines_.size();
776  lines_.resize(linei+nLines);
777  lineMap_.resize(lines_.size());
778 
779  label dataIndex = 0;
780  for (label i = 0; i < nLines; i++)
781  {
782  const label nVerts =
783  (
784  elemOffsets.empty()
785  ? elemVerts[dataIndex++]
786  : (elemOffsets[i+1] - elemOffsets[i])
787  );
788  const labelSubList verts(elemVerts, nVerts, dataIndex);
789  dataIndex += nVerts;
790 
791  lineMap_[linei] = linei;
792  lines_[linei++] = verts;
793  }
794  }
795  else if (tag == "POLYGONS")
796  {
797  label nFaces(readLabel(inFile));
798  const label nNumbers(readLabel(inFile));
799 
800  labelList elemOffsets, elemVerts;
801 
802  if (version_ < 5.0)
803  {
804  // VTK 4.2 and earlier (single-block)
805  DebugInfo
806  << "Reading " << nFaces
807  << " faces (single block)" << nl;
808 
809  readBlock(inFile, nNumbers, elemVerts);
810  }
811  else
812  {
813  // VTK 5.0 and later (OFFSETS and CONNECTIVITY)
814 
815  const label nOffsets(nFaces);
816  --nFaces;
817 
818  DebugInfo
819  << "Reading offsets/connectivity for "
820  << nFaces << " faces" << nl;
821 
822  readOffsetsConnectivity
823  (
824  inFile,
825  "POLYGONS",
826  nOffsets, elemOffsets,
827  nNumbers, elemVerts
828  );
829  }
830 
831  // Append into faces
832  label facei = faces_.size();
833  faces_.resize(facei+nFaces);
834  faceMap_.resize(faces_.size());
835 
836  label dataIndex = 0;
837  for (label i = 0; i < nFaces; ++i)
838  {
839  const label nVerts =
840  (
841  elemOffsets.empty()
842  ? elemVerts[dataIndex++]
843  : (elemOffsets[i+1] - elemOffsets[i])
844  );
845  const labelSubList verts(elemVerts, nVerts, dataIndex);
846  dataIndex += nVerts;
847 
848  faceMap_[facei] = facei;
849  static_cast<labelList&>(faces_[facei++]) = verts;
850  }
851  }
852  else if (tag == "POINT_DATA")
853  {
854  // 'POINT_DATA 24'
855  readMode = POINT_DATA;
856  wantedSize = points_.size();
857 
858  label nPoints(readLabel(inFile));
859  if (nPoints != wantedSize)
860  {
861  FatalIOErrorInFunction(inFile)
862  << "Reading POINT_DATA : expected " << wantedSize
863  << " but read " << nPoints << nl
864  << exit(FatalIOError);
865  }
866  }
867  else if (tag == "CELL_DATA")
868  {
869  readMode = CELL_DATA;
870  wantedSize = cells_.size()+faces_.size()+lines_.size();
871 
872  label nCells(readLabel(inFile));
873  if (nCells != wantedSize)
874  {
875  FatalIOErrorInFunction(inFile)
876  << "Reading CELL_DATA : expected "
877  << wantedSize
878  << " but read " << nCells << nl
879  << exit(FatalIOError);
880  }
881  }
882  else if (tag == "FIELD")
883  {
884  // wantedSize already set according to type we expected to read.
885  readFieldArray(inFile, selectRegistry(readMode), wantedSize);
886  }
887  else if (tag == "SCALARS")
888  {
889  string line;
890  inFile.getLine(line);
891  IStringStream is(line);
892  word dataName(is);
893  word dataType(is);
894  //label numComp(readLabel(inFile));
895 
896  DebugInfo
897  << "Reading scalar " << dataName
898  << " of type " << dataType
899  << " from lookup table" << nl;
900 
901  word lookupTableTag(inFile);
902  if (lookupTableTag != "LOOKUP_TABLE")
903  {
904  FatalIOErrorInFunction(inFile)
905  << "Expected tag LOOKUP_TABLE but read "
906  << lookupTableTag << nl
907  << exit(FatalIOError);
908  }
909 
910  word lookupTableName(inFile);
911 
912  readField
913  (
914  inFile,
915  selectRegistry(readMode),
916  dataName,
917  dataType,
918  wantedSize//*numComp
919  );
920  }
921  else if (tag == "VECTORS" || tag == "NORMALS")
922  {
923  // 'NORMALS Normals float'
924  string line;
925  inFile.getLine(line);
926  IStringStream is(line);
927  word dataName(is);
928  word dataType(is);
929  DebugInfo
930  << "Reading vector " << dataName
931  << " of type " << dataType << nl;
932 
933  objectRegistry& reg = selectRegistry(readMode);
934 
935  readField
936  (
937  inFile,
938  reg,
939  dataName,
940  dataType,
941  3*wantedSize
942  );
943 
944  if
945  (
946  vtkDataTypeNames[dataType] == VTK_FLOAT
947  || vtkDataTypeNames[dataType] == VTK_DOUBLE
948  )
949  {
950  objectRegistry::iterator iter = reg.find(dataName);
951  scalarField s(*dynamic_cast<const scalarField*>(iter()));
952  reg.erase(iter);
953  auto fieldVals = autoPtr<vectorIOField>::New
954  (
955  IOobject(dataName, "", reg),
956  s.size()/3
957  );
958 
959  label elemI = 0;
960  for (vector& val : fieldVals())
961  {
962  val.x() = s[elemI++];
963  val.y() = s[elemI++];
964  val.z() = s[elemI++];
965  }
966  regIOobject::store(fieldVals);
967  }
968  }
969  else if (tag == "TEXTURE_COORDINATES")
970  {
971  // 'TEXTURE_COORDINATES TCoords 2 float'
972  string line;
973  inFile.getLine(line);
974  IStringStream is(line);
975  word dataName(is); //"Tcoords"
976  label dim(readLabel(is));
977  word dataType(is);
978 
979  DebugInfo
980  << "Reading texture coords " << dataName
981  << " dimension " << dim
982  << " of type " << dataType << nl;
983 
984  scalarField coords(dim*points_.size());
985  readBlock(inFile, coords.size(), coords);
986  }
987  else if (tag == "TRIANGLE_STRIPS")
988  {
989  label nStrips(readLabel(inFile));
990  const label nNumbers(readLabel(inFile));
991 
992  labelList elemOffsets, elemVerts;
993 
994  // Total number of faces in strips
995  label nFaces = 0;
996 
997  if (version_ < 5.0)
998  {
999  // VTK 4.2 and earlier (single-block)
1000  DebugInfo
1001  << "Reading " << nStrips
1002  << " strips (single block)" << nl;
1003 
1004  readBlock(inFile, nNumbers, elemVerts);
1005 
1006  // Count number of faces (triangles)
1007  {
1008  label dataIndex = 0;
1009  for (label i = 0; i < nStrips; ++i)
1010  {
1011  const label nVerts = elemVerts[dataIndex++];
1012  nFaces += nVerts-2;
1013  dataIndex += nVerts;
1014  }
1015  }
1016  }
1017  else
1018  {
1019  // VTK 5.0 and later (OFFSETS and CONNECTIVITY)
1020 
1021  const label nOffsets(nStrips);
1022  --nStrips;
1023 
1024  DebugInfo
1025  << "Reading offsets/connectivity for "
1026  << nStrips << " triangle strips." << nl;
1027 
1028  readOffsetsConnectivity
1029  (
1030  inFile,
1031  "TRIANGLE_STRIPS",
1032  nOffsets, elemOffsets,
1033  nNumbers, elemVerts
1034  );
1035 
1036  // Count number of faces (triangles)
1037  for (label i = 0; i < nStrips; ++i)
1038  {
1039  const label nVerts = (elemOffsets[i+1] - elemOffsets[i]);
1040  nFaces += nVerts-2;
1041  }
1042  }
1043 
1044  // Append into faces
1045  label facei = faces_.size();
1046  faces_.resize(facei+nFaces);
1047  faceMap_.resize(faces_.size());
1048 
1049  label dataIndex = 0;
1050  for (label i = 0; i < nStrips; ++i)
1051  {
1052  const label nVerts =
1053  (
1054  elemOffsets.empty()
1055  ? elemVerts[dataIndex++]
1056  : (elemOffsets[i+1] - elemOffsets[i])
1057  );
1058  const label nTris = nVerts-2;
1059 
1060  // Advance before the first triangle
1061  if (nTris > 0)
1062  {
1063  dataIndex += 2;
1064  }
1065 
1066  for (label triI = 0; triI < nTris; ++triI)
1067  {
1068  faceMap_[facei] = facei;
1069  face& f = faces_[facei++];
1070 
1071  f.resize(3);
1072 
1073  // NOTE: not clear if the orientation is correct
1074  if ((triI % 2) == 0)
1075  {
1076  // Even (eg, 0-1-2, 2-3-4)
1077  f[0] = elemVerts[dataIndex-2];
1078  f[1] = elemVerts[dataIndex-1];
1079  }
1080  else
1081  {
1082  // Odd (eg, 2-1-3, 4-3-5)
1083  f[0] = elemVerts[dataIndex-1];
1084  f[1] = elemVerts[dataIndex-2];
1085  }
1086  f[2] = elemVerts[dataIndex++];
1087  }
1088  }
1089  }
1090  else if (tag == "METADATA")
1091  {
1092  word infoTag(inFile);
1093  if (infoTag != "INFORMATION")
1094  {
1095  FatalIOErrorInFunction(inFile)
1096  << "Unsupported tag "
1097  << infoTag << nl
1098  << exit(FatalIOError);
1099  }
1100  label nInfo(readLabel(inFile));
1101  DebugInfo
1102  << "Ignoring " << nInfo << " metadata information." << nl;
1103 
1104  // Consume rest of line
1105  inFile.getLine(nullptr);
1106  for (label i = 0; i < 2*nInfo; i++)
1107  {
1108  inFile.getLine(nullptr);
1109  }
1110  }
1111  else
1112  {
1113  FatalIOErrorInFunction(inFile)
1114  << "Unsupported tag "
1115  << tag << nl
1116  << exit(FatalIOError);
1117  }
1118  }
1119 
1120 
1121  // There is some problem with orientation of prisms - the point
1122  // ordering seems to be different for some exports (e.g. of cgns)
1123  {
1124  const cellModel& prism = cellModel::ref(cellModel::PRISM);
1125 
1126  label nSwapped = 0;
1127 
1128  for (cellShape& shape : cells_)
1129  {
1130  if (shape.model() == prism)
1131  {
1132  const triPointRef bottom
1133  (
1134  points_[shape[0]],
1135  points_[shape[1]],
1136  points_[shape[2]]
1137  );
1138  const triPointRef top
1139  (
1140  points_[shape[3]],
1141  points_[shape[4]],
1142  points_[shape[5]]
1143  );
1144 
1145  const point bottomCc(bottom.centre());
1146  const vector bottomNormal(bottom.areaNormal());
1147  const point topCc(top.centre());
1148 
1149  if (((topCc - bottomCc) & bottomNormal) < 0)
1150  {
1151  // Flip top and bottom
1152  std::swap(shape[0], shape[3]);
1153  std::swap(shape[1], shape[4]);
1154  std::swap(shape[2], shape[5]);
1155  ++nSwapped;
1156  }
1157  }
1158  }
1159  if (nSwapped)
1160  {
1161  WarningInFunction << "Swapped " << nSwapped
1162  << " prismatic cells" << nl;
1163  }
1164  }
1165 
1166  if (debug)
1167  {
1168  Info<< "Read points:" << points_.size()
1169  << " cells:" << cells_.size()
1170  << " faces:" << faces_.size()
1171  << " lines:" << lines_.size()
1172  << nl << nl;
1173 
1174  Info<< "Cell fields:" << nl;
1175  printFieldStats<vectorIOField>(cellData_);
1176  printFieldStats<scalarIOField>(cellData_);
1177  printFieldStats<labelIOField>(cellData_);
1178  printFieldStats<stringIOList>(cellData_);
1179  Info<< nl << nl;
1180 
1181  Info<< "Point fields:" << nl;
1182  printFieldStats<vectorIOField>(pointData_);
1183  printFieldStats<scalarIOField>(pointData_);
1184  printFieldStats<labelIOField>(pointData_);
1185  printFieldStats<stringIOList>(pointData_);
1186  Info<< nl << nl;
1187 
1188  Info<< "Other fields:" << nl;
1189  printFieldStats<vectorIOField>(otherData_);
1190  printFieldStats<scalarIOField>(otherData_);
1191  printFieldStats<labelIOField>(otherData_);
1192  printFieldStats<stringIOList>(otherData_);
1193  }
1194 }
1195 
1196 
1197 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::vtkUnstructuredReader::vtkDataSetTypeNames
static const Enum< vtkDataSetType > vtkDataSetTypeNames
Definition: vtkUnstructuredReader.H:98
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::vtkUnstructuredReader::vtkDataSetType
vtkDataSetType
Enumeration defining the vtk dataset types.
Definition: vtkUnstructuredReader.H:91
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::ISstream::getLine
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::vtkUnstructuredReader::parseModeNames
static const Enum< parseMode > parseModeNames
Definition: vtkUnstructuredReader.H:111
vtkUnstructuredReader.H
Foam::cellModel::HEX
hex
Definition: cellModel.H:81
Foam::vtk::VTK_HEXAHEDRON
Definition: foamVtkCore.H:103
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::vtk::VTK_PYRAMID
Definition: foamVtkCore.H:105
Foam::IOstream::lineNumber
label lineNumber() const noexcept
Const access to the current stream line number.
Definition: IOstream.H:318
Foam::FatalIOError
IOerror FatalIOError
scalarIOField.H
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
triPointRef.H
Foam::stringOps::splitSpace
Foam::SubStrings< StringType > splitSpace(const StringType &str)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
Definition: stringOpsTemplates.C:246
Foam::cellModel::TET
tet
Definition: cellModel.H:85
Foam::regIOobject::store
bool store()
Definition: regIOobjectI.H:37
Foam::vtk::VTK_LINE
Definition: foamVtkCore.H:94
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::vtkUnstructuredReader::vtkDataType
vtkDataType
Enumeration defining the vtk data types.
Definition: vtkUnstructuredReader.H:74
cellModel.H
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::labelSubList
SubList< label > labelSubList
A SubList of labels.
Definition: SubList.H:59
Foam::vtk::VTK_POLY_VERTEX
Definition: foamVtkCore.H:93
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::vtk::VTK_WEDGE
Definition: foamVtkCore.H:104
Foam::cellModel::PRISM
prism
Definition: cellModel.H:83
Foam::cellModel::ref
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:157
Foam::vtk::VTK_TRIANGLE
Definition: foamVtkCore.H:96
Foam::vtk::VTK_POLY_LINE
Definition: foamVtkCore.H:95
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::vtk::VTK_VERTEX
Definition: foamVtkCore.H:92
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::hex
IOstream & hex(IOstream &io)
Definition: IOstream.H:446
vectorIOField.H
Foam::cellModel::PYR
pyr
Definition: cellModel.H:84
cellTypes
const labelList & cellTypes
Definition: setCellMask.H:33
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::readLabel
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::vtk::VTK_POLYGON
Definition: foamVtkCore.H:98
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::vtkUnstructuredReader::vtkUnstructuredReader
vtkUnstructuredReader(const objectRegistry &obr, ISstream &is)
Construct from input stream, read all.
Definition: vtkUnstructuredReader.C:594
Foam::vtk::VTK_TETRA
Definition: foamVtkCore.H:101
Foam::expressions::POINT_DATA
Point data.
Definition: exprFieldAssociation.H:46
Foam::ISstream::read
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
split
static bool split(const std::string &line, std::string &key, std::string &val)
Definition: cpuInfo.C:39
Foam::vtk::fileTag::CELL_DATA
"CellData"
Foam::vtk::VTK_QUAD
Definition: foamVtkCore.H:100
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:340
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
stringOps.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::vtkUnstructuredReader::vtkDataTypeNames
static const Enum< vtkDataType > vtkDataTypeNames
Definition: vtkUnstructuredReader.H:87
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
fields
multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
Definition: createFields.H:97
Foam::vtkUnstructuredReader::parseMode
parseMode
Enumeration defining the parse mode - type of data being read.
Definition: vtkUnstructuredReader.H:102
Foam::triPointRef
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangle.H:71
labelIOField.H
Foam::readBlock
static void readBlock(Istream &is, const label n, List< T > &list)
Definition: vtkUnstructuredReader.C:96
stringIOList.H