1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkEnSight6BinaryReader.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkEnSight6BinaryReader.h"
16 
17 #include "vtkByteSwap.h"
18 #include "vtkCellData.h"
19 #include "vtkCharArray.h"
20 #include "vtkFloatArray.h"
21 #include "vtkIdList.h"
22 #include "vtkIdTypeArray.h"
23 #include "vtkMultiBlockDataSet.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkPointData.h"
26 #include "vtkPolyData.h"
27 #include "vtkRectilinearGrid.h"
28 #include "vtkStructuredGrid.h"
29 #include "vtkStructuredPoints.h"
30 #include "vtkUnstructuredGrid.h"
31 
32 #include <sys/stat.h>
33 #include <cctype>
34 #include <string>
35 
36 #if defined(_WIN32)
37 # define VTK_STAT_STRUCT struct _stat64
38 # define VTK_STAT_FUNC _stat64
39 #elif defined _DARWIN_FEATURE_64_BIT_INODE || (defined __FreeBSD__||defined(__DragonFly__))
40 // FreeBSD and OSX use stat
41 # define VTK_STAT_STRUCT struct stat
42 # define VTK_STAT_FUNC stat
43 #else
44 // here, we're relying on _FILE_OFFSET_BITS defined in vtkWin32Header.h to help
45 // us on POSIX without resorting to using stat64.
46 # define VTK_STAT_STRUCT struct stat64
47 # define VTK_STAT_FUNC stat64
48 #endif
49 
50 vtkStandardNewMacro(vtkEnSight6BinaryReader);
51 
52 //----------------------------------------------------------------------------
vtkEnSight6BinaryReader()53 vtkEnSight6BinaryReader::vtkEnSight6BinaryReader()
54 {
55   this->NumberOfUnstructuredPoints = 0;
56   this->UnstructuredPoints = vtkPoints::New();
57   this->UnstructuredNodeIds = nullptr;
58 
59   this->BinaryIFile = nullptr;
60 
61   this->FileSize = 0;
62 
63   this->ElementIdsListed = 0;
64 }
65 
66 //----------------------------------------------------------------------------
~vtkEnSight6BinaryReader()67 vtkEnSight6BinaryReader::~vtkEnSight6BinaryReader()
68 {
69   if (this->UnstructuredNodeIds)
70   {
71     this->UnstructuredNodeIds->Delete();
72     this->UnstructuredNodeIds = nullptr;
73   }
74   this->UnstructuredPoints->Delete();
75   this->UnstructuredPoints = nullptr;
76 
77   if (this->BinaryIFile)
78   {
79     this->BinaryIFile->close();
80     delete this->BinaryIFile;
81     this->BinaryIFile = nullptr;
82   }
83 }
84 
85 //----------------------------------------------------------------------------
OpenFile(const char * filename)86 int vtkEnSight6BinaryReader::OpenFile(const char* filename)
87 {
88   if (!filename)
89   {
90     vtkErrorMacro(<<"Missing filename.");
91     return 0;
92   }
93 
94   // Close file from any previous image
95   if (this->BinaryIFile)
96   {
97     this->BinaryIFile->close();
98     delete this->BinaryIFile;
99     this->BinaryIFile = nullptr;
100   }
101 
102   // Open the new file
103   vtkDebugMacro(<< "Opening file " << filename);
104   VTK_STAT_STRUCT fs;
105   if ( !VTK_STAT_FUNC( filename, &fs) )
106   {
107     // Find out how big the file is.
108     this->FileSize = static_cast<vtkTypeUInt64>(fs.st_size);
109 
110 #ifdef _WIN32
111     this->BinaryIFile = new ifstream(filename, ios::in | ios::binary);
112 #else
113     this->BinaryIFile = new ifstream(filename, ios::in);
114 #endif
115   }
116   else
117   {
118     vtkErrorMacro("stat failed.");
119     return 0;
120   }
121   if (! this->BinaryIFile || this->BinaryIFile->fail())
122   {
123     vtkErrorMacro(<< "Could not open file " << filename);
124     return 0;
125   }
126   return 1;
127 }
128 
129 //----------------------------------------------------------------------------
ReadGeometryFile(const char * fileName,int timeStep,vtkMultiBlockDataSet * output)130 int vtkEnSight6BinaryReader::ReadGeometryFile(const char* fileName,
131                                               int timeStep,
132                                               vtkMultiBlockDataSet *output)
133 {
134   char line[80], subLine[80];
135   int partId, realId;
136   int lineRead;
137   float *coordinateArray;
138   int i;
139   int pointIdsListed;
140   int *pointIds;
141 
142   // Initialize
143   //
144   if (!fileName)
145   {
146     vtkErrorMacro("A GeometryFileName must be specified in the case file.");
147     return 0;
148   }
149   std::string sfilename;
150   if (this->FilePath)
151   {
152     sfilename = this->FilePath;
153     if (sfilename.at(sfilename.length()-1) != '/')
154     {
155       sfilename += "/";
156     }
157     sfilename += fileName;
158     vtkDebugMacro("full path to geometry file: " << sfilename.c_str());
159   }
160   else
161   {
162     sfilename = fileName;
163   }
164 
165   if (this->OpenFile(sfilename.c_str()) == 0)
166   {
167     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
168     return 0;
169   }
170 
171   lineRead = this->ReadLine(line);
172   sscanf(line, " %*s %s", subLine);
173   if (strcmp(subLine, "Binary") != 0 &&
174       strcmp(subLine, "binary") != 0)
175   {
176     vtkErrorMacro("This is not an EnSight6 binary file. Try "
177                   << "vtkEnSight6Reader.");
178     return 0;
179   }
180 
181   if (this->UseFileSets)
182   {
183     for (i = 0; i < timeStep - 1; i++)
184     {
185       if (!this->SkipTimeStep())
186       {
187         return 0;
188       }
189     }
190     while (strncmp(line, "BEGIN TIME STEP", 15) != 0 && lineRead)
191     {
192       lineRead = this->ReadLine(line);
193     }
194   }
195 
196   // Skip the 2 description lines.  Using ReadLine instead of ReadLine
197   // because the description line could be blank.
198   this->ReadLine(line);
199   this->ReadLine(line);
200 
201   // Read the node id and element id lines.
202   this->ReadLine(line); // node id *
203   sscanf(line, " %*s %*s %s", subLine);
204   if (strcmp(subLine, "given") == 0)
205   {
206     this->UnstructuredNodeIds = vtkIdTypeArray::New();
207     pointIdsListed = 1;
208   }
209   else if (strcmp(subLine, "ignore") == 0)
210   {
211     pointIdsListed = 1;
212   }
213   else
214   {
215     pointIdsListed = 0;
216   }
217 
218   this->ReadLine(line); // element id *
219   sscanf(line, " %*s %*s %s", subLine);
220   if (strcmp(subLine, "given") == 0 || strcmp(subLine, "ignore") == 0)
221   {
222     this->ElementIdsListed = 1;
223   }
224   else
225   {
226     this->ElementIdsListed = 0;
227   }
228 
229   this->ReadLine(line); // "coordinates"
230   this->ReadIntNumber(&this->NumberOfUnstructuredPoints); // number of points
231   if (this->NumberOfUnstructuredPoints < 0 ||
232     static_cast<unsigned int>(this->NumberOfUnstructuredPoints) * sizeof(int) > this->FileSize)
233   {
234     vtkErrorMacro("Invalid number of unstructured points; check that ByteOrder is set correctly.");
235     return 0;
236   }
237 
238   this->UnstructuredPoints->SetNumberOfPoints(
239                                this->NumberOfUnstructuredPoints);
240 
241   if (pointIdsListed)
242   {
243     pointIds = new int[this->NumberOfUnstructuredPoints];
244     this->ReadIntArray(pointIds, this->NumberOfUnstructuredPoints);
245 
246     if (this->UnstructuredNodeIds)
247     {
248       int maxId = 0;
249       for (i = 0; i < this->NumberOfUnstructuredPoints; i++)
250       {
251         if (pointIds[i] > maxId)
252         {
253           maxId = pointIds[i];
254         }
255       }
256 
257       this->UnstructuredNodeIds->Allocate(maxId);
258       this->UnstructuredNodeIds->FillComponent(0, -1);
259 
260       for (i = 0; i < this->NumberOfUnstructuredPoints; i++)
261       {
262         this->UnstructuredNodeIds->InsertValue(pointIds[i]-1, i);
263       }
264     }
265     delete [] pointIds;
266   }
267 
268   coordinateArray = (float*)(this->UnstructuredPoints->GetVoidPointer(0));
269   this->ReadFloatArray(coordinateArray, this->NumberOfUnstructuredPoints * 3);
270 
271   lineRead = this->ReadLine(line); // "part"
272 
273   while (lineRead && strncmp(line, "part", 4) == 0)
274   {
275     this->NumberOfGeometryParts++;
276     sscanf(line, " part %d", &partId);
277     partId--; // EnSight starts #ing at 1.
278     realId = this->InsertNewPartId(partId);
279 
280     this->ReadLine(line); // part description line
281     char *name = strdup(line);
282     this->ReadLine(line);
283 
284     if (strncmp(line, "block", 5) == 0)
285     {
286       lineRead = this->CreateStructuredGridOutput(realId, line, name, output);
287     }
288     else
289     {
290       lineRead = this->CreateUnstructuredGridOutput(realId, line, name, output);
291     }
292     free(name);
293   }
294 
295   if (this->UnstructuredNodeIds)
296   {
297       this->UnstructuredNodeIds->Delete();
298       this->UnstructuredNodeIds = nullptr;
299   }
300   // Close file from any previous image
301   if (this->BinaryIFile)
302   {
303     this->BinaryIFile->close();
304     delete this->BinaryIFile;
305     this->BinaryIFile = nullptr;
306   }
307   if (lineRead < 0)
308   {
309     return 0;
310   }
311   return 1;
312 }
313 
314 //----------------------------------------------------------------------------
SkipTimeStep()315 int vtkEnSight6BinaryReader::SkipTimeStep()
316 {
317   char line[80], subLine[80];
318   int lineRead;
319   int pointIdsListed;
320 
321   this->ReadLine(line);
322   while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
323   {
324     this->ReadLine(line);
325   }
326 
327   // Skip the 2 description lines.
328   this->ReadLine(line);
329   this->ReadLine(line);
330 
331   // Read the node id and element id lines.
332   this->ReadLine(line); // node id *
333   sscanf(line, " %*s %*s %s", subLine);
334   if (strcmp(subLine, "given") == 0 ||
335       strcmp(subLine, "ignore") == 0)
336   {
337     pointIdsListed = 1;
338   }
339   else
340   {
341     pointIdsListed = 0;
342   }
343 
344   this->ReadLine(line); // element id *
345   sscanf(line, " %*s %*s %s", subLine);
346   if (strcmp(subLine, "given") == 0 || strcmp(subLine, "ignore") == 0)
347   {
348     this->ElementIdsListed = 1;
349   }
350   else
351   {
352     this->ElementIdsListed = 0;
353   }
354 
355   this->ReadLine(line); // "coordinates"
356   this->ReadIntNumber(&this->NumberOfUnstructuredPoints); // number of points
357   if (this->NumberOfUnstructuredPoints < 0 ||
358     static_cast<unsigned int>(this->NumberOfUnstructuredPoints * sizeof(int)) > this->FileSize)
359   {
360     vtkErrorMacro("Invalid number of unstructured points; check that ByteOrder is set correctly.");
361     return 0;
362   }
363 
364   if (pointIdsListed)
365   { // skip point ids.
366     this->BinaryIFile->seekg((sizeof(int)*this->NumberOfUnstructuredPoints), ios::cur);
367   }
368 
369   this->BinaryIFile->seekg((sizeof(float)*3*this->NumberOfUnstructuredPoints), ios::cur);
370 
371   lineRead = this->ReadLine(line); // "part"
372 
373   while (lineRead && strncmp(line, "part", 4) == 0)
374   {
375     this->ReadLine(line); // part description line
376     this->ReadLine(line);
377 
378     if (strncmp(line, "block", 5) == 0)
379     {
380       lineRead = this->SkipStructuredGrid(line);
381     }
382     else
383     {
384       lineRead = this->SkipUnstructuredGrid(line);
385     }
386   }
387   if (lineRead < 0)
388   {
389     return 0;
390   }
391 
392   return 1;
393 }
394 
395 //----------------------------------------------------------------------------
SkipStructuredGrid(char line[256])396 int vtkEnSight6BinaryReader::SkipStructuredGrid(char line[256])
397 {
398   char subLine[80];
399   int lineRead;
400   int iblanked = 0;
401   int dimensions[3];
402   int numPts;
403 
404   if (sscanf(line, " %*s %s", subLine) == 1)
405   {
406     if (strcmp(subLine, "iblanked") == 0)
407     {
408       iblanked = 1;
409     }
410   }
411 
412   // Read these separately to get byte order set.
413   this->ReadIntNumber(dimensions);
414   this->ReadIntNumber(dimensions+1);
415   this->ReadIntNumber(dimensions+2);
416   numPts = dimensions[0] * dimensions[1] * dimensions[2];
417   if (dimensions[0] < 0 ||
418     static_cast<unsigned int>(dimensions[0] * sizeof(int)) > this->FileSize ||
419     dimensions[1] < 0 ||
420     static_cast<unsigned int>(dimensions[1] * sizeof(int)) > this->FileSize ||
421     dimensions[2] < 0 ||
422     static_cast<unsigned int>(dimensions[2] * sizeof(int)) > this->FileSize ||
423     numPts < 0 ||
424     static_cast<unsigned int>(numPts * sizeof(int)) > this->FileSize)
425   {
426     vtkErrorMacro("Invalid dimensions read; check that ByteOrder is set correctly.");
427     return -1;
428   }
429 
430   // Skip coordinates.
431   this->BinaryIFile->seekg((sizeof(float)*3*numPts), ios::cur);
432 
433   if (iblanked)
434   { // skip blanking array.
435     this->BinaryIFile->seekg((sizeof(int)*numPts), ios::cur);
436   }
437 
438   // reading next line to check for EOF
439   lineRead = this->ReadLine(line);
440   return lineRead;
441 }
442 
443 //----------------------------------------------------------------------------
SkipUnstructuredGrid(char line[256])444 int vtkEnSight6BinaryReader::SkipUnstructuredGrid(char line[256])
445 {
446   int lineRead = 1;
447   int numElements;
448   int cellType;
449 
450   while(lineRead && strncmp(line, "part", 4) != 0)
451   {
452     if (strncmp(line, "point", 5) == 0)
453     {
454       vtkDebugMacro("point");
455 
456       this->ReadIntNumber(&numElements);
457       if (numElements < 0 ||
458         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
459       {
460         vtkErrorMacro("Invalid number of point cells; check that ByteOrder is set correctly.");
461         return -1;
462       }
463       if (this->ElementIdsListed)
464       { // skip element ids.
465         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
466       }
467 
468       // nodeIdList
469       this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
470     }
471     else if (strncmp(line, "bar2", 4) == 0)
472     {
473       vtkDebugMacro("bar2");
474 
475       this->ReadIntNumber(&numElements);
476       if (numElements < 0 ||
477         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
478       {
479         vtkErrorMacro("Invalid number of bar2 cells; check that ByteOrder is set correctly.");
480         return -1;
481       }
482       if (this->ElementIdsListed)
483       { // skip element ids.
484         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
485       }
486 
487       // Skip node ids.
488       this->BinaryIFile->seekg((sizeof(int)*2*numElements), ios::cur);
489     }
490     else if (strncmp(line, "bar3", 4) == 0)
491     {
492       vtkDebugMacro("bar3");
493       vtkWarningMacro("Only vertex nodes of this element will be read.");
494 
495       this->ReadIntNumber(&numElements);
496       if (numElements < 0 ||
497         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
498       {
499         vtkErrorMacro("Invalid number of bar3 cells; check that ByteOrder is set correctly.");
500         return -1;
501       }
502       if (this->ElementIdsListed)
503       {
504         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
505       }
506 
507       // Skip node ids.
508       this->BinaryIFile->seekg((sizeof(int)*3*numElements), ios::cur);
509     }
510     else if (strncmp(line, "tria3", 5) == 0 ||
511              strncmp(line, "tria6", 5) == 0)
512     {
513       if (strncmp(line, "tria3", 5) == 0)
514       {
515         vtkDebugMacro("tria3");
516         cellType = vtkEnSightReader::TRIA3;
517       }
518       else
519       {
520         vtkDebugMacro("tria6");
521         vtkWarningMacro("Only vertex nodes of this element will be read.");
522         cellType = vtkEnSightReader::TRIA6;
523       }
524 
525       this->ReadIntNumber(&numElements);
526       if (numElements < 0 ||
527         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
528       {
529         vtkErrorMacro("Invalid number of triangle cells; check that ByteOrder is set correctly.");
530         return -1;
531       }
532       if (this->ElementIdsListed)
533       {
534         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
535       }
536 
537       if (cellType == vtkEnSightReader::TRIA3)
538       {
539         this->BinaryIFile->seekg((sizeof(int)*3*numElements), ios::cur);
540       }
541       else
542       {
543         this->BinaryIFile->seekg((sizeof(int)*6*numElements), ios::cur);
544       }
545     }
546     else if (strncmp(line, "quad4", 5) == 0 ||
547              strncmp(line, "quad8", 5) == 0)
548     {
549       if (strncmp(line, "quad8", 5) == 0)
550       {
551         vtkDebugMacro("quad8");
552         vtkWarningMacro("Only vertex nodes of this element will be read.");
553         cellType = vtkEnSightReader::QUAD8;
554       }
555       else
556       {
557         vtkDebugMacro("quad4");
558         cellType = vtkEnSightReader::QUAD4;
559       }
560 
561       this->ReadIntNumber(&numElements);
562       if (numElements < 0 ||
563         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
564       {
565         vtkErrorMacro("Invalid number of quad cells; check that ByteOrder is set correctly.");
566         return -1;
567       }
568       if (this->ElementIdsListed)
569       {
570         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
571       }
572 
573       if (cellType == vtkEnSightReader::QUAD4)
574       {
575         this->BinaryIFile->seekg((sizeof(int)*4*numElements), ios::cur);
576       }
577       else
578       {
579         this->BinaryIFile->seekg((sizeof(int)*8*numElements), ios::cur);
580       }
581     }
582     else if (strncmp(line, "tetra4", 6) == 0 ||
583              strncmp(line, "tetra10", 7) == 0)
584     {
585       if (strncmp(line, "tetra10", 7) == 0)
586       {
587         vtkDebugMacro("tetra10");
588         vtkWarningMacro("Only vertex nodes of this element will be read.");
589         cellType = vtkEnSightReader::TETRA10;
590       }
591       else
592       {
593         vtkDebugMacro("tetra4");
594         cellType = vtkEnSightReader::TETRA4;
595       }
596 
597       this->ReadIntNumber(&numElements);
598       if (numElements < 0 ||
599         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
600       {
601         vtkErrorMacro("Invalid number of tetrahedral cells; check that ByteOrder is set correctly.");
602         return -1;
603       }
604       if (this->ElementIdsListed)
605       {
606         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
607       }
608 
609       if (cellType == vtkEnSightReader::TETRA4)
610       {
611         this->BinaryIFile->seekg((sizeof(int)*4*numElements), ios::cur);
612       }
613       else
614       {
615         this->BinaryIFile->seekg((sizeof(int)*10*numElements), ios::cur);
616       }
617     }
618     else if (strncmp(line, "pyramid5", 8) == 0 ||
619              strncmp(line, "pyramid13", 9) == 0)
620     {
621       if (strncmp(line, "pyramid13", 9) == 0)
622       {
623         vtkDebugMacro("pyramid13");
624         vtkWarningMacro("Only vertex nodes of this element will be read.");
625         cellType = vtkEnSightReader::PYRAMID13;
626       }
627       else
628       {
629         vtkDebugMacro("pyramid5");
630         cellType = vtkEnSightReader::PYRAMID5;
631       }
632 
633       this->ReadIntNumber(&numElements);
634       if (numElements < 0 ||
635         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
636       {
637         vtkErrorMacro("Invalid number of pyramid cells; check that ByteOrder is set correctly.");
638         return -1;
639       }
640       if (this->ElementIdsListed)
641       {
642         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
643       }
644 
645       if (cellType == vtkEnSightReader::PYRAMID5)
646       {
647         this->BinaryIFile->seekg((sizeof(int)*5*numElements), ios::cur);
648       }
649       else
650       {
651         this->BinaryIFile->seekg((sizeof(int)*13*numElements), ios::cur);
652       }
653     }
654     else if (strncmp(line, "hexa8", 5) == 0 ||
655              strncmp(line, "hexa20", 6) == 0)
656     {
657       if (strncmp(line, "hexa20", 6) == 0)
658       {
659         vtkDebugMacro("hexa20");
660         vtkWarningMacro("Only vertex nodes of this element will be read.");
661         cellType = vtkEnSightReader::HEXA20;
662       }
663       else
664       {
665         vtkDebugMacro("hexa8");
666         cellType = vtkEnSightReader::HEXA8;
667       }
668 
669       this->ReadIntNumber(&numElements);
670       if (numElements < 0 ||
671         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
672       {
673         vtkErrorMacro("Invalid number of hexahedral cells; check that ByteOrder is set correctly.");
674         return -1;
675       }
676       if (this->ElementIdsListed)
677       {
678         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
679       }
680 
681       if (cellType == vtkEnSightReader::HEXA8)
682       {
683         this->BinaryIFile->seekg((sizeof(int)*8*numElements), ios::cur);
684       }
685       else
686       {
687         this->BinaryIFile->seekg((sizeof(int)*20*numElements), ios::cur);
688       }
689     }
690     else if (strncmp(line, "penta6", 6) == 0 ||
691              strncmp(line, "penta15", 7) == 0)
692     {
693       if (strncmp(line, "penta15", 7) == 0)
694       {
695         vtkDebugMacro("penta15");
696         vtkWarningMacro("Only vertex nodes of this element will be read.");
697         cellType = vtkEnSightReader::PENTA15;
698       }
699       else
700       {
701         vtkDebugMacro("penta6");
702         cellType = vtkEnSightReader::PENTA6;
703       }
704 
705       this->ReadIntNumber(&numElements);
706       if (numElements < 0 ||
707         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
708       {
709         vtkErrorMacro("Invalid number of pentagonal cells; check that ByteOrder is set correctly.");
710         return -1;
711       }
712       if (this->ElementIdsListed)
713       {
714         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
715       }
716 
717       if (cellType == vtkEnSightReader::PENTA6)
718       {
719         this->BinaryIFile->seekg((sizeof(int)*6*numElements), ios::cur);
720       }
721       else
722       {
723         this->BinaryIFile->seekg((sizeof(int)*15*numElements), ios::cur);
724       }
725     }
726     else if (strncmp(line, "END TIME STEP", 13) == 0)
727     {
728       break;
729     }
730     lineRead = this->ReadLine(line);
731   }
732 
733   return lineRead;
734 }
735 
736 //----------------------------------------------------------------------------
ReadMeasuredGeometryFile(const char * fileName,int timeStep,vtkMultiBlockDataSet * output)737 int vtkEnSight6BinaryReader::ReadMeasuredGeometryFile(
738   const char* fileName, int timeStep, vtkMultiBlockDataSet *output)
739 {
740   char line[80], subLine[80];
741   vtkIdType i;
742   int *pointIds;
743   float *coords;
744   vtkPoints *points = vtkPoints::New();
745   vtkPolyData *pd = vtkPolyData::New();
746 
747   this->NumberOfNewOutputs++;
748 
749   // Initialize
750   //
751   if (!fileName)
752   {
753     vtkErrorMacro("A MeasuredFileName must be specified in the case file.");
754     points->Delete();
755     pd->Delete();
756     return 0;
757   }
758   std::string sfilename;
759   if (this->FilePath)
760   {
761     sfilename = this->FilePath;
762     if (sfilename.at(sfilename.length()-1) != '/')
763     {
764       sfilename += "/";
765     }
766     sfilename += fileName;
767     vtkDebugMacro("full path to measured geometry file: "
768                   << sfilename.c_str());
769   }
770   else
771   {
772     sfilename = fileName;
773   }
774 
775   if (this->OpenFile(sfilename.c_str()) == 0)
776   {
777     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
778     points->Delete();
779     pd->Delete();
780     return 0;
781   }
782 
783   this->ReadLine(line);
784   sscanf(line, " %*s %s", subLine);
785   if (strcmp(subLine, "Binary") != 0)
786   {
787     vtkErrorMacro("This is not a binary data set. Try "
788                   << "vtkEnSightGoldReader.");
789     points->Delete();
790     pd->Delete();
791     return 0;
792   }
793 
794   if (this->UseFileSets)
795   {
796     for (i = 0; i < timeStep - 1; i++)
797     {
798       this->ReadLine(line);
799       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
800       {
801         this->ReadLine(line);
802       }
803 
804       // Skip the description line.
805       this->ReadLine(line);
806 
807       this->ReadLine(line); // "particle coordinates"
808 
809       this->ReadIntNumber(&this->NumberOfMeasuredPoints);
810       if (this->NumberOfMeasuredPoints < 0 ||
811         static_cast<unsigned int>(this->NumberOfMeasuredPoints * sizeof(int)) > this->FileSize)
812       {
813         vtkErrorMacro("Invalid number of measured points; check that ByteOrder is set correctly.");
814         points->Delete();
815         pd->Delete();
816         return 0;
817       }
818 
819       pointIds = new int[this->NumberOfMeasuredPoints];
820       coords = new float [this->NumberOfMeasuredPoints*3];
821 
822       this->ReadIntArray(pointIds, this->NumberOfMeasuredPoints);
823       this->ReadFloatArray(coords, this->NumberOfMeasuredPoints*3);
824 
825       delete [] pointIds;
826       delete [] coords;
827 
828       this->ReadLine(line); // END TIME STEP
829     }
830     while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
831     {
832       this->ReadLine(line);
833     }
834   }
835 
836   // Skip the description line.
837   this->ReadLine(line);
838 
839   this->ReadLine(line); // "particle coordinates"
840 
841   this->ReadIntNumber(&this->NumberOfMeasuredPoints);
842   if (this->NumberOfMeasuredPoints < 0 ||
843     static_cast<unsigned int>(this->NumberOfMeasuredPoints * sizeof(int)) > this->FileSize)
844   {
845     vtkErrorMacro("Invalid number of measured points; check that ByteOrder is set correctly.");
846     points->Delete();
847     pd->Delete();
848     return 0;
849   }
850 
851   pointIds = new int[this->NumberOfMeasuredPoints];
852   coords = new float [this->NumberOfMeasuredPoints*3];
853   points->Allocate(this->NumberOfMeasuredPoints);
854   pd->Allocate(this->NumberOfMeasuredPoints);
855 
856   this->ReadIntArray(pointIds, this->NumberOfMeasuredPoints);
857   this->ReadFloatArray(coords, this->NumberOfMeasuredPoints*3);
858 
859   if (this->ParticleCoordinatesByIndex)
860   {
861     for (i = 0; i < this->NumberOfMeasuredPoints; i++)
862     {
863       points->InsertNextPoint(coords[3*i], coords[3*i+1], coords[3*i+2]);
864       pd->InsertNextCell(VTK_VERTEX, 1, &i);
865     }
866   }
867   else
868   {
869     vtkIdType id;
870     for (i = 0; i < this->NumberOfMeasuredPoints; i++)
871     {
872       id = pointIds[i];
873       points->InsertNextPoint(coords[3*i], coords[3*i+1], coords[3*i+2]);
874       pd->InsertNextCell(VTK_VERTEX, 1, &id);
875     }
876   }
877 
878   pd->SetPoints(points);
879   this->AddToBlock(output, this->NumberOfGeometryParts, pd);
880 
881   points->Delete();
882   pd->Delete();
883   delete [] pointIds;
884   delete [] coords;
885 
886   if (this->BinaryIFile)
887   {
888     this->BinaryIFile->close();
889     delete this->BinaryIFile;
890     this->BinaryIFile = nullptr;
891   }
892   return 1;
893 }
894 
895 //----------------------------------------------------------------------------
ReadScalarsPerNode(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput,int measured,int numberOfComponents,int component)896 int vtkEnSight6BinaryReader::ReadScalarsPerNode(
897   const char* fileName, const char* description, int timeStep,
898   vtkMultiBlockDataSet *compositeOutput, int measured,
899   int numberOfComponents, int component)
900 {
901   char line[80];
902   int partId, realId, numPts, numParts, i;
903   vtkFloatArray *scalars;
904   float* scalarsRead;
905   long pos;
906   vtkDataSet *output;
907   int lineRead;
908 
909   // Initialize
910   //
911   if (!fileName)
912   {
913     vtkErrorMacro("nullptr ScalarPerNode variable file name");
914     return 0;
915   }
916   std::string sfilename;
917   if (this->FilePath)
918   {
919     sfilename = this->FilePath;
920     if (sfilename.at(sfilename.length()-1) != '/')
921     {
922       sfilename += "/";
923     }
924     sfilename += fileName;
925     vtkDebugMacro("full path to scalar per node file: " << sfilename.c_str());
926   }
927   else
928   {
929     sfilename = fileName;
930   }
931 
932   if (this->OpenFile(sfilename.c_str()) == 0)
933   {
934     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
935     return 0;
936   }
937 
938   if (this->UseFileSets)
939   {
940     for (i = 0; i < timeStep - 1; i++)
941     {
942       this->ReadLine(line);
943       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
944       {
945         this->ReadLine(line);
946       }
947       this->ReadLine(line); // skip the description line
948 
949       pos = this->BinaryIFile->tellg();
950       this->ReadLine(line); // 1st data line or part #
951       if (strncmp(line, "part", 4) != 0)
952       {
953         this->BinaryIFile->seekg(pos, ios::beg);
954         if (!measured)
955         {
956           numPts = this->UnstructuredPoints->GetNumberOfPoints();
957         }
958         else
959         {
960           numPts = this->GetDataSetFromBlock(
961             compositeOutput, this->NumberOfGeometryParts)->GetNumberOfPoints();
962         }
963 
964         // Here I am assuming that we are skipping over data
965         // we do not need to read.
966         //scalarsRead = new float[numPts];
967         //this->ReadFloatArray(scalarsRead, numPts);
968         //delete [] scalarsRead;
969         this->BinaryIFile->seekg((long)(numPts)*(long)(sizeof(float)), ios::cur);
970         if (this->BinaryIFile->fail())
971         {
972           vtkErrorMacro("File seek failed.");
973         }
974       }
975 
976       // scalars for structured parts
977       while (this->ReadLine(line) && strncmp(line, "part", 4) == 0)
978       {
979         sscanf(line, " part %d", &partId);
980         partId--;
981         realId = this->InsertNewPartId(partId);
982         this->ReadLine(line); // block
983         numPts = this->GetDataSetFromBlock(
984           compositeOutput, realId)->GetNumberOfPoints();
985 
986         // Here I am assuming that we are skipping over data
987         // we do not need to read.
988         //scalarsRead = new float[numPts];
989         //this->ReadFloatArray(scalarsRead, numPts);
990         //delete [] scalarsRead;
991         this->BinaryIFile->seekg((long)(numPts)*(long)(sizeof(float)), ios::cur);
992         if (this->BinaryIFile->fail())
993         {
994           vtkErrorMacro("File seek failed.");
995         }
996         //scalarsRead = new float[numPts];
997         //this->ReadFloatArray(scalarsRead, numPts);
998         //delete [] scalarsRead;
999       }
1000     }
1001     lineRead = this->ReadLine(line);
1002     while (strncmp(line, "BEGIN TIME STEP", 15) != 0 && lineRead)
1003     {
1004       lineRead = this->ReadLine(line);
1005     }
1006   }
1007 
1008   this->ReadLine(line); // skip the description line
1009 
1010   pos = this->BinaryIFile->tellg();
1011   lineRead = this->ReadLine(line); // 1st data line or part #
1012   if (strncmp(line, "part", 4) != 0)
1013   {
1014     int allocatedScalars = 0;
1015     this->BinaryIFile->seekg(pos, ios::beg);
1016     if (!measured)
1017     {
1018       numPts = this->UnstructuredPoints->GetNumberOfPoints();
1019     }
1020     else
1021     {
1022       numPts = this->GetDataSetFromBlock(compositeOutput,
1023         this->NumberOfGeometryParts)->GetNumberOfPoints();
1024     }
1025     if (component == 0)
1026     {
1027       scalars = vtkFloatArray::New();
1028       scalars->SetNumberOfTuples(numPts);
1029       scalars->SetNumberOfComponents(numberOfComponents);
1030       scalars->Allocate(numPts * numberOfComponents);
1031       allocatedScalars = 1;
1032     }
1033     else
1034     {
1035       partId = this->UnstructuredPartIds->GetId(0);
1036       scalars = static_cast<vtkFloatArray*>(
1037         this->GetDataSetFromBlock(compositeOutput, partId)->
1038         GetPointData()->GetArray(description));
1039     }
1040     scalarsRead = new float[numPts];
1041     this->ReadFloatArray(scalarsRead, numPts);
1042     for (i = 0; i < numPts; i++)
1043     {
1044       scalars->InsertComponent(i, component, scalarsRead[i]);
1045     }
1046 
1047     if (!measured)
1048     {
1049       numParts = this->UnstructuredPartIds->GetNumberOfIds();
1050       for (i = 0; i < numParts; i++)
1051       {
1052         partId = this->UnstructuredPartIds->GetId(i);
1053         output = this->GetDataSetFromBlock(compositeOutput, partId);
1054         if (component == 0)
1055         {
1056           scalars->SetName(description);
1057           output->GetPointData()->AddArray(scalars);
1058           if (!output->GetPointData()->GetScalars())
1059           {
1060             output->GetPointData()->SetScalars(scalars);
1061           }
1062         }
1063         else
1064         {
1065           output->GetPointData()->AddArray(scalars);
1066         }
1067       }
1068     }
1069     else
1070     {
1071       scalars->SetName(description);
1072       output = this->GetDataSetFromBlock(
1073         compositeOutput, this->NumberOfGeometryParts);
1074       output->GetPointData()->AddArray(scalars);
1075       if (!output->GetPointData()->GetScalars())
1076       {
1077         output->GetPointData()->SetScalars(scalars);
1078       }
1079     }
1080     delete [] scalarsRead;
1081     if(allocatedScalars)
1082     {
1083       scalars->Delete();
1084     }
1085   }
1086 
1087   // scalars for structured parts
1088   while (lineRead && strncmp(line, "part", 4) == 0)
1089   {
1090     int allocatedScalars = 0;
1091     sscanf(line, " part %d", &partId);
1092     partId--;
1093     realId = this->InsertNewPartId(partId);
1094     output = this->GetDataSetFromBlock(compositeOutput, realId);
1095     if (output == nullptr)
1096     {
1097       vtkErrorMacro("Could not get output for part " << partId);
1098       vtkErrorMacro("Got part from line: " << line);
1099       return 0;
1100     }
1101 
1102     this->ReadLine(line); // block
1103     numPts = output->GetNumberOfPoints();
1104     scalarsRead = new float[numPts];
1105     if (component == 0)
1106     {
1107       scalars = vtkFloatArray::New();
1108       scalars->SetNumberOfTuples(numPts);
1109       scalars->SetNumberOfComponents(numberOfComponents);
1110       scalars->Allocate(numPts * numberOfComponents);
1111       allocatedScalars = 1;
1112     }
1113     else
1114     {
1115       scalars = (vtkFloatArray*)(output->GetPointData()->
1116                                  GetArray(description));
1117     }
1118     this->ReadFloatArray(scalarsRead, numPts);
1119     for (i = 0; i < numPts; i++)
1120     {
1121       scalars->InsertComponent(i, component, scalarsRead[i]);
1122     }
1123     if (component == 0)
1124     {
1125       scalars->SetName(description);
1126       output->GetPointData()->AddArray(scalars);
1127       if (!output->GetPointData()->GetScalars())
1128       {
1129         output->GetPointData()->SetScalars(scalars);
1130       }
1131     }
1132     else
1133     {
1134       output->GetPointData()->AddArray(scalars);
1135     }
1136     delete [] scalarsRead;
1137     lineRead = this->ReadLine(line);
1138     if(allocatedScalars)
1139     {
1140       scalars->Delete();
1141     }
1142   }
1143 
1144   if (this->BinaryIFile)
1145   {
1146     this->BinaryIFile->close();
1147     delete this->BinaryIFile;
1148     this->BinaryIFile = nullptr;
1149   }
1150   return 1;
1151 }
1152 
1153 //----------------------------------------------------------------------------
ReadVectorsPerNode(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput,int measured)1154 int vtkEnSight6BinaryReader::ReadVectorsPerNode(
1155   const char* fileName, const char* description, int timeStep,
1156   vtkMultiBlockDataSet *compositeOutput, int measured)
1157 {
1158   char line[80];
1159   int partId, realId, numPts, i;
1160   vtkFloatArray *vectors;
1161   float vector[3];
1162   float *vectorsRead;
1163   long pos;
1164   vtkDataSet *output;
1165   int lineRead;
1166 
1167   // Initialize
1168   //
1169   if (!fileName)
1170   {
1171     vtkErrorMacro("nullptr VectorPerNode variable file name");
1172     return 0;
1173   }
1174   std::string sfilename;
1175   if (this->FilePath)
1176   {
1177     sfilename = this->FilePath;
1178     if (sfilename.at(sfilename.length()-1) != '/')
1179     {
1180       sfilename += "/";
1181     }
1182     sfilename += fileName;
1183     vtkDebugMacro("full path to vector per node file: " << sfilename.c_str());
1184   }
1185   else
1186   {
1187     sfilename = fileName;
1188   }
1189 
1190   if (this->OpenFile(sfilename.c_str()) == 0)
1191   {
1192     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
1193     return 0;
1194   }
1195 
1196   if (this->UseFileSets)
1197   {
1198     for (i = 0; i < timeStep - 1; i++)
1199     {
1200       this->ReadLine(line);
1201       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1202       {
1203         this->ReadLine(line);
1204       }
1205       this->ReadLine(line); // skip the description line
1206 
1207       pos = this->BinaryIFile->tellg();
1208       this->ReadLine(line); // 1st data line or part #
1209       if (strncmp(line, "part", 4) != 0)
1210       {
1211         this->BinaryIFile->seekg(pos, ios::beg);
1212         if (!measured)
1213         {
1214           numPts = this->UnstructuredPoints->GetNumberOfPoints();
1215         }
1216         else
1217         {
1218           numPts = this->GetDataSetFromBlock(compositeOutput,
1219             this->NumberOfGeometryParts)->GetNumberOfPoints();
1220         }
1221 
1222         vectorsRead = new float[numPts*3];
1223         this->ReadFloatArray(vectorsRead, numPts*3);
1224 
1225         delete [] vectorsRead;
1226       }
1227 
1228       // vectors for structured parts
1229       while (this->ReadLine(line) && strncmp(line, "part", 4) == 0)
1230       {
1231         sscanf(line, " part %d", &partId);
1232         partId--;
1233         realId = this->InsertNewPartId(partId);
1234         this->ReadLine(line); // block
1235         numPts = this->GetDataSetFromBlock(
1236           compositeOutput, realId)->GetNumberOfPoints();
1237         vectorsRead = new float[numPts*3];
1238 
1239         this->ReadFloatArray(vectorsRead, numPts*3);
1240 
1241         delete [] vectorsRead;
1242       }
1243     }
1244     lineRead = this->ReadLine(line);
1245     while (strncmp(line, "BEGIN TIME STEP", 15) != 0 && lineRead)
1246     {
1247       lineRead = this->ReadLine(line);
1248     }
1249   }
1250 
1251   this->ReadLine(line); // skip the description line
1252 
1253   pos = this->BinaryIFile->tellg();
1254   lineRead = this->ReadLine(line); // 1st data line or part #
1255   if (strncmp(line, "part", 4) != 0)
1256   {
1257     this->BinaryIFile->seekg(pos, ios::beg);
1258     if (!measured)
1259     {
1260       numPts = this->UnstructuredPoints->GetNumberOfPoints();
1261     }
1262     else
1263     {
1264       numPts = this->GetDataSetFromBlock(
1265         compositeOutput, this->NumberOfGeometryParts)->
1266         GetNumberOfPoints();
1267     }
1268 
1269     vectors = vtkFloatArray::New();
1270     vectors->SetNumberOfTuples(numPts);
1271     vectors->SetNumberOfComponents(3);
1272     vectors->Allocate(numPts*3);
1273     vectorsRead = new float[numPts*3];
1274     this->ReadFloatArray(vectorsRead, numPts*3);
1275     for (i = 0; i < numPts; i++)
1276     {
1277       vector[0] = vectorsRead[3*i];
1278       vector[1] = vectorsRead[3*i+1];
1279       vector[2] = vectorsRead[3*i+2];
1280       vectors->InsertTuple(i, vector);
1281     }
1282 
1283     if (!measured)
1284     {
1285       for (i = 0; i < this->UnstructuredPartIds->GetNumberOfIds(); i++)
1286       {
1287         partId = this->UnstructuredPartIds->GetId(i);
1288         output = this->GetDataSetFromBlock(compositeOutput, partId);
1289         vectors->SetName(description);
1290         output->GetPointData()->AddArray(vectors);
1291         if (!output->GetPointData()->GetVectors())
1292         {
1293           output->GetPointData()->SetVectors(vectors);
1294         }
1295       }
1296     }
1297     else
1298     {
1299       vectors->SetName(description);
1300       output = this->GetDataSetFromBlock(
1301         compositeOutput, this->NumberOfGeometryParts);
1302       output->GetPointData()->AddArray(vectors);
1303       if (!output->GetPointData()->GetVectors())
1304       {
1305         output->GetPointData()->SetVectors(vectors);
1306       }
1307     }
1308 
1309     vectors->Delete();
1310     delete [] vectorsRead;
1311   }
1312 
1313   // vectors for structured parts
1314   while (lineRead && strncmp(line, "part", 4) == 0)
1315   {
1316     sscanf(line, " part %d", &partId);
1317     partId--;
1318     realId = this->InsertNewPartId(partId);
1319     output = this->GetDataSetFromBlock(compositeOutput, realId);
1320     this->ReadLine(line); // block
1321     numPts = output->GetNumberOfPoints();
1322     vectors = vtkFloatArray::New();
1323     vectors->SetNumberOfTuples(numPts);
1324     vectors->SetNumberOfComponents(3);
1325     vectors->Allocate(numPts*3);
1326     vectorsRead = new float[numPts*3];
1327 
1328     this->ReadFloatArray(vectorsRead, numPts*3);
1329     for (i = 0; i < numPts; i++)
1330     {
1331       vector[0] = vectorsRead[3*i];
1332       vector[1] = vectorsRead[3*i+1];
1333       vector[2] = vectorsRead[3*i+2];
1334       vectors->InsertTuple(i, vector);
1335     }
1336 
1337     vectors->SetName(description);
1338     output->GetPointData()->AddArray(vectors);
1339     if (!output->GetPointData()->GetVectors())
1340     {
1341       output->GetPointData()->SetVectors(vectors);
1342     }
1343     vectors->Delete();
1344     delete [] vectorsRead;
1345     lineRead = this->ReadLine(line);
1346   }
1347 
1348   if (this->BinaryIFile)
1349   {
1350     this->BinaryIFile->close();
1351     delete this->BinaryIFile;
1352     this->BinaryIFile = nullptr;
1353   }
1354 
1355   return 1;
1356 }
1357 
1358 //----------------------------------------------------------------------------
ReadTensorsPerNode(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput)1359 int vtkEnSight6BinaryReader::ReadTensorsPerNode(
1360   const char* fileName, const char* description, int timeStep,
1361   vtkMultiBlockDataSet *compositeOutput)
1362 {
1363   char line[80];
1364   int partId, realId, numPts, i;
1365   vtkFloatArray *tensors;
1366   float tensor[6];
1367   float* tensorsRead;
1368   long pos;
1369   vtkDataSet *output;
1370   int lineRead;
1371 
1372   // Initialize
1373   //
1374   if (!fileName)
1375   {
1376     vtkErrorMacro("nullptr TensorSymmPerNode variable file name");
1377     return 0;
1378   }
1379   std::string sfilename;
1380   if (this->FilePath)
1381   {
1382     sfilename = this->FilePath;
1383     if (sfilename.at(sfilename.length()-1) != '/')
1384     {
1385       sfilename += "/";
1386     }
1387     sfilename += fileName;
1388     vtkDebugMacro("full path to tensor symm per node file: "
1389                   << sfilename.c_str());
1390   }
1391   else
1392   {
1393     sfilename = fileName;
1394   }
1395 
1396   if (this->OpenFile(sfilename.c_str()) == 0)
1397   {
1398     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
1399     return 0;
1400   }
1401 
1402   if (this->UseTimeSets)
1403   {
1404     for (i = 0; i < timeStep - 1; i++)
1405     {
1406       this->ReadLine(line);
1407       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1408       {
1409         this->ReadLine(line);
1410       }
1411       this->ReadLine(line); // skip the description line
1412 
1413       pos = this->BinaryIFile->tellg();
1414       this->ReadLine(line); // 1st data line or part #
1415       if (strncmp(line, "part", 4) != 0)
1416       {
1417         this->BinaryIFile->seekg(pos, ios::beg);
1418         numPts = this->UnstructuredPoints->GetNumberOfPoints();
1419         tensorsRead = new float[numPts*6];
1420         this->ReadFloatArray(tensorsRead, numPts*6);
1421 
1422         delete [] tensorsRead;
1423       }
1424 
1425       // vectors for structured parts
1426       while (this->ReadLine(line) &&
1427              strncmp(line, "part", 4) == 0)
1428       {
1429         sscanf(line, " part %d", &partId);
1430         partId--;
1431         realId = this->InsertNewPartId(partId);
1432         this->ReadLine(line); // block
1433         numPts = this->GetDataSetFromBlock(
1434           compositeOutput, realId)->GetNumberOfPoints();
1435         tensorsRead = new float[numPts*6];
1436         this->ReadFloatArray(tensorsRead, numPts*6);
1437 
1438         delete [] tensorsRead;
1439       }
1440     }
1441     this->ReadLine(line);
1442     while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1443     {
1444       this->ReadLine(line);
1445     }
1446   }
1447 
1448   this->ReadLine(line); // skip the description line
1449 
1450   pos = this->BinaryIFile->tellg();
1451   lineRead = this->ReadLine(line); // 1st data line or part #
1452   if (strncmp(line, "part", 4) != 0)
1453   {
1454     this->BinaryIFile->seekg(pos, ios::beg);
1455     numPts = this->UnstructuredPoints->GetNumberOfPoints();
1456     tensors = vtkFloatArray::New();
1457     tensors->SetNumberOfTuples(numPts);
1458     tensors->SetNumberOfComponents(6);
1459     tensors->Allocate(numPts*6);
1460     tensorsRead = new float[numPts*6];
1461     this->ReadFloatArray(tensorsRead, numPts*6);
1462     for (i = 0; i < numPts; i++)
1463     {
1464       tensor[0] = tensorsRead[6*i];
1465       tensor[1] = tensorsRead[6*i+1];
1466       tensor[2] = tensorsRead[6*i+2];
1467       tensor[3] = tensorsRead[6*i+3];
1468       tensor[4] = tensorsRead[6*i+5];
1469       tensor[5] = tensorsRead[6*i+4];
1470       tensors->InsertTuple(i, tensor);
1471     }
1472 
1473     for (i = 0; i < this->UnstructuredPartIds->GetNumberOfIds(); i++)
1474     {
1475       partId = this->UnstructuredPartIds->GetId(i);
1476       tensors->SetName(description);
1477       this->GetDataSetFromBlock(compositeOutput, partId)->
1478         GetPointData()->AddArray(tensors);
1479     }
1480     tensors->Delete();
1481     delete [] tensorsRead;
1482   }
1483 
1484   // vectors for structured parts
1485   while (lineRead && strncmp(line, "part", 4) == 0)
1486   {
1487     sscanf(line, " part %d", &partId);
1488     partId--;
1489     realId = this->InsertNewPartId(partId);
1490     output = this->GetDataSetFromBlock(compositeOutput, realId);
1491     this->ReadLine(line); // block
1492     numPts = output->GetNumberOfPoints();
1493     tensors = vtkFloatArray::New();
1494     tensors->SetNumberOfTuples(numPts);
1495     tensors->SetNumberOfComponents(6);
1496     tensors->Allocate(numPts*6);
1497     tensorsRead = new float[numPts*6];
1498     this->ReadFloatArray(tensorsRead, numPts*6);
1499 
1500     for (i = 0; i < numPts; i++)
1501     {
1502       tensor[0] = tensorsRead[6*i];
1503       tensor[1] = tensorsRead[6*i+1];
1504       tensor[2] = tensorsRead[6*i+2];
1505       tensor[3] = tensorsRead[6*i+3];
1506       tensor[4] = tensorsRead[6*i+5];
1507       tensor[5] = tensorsRead[6*i+4];
1508       tensors->InsertTuple(i, tensor);
1509     }
1510 
1511     tensors->SetName(description);
1512     output->GetPointData()->AddArray(tensors);
1513     tensors->Delete();
1514     delete [] tensorsRead;
1515 
1516     lineRead = this->ReadLine(line);
1517   }
1518 
1519   if (this->BinaryIFile)
1520   {
1521     this->BinaryIFile->close();
1522     delete this->BinaryIFile;
1523     this->BinaryIFile = nullptr;
1524   }
1525   return 1;
1526 }
1527 
1528 //----------------------------------------------------------------------------
ReadScalarsPerElement(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput,int numberOfComponents,int component)1529 int vtkEnSight6BinaryReader::ReadScalarsPerElement(
1530   const char* fileName, const char* description, int timeStep,
1531   vtkMultiBlockDataSet *compositeOutput, int numberOfComponents,
1532   int component)
1533 {
1534   char line[80];
1535   int partId, realId, numCells, numCellsPerElement, i, idx;
1536   vtkFloatArray *scalars;
1537   int elementType;
1538   float* scalarsRead;
1539   int lineRead;
1540   vtkDataSet *output;
1541 
1542   // Initialize
1543   //
1544   if (!fileName)
1545   {
1546     vtkErrorMacro("nullptr ScalarPerElement variable file name");
1547     return 0;
1548   }
1549   std::string sfilename;
1550   if (this->FilePath)
1551   {
1552     sfilename = this->FilePath;
1553     if (sfilename.at(sfilename.length()-1) != '/')
1554     {
1555       sfilename += "/";
1556     }
1557     sfilename += fileName;
1558     vtkDebugMacro("full path to scalar per element file: "
1559                   << sfilename.c_str());
1560   }
1561   else
1562   {
1563     sfilename = fileName;
1564   }
1565 
1566   if (this->OpenFile(sfilename.c_str()) == 0)
1567   {
1568     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
1569     return 0;
1570   }
1571 
1572   if (this->UseFileSets)
1573   {
1574     for (i = 0; i < timeStep - 1; i++)
1575     {
1576       this->ReadLine(line);
1577       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1578       {
1579         this->ReadLine(line);
1580       }
1581       this->ReadLine(line); // skip the description line
1582       lineRead = this->ReadLine(line);
1583 
1584       while (lineRead && strncmp(line, "part", 4) == 0)
1585       {
1586         sscanf(line, " part %d", &partId);
1587         partId--; // EnSight starts #ing with 1.
1588         realId = this->InsertNewPartId(partId);
1589         numCells = this->GetDataSetFromBlock(
1590           compositeOutput, realId)->GetNumberOfCells();
1591         lineRead = this->ReadLine(line); // element type or "block"
1592 
1593         // need to find out from CellIds how many cells we have of this element
1594         // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
1595         if (strcmp(line, "block") != 0)
1596         {
1597           while (lineRead && strncmp(line, "part", 4) != 0 &&
1598                  strncmp(line, "END TIME STEP", 13) != 0)
1599           {
1600             elementType = this->GetElementType(line);
1601             if (elementType < 0)
1602             {
1603               vtkErrorMacro("invalid element type");
1604               this->BinaryIFile->close();
1605               delete this->BinaryIFile;
1606               this->BinaryIFile = nullptr;
1607               return 0;
1608             }
1609             idx = this->UnstructuredPartIds->IsId(realId);
1610             numCellsPerElement = this->GetCellIds(idx, elementType)->
1611               GetNumberOfIds();
1612             scalarsRead = new float[numCellsPerElement];
1613             this->ReadFloatArray(scalarsRead, numCellsPerElement);
1614 
1615             delete [] scalarsRead;
1616             lineRead = this->ReadLine(line);
1617           } // end while
1618         }
1619         else
1620         {
1621           scalarsRead = new float[numCells];
1622           this->ReadFloatArray(scalarsRead, numCells);
1623 
1624           delete [] scalarsRead;
1625           lineRead = this->ReadLine(line);
1626         }
1627       }
1628     }
1629     this->ReadLine(line);
1630     while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1631     {
1632       this->ReadLine(line);
1633     }
1634   }
1635 
1636   this->ReadLine(line); // skip the description line
1637   lineRead = this->ReadLine(line);
1638 
1639   while (lineRead && strncmp(line, "part", 4) == 0)
1640   {
1641     int allocatedScalars = 0;
1642     sscanf(line, " part %d", &partId);
1643     partId--; // EnSight starts #ing with 1.
1644     realId = this->InsertNewPartId(partId);
1645     output = this->GetDataSetFromBlock(compositeOutput, realId);
1646     numCells = output->GetNumberOfCells();
1647     lineRead = this->ReadLine(line); // element type or "block"
1648     if (component == 0)
1649     {
1650       scalars = vtkFloatArray::New();
1651       scalars->SetNumberOfTuples(numCells);
1652       scalars->SetNumberOfComponents(numberOfComponents);
1653       scalars->Allocate(numCells * numberOfComponents);
1654       allocatedScalars = 1;
1655     }
1656     else
1657     {
1658       scalars = (vtkFloatArray*)(output->GetCellData()->GetArray(description));
1659     }
1660 
1661     // need to find out from CellIds how many cells we have of this element
1662     // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
1663     if (strcmp(line, "block") != 0)
1664     {
1665       while (lineRead && strncmp(line, "part", 4) != 0 &&
1666         strncmp(line, "END TIME STEP", 13) != 0)
1667       {
1668         elementType = this->GetElementType(line);
1669         if (elementType < 0)
1670         {
1671           vtkErrorMacro("invalid element type");
1672           this->BinaryIFile->close();
1673           delete this->BinaryIFile;
1674           this->BinaryIFile = nullptr;
1675           return 0;
1676         }
1677         idx = this->UnstructuredPartIds->IsId(realId);
1678         numCellsPerElement = this->GetCellIds(idx, elementType)->GetNumberOfIds();
1679         scalarsRead = new float[numCellsPerElement];
1680         this->ReadFloatArray(scalarsRead, numCellsPerElement);
1681         for (i = 0; i < numCellsPerElement; i++)
1682         {
1683           scalars->InsertComponent(this->GetCellIds(idx, elementType)->GetId(i),
1684                                    component, scalarsRead[i]);
1685         }
1686         delete [] scalarsRead;
1687         lineRead = this->ReadLine(line);
1688       } // end while
1689     }
1690     else
1691     {
1692       scalarsRead = new float[numCells];
1693       this->ReadFloatArray(scalarsRead, numCells);
1694       for (i = 0; i < numCells; i++)
1695       {
1696         scalars->InsertComponent(i, component, scalarsRead[i]);
1697       }
1698       delete [] scalarsRead;
1699       lineRead = this->ReadLine(line);
1700     }
1701 
1702     if (component == 0)
1703     {
1704       scalars->SetName(description);
1705       output->GetCellData()->AddArray(scalars);
1706       if (!output->GetCellData()->GetScalars())
1707       {
1708         output->GetCellData()->SetScalars(scalars);
1709       }
1710     }
1711     else
1712     {
1713       output->GetCellData()->AddArray(scalars);
1714     }
1715     if(allocatedScalars)
1716     {
1717       scalars->Delete();
1718     }
1719   }
1720 
1721   if (this->BinaryIFile)
1722   {
1723     this->BinaryIFile->close();
1724     delete this->BinaryIFile;
1725     this->BinaryIFile = nullptr;
1726   }
1727   return 1;
1728 }
1729 
1730 //----------------------------------------------------------------------------
ReadVectorsPerElement(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput)1731 int vtkEnSight6BinaryReader::ReadVectorsPerElement(
1732   const char* fileName, const char* description, int timeStep,
1733   vtkMultiBlockDataSet *compositeOutput)
1734 {
1735   char line[80];
1736   int partId, realId, numCells, numCellsPerElement, i, idx;
1737   vtkFloatArray *vectors;
1738   int elementType;
1739   float vector[3];
1740   float *vectorsRead;
1741   int lineRead;
1742   vtkDataSet *output;
1743 
1744   // Initialize
1745   //
1746   if (!fileName)
1747   {
1748     vtkErrorMacro("nullptr VectorPerElement variable file name");
1749     return 0;
1750   }
1751   std::string sfilename;
1752   if (this->FilePath)
1753   {
1754     sfilename = this->FilePath;
1755     if (sfilename.at(sfilename.length()-1) != '/')
1756     {
1757       sfilename += "/";
1758     }
1759     sfilename += fileName;
1760     vtkDebugMacro("full path to vector per element file: "
1761                   << sfilename.c_str());
1762   }
1763   else
1764   {
1765     sfilename = fileName;
1766   }
1767 
1768   if (this->OpenFile(sfilename.c_str()) == 0)
1769   {
1770     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
1771     return 0;
1772   }
1773 
1774   if (this->UseFileSets)
1775   {
1776     for (i = 0; i < timeStep - 1; i++)
1777     {
1778       this->ReadLine(line);
1779       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1780       {
1781         this->ReadLine(line);
1782       }
1783       this->ReadLine(line); // skip the description line
1784       lineRead = this->ReadLine(line);
1785 
1786       while (lineRead && strncmp(line, "part", 4) == 0)
1787       {
1788         sscanf(line, " part %d", &partId);
1789         partId--; // EnSight starts #ing with 1.
1790         realId = this->InsertNewPartId(partId);
1791         numCells = this->GetDataSetFromBlock(
1792           compositeOutput, realId)->GetNumberOfCells();
1793         lineRead = this->ReadLine(line); // element type or "block"
1794 
1795         // need to find out from CellIds how many cells we have of this element
1796         // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
1797         if (strcmp(line, "block") != 0)
1798         {
1799           while (lineRead && strncmp(line, "part", 4) != 0 &&
1800                   strncmp(line, "END TIME STEP", 13) != 0)
1801           {
1802             elementType = this->GetElementType(line);
1803             if (elementType < 0)
1804             {
1805               vtkErrorMacro("invalid element type");
1806               delete this->IS;
1807               this->IS = nullptr;
1808               return 0;
1809             }
1810             idx = this->UnstructuredPartIds->IsId(realId);
1811             numCellsPerElement =
1812               this->GetCellIds(idx, elementType)->GetNumberOfIds();
1813             vectorsRead = new float[numCellsPerElement*3];
1814             this->ReadFloatArray(vectorsRead, numCellsPerElement*3);
1815 
1816             delete [] vectorsRead;
1817             lineRead = this->ReadLine(line);
1818           } // end while
1819         }
1820         else
1821         {
1822           vectorsRead = new float[numCells*3];
1823           this->ReadFloatArray(vectorsRead, numCells*3);
1824 
1825           delete [] vectorsRead;
1826           lineRead = this->ReadLine(line);
1827         }
1828       }
1829     }
1830     this->ReadLine(line);
1831     while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1832     {
1833       this->ReadLine(line);
1834     }
1835   }
1836 
1837   this->ReadLine(line); // skip the description line
1838   lineRead = this->ReadLine(line);
1839 
1840   while (lineRead && strncmp(line, "part", 4) == 0)
1841   {
1842     vectors = vtkFloatArray::New();
1843     sscanf(line, " part %d", &partId);
1844     partId--; // EnSight starts #ing with 1.
1845     realId = this->InsertNewPartId(partId);
1846     output = this->GetDataSetFromBlock(compositeOutput, realId);
1847     numCells = output->GetNumberOfCells();
1848     lineRead = this->ReadLine(line); // element type or "block"
1849     vectors->SetNumberOfTuples(numCells);
1850     vectors->SetNumberOfComponents(3);
1851     vectors->Allocate(numCells*3);
1852 
1853     // need to find out from CellIds how many cells we have of this element
1854     // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
1855     if (strcmp(line, "block") != 0)
1856     {
1857       while (lineRead && strncmp(line, "part", 4) != 0 &&
1858         strncmp(line, "END TIME STEP", 13) != 0)
1859       {
1860         elementType = this->GetElementType(line);
1861         if (elementType < 0)
1862         {
1863           vtkErrorMacro("invalid element type");
1864           delete this->IS;
1865           this->IS = nullptr;
1866           return 0;
1867         }
1868         idx = this->UnstructuredPartIds->IsId(realId);
1869         numCellsPerElement = this->GetCellIds(idx, elementType)->GetNumberOfIds();
1870         vectorsRead = new float[numCellsPerElement*3];
1871         this->ReadFloatArray(vectorsRead, numCellsPerElement*3);
1872 
1873         for (i = 0; i < numCellsPerElement; i++)
1874         {
1875           vector[0] = vectorsRead[3*i];
1876           vector[1] = vectorsRead[3*i+1];
1877           vector[2] = vectorsRead[3*i+2];
1878           vectors->InsertTuple(this->GetCellIds(idx, elementType)->GetId(i),
1879                                vector);
1880         }
1881         delete [] vectorsRead;
1882         lineRead = this->ReadLine(line);
1883       } // end while
1884     }
1885     else
1886     {
1887       vectorsRead = new float[numCells*3];
1888       this->ReadFloatArray(vectorsRead, numCells*3);
1889       for (i = 0; i < numCells; i++)
1890       {
1891         vector[0] = vectorsRead[3*i];
1892         vector[1] = vectorsRead[3*i+1];
1893         vector[2] = vectorsRead[3*i+2];
1894         vectors->InsertTuple(i, vector);
1895       }
1896       delete [] vectorsRead;
1897       lineRead = this->ReadLine(line);
1898     }
1899     vectors->SetName(description);
1900     output->GetCellData()->AddArray(vectors);
1901     if (!output->GetCellData()->GetVectors())
1902     {
1903       output->GetCellData()->SetVectors(vectors);
1904     }
1905     vectors->Delete();
1906   }
1907 
1908   if (this->BinaryIFile)
1909   {
1910     this->BinaryIFile->close();
1911     delete this->BinaryIFile;
1912     this->BinaryIFile = nullptr;
1913   }
1914   return 1;
1915 }
1916 
1917 //----------------------------------------------------------------------------
ReadTensorsPerElement(const char * fileName,const char * description,int timeStep,vtkMultiBlockDataSet * compositeOutput)1918 int vtkEnSight6BinaryReader::ReadTensorsPerElement(
1919   const char* fileName, const char* description, int timeStep,
1920   vtkMultiBlockDataSet *compositeOutput)
1921 {
1922   char line[80];
1923   int partId, realId, numCells, numCellsPerElement, i, idx;
1924   vtkFloatArray *tensors;
1925   int elementType;
1926   float tensor[6];
1927   float *tensorsRead;
1928   int lineRead;
1929   vtkDataSet *output;
1930 
1931   // Initialize
1932   //
1933   if (!fileName)
1934   {
1935     vtkErrorMacro("nullptr TensorPerElement variable file name");
1936     return 0;
1937   }
1938   std::string sfilename;
1939   if (this->FilePath)
1940   {
1941     sfilename = this->FilePath;
1942     if (sfilename.at(sfilename.length()-1) != '/')
1943     {
1944       sfilename += "/";
1945     }
1946     sfilename += fileName;
1947     vtkDebugMacro("full path to tensor per element file: "
1948                   << sfilename.c_str());
1949   }
1950   else
1951   {
1952     sfilename = fileName;
1953   }
1954 
1955   if (this->OpenFile(sfilename.c_str()) == 0)
1956   {
1957     vtkErrorMacro("Unable to open file: " << sfilename.c_str());
1958     return 0;
1959   }
1960 
1961   if (this->UseTimeSets)
1962   {
1963     for (i = 0; i < timeStep - 1; i++)
1964     {
1965       this->ReadLine(line);
1966       while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
1967       {
1968         this->ReadLine(line);
1969       }
1970       this->ReadLine(line); // skip the description line
1971       lineRead = this->ReadLine(line);
1972 
1973       while (lineRead && strncmp(line, "part", 4) == 0)
1974       {
1975         sscanf(line, " part %d", &partId);
1976         partId--; // EnSight starts #ing with 1.
1977         realId = this->InsertNewPartId(partId);
1978         numCells = this->GetDataSetFromBlock(
1979           compositeOutput, realId)->GetNumberOfCells();
1980         lineRead = this->ReadLine(line); // element type or "block"
1981 
1982         // need to find out from CellIds how many cells we have of this element
1983         // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
1984         if (strcmp(line, "block") != 0)
1985         {
1986           while (lineRead && strncmp(line, "part", 4) != 0 &&
1987                  strncmp(line, "END TIME STEP", 13) != 0)
1988           {
1989             elementType = this->GetElementType(line);
1990             if (elementType < 0)
1991             {
1992               vtkErrorMacro("invalid element type");
1993               this->BinaryIFile->close();
1994               delete this->BinaryIFile;
1995               this->BinaryIFile = nullptr;
1996               return 0;
1997             }
1998             idx = this->UnstructuredPartIds->IsId(realId);
1999             numCellsPerElement = this->GetCellIds(idx, elementType)->
2000               GetNumberOfIds();
2001             tensorsRead = new float[numCellsPerElement*6];
2002             this->ReadFloatArray(tensorsRead, numCellsPerElement*6);
2003 
2004             delete [] tensorsRead;
2005             lineRead = this->ReadLine(line);
2006           } // end while
2007         }
2008         else
2009         {
2010           tensorsRead = new float[numCells*6];
2011           this->ReadFloatArray(tensorsRead, numCells*6);
2012 
2013           delete [] tensorsRead;
2014           lineRead = this->ReadLine(line);
2015         }
2016       }
2017     }
2018     this->ReadLine(line);
2019     while (strncmp(line, "BEGIN TIME STEP", 15) != 0)
2020     {
2021       this->ReadLine(line);
2022     }
2023   }
2024 
2025   this->ReadLine(line); // skip the description line
2026   lineRead = this->ReadLine(line);
2027 
2028   while (lineRead && strncmp(line, "part", 4) == 0)
2029   {
2030     tensors = vtkFloatArray::New();
2031     sscanf(line, " part %d", &partId);
2032     partId--; // EnSight starts #ing with 1.
2033     realId = this->InsertNewPartId(partId);
2034     output = this->GetDataSetFromBlock(compositeOutput, realId);
2035     numCells = output->GetNumberOfCells();
2036     lineRead = this->ReadLine(line); // element type or "block"
2037     tensors->SetNumberOfTuples(numCells);
2038     tensors->SetNumberOfComponents(6);
2039     tensors->Allocate(numCells*6);
2040 
2041     // need to find out from CellIds how many cells we have of this element
2042     // type (and what their ids are) -- IF THIS IS NOT A BLOCK SECTION
2043     if (strcmp(line, "block") != 0)
2044     {
2045       while (lineRead && strncmp(line, "part", 4) != 0 &&
2046              strncmp(line, "END TIME STEP", 13) != 0)
2047       {
2048         elementType = this->GetElementType(line);
2049         if (elementType < 0)
2050         {
2051           vtkErrorMacro("invalid element type");
2052           this->BinaryIFile->close();
2053           delete this->BinaryIFile;
2054           this->BinaryIFile = nullptr;
2055           return 0;
2056         }
2057         idx = this->UnstructuredPartIds->IsId(realId);
2058         numCellsPerElement = this->GetCellIds(idx, elementType)->GetNumberOfIds();
2059         tensorsRead = new float[numCellsPerElement*6];
2060         this->ReadFloatArray(tensorsRead, numCellsPerElement*6);
2061 
2062         for (i = 0; i < numCellsPerElement; i++)
2063         {
2064           tensor[0] = tensorsRead[6*i];
2065           tensor[1] = tensorsRead[6*i+1];
2066           tensor[2] = tensorsRead[6*i+2];
2067           tensor[3] = tensorsRead[6*i+3];
2068           tensor[4] = tensorsRead[6*i+5];
2069           tensor[5] = tensorsRead[6*i+4];
2070 
2071           tensors->InsertTuple(this->GetCellIds(idx, elementType)->GetId(i),
2072                                tensor);
2073         }
2074         delete [] tensorsRead;
2075         lineRead = this->ReadLine(line);
2076       } // end while
2077     }
2078     else
2079     {
2080       tensorsRead = new float[numCells*6];
2081       this->ReadFloatArray(tensorsRead, numCells*6);
2082 
2083       for (i = 0; i < numCells; i++)
2084       {
2085         tensor[0] = tensorsRead[6*i];
2086         tensor[1] = tensorsRead[6*i+1];
2087         tensor[2] = tensorsRead[6*i+2];
2088         tensor[3] = tensorsRead[6*i+3];
2089         tensor[4] = tensorsRead[6*i+5];
2090         tensor[5] = tensorsRead[6*i+4];
2091         tensors->InsertTuple(i, tensor);
2092       }
2093       delete [] tensorsRead;
2094       lineRead = this->ReadLine(line);
2095     }
2096     tensors->SetName(description);
2097     output->GetCellData()->AddArray(tensors);
2098     tensors->Delete();
2099   }
2100 
2101   if (this->BinaryIFile)
2102   {
2103     this->BinaryIFile->close();
2104     delete this->BinaryIFile;
2105     this->BinaryIFile = nullptr;
2106   }
2107   return 1;
2108 }
2109 
2110 //----------------------------------------------------------------------------
CreateUnstructuredGridOutput(int partId,char line[80],const char * name,vtkMultiBlockDataSet * compositeOutput)2111 int vtkEnSight6BinaryReader::CreateUnstructuredGridOutput(
2112   int partId, char line[80], const char* name,
2113   vtkMultiBlockDataSet *compositeOutput)
2114 {
2115   int lineRead = 1;
2116   int i, j;
2117   int *nodeIdList;
2118   vtkIdType *nodeIds;
2119   int numElements;
2120   int idx, cellType;
2121   vtkIdType cellId;
2122 
2123   this->NumberOfNewOutputs++;
2124 
2125   if (this->GetDataSetFromBlock(compositeOutput, partId) == nullptr ||
2126     !this->GetDataSetFromBlock(compositeOutput, partId)->IsA("vtkUnstructuredGrid"))
2127   {
2128     vtkDebugMacro("creating new unstructured output");
2129     vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::New();
2130     this->AddToBlock(compositeOutput, partId, ugrid);
2131     ugrid->Delete();
2132 
2133     this->UnstructuredPartIds->InsertNextId(partId);
2134   }
2135 
2136   vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(
2137     this->GetDataSetFromBlock(compositeOutput, partId));
2138   this->SetBlockName(compositeOutput, partId, name);
2139 
2140   // Clear all cell ids from the last execution, if any.
2141   idx = this->UnstructuredPartIds->IsId(partId);
2142   for (i = 0; i < vtkEnSightReader::NUMBER_OF_ELEMENT_TYPES; i++)
2143   {
2144     this->GetCellIds(idx, i)->Reset();
2145   }
2146 
2147   output->Allocate(1000);
2148 
2149   while(lineRead && strncmp(line, "part", 4) != 0)
2150   {
2151     if (strncmp(line, "point", 5) == 0)
2152     {
2153       vtkDebugMacro("point");
2154 
2155       this->ReadIntNumber(&numElements);
2156       if (numElements < 0 ||
2157         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2158       {
2159         vtkErrorMacro("Invalid number of point cells; check that ByteOrder is set correctly.");
2160         return 0;
2161       }
2162       nodeIds = new vtkIdType[1];
2163       if (this->ElementIdsListed)
2164       {
2165         // skip element ids
2166         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2167       }
2168 
2169       nodeIdList = new int[numElements];
2170       this->ReadIntArray(nodeIdList, numElements);
2171 
2172       for (i = 0; i < numElements; i++)
2173       {
2174         nodeIds[0] = nodeIdList[i] - 1;
2175         if (this->UnstructuredNodeIds)
2176         {
2177           nodeIds[0] = this->UnstructuredNodeIds->GetValue(nodeIds[0]);
2178         }
2179         cellId = output->InsertNextCell(VTK_VERTEX, 1, nodeIds);
2180         this->GetCellIds(idx, vtkEnSightReader::POINT)->InsertNextId(cellId);
2181       }
2182       delete [] nodeIds;
2183       delete [] nodeIdList;
2184     }
2185     else if (strncmp(line, "bar2", 4) == 0)
2186     {
2187       vtkDebugMacro("bar2");
2188 
2189       this->ReadIntNumber(&numElements);
2190       if (numElements < 0 ||
2191         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2192       {
2193         vtkErrorMacro("Invalid number of bar2 cells; check that ByteOrder is set correctly.");
2194         return 0;
2195       }
2196       nodeIds = new vtkIdType[2];
2197       if (this->ElementIdsListed)
2198       {
2199         // skip element ids
2200         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2201       }
2202 
2203       nodeIdList = new int[numElements * 2];
2204       this->ReadIntArray(nodeIdList, numElements*2);
2205 
2206       for (i = 0; i < numElements; i++)
2207       {
2208         for (j = 0; j < 2; j++)
2209         {
2210           nodeIds[j] = nodeIdList[2*i+j] - 1;
2211         }
2212 
2213         if (this->UnstructuredNodeIds)
2214         {
2215           for (j = 0; j < 2; j++)
2216           {
2217             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2218           }
2219         }
2220         cellId = output->InsertNextCell(VTK_LINE, 2, nodeIds);
2221         this->GetCellIds(idx, vtkEnSightReader::BAR2)->InsertNextId(cellId);
2222       }
2223       delete [] nodeIds;
2224       delete [] nodeIdList;
2225     }
2226     else if (strncmp(line, "bar3", 4) == 0)
2227     {
2228       vtkDebugMacro("bar3");
2229       vtkWarningMacro("Only vertex nodes of this element will be read.");
2230 
2231       this->ReadIntNumber(&numElements);
2232       if (numElements < 0 ||
2233         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2234       {
2235         vtkErrorMacro("Invalid number of bar3 cells; check that ByteOrder is set correctly.");
2236         return 0;
2237       }
2238       nodeIds = new vtkIdType[2];
2239       if (this->ElementIdsListed)
2240       {
2241         // skip element ids
2242         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2243       }
2244 
2245       nodeIdList = new int[numElements * 3];
2246       this->ReadIntArray(nodeIdList, numElements*3);
2247 
2248       for (i = 0; i < numElements; i++)
2249       {
2250         for (j = 0; j < 2; j++)
2251         {
2252           nodeIds[j] = nodeIdList[3*i+2*j] - 1;
2253         }
2254 
2255         if (this->UnstructuredNodeIds)
2256         {
2257           for (j = 0; j < 2; j++)
2258           {
2259             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2260           }
2261         }
2262         cellId = output->InsertNextCell(VTK_LINE, 2, nodeIds);
2263         this->GetCellIds(idx, vtkEnSightReader::BAR3)->InsertNextId(cellId);
2264       }
2265       delete [] nodeIds;
2266       delete [] nodeIdList;
2267     }
2268     else if (strncmp(line, "tria3", 5) == 0 ||
2269              strncmp(line, "tria6", 5) == 0)
2270     {
2271       if (strncmp(line, "tria3", 5) == 0)
2272       {
2273         vtkDebugMacro("tria3");
2274         cellType = vtkEnSightReader::TRIA3;
2275       }
2276       else
2277       {
2278         vtkDebugMacro("tria6");
2279         vtkWarningMacro("Only vertex nodes of this element will be read.");
2280         cellType = vtkEnSightReader::TRIA6;
2281       }
2282 
2283       this->ReadIntNumber(&numElements);
2284       if (numElements < 0 ||
2285         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2286       {
2287         vtkErrorMacro("Invalid number of triangle cells; check that ByteOrder is set correctly.");
2288         return 0;
2289       }
2290       nodeIds = new vtkIdType[3];
2291       if (this->ElementIdsListed)
2292       {
2293         // skip element ids
2294         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2295       }
2296 
2297       if (cellType == vtkEnSightReader::TRIA3)
2298       {
2299         nodeIdList = new int[numElements * 3];
2300         this->ReadIntArray(nodeIdList, numElements*3);
2301       }
2302       else
2303       {
2304         nodeIdList = new int[numElements * 6];
2305         this->ReadIntArray(nodeIdList, numElements*6);
2306       }
2307 
2308       for (i = 0; i < numElements; i++)
2309       {
2310         if (cellType == vtkEnSightReader::TRIA3)
2311         {
2312           for (j = 0; j < 3; j++)
2313           {
2314             nodeIds[j] = nodeIdList[3*i+j] - 1;
2315           }
2316         }
2317         else
2318         {
2319           for (j = 0; j < 3; j++)
2320           {
2321             nodeIds[j] = nodeIdList[6*i+j] - 1;
2322           }
2323         }
2324         if (this->UnstructuredNodeIds)
2325         {
2326           for (j = 0; j < 3; j++)
2327           {
2328             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2329           }
2330         }
2331         cellId = output->InsertNextCell(VTK_TRIANGLE, 3, nodeIds);
2332         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2333       }
2334       delete [] nodeIds;
2335       delete [] nodeIdList;
2336     }
2337     else if (strncmp(line, "quad4", 5) == 0 ||
2338              strncmp(line, "quad8", 5) == 0)
2339     {
2340       if (strncmp(line, "quad8", 5) == 0)
2341       {
2342         vtkDebugMacro("quad8");
2343         vtkWarningMacro("Only vertex nodes of this element will be read.");
2344         cellType = vtkEnSightReader::QUAD8;
2345       }
2346       else
2347       {
2348         vtkDebugMacro("quad4");
2349         cellType = vtkEnSightReader::QUAD4;
2350       }
2351 
2352       this->ReadIntNumber(&numElements);
2353       if (numElements < 0 ||
2354         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2355       {
2356         vtkErrorMacro("Invalid number of quad cells; check that ByteOrder is set correctly.");
2357         return 0;
2358       }
2359       nodeIds = new vtkIdType[4];
2360       if (this->ElementIdsListed)
2361       {
2362         // skip element ids
2363         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2364       }
2365 
2366       if (cellType == vtkEnSightReader::QUAD4)
2367       {
2368         nodeIdList = new int[numElements * 4];
2369         this->ReadIntArray(nodeIdList, numElements*4);
2370       }
2371       else
2372       {
2373         nodeIdList = new int[numElements * 8];
2374         this->ReadIntArray(nodeIdList, numElements*8);
2375       }
2376 
2377       for (i = 0; i < numElements; i++)
2378       {
2379         if (cellType == vtkEnSightReader::QUAD4)
2380         {
2381           for (j = 0; j < 4; j++)
2382           {
2383             nodeIds[j] = nodeIdList[4*i+j] - 1;
2384           }
2385         }
2386         else
2387         {
2388           for (j = 0; j < 4; j++)
2389           {
2390             nodeIds[j] = nodeIdList[8*i+j] - 1;
2391           }
2392         }
2393         if (this->UnstructuredNodeIds)
2394         {
2395           for (j = 0; j < 4; j++)
2396           {
2397             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2398           }
2399         }
2400         cellId = output->InsertNextCell(VTK_QUAD, 4, nodeIds);
2401         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2402       }
2403       delete [] nodeIds;
2404       delete [] nodeIdList;
2405     }
2406     else if (strncmp(line, "tetra4", 6) == 0 ||
2407              strncmp(line, "tetra10", 7) == 0)
2408     {
2409       if (strncmp(line, "tetra10", 7) == 0)
2410       {
2411         vtkDebugMacro("tetra10");
2412         vtkWarningMacro("Only vertex nodes of this element will be read.");
2413         cellType = vtkEnSightReader::TETRA10;
2414       }
2415       else
2416       {
2417         vtkDebugMacro("tetra4");
2418         cellType = vtkEnSightReader::TETRA4;
2419       }
2420 
2421       this->ReadIntNumber(&numElements);
2422       if (numElements < 0 ||
2423         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2424       {
2425         vtkErrorMacro("Invalid number of tetrahedral cells; check that ByteOrder is set correctly.");
2426         return 0;
2427       }
2428       nodeIds = new vtkIdType[4];
2429       if (this->ElementIdsListed)
2430       {
2431         // skip element ids
2432         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2433       }
2434 
2435       if (cellType == vtkEnSightReader::TETRA4)
2436       {
2437         nodeIdList = new int[numElements * 4];
2438         this->ReadIntArray(nodeIdList, numElements*4);
2439       }
2440       else
2441       {
2442         nodeIdList = new int[numElements * 10];
2443         this->ReadIntArray(nodeIdList, numElements*10);
2444       }
2445 
2446       for (i = 0; i < numElements; i++)
2447       {
2448         if (cellType == vtkEnSightReader::TETRA4)
2449         {
2450           for (j = 0; j < 4; j++)
2451           {
2452             nodeIds[j] = nodeIdList[4*i+j] - 1;
2453           }
2454         }
2455         else
2456         {
2457           for (j = 0; j < 4; j++)
2458           {
2459             nodeIds[j] = nodeIdList[10*i+j] - 1;
2460           }
2461         }
2462         if (this->UnstructuredNodeIds)
2463         {
2464           for (j = 0; j < 3; j++)
2465           {
2466             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2467           }
2468         }
2469         cellId = output->InsertNextCell(VTK_TETRA, 4, nodeIds);
2470         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2471       }
2472       delete [] nodeIds;
2473       delete [] nodeIdList;
2474     }
2475     else if (strncmp(line, "pyramid5", 8) == 0 ||
2476              strncmp(line, "pyramid13", 9) == 0)
2477     {
2478       if (strncmp(line, "pyramid13", 9) == 0)
2479       {
2480         vtkDebugMacro("pyramid13");
2481         vtkWarningMacro("Only vertex nodes of this element will be read.");
2482         cellType = vtkEnSightReader::PYRAMID13;
2483       }
2484       else
2485       {
2486         vtkDebugMacro("pyramid5");
2487         cellType = vtkEnSightReader::PYRAMID5;
2488       }
2489 
2490       this->ReadIntNumber(&numElements);
2491       if (numElements < 0 ||
2492         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2493       {
2494         vtkErrorMacro("Invalid number of pyramid cells; check that ByteOrder is set correctly.");
2495         return 0;
2496       }
2497       nodeIds = new vtkIdType[5];
2498       if (this->ElementIdsListed)
2499       {
2500         // skip element ids
2501         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2502       }
2503 
2504       if (cellType == vtkEnSightReader::PYRAMID5)
2505       {
2506         nodeIdList = new int[numElements * 5];
2507         this->ReadIntArray(nodeIdList, numElements*5);
2508       }
2509       else
2510       {
2511         nodeIdList = new int[numElements * 13];
2512         this->ReadIntArray(nodeIdList, numElements*13);
2513       }
2514 
2515       for (i = 0; i < numElements; i++)
2516       {
2517         if (cellType == vtkEnSightReader::PYRAMID5)
2518         {
2519           for (j = 0; j < 5; j++)
2520           {
2521             nodeIds[j] = nodeIdList[5*i+j] - 1;
2522           }
2523         }
2524         else
2525         {
2526           for (j = 0; j < 5; j++)
2527           {
2528             nodeIds[j] = nodeIdList[13*i+j] - 1;
2529           }
2530         }
2531         if (this->UnstructuredNodeIds)
2532         {
2533           for (j = 0; j < 5; j++)
2534           {
2535             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2536           }
2537         }
2538         cellId = output->InsertNextCell(VTK_PYRAMID, 5, nodeIds);
2539         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2540       }
2541       delete [] nodeIds;
2542       delete [] nodeIdList;
2543     }
2544     else if (strncmp(line, "hexa8", 5) == 0 ||
2545              strncmp(line, "hexa20", 6) == 0)
2546     {
2547       if (strncmp(line, "hexa20", 6) == 0)
2548       {
2549         vtkDebugMacro("hexa20");
2550         vtkWarningMacro("Only vertex nodes of this element will be read.");
2551         cellType = vtkEnSightReader::HEXA20;
2552       }
2553       else
2554       {
2555         vtkDebugMacro("hexa8");
2556         cellType = vtkEnSightReader::HEXA8;
2557       }
2558 
2559       this->ReadIntNumber(&numElements);
2560       if (numElements < 0 ||
2561         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2562       {
2563         vtkErrorMacro("Invalid number of hexahedral cells; check that ByteOrder is set correctly.");
2564         return 0;
2565       }
2566       nodeIds = new vtkIdType[8];
2567       if (this->ElementIdsListed)
2568       {
2569         // skip element ids
2570         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2571       }
2572 
2573       if (cellType == vtkEnSightReader::HEXA8)
2574       {
2575         nodeIdList = new int[numElements * 8];
2576         this->ReadIntArray(nodeIdList, numElements*8);
2577       }
2578       else
2579       {
2580         nodeIdList = new int[numElements * 20];
2581         this->ReadIntArray(nodeIdList, numElements*20);
2582       }
2583 
2584       for (i = 0; i < numElements; i++)
2585       {
2586         if (cellType == vtkEnSightReader::HEXA8)
2587         {
2588           for (j = 0; j < 8; j++)
2589           {
2590             nodeIds[j] = nodeIdList[8*i+j] - 1;
2591           }
2592         }
2593         else
2594         {
2595           for (j = 0; j < 8; j++)
2596           {
2597             nodeIds[j] = nodeIdList[20*i+j] - 1;
2598           }
2599         }
2600         if (this->UnstructuredNodeIds)
2601         {
2602           for (j = 0; j < 8; j++)
2603           {
2604             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2605           }
2606         }
2607         cellId = output->InsertNextCell(VTK_HEXAHEDRON, 8, nodeIds);
2608         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2609       }
2610       delete [] nodeIds;
2611       delete [] nodeIdList;
2612     }
2613     else if (strncmp(line, "penta6", 6) == 0 ||
2614              strncmp(line, "penta15", 7) == 0)
2615     {
2616       if (strncmp(line, "penta15", 7) == 0)
2617       {
2618         vtkDebugMacro("penta15");
2619         vtkWarningMacro("Only vertex nodes of this element will be read.");
2620         cellType = vtkEnSightReader::PENTA15;
2621       }
2622       else
2623       {
2624         vtkDebugMacro("penta6");
2625         cellType = vtkEnSightReader::PENTA6;
2626       }
2627 
2628       this->ReadIntNumber(&numElements);
2629       if (numElements < 0 ||
2630         static_cast<unsigned int>(numElements * sizeof(int)) > this->FileSize)
2631       {
2632         vtkErrorMacro("Invalid number of pentagonal cells; check that ByteOrder is set correctly.");
2633         return 0;
2634       }
2635       nodeIds = new vtkIdType[6];
2636       if (this->ElementIdsListed)
2637       {
2638         // skip element ids
2639         this->BinaryIFile->seekg((sizeof(int)*numElements), ios::cur);
2640       }
2641 
2642       if (cellType == vtkEnSightReader::PENTA6)
2643       {
2644         nodeIdList = new int[numElements * 6];
2645         this->ReadIntArray(nodeIdList, numElements*6);
2646       }
2647       else
2648       {
2649         nodeIdList = new int[numElements * 15];
2650         this->ReadIntArray(nodeIdList, numElements*15);
2651       }
2652 
2653       const unsigned char wedgeMap[6] = {0, 2, 1, 3, 5, 4};
2654       for (i = 0; i < numElements; i++)
2655       {
2656         if (cellType == vtkEnSightReader::PENTA6)
2657         {
2658           for (j = 0; j < 6; j++)
2659           {
2660             nodeIds[wedgeMap[j]] = nodeIdList[6*i+j] - 1;
2661           }
2662         }
2663         else
2664         {
2665           for (j = 0; j < 6; j++)
2666           {
2667             nodeIds[wedgeMap[j]] = nodeIdList[15*i+j] - 1;
2668           }
2669         }
2670         if (this->UnstructuredNodeIds)
2671         {
2672           for (j = 0; j < 6; j++)
2673           {
2674             nodeIds[j] = this->UnstructuredNodeIds->GetValue(nodeIds[j]);
2675           }
2676         }
2677         cellId = output->InsertNextCell(VTK_WEDGE, 6, nodeIds);
2678         this->GetCellIds(idx, cellType)->InsertNextId(cellId);
2679       }
2680       delete [] nodeIds;
2681       delete [] nodeIdList;
2682     }
2683     lineRead = this->ReadLine(line);
2684   }
2685 
2686   ((vtkUnstructuredGrid*)this->GetDataSetFromBlock(compositeOutput, partId))->
2687     SetPoints(this->UnstructuredPoints);
2688   return lineRead;
2689 }
2690 
2691 //----------------------------------------------------------------------------
CreateStructuredGridOutput(int partId,char line[80],const char * name,vtkMultiBlockDataSet * compositeOutput)2692 int vtkEnSight6BinaryReader::CreateStructuredGridOutput(
2693   int partId, char line[80], const char* name,
2694   vtkMultiBlockDataSet *compositeOutput)
2695 {
2696   char subLine[80];
2697   int lineRead;
2698   int iblanked = 0;
2699   int dimensions[3];
2700   int i;
2701   vtkPoints *points = vtkPoints::New();
2702   int numPts;
2703   float *coordsRead;
2704   int *iblanks;
2705 
2706   this->NumberOfNewOutputs++;
2707 
2708   if (this->GetDataSetFromBlock(compositeOutput, partId) == nullptr ||
2709     !this->GetDataSetFromBlock(compositeOutput, partId)->IsA("vtkStructuredGrid"))
2710   {
2711     vtkDebugMacro("creating new structured grid output");
2712     vtkStructuredGrid* sgrid = vtkStructuredGrid::New();
2713     this->AddToBlock(compositeOutput, partId, sgrid);
2714     sgrid->Delete();
2715   }
2716 
2717   vtkStructuredGrid* output = vtkStructuredGrid::SafeDownCast(
2718     this->GetDataSetFromBlock(compositeOutput, partId));
2719   this->SetBlockName(compositeOutput, partId, name);
2720 
2721   if (sscanf(line, " %*s %s", subLine) == 1)
2722   {
2723     if (strcmp(subLine, "iblanked") == 0)
2724     {
2725       iblanked = 1;
2726     }
2727   }
2728   // Read these separately to get the byte order correct.
2729   this->ReadIntNumber(dimensions);
2730   this->ReadIntNumber(dimensions+1);
2731   this->ReadIntNumber(dimensions+2);
2732   numPts = dimensions[0] * dimensions[1] * dimensions[2];
2733   if (dimensions[0] < 0 ||
2734     static_cast<unsigned int>(dimensions[0] * sizeof(int)) > this->FileSize ||
2735     dimensions[1] < 0 ||
2736     static_cast<unsigned int>(dimensions[1] * sizeof(int)) > this->FileSize ||
2737     dimensions[2] < 0 ||
2738     static_cast<unsigned int>(dimensions[2] * sizeof(int)) > this->FileSize ||
2739     numPts < 0 ||
2740     static_cast<unsigned int>(numPts * sizeof(int)) > this->FileSize)
2741   {
2742     vtkErrorMacro("Invalid dimensions; check that ByteOrder is set correctly.");
2743     points->Delete();
2744     return -1;
2745   }
2746   output->SetDimensions(dimensions);
2747   points->Allocate(numPts);
2748 
2749   coordsRead = new float[numPts*3];
2750   this->ReadFloatArray(coordsRead, numPts*3);
2751 
2752   for (i = 0; i < numPts; i++)
2753   {
2754     points->InsertNextPoint(coordsRead[i], coordsRead[numPts+i],
2755                             coordsRead[2*numPts+i]);
2756   }
2757 
2758   delete [] coordsRead;
2759 
2760   output->SetPoints(points);
2761   if (iblanked)
2762   {
2763     iblanks = new int[numPts];
2764     this->ReadIntArray(iblanks, numPts);
2765     for (i = 0; i < numPts; i++)
2766     {
2767       if (!iblanks[i])
2768       {
2769         output->BlankPoint(i);
2770       }
2771     }
2772     delete [] iblanks;
2773   }
2774 
2775   points->Delete();
2776   // reading next line to check for EOF
2777   lineRead = this->ReadLine(line);
2778   return lineRead;
2779 }
2780 
2781 // Internal function to read in a line up to 80 characters.
2782 // Returns zero if there was an error.
ReadLine(char result[80])2783 int vtkEnSight6BinaryReader::ReadLine(char result[80])
2784 {
2785   if ( ! this->BinaryIFile->read(result, sizeof(char)*80))
2786   {
2787     return 0;
2788   }
2789 
2790   return 1;
2791 }
2792 
2793 // Internal function to read a single integer.
2794 // Returns zero if there was an error.
2795 // This method is used to read the number of points ...
2796 // It also tries to determine the byte order.
2797 // It uses the byte order that produces the largest value that
2798 // is smaller than the file.  Although this computation
2799 // assumes only one int array is in the file,
2800 // it should still work fine.
ReadIntNumber(int * result)2801 int vtkEnSight6BinaryReader::ReadIntNumber(int *result)
2802 {
2803   if ( ! this->BinaryIFile->read((char*)result, sizeof(int)))
2804   {
2805     vtkErrorMacro("Read failed");
2806     return 0;
2807   }
2808   if (this->ByteOrder == FILE_LITTLE_ENDIAN)
2809   {
2810     vtkByteSwap::Swap4LE(result);
2811     vtkDebugMacro(<<"ByteOrder == FILE_LITTLE_ENDIAN");
2812   }
2813   else if (this->ByteOrder == FILE_BIG_ENDIAN)
2814   {
2815     vtkByteSwap::Swap4BE(result);
2816     vtkDebugMacro(<<"ByteOrder == FILE_BIG_ENDIAN");
2817   }
2818   else
2819   {
2820     // Experimental byte swap.
2821     int tmpLE = *result;
2822     int tmpBE = *result;
2823     vtkByteSwap::Swap4LE(&tmpLE);
2824     vtkByteSwap::Swap4BE(&tmpBE);
2825 
2826     // Compare to file size, being careful not to overflow the
2827     // multiplication (by doing 64 bit math).
2828     // Use negative value as an indication of bad number.
2829     if (tmpLE < 0 ||
2830       static_cast<unsigned int>(tmpLE * sizeof(int)) > this->FileSize)
2831     {
2832       tmpLE = -1;
2833     }
2834     if (tmpBE < 0 ||
2835       static_cast<unsigned int>(tmpBE * sizeof(int)) > this->FileSize)
2836     {
2837       tmpBE = -1;
2838     }
2839 
2840     // Just a sanity check. (0, 0 occurs often).
2841     // This condition would only occur for some really large files.
2842     if (tmpLE > 0 && tmpBE > 0)
2843     {
2844       vtkWarningMacro("Byte order is ambiguous.");
2845     }
2846 
2847     // If they are both valid, use the larger one.
2848     if (tmpLE > 0)
2849     {
2850       if (tmpBE > tmpLE)
2851       {
2852         this->ByteOrder = FILE_BIG_ENDIAN;
2853         *result = tmpBE;
2854       }
2855       else
2856       {
2857         this->ByteOrder = FILE_LITTLE_ENDIAN;
2858         *result = tmpLE;
2859       }
2860       return 1;
2861     }
2862     if (tmpBE > 0)
2863     {
2864       this->ByteOrder = FILE_BIG_ENDIAN;
2865       *result = tmpBE;
2866       return 1;
2867     }
2868 
2869     if (tmpLE < 0 && tmpBE < 0)
2870     { // both byte swaps are bad.
2871       vtkErrorMacro("Could not find a suitable byte order.");
2872       *result = 0;
2873       return 0;
2874     }
2875   }
2876 
2877   return 1;
2878 }
2879 
2880 // Internal function to read an integer array.
2881 // Returns zero if there was an error.
ReadIntArray(int * result,int numInts)2882 int vtkEnSight6BinaryReader::ReadIntArray(int *result,
2883                                           int numInts)
2884 {
2885   if (numInts <= 0)
2886   {
2887     return 1;
2888   }
2889 
2890   if ( ! this->BinaryIFile->read((char*)result, sizeof(int)*numInts))
2891   {
2892     vtkErrorMacro("Read failed.");
2893     return 0;
2894   }
2895   if (this->ByteOrder == FILE_LITTLE_ENDIAN)
2896   {
2897     vtkByteSwap::Swap4LERange(result, numInts);
2898   }
2899   else
2900   {
2901     vtkByteSwap::Swap4BERange(result, numInts);
2902   }
2903 
2904   return 1;
2905 }
2906 
2907 // Internal function to read a float array.
2908 // Returns zero if there was an error.
ReadFloatArray(float * result,int numFloats)2909 int vtkEnSight6BinaryReader::ReadFloatArray(float *result,
2910                                             int numFloats)
2911 {
2912   if (numFloats <= 0)
2913   {
2914     return 1;
2915   }
2916 
2917   if ( ! this->BinaryIFile->read((char*)result, sizeof(float)*numFloats))
2918   {
2919     vtkErrorMacro("Read failed.");
2920     return 0;
2921   }
2922 
2923   if (this->ByteOrder == FILE_LITTLE_ENDIAN)
2924   {
2925     vtkByteSwap::Swap4LERange(result, numFloats);
2926   }
2927   else
2928   {
2929     vtkByteSwap::Swap4BERange(result, numFloats);
2930   }
2931 
2932   return 1;
2933 }
2934 
2935 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)2936 void vtkEnSight6BinaryReader::PrintSelf(ostream& os, vtkIndent indent)
2937 {
2938   this->Superclass::PrintSelf(os,indent);
2939 }
2940