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