VTK
vtkMultiBlockPLOT3DReaderInternals.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkMultiBlockPLOT3DReaderInternals.h
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 #ifndef vtkMultiBlockPLOT3DReaderInternals_h
16 #define vtkMultiBlockPLOT3DReaderInternals_h
17 #ifndef __VTK_WRAP__
18 
19 #include "vtkIOParallelModule.h" // For export macro
20 #include "vtkByteSwap.h"
22 #include "vtkSmartPointer.h"
23 #include "vtkStructuredGrid.h"
24 
25 #include <exception>
26 #include <vector>
27 
29 
30 #ifdef _WIN64
31 # define vtk_fseek _fseeki64
32 # define vtk_ftell _ftelli64
33 # define vtk_off_t __int64
34 #else
35 # define vtk_fseek fseek
36 # define vtk_ftell ftell
37 # define vtk_off_t long
38 #endif
39 
41 {
42  struct Dims
43  {
44 
45  Dims()
46  {
47  memset(this->Values, 0, 3*sizeof(int));
48  }
49 
50  int Values[3];
51  };
52 
53  std::vector<Dims> Dimensions;
54  std::vector<vtkSmartPointer<vtkStructuredGrid> > Blocks;
55 
57  {
59  int ByteOrder;
61  int MultiGrid;
63  int Precision; // in bytes
64  int IBlanking;
66  BinaryFile(1),
67  ByteOrder(vtkMultiBlockPLOT3DReader::FILE_BIG_ENDIAN),
68  HasByteCount(1),
69  MultiGrid(0),
70  NumberOfDimensions(3),
71  Precision(4),
72  IBlanking(0)
73  {
74  }
75  };
76 
79 
81  NeedToCheckXYZFile(true)
82  {
83  }
84 
85  int ReadInts(FILE* fp, int n, int* val);
86  void CheckBinaryFile(FILE *fp, size_t fileSize);
87  int CheckByteOrder(FILE* fp);
88  int CheckByteCount(FILE* fp);
89  int CheckMultiGrid(FILE* fp);
90  int Check2DGeom(FILE* fp);
91  int CheckBlankingAndPrecision(FILE* fp);
92  int CheckCFile(FILE* fp, size_t fileSize);
93  size_t CalculateFileSize(int mgrid,
94  int precision, // in bytes
95  int blanking,
96  int ndims,
97  int hasByteCount,
98  int nGrids,
99  int* gridDims);
100  size_t CalculateFileSizeForBlock(int precision, // in bytes
101  int blanking,
102  int ndims,
103  int hasByteCount,
104  int* gridDims);
105 
106  static void CalculateSkips(const int extent[6], const int wextent[6],
107  vtkIdType& preskip, vtkIdType& postskip)
108  {
109  vtkIdType nPtsInPlane = static_cast<vtkIdType>(wextent[1]+1)*(wextent[3]+1);
110  preskip = nPtsInPlane * extent[4];
111  postskip = nPtsInPlane * (wextent[5] - extent[5]);
112  }
113 };
114 
115 namespace
116 {
117 class Plot3DException : public std::exception
118 {
119 };
120 }
121 
122 // Description:
123 // vtkMultiBlockPLOT3DReaderRecord represents a data record in the file. For
124 // binary Plot3D files with record separators (i.e. leading and trailing length
125 // field per record see: https://software.intel.com/en-us/node/525311), if the
126 // record length is greater than 2,147,483,639 bytes, the record get split into
127 // multiple records. This class allows use to manage that.
128 // It corresponds to a complete record i.e. including all the records when split
129 // among multiple records due to length limit.
130 class VTKIOPARALLEL_EXPORT vtkMultiBlockPLOT3DReaderRecord
131 {
132  struct vtkSubRecord
133  {
134  vtkTypeUInt64 HeaderOffset;
135  vtkTypeUInt64 FooterOffset;
136  };
137 
138  typedef std::vector<vtkSubRecord> VectorOfSubRecords;
139  VectorOfSubRecords SubRecords;
140 
141 public:
142  // Description:
143  // A type for collection of sub-record separators i.e. separators encountered
144  // within a record when the record length is greater than 2,147,483,639 bytes.
145  typedef std::vector<vtkTypeUInt64> SubRecordSeparators;
146 
147  // Description:
148  // Since a sub-record separator is made up of the trailing length field of a
149  // sub-record and the leading length field of the next sub-record, it's length
150  // is two ints.
151  static const int SubRecordSeparatorWidth = sizeof(int) * 2;
152 
153  // Description:
154  // Initialize metadata about the record located at the given offset.
155  // This reads the file on the root node to populate record information,
156  // seeking and marching forward through the file if the record comprises of
157  // multiple sub-records. The file is reset back to the original starting
158  // position when done.
159  //
160  // This method has no effect for non-binary files or files that don't have
161  // record separators i.e. HasByteCount == 0.
162  bool Initialize(FILE* fp, vtkTypeUInt64 offset,
164  vtkMultiProcessController* controller);
165 
166  // Description:
167  // Returns true if:
168  // 1. file doesn't comprise of records i.e. ASCII or doesn't have byte-count markers.
169  // 2. offset is same as the start offset for this record.
170  bool AtStart(vtkTypeUInt64 offset)
171  {
172  return (this->SubRecords.size()==0 || this->SubRecords.front().HeaderOffset == offset);
173  }
174 
175  // Description:
176  // Returns true if:
177  // 1. file doesn't comprise of records i.e. ASCII or doesn't have byte-count markers.
178  // 2. offset is at the end of this record i.e. the start of the next record.
179  bool AtEnd(vtkTypeUInt64 offset)
180  {
181  return (this->SubRecords.size()==0 ||
182  (this->SubRecords.back().FooterOffset + sizeof(int) == offset));
183  }
184 
185  // Description:
186  // Returns the location of SubRecordSeparators (bad two 4-byte ints) between startOffset and
187  // (startOffset + length).
188  SubRecordSeparators GetSubRecordSeparators(vtkTypeUInt64 startOffset, vtkTypeUInt64 length) const;
189 
190  // Description:
191  // When reading between file offsets \c start and \c (start + length) from the file, if it has any
192  // sub-record separators, this method splits the read into chunks so that it
193  // skips the sub-record separators. The returned value is a vector of pairs
194  // (offset, length-in-bytes).
195  static std::vector<std::pair<vtkTypeUInt64, vtkTypeUInt64> > GetChunksToRead(
196  vtkTypeUInt64 start, vtkTypeUInt64 length, const std::vector<vtkTypeUInt64> &markers);
197 
198  // Description:
199  // If the block in file (start, start+length) steps over sub-record separators
200  // within this record, then this method will return a new length that includes
201  // the bytes for the separators to be skipped. Otherwise, simply returns the
202  // length.
203  vtkTypeUInt64 GetLengthWithSeparators(vtkTypeUInt64 start, vtkTypeUInt64 length) const;
204 
205  std::vector<std::pair<vtkTypeUInt64, vtkTypeUInt64> > GetChunksToRead(
206  vtkTypeUInt64 start, vtkTypeUInt64 length) const
207  {
208  return this->GetChunksToRead(start, length, this->GetSubRecordSeparators(start, length));
209  }
210 
211 };
212 
213 #endif
214 #endif
215 // VTK-HeaderTest-Exclude: vtkMultiBlockPLOT3DReaderInternals.h
int ReadInts(FILE *fp, int n, int *val)
int vtkIdType
Definition: vtkType.h:347
static void CalculateSkips(const int extent[6], const int wextent[6], vtkIdType &preskip, vtkIdType &postskip)
size_t CalculateFileSize(int mgrid, int precision, int blanking, int ndims, int hasByteCount, int nGrids, int *gridDims)
size_t CalculateFileSizeForBlock(int precision, int blanking, int ndims, int hasByteCount, int *gridDims)
std::vector< vtkSmartPointer< vtkStructuredGrid > > Blocks
void CheckBinaryFile(FILE *fp, size_t fileSize)
int CheckCFile(FILE *fp, size_t fileSize)
std::vector< std::pair< vtkTypeUInt64, vtkTypeUInt64 > > GetChunksToRead(vtkTypeUInt64 start, vtkTypeUInt64 length) const
Multiprocessing communication superclass.