diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C index 6051109404..cbe2d515bc 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C @@ -226,20 +226,27 @@ void Foam::vtk::lagrangianWriter::beginParcelData(label nFields) { if (!nParcels_) return; // Skip if there are no parcels - const vtk::fileTag dataType = - ( - useVerts_ - ? vtk::fileTag::CELL_DATA - : vtk::fileTag::POINT_DATA - ); - - if (legacy_) + if (useVerts_) { - legacy::dataHeader(os_, dataType, nParcels_, nFields); + if (legacy_) + { + legacy::beginCellData(format(), nParcels_, nFields); + } + else + { + format().beginCellData(); + } } else { - format().tag(dataType); + if (legacy_) + { + legacy::beginPointData(format(), nParcels_, nFields); + } + else + { + format().beginPointData(); + } } } @@ -248,16 +255,17 @@ void Foam::vtk::lagrangianWriter::endParcelData() { if (!nParcels_) return; // Skip if there are no parcels - const vtk::fileTag dataType = - ( - useVerts_ - ? vtk::fileTag::CELL_DATA - : vtk::fileTag::POINT_DATA - ); - if (!legacy_) { - format().endTag(dataType); + + if (useVerts_) + { + format().endCellData(); + } + else + { + format().endPointData(); + } } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C index 5b4181f55f..bd0e7202ea 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C @@ -78,7 +78,7 @@ void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames) if (legacy_) { - legacy::intField(os(), fldName, nCmpt, fld.size()); + legacy::intField(format(), fldName, fld.size()); } else { @@ -103,7 +103,7 @@ void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames) if (legacy_) { - legacy::floatField(os(), fldName, nCmpt, fld.size()); + legacy::floatField(format(), fldName, fld.size()); } else { diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.C b/src/conversion/vtk/output/foamVtkInternalWriter.C index 49bf062e82..4972f98ca1 100644 --- a/src/conversion/vtk/output/foamVtkInternalWriter.C +++ b/src/conversion/vtk/output/foamVtkInternalWriter.C @@ -284,17 +284,11 @@ void Foam::vtk::internalWriter::beginCellData(label nFields) { if (legacy_) { - legacy::dataHeader - ( - os(), - vtk::fileTag::CELL_DATA, - vtuCells_.nFieldCells(), - nFields - ); + legacy::beginCellData(format(), vtuCells_.nFieldCells(), nFields); } else { - format().tag(vtk::fileTag::CELL_DATA); + format().beginCellData(); } } @@ -303,7 +297,7 @@ void Foam::vtk::internalWriter::endCellData() { if (!legacy_) { - format().endTag(vtk::fileTag::CELL_DATA); + format().endCellData(); } } @@ -312,17 +306,16 @@ void Foam::vtk::internalWriter::beginPointData(label nFields) { if (legacy_) { - legacy::dataHeader + legacy::beginPointData ( - os(), - vtk::fileTag::POINT_DATA, + format(), vtuCells_.nFieldPoints(), nFields ); } else { - format().tag(vtk::fileTag::POINT_DATA); + format().beginPointData(); } } @@ -331,7 +324,7 @@ void Foam::vtk::internalWriter::endPointData() { if (!legacy_) { - format().endTag(vtk::fileTag::POINT_DATA); + format().endPointData(); } } diff --git a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C index 77689e5ec7..b0177ade71 100644 --- a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C +++ b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C @@ -43,7 +43,7 @@ void Foam::vtk::internalWriter::write if (legacy_) { - legacy::floatField(os(), field.name(), nCmpt, cellMap.size()); + legacy::floatField(format(), field.name(), cellMap.size()); } else { @@ -87,7 +87,7 @@ void Foam::vtk::internalWriter::write if (legacy_) { - legacy::floatField(os(), field.name(), nCmpt, nVals); + legacy::floatField(format(), field.name(), nVals); } else { @@ -136,7 +136,7 @@ void Foam::vtk::internalWriter::write if (legacy_) { - legacy::floatField(os(), vfield.name(), nCmpt, nVals); + legacy::floatField(format(), vfield.name(), nVals); } else { @@ -179,7 +179,7 @@ void Foam::vtk::internalWriter::write if (legacy_) { - legacy::floatField(os(), vfield.name(), nCmpt, nVals); + legacy::floatField(format(), vfield.name(), nVals); } else { diff --git a/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C b/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C index 74cb846a1b..5136eb0bf5 100644 --- a/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C +++ b/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -39,7 +39,7 @@ void Foam::vtk::writeField ); fmt.writeSize(payLoad); - writeList(fmt, fld); + vtk::writeList(fmt, fld); fmt.flush(); } @@ -59,7 +59,7 @@ void Foam::vtk::writeField ); fmt.writeSize(payLoad); - writeList(fmt, fld, cellMap); + vtk::writeList(fmt, fld, cellMap); fmt.flush(); } @@ -78,7 +78,7 @@ void Foam::vtk::writeField ); fmt.writeSize(payLoad); - writeList(fmt, fld.internalField()); + vtk::writeList(fmt, fld.internalField()); fmt.flush(); } @@ -98,7 +98,7 @@ void Foam::vtk::writeField ); fmt.writeSize(payLoad); - writeList(fmt, fld.internalField(), cellMap); + vtk::writeList(fmt, fld.internalField(), cellMap); fmt.flush(); } diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.C b/src/conversion/vtk/output/foamVtkPatchWriter.C index 18764148cd..3ca9500a84 100644 --- a/src/conversion/vtk/output/foamVtkPatchWriter.C +++ b/src/conversion/vtk/output/foamVtkPatchWriter.C @@ -301,17 +301,11 @@ void Foam::vtk::patchWriter::beginCellData(label nFields) { if (legacy_) { - legacy::dataHeader - ( - os(), - vtk::fileTag::CELL_DATA, - nFaces_, - nFields - ); + legacy::beginCellData(format(), nFaces_, nFields); } else { - format().tag(vtk::fileTag::CELL_DATA); + format().beginCellData(); } } @@ -320,7 +314,7 @@ void Foam::vtk::patchWriter::endCellData() { if (!legacy_) { - format().endTag(vtk::fileTag::CELL_DATA); + format().endCellData(); } } @@ -329,17 +323,11 @@ void Foam::vtk::patchWriter::beginPointData(label nFields) { if (legacy_) { - legacy::dataHeader - ( - os(), - vtk::fileTag::POINT_DATA, - nPoints_, - nFields - ); + legacy::beginPointData(format(), nPoints_, nFields); } else { - format().tag(vtk::fileTag::POINT_DATA); + format().beginPointData(); } } @@ -348,7 +336,7 @@ void Foam::vtk::patchWriter::endPointData() { if (!legacy_) { - format().endTag(vtk::fileTag::POINT_DATA); + format().endPointData(); } } @@ -373,7 +361,7 @@ void Foam::vtk::patchWriter::writePatchIDs() if (legacy_) { - legacy::intField(os_, "patchID", 1, nFaces_); + legacy::intField<1>(format(), "patchID", nFaces_); // 1 component } else { diff --git a/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C b/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C index 9c77912499..0bc9602390 100644 --- a/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C +++ b/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C @@ -39,7 +39,7 @@ void Foam::vtk::patchWriter::write if (legacy_) { - legacy::floatField(os_, field.name(), nCmpt, nFaces_); + legacy::floatField(format(), field.name(), nFaces_); } else { @@ -83,7 +83,7 @@ void Foam::vtk::patchWriter::write if (legacy_) { - legacy::floatField(os_, field.name(), nCmpt, nPoints_); + legacy::floatField(format(), field.name(), nPoints_); } else { @@ -121,7 +121,7 @@ void Foam::vtk::patchWriter::write if (legacy_) { - legacy::floatField(os_, field.name(), nCmpt, nPoints_); + legacy::floatField(format(), field.name(), nPoints_); } else { diff --git a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C index f5ba90efc1..96b62ed9c7 100644 --- a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C +++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C @@ -230,11 +230,11 @@ void Foam::vtk::surfaceMeshWriter::beginCellData(label nFields) { if (legacy_) { - legacy::dataHeader(os(), vtk::fileTag::CELL_DATA, pp_.size(), nFields); + legacy::beginCellData(format(), pp_.size(), nFields); } else { - format().tag(vtk::fileTag::CELL_DATA); + format().beginCellData(); } } @@ -243,7 +243,7 @@ void Foam::vtk::surfaceMeshWriter::endCellData() { if (!legacy_) { - format().endTag(vtk::fileTag::CELL_DATA); + format().endCellData(); } } diff --git a/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C b/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C index 8b52dfc02f..c54d53f3dd 100644 --- a/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C +++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C @@ -70,7 +70,7 @@ void Foam::vtk::surfaceMeshWriter::write if (legacy_) { - legacy::floatField(os(), field.name(), nCmpt, pp_.size()); + legacy::floatField(format(), field.name(), pp_.size()); } else { @@ -100,7 +100,7 @@ void Foam::vtk::surfaceMeshWriter::write if (legacy_) { - legacy::floatField(os(), field.name(), nCmpt, pp_.size()); + legacy::floatField(format(), field.name(), pp_.size()); } else { diff --git a/src/conversion/vtk/output/foamVtkWriteSurfFields.C b/src/conversion/vtk/output/foamVtkWriteSurfFields.C index bfe1f35038..1742470dbf 100644 --- a/src/conversion/vtk/output/foamVtkWriteSurfFields.C +++ b/src/conversion/vtk/output/foamVtkWriteSurfFields.C @@ -94,10 +94,9 @@ void Foam::vtk::writeSurfFields // Fields if (legacy_) { - legacy::dataHeader + legacy::beginPointData ( - os, - vtk::fileTag::POINT_DATA, + format(), mesh.nFaces(), surfVectorFields.size() ); @@ -114,7 +113,7 @@ void Foam::vtk::writeSurfFields if (legacy_) { - legacy::floatField(os, fld.name(), nCmpt, mesh.nFaces()); + legacy::floatField(format(), fld.name(), mesh.nFaces()); } else { diff --git a/src/fileFormats/vtk/core/foamVtkCore.C b/src/fileFormats/vtk/core/foamVtkCore.C index 7a61ccb034..c8b41b924c 100644 --- a/src/fileFormats/vtk/core/foamVtkCore.C +++ b/src/fileFormats/vtk/core/foamVtkCore.C @@ -27,6 +27,32 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +const Foam::Enum +< + Foam::vtk::fileTag +> +Foam::vtk::fileExtension +{ + { fileTag::POLY_DATA, "vtp" }, + { fileTag::UNSTRUCTURED_GRID, "vtu" }, + { fileTag::MULTI_BLOCK, "vtm" }, + // { fileTag::COLLECTION, "pvd" }, +}; + + +const Foam::Enum +< + Foam::vtk::fileTag +> +Foam::vtk::fileContentVersions +{ + { fileTag::POLY_DATA, "0.1" }, + { fileTag::UNSTRUCTURED_GRID, "0.1" }, + { fileTag::MULTI_BLOCK, "1.0" }, + // { fileTag::COLLECTION, "0.1" }, +}; + + const Foam::Enum < Foam::vtk::fileTag @@ -35,6 +61,7 @@ Foam::vtk::fileTagNames ({ { fileTag::VTK_FILE, "VTKFile" }, { fileTag::DATA_ARRAY, "DataArray" }, + { fileTag::BLOCK, "Block" }, { fileTag::PIECE, "Piece" }, { fileTag::DATA_SET, "DataSet" }, { fileTag::POINTS, "Points" }, @@ -44,9 +71,11 @@ Foam::vtk::fileTagNames { fileTag::LINES, "Lines" }, { fileTag::CELL_DATA, "CellData" }, { fileTag::POINT_DATA, "PointData" }, + { fileTag::FIELD_DATA, "FieldData" }, { fileTag::POLY_DATA, "PolyData" }, { fileTag::UNSTRUCTURED_GRID, "UnstructuredGrid" }, { fileTag::MULTI_BLOCK, "vtkMultiBlockDataSet" }, + // { fileTag::COLLECTION, "Collection" }, }); @@ -58,6 +87,7 @@ Foam::vtk::fileAttrNames ({ { fileAttr::OFFSET, "offset" }, { fileAttr::NUMBER_OF_COMPONENTS, "NumberOfComponents" }, + { fileAttr::NUMBER_OF_TUPLES, "NumberOfTuples" }, { fileAttr::NUMBER_OF_POINTS, "NumberOfPoints" }, { fileAttr::NUMBER_OF_CELLS, "NumberOfCells" }, { fileAttr::NUMBER_OF_POLYS, "NumberOfPolys" }, @@ -81,4 +111,30 @@ Foam::vtk::dataArrayAttrNames }); +// Legacy + +const Foam::word Foam::vtk::legacy::fileExtension("vtk"); + +const Foam::Enum +< + Foam::vtk::fileTag +> +Foam::vtk::legacy::contentNames +({ + { vtk::fileTag::POLY_DATA, "POLYDATA" }, + { vtk::fileTag::UNSTRUCTURED_GRID, "UNSTRUCTURED_GRID" }, +}); + + +const Foam::Enum +< + Foam::vtk::fileTag +> +Foam::vtk::legacy::dataTypeNames +({ + { vtk::fileTag::CELL_DATA, "CELL_DATA" }, + { vtk::fileTag::POINT_DATA, "POINT_DATA" }, +}); + + // ************************************************************************* // diff --git a/src/fileFormats/vtk/core/foamVtkCore.H b/src/fileFormats/vtk/core/foamVtkCore.H index 8584c9672c..88620ebc5c 100644 --- a/src/fileFormats/vtk/core/foamVtkCore.H +++ b/src/fileFormats/vtk/core/foamVtkCore.H @@ -35,6 +35,7 @@ SourceFiles #ifndef foamVtkCore_H #define foamVtkCore_H +#include #include "Enum.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -59,22 +60,29 @@ namespace vtk //- The output format type for file contents. // Upper bits for output type, lower bits for the format itself. - enum class formatType + enum class formatType : uint8_t { - /** XML inline ASCII, using the asciiFormatter */ - INLINE_ASCII = 0, - /** XML inline base64, using the base64Formatter */ - INLINE_BASE64 = 0x01, - /** XML append base64, using the appendBase64Formatter */ - APPEND_BASE64 = 0x11, - /** XML append raw binary, using the appendRawFormatter */ - APPEND_BINARY = 0x12, - /** Legacy ASCII, using the legacyAsciiFormatter */ - LEGACY_ASCII = 0x20, - /** Legacy raw binary, using the legacyRawFormatter */ - LEGACY_BINARY = 0x22, + INLINE_ASCII = 0, //!< XML inline ASCII, asciiFormatter + INLINE_BASE64 = 0x01, //!< XML inline base64, base64Formatter + APPEND_BASE64 = 0x11, //!< XML append base64, appendBase64Formatter + APPEND_BINARY = 0x12, //!< XML append raw binary, appendRawFormatter + LEGACY_ASCII = 0x20, //!< Legacy ASCII, legacyAsciiFormatter + LEGACY_BINARY = 0x22, //!< Legacy raw binary, legacyRawFormatter }; + //- Test for XML append format + inline bool isAppend(enum formatType fmt) + { + return (uint8_t(fmt) & 0x10); + } + + //- Test for vtk legacy format + inline bool isLegacy(enum formatType fmt) + { + return (uint8_t(fmt) & 0x20); + } + + //- Equivalent to enumeration in "vtkCellType.h" enum cellType { @@ -104,6 +112,7 @@ namespace vtk { VTK_FILE, //!< "VTKFile" DATA_ARRAY, //!< "DataArray" + BLOCK, //!< "Block" PIECE, //!< "Piece" DATA_SET, //!< "DataSet" POINTS, //!< "Points" @@ -113,12 +122,19 @@ namespace vtk LINES, //!< "Lines" CELL_DATA, //!< "CellData" POINT_DATA, //!< "PointData" + FIELD_DATA, //!< "FieldData" POLY_DATA, //!< "PolyData" UNSTRUCTURED_GRID, //!< "UnstructuredGrid" MULTI_BLOCK, //!< "vtkMultiBlockDataSet" }; - //- Strings corresponding to the vtk xml tags + //- File extension (without ".") for some vtk XML file content types + extern const Foam::Enum fileExtension; + + //- Version string for some vtk XML file content types + extern const Foam::Enum fileContentVersions; + + //- Strings corresponding to the vtk XML tags extern const Foam::Enum fileTagNames; //- Some common XML attributes for vtk files @@ -126,6 +142,7 @@ namespace vtk { OFFSET, //!< "offset" NUMBER_OF_COMPONENTS, //!< "NumberOfComponents" + NUMBER_OF_TUPLES, //!< "NumberOfTuples" NUMBER_OF_POINTS, //!< "NumberOfPoints" NUMBER_OF_CELLS, //!< "NumberOfCells" NUMBER_OF_POLYS, //!< "NumberOfPolys" @@ -133,10 +150,10 @@ namespace vtk NUMBER_OF_LINES, //!< "NumberOfLines" }; - //- Strings corresponding to the vtk xml attributes + //- Strings corresponding to the vtk XML attributes extern const Foam::Enum fileAttrNames; - //- Some common names for XML data arrays + //- Some common names for XML DataArray entries enum class dataArrayAttr { POINTS, //!< "Points" @@ -147,10 +164,29 @@ namespace vtk FACEOFFSETS, //!< "faceoffsets" }; - //- Strings corresponding to the vtk xml attributes + //- Strings corresponding to the vtk XML DataArray attributes extern const Foam::Enum dataArrayAttrNames; +/*---------------------------------------------------------------------------*\ + Namespace legacy +\*---------------------------------------------------------------------------*/ + +namespace legacy +{ + + //- Legacy file extension ("vtk") + extern const word fileExtension; + + //- Legacy content names (POLYDATA, UNSTRUCTURED_GRID) + extern const Foam::Enum contentNames; + + //- Legacy data type names (CELL_DATA, POINT_DATA) + extern const Foam::Enum dataTypeNames; + +} // End namespace legacy + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace vtk diff --git a/src/fileFormats/vtk/core/foamVtkPTraits.C b/src/fileFormats/vtk/core/foamVtkPTraits.C index 0cc5ca04e4..7a542257c8 100644 --- a/src/fileFormats/vtk/core/foamVtkPTraits.C +++ b/src/fileFormats/vtk/core/foamVtkPTraits.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -66,5 +66,9 @@ const char* const Foam::vtkPTraits::typeName = "BigEndian"; #endif +template<> +const char* const +Foam::vtkPTraits::typeName = "String"; + // ************************************************************************* // diff --git a/src/fileFormats/vtk/core/foamVtkPTraits.H b/src/fileFormats/vtk/core/foamVtkPTraits.H index ac8df06646..b40375f1fb 100644 --- a/src/fileFormats/vtk/core/foamVtkPTraits.H +++ b/src/fileFormats/vtk/core/foamVtkPTraits.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -33,6 +33,7 @@ Description #define foamVtkPTraits_H #include +#include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -47,13 +48,10 @@ class endian; \*---------------------------------------------------------------------------*/ template -class vtkPTraits +struct vtkPTraits { -public: - // Static data members - - static const char* const typeName; + static const char* const typeName; }; @@ -81,6 +79,9 @@ const char* const vtkPTraits::typeName; // Float64 template<> const char* const vtkPTraits::typeName; // (Big|Little)Endian +template<> +const char* const vtkPTraits::typeName; // String + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C index 5527e5c35a..334241b2f1 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C +++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -41,7 +41,8 @@ Foam::vtk::appendBase64Formatter::appendBase64Formatter std::ostream& os ) : - foamVtkBase64Layer(os) + foamVtkBase64Layer(os), + offset_(0) {} @@ -68,4 +69,16 @@ const char* Foam::vtk::appendBase64Formatter::name() const } +uint64_t Foam::vtk::appendBase64Formatter::offset(const uint64_t numbytes) +{ + uint64_t prev = offset_; + + if (formatter::npos != numbytes) + { + offset_ += this->encodedLength(sizeof(uint64_t) + numbytes); + } + return prev; +} + + // ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H index 2384289f67..6f3814a22a 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H +++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,7 +46,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class appendBase64Formatter Declaration + Class vtk::appendBase64Formatter Declaration \*---------------------------------------------------------------------------*/ class appendBase64Formatter @@ -58,6 +58,9 @@ class appendBase64Formatter static const char* name_; static const outputOptions opts_; + //- The current offset for append data. + uint64_t offset_; + // Private Member Functions @@ -88,6 +91,12 @@ public: //- Output name for XML type ("append") virtual const char* name() const; + //- Increase the append data offset by numbytes and sizeof(uint64_t). + // The additional (uint64_t) size information is consistent with + // writeSize(). + // + // \return The previous data offset + virtual uint64_t offset(const uint64_t numbytes); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C index f8b7bcf29f..c7e2783c5e 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C @@ -52,7 +52,8 @@ void Foam::vtk::appendRawFormatter::write Foam::vtk::appendRawFormatter::appendRawFormatter(std::ostream& os) : - formatter(os) + formatter(os), + offset_(0) {} @@ -77,9 +78,22 @@ const char* Foam::vtk::appendRawFormatter::encoding() const } -void Foam::vtk::appendRawFormatter::writeSize(const uint64_t nBytes) +uint64_t Foam::vtk::appendRawFormatter::offset(const uint64_t numbytes) { - write(reinterpret_cast(&nBytes), sizeof(uint64_t)); + uint64_t prev = offset_; + + if (formatter::npos != numbytes) + { + offset_ += this->encodedLength(sizeof(uint64_t) + numbytes); + } + return prev; +} + + +bool Foam::vtk::appendRawFormatter::writeSize(const uint64_t numbytes) +{ + write(reinterpret_cast(&numbytes), sizeof(uint64_t)); + return true; } diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H index dbbcf0788a..fc05f9249c 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -45,7 +45,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class appendRawFormatter Declaration + Class vtk::appendRawFormatter Declaration \*---------------------------------------------------------------------------*/ class appendRawFormatter @@ -58,6 +58,9 @@ class appendRawFormatter static const char* encoding_; static const outputOptions opts_; + //- The current offset for append data. + uint64_t offset_; + // Private Member Functions @@ -99,9 +102,16 @@ public: //- Output name for append encoding type ("raw") virtual const char* encoding() const; + //- Increase the append data offset by numbytes and sizeof(uint64_t). + // The additional (uint64_t) size information is consistent with + // writeSize() + // + // \return The previous data offset + virtual uint64_t offset(const uint64_t numbytes); //- Write leading size for binary output - virtual void writeSize(const uint64_t nBytes); + // \return True - format uses this information + virtual bool writeSize(const uint64_t numbytes); virtual void write(const uint8_t val); virtual void write(const label val); diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C index d220627ab7..fa549ff24a 100644 --- a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C @@ -113,8 +113,10 @@ const char* Foam::vtk::asciiFormatter::encoding() const } -void Foam::vtk::asciiFormatter::writeSize(const uint64_t ignored) -{/*nop*/} +bool Foam::vtk::asciiFormatter::writeSize(const uint64_t) +{ + return false; +} void Foam::vtk::asciiFormatter::write(const uint8_t val) @@ -163,8 +165,7 @@ void Foam::vtk::asciiFormatter::flush() } -std::size_t -Foam::vtk::asciiFormatter::encodedLength(std::size_t ignored) const +std::size_t Foam::vtk::asciiFormatter::encodedLength(std::size_t) const { return 0; } diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H index b050d6573c..25d7fc7f38 100644 --- a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -47,7 +47,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class asciiFormatter Declaration + Class vtk::asciiFormatter Declaration \*---------------------------------------------------------------------------*/ class asciiFormatter @@ -108,7 +108,8 @@ public: //- Write leading size - this is a no-op for ascii output - virtual void writeSize(const uint64_t ignored); + // \return False - never used by this format + virtual bool writeSize(const uint64_t ignored); virtual void write(const uint8_t val); virtual void write(const label val); @@ -119,6 +120,7 @@ public: virtual void flush(); //- The encoded length for ascii output is not applicable. + // \return 0 virtual std::size_t encodedLength(std::size_t ignored) const; }; diff --git a/src/fileFormats/vtk/format/foamVtkBase64Formatter.H b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H index cd733e643e..9b96c1ac71 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Formatter.H +++ b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H @@ -44,7 +44,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class base64Formatter Declaration + Class vtk::base64Formatter Declaration \*---------------------------------------------------------------------------*/ class base64Formatter diff --git a/src/fileFormats/vtk/format/foamVtkBase64Layer.C b/src/fileFormats/vtk/format/foamVtkBase64Layer.C index fbdc7ad525..8cbfbc2c01 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Layer.C +++ b/src/fileFormats/vtk/format/foamVtkBase64Layer.C @@ -68,9 +68,10 @@ const char* Foam::vtk::foamVtkBase64Layer::encoding() const } -void Foam::vtk::foamVtkBase64Layer::writeSize(const uint64_t nBytes) +bool Foam::vtk::foamVtkBase64Layer::writeSize(const uint64_t numbytes) { - write(reinterpret_cast(&nBytes), sizeof(uint64_t)); + write(reinterpret_cast(&numbytes), sizeof(uint64_t)); + return true; } @@ -121,10 +122,7 @@ void Foam::vtk::foamVtkBase64Layer::flush() } -std::size_t Foam::vtk::foamVtkBase64Layer::encodedLength -( - std::size_t n -) const +std::size_t Foam::vtk::foamVtkBase64Layer::encodedLength(std::size_t n) const { return base64Layer::encodedLength(n); } diff --git a/src/fileFormats/vtk/format/foamVtkBase64Layer.H b/src/fileFormats/vtk/format/foamVtkBase64Layer.H index d965c6348d..3805a57747 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Layer.H +++ b/src/fileFormats/vtk/format/foamVtkBase64Layer.H @@ -43,7 +43,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class foamVtkBase64Layer Declaration + Class vtk::foamVtkBase64Layer Declaration \*---------------------------------------------------------------------------*/ class foamVtkBase64Layer @@ -89,9 +89,9 @@ public: //- Name for the XML append encoding ("base64"). virtual const char* encoding() const; - //- Write leading size for binary output - virtual void writeSize(const uint64_t nBytes); + // \return True - format uses this information + virtual bool writeSize(const uint64_t numbytes); virtual void write(const uint8_t val); virtual void write(const label val); diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.C b/src/fileFormats/vtk/format/foamVtkFormatter.C index 711bcdecd2..c6b2a4e56f 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkFormatter.C @@ -24,104 +24,103 @@ License #include "foamVtkFormatter.H" +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +bool Foam::vtk::formatter::canWriteAttr(const word& k) const +{ + if (!inTag_) + { + WarningInFunction + << "xml attribute '" << k << "' but not inside a tag!" << endl; + } + + return inTag_; +} + + +bool Foam::vtk::formatter::canWriteToplevel(const char* what) const +{ + if (inTag_) + { + WarningInFunction + << "Cannot add " << what << " inside a tag!" + << endl; + } + + return !inTag_; +} + + // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +void Foam::vtk::formatter::quoting(const quoteChar quote) +{ + quote_ = quote; +} + + +uint64_t Foam::vtk::formatter::offset(const uint64_t) +{ + return formatter::npos; +} + + std::size_t Foam::vtk::formatter::encodedLength(std::size_t n) const { return n; } -void Foam::vtk::formatter::indent() -{ - label n = xmlTags_.size() * 2; - while (n--) - { - os_ << ' '; - } -} - - -Foam::vtk::formatter& -Foam::vtk::formatter::xmlHeader() +bool Foam::vtk::formatter::openTagImpl(const word& tagName) { if (inTag_) { WarningInFunction - << "xml header, but already within a tag!" - << endl; - } - - os_ << "" << nl; - - return *this; -} - - -Foam::vtk::formatter& -Foam::vtk::formatter::xmlComment(const std::string& comment) -{ - if (inTag_) - { - WarningInFunction - << "adding xml comment inside a tag??" - << endl; - } - - indent(); - os_ << "" << nl; - - return *this; -} - - -Foam::vtk::formatter& -Foam::vtk::formatter::openTag(const word& tagName) -{ - if (inTag_) - { - WarningInFunction - << "open XML tag '" << tagName - << "', but already within a tag!" + << "open xml tag '" << tagName << "', but already within a tag!" << endl; + + return false; } + // Emit, before changing the stack or the state. indent(); os_ << '<' << tagName; + // Add to the stack and change the state. xmlTags_.append(tagName); inTag_ = true; - return *this; + return true; } -Foam::vtk::formatter& -Foam::vtk::formatter::closeTag(const bool isEmpty) +Foam::vtk::formatter& Foam::vtk::formatter::closeTag(const bool isEmpty) { if (!inTag_) { WarningInFunction - << "close XML tag, but not within a tag!" + << "attempt to close xml tag, but not within a tag!" << endl; } - - if (isEmpty) + else { - // eg, - xmlTags_.remove(); - os_ << " /"; - } - os_ << '>' << nl; + // Change the state + inTag_ = false; - inTag_ = false; + if (isEmpty) + { + // Eg, + xmlTags_.remove(); + os_ << " /"; + } + os_ << '>' << nl; + } return *this; } -Foam::vtk::formatter& -Foam::vtk::formatter::endTag(const word& tagName) +Foam::vtk::formatter& Foam::vtk::formatter::endTag(const word& tagName) { const word curr(xmlTags_.remove()); indent(); @@ -129,16 +128,18 @@ Foam::vtk::formatter::endTag(const word& tagName) if (inTag_) { WarningInFunction - << "adding XML endTag '" << curr + << "adding xml endTag '" << curr << "' but already in another tag!" << endl; + + // Also suppress further output, or not? } - // verify expected end tag + // Verify expected end tag if (!tagName.empty() && tagName != curr) { WarningInFunction - << "expecting to end xml-tag '" << tagName + << "expecting to end xml tag '" << tagName << "' but found '" << curr << "' instead" << endl; } @@ -151,8 +152,7 @@ Foam::vtk::formatter::endTag(const word& tagName) } -Foam::vtk::formatter& -Foam::vtk::formatter::beginVTKFile +Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile ( const word& contentType, const word& contentVersion, @@ -176,15 +176,7 @@ Foam::vtk::formatter::beginVTKFile } -Foam::vtk::formatter& -Foam::vtk::formatter::endVTKFile() -{ - return endTag(vtk::fileTag::VTK_FILE); -} - - -Foam::vtk::formatter& -Foam::vtk::formatter::beginAppendedData() +Foam::vtk::formatter& Foam::vtk::formatter::beginAppendedData() { openTag("AppendedData"); xmlAttr("encoding", encoding()); @@ -195,31 +187,124 @@ Foam::vtk::formatter::beginAppendedData() } -Foam::vtk::formatter& -Foam::vtk::formatter::endAppendedData() +Foam::vtk::formatter& Foam::vtk::formatter::endAppendedData() { - flush(); // flush any pending encoded content - os_ << nl; // ensure clear separation from content. + flush(); // Flush any pending encoded content + os_ << nl; // Ensure clear separation from content return endTag("AppendedData"); } -Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +Foam::vtk::formatter& Foam::vtk::formatter::beginBlock ( - const word& k, - const std::string& v, - const char quote + label index, + std::string name ) { - if (!inTag_) + openTag(vtk::fileTag::BLOCK); + if (index >= 0) { - WarningInFunction - << "xml attribute '" << k << "' but not within a tag!" - << endl; + xmlAttr("index", index); } + if (name.size()) + { + xmlAttr("name", name); + } + closeTag(); - os_ << ' ' << k << '=' << quote << v.c_str() << quote; + return *this; +} + + +Foam::vtk::formatter& Foam::vtk::formatter::beginPiece +( + label index, + std::string name +) +{ + openTag(vtk::fileTag::PIECE); + if (index >= 0) + { + xmlAttr("index", index); + } + if (name.size()) + { + xmlAttr("name", name); + } + closeTag(); + + return *this; +} + + +Foam::vtk::formatter& Foam::vtk::formatter::DataSet +( + label index, + std::string file, + bool autoName +) +{ + openTag(vtk::fileTag::DATA_SET); + + if (index >= 0) + { + xmlAttr("index", index); + } + if (file.size()) + { + if (autoName) + { + xmlAttr("name", fileName::nameLessExt(file)); + } + xmlAttr("file", file); + } + closeTag(true); // Empty tag. ie, + + return *this; +} + + +Foam::vtk::formatter& Foam::vtk::formatter::DataSet +( + label index, + std::string file, + std::string name +) +{ + openTag(vtk::fileTag::DATA_SET); + + if (index >= 0) + { + xmlAttr("index", index); + } + if (name.size()) + { + xmlAttr("name", name); + } + if (file.size()) + { + xmlAttr("file", file); + } + closeTag(true); // Empty tag. ie, + + return *this; +} + + +Foam::vtk::formatter& Foam::vtk::formatter::writeTimeValue(scalar timeValue) +{ + // Emit "TimeValue" as FieldData + // NumberOfTuples="1" (required!) + + uint64_t payLoad = vtk::sizeofData(1); + + beginDataArray("TimeValue"); + writeSize(payLoad); + + write(timeValue); + flush(); + + endDataArray(); return *this; } diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.H b/src/fileFormats/vtk/format/foamVtkFormatter.H index c3e9c91638..ef423c10cc 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkFormatter.H @@ -27,7 +27,8 @@ Class Description Abstract class for a VTK output stream formatter. - Includes very simple support for writing XML elements. + Includes simple support for writing XML elements. + By default uses single-quoting for XML attributes. SourceFiles foamVtkFormatter.C @@ -39,8 +40,9 @@ SourceFiles #define foamVtkFormatter_H #include "int.H" -#include "uint64.H" #include "label.H" +#include "uint64.H" +#include "direction.H" #include "word.H" #include "UList.H" #include "DynamicList.H" @@ -59,11 +61,23 @@ namespace vtk class outputOptions; /*---------------------------------------------------------------------------*\ - Class formatter Declaration + Class vtk::formatter Declaration \*---------------------------------------------------------------------------*/ class formatter { +public: + + //- Quoting for XML attributes + enum quoteChar : char + { + DOUBLE_QUOTE = '\"', //!< Double-quote XML attributes + SINGLE_QUOTE = '\'', //!< Single-quote XML attributes + }; + + +protected: + // Private Data //- The output stream for the formatter @@ -75,33 +89,60 @@ class formatter //- Tag open/closed/ended state mutable bool inTag_; - - // Private Member Functions - - //- Write XML attribute key/value pair - template - formatter& writeAttribute - ( - const word& k, - const Type& v, - const char quote = '\'' - ); + //- Quoting character for XML attributes + char quote_; protected: // Protected Member Functions + //- Can write XML key/value attribute pair when inside a tag. + //- Emit warning and return false if this condition is not met. + bool canWriteAttr(const word& k) const; + + //- Can write tag-like top-level content (eg, comment, ...) + //- when not already inside a tag. + //- Emit warning and return false if this condition is not met. + bool canWriteToplevel(const char* what) const; + + //- Write XML key/value attribute pair (implementation). + template + inline void writeAttr(const word& k, const Type& v); + + //- No-op write XML attribute (for templating code). + // \return formatter for chaining + inline formatter& xmlAttr(); + + //- No-op XML comment loop (for templating code). + inline void xmlCommentLoop(); + + //- Loop/output XML comments + template + inline void xmlCommentLoop(const std::string& text, Args&&... args); + + //- Open XML tag (implementation), checking if not already inside + //- another tag. + //- Emit warning and return false if this condition is not met. + bool openTagImpl(const word& tagName); + + + // Constructors + //- Construct and attach to an output stream inline formatter(std::ostream& os); + public: // Public typedefs - //- Use UInt64 for header data + //- The header data is vtk UInt64 typedef uint64_t headerType; + //- Out of range position or size. + static constexpr uint64_t npos = uint64_t(-1); + //- Destructor virtual ~formatter() = default; @@ -123,9 +164,23 @@ public: //- Name for the XML append encoding virtual const char* encoding() const = 0; + //- Change quoting char for XML attributes (default: SINGLE_QUOTE) + void quoting(const quoteChar quote); + + //- Increase the append data offset by numbytes and sizeof(uint64_t). + // The additional (uint64_t) size information is consistent with + // writeSize() + // + // \return The previous data offset or formatter::npos for formats + // that do not support appending data. + virtual uint64_t offset(const uint64_t numbytes); + + //- The encoded length for binary output is pass-through. + virtual std::size_t encodedLength(std::size_t n) const; //- Write leading size for binary output - virtual void writeSize(const uint64_t nBytes) = 0; + // \return True if used by the formatter. + virtual bool writeSize(const uint64_t numbytes) = 0; virtual void write(const uint8_t val) = 0; virtual void write(const label val) = 0; @@ -135,61 +190,65 @@ public: //- Flush encoding, write newline etc. virtual void flush() = 0; - //- The encoded length for binary output. - // The default is pass-through. - virtual std::size_t encodedLength(std::size_t n) const; + // General Output - // Member Functions + //- Add indenting according to the current XML tag depth + // Two spaces per depth. + inline void indent(); - // Output - - //- Indent according to the currently nested XML tags - void indent(); + //- Add indenting of n spaces. + inline void indent(label n); //- Write XML header // \return formatter for chaining - formatter& xmlHeader(); + inline formatter& xmlHeader(); //- Write XML comment (at the current indentation level) // \return formatter for chaining - formatter& xmlComment(const std::string& comment); + template + inline formatter& xmlComment(const std::string& text, Args&&... args); - //- Open XML tag + //- Start an XML tag, optionally with attributes // \return formatter for chaining - formatter& openTag(const word& tagName); + template + inline formatter& openTag(const word& tagName, Args&&... args); - //- Open XML tag + //- Start an XML tag, optionally with attributes // \return formatter for chaining - inline formatter& openTag(const vtk::fileTag& tagEnum); + template + inline formatter& openTag(vtk::fileTag t, Args&&... args); - //- Close XML tag, optional as an empty container. + //- Finish an XML tag, optional as an empty container. // Always adds a trailing newline. // \return formatter for chaining formatter& closeTag(const bool isEmpty = false); - //- End XML tag, optional with sanity check + //- An end XML tag, optional with sanity check // Always adds a trailing newline. // \return formatter for chaining formatter& endTag(const word& tagName = word::null); - //- End XML tag with sanity check + //- An end XML tag with sanity check // Always adds a trailing newline. // \return formatter for chaining - inline formatter& endTag(const vtk::fileTag& tagEnum); + inline virtual formatter& endTag(vtk::fileTag t); //- Write XML tag without any attributes. Combines openTag/closeTag. // \return formatter for chaining - inline formatter& tag(const word& tagName); + template + inline formatter& tag(const word& t, Args&&... args); //- Write XML tag without any attributes. Combines openTag/closeTag. // \return formatter for chaining - inline formatter& tag(const vtk::fileTag& tagEnum); + template + inline formatter& tag(vtk::fileTag t, Args&&... args); + //- Add a "VTKFile" XML tag for contentType, followed by a tag for - // the contentType itself. Optionally leave the contentType tag - // open for adding additional attributes. + //- the contentType itself. + // \param leaveOpen Leave tag open for additional attributes. // \return formatter for chaining formatter& beginVTKFile ( @@ -199,127 +258,300 @@ public: ); //- Add a "VTKFile" XML tag for contentType, followed by a tag for - // the contentType itself. Optionally leave the contentType tag - // open for adding additional attributes. + //- the contentType itself. + // \param leaveOpen Leave tag open for additional attributes. // \return formatter for chaining inline formatter& beginVTKFile ( - const vtk::fileTag& contentType, + vtk::fileTag contentType, const word& contentVersion, const bool leaveOpen = false ); + //- Add a "VTKFile" XML tag for contentType, followed by a tag for + //- the contentType itself. + // \param leaveOpen Leave tag open for additional attributes. + // \return formatter for chaining + inline formatter& beginVTKFile + ( + vtk::fileTag contentType, + const bool leaveOpen = false + ); + + //- Add a "VTKFile" XML tag for contentType, followed by a tag for + //- the contentType itself. + // \param leaveOpen Leave tag open for additional attributes. + // \return formatter for chaining + template + inline formatter& beginVTKFile(bool leaveOpen = false); + //- Add a "AppendedData" XML tag with the current encoding and output - // the requisite '_' prefix. + //- the requisite '_' prefix. // \return formatter for chaining formatter& beginAppendedData(); - - //- Open "DataArray" XML tag + //- Begin "Block" XML section. + // \param index The index of the block + // \param name The name of the block (ignored if empty) // \return formatter for chaining - template - formatter& openDataArray(const word& dataName); + formatter& beginBlock(label index, std::string name = ""); - //- Open "DataArray" XML tag + //- End "Block" XML section. // \return formatter for chaining - template - formatter& openDataArray(const vtk::dataArrayAttr& attrEnum); + inline formatter& endBlock(); + //- Begin "Piece" XML section. + // \param index The index of the piece + // \param name The name of the piece (ignored if empty) + // \return formatter for chaining + formatter& beginPiece(label index, std::string name = ""); + + //- End "Piece" XML section. + // \return formatter for chaining + inline virtual formatter& endPiece(); + + //- Insert a single "DataSet" XML entry tag. + // \param index The index of the DataSet + // \param file The file name for the data (ignored if empty) + // \param autoName The name for the data extracted from the file name + // (without extension) + // \return formatter for chaining + formatter& DataSet + ( + label index, + std::string file = "", + bool autoName = true + ); + + //- Insert a single "DataSet" XML entry tag. + // \param index The index of the DataSet + // \param file The file name for the data (ignored if empty) + // \param name The name for the dataset + // \return formatter for chaining + formatter& DataSet + ( + label index, + std::string file, + std::string name + ); + + //- Begin "DataArray" XML section. + // + // \param dataName The name of the DataArray + // \param payLoad Additional payLoad information to increment + // the offset for an append formatter and add the "offset" + // attribute accordingly. + // \param leaveOpen Leave tag open for additional attributes. + // + // \return formatter for chaining + template + formatter& beginDataArray + ( + const word& dataName, + uint64_t payLoad = npos, + bool leaveOpen = false + ); + + //- Begin "DataArray" XML section. + // + // \param dataName The name of the DataArray as an enumeration + // \param payLoad Additional payLoad information to increment + // the offset for an append formatter and add the "offset" + // attribute accordingly. + // \param leaveOpen Leave tag open for additional attributes. + // + // \return formatter for chaining + template + inline formatter& beginDataArray + ( + const vtk::dataArrayAttr& dataName, + uint64_t payLoad = npos, + bool leaveOpen = false + ); + + //- End "DataArray" XML section + // \return formatter for chaining + inline virtual formatter& endDataArray(); //- Insert a single "PDataArray" XML entry tag. // For some entries, the name is optional. // \return formatter for chaining - template + template formatter& PDataArray(const word& dataName); - //- End "DataArray" XML tag - // \return formatter for chaining - inline formatter& endDataArray(); + //- Begin "FieldData" XML section. + inline formatter& beginFieldData(); - //- End "AppendedData" XML tag + //- Begin "CellData" XML section. + inline formatter& beginCellData(); + + //- Begin "PointData" XML section. + inline formatter& beginPointData(); + + //- End "FieldData" XML section. + inline virtual formatter& endFieldData(); + + //- End "CellData" XML section. + inline virtual formatter& endCellData(); + + //- End "PointData" XML section. + inline virtual formatter& endPointData(); + + + //- End "AppendedData" XML section // \return formatter for chaining formatter& endAppendedData(); - //- End "VTKFile" XML tag + //- End "VTKFile" XML section. // \return formatter for chaining - formatter& endVTKFile(); + inline virtual formatter& endVTKFile(); - //- Write XML attribute + //- Emit "TimeValue" for FieldData (name as per Catalyst output) + formatter& writeTimeValue(scalar timeValue); + + + // XML Attributes + + //- Pair-wise write of XML key/value attributes // \return formatter for chaining - formatter& xmlAttr + template + inline formatter& xmlAttr ( const word& k, const std::string& v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( const word& k, const int32_t v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( const word& k, const int64_t v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( const word& k, const uint64_t v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( const word& k, const scalar v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, + const std::string& v, + Args&&... args + ); + + //- Pair-wise write of XML key/value attributes + // \return formatter for chaining + template + inline formatter& xmlAttr + ( + const vtk::fileAttr& k, const int32_t v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, const int64_t v, - const char quote = '\'' + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template inline formatter& xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, const uint64_t v, - const char quote = '\'' + Args&&... args ); + + //- Pair-wise write of XML key/value attributes + // \return formatter for chaining + template + inline formatter& xmlAttr + ( + const vtk::fileAttr& k, + const scalar v, + Args&&... args + ); + + + // Housekeeping + + //- Open "DataArray" XML tag and leave open (requires a closeTag). + // \deprecated Use beginDataArray instead (SEPT-2018) + template + formatter& openDataArray(const word& dataName) + { + return beginDataArray + ( + dataName, formatter::npos, true + ); + } + + //- Open "DataArray" XML tag and leave open (requires a closeTag). + // \deprecated Use beginDataArray instead (SEPT-2018) + template + formatter& openDataArray(const vtk::dataArrayAttr& dataName) + { + return beginDataArray + ( + dataName, formatter::npos, true + ); + } + }; +// Global Functions + +//- Commonly used calculation for header and payload sizes +template +inline uint64_t sizeofData(label count) +{ + return (count * nComp * sizeof(Type)); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace vtk diff --git a/src/fileFormats/vtk/format/foamVtkFormatterI.H b/src/fileFormats/vtk/format/foamVtkFormatterI.H index 58e050bf54..bf3204c388 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatterI.H +++ b/src/fileFormats/vtk/format/foamVtkFormatterI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,13 +23,43 @@ License \*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr() +{ + return *this; +} + + +inline void Foam::vtk::formatter::xmlCommentLoop() +{} + + +template +inline void Foam::vtk::formatter::xmlCommentLoop +( + const std::string& text, + Args&&... args +) +{ + if (text.length()) + { + indent(); indent(4); + os_ << text << nl; + } + + xmlCommentLoop(std::forward(args)...); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // inline Foam::vtk::formatter::formatter(std::ostream& os) : os_(os), xmlTags_(), - inTag_(false) + inTag_(false), + quote_(SINGLE_QUOTE) {} @@ -41,43 +71,124 @@ inline std::ostream& Foam::vtk::formatter::os() } -inline Foam::vtk::formatter& -Foam::vtk::formatter::openTag(const vtk::fileTag& tagEnum) +inline void Foam::vtk::formatter::indent() { - return openTag(vtk::fileTagNames[tagEnum]); + indent(2*xmlTags_.size()); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::endTag(const vtk::fileTag& tagEnum) +inline void Foam::vtk::formatter::indent(label n) { - return endTag(vtk::fileTagNames[tagEnum]); + while (n-- > 0) + { + os_ << ' '; + } } -inline Foam::vtk::formatter& -Foam::vtk::formatter::tag(const word& tagName) +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlHeader() { - openTag(tagName); + if (canWriteToplevel("xml header")) + { + os_ << "" << nl; + } + + return *this; +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlComment +( + const std::string& text, + Args&&... args +) +{ + if (canWriteToplevel("xml comment")) + { + indent(); + os_ << "" << nl; + } + + return *this; +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::openTag +( + const word& tagName, + Args&&... args +) +{ + if (openTagImpl(tagName)) + { + xmlAttr(std::forward(args)...); + } + + return *this; +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::openTag +( + vtk::fileTag t, + Args&&... args +) +{ + return openTag(vtk::fileTagNames[t], std::forward(args)...); +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::tag +( + const word& t, + Args&&... args +) +{ + openTagImpl(t); + xmlAttr(std::forward(args)...); closeTag(); return *this; } -inline Foam::vtk::formatter& -Foam::vtk::formatter::tag(const vtk::fileTag& tagEnum) +template +inline Foam::vtk::formatter& Foam::vtk::formatter::tag +( + vtk::fileTag t, + Args&&... args +) { - return tag(vtk::fileTagNames[tagEnum]); + return tag(vtk::fileTagNames[t], std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::beginVTKFile +// Begin tags + +inline Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile ( - const vtk::fileTag& contentType, + vtk::fileTag contentType, const word& contentVersion, - const bool leaveOpen + bool leaveOpen ) { return beginVTKFile @@ -89,94 +200,275 @@ Foam::vtk::formatter::beginVTKFile } -inline Foam::vtk::formatter& -Foam::vtk::formatter::endDataArray() +inline Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile +( + vtk::fileTag contentType, + bool leaveOpen +) { - return endTag("DataArray"); + return beginVTKFile + ( + vtk::fileTagNames[contentType], + vtk::fileContentVersions[contentType], + leaveOpen + ); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile(bool leaveOpen) +{ + return beginVTKFile + ( + vtk::fileTagNames[ContentType], + vtk::fileContentVersions[ContentType], + leaveOpen + ); +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::beginDataArray +( + const vtk::dataArrayAttr& dataName, + uint64_t payLoad, + bool leaveOpen +) +{ + return + beginDataArray + ( + vtk::dataArrayAttrNames[dataName], + payLoad, + leaveOpen + ); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::beginCellData() +{ + return tag(vtk::fileTag::CELL_DATA); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::beginPointData() +{ + return tag(vtk::fileTag::POINT_DATA); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::beginFieldData() +{ + return tag(vtk::fileTag::FIELD_DATA); +} + + +// End tags + +inline Foam::vtk::formatter& Foam::vtk::formatter::endTag(vtk::fileTag t) +{ + return endTag(vtk::fileTagNames[t]); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endCellData() +{ + return endTag(vtk::fileTag::CELL_DATA); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endPointData() +{ + return endTag(vtk::fileTag::POINT_DATA); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endFieldData() +{ + return endTag(vtk::fileTag::FIELD_DATA); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endDataArray() +{ + return endTag(vtk::fileTag::DATA_ARRAY); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endBlock() +{ + return endTag(vtk::fileTag::BLOCK); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endPiece() +{ + return endTag(vtk::fileTag::PIECE); +} + + +inline Foam::vtk::formatter& Foam::vtk::formatter::endVTKFile() +{ + return endTag(vtk::fileTag::VTK_FILE); +} + + +// Attributes + +template +inline void Foam::vtk::formatter::writeAttr(const word& k, const Type& v) +{ + os_ << ' ' << k << '=' << quote_ << v << quote_; +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr +( + const word& k, + const std::string& v, + Args&&... args +) +{ + if (!canWriteAttr(k)) return *this; + + writeAttr(k, v.c_str()); + return xmlAttr(std::forward(args)...); +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( const word& k, const int32_t v, - const char quote + Args&&... args ) { - return writeAttribute(k, v, quote); + if (!canWriteAttr(k)) return *this; + + writeAttr(k, v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( const word& k, const int64_t v, - const char quote + Args&&... args ) { - return writeAttribute(k, v, quote); + if (!canWriteAttr(k)) return *this; + + writeAttr(k, v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( const word& k, const uint64_t v, - const char quote + Args&&... args ) { - return writeAttribute(k, v, quote); + if (!canWriteAttr(k)) return *this; + + writeAttr(k, v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( const word& k, const scalar v, - const char quote + Args&&... args ) { - return writeAttribute(k, v, quote); + if (!canWriteAttr(k)) return *this; + + writeAttr(k, v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, + const std::string& v, + Args&&... args +) +{ + if (!canWriteAttr(vtk::fileAttrNames[k])) return *this; + + writeAttr(vtk::fileAttrNames[k], v.c_str()); + return xmlAttr(std::forward(args)...); +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr +( + const vtk::fileAttr& k, const int32_t v, - const char quote + Args&&... args ) { - return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); + if (!canWriteAttr(vtk::fileAttrNames[k])) return *this; + + writeAttr(vtk::fileAttrNames[k], v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, const int64_t v, - const char quote + Args&&... args ) { - return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); + if (!canWriteAttr(vtk::fileAttrNames[k])) return *this; + + writeAttr(vtk::fileAttrNames[k], v); + return xmlAttr(std::forward(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( - const vtk::fileAttr& attrEnum, + const vtk::fileAttr& k, const uint64_t v, - const char quote + Args&&... args ) { - return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); + if (!canWriteAttr(vtk::fileAttrNames[k])) return *this; + + writeAttr(vtk::fileAttrNames[k], v); + return xmlAttr(std::forward(args)...); +} + + +template +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr +( + const vtk::fileAttr& k, + const scalar v, + Args&&... args +) +{ + if (!canWriteAttr(vtk::fileAttrNames[k])) return *this; + + writeAttr(vtk::fileAttrNames[k], v); + return xmlAttr(std::forward(args)...); } diff --git a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C index 87f4f9131b..215d8bcb7d 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C +++ b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,75 +26,66 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -template -Foam::vtk::formatter& -Foam::vtk::formatter::writeAttribute +template +Foam::vtk::formatter& Foam::vtk::formatter::beginDataArray ( - const word& k, - const Type& v, - const char quote + const word& dataName, + uint64_t payLoad, + bool leaveOpen ) { - if (!inTag_) - { - WarningInFunction - << "xml attribute '" << k << "' but not within a tag!" - << endl; - } - - os_ << ' ' << k << '=' << quote << v << quote; - - return *this; -} - - -template -Foam::vtk::formatter& -Foam::vtk::formatter::openDataArray -( - const word& dataName -) -{ - openTag("DataArray"); + openTag(vtk::fileTag::DATA_ARRAY); xmlAttr("type", vtkPTraits::typeName); xmlAttr("Name", dataName); + if (nComp > 1) { - xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, nComp); + xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, int(nComp)); + } + if (nTuple > 0) + { + xmlAttr(fileAttr::NUMBER_OF_TUPLES, nTuple); } xmlAttr("format", name()); + if (formatter::npos != payLoad) + { + uint64_t off = offset(payLoad); + if (formatter::npos != off) + { + xmlAttr("offset", off); + } + } + + if (!leaveOpen) + { + closeTag(); + } + return *this; } -template -Foam::vtk::formatter& -Foam::vtk::formatter::openDataArray -( - const vtk::dataArrayAttr& attrEnum -) -{ - return openDataArray(vtk::dataArrayAttrNames[attrEnum]); -} - - -template -Foam::vtk::formatter& -Foam::vtk::formatter::PDataArray +template +Foam::vtk::formatter& Foam::vtk::formatter::PDataArray ( const word& dataName ) { openTag("PDataArray"); xmlAttr("type", vtkPTraits::typeName); + if (dataName.size()) { xmlAttr("Name", dataName); } if (nComp > 1) { - xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, nComp); + xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, int(nComp)); + } + if (nTuple > 0) + { + xmlAttr(fileAttr::NUMBER_OF_TUPLES, nTuple); } closeTag(true); diff --git a/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H index e191d1eb93..9bfec2594c 100644 --- a/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,7 +46,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class legacyAsciiFormatter Declaration + Class vtk::legacyAsciiFormatter Declaration \*---------------------------------------------------------------------------*/ class legacyAsciiFormatter @@ -95,6 +95,17 @@ public: // Currently identical to name(), but do not rely on this. virtual const char* encoding() const; + + // Disable some XML-only methods + + inline virtual formatter& endTag(vtk::fileTag) { return *this; } + inline virtual formatter& endDataArray() { return *this; } + inline virtual formatter& endFieldData() { return *this; } + inline virtual formatter& endCellData() { return *this; } + inline virtual formatter& endPointData() { return *this; } + inline virtual formatter& endPiece() { return *this; } + inline virtual formatter& endVTKFile() { return *this; } + }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C index 18f6890404..85a78e91c8 100644 --- a/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C @@ -80,11 +80,10 @@ const char* Foam::vtk::legacyRawFormatter::encoding() const } -void Foam::vtk::legacyRawFormatter::writeSize -( - const uint64_t ignored -) -{/*nop*/} +bool Foam::vtk::legacyRawFormatter::writeSize(const uint64_t) +{ + return false; +} void Foam::vtk::legacyRawFormatter::write diff --git a/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H index ae88684b05..d37624c581 100644 --- a/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -48,7 +48,7 @@ namespace vtk { /*---------------------------------------------------------------------------*\ - Class legacyRawFormatter Declaration + Class vtk::legacyRawFormatter Declaration \*---------------------------------------------------------------------------*/ class legacyRawFormatter @@ -104,7 +104,8 @@ public: //- Write leading size - a no-op for legacy binary output - virtual void writeSize(const uint64_t ignored); + // \return False - never used by this format + virtual bool writeSize(const uint64_t ignored); virtual void write(const uint8_t val); virtual void write(const label val); @@ -114,6 +115,17 @@ public: //- Write a newline to the output virtual void flush(); + + // Disable some XML-only methods + + inline virtual formatter& endTag(vtk::fileTag) { return *this; } + inline virtual formatter& endDataArray() { return *this; } + inline virtual formatter& endFieldData() { return *this; } + inline virtual formatter& endCellData() { return *this; } + inline virtual formatter& endPointData() { return *this; } + inline virtual formatter& endPiece() { return *this; } + inline virtual formatter& endVTKFile() { return *this; } + }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/output/foamVtkOutput.C b/src/fileFormats/vtk/output/foamVtkOutput.C index 589537fd28..ea5f533cb6 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.C +++ b/src/fileFormats/vtk/output/foamVtkOutput.C @@ -33,34 +33,21 @@ License #include "foamVtkLegacyAsciiFormatter.H" #include "foamVtkLegacyRawFormatter.H" #include "typeInfo.H" +#include "globalIndex.H" #include "instant.H" - -// * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * * // - -const Foam::Enum -< - Foam::vtk::fileTag -> -Foam::vtk::legacy::contentNames -({ - { vtk::fileTag::POLY_DATA, "POLYDATA" }, - { vtk::fileTag::UNSTRUCTURED_GRID, "UNSTRUCTURED_GRID" }, -}); - - -const Foam::Enum -< - Foam::vtk::fileTag -> -Foam::vtk::legacy::dataTypeNames -({ - { vtk::fileTag::CELL_DATA, "CELL_DATA" }, - { vtk::fileTag::POINT_DATA, "POINT_DATA" } -}); - +#include "Fstream.H" +#include "Pstream.H" +#include "OSspecific.H" // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // +Foam::autoPtr +Foam::vtk::newFormatter(std::ostream& os, unsigned prec) +{ + return autoPtr::NewFrom(os, prec); +} + + Foam::autoPtr Foam::vtk::newFormatter ( @@ -102,14 +89,24 @@ Foam::vtk::newFormatter } -void Foam::vtk::writeSeries +void Foam::vtk::seriesInfo ( Ostream& os, - const word& prefix, - const word& suffix, - const UList& series + const fileName& base, + const UList& series, + const char sep ) { + // Split the base into (stem, ext) components + // + // base = "path/file.vtm" + // + // stem = "file" + // ext = ".vtm" + + const word stem = base.nameLessExt(); + const word ext = "." + base.ext(); + // Begin file-series (JSON) os << "{\n \"file-series-version\" : \"1.0\",\n \"files\" : [\n"; @@ -118,12 +115,12 @@ void Foam::vtk::writeSeries label nremain = series.size(); // Each entry - // { "name" : "name", "time" : value } + // { "name" : "name", "time" : value } for (const instant& inst : series) { os << " { \"name\" : \"" - << prefix << inst.name() << suffix + << stem << sep << inst.name() << ext << "\", \"time\" : " << inst.value() << " }"; if (--nremain) @@ -137,34 +134,207 @@ void Foam::vtk::writeSeries } -Foam::label Foam::vtk::writeVtmFile +void Foam::vtk::seriesWrite ( - std::ostream& os, - const UList& files + const fileName& base, + const UList& series, + const char sep ) { - asciiFormatter vtmFile(os); + mkDir(base.path()); - vtmFile - .xmlHeader() - .beginVTKFile(fileTagNames[vtk::fileTag::MULTI_BLOCK], "1.0"); + autoPtr osPtr = + ( + base.hasExt("series") + ? autoPtr::New(base) + : autoPtr::New(base + ".series") + ); - forAll(files, i) - { - vtmFile - .openTag(vtk::fileTag::DATA_SET) - .xmlAttr("index", i) - .xmlAttr("file", files[i]) - .closeTag(true); - } - - vtmFile.endTag(fileTagNames[vtk::fileTag::MULTI_BLOCK]).endVTKFile(); - - return files.size(); + seriesInfo(*osPtr, base, series, sep); } -std::ostream& Foam::vtk::legacy::fileHeader +Foam::fileName Foam::vtk::seriesBase +( + const fileName& outputName, + const char sep +) +{ + const auto dash = outputName.rfind(sep); + + // No separator? Or separator in path() instead of name()? + if + ( + std::string::npos == dash + || std::string::npos != outputName.find('/', dash) + ) + { + // Warn? + return outputName; + } + + const auto dot = outputName.find('.', dash); + + if (std::string::npos == dot) + { + return outputName.substr(0, dash); + } + + return outputName.substr(0, dash) + outputName.substr(dot); +} + + +void Foam::vtk::writeList +( + vtk::formatter& fmt, + const UList& values +) +{ + // No nComponents for char, so use fmt.write() directly + for (const uint8_t val : values) + { + fmt.write(val); + } +} + + +void Foam::vtk::writeListParallel +( + vtk::formatter& fmt, + const UList& values +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values); + + List recv; + + // Receive and write + for + ( + int slave=Pstream::firstSlave(); + slave<=Pstream::lastSlave(); + ++slave + ) + { + IPstream fromSlave(Pstream::commsTypes::blocking, slave); + + fromSlave >> recv; + + vtk::writeList(fmt, recv); + } + } + else + { + // Send to master + OPstream toMaster + ( + Pstream::commsTypes::blocking, + Pstream::masterNo() + ); + + toMaster << values; + } +} + + +void Foam::vtk::writeListParallel +( + vtk::formatter& fmt, + const labelUList& values, + const globalIndex& procOffset +) +{ + if (Pstream::master()) + { + // Write with offset + const label offsetId = procOffset.offset(0); + + for (const label val : values) + { + vtk::write(fmt, val + offsetId); + } + + labelList recv; + + // Receive and write + for + ( + int slave=Pstream::firstSlave(); + slave<=Pstream::lastSlave(); + ++slave + ) + { + IPstream fromSlave(Pstream::commsTypes::blocking, slave); + + fromSlave >> recv; + + const label offsetId = procOffset.offset(slave); + + // Write with offset + for (const label val : recv) + { + vtk::write(fmt, val + offsetId); + } + } + } + else + { + // Send to master + OPstream toMaster + ( + Pstream::commsTypes::blocking, + Pstream::masterNo() + ); + + toMaster << values; + } +} + + +// * * * * * * * * * * * * * * Legacy Functions * * * * * * * * * * * * * * // + + +void Foam::vtk::legacy::fileHeader +( + std::ostream& os, + const std::string& title, + bool binary +) +{ + // Line 1: + os << "# vtk DataFile Version 2.0" << nl; + + // Line 2: title + + const auto truncate = title.find('\n'); + + if (title.empty() || 0 == truncate) + { + // Avoid an empty title + + os << "File generated by OpenFOAM"; + #if OPENFOAM + os << ' ' << OPENFOAM; + #endif + os << nl; + } + else if (std::string::npos == truncate) + { + os << title << nl; + } + else + { + os << title.substr(0, truncate) << nl; + } + + // Line 3: format + os << (binary ? "BINARY" : "ASCII") << nl; +} + + +void Foam::vtk::legacy::fileHeader ( vtk::formatter& fmt, const std::string& title, @@ -173,13 +343,11 @@ std::ostream& Foam::vtk::legacy::fileHeader { std::ostream& os = fmt.os(); - fileHeader(os, title, isType(fmt)); - if (!contentType.empty()) + legacy::fileHeader(os, title, isType(fmt)); + if (contentType.size()) { os << "DATASET " << contentType.c_str() << nl; } - - return os; } diff --git a/src/fileFormats/vtk/output/foamVtkOutput.H b/src/fileFormats/vtk/output/foamVtkOutput.H index 2f4a0d2f7a..9cd5434847 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.H +++ b/src/fileFormats/vtk/output/foamVtkOutput.H @@ -44,6 +44,7 @@ SourceFiles #define foamVtkOutput_H #include "autoPtr.H" +#include "bitSet.H" #include "Enum.H" #include "foamVtkCore.H" #include "foamVtkFormatter.H" @@ -55,8 +56,10 @@ SourceFiles namespace Foam { + // Forward declarations class instant; +class globalIndex; namespace vtk { @@ -66,7 +69,11 @@ namespace vtk // General Functions //- Return a default asciiFormatter - autoPtr newFormatter(std::ostream& os); + autoPtr newFormatter + ( + std::ostream& os, + unsigned prec = IOstream::defaultPrecision() + ); //- Return a new formatter based on the specified format type autoPtr newFormatter @@ -77,22 +84,55 @@ namespace vtk ); - //- Write file series (JSON format) for specified time instances + //- Print file series (JSON format) for specified time instances // - // \param prefix before the \c instant.name() - // \param suffix after the \c instant.name() - // \param series the list of name/value entries - void writeSeries + // \param os The output stream + // \param base The name for the series (eg, "path/file.vtm") + // \param series The list of suffix/value entries + // \param sep The separator used between file stem and suffix. + void seriesInfo ( Ostream& os, - const word& prefix, - const word& suffix, - const UList& series + const fileName& base, + const UList& series, + const char sep = '_' ); - //- Write vtm datasets for specified files - label writeVtmFile(std::ostream& os, const UList& files); + //- Write file series (JSON format) to disk, for specified time instances + // + // \param base The name for the series (eg, "path/file.vtm") + // \param series The list of suffix/value entries + // \param sep The separator used between file stem and suffix. + void seriesWrite + ( + const fileName& base, + const UList& series, + const char sep = '_' + ); + //- Extract the base name for a file series + // + // \param outputName The name of the data output file + // Eg, "somefile_0001.vtm" would extract to "somefile.vtm" + // \param sep The separator used between file stem and suffix. + fileName seriesBase(const fileName& outputName, const char sep = '_'); + + + //- Write a list of uint8_t values. + // The output does not include the payload size. + void writeList + ( + vtk::formatter& fmt, + const UList& values + ); + + //- Write a list of uint8_t values. + // The output does not include the payload size. + void writeListParallel + ( + vtk::formatter& fmt, + const UList& values + ); //- Write a value component-wise. template @@ -109,7 +149,7 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const UList& list + const UList& values ); //- Write a list of values. @@ -118,7 +158,7 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const FixedList& list + const FixedList& values ); @@ -128,7 +168,88 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const UList& list, + const UList& values, + const labelUList& addressing + ); + + //- Write a list of values via indirect addressing. + // The output does not include the payload size. + template + void writeList + ( + vtk::formatter& fmt, + const UList& values, + const bitSet& selected + ); + + //- Write a list of values and a list of values via indirect addressing. + // The output does not include the payload size. + template + void writeLists + ( + vtk::formatter& fmt, + const UList& values1, + const UList& values2, + const labelUList& addressing + ); + + + //- Write a list of values. + // The output does not include the payload size. + template + void writeListParallel + ( + vtk::formatter& fmt, + const UList& values + ); + + //- Write a list of values, with constant per-processor offset + // The output does not include the payload size. + void writeListParallel + ( + vtk::formatter& fmt, + const UList