ENH: improvements for foamVtkOutput, foamVtkFormatter (issue #926)

- parallel list output for foamVtkOutput

- simplified '.series' file output

- beginDataArray() method instead of openDataArray() + closeTag()
  since this seems to be the most common use anyhow.
  With an optional argument for leaving the tag open, this works the
  same as openDataArray() which may be deprecated in the future.

- begin/end methods for CellData, PointData, FieldData (commonly used)

- templating parameters for file headers, content version,
  legacy fields. This improves coding robustness and convenience of use.

- use formatter and higher-level methods for legacy output

- attribute quoting character now part of the formatter itself
  instead of as an argument for xmlAttr().
  Toggle with quoting() method.

- pair-wise processing of xml attributes, which also allows them to be
  passed as optional entries when creating an xml tag.

- xmlComment with multiple arguments
This commit is contained in:
Mark Olesen
2018-09-17 08:59:03 +02:00
parent 19e03f7dd1
commit 05427217a0
41 changed files with 1957 additions and 603 deletions

View File

@ -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();
}
}
}

View File

@ -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
{

View File

@ -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();
}
}

View File

@ -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
{

View File

@ -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();
}

View File

@ -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
{

View File

@ -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
{

View File

@ -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();
}
}

View File

@ -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
{

View File

@ -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
{

View File

@ -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" },
});
// ************************************************************************* //

View File

@ -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

View File

@ -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";
// ************************************************************************* //

View File

@ -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
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
};

View File

@ -44,7 +44,7 @@ namespace vtk
{
/*---------------------------------------------------------------------------*\
Class base64Formatter Declaration
Class vtk::base64Formatter Declaration
\*---------------------------------------------------------------------------*/
class base64Formatter

View File

@ -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);
}

View File

@ -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);

View File

@ -24,104 +24,103 @@ License
#include "foamVtkFormatter.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::vtk::formatter::canWriteAttr(const word& k) const
{
if (!inTag_)
{
WarningInFunction
<< "xml attribute '" << k << "' but not inside a tag!" << endl;
}
return inTag_;
}
bool Foam::vtk::formatter::canWriteToplevel(const char* what) const
{
if (inTag_)
{
WarningInFunction
<< "Cannot add " << what << " inside a tag!"
<< endl;
}
return !inTag_;
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::vtk::formatter::quoting(const quoteChar quote)
{
quote_ = quote;
}
uint64_t Foam::vtk::formatter::offset(const uint64_t)
{
return formatter::npos;
}
std::size_t Foam::vtk::formatter::encodedLength(std::size_t n) const
{
return n;
}
void Foam::vtk::formatter::indent()
{
label n = xmlTags_.size() * 2;
while (n--)
{
os_ << ' ';
}
}
Foam::vtk::formatter&
Foam::vtk::formatter::xmlHeader()
bool Foam::vtk::formatter::openTagImpl(const word& tagName)
{
if (inTag_)
{
WarningInFunction
<< "xml header, but already within a tag!"
<< endl;
}
os_ << "<?xml version='1.0'?>" << nl;
return *this;
}
Foam::vtk::formatter&
Foam::vtk::formatter::xmlComment(const std::string& comment)
{
if (inTag_)
{
WarningInFunction
<< "adding xml comment inside a tag??"
<< endl;
}
indent();
os_ << "<!-- " << comment << " -->" << nl;
return *this;
}
Foam::vtk::formatter&
Foam::vtk::formatter::openTag(const word& tagName)
{
if (inTag_)
{
WarningInFunction
<< "open XML tag '" << tagName
<< "', but already within a tag!"
<< "open xml tag '" << tagName << "', but already within a tag!"
<< endl;
return false;
}
// Emit, before changing the stack or the state.
indent();
os_ << '<' << tagName;
// Add to the stack and change the state.
xmlTags_.append(tagName);
inTag_ = true;
return *this;
return true;
}
Foam::vtk::formatter&
Foam::vtk::formatter::closeTag(const bool isEmpty)
Foam::vtk::formatter& Foam::vtk::formatter::closeTag(const bool isEmpty)
{
if (!inTag_)
{
WarningInFunction
<< "close XML tag, but not within a tag!"
<< "attempt to close xml tag, but not within a tag!"
<< endl;
}
if (isEmpty)
else
{
// eg, <tag ... />
xmlTags_.remove();
os_ << " /";
}
os_ << '>' << nl;
// Change the state
inTag_ = false;
inTag_ = false;
if (isEmpty)
{
// Eg, <tag ... />
xmlTags_.remove();
os_ << " /";
}
os_ << '>' << nl;
}
return *this;
}
Foam::vtk::formatter&
Foam::vtk::formatter::endTag(const word& tagName)
Foam::vtk::formatter& Foam::vtk::formatter::endTag(const word& tagName)
{
const word curr(xmlTags_.remove());
indent();
@ -129,16 +128,18 @@ Foam::vtk::formatter::endTag(const word& tagName)
if (inTag_)
{
WarningInFunction
<< "adding XML endTag '" << curr
<< "adding xml endTag '" << curr
<< "' but already in another tag!"
<< endl;
// Also suppress further output, or not?
}
// verify expected end tag
// Verify expected end tag
if (!tagName.empty() && tagName != curr)
{
WarningInFunction
<< "expecting to end xml-tag '" << tagName
<< "expecting to end xml tag '" << tagName
<< "' but found '" << curr << "' instead"
<< endl;
}
@ -151,8 +152,7 @@ Foam::vtk::formatter::endTag(const word& tagName)
}
Foam::vtk::formatter&
Foam::vtk::formatter::beginVTKFile
Foam::vtk::formatter& Foam::vtk::formatter::beginVTKFile
(
const word& contentType,
const word& contentVersion,
@ -176,15 +176,7 @@ Foam::vtk::formatter::beginVTKFile
}
Foam::vtk::formatter&
Foam::vtk::formatter::endVTKFile()
{
return endTag(vtk::fileTag::VTK_FILE);
}
Foam::vtk::formatter&
Foam::vtk::formatter::beginAppendedData()
Foam::vtk::formatter& Foam::vtk::formatter::beginAppendedData()
{
openTag("AppendedData");
xmlAttr("encoding", encoding());
@ -195,31 +187,124 @@ Foam::vtk::formatter::beginAppendedData()
}
Foam::vtk::formatter&
Foam::vtk::formatter::endAppendedData()
Foam::vtk::formatter& Foam::vtk::formatter::endAppendedData()
{
flush(); // flush any pending encoded content
os_ << nl; // ensure clear separation from content.
flush(); // Flush any pending encoded content
os_ << nl; // Ensure clear separation from content
return endTag("AppendedData");
}
Foam::vtk::formatter&
Foam::vtk::formatter::xmlAttr
Foam::vtk::formatter& Foam::vtk::formatter::beginBlock
(
const word& k,
const std::string& v,
const char quote
label index,
std::string name
)
{
if (!inTag_)
openTag(vtk::fileTag::BLOCK);
if (index >= 0)
{
WarningInFunction
<< "xml attribute '" << k << "' but not within a tag!"
<< endl;
xmlAttr("index", index);
}
if (name.size())
{
xmlAttr("name", name);
}
closeTag();
os_ << ' ' << k << '=' << quote << v.c_str() << quote;
return *this;
}
Foam::vtk::formatter& Foam::vtk::formatter::beginPiece
(
label index,
std::string name
)
{
openTag(vtk::fileTag::PIECE);
if (index >= 0)
{
xmlAttr("index", index);
}
if (name.size())
{
xmlAttr("name", name);
}
closeTag();
return *this;
}
Foam::vtk::formatter& Foam::vtk::formatter::DataSet
(
label index,
std::string file,
bool autoName
)
{
openTag(vtk::fileTag::DATA_SET);
if (index >= 0)
{
xmlAttr("index", index);
}
if (file.size())
{
if (autoName)
{
xmlAttr("name", fileName::nameLessExt(file));
}
xmlAttr("file", file);
}
closeTag(true); // Empty tag. ie, <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();
endDataArray();
return *this;
}

View File

@ -27,7 +27,8 @@ Class
Description
Abstract class for a VTK output stream formatter.
Includes very simple support for writing XML elements.
Includes simple support for writing XML elements.
By default uses single-quoting for XML attributes.
SourceFiles
foamVtkFormatter.C
@ -39,8 +40,9 @@ SourceFiles
#define foamVtkFormatter_H
#include "int.H"
#include "uint64.H"
#include "label.H"
#include "uint64.H"
#include "direction.H"
#include "word.H"
#include "UList.H"
#include "DynamicList.H"
@ -59,11 +61,23 @@ namespace vtk
class outputOptions;
/*---------------------------------------------------------------------------*\
Class formatter Declaration
Class vtk::formatter Declaration
\*---------------------------------------------------------------------------*/
class formatter
{
public:
//- Quoting for XML attributes
enum quoteChar : char
{
DOUBLE_QUOTE = '\"', //!< Double-quote XML attributes
SINGLE_QUOTE = '\'', //!< Single-quote XML attributes
};
protected:
// Private Data
//- The output stream for the formatter
@ -75,33 +89,60 @@ class formatter
//- Tag open/closed/ended state
mutable bool inTag_;
// Private Member Functions
//- Write XML attribute key/value pair
template<class Type>
formatter& writeAttribute
(
const word& k,
const Type& v,
const char quote = '\''
);
//- Quoting character for XML attributes
char quote_;
protected:
// Protected Member Functions
//- Can write XML key/value attribute pair when inside a tag.
//- Emit warning and return false if this condition is not met.
bool canWriteAttr(const word& k) const;
//- Can write tag-like top-level content (eg, comment, ...)
//- when not already inside a tag.
//- Emit warning and return false if this condition is not met.
bool canWriteToplevel(const char* what) const;
//- Write XML key/value attribute pair (implementation).
template<class Type>
inline void writeAttr(const word& k, const Type& v);
//- No-op write XML attribute (for templating code).
// \return formatter for chaining
inline formatter& xmlAttr();
//- No-op XML comment loop (for templating code).
inline void xmlCommentLoop();
//- Loop/output XML comments
template<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;
// General Output
// Member Functions
//- Add indenting according to the current XML tag depth
// Two spaces per depth.
inline void indent();
// Output
//- Indent according to the currently nested XML tags
void indent();
//- Add indenting of n spaces.
inline void indent(label n);
//- Write XML header
// \return formatter for chaining
formatter& xmlHeader();
inline formatter& xmlHeader();
//- Write XML comment (at the current indentation level)
// \return formatter for chaining
formatter& xmlComment(const std::string& comment);
template<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();
//- Open "DataArray" XML tag
//- Begin "Block" XML section.
// \param index The index of the block
// \param name The name of the block (ignored if empty)
// \return formatter for chaining
template<class Type, int nComp=0>
formatter& openDataArray(const word& dataName);
formatter& beginBlock(label index, std::string name = "");
//- Open "DataArray" XML tag
//- End "Block" XML section.
// \return formatter for chaining
template<class Type, int nComp=0>
formatter& openDataArray(const vtk::dataArrayAttr& attrEnum);
inline formatter& endBlock();
//- Begin "Piece" XML section.
// \param index The index of the piece
// \param name The name of the piece (ignored if empty)
// \return formatter for chaining
formatter& beginPiece(label index, std::string name = "");
//- End "Piece" XML section.
// \return formatter for chaining
inline virtual formatter& endPiece();
//- Insert a single "DataSet" XML entry tag.
// \param index The index of the DataSet
// \param file The file name for the data (ignored if empty)
// \param autoName The name for the data extracted from the file name
// (without extension)
// \return formatter for chaining
formatter& DataSet
(
label index,
std::string file = "",
bool autoName = true
);
//- Insert a single "DataSet" XML entry tag.
// \param index The index of the DataSet
// \param file The file name for the data (ignored if empty)
// \param name The name for the dataset
// \return formatter for chaining
formatter& DataSet
(
label index,
std::string file,
std::string name
);
//- Begin "DataArray" XML section.
//
// \param dataName The name of the DataArray
// \param payLoad Additional payLoad information to increment
// the offset for an append formatter and add the "offset"
// attribute accordingly.
// \param leaveOpen Leave tag open for additional attributes.
//
// \return formatter for chaining
template<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();
//- End "AppendedData" XML tag
//- Begin "CellData" XML section.
inline formatter& beginCellData();
//- Begin "PointData" XML section.
inline formatter& beginPointData();
//- End "FieldData" XML section.
inline virtual formatter& endFieldData();
//- End "CellData" XML section.
inline virtual formatter& endCellData();
//- End "PointData" XML section.
inline virtual formatter& endPointData();
//- End "AppendedData" XML section
// \return formatter for chaining
formatter& endAppendedData();
//- End "VTKFile" XML tag
//- End "VTKFile" XML section.
// \return formatter for chaining
formatter& endVTKFile();
inline virtual formatter& endVTKFile();
//- Write XML attribute
//- Emit "TimeValue" for FieldData (name as per Catalyst output)
formatter& writeTimeValue(scalar timeValue);
// XML Attributes
//- Pair-wise write of XML key/value attributes
// \return formatter for chaining
formatter& xmlAttr
template<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
);
//- 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 std::string& v,
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 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

View File

@ -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 endTag("DataArray");
return beginVTKFile
(
vtk::fileTagNames[contentType],
vtk::fileContentVersions[contentType],
leaveOpen
);
}
inline Foam::vtk::formatter&
Foam::vtk::formatter::xmlAttr
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(vtk::fileTag::CELL_DATA);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endPointData()
{
return endTag(vtk::fileTag::POINT_DATA);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endFieldData()
{
return endTag(vtk::fileTag::FIELD_DATA);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endDataArray()
{
return endTag(vtk::fileTag::DATA_ARRAY);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endBlock()
{
return endTag(vtk::fileTag::BLOCK);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endPiece()
{
return endTag(vtk::fileTag::PIECE);
}
inline Foam::vtk::formatter& Foam::vtk::formatter::endVTKFile()
{
return endTag(vtk::fileTag::VTK_FILE);
}
// Attributes
template<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)...);
}
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 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)...);
}
template<class... Args>
inline Foam::vtk::formatter& Foam::vtk::formatter::xmlAttr
(
const vtk::fileAttr& k,
const int32_t v,
const char quote
Args&&... args
)
{
return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote);
if (!canWriteAttr(vtk::fileAttrNames[k])) return *this;
writeAttr(vtk::fileAttrNames[k], v);
return xmlAttr(std::forward<Args>(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)...);
}

View File

@ -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());
if (formatter::npos != payLoad)
{
uint64_t off = offset(payLoad);
if (formatter::npos != off)
{
xmlAttr("offset", off);
}
}
if (!leaveOpen)
{
closeTag();
}
return *this;
}
template<class Type, int nComp>
Foam::vtk::formatter&
Foam::vtk::formatter::openDataArray
(
const vtk::dataArrayAttr& attrEnum
)
{
return openDataArray<Type, nComp>(vtk::dataArrayAttrNames[attrEnum]);
}
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);

View File

@ -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; }
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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

View File

@ -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; }
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -33,34 +33,21 @@ License
#include "foamVtkLegacyAsciiFormatter.H"
#include "foamVtkLegacyRawFormatter.H"
#include "typeInfo.H"
#include "globalIndex.H"
#include "instant.H"
// * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * * //
const Foam::Enum
<
Foam::vtk::fileTag
>
Foam::vtk::legacy::contentNames
({
{ vtk::fileTag::POLY_DATA, "POLYDATA" },
{ vtk::fileTag::UNSTRUCTURED_GRID, "UNSTRUCTURED_GRID" },
});
const Foam::Enum
<
Foam::vtk::fileTag
>
Foam::vtk::legacy::dataTypeNames
({
{ vtk::fileTag::CELL_DATA, "CELL_DATA" },
{ vtk::fileTag::POINT_DATA, "POINT_DATA" }
});
#include "Fstream.H"
#include "Pstream.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::vtk::formatter>
Foam::vtk::newFormatter(std::ostream& os, unsigned prec)
{
return autoPtr<vtk::formatter>::NewFrom<vtk::asciiFormatter>(os, prec);
}
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)
{
vtmFile
.openTag(vtk::fileTag::DATA_SET)
.xmlAttr("index", i)
.xmlAttr("file", files[i])
.closeTag(true);
}
vtmFile.endTag(fileTagNames[vtk::fileTag::MULTI_BLOCK]).endVTKFile();
return files.size();
seriesInfo(*osPtr, base, series, sep);
}
std::ostream& Foam::vtk::legacy::fileHeader
Foam::fileName Foam::vtk::seriesBase
(
const fileName& outputName,
const char sep
)
{
const auto dash = outputName.rfind(sep);
// No separator? Or separator in path() instead of name()?
if
(
std::string::npos == dash
|| std::string::npos != outputName.find('/', dash)
)
{
// Warn?
return outputName;
}
const auto dot = outputName.find('.', dash);
if (std::string::npos == dot)
{
return outputName.substr(0, dash);
}
return outputName.substr(0, dash) + outputName.substr(dot);
}
void Foam::vtk::writeList
(
vtk::formatter& fmt,
const UList<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;
}

View File

@ -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,22 +84,55 @@ namespace vtk
);
//- Write file series (JSON format) for specified time instances
//- Print file series (JSON format) for specified time instances
//
// \param prefix before the \c instant.name()
// \param suffix after the \c instant.name()
// \param series the list of name/value entries
void writeSeries
// \param os The output stream
// \param base The name for the series (eg, "path/file.vtm")
// \param series The list of suffix/value entries
// \param sep The separator used between file stem and suffix.
void seriesInfo
(
Ostream& os,
const word& prefix,
const word& suffix,
const UList<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>
@ -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
(
vtk::formatter& fmt,
const std::string& title,
const vtk::fileTag& contentTypeTag
);
//- Emit header for legacy file, with "ASCII" or "BINARY" depending on
// the formatter type.
//- the formatter type.
// If the contentType is non-empty, it is used for "DATASET" line.
std::ostream& fileHeader
void fileHeader
(
vtk::formatter& fmt,
const std::string& title,
const std::string& contentType
);
//- Emit header for legacy file, with "ASCII" or "BINARY" depending on
//- the formatter type.
// Includes "DATASET" with the specified dataset type.
inline void fileHeader
(
vtk::formatter& fmt,
const std::string& title,
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
);
//- Emit legacy POINT_DATA nPoints, FIELD FieldData nFields.
inline void beginPointData
(
vtk::formatter& fmt,
label nPoints,
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
(
std::ostream& os,
const vtk::fileTag& dataTypeTag,
const label nEntries,
const 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
);

View File

@ -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
(
std::ostream& os,
const std::string& title,
const bool binary
)
{
os << "# vtk DataFile Version 2.0" << nl
<< title << nl
<< (binary ? "BINARY" : "ASCII") << nl;
return os;
}
inline void Foam::vtk::legacy::fileHeader
(
vtk::formatter& fmt,
const std::string& title,
const vtk::fileTag& contentTypeTag
vtk::fileTag contentType
)
{
fileHeader(fmt, title, contentNames[contentTypeTag]);
legacy::fileHeader(fmt, title, legacy::contentNames[contentType]);
}
inline void Foam::vtk::legacy::beginPoints
template<Foam::vtk::fileTag ContentType>
inline void Foam::vtk::legacy::fileHeader
(
std::ostream& os,
const label nPoints
vtk::formatter& fmt,
const std::string& title
)
{
os << "POINTS " << nPoints << " float" << nl;
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::beginPolys
(
std::ostream& os,
const label nPolys,
const label nConnectivity
label nPolys,
label nConnectivity
)
{
os << "POLYGONS " << nPolys << ' ' << (nPolys + nConnectivity) << nl;
os << nl
<< "POLYGONS " << nPolys << ' ' << (nPolys + nConnectivity) << nl;
}
inline void Foam::vtk::legacy::dataHeader
inline void Foam::vtk::legacy::fieldData
(
std::ostream& os,
const vtk::fileTag& dataTypeTag,
const label nEntries,
const label nFields
vtk::formatter& fmt,
label nFields
)
{
os << dataTypeNames[dataTypeTag] << ' ' << nEntries << nl
<< "FIELD attributes " << nFields << nl;
fmt.os()
<< "FIELD FieldData " << nFields << nl;
}
inline void Foam::vtk::legacy::beginFieldData
(
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
)
{
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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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]
);
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();