You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
522 lines
17 KiB
C++
522 lines
17 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkXMLWriter.h
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
/**
|
|
* @class vtkXMLWriter
|
|
* @brief Superclass for VTK's XML file writers.
|
|
*
|
|
* vtkXMLWriter provides methods implementing most of the
|
|
* functionality needed to write VTK XML file formats. Concrete
|
|
* subclasses provide actual writer implementations calling upon this
|
|
* functionality.
|
|
*
|
|
* @par Thanks
|
|
* CompressionLevel getters/setters exposed by Quincy Wofford
|
|
* (qwofford@lanl.gov) and John Patchett (patchett@lanl.gov),
|
|
* Los Alamos National Laboratory (2017)
|
|
*/
|
|
|
|
#ifndef vtkXMLWriter_h
|
|
#define vtkXMLWriter_h
|
|
|
|
#include "vtkAlgorithm.h"
|
|
#include "vtkIOXMLModule.h" // For export macro
|
|
|
|
#include <sstream> // For ostringstream ivar
|
|
|
|
class vtkAbstractArray;
|
|
class vtkArrayIterator;
|
|
|
|
template <class T>
|
|
class vtkArrayIteratorTemplate;
|
|
|
|
class vtkCellData;
|
|
class vtkDataArray;
|
|
class vtkDataCompressor;
|
|
class vtkDataSet;
|
|
class vtkDataSetAttributes;
|
|
class vtkFieldData;
|
|
class vtkOutputStream;
|
|
class vtkPointData;
|
|
class vtkPoints;
|
|
class vtkFieldData;
|
|
class vtkXMLDataHeader;
|
|
|
|
class vtkStdString;
|
|
class OffsetsManager; // one per piece/per time
|
|
class OffsetsManagerGroup; // array of OffsetsManager
|
|
class OffsetsManagerArray; // array of OffsetsManagerGroup
|
|
|
|
class VTKIOXML_EXPORT vtkXMLWriter : public vtkAlgorithm
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkXMLWriter, vtkAlgorithm);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
/**
|
|
* Enumerate big and little endian byte order settings.
|
|
*/
|
|
enum
|
|
{
|
|
BigEndian,
|
|
LittleEndian
|
|
};
|
|
|
|
/**
|
|
* Enumerate the supported data modes.
|
|
* Ascii = Inline ascii data.
|
|
* Binary = Inline binary data (base64 encoded, possibly compressed).
|
|
* Appended = Appended binary data (possibly compressed and/or base64).
|
|
*/
|
|
enum
|
|
{
|
|
Ascii,
|
|
Binary,
|
|
Appended
|
|
};
|
|
|
|
/**
|
|
* Enumerate the supported vtkIdType bit lengths.
|
|
* Int32 = File stores 32-bit values for vtkIdType.
|
|
* Int64 = File stores 64-bit values for vtkIdType.
|
|
*/
|
|
enum
|
|
{
|
|
Int32 = 32,
|
|
Int64 = 64
|
|
};
|
|
|
|
/**
|
|
* Enumerate the supported binary data header bit lengths.
|
|
* UInt32 = File stores 32-bit binary data header elements.
|
|
* UInt64 = File stores 64-bit binary data header elements.
|
|
*/
|
|
enum
|
|
{
|
|
UInt32 = 32,
|
|
UInt64 = 64
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the byte order of data written to the file. The default
|
|
* is the machine's hardware byte order.
|
|
*/
|
|
vtkSetMacro(ByteOrder, int);
|
|
vtkGetMacro(ByteOrder, int);
|
|
void SetByteOrderToBigEndian();
|
|
void SetByteOrderToLittleEndian();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the binary data header word type. The default is UInt32.
|
|
* Set to UInt64 when storing arrays requiring 64-bit indexing.
|
|
*/
|
|
virtual void SetHeaderType(int);
|
|
vtkGetMacro(HeaderType, int);
|
|
void SetHeaderTypeToUInt32();
|
|
void SetHeaderTypeToUInt64();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the size of the vtkIdType values stored in the file. The
|
|
* default is the real size of vtkIdType.
|
|
*/
|
|
virtual void SetIdType(int);
|
|
vtkGetMacro(IdType, int);
|
|
void SetIdTypeToInt32();
|
|
void SetIdTypeToInt64();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the name of the output file.
|
|
*/
|
|
vtkSetStringMacro(FileName);
|
|
vtkGetStringMacro(FileName);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Enable writing to an OutputString instead of the default, a file.
|
|
*/
|
|
vtkSetMacro(WriteToOutputString, vtkTypeBool);
|
|
vtkGetMacro(WriteToOutputString, vtkTypeBool);
|
|
vtkBooleanMacro(WriteToOutputString, vtkTypeBool);
|
|
std::string GetOutputString() { return this->OutputString; }
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the compressor used to compress binary and appended data
|
|
* before writing to the file. Default is a vtkZLibDataCompressor.
|
|
*/
|
|
virtual void SetCompressor(vtkDataCompressor*);
|
|
vtkGetObjectMacro(Compressor, vtkDataCompressor);
|
|
//@}
|
|
|
|
enum CompressorType
|
|
{
|
|
NONE,
|
|
ZLIB,
|
|
LZ4,
|
|
LZMA
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Convenience functions to set the compressor to certain known types.
|
|
*/
|
|
void SetCompressorType(int compressorType);
|
|
void SetCompressorTypeToNone() { this->SetCompressorType(NONE); }
|
|
void SetCompressorTypeToLZ4() { this->SetCompressorType(LZ4); }
|
|
void SetCompressorTypeToZLib() { this->SetCompressorType(ZLIB); }
|
|
void SetCompressorTypeToLZMA() { this->SetCompressorType(LZMA); }
|
|
|
|
void SetCompressionLevel(int compressorLevel);
|
|
vtkGetMacro(CompressionLevel, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the block size used in compression. When reading, this
|
|
* controls the granularity of how much extra information must be
|
|
* read when only part of the data are requested. The value should
|
|
* be a multiple of the largest scalar data type.
|
|
*/
|
|
virtual void SetBlockSize(size_t blockSize);
|
|
vtkGetMacro(BlockSize, size_t);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the data mode used for the file's data. The options are
|
|
* vtkXMLWriter::Ascii, vtkXMLWriter::Binary, and
|
|
* vtkXMLWriter::Appended.
|
|
*/
|
|
vtkSetMacro(DataMode, int);
|
|
vtkGetMacro(DataMode, int);
|
|
void SetDataModeToAscii();
|
|
void SetDataModeToBinary();
|
|
void SetDataModeToAppended();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set whether the appended data section is base64 encoded. If
|
|
* encoded, reading and writing will be slower, but the file will be
|
|
* fully valid XML and text-only. If not encoded, the XML
|
|
* specification will be violated, but reading and writing will be
|
|
* fast. The default is to do the encoding.
|
|
*/
|
|
vtkSetMacro(EncodeAppendedData, vtkTypeBool);
|
|
vtkGetMacro(EncodeAppendedData, vtkTypeBool);
|
|
vtkBooleanMacro(EncodeAppendedData, vtkTypeBool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Assign a data object as input. Note that this method does not
|
|
* establish a pipeline connection. Use SetInputConnection() to
|
|
* setup a pipeline connection.
|
|
*/
|
|
void SetInputData(vtkDataObject*);
|
|
void SetInputData(int, vtkDataObject*);
|
|
vtkDataObject* GetInput(int port);
|
|
vtkDataObject* GetInput() { return this->GetInput(0); }
|
|
//@}
|
|
|
|
/**
|
|
* Get the default file extension for files written by this writer.
|
|
*/
|
|
virtual const char* GetDefaultFileExtension() = 0;
|
|
|
|
/**
|
|
* Invoke the writer. Returns 1 for success, 0 for failure.
|
|
*/
|
|
int Write();
|
|
|
|
// See the vtkAlgorithm for a description of what these do
|
|
vtkTypeBool ProcessRequest(vtkInformation* request, vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector) override;
|
|
|
|
//@{
|
|
/**
|
|
* Set the number of time steps
|
|
*/
|
|
vtkGetMacro(NumberOfTimeSteps, int);
|
|
vtkSetMacro(NumberOfTimeSteps, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* API to interface an outside the VTK pipeline control
|
|
*/
|
|
void Start();
|
|
void Stop();
|
|
void WriteNextTime(double time);
|
|
//@}
|
|
|
|
protected:
|
|
vtkXMLWriter();
|
|
~vtkXMLWriter() override;
|
|
|
|
virtual int RequestInformation(vtkInformation* request, vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector);
|
|
virtual int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector);
|
|
|
|
// The name of the output file.
|
|
char* FileName;
|
|
|
|
// The output stream to which the XML is written.
|
|
ostream* Stream;
|
|
|
|
// Whether this object is writing to a string or a file.
|
|
// Default is 0: write to file.
|
|
vtkTypeBool WriteToOutputString;
|
|
|
|
// The output string.
|
|
std::string OutputString;
|
|
|
|
// The output byte order.
|
|
int ByteOrder;
|
|
|
|
// The output binary header word type.
|
|
int HeaderType;
|
|
|
|
// The output vtkIdType.
|
|
int IdType;
|
|
|
|
// The form of binary data to write. Used by subclasses to choose
|
|
// how to write data.
|
|
int DataMode;
|
|
|
|
// Whether to base64-encode the appended data section.
|
|
vtkTypeBool EncodeAppendedData;
|
|
|
|
// The stream position at which appended data starts.
|
|
vtkTypeInt64 AppendedDataPosition;
|
|
|
|
// appended data offsets for field data
|
|
OffsetsManagerGroup* FieldDataOM; // one per array
|
|
|
|
// We need a 32 bit signed integer type to which vtkIdType will be
|
|
// converted if Int32 is specified for the IdType parameter to this
|
|
// writer.
|
|
#if VTK_SIZEOF_SHORT == 4
|
|
typedef short Int32IdType;
|
|
#elif VTK_SIZEOF_INT == 4
|
|
typedef int Int32IdType;
|
|
#elif VTK_SIZEOF_LONG == 4
|
|
typedef long Int32IdType;
|
|
#else
|
|
#error "No native data type can represent a signed 32-bit integer."
|
|
#endif
|
|
|
|
// Buffer for vtkIdType conversion.
|
|
Int32IdType* Int32IdTypeBuffer;
|
|
|
|
// The byte swapping buffer.
|
|
unsigned char* ByteSwapBuffer;
|
|
|
|
// Compression information.
|
|
vtkDataCompressor* Compressor;
|
|
size_t BlockSize;
|
|
size_t CompressionBlockNumber;
|
|
vtkXMLDataHeader* CompressionHeader;
|
|
vtkTypeInt64 CompressionHeaderPosition;
|
|
// Compression Level for vtkDataCompressor objects
|
|
// 1 (worst compression, fastest) ... 9 (best compression, slowest)
|
|
int CompressionLevel = 5;
|
|
|
|
// The output stream used to write binary and appended data. May
|
|
// transparently encode the data.
|
|
vtkOutputStream* DataStream;
|
|
|
|
// Allow subclasses to set the data stream.
|
|
virtual void SetDataStream(vtkOutputStream*);
|
|
vtkGetObjectMacro(DataStream, vtkOutputStream);
|
|
|
|
// Method to drive most of actual writing.
|
|
virtual int WriteInternal();
|
|
|
|
// Method defined by subclasses to write data. Return 1 for
|
|
// success, 0 for failure.
|
|
virtual int WriteData() { return 1; }
|
|
|
|
// Method defined by subclasses to specify the data set's type name.
|
|
virtual const char* GetDataSetName() = 0;
|
|
|
|
// Methods to define the file's major and minor version numbers.
|
|
virtual int GetDataSetMajorVersion();
|
|
virtual int GetDataSetMinorVersion();
|
|
|
|
// Utility methods for subclasses.
|
|
vtkDataSet* GetInputAsDataSet();
|
|
virtual int StartFile();
|
|
virtual void WriteFileAttributes();
|
|
virtual int EndFile();
|
|
void DeleteAFile();
|
|
void DeleteAFile(const char* name);
|
|
|
|
virtual int WritePrimaryElement(ostream& os, vtkIndent indent);
|
|
virtual void WritePrimaryElementAttributes(ostream& os, vtkIndent indent);
|
|
void StartAppendedData();
|
|
void EndAppendedData();
|
|
|
|
// Write enough space to go back and write the given attribute with
|
|
// at most "length" characters in the value. Returns the stream
|
|
// position at which attribute should be later written. The default
|
|
// length of 20 is enough for a 64-bit integer written in decimal or
|
|
// a double-precision floating point value written to 13 digits of
|
|
// precision (the other 7 come from a minus sign, decimal place, and
|
|
// a big exponent like "e+300").
|
|
vtkTypeInt64 ReserveAttributeSpace(const char* attr, size_t length = 20);
|
|
|
|
vtkTypeInt64 GetAppendedDataOffset();
|
|
void WriteAppendedDataOffset(
|
|
vtkTypeInt64 streamPos, vtkTypeInt64& lastoffset, const char* attr = nullptr);
|
|
void ForwardAppendedDataOffset(
|
|
vtkTypeInt64 streamPos, vtkTypeInt64 offset, const char* attr = nullptr);
|
|
void ForwardAppendedDataDouble(vtkTypeInt64 streamPos, double value, const char* attr);
|
|
|
|
int WriteScalarAttribute(const char* name, int data);
|
|
int WriteScalarAttribute(const char* name, float data);
|
|
int WriteScalarAttribute(const char* name, double data);
|
|
#ifdef VTK_USE_64BIT_IDS
|
|
int WriteScalarAttribute(const char* name, vtkIdType data);
|
|
#endif
|
|
|
|
int WriteVectorAttribute(const char* name, int length, int* data);
|
|
int WriteVectorAttribute(const char* name, int length, float* data);
|
|
int WriteVectorAttribute(const char* name, int length, double* data);
|
|
#ifdef VTK_USE_64BIT_IDS
|
|
int WriteVectorAttribute(const char* name, int length, vtkIdType* data);
|
|
#endif
|
|
|
|
int WriteDataModeAttribute(const char* name);
|
|
int WriteWordTypeAttribute(const char* name, int dataType);
|
|
int WriteStringAttribute(const char* name, const char* value);
|
|
|
|
// Returns true if any keys were written.
|
|
bool WriteInformation(vtkInformation* info, vtkIndent indent);
|
|
|
|
void WriteArrayHeader(vtkAbstractArray* a, vtkIndent indent, const char* alternateName,
|
|
int writeNumTuples, int timestep);
|
|
virtual void WriteArrayFooter(
|
|
ostream& os, vtkIndent indent, vtkAbstractArray* a, int shortFormat);
|
|
virtual void WriteArrayInline(vtkAbstractArray* a, vtkIndent indent,
|
|
const char* alternateName = nullptr, int writeNumTuples = 0);
|
|
virtual void WriteInlineData(vtkAbstractArray* a, vtkIndent indent);
|
|
|
|
void WriteArrayAppended(vtkAbstractArray* a, vtkIndent indent, OffsetsManager& offs,
|
|
const char* alternateName = nullptr, int writeNumTuples = 0, int timestep = 0);
|
|
int WriteAsciiData(vtkAbstractArray* a, vtkIndent indent);
|
|
int WriteBinaryData(vtkAbstractArray* a);
|
|
int WriteBinaryDataInternal(vtkAbstractArray* a);
|
|
void WriteArrayAppendedData(vtkAbstractArray* a, vtkTypeInt64 pos, vtkTypeInt64& lastoffset);
|
|
|
|
// Methods for writing points, point data, and cell data.
|
|
void WriteFieldData(vtkIndent indent);
|
|
void WriteFieldDataInline(vtkFieldData* fd, vtkIndent indent);
|
|
void WritePointDataInline(vtkPointData* pd, vtkIndent indent);
|
|
void WriteCellDataInline(vtkCellData* cd, vtkIndent indent);
|
|
void WriteFieldDataAppended(vtkFieldData* fd, vtkIndent indent, OffsetsManagerGroup* fdManager);
|
|
void WriteFieldDataAppendedData(vtkFieldData* fd, int timestep, OffsetsManagerGroup* fdManager);
|
|
void WritePointDataAppended(vtkPointData* pd, vtkIndent indent, OffsetsManagerGroup* pdManager);
|
|
void WritePointDataAppendedData(vtkPointData* pd, int timestep, OffsetsManagerGroup* pdManager);
|
|
void WriteCellDataAppended(vtkCellData* cd, vtkIndent indent, OffsetsManagerGroup* cdManager);
|
|
void WriteCellDataAppendedData(vtkCellData* cd, int timestep, OffsetsManagerGroup* cdManager);
|
|
void WriteAttributeIndices(vtkDataSetAttributes* dsa, char** names);
|
|
void WritePointsAppended(vtkPoints* points, vtkIndent indent, OffsetsManager* manager);
|
|
void WritePointsAppendedData(vtkPoints* points, int timestep, OffsetsManager* pdManager);
|
|
void WritePointsInline(vtkPoints* points, vtkIndent indent);
|
|
void WriteCoordinatesInline(
|
|
vtkDataArray* xc, vtkDataArray* yc, vtkDataArray* zc, vtkIndent indent);
|
|
void WriteCoordinatesAppended(vtkDataArray* xc, vtkDataArray* yc, vtkDataArray* zc,
|
|
vtkIndent indent, OffsetsManagerGroup* coordManager);
|
|
void WriteCoordinatesAppendedData(vtkDataArray* xc, vtkDataArray* yc, vtkDataArray* zc,
|
|
int timestep, OffsetsManagerGroup* coordManager);
|
|
void WritePPointData(vtkPointData* pd, vtkIndent indent);
|
|
void WritePCellData(vtkCellData* cd, vtkIndent indent);
|
|
void WritePPoints(vtkPoints* points, vtkIndent indent);
|
|
void WritePArray(vtkAbstractArray* a, vtkIndent indent, const char* alternateName = nullptr);
|
|
void WritePCoordinates(vtkDataArray* xc, vtkDataArray* yc, vtkDataArray* zc, vtkIndent indent);
|
|
|
|
// Internal utility methods.
|
|
int WriteBinaryDataBlock(unsigned char* in_data, size_t numWords, int wordType);
|
|
void PerformByteSwap(void* data, size_t numWords, size_t wordSize);
|
|
int CreateCompressionHeader(size_t size);
|
|
int WriteCompressionBlock(unsigned char* data, size_t size);
|
|
int WriteCompressionHeader();
|
|
size_t GetWordTypeSize(int dataType);
|
|
const char* GetWordTypeName(int dataType);
|
|
size_t GetOutputWordTypeSize(int dataType);
|
|
|
|
char** CreateStringArray(int numStrings);
|
|
void DestroyStringArray(int numStrings, char** strings);
|
|
|
|
// The current range over which progress is moving. This allows for
|
|
// incrementally fine-tuned progress updates.
|
|
virtual void GetProgressRange(float range[2]);
|
|
virtual void SetProgressRange(const float range[2], int curStep, int numSteps);
|
|
virtual void SetProgressRange(const float range[2], int curStep, const float* fractions);
|
|
virtual void SetProgressPartial(float fraction);
|
|
virtual void UpdateProgressDiscrete(float progress);
|
|
float ProgressRange[2];
|
|
|
|
// This shallows copy input field data to the passed field data and
|
|
// then adds any additional field arrays. For example, TimeValue.
|
|
void UpdateFieldData(vtkFieldData*);
|
|
|
|
ostream* OutFile;
|
|
std::ostringstream* OutStringStream;
|
|
|
|
int OpenStream();
|
|
int OpenFile();
|
|
int OpenString();
|
|
void CloseStream();
|
|
void CloseFile();
|
|
void CloseString();
|
|
|
|
// The timestep currently being written
|
|
int CurrentTimeIndex;
|
|
int NumberOfTimeSteps;
|
|
|
|
// Dummy boolean var to start/stop the continue executing:
|
|
// when using the Start/Stop/WriteNextTime API
|
|
int UserContinueExecuting; // can only be -1 = invalid, 0 = stop, 1 = start
|
|
|
|
// This variable is used to ease transition to new versions of VTK XML files.
|
|
// If data that needs to be written satisfies certain conditions,
|
|
// the writer can use the previous file version version.
|
|
// For version change 0.1 -> 2.0 (UInt32 header) and 1.0 -> 2.0
|
|
// (UInt64 header), if data does not have a vtkGhostType array,
|
|
// the file is written with version: 0.1/1.0.
|
|
bool UsePreviousVersion;
|
|
|
|
vtkTypeInt64* NumberOfTimeValues; // one per piece / per timestep
|
|
|
|
friend class vtkXMLWriterHelper;
|
|
|
|
private:
|
|
vtkXMLWriter(const vtkXMLWriter&) = delete;
|
|
void operator=(const vtkXMLWriter&) = delete;
|
|
};
|
|
|
|
#endif
|