/*========================================================================= 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 // For ostringstream ivar class vtkAbstractArray; class vtkArrayIterator; template 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