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