vtkUnstructuredReader.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2012-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "vtkUnstructuredReader.H"
27 #include "labelIOField.H"
28 #include "scalarIOField.H"
29 #include "stringIOList.H"
30 #include "cellModeller.H"
31 #include "vectorIOField.H"
32 #include "tensorIOField.H"
33 #include "stringOps.H"
34 
35 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
36 
37 namespace Foam
38 {
40 }
41 
44 {
45  "int",
46  "unsigned_int",
47  "long",
48  "unsigned_long",
49  "float",
50  "double",
51  "string",
52  "vtkIdType"
53  };
54 
57 {
58  "FIELD",
59  "SCALARS",
60  "VECTORS"
61  };
62 
65 {
66  "NOMODE",
67  "UNSTRUCTURED_GRID",
68  "POLYDATA",
69  "CELL_DATA",
70  "POINT_DATA"
71 };
72 
73 
74 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
75 
76 void Foam::vtkUnstructuredReader::warnUnhandledType
77 (
78  Istream& inFile,
79  const label type,
80  labelHashSet& warningGiven
81 ) const
82 {
83  if (warningGiven.insert(type))
84  {
85  IOWarningInFunction(inFile)
86  << "Skipping unknown cell type " << type << endl;
87  }
88 }
89 
90 
91 void Foam::vtkUnstructuredReader::extractCells
92 (
93  Istream& inFile,
94  const labelList& cellTypes,
95  const labelList& cellVertData
96 )
97 {
98  const cellModel& hex = *(cellModeller::lookup("hex"));
99  const cellModel& prism = *(cellModeller::lookup("prism"));
100  const cellModel& pyr = *(cellModeller::lookup("pyr"));
101  const cellModel& tet = *(cellModeller::lookup("tet"));
102 
103  labelList tetPoints(4);
104  labelList pyrPoints(5);
105  labelList prismPoints(6);
106  labelList hexPoints(8);
107 
108  label celli = cells_.size();
109  cells_.setSize(celli+cellTypes.size());
110  cellMap_.setSize(cells_.size(), -1);
111 
112  label facei = faces_.size();
113  faces_.setSize(facei+cellTypes.size());
114  faceMap_.setSize(faces_.size(), -1);
115 
116  label lineI = lines_.size();
117  lines_.setSize(lineI+cellTypes.size());
118  lineMap_.setSize(lines_.size(), -1);
119 
120  label dataIndex = 0;
121 
122 
123  // To mark whether unhandled type has been visited.
124  labelHashSet warningGiven;
125 
126  forAll(cellTypes, i)
127  {
128  switch (cellTypes[i])
129  {
130  case VTK_VERTEX:
131  {
132  warnUnhandledType(inFile, cellTypes[i], warningGiven);
133  label nRead = cellVertData[dataIndex++];
134  if (nRead != 1)
135  {
137  (
138  inFile
139  ) << "Expected size 1 for VTK_VERTEX but found "
140  << nRead << exit(FatalIOError);
141  }
142  dataIndex += nRead;
143  }
144  break;
145 
146  case VTK_POLY_VERTEX:
147  {
148  warnUnhandledType(inFile, cellTypes[i], warningGiven);
149  label nRead = cellVertData[dataIndex++];
150  dataIndex += nRead;
151  }
152  break;
153 
154  case VTK_LINE:
155  {
156  // warnUnhandledType(inFile, cellTypes[i], warningGiven);
157  label nRead = cellVertData[dataIndex++];
158  if (nRead != 2)
159  {
161  (
162  inFile
163  ) << "Expected size 2 for VTK_LINE but found "
164  << nRead << exit(FatalIOError);
165  }
166  lineMap_[lineI] = i;
167  labelList& segment = lines_[lineI++];
168  segment.setSize(2);
169  segment[0] = cellVertData[dataIndex++];
170  segment[1] = cellVertData[dataIndex++];
171  }
172  break;
173 
174  case VTK_POLY_LINE:
175  {
176  // warnUnhandledType(inFile, cellTypes[i], warningGiven);
177  label nRead = cellVertData[dataIndex++];
178  lineMap_[lineI] = i;
179  labelList& segment = lines_[lineI++];
180  segment.setSize(nRead);
181  forAll(segment, i)
182  {
183  segment[i] = cellVertData[dataIndex++];
184  }
185  }
186  break;
187 
188  case VTK_TRIANGLE:
189  {
190  faceMap_[facei] = i;
191  face& f = faces_[facei++];
192  f.setSize(3);
193  label nRead = cellVertData[dataIndex++];
194  if (nRead != 3)
195  {
197  (
198  inFile
199  ) << "Expected size 3 for VTK_TRIANGLE but found "
200  << nRead << exit(FatalIOError);
201  }
202  f[0] = cellVertData[dataIndex++];
203  f[1] = cellVertData[dataIndex++];
204  f[2] = cellVertData[dataIndex++];
205  }
206  break;
207 
208  case VTK_QUAD:
209  {
210  faceMap_[facei] = i;
211  face& f = faces_[facei++];
212  f.setSize(4);
213  label nRead = cellVertData[dataIndex++];
214  if (nRead != 4)
215  {
217  (
218  inFile
219  ) << "Expected size 4 for VTK_QUAD but found "
220  << nRead << exit(FatalIOError);
221  }
222  f[0] = cellVertData[dataIndex++];
223  f[1] = cellVertData[dataIndex++];
224  f[2] = cellVertData[dataIndex++];
225  f[3] = cellVertData[dataIndex++];
226  }
227  break;
228 
229  case VTK_POLYGON:
230  {
231  faceMap_[facei] = i;
232  face& f = faces_[facei++];
233  label nRead = cellVertData[dataIndex++];
234  f.setSize(nRead);
235  forAll(f, fp)
236  {
237  f[fp] = cellVertData[dataIndex++];
238  }
239  }
240  break;
241 
242  case VTK_TETRA:
243  {
244  label nRead = cellVertData[dataIndex++];
245  if (nRead != 4)
246  {
248  (
249  inFile
250  ) << "Expected size 4 for VTK_TETRA but found "
251  << nRead << exit(FatalIOError);
252  }
253  tetPoints[0] = cellVertData[dataIndex++];
254  tetPoints[1] = cellVertData[dataIndex++];
255  tetPoints[2] = cellVertData[dataIndex++];
256  tetPoints[3] = cellVertData[dataIndex++];
257  cellMap_[celli] = i;
258  cells_[celli++] = cellShape(tet, tetPoints, true);
259  }
260  break;
261 
262  case VTK_PYRAMID:
263  {
264  label nRead = cellVertData[dataIndex++];
265  if (nRead != 5)
266  {
268  (
269  inFile
270  ) << "Expected size 5 for VTK_PYRAMID but found "
271  << nRead << exit(FatalIOError);
272  }
273  pyrPoints[0] = cellVertData[dataIndex++];
274  pyrPoints[1] = cellVertData[dataIndex++];
275  pyrPoints[2] = cellVertData[dataIndex++];
276  pyrPoints[3] = cellVertData[dataIndex++];
277  pyrPoints[4] = cellVertData[dataIndex++];
278  cellMap_[celli] = i;
279  cells_[celli++] = cellShape(pyr, pyrPoints, true);
280  }
281  break;
282 
283  case VTK_WEDGE:
284  {
285  label nRead = cellVertData[dataIndex++];
286  if (nRead != 6)
287  {
289  (
290  inFile
291  ) << "Expected size 6 for VTK_WEDGE but found "
292  << nRead << exit(FatalIOError);
293  }
294  prismPoints[0] = cellVertData[dataIndex++];
295  prismPoints[2] = cellVertData[dataIndex++];
296  prismPoints[1] = cellVertData[dataIndex++];
297  prismPoints[3] = cellVertData[dataIndex++];
298  prismPoints[5] = cellVertData[dataIndex++];
299  prismPoints[4] = cellVertData[dataIndex++];
300  cellMap_[celli] = i;
301  cells_[celli++] = cellShape(prism, prismPoints, true);
302  }
303  break;
304 
305  case VTK_HEXAHEDRON:
306  {
307  label nRead = cellVertData[dataIndex++];
308  if (nRead != 8)
309  {
311  (
312  inFile
313  ) << "Expected size 8 for VTK_HEXAHEDRON but found "
314  << nRead << exit(FatalIOError);
315  }
316  hexPoints[0] = cellVertData[dataIndex++];
317  hexPoints[1] = cellVertData[dataIndex++];
318  hexPoints[2] = cellVertData[dataIndex++];
319  hexPoints[3] = cellVertData[dataIndex++];
320  hexPoints[4] = cellVertData[dataIndex++];
321  hexPoints[5] = cellVertData[dataIndex++];
322  hexPoints[6] = cellVertData[dataIndex++];
323  hexPoints[7] = cellVertData[dataIndex++];
324  cellMap_[celli] = i;
325  cells_[celli++] = cellShape(hex, hexPoints, true);
326  }
327  break;
328 
329  default:
330  warnUnhandledType(inFile, cellTypes[i], warningGiven);
331  label nRead = cellVertData[dataIndex++];
332  dataIndex += nRead;
333  }
334  }
335 
336  if (debug)
337  {
338  Info<< "Read " << celli << " cells;" << facei << " faces." << endl;
339  }
340  cells_.setSize(celli);
341  cellMap_.setSize(celli);
342  faces_.setSize(facei);
343  faceMap_.setSize(facei);
344  lines_.setSize(lineI);
345  lineMap_.setSize(lineI);
346 }
347 
348 
349 void Foam::vtkUnstructuredReader::readField
350 (
351  ISstream& inFile,
352  objectRegistry& obj,
353  const word& arrayName,
354  const word& dataType,
355  const label size
356 ) const
357 {
358  switch (vtkDataTypeNames[dataType])
359  {
360  case VTK_INT:
361  case VTK_UINT:
362  case VTK_LONG:
363  case VTK_ULONG:
364  case VTK_ID:
365  {
366  autoPtr<labelIOField> fieldVals
367  (
368  new labelIOField
369  (
370  IOobject
371  (
372  arrayName,
373  "",
374  obj
375  ),
376  size
377  )
378  );
379  readBlock(inFile, fieldVals().size(), fieldVals());
380  regIOobject::store(fieldVals);
381  }
382  break;
383 
384  case VTK_FLOAT:
385  case VTK_DOUBLE:
386  {
387  autoPtr<scalarIOField> fieldVals
388  (
389  new scalarIOField
390  (
391  IOobject
392  (
393  arrayName,
394  "",
395  obj
396  ),
397  size
398  )
399  );
400  readBlock(inFile, fieldVals().size(), fieldVals());
401  regIOobject::store(fieldVals);
402  }
403  break;
404 
405  case VTK_STRING:
406  {
407  if (debug)
408  {
409  Info<< "Reading strings:" << size << endl;
410  }
411  autoPtr<stringIOList> fieldVals
412  (
413  new stringIOList
414  (
415  IOobject
416  (
417  arrayName,
418  "",
419  obj
420  ),
421  size
422  )
423  );
424  // Consume current line.
425  inFile.getLine(fieldVals()[0]);
426 
427  // Read without parsing
428  forAll(fieldVals(), i)
429  {
430  inFile.getLine(fieldVals()[i]);
431  }
432  regIOobject::store(fieldVals);
433  }
434  break;
435 
436  default:
437  {
438  IOWarningInFunction(inFile)
439  << "Unhandled type " << vtkDataTypeNames[dataType] << endl
440  << "Skipping " << size
441  << " words." << endl;
442  scalarField fieldVals;
443  readBlock(inFile, size, fieldVals);
444  }
445  break;
446  }
447 }
448 
449 
450 Foam::wordList Foam::vtkUnstructuredReader::readFieldArray
451 (
452  ISstream& inFile,
453  objectRegistry& obj,
454  const label wantedSize
455 ) const
456 {
457  DynamicList<word> fields;
458 
459  word dataName(inFile);
460  if (debug)
461  {
462  Info<< "dataName:" << dataName << endl;
463  }
464  label numArrays(readLabel(inFile));
465  if (debug)
466  {
467  Pout<< "numArrays:" << numArrays << endl;
468  }
469  for (label i = 0; i < numArrays; i++)
470  {
471  word arrayName(inFile);
472  label numComp(readLabel(inFile));
473  label numTuples(readLabel(inFile));
474  word dataType(inFile);
475 
476  if (debug)
477  {
478  Info<< "Reading field " << arrayName
479  << " of " << numTuples << " tuples of rank " << numComp << endl;
480  }
481 
482  if (wantedSize != -1 && numTuples != wantedSize)
483  {
484  FatalIOErrorInFunction(inFile)
485  << "Expected " << wantedSize << " tuples but only have "
486  << numTuples << exit(FatalIOError);
487  }
488 
489  readField
490  (
491  inFile,
492  obj,
493  arrayName,
494  dataType,
495  numTuples*numComp
496  );
497  fields.append(arrayName);
498  }
499  return fields.shrink();
500 }
501 
502 
503 Foam::objectRegistry& Foam::vtkUnstructuredReader::selectRegistry
504 (
505  const parseMode readMode
506 )
507 {
508  if (readMode == CELL_DATA)
509  {
510  return cellData_;
511  }
512  else if (readMode == POINT_DATA)
513  {
514  return pointData_;
515  }
516  else
517  {
518  return otherData_;
519  }
520 }
521 
522 
523 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
524 
526 (
527  const objectRegistry& obr,
528  ISstream& inFile
529 )
530 :
531  cellData_(IOobject("cellData", obr)),
532  pointData_(IOobject("pointData", obr)),
533  otherData_(IOobject("otherData", obr))
534 {
535  read(inFile);
536 }
537 
538 
539 void Foam::vtkUnstructuredReader::read(ISstream& inFile)
540 {
541  inFile.getLine(header_);
542  if (debug)
543  {
544  Info<< "Header : " << header_ << endl;
545  }
546  inFile.getLine(title_);
547  if (debug)
548  {
549  Info<< "Title : " << title_ << endl;
550  }
551  inFile.getLine(dataType_);
552  if (debug)
553  {
554  Info<< "dataType : " << dataType_ << endl;
555  }
556 
557  if (dataType_ == "BINARY")
558  {
559  FatalIOErrorInFunction(inFile)
560  << "Binary reading not supported " << exit(FatalIOError);
561  }
562 
563  parseMode readMode = NOMODE;
564  label wantedSize = -1;
565 
566 
567  // Temporary storage for vertices of cells.
568  labelList cellVerts;
569 
570  while (inFile.good())
571  {
572  word tag(inFile);
573 
574  if (!inFile.good())
575  {
576  break;
577  }
578 
579  if (debug)
580  {
581  Info<< "line:" << inFile.lineNumber()
582  << " tag:" << tag << endl;
583  }
584 
585  if (tag == "DATASET")
586  {
587  word geomType(inFile);
588  if (debug)
589  {
590  Info<< "geomType : " << geomType << endl;
591  }
592  readMode = parseModeNames[geomType];
593  wantedSize = -1;
594  }
595  else if (tag == "POINTS")
596  {
597  label nPoints(readLabel(inFile));
598  points_.setSize(nPoints);
599  if (debug)
600  {
601  Info<< "Reading " << nPoints << " numbers representing "
602  << points_.size() << " coordinates." << endl;
603  }
604 
605  word primitiveTag(inFile);
606  if (primitiveTag != "float" && primitiveTag != "double")
607  {
608  FatalIOErrorInFunction(inFile)
609  << "Expected 'float' entry but found "
610  << primitiveTag
611  << exit(FatalIOError);
612  }
613  forAll(points_, i)
614  {
615  inFile >> points_[i].x() >> points_[i].y() >> points_[i].z();
616  }
617  }
618  else if (tag == "CELLS")
619  {
620  label nCells(readLabel(inFile));
621  label nNumbers(readLabel(inFile));
622 
623  token next(inFile);
624  if (next.isNumber())
625  {
626  if (debug)
627  {
628  Info<< "Reading " << nCells << " cells or faces." << endl;
629  }
630 
631  inFile.putBack(next);
632  readBlock(inFile, nNumbers, cellVerts);
633  }
634  else if (next.isWord() && next.wordToken() == "OFFSETS")
635  {
636  nCells --;
637 
638  if (debug)
639  {
640  Info<< "Reading " << nCells << " cells or faces." << endl;
641  }
642 
643  // Read the offsets
644  const token offsetsIntType(inFile);
645  labelList cellOffsets;
646  readBlock(inFile, nCells + 1, cellOffsets);
647 
648  // Check the next tag is "CONNECTIVITY"
649  const token connectivityTag(inFile);
650  if
651  (
652  !connectivityTag.isWord()
653  || connectivityTag.wordToken() != "CONNECTIVITY"
654  )
655  {
656  FatalIOErrorInFunction(inFile)
657  << "Expected 'CONNECTIVITY' but found "
658  << next
659  << exit(FatalIOError);
660  }
661 
662  // Read the connectivity
663  const token connectivityIntType(inFile);
664  labelList cellConnectivity;
665  readBlock(inFile, nNumbers, cellConnectivity);
666 
667  // Build the cell vertices
668  cellVerts.resize(nCells + nNumbers);
669  for
670  (
671  label cellOffseti = 0, cellVerti = 0;
672  cellOffseti < nCells;
673  ++ cellOffseti
674  )
675  {
676  const label cellConnectivityi0 =
677  cellOffsets[cellOffseti];
678  const label cellConnectivityi1 =
679  cellOffsets[cellOffseti + 1];
680 
681  const label n = cellConnectivityi1 - cellConnectivityi0;
682 
683  cellVerts[cellVerti ++] = n;
684 
685  for (label i = 0; i < n; ++ i)
686  {
687  cellVerts[cellVerti ++] =
688  cellConnectivity[cellConnectivityi0 + i];
689  }
690  }
691  }
692  else
693  {
694  FatalIOErrorInFunction(inFile)
695  << "Expected 'label' entry or 'OFFSETS' but found "
696  << next
697  << exit(FatalIOError);
698  }
699  }
700  else if (tag == "CELL_TYPES")
701  {
702  label nCellTypes(readLabel(inFile));
703 
704  labelList cellTypes;
705  readBlock(inFile, nCellTypes, cellTypes);
706 
707  if (cellTypes.size() > 0 && cellVerts.size() == 0)
708  {
709  FatalIOErrorInFunction(inFile)
710  << "Found " << cellTypes.size()
711  << " cellTypes but no cells."
712  << exit(FatalIOError);
713  }
714 
715  extractCells(inFile, cellTypes, cellVerts);
716  cellVerts.clear();
717  }
718  else if (tag == "LINES")
719  {
720  label nLines(readLabel(inFile));
721  label nNumbers(readLabel(inFile));
722  if (debug)
723  {
724  Info<< "Reading " << nLines << " lines." << endl;
725  }
726  labelList lineVerts;
727  readBlock(inFile, nNumbers, lineVerts);
728 
729  label lineI = lines_.size();
730  lines_.setSize(lineI+nLines);
731  lineMap_.setSize(lines_.size());
732 
733  label elemI = 0;
734  for (label i = 0; i < nLines; i++)
735  {
736  lineMap_[lineI] = lineI;
737  labelList& f = lines_[lineI];
738  f.setSize(lineVerts[elemI++]);
739  forAll(f, fp)
740  {
741  f[fp] = lineVerts[elemI++];
742  }
743  lineI++;
744  }
745  }
746  else if (tag == "POLYGONS")
747  {
748  // If in polydata mode
749 
750  label nFaces(readLabel(inFile));
751  label nNumbers(readLabel(inFile));
752  if (debug)
753  {
754  Info<< "Reading " << nFaces << " faces." << endl;
755  }
756  labelList faceVerts;
757  readBlock(inFile, nNumbers, faceVerts);
758 
759  label facei = faces_.size();
760  faces_.setSize(facei+nFaces);
761  faceMap_.setSize(faces_.size());
762 
763  label elemI = 0;
764  for (label i = 0; i < nFaces; i++)
765  {
766  faceMap_[facei] = facei;
767  face& f = faces_[facei];
768  f.setSize(faceVerts[elemI++]);
769  forAll(f, fp)
770  {
771  f[fp] = faceVerts[elemI++];
772  }
773  facei++;
774  }
775  }
776  else if (tag == "POINT_DATA")
777  {
778  // 'POINT_DATA 24'
779  readMode = POINT_DATA;
780  wantedSize = points_.size();
781 
782  label nPoints(readLabel(inFile));
783  if (nPoints != wantedSize)
784  {
785  FatalIOErrorInFunction(inFile)
786  << "Reading POINT_DATA : expected " << wantedSize
787  << " but read " << nPoints << exit(FatalIOError);
788  }
789  }
790  else if (tag == "CELL_DATA")
791  {
792  readMode = CELL_DATA;
793  wantedSize = cells_.size()+faces_.size()+lines_.size();
794 
795  label nCells(readLabel(inFile));
796  if (nCells != wantedSize)
797  {
798  FatalIOErrorInFunction(inFile)
799  << "Reading CELL_DATA : expected "
800  << wantedSize
801  << " but read " << nCells << exit(FatalIOError);
802  }
803  }
804  else if (tag == "FIELD")
805  {
806  // wantedSize already set according to type we expected to read.
807  readFieldArray(inFile, selectRegistry(readMode), wantedSize);
808  }
809  else if (tag == "SCALARS")
810  {
811  string line;
812  inFile.getLine(line);
813  IStringStream is(line);
814  word dataName(is);
815  word dataType(is);
816  // label numComp(readLabel(inFile));
817 
818  if (debug)
819  {
820  Info<< "Reading scalar " << dataName
821  << " of type " << dataType
822  << " from lookup table" << endl;
823  }
824 
825  word lookupTableTag(inFile);
826  if (lookupTableTag != "LOOKUP_TABLE")
827  {
828  FatalIOErrorInFunction(inFile)
829  << "Expected tag LOOKUP_TABLE but read "
830  << lookupTableTag
831  << exit(FatalIOError);
832  }
833 
834  word lookupTableName(inFile);
835 
836  readField
837  (
838  inFile,
839  selectRegistry(readMode),
840  dataName,
841  dataType,
842  wantedSize//*numComp
843  );
844  }
845  else if (tag == "VECTORS" || tag == "NORMALS")
846  {
847  // 'NORMALS Normals float'
848  string line;
849  inFile.getLine(line);
850  IStringStream is(line);
851  word dataName(is);
852  word dataType(is);
853  if (debug)
854  {
855  Info<< "Reading vector " << dataName
856  << " of type " << dataType << endl;
857  }
858 
859  objectRegistry& reg = selectRegistry(readMode);
860 
861  readField
862  (
863  inFile,
864  reg,
865  dataName,
866  dataType,
867  3*wantedSize
868  );
869 
870  if
871  (
872  vtkDataTypeNames[dataType] == VTK_FLOAT
873  || vtkDataTypeNames[dataType] == VTK_DOUBLE
874  )
875  {
876  objectRegistry::iterator iter = reg.find(dataName);
877  scalarField s(*dynamic_cast<const scalarField*>(iter()));
878  reg.erase(iter);
879  autoPtr<vectorIOField> fieldVals
880  (
881  new vectorIOField
882  (
883  IOobject
884  (
885  dataName,
886  "",
887  reg
888  ),
889  s.size()/3
890  )
891  );
892 
893  label elemI = 0;
894  forAll(fieldVals(), i)
895  {
896  fieldVals()[i].x() = s[elemI++];
897  fieldVals()[i].y() = s[elemI++];
898  fieldVals()[i].z() = s[elemI++];
899  }
900  regIOobject::store(fieldVals);
901  }
902  }
903  else if (tag == "TENSORS")
904  {
905  // 'TENSORS Tensors float'
906  string line;
907  inFile.getLine(line);
908  IStringStream is(line);
909  word dataName(is);
910  word dataType(is);
911  if (debug)
912  {
913  Info<< "Reading tensor " << dataName
914  << " of type " << dataType << endl;
915  }
916 
917  objectRegistry& reg = selectRegistry(readMode);
918 
919  readField
920  (
921  inFile,
922  reg,
923  dataName,
924  dataType,
925  9*wantedSize
926  );
927 
928  if
929  (
930  vtkDataTypeNames[dataType] == VTK_FLOAT
931  || vtkDataTypeNames[dataType] == VTK_DOUBLE
932  )
933  {
934  objectRegistry::iterator iter = reg.find(dataName);
935  scalarField s(*dynamic_cast<const scalarField*>(iter()));
936  reg.erase(iter);
937  autoPtr<tensorIOField> fieldVals
938  (
939  new tensorIOField
940  (
941  IOobject
942  (
943  dataName,
944  "",
945  reg
946  ),
947  s.size()/9
948  )
949  );
950 
951  label elemI = 0;
952  forAll(fieldVals(), i)
953  {
954  fieldVals()[i].xx() = s[elemI++];
955  fieldVals()[i].xy() = s[elemI++];
956  fieldVals()[i].xz() = s[elemI++];
957  fieldVals()[i].yx() = s[elemI++];
958  fieldVals()[i].yy() = s[elemI++];
959  fieldVals()[i].yz() = s[elemI++];
960  fieldVals()[i].zx() = s[elemI++];
961  fieldVals()[i].zy() = s[elemI++];
962  fieldVals()[i].zz() = s[elemI++];
963  }
964  regIOobject::store(fieldVals);
965  }
966  }
967  else if (tag == "TEXTURE_COORDINATES")
968  {
969  // 'TEXTURE_COORDINATES TCoords 2 float'
970  string line;
971  inFile.getLine(line);
972  IStringStream is(line);
973  word dataName(is); //"Tcoords"
974  label dim(readLabel(is));
975  word dataType(is);
976 
977  if (debug)
978  {
979  Info<< "Reading texture coords " << dataName
980  << " dimension " << dim
981  << " of type " << dataType << endl;
982  }
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  label nNumbers(readLabel(inFile));
991  if (debug)
992  {
993  Info<< "Reading " << nStrips << " triangle strips." << endl;
994  }
995  labelList faceVerts;
996  readBlock(inFile, nNumbers, faceVerts);
997 
998  // Count number of triangles
999  label elemI = 0;
1000  label nTris = 0;
1001  for (label i = 0; i < nStrips; i++)
1002  {
1003  label nVerts = faceVerts[elemI++];
1004  nTris += nVerts-2;
1005  elemI += nVerts;
1006  }
1007 
1008 
1009  // Store
1010  label facei = faces_.size();
1011  faces_.setSize(facei+nTris);
1012  faceMap_.setSize(faces_.size());
1013  elemI = 0;
1014  for (label i = 0; i < nStrips; i++)
1015  {
1016  label nVerts = faceVerts[elemI++];
1017  label nTris = nVerts-2;
1018 
1019  // Read first triangle
1020  faceMap_[facei] = facei;
1021  face& f = faces_[facei++];
1022  f.setSize(3);
1023  f[0] = faceVerts[elemI++];
1024  f[1] = faceVerts[elemI++];
1025  f[2] = faceVerts[elemI++];
1026  for (label triI = 1; triI < nTris; triI++)
1027  {
1028  faceMap_[facei] = facei;
1029  face& f = faces_[facei++];
1030  f.setSize(3);
1031  f[0] = faceVerts[elemI-1];
1032  f[1] = faceVerts[elemI-2];
1033  f[2] = faceVerts[elemI++];
1034  }
1035  }
1036  }
1037  else if (tag == "METADATA")
1038  {
1039  // Read rest of the line
1040  string line;
1041  inFile.getLine(line);
1042 
1043  // Skip until an empty line is found
1044  inFile.getLine(line);
1045  while (!stringOps::trim(line).empty())
1046  {
1047  inFile.getLine(line);
1048  }
1049  }
1050  else
1051  {
1052  FatalIOErrorInFunction(inFile)
1053  << "Unsupported tag "
1054  << tag << exit(FatalIOError);
1055  }
1056  }
1057 
1058  if (debug)
1059  {
1060  Info<< "Read points:" << points_.size()
1061  << " cellShapes:" << cells_.size()
1062  << " faces:" << faces_.size()
1063  << " lines:" << lines_.size()
1064  << nl << endl;
1065 
1066  Info<< "Cell fields:" << endl;
1067  printFieldStats<scalarIOField>(cellData_);
1068  printFieldStats<vectorIOField>(cellData_);
1069  printFieldStats<tensorIOField>(cellData_);
1070  printFieldStats<labelIOField>(cellData_);
1071  printFieldStats<stringIOList>(cellData_);
1072  Info<< nl << endl;
1073 
1074  Info<< "Point fields:" << endl;
1075  printFieldStats<scalarIOField>(pointData_);
1076  printFieldStats<vectorIOField>(pointData_);
1077  printFieldStats<tensorIOField>(pointData_);
1078  printFieldStats<labelIOField>(pointData_);
1079  printFieldStats<stringIOList>(pointData_);
1080  Info<< nl << endl;
1081 
1082  Info<< "Other fields:" << endl;
1083  printFieldStats<scalarIOField>(otherData_);
1084  printFieldStats<vectorIOField>(otherData_);
1085  printFieldStats<tensorIOField>(otherData_);
1086  printFieldStats<labelIOField>(otherData_);
1087  printFieldStats<stringIOList>(otherData_);
1088  }
1089 }
1090 
1091 
1092 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
friend class iterator
Declare friendship with the iterator.
Definition: HashTable.H:194
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
label lineNumber() const
Return current stream line number.
Definition: IOstream.H:450
Generic input stream.
Definition: ISstream.H:55
ISstream & getLine(string &, const bool continuation=true)
Read line into a string.
Definition: ISstream.C:703
bool good() const
Return true if next operation might succeed.
Definition: Istream.H:101
void putBack(const token &)
Put back token.
Definition: Istream.C:30
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:55
static const cellModel * lookup(const word &)
Look up a model by name and return a pointer to the model or nullptr.
Definition: cellModeller.C:100
Registry of regIOobjects.
void store()
Transfer ownership of this object to its registry.
Definition: regIOobjectI.H:40
Reader for vtk unstructured_grid legacy files. Supports single CELLS, POINTS etc. entry only.
static const NamedEnum< parseMode, 5 > parseModeNames
vtkUnstructuredReader(const objectRegistry &obr, ISstream &)
Construct from Istream, read all.
static const NamedEnum< vtkDataSetType, 3 > vtkDataSetTypeNames
static const NamedEnum< vtkDataType, 8 > vtkDataTypeNames
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
label nPoints
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Info<< "Calculating turbulent flame speed field St\n"<< endl;volScalarField St(IOobject("St", runTime.name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), flameWrinkling->Xi() *Su);multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
Definition: createFields.H:234
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
string trim(const string &)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:947
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
IOField< tensor > tensorIOField
tensorField with IO.
Definition: tensorIOField.H:42
IOstream & hex(IOstream &io)
Definition: IOstream.H:585
messageStream Info
IOField< scalar > scalarIOField
scalarField with IO.
Definition: scalarIOField.H:43
IOField< label > labelIOField
labelField with IO.
Definition: labelIOField.H:42
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
IOList< string > stringIOList
IO of a list of strings.
Definition: stringIOList.H:42
IOField< vector > vectorIOField
vectorField with IO.
Definition: vectorIOField.H:43
IOerror FatalIOError
label readLabel(Istream &is)
Definition: label.H:64
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:213
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
static const char nl
Definition: Ostream.H:297
Pair< point > segment
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
labelList f(nPoints)