VTK  9.4.20241222
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
15VTK_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 {
38 int Precision; // in bytes
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};
82VTK_ABI_NAMESPACE_END
83
84namespace
85{
86class Plot3DException : public std::exception
87{
88};
89}
90
91VTK_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.
100class 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
111public:
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
182VTK_ABI_NAMESPACE_END
183#endif
184// 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.
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