diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C index 605110940435ea50d4a5f85ca7cbb11678dd76ba..cbe2d515bc7d73d301146692382ea10800b7fd40 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 5b4181f55f751692545d54c5d6c3eaa18a636241..bd0e7202eade1a428d22febd3d462828fefbd9bf 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<nCmpt>(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<nCmpt>(format(), fldName, fld.size()); } else { diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.C b/src/conversion/vtk/output/foamVtkInternalWriter.C index 49bf062e8273aea0e407a27d7df3b77ccf93590f..4972f98ca12eb27e158d9e9ed8859f186841cc4d 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 77689e5ec7b8d37391168db0ae145d2e91955e88..b0177ade71fb1c825d924b177ce1157720f1c584 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<nCmpt>(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<nCmpt>(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<nCmpt>(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<nCmpt>(format(), vfield.name(), nVals); } else { diff --git a/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C b/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C index 74cb846a1b4db8d29465a5129d1e90e80d7d90c9..5136eb0bf51f21d6f35bac440cd2d6d24b1c96cf 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 18764148cd6cc6b351bb13ed71fd2450e5487fa3..3ca9500a84f87b11fb87fe35dd51cb3988526b38 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 9c77912499fce907fe916f401ee10ae7b1fe4ab7..0bc9602390497a4c501260c1c12e0891be1a5889 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<nCmpt>(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<nCmpt>(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<nCmpt>(format(), field.name(), nPoints_); } else { diff --git a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C index f5ba90efc171b7cb0a2e2946fae57e95429700d9..96b62ed9c78382e80afd84a014f1e47fe111f193 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 8b52dfc02f43eabaa09101f78522fb8cd6b4b862..c54d53f3dd0226479fdc9330b85ef680b2c983e8 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<nCmpt>(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<nCmpt>(format(), field.name(), pp_.size()); } else { diff --git a/src/conversion/vtk/output/foamVtkWriteSurfFields.C b/src/conversion/vtk/output/foamVtkWriteSurfFields.C index bfe1f35038153a731c738266c23fe83a473bd6f7..1742470dbf89c8a36351feafb47a6efc3d829602 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<nCmpt>(format(), fld.name(), mesh.nFaces()); } else { diff --git a/src/fileFormats/vtk/core/foamVtkCore.C b/src/fileFormats/vtk/core/foamVtkCore.C index 7a61ccb0345d2744588811d211e5ac534935a49b..c8b41b924c2de40b8e4925ab266918286e057976 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 8584c9672ceebb8655b6c6403ffcb5ccb85b3d81..88620ebc5c3c57a3e94a899fcfe8b53ee82a339d 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 <cstdint> #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<fileTag> fileExtension; + + //- Version string for some vtk XML file content types + extern const Foam::Enum<fileTag> fileContentVersions; + + //- Strings corresponding to the vtk XML tags extern const Foam::Enum<fileTag> 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<fileAttr> 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<dataArrayAttr> dataArrayAttrNames; +/*---------------------------------------------------------------------------*\ + Namespace legacy +\*---------------------------------------------------------------------------*/ + +namespace legacy +{ + + //- Legacy file extension ("vtk") + extern const word fileExtension; + + //- Legacy content names (POLYDATA, UNSTRUCTURED_GRID) + extern const Foam::Enum<vtk::fileTag> contentNames; + + //- Legacy data type names (CELL_DATA, POINT_DATA) + extern const Foam::Enum<vtk::fileTag> dataTypeNames; + +} // End namespace legacy + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace vtk diff --git a/src/fileFormats/vtk/core/foamVtkPTraits.C b/src/fileFormats/vtk/core/foamVtkPTraits.C index 0cc5ca04e49720ba33bc279637be951e5801f9ba..7a542257c8b6867617214ca5b48fe0e5684d1bf6 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<Foam::endian>::typeName = "BigEndian"; #endif +template<> +const char* const +Foam::vtkPTraits<std::string>::typeName = "String"; + // ************************************************************************* // diff --git a/src/fileFormats/vtk/core/foamVtkPTraits.H b/src/fileFormats/vtk/core/foamVtkPTraits.H index ac8df0664659fe746c0c1b32e286aca89f2975e1..b40375f1fb277886b88771d3e6581e89fa7dd2dd 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 <cstdint> +#include <string> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -47,13 +48,10 @@ class endian; \*---------------------------------------------------------------------------*/ template<class PrimitiveType> -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<double>::typeName; // Float64 template<> const char* const vtkPTraits<Foam::endian>::typeName; // (Big|Little)Endian +template<> +const char* const vtkPTraits<std::string>::typeName; // String + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C index 5527e5c35aefc28cc4ce9d9bbc34fae72e434002..334241b2f1842b4ca70628510fefbb248eff7d24 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 2384289f679b37e2f702606f71b1fdae1782c8c9..6f3814a22ac6abc5ec01b42db69627752fd47dbb 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 f8b7bcf29fd6c660ce1396628b9b68680a911039..c7e2783c5e69e62dae2875897ca5615846cf7f7b 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<const char*>(&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<const char*>(&numbytes), sizeof(uint64_t)); + return true; } diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H index dbbcf0788ae8f008a22871ba2d530306bac990e7..fc05f9249c446c4e1a8577f78cf2f8df2a89c683 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 d220627ab7182a8b2e659add37f0ee34c1ae4b24..fa549ff24a2b7999b6ed2845a061b910b13a6940 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 b050d6573c31ba01f348e0bfe99b3b6d1c4fac18..25d7fc7f380122046ed3a4fe6c89b9476b3cc154 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 cd733e643e5d6388ae385fce3bed1936cef50532..9b96c1ac719891379aca65695fbef4e00f37e18e 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 fbdc7ad5257203ae75a0ead3919a00e4cb21789e..8cbfbc2c01ffcaf7de691b984265ab5b3bc01375 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<const char*>(&nBytes), sizeof(uint64_t)); + write(reinterpret_cast<const char*>(&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 d965c6348ddb176ba3c2328b9036857c48cac301..3805a57747af2b4b4c458ad354ed0c68c4382954 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 711bcdecd248278378b5df3a9b9b1c4d32f26b5f..c6b2a4e56f70604b6f6246eabce354ffffa46d26 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkFormatter.C @@ -24,104 +24,103 @@ License #include "foamVtkFormatter.H" -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -std::size_t Foam::vtk::formatter::encodedLength(std::size_t n) const -{ - return n; -} +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // - -void Foam::vtk::formatter::indent() +bool Foam::vtk::formatter::canWriteAttr(const word& k) const { - label n = xmlTags_.size() * 2; - while (n--) + if (!inTag_) { - os_ << ' '; + WarningInFunction + << "xml attribute '" << k << "' but not inside a tag!" << endl; } + + return inTag_; } -Foam::vtk::formatter& -Foam::vtk::formatter::xmlHeader() +bool Foam::vtk::formatter::canWriteToplevel(const char* what) const { if (inTag_) { WarningInFunction - << "xml header, but already within a tag!" + << "Cannot add " << what << " inside a tag!" << endl; } - os_ << "<?xml version='1.0'?>" << nl; + return !inTag_; +} - return *this; + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::vtk::formatter::quoting(const quoteChar quote) +{ + quote_ = quote; } -Foam::vtk::formatter& -Foam::vtk::formatter::xmlComment(const std::string& comment) +uint64_t Foam::vtk::formatter::offset(const uint64_t) { - if (inTag_) - { - WarningInFunction - << "adding xml comment inside a tag??" - << endl; - } + return formatter::npos; +} - indent(); - os_ << "<!-- " << comment << " -->" << nl; - return *this; +std::size_t Foam::vtk::formatter::encodedLength(std::size_t n) const +{ + return n; } -Foam::vtk::formatter& -Foam::vtk::formatter::openTag(const word& tagName) +bool Foam::vtk::formatter::openTagImpl(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, <tag ... /> - xmlTags_.remove(); - os_ << " /"; + // Change the state + inTag_ = false; + + if (isEmpty) + { + // Eg, <tag ... /> + xmlTags_.remove(); + os_ << " /"; + } + os_ << '>' << nl; } - os_ << '>' << nl; - - inTag_ = false; 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(); + + 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, <DataSet ... /> + + 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, <DataSet ... /> + + return *this; +} + + +Foam::vtk::formatter& Foam::vtk::formatter::writeTimeValue(scalar timeValue) +{ + // Emit "TimeValue" as FieldData + // NumberOfTuples="1" (required!) + + uint64_t payLoad = vtk::sizeofData<float>(1); + + beginDataArray<float,1,1>("TimeValue"); + writeSize(payLoad); + + write(timeValue); + flush(); - os_ << ' ' << k << '=' << quote << v.c_str() << quote; + endDataArray(); return *this; } diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.H b/src/fileFormats/vtk/format/foamVtkFormatter.H index c3e9c916386ff62e8c0a0df92917760706d71e19..ef423c10cc26a18ec80ab790e0f2d68496ecca51 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_; + //- Quoting character for XML attributes + char quote_; + - // Private Member Functions +protected: + + // Protected Member Functions - //- Write XML attribute key/value pair + //- 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<class Type> - formatter& writeAttribute - ( - const word& k, - const Type& v, - const char quote = '\'' - ); + inline void writeAttr(const word& k, const Type& v); + //- No-op write XML attribute (for templating code). + // \return formatter for chaining + inline formatter& xmlAttr(); -protected: + //- No-op XML comment loop (for templating code). + inline void xmlCommentLoop(); - // Protected Member Functions + //- Loop/output XML comments + template<class... Args> + 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; - - // Member Functions + // General Output - // Output + //- Add indenting according to the current XML tag depth + // Two spaces per depth. + inline void indent(); - //- 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<class... Args> + 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<class... Args> + 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<class... Args> + 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<class... Args> + 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<class... Args> + 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<vtk::fileTag ContentType> + 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(); + //- 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 + formatter& beginBlock(label index, std::string name = ""); + + //- End "Block" XML section. + // \return formatter for chaining + 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(); - //- Open "DataArray" XML tag + //- 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 - template<class Type, int nComp=0> - formatter& openDataArray(const word& dataName); + formatter& DataSet + ( + label index, + std::string file = "", + bool autoName = true + ); - //- Open "DataArray" XML tag + //- 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 - template<class Type, int nComp=0> - formatter& openDataArray(const vtk::dataArrayAttr& attrEnum); + 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<class Type, direction nComp=1, int nTuple=0> + 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<class Type, direction nComp=1, int nTuple=0> + 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<class Type, int nComp=0> + template<class Type, direction nComp=1, int nTuple=0> formatter& PDataArray(const word& dataName); - //- End "DataArray" XML tag - // \return formatter for chaining - inline formatter& endDataArray(); + //- Begin "FieldData" XML section. + inline formatter& beginFieldData(); + + //- 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 tag + //- 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<class... Args> + 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<class... Args> 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<class... Args> 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<class... Args> 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<class... Args> inline formatter& xmlAttr ( const word& k, const scalar v, - const char quote = '\'' + Args&&... args + ); + + //- Pair-wise write of XML key/value attributes + // \return formatter for chaining + template<class... Args> + inline formatter& xmlAttr + ( + const vtk::fileAttr& k, + const std::string& v, + Args&&... args ); - //- Write XML attribute + //- Pair-wise write of XML key/value attributes // \return formatter for chaining + template<class... Args> inline formatter& xmlAttr ( - const vtk::fileAttr& attrEnum, + 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<class... Args> 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<class... Args> 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<class... Args> + 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<class Type, direction nComp=1, int nTuple=0> + formatter& openDataArray(const word& dataName) + { + return beginDataArray<Type, nComp, nTuple> + ( + dataName, formatter::npos, true + ); + } + + //- Open "DataArray" XML tag and leave open (requires a closeTag). + // \deprecated Use beginDataArray instead (SEPT-2018) + template<class Type, direction nComp=1, int nTuple=0> + formatter& openDataArray(const vtk::dataArrayAttr& dataName) + { + return beginDataArray<Type, nComp, nTuple> + ( + dataName, formatter::npos, true + ); + } + }; +// Global Functions + +//- Commonly used calculation for header and payload sizes +template<class Type, direction nComp=1> +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 58e050bf54223b03609bab01eff9afe9f385e85a..bf3204c388a505f28a5a4432bede3c026ffa0fd1 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<class... Args> +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>(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_ << "<?xml version='1.0'?>" << nl; + } + + return *this; +} + + +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlComment +( + const std::string& text, + Args&&... args +) +{ + if (canWriteToplevel("xml comment")) + { + indent(); + os_ << "<!--"; + + if (sizeof...(Args)) + { + os_ << nl; + + xmlCommentLoop(text, std::forward<Args>(args)...); + + indent(); indent(2); + } + else + { + os_ << ' ' << text << ' '; + } + + os_ << "-->" << nl; + } + + return *this; +} + + +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::openTag +( + const word& tagName, + Args&&... args +) +{ + if (openTagImpl(tagName)) + { + xmlAttr(std::forward<Args>(args)...); + } + + return *this; +} + + +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::openTag +( + vtk::fileTag t, + Args&&... args +) +{ + return openTag(vtk::fileTagNames[t], std::forward<Args>(args)...); +} + + +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::tag +( + const word& t, + Args&&... args +) +{ + openTagImpl(t); + xmlAttr(std::forward<Args>(args)...); closeTag(); return *this; } -inline Foam::vtk::formatter& -Foam::vtk::formatter::tag(const vtk::fileTag& tagEnum) +template<class... Args> +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>(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 beginVTKFile + ( + vtk::fileTagNames[contentType], + vtk::fileContentVersions[contentType], + leaveOpen + ); +} + + +template<Foam::vtk::fileTag ContentType> +inline Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile(bool leaveOpen) +{ + return beginVTKFile + ( + vtk::fileTagNames[ContentType], + vtk::fileContentVersions[ContentType], + leaveOpen + ); +} + + +template<class Type, Foam::direction nComp, int nTuple> +inline Foam::vtk::formatter& Foam::vtk::formatter::beginDataArray +( + const vtk::dataArrayAttr& dataName, + uint64_t payLoad, + bool leaveOpen +) +{ + return + beginDataArray<Type, nComp, nTuple> + ( + 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("DataArray"); + return endTag(vtk::fileTag::CELL_DATA); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +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<class Type> +inline void Foam::vtk::formatter::writeAttr(const word& k, const Type& v) +{ + os_ << ' ' << k << '=' << quote_ << v << quote_; +} + + +template<class... Args> +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>(args)...); +} + + +template<class... Args> +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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +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>(args)...); +} + + +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr +( + 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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr ( - const vtk::fileAttr& attrEnum, + 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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +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>(args)...); } -inline Foam::vtk::formatter& -Foam::vtk::formatter::xmlAttr +template<class... Args> +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>(args)...); +} + + +template<class... Args> +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>(args)...); } diff --git a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C index 87f4f9131b50ccfdc3fb37088d95c240e57a147e..215d8bcb7d9d7fb0c33d586d8d291e2dc6b59717 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<class Type> -Foam::vtk::formatter& -Foam::vtk::formatter::writeAttribute +template<class Type, Foam::direction nComp, int nTuple> +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<class Type, int nComp> -Foam::vtk::formatter& -Foam::vtk::formatter::openDataArray -( - const word& dataName -) -{ - openTag("DataArray"); + openTag(vtk::fileTag::DATA_ARRAY); xmlAttr("type", vtkPTraits<Type>::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()); - return *this; -} + if (formatter::npos != payLoad) + { + uint64_t off = offset(payLoad); + if (formatter::npos != off) + { + xmlAttr("offset", off); + } + } + if (!leaveOpen) + { + closeTag(); + } -template<class Type, int nComp> -Foam::vtk::formatter& -Foam::vtk::formatter::openDataArray -( - const vtk::dataArrayAttr& attrEnum -) -{ - return openDataArray<Type, nComp>(vtk::dataArrayAttrNames[attrEnum]); + return *this; } -template<class Type, int nComp> -Foam::vtk::formatter& -Foam::vtk::formatter::PDataArray +template<class Type, Foam::direction nComp, int nTuple> +Foam::vtk::formatter& Foam::vtk::formatter::PDataArray ( const word& dataName ) { openTag("PDataArray"); xmlAttr("type", vtkPTraits<Type>::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 e191d1eb937561ae4fe7c055f5cb0c6c177347f3..9bfec2594cba3045b6747d6690fbeba71f69192c 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 18f6890404c779af14494c5d490eb0a9360ef221..85a78e91c8a815a0477078e126db9d633b5cd97d 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 ae88684b052675aa32a56fbc2a0c8bed2a6938ff..d37624c581febe7891a4e7206b297462f691ced1 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 589537fd286b0cca87398a032492cf4c2494eb5c..ea5f533cb6771cc439ee10cbeae762dd5d4f7e0a 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.C +++ b/src/fileFormats/vtk/output/foamVtkOutput.C @@ -33,33 +33,20 @@ License #include "foamVtkLegacyAsciiFormatter.H" #include "foamVtkLegacyRawFormatter.H" #include "typeInfo.H" +#include "globalIndex.H" #include "instant.H" +#include "Fstream.H" +#include "Pstream.H" +#include "OSspecific.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" } -}); +// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // +Foam::autoPtr<Foam::vtk::formatter> +Foam::vtk::newFormatter(std::ostream& os, unsigned prec) +{ + return autoPtr<vtk::formatter>::NewFrom<vtk::asciiFormatter>(os, prec); +} -// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // Foam::autoPtr<Foam::vtk::formatter> 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<instant>& series + const fileName& base, + const UList<instant>& 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" : "<prefix>name<suffix>", "time" : value } + // { "name" : "<stem><sep>name<ext>", "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<fileName>& files + const fileName& base, + const UList<instant>& series, + const char sep ) { - asciiFormatter vtmFile(os); + mkDir(base.path()); - vtmFile - .xmlHeader() - .beginVTKFile(fileTagNames[vtk::fileTag::MULTI_BLOCK], "1.0"); + autoPtr<OFstream> osPtr = + ( + base.hasExt("series") + ? autoPtr<OFstream>::New(base) + : autoPtr<OFstream>::New(base + ".series") + ); - forAll(files, i) + seriesInfo(*osPtr, base, series, sep); +} + + +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) + ) { - vtmFile - .openTag(vtk::fileTag::DATA_SET) - .xmlAttr("index", i) - .xmlAttr("file", files[i]) - .closeTag(true); + // Warn? + return outputName; } - vtmFile.endTag(fileTagNames[vtk::fileTag::MULTI_BLOCK]).endVTKFile(); + const auto dot = outputName.find('.', dash); - return files.size(); + if (std::string::npos == dot) + { + return outputName.substr(0, dash); + } + + return outputName.substr(0, dash) + outputName.substr(dot); } -std::ostream& Foam::vtk::legacy::fileHeader +void Foam::vtk::writeList +( + vtk::formatter& fmt, + const UList<uint8_t>& 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<uint8_t>& values +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values); + + List<uint8_t> 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<legacyRawFormatter>(fmt)); - if (!contentType.empty()) + legacy::fileHeader(os, title, isType<legacyRawFormatter>(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 2f4a0d2f7af03c1dfc5d9a2c85184ccede0b9c1d..9cd5434847a8aedefe6397973890d839fe90a601 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<vtk::formatter> newFormatter(std::ostream& os); + autoPtr<vtk::formatter> newFormatter + ( + std::ostream& os, + unsigned prec = IOstream::defaultPrecision() + ); //- Return a new formatter based on the specified format type autoPtr<vtk::formatter> newFormatter @@ -77,23 +84,56 @@ 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<instant>& series + const fileName& base, + const UList<instant>& series, + const char sep = '_' ); - //- Write vtm datasets for specified files - label writeVtmFile(std::ostream& os, const UList<fileName>& 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<instant>& 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<uint8_t>& values + ); + + //- Write a list of uint8_t values. + // The output does not include the payload size. + void writeListParallel + ( + vtk::formatter& fmt, + const UList<uint8_t>& values + ); + //- Write a value component-wise. template<class Type> inline void write @@ -109,7 +149,7 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const UList<Type>& list + const UList<Type>& values ); //- Write a list of values. @@ -118,7 +158,7 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const FixedList<Type, Size>& list + const FixedList<Type, Size>& values ); @@ -128,7 +168,88 @@ namespace vtk void writeList ( vtk::formatter& fmt, - const UList<Type>& list, + const UList<Type>& values, + const labelUList& addressing + ); + + //- Write a list of values via indirect addressing. + // The output does not include the payload size. + template<class Type> + void writeList + ( + vtk::formatter& fmt, + const UList<Type>& 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<class Type> + void writeLists + ( + vtk::formatter& fmt, + const UList<Type>& values1, + const UList<Type>& values2, + const labelUList& addressing + ); + + + //- Write a list of values. + // The output does not include the payload size. + template<class Type> + void writeListParallel + ( + vtk::formatter& fmt, + const UList<Type>& 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<label>& values, + const globalIndex& procOffset + ); + + //- Write a list of values via indirect addressing. + // The output does not include the payload size. + template<class Type> + void writeListParallel + ( + vtk::formatter& fmt, + const UList<Type>& values, + const labelUList& addressing + ); + + //- Write a list of values via indirect addressing. + // The output does not include the payload size. + template<class Type> + void writeListParallel + ( + vtk::formatter& fmt, + const UList<Type>& values, + const bitSet& selected + ); + + //- Write a list of values and another list of values. + // The output does not include the payload size. + template<class Type> + void writeListsParallel + ( + vtk::formatter& fmt, + const UList<Type>& values1, + const UList<Type>& values2 + ); + + //- Write a list of values and a list of values via indirect addressing. + // The output does not include the payload size. + template<class Type> + void writeListsParallel + ( + vtk::formatter& fmt, + const UList<Type>& values1, + const UList<Type>& values2, const labelUList& addressing ); @@ -137,93 +258,101 @@ namespace vtk Namespace legacy \*---------------------------------------------------------------------------*/ -//- Some minimal additional support for writing legacy files namespace legacy { -// Constants - - //- Strings corresponding to the (POLYDATA, UNSTRUCTURED_GRID) elements - extern const Foam::Enum<vtk::fileTag> contentNames; - - //- Strings corresponding to the (CELL_DATA, POINT_DATA) elements - extern const Foam::Enum<vtk::fileTag> dataTypeNames; - - // Functions //- Emit header for legacy file. // Writes "ASCII" or "BINARY" depending on specified type. - inline std::ostream& fileHeader - ( - std::ostream& os, - const std::string& title, - const bool binary - ); + void fileHeader(std::ostream& os, const std::string& title, bool binary); //- Emit header for legacy file, with "ASCII" or "BINARY" depending on - // the formatter type. - // Includes "DATASET" with the specified dataset type. - inline void fileHeader + //- the formatter type. + // If the contentType is non-empty, it is used for "DATASET" line. + void fileHeader ( vtk::formatter& fmt, const std::string& title, - const vtk::fileTag& contentTypeTag + const std::string& contentType ); //- Emit header for legacy file, with "ASCII" or "BINARY" depending on - // the formatter type. - // If the contentType is non-empty, it is used for "DATASET" line. - std::ostream& fileHeader + //- the formatter type. + // Includes "DATASET" with the specified dataset type. + inline void fileHeader ( vtk::formatter& fmt, const std::string& title, - const std::string& contentType + vtk::fileTag contentType ); + //- Emit header for legacy file, with "ASCII" or "BINARY" depending on + //- the formatter type. + // Includes "DATASET" of the templated dataset type. + template<vtk::fileTag ContentType> + inline void fileHeader(vtk::formatter& fmt, const std::string& title); //- Emit header for POINTS (with trailing newline). - inline void beginPoints(std::ostream& os, const label nPoints); + inline void beginPoints(std::ostream& os, label nPoints); //- Emit header for POLYGONS (with trailing newline). // The nConnectivity is the sum of all connectivity points used, // but \b without additional space for the size prefixes. // The additional prefix sizes are added internally. - inline void beginPolys + inline void beginPolys(std::ostream& os, label nPolys, label nConnectivity); + + + //- Emit "FIELD FieldData <n>" + inline void fieldData(vtk::formatter& fmt, label nFields); + + //- Emit legacy FIELD FieldData nFields. + inline void beginFieldData(vtk::formatter& fmt, label nFields); + + //- Emit legacy CELL_DATA nCells, FIELD FieldData nFields. + inline void beginCellData ( - std::ostream& os, - const label nPolys, - const label nConnectivity + vtk::formatter& fmt, + label nCells, + label nFields ); - - //- Use the enumerations vtk::fileTag::CELL_DATA, vtk::fileTag::POINT_DATA, - // to emit a legacy CELL_DATA, POINT_DATA element. - // The nEntries corresponds similarly to the number of cells or points, - // respectively. - inline void dataHeader + //- Emit legacy POINT_DATA nPoints, FIELD FieldData nFields. + inline void beginPointData ( - std::ostream& os, - const vtk::fileTag& dataTypeTag, - const label nEntries, - const label nFields + vtk::formatter& fmt, + label nPoints, + label nFields ); + + //- Emit "TimeValue" for a FIELD entry (name as per Catalyst output) + inline void writeTimeValue(vtk::formatter& fmt, scalar timeValue); + //- Start output of float field with the specified name. + template<direction nComp> inline void floatField ( - std::ostream& os, + vtk::formatter& fmt, + const word& name, + const label nEntries + ); + + //- Start output of double field with the specified name. + template<direction nComp> + inline void doubleField + ( + vtk::formatter& fmt, const word& name, - const int nCmpt, const label nEntries ); //- Start output of int field with the specified name. + template<direction nComp> inline void intField ( - std::ostream& os, + vtk::formatter& fmt, const word& name, - const int nCmpt, const label nEntries ); diff --git a/src/fileFormats/vtk/output/foamVtkOutputI.H b/src/fileFormats/vtk/output/foamVtkOutputI.H index b7717ea66d34faaa88930bde4fb797b724d16a68..40b5275737a809d406c51cba3abf1f59a5ec03a8 100644 --- a/src/fileFormats/vtk/output/foamVtkOutputI.H +++ b/src/fileFormats/vtk/output/foamVtkOutputI.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 @@ -59,87 +59,149 @@ inline void write<double>(vtk::formatter& fmt, const double& val) // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // -inline std::ostream& Foam::vtk::legacy::fileHeader +inline void Foam::vtk::legacy::fileHeader ( - std::ostream& os, + vtk::formatter& fmt, const std::string& title, - const bool binary + vtk::fileTag contentType ) { - os << "# vtk DataFile Version 2.0" << nl - << title << nl - << (binary ? "BINARY" : "ASCII") << nl; - - return os; + legacy::fileHeader(fmt, title, legacy::contentNames[contentType]); } +template<Foam::vtk::fileTag ContentType> inline void Foam::vtk::legacy::fileHeader ( vtk::formatter& fmt, - const std::string& title, - const vtk::fileTag& contentTypeTag + const std::string& title ) { - fileHeader(fmt, title, contentNames[contentTypeTag]); + legacy::fileHeader(fmt, title, legacy::contentNames[ContentType]); +} + + +inline void Foam::vtk::legacy::beginPoints(std::ostream& os, label nPoints) +{ + os << nl + << "POINTS " << nPoints << " float" << nl; } -inline void Foam::vtk::legacy::beginPoints +inline void Foam::vtk::legacy::beginPolys ( std::ostream& os, - const label nPoints + label nPolys, + label nConnectivity ) { - os << "POINTS " << nPoints << " float" << nl; + os << nl + << "POLYGONS " << nPolys << ' ' << (nPolys + nConnectivity) << nl; } -inline void Foam::vtk::legacy::beginPolys +inline void Foam::vtk::legacy::fieldData ( - std::ostream& os, - const label nPolys, - const label nConnectivity + vtk::formatter& fmt, + label nFields ) { - os << "POLYGONS " << nPolys << ' ' << (nPolys + nConnectivity) << nl; + fmt.os() + << "FIELD FieldData " << nFields << nl; } -inline void Foam::vtk::legacy::dataHeader +inline void Foam::vtk::legacy::beginFieldData ( - std::ostream& os, - const vtk::fileTag& dataTypeTag, - const label nEntries, - const label nFields + vtk::formatter& fmt, + label nFields +) +{ + legacy::fieldData(fmt, nFields); +} + + +inline void Foam::vtk::legacy::beginCellData +( + vtk::formatter& fmt, + label nCells, + label nFields +) +{ + fmt.os() + << nl + << legacy::dataTypeNames[vtk::fileTag::CELL_DATA] + << ' ' << nCells << nl; + legacy::fieldData(fmt, nFields); +} + + +inline void Foam::vtk::legacy::beginPointData +( + vtk::formatter& fmt, + label nPoints, + label nFields +) +{ + fmt.os() + << nl + << legacy::dataTypeNames[vtk::fileTag::POINT_DATA] + << ' ' << nPoints << nl; + legacy::fieldData(fmt, nFields); +} + + +inline void Foam::vtk::legacy::writeTimeValue +( + vtk::formatter& fmt, + scalar timeValue ) { - os << dataTypeNames[dataTypeTag] << ' ' << nEntries << nl - << "FIELD attributes " << nFields << nl; + legacy::floatField<1>(fmt, "TimeValue", 1); + fmt.write(timeValue); + fmt.flush(); } +template<Foam::direction nComp> +inline void Foam::vtk::legacy::doubleField +( + vtk::formatter& fmt, + const word& fieldName, + label nEntries +) +{ + fmt.os() + << fieldName << ' ' + << int(nComp) << ' ' << nEntries << " double" << nl; +} + + +template<Foam::direction nComp> inline void Foam::vtk::legacy::floatField ( - std::ostream& os, + vtk::formatter& fmt, const word& fieldName, - const int nCmpt, - const label nEntries + label nEntries ) { - os << fieldName << ' ' << nCmpt << ' ' << nEntries << " float" << nl; + fmt.os() + << fieldName << ' ' + << int(nComp) << ' ' << nEntries << " float" << nl; } +template<Foam::direction nComp> inline void Foam::vtk::legacy::intField ( - std::ostream& os, + vtk::formatter& fmt, const word& fieldName, - const int nCmpt, - const label nEntries + label nEntries ) { - os << fieldName << ' ' << nCmpt << ' ' << nEntries << " int" << nl; + fmt.os() + << fieldName << ' ' + << int(nComp) << ' ' << nEntries << " int" << nl; } diff --git a/src/fileFormats/vtk/output/foamVtkOutputOptions.H b/src/fileFormats/vtk/output/foamVtkOutputOptions.H index fb15f9dd00dc786923d3e9ecb30e7b5cfa07ab5f..976c5413b711dda11fa24419e5ae042bfc88ec61 100644 --- a/src/fileFormats/vtk/output/foamVtkOutputOptions.H +++ b/src/fileFormats/vtk/output/foamVtkOutputOptions.H @@ -97,6 +97,9 @@ public: //- The output format type inline formatType fmt() const; + //- The file extension (legacy or xml) for the given content-type + inline word ext(vtk::fileTag contentType) const; + //- True if writer uses legacy file format inline bool legacy() const; diff --git a/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H b/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H index c8802c3da8b5744fac2e80190ad9185b6656ce57..36a0a3c7b211142104cb10f70b95a095d5578bfb 100644 --- a/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H +++ b/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H @@ -25,7 +25,6 @@ License #include "foamVtkOutput.H" - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // inline Foam::vtk::outputOptions::outputOptions() @@ -56,13 +55,23 @@ Foam::vtk::outputOptions::newFormatter(std::ostream& os) const // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -inline Foam::vtk::formatType -Foam::vtk::outputOptions::fmt() const +inline Foam::vtk::formatType Foam::vtk::outputOptions::fmt() const { return fmtType_; } +inline Foam::word Foam::vtk::outputOptions::ext(vtk::fileTag contentType) const +{ + return + ( + legacy() + ? vtk::legacy::fileExtension + : vtk::fileExtension[contentType] + ); +} + + inline bool Foam::vtk::outputOptions::legacy() const { return diff --git a/src/fileFormats/vtk/output/foamVtkOutputTemplates.C b/src/fileFormats/vtk/output/foamVtkOutputTemplates.C index 7a398f8d9d0c6199ecb3fd2e4d40e20156251c86..917aaa75d66e90af0f14978ea33f55e9300586c6 100644 --- a/src/fileFormats/vtk/output/foamVtkOutputTemplates.C +++ b/src/fileFormats/vtk/output/foamVtkOutputTemplates.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 @@ -23,6 +23,9 @@ License \*---------------------------------------------------------------------------*/ +#include "Pstream.H" +#include "ListOps.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class Type> @@ -44,12 +47,12 @@ template<class Type> void Foam::vtk::writeList ( vtk::formatter& fmt, - const UList<Type>& list + const UList<Type>& values ) { - for (const Type& val : list) + for (const Type& val : values) { - write(fmt, val); + vtk::write(fmt, val); } } @@ -58,12 +61,12 @@ template<class Type, unsigned Size> void Foam::vtk::writeList ( vtk::formatter& fmt, - const FixedList<Type, Size>& list + const FixedList<Type, Size>& values ) { - for (const Type& val : list) + for (const Type& val : values) { - write(fmt, val); + vtk::write(fmt, val); } } @@ -72,13 +75,261 @@ template<class Type> void Foam::vtk::writeList ( vtk::formatter& fmt, - const UList<Type>& list, + const UList<Type>& values, const labelUList& addressing ) { for (const label idx : addressing) { - write(fmt, list[idx]); + vtk::write(fmt, values[idx]); + } +} + + +template<class Type> +void Foam::vtk::writeList +( + vtk::formatter& fmt, + const UList<Type>& values, + const bitSet& selected +) +{ + for (const label idx : selected) + { + vtk::write(fmt, values[idx]); + } +} + + +template<class Type> +void Foam::vtk::writeLists +( + vtk::formatter& fmt, + const UList<Type>& values, + const UList<Type>& indirect, + const labelUList& addressing +) +{ + vtk::writeList(fmt, values); + vtk::writeList(fmt, indirect, addressing); +} + + +template<class Type> +void Foam::vtk::writeListParallel +( + vtk::formatter& fmt, + const UList<Type>& values +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values); + + List<Type> 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; + } +} + + +template<class Type> +void Foam::vtk::writeListParallel +( + vtk::formatter& fmt, + const UList<Type>& values, + const labelUList& addressing +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values, addressing); + + List<Type> 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 << List<Type>(values, addressing); + } +} + + +template<class Type> +void Foam::vtk::writeListParallel +( + vtk::formatter& fmt, + const UList<Type>& values, + const bitSet& selected +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values, selected); + + List<Type> 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 << subset(selected, values); + } +} + + +template<class Type> +void Foam::vtk::writeListsParallel +( + vtk::formatter& fmt, + const UList<Type>& values1, + const UList<Type>& values2 +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values1); + vtk::writeList(fmt, values2); + + List<Type> recv1, recv2; + + // Receive and write + for + ( + int slave=Pstream::firstSlave(); + slave<=Pstream::lastSlave(); + ++slave + ) + { + IPstream fromSlave(Pstream::commsTypes::blocking, slave); + + fromSlave >> recv1 >> recv2; + + vtk::writeList(fmt, recv1); + vtk::writeList(fmt, recv2); + } + } + else + { + // Send to master + OPstream toMaster + ( + Pstream::commsTypes::blocking, + Pstream::masterNo() + ); + + toMaster << values1 << values2; + } +} + + +template<class Type> +void Foam::vtk::writeListsParallel +( + vtk::formatter& fmt, + const UList<Type>& values1, + const UList<Type>& values2, + const labelUList& addressing +) +{ + if (Pstream::master()) + { + vtk::writeList(fmt, values1); + vtk::writeList(fmt, values2, addressing); + + List<Type> recv1, recv2; +; + // Receive and write + for + ( + int slave=Pstream::firstSlave(); + slave<=Pstream::lastSlave(); + ++slave + ) + { + IPstream fromSlave(Pstream::commsTypes::blocking, slave); + + fromSlave >> recv1 >> recv2; + + vtk::writeList(fmt, recv1); + vtk::writeList(fmt, recv2); + } + } + else + { + // Send to master + OPstream toMaster + ( + Pstream::commsTypes::blocking, + Pstream::masterNo() + ); + + toMaster << values1 << List<Type>(values2, addressing); } } diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C index 07500761acd37e1fe1dbb9986ffa703cb951a70f..c99faa34ce0d1aba1df4051386ae958f5a86a435 100644 --- a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C @@ -466,10 +466,12 @@ bool Foam::functionObjects::vtkCloud::write() // Each cloud separately for (const word& cloudName : cloudNames) { - const word prefix(cloudName + "_"); - const word suffix(".vtp"); // No legacy supported + // Legacy is not to be supported - const fileName outputName(vtkDir/prefix + timeDesc + suffix); + const fileName outputName + ( + vtkDir/cloudName + "_" + timeDesc + ".vtp" + ); if (writeCloud(outputName, cloudName)) { @@ -483,9 +485,11 @@ bool Foam::functionObjects::vtkCloud::write() series_(cloudName).append({time_.value(), timeDesc}); - OFstream os(vtkDir/cloudName + ".vtp.series", IOstream::ASCII); - - vtk::writeSeries(os, prefix, suffix, series_[cloudName]); + vtk::seriesWrite + ( + vtkDir/cloudName + ".vtp", + series_[cloudName] + ); } } } diff --git a/src/meshTools/output/foamVtkWriteCellSetFaces.C b/src/meshTools/output/foamVtkWriteCellSetFaces.C index 9a10c37e72d9fce91dc0c3b093991380bf6ae034..38bc7d107d0a6e127637bbfd5036f842d1265a1e 100644 --- a/src/meshTools/output/foamVtkWriteCellSetFaces.C +++ b/src/meshTools/output/foamVtkWriteCellSetFaces.C @@ -132,7 +132,7 @@ void Foam::vtk::writeCellSetFaces // Write data - faceId/cellId - legacy::dataHeader(os, vtk::fileTag::CELL_DATA, pp.size(), 1); + legacy::beginCellData(format(), pp.size(), 1); os << "cellID 1 " << pp.size() << " int" << nl; diff --git a/src/meshTools/output/foamVtkWriteFaceSet.C b/src/meshTools/output/foamVtkWriteFaceSet.C index f0f2a215211dffa010b5867c37733e2bc06d6c0f..cfe8a5e895dd3744d32a88f8d3db6569538b86ba 100644 --- a/src/meshTools/output/foamVtkWriteFaceSet.C +++ b/src/meshTools/output/foamVtkWriteFaceSet.C @@ -96,7 +96,7 @@ void Foam::vtk::writeFaceSet // Write data - faceId/cellId - legacy::dataHeader(os, vtk::fileTag::CELL_DATA, pp.size(), 1); + legacy::beginCellData(format(), pp.size(), 1); os << "faceID 1 " << pp.size() << " int" << nl; diff --git a/src/meshTools/output/foamVtkWritePointSet.C b/src/meshTools/output/foamVtkWritePointSet.C index 64c88f0350a281660fd4fdf852bd79ec43a110f4..e228359946280463e44af830e7d077cb74eeb1b2 100644 --- a/src/meshTools/output/foamVtkWritePointSet.C +++ b/src/meshTools/output/foamVtkWritePointSet.C @@ -64,7 +64,7 @@ void Foam::vtk::writePointSet format().flush(); // Write data - pointID - legacy::dataHeader(os, vtk::fileTag::POINT_DATA, pointLabels.size(), 1); + legacy::beginPointData(format(), pointLabels.size(), 1); os << "pointID 1 " << pointLabels.size() << " int" << nl; diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C index 9de55aae6fad67d514f9e142bd058f33bd770876..9d921f48ff677aa636d245104250b8c8eccdf0cf 100644 --- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C +++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C @@ -92,21 +92,8 @@ void Foam::fileFormats::VTKsurfaceFormatCore::writeCellData nFaces += z.size(); } - vtk::legacy::dataHeader - ( - format.os(), - vtk::fileTag::CELL_DATA, - nFaces, - 1 // Only one field - ); - - vtk::legacy::intField - ( - format.os(), - "region", - 1, // nComponent - nFaces - ); + vtk::legacy::beginCellData(format, nFaces, 1); // 1 field + vtk::legacy::intField<1>(format, "region", nFaces); // 1 component label zoneId = 0; for (const surfZone& zone : zones) @@ -132,21 +119,8 @@ void Foam::fileFormats::VTKsurfaceFormatCore::writeCellData // Number of faces const label nFaces = zoneIds.size(); - vtk::legacy::dataHeader - ( - format.os(), - vtk::fileTag::CELL_DATA, - nFaces, - 1 // Only one field - ); - - vtk::legacy::intField - ( - format.os(), - "region", - 1, // nComponent - nFaces - ); + vtk::legacy::beginCellData(format, nFaces, 1); // 1 field + vtk::legacy::intField<1>(format, "region", nFaces); // 1 component vtk::writeList(format, zoneIds); format.flush();