vtk9/IO/XML/vtkXMLWriter.h

306 lines
11 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 "vtkIOXMLModule.h" // For export macro
#include "vtkXMLWriterBase.h"
#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 vtkXMLWriterBase
{
public:
vtkTypeMacro(vtkXMLWriter, vtkXMLWriterBase);
void PrintSelf(ostream& os, vtkIndent indent) override;
///@{
/**
* 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); }
///@}
// 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 output stream to which the XML is written.
ostream* Stream;
// 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.
size_t CompressionBlockNumber;
vtkXMLDataHeader* CompressionHeader;
vtkTypeInt64 CompressionHeaderPosition;
// 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;
// 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
vtkTypeInt64* NumberOfTimeValues; // one per piece / per timestep
friend class vtkXMLWriterHelper;
private:
vtkXMLWriter(const vtkXMLWriter&) = delete;
void operator=(const vtkXMLWriter&) = delete;
};
#endif