mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add VTP, VTU output for most vtk writers (insitu only)
- with the xml append format it is possible to write raw binary
(instead of base64), but the writer becomes more complicated.
Either needs two passes to create, or need to allocate a block
of space for the header information (like VTK itself does) and
write later.
* internalWriter
* patchWriter
* surfaceMeshWriter
* lagrangianWriter
Also these special purpose ones:
* foamVtkWriteSurfFields
This commit is contained in:
@ -25,51 +25,62 @@ License
|
||||
|
||||
#include "foamVtkInternalWriter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::foamVtkOutput::internalWriter::internalWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtkCells& cells,
|
||||
const fileName& baseName,
|
||||
const foamVtkOutput::outputOptions outOpts
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
format_(),
|
||||
vtkCells_(cells),
|
||||
os_()
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::beginPiece()
|
||||
{
|
||||
outputOptions opts(outOpts);
|
||||
opts.legacy(true); // Legacy only, no append
|
||||
|
||||
os_.open((baseName + (opts.legacy() ? ".vtk" : ".vtu")).c_str());
|
||||
format_ = opts.newFormatter(os_);
|
||||
|
||||
if (opts.legacy())
|
||||
if (!legacy_)
|
||||
{
|
||||
foamVtkOutput::legacy::fileHeader(format(), mesh.time().caseName())
|
||||
<< "DATASET UNSTRUCTURED_GRID" << nl;
|
||||
format()
|
||||
.openTag(vtkFileTag::PIECE)
|
||||
( "NumberOfPoints", vtkCells_.nFieldPoints() )
|
||||
( "NumberOfCells", vtkCells_.nFieldCells() )
|
||||
.closeTag();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writePoints()
|
||||
{
|
||||
// payload size
|
||||
const uint64_t payLoad = (vtkCells_.nFieldPoints() * 3 * sizeof(float));
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::beginPoints(os_, vtkCells_.nFieldPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
format()
|
||||
.tag(vtkFileTag::POINTS)
|
||||
.openDataArray<float,3>(vtkFileTag::POINTS)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// Write topology
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
format().writeSize(payLoad);
|
||||
|
||||
os_ << "POINTS " << vtkCells_.nFieldPoints() << " float" << nl;
|
||||
foamVtkOutput::writeList(format(), mesh.points());
|
||||
|
||||
const pointField& ctrs = mesh.cellCentres();
|
||||
foamVtkOutput::writeList(format(), ctrs, vtkCells_.addPointCellLabels());
|
||||
foamVtkOutput::writeList(format(), mesh_.points());
|
||||
foamVtkOutput::writeList
|
||||
(
|
||||
format(),
|
||||
mesh_.cellCentres(),
|
||||
vtkCells_.addPointCellLabels()
|
||||
);
|
||||
|
||||
format().flush();
|
||||
|
||||
//
|
||||
// Write cells
|
||||
//
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.endDataArray()
|
||||
.endTag(vtkFileTag::POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writeCellsLegacy()
|
||||
{
|
||||
const List<uint8_t>& cellTypes = vtkCells_.cellTypes();
|
||||
const labelList& vertLabels = vtkCells_.vertLabels();
|
||||
|
||||
@ -90,6 +101,177 @@ Foam::foamVtkOutput::internalWriter::internalWriter
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writeCells()
|
||||
{
|
||||
format().tag(vtkFileTag::CELLS);
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
//
|
||||
{
|
||||
const labelList& vertLabels = vtkCells_.vertLabels();
|
||||
const uint64_t payLoad = vertLabels.size() * sizeof(label);
|
||||
|
||||
format().openDataArray<label>("connectivity")
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), vertLabels);
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'offsets' (connectivity offsets)
|
||||
//
|
||||
{
|
||||
const labelList& vertOffsets = vtkCells_.vertOffsets();
|
||||
const uint64_t payLoad = vertOffsets.size() * sizeof(label);
|
||||
|
||||
format().openDataArray<label>("offsets")
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), vertOffsets);
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'types' (cell types)
|
||||
//
|
||||
{
|
||||
const List<uint8_t>& cellTypes = vtkCells_.cellTypes();
|
||||
const uint64_t payLoad = cellTypes.size() * sizeof(uint8_t);
|
||||
|
||||
format().openDataArray<uint8_t>("types")
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
forAll(cellTypes, i)
|
||||
{
|
||||
// No nComponents for char, cannot use foamVtkOutput::writeList here
|
||||
format().write(cellTypes[i]);
|
||||
}
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// can quit here if there are NO face streams
|
||||
//
|
||||
if (vtkCells_.faceLabels().empty())
|
||||
{
|
||||
format().endTag(vtkFileTag::CELLS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
|
||||
//
|
||||
// 'faces' (face streams)
|
||||
//
|
||||
{
|
||||
const labelList& faceLabels = vtkCells_.faceLabels();
|
||||
const uint64_t payLoad = faceLabels.size() * sizeof(label);
|
||||
|
||||
format().openDataArray<label>("faces")
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), faceLabels);
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
|
||||
// 'faceoffsets' (face stream offsets)
|
||||
// -1 to indicate that the cell is a primitive type that does not
|
||||
// have a face stream
|
||||
{
|
||||
const labelList& faceOffsets = vtkCells_.faceOffsets();
|
||||
const uint64_t payLoad = faceOffsets.size() * sizeof(label);
|
||||
|
||||
format().openDataArray<label>("faceoffsets")
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), faceOffsets);
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
format().endTag(vtkFileTag::CELLS);
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writeMesh()
|
||||
{
|
||||
writePoints();
|
||||
if (legacy_)
|
||||
{
|
||||
writeCellsLegacy();
|
||||
}
|
||||
else
|
||||
{
|
||||
writeCells();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::foamVtkOutput::internalWriter::internalWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtkCells& cells,
|
||||
const fileName& baseName,
|
||||
const foamVtkOutput::outputOptions outOpts
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
legacy_(outOpts.legacy()),
|
||||
format_(),
|
||||
vtkCells_(cells),
|
||||
os_()
|
||||
{
|
||||
outputOptions opts(outOpts);
|
||||
opts.append(false); // No append supported
|
||||
|
||||
os_.open((baseName + (legacy_ ? ".vtk" : ".vtu")).c_str());
|
||||
format_ = opts.newFormatter(os_);
|
||||
|
||||
const auto& title = mesh_.time().caseName();
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::fileHeader(format(), title, vtkFileTag::UNSTRUCTURED_GRID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XML (inline)
|
||||
|
||||
format()
|
||||
.xmlHeader()
|
||||
.xmlComment(title)
|
||||
.beginVTKFile(vtkFileTag::UNSTRUCTURED_GRID, "0.1");
|
||||
}
|
||||
|
||||
beginPiece();
|
||||
writeMesh();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::foamVtkOutput::internalWriter::~internalWriter()
|
||||
@ -101,43 +283,98 @@ Foam::foamVtkOutput::internalWriter::~internalWriter()
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::beginCellData(label nFields)
|
||||
{
|
||||
foamVtkOutput::legacy::cellDataHeader
|
||||
(
|
||||
os(),
|
||||
vtkCells_.nFieldCells(),
|
||||
nFields
|
||||
);
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader
|
||||
(
|
||||
os(),
|
||||
vtkFileTag::CELL_DATA,
|
||||
vtkCells_.nFieldCells(),
|
||||
nFields
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::endCellData()
|
||||
{}
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::beginPointData(label nFields)
|
||||
{
|
||||
foamVtkOutput::legacy::pointDataHeader
|
||||
(
|
||||
os(),
|
||||
vtkCells_.nFieldPoints(),
|
||||
nFields
|
||||
);
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader
|
||||
(
|
||||
os(),
|
||||
vtkFileTag::POINT_DATA,
|
||||
vtkCells_.nFieldPoints(),
|
||||
nFields
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::POINT_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::endPointData()
|
||||
{}
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::POINT_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writeFooter()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
// slight cheat. </Piece> too
|
||||
format().endTag(vtkFileTag::PIECE);
|
||||
|
||||
format().endTag(vtkFileTag::UNSTRUCTURED_GRID)
|
||||
.endVTKFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::internalWriter::writeCellIDs()
|
||||
{
|
||||
const labelList& cellMap = vtkCells_.cellMap();
|
||||
|
||||
// Cell ids first
|
||||
os_ << "cellID 1 " << vtkCells_.nFieldCells() << " int" << nl;
|
||||
const labelList& cellMap = vtkCells_.cellMap();
|
||||
const uint64_t payLoad = vtkCells_.nFieldCells() * sizeof(label);
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
os_ << "cellID 1 " << vtkCells_.nFieldCells() << " int" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<label>("cellID")
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
foamVtkOutput::writeList(format(), cellMap);
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -64,6 +64,9 @@ class internalWriter
|
||||
//- Reference to the OpenFOAM mesh (or subset)
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- Commonly used query
|
||||
const bool legacy_;
|
||||
|
||||
autoPtr<foamVtkOutput::formatter> format_;
|
||||
|
||||
//- The volume cells (internalMesh)
|
||||
@ -71,6 +74,32 @@ class internalWriter
|
||||
|
||||
std::ofstream os_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Begin piece
|
||||
void beginPiece();
|
||||
|
||||
//- Write mesh points
|
||||
void writePoints();
|
||||
|
||||
//- Write mesh cells
|
||||
void writeCellsLegacy();
|
||||
|
||||
//- Write mesh cells
|
||||
void writeCells();
|
||||
|
||||
//- Write mesh topology
|
||||
void writeMesh();
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
internalWriter(const internalWriter&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const internalWriter&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
@ -120,6 +149,10 @@ public:
|
||||
//- Write cellIDs
|
||||
void writeCellIDs();
|
||||
|
||||
//- Write file footer
|
||||
void writeFooter();
|
||||
|
||||
|
||||
//- Write internal fields
|
||||
template<class Type>
|
||||
void write
|
||||
|
||||
@ -36,21 +36,32 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
const UPtrList<const DimensionedField<Type, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const labelList& cellMap = vtkCells_.cellMap();
|
||||
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
// const uint64_t payLoad(cellMap.size() * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, i)
|
||||
{
|
||||
const auto& fld = flds[i];
|
||||
|
||||
// Legacy
|
||||
os()<< fld.name() << ' '
|
||||
<< nCmpt << ' '
|
||||
<< cellMap.size() << " float"
|
||||
<< nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), fld.name(), nCmpt, cellMap.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
// writeField includes payload size
|
||||
foamVtkOutput::writeField(format(), fld, cellMap);
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,21 +72,32 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
const UPtrList<const GeometricField<Type, PatchField, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const labelList& cellMap = vtkCells_.cellMap();
|
||||
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
// const uint64_t payLoad(cellMap.size() * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, i)
|
||||
{
|
||||
const auto& fld = flds[i];
|
||||
|
||||
// Legacy
|
||||
os()<< fld.name() << ' '
|
||||
<< nCmpt << ' '
|
||||
<< cellMap.size() << " float"
|
||||
<< nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), fld.name(), nCmpt, cellMap.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
// writeField includes payload size
|
||||
foamVtkOutput::writeField(format(), fld, cellMap);
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,25 +108,27 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
const UPtrList<const GeometricField<Type, PatchField, pointMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
const labelList& addPointCellLabels = vtkCells_.addPointCellLabels();
|
||||
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
|
||||
// Only needed for non-legacy
|
||||
const uint64_t payLoad
|
||||
(
|
||||
nVals * nCmpt * sizeof(float)
|
||||
);
|
||||
const uint64_t payLoad(nVals * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, i)
|
||||
{
|
||||
const auto& fld = flds[i];
|
||||
|
||||
// Legacy
|
||||
os()<< fld.name() << ' '
|
||||
<< nCmpt << ' '
|
||||
<< nVals << " float"
|
||||
<< nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), fld.name(), nCmpt, nVals);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), fld);
|
||||
@ -116,6 +140,11 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,31 +156,38 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
const UPtrList<const DimensionedField<Type, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
const labelList& addPointCellLabels = vtkCells_.addPointCellLabels();
|
||||
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
|
||||
// Only needed for non-legacy
|
||||
const uint64_t payLoad
|
||||
(
|
||||
nVals * nCmpt * sizeof(float)
|
||||
);
|
||||
const uint64_t payLoad(nVals * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, i)
|
||||
{
|
||||
const auto& vfield = flds[i];
|
||||
const auto& pfield = pInterp.interpolate(vfield)();
|
||||
|
||||
// Legacy
|
||||
os()<< vfield.name() << ' '
|
||||
<< nCmpt << ' '
|
||||
<< nVals << " float"
|
||||
<< nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), vfield.name(), nCmpt, nVals);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(vfield.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), pfield);
|
||||
foamVtkOutput::writeList(format(), vfield, addPointCellLabels);
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,31 +199,38 @@ void Foam::foamVtkOutput::internalWriter::write
|
||||
const UPtrList<const GeometricField<Type, PatchField, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
const labelList& addPointCellLabels = vtkCells_.addPointCellLabels();
|
||||
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const int nVals(vtkCells_.nFieldPoints());
|
||||
|
||||
// Only needed for non-legacy
|
||||
const uint64_t payLoad
|
||||
(
|
||||
nVals * nCmpt * sizeof(float)
|
||||
);
|
||||
const uint64_t payLoad(nVals * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, i)
|
||||
{
|
||||
const auto& vfield = flds[i];
|
||||
const auto& pfield = pInterp.interpolate(vfield)();
|
||||
|
||||
// Legacy
|
||||
os()<< vfield.name() << ' '
|
||||
<< nCmpt << ' '
|
||||
<< nVals << " float"
|
||||
<< nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), vfield.name(), nCmpt, nVals);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(vfield.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), pfield);
|
||||
foamVtkOutput::writeList(format(), vfield, addPointCellLabels);
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,206 @@ License
|
||||
#include "foamVtkPatchWriter.H"
|
||||
#include "foamVtkOutput.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::beginPiece()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.openTag(vtkFileTag::PIECE)
|
||||
( "NumberOfPoints", nPoints_ )
|
||||
( "NumberOfPolys", nFaces_ )
|
||||
.closeTag();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writePoints()
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
// payload count
|
||||
const uint64_t payLoad = (nPoints_*3* sizeof(float));
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::beginPoints(os_, nPoints_);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::POINTS)
|
||||
.openDataArray<float, 3>(vtkFileTag::POINTS)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
foamVtkOutput::writeList(format(), pp.localPoints());
|
||||
}
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.endDataArray()
|
||||
.endTag(vtkFileTag::POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writePolysLegacy()
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
// connectivity count without additional storage (done internally)
|
||||
uint64_t nConnectivity = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
nConnectivity += pp[facei].size();
|
||||
}
|
||||
}
|
||||
|
||||
legacy::beginPolys(os_, nFaces_, nConnectivity);
|
||||
|
||||
|
||||
// legacy: size + connectivity together
|
||||
// [nPts, id1, id2, ..., nPts, id1, id2, ...]
|
||||
|
||||
label off = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
const face& f = pp.localFaces()[facei];
|
||||
|
||||
format().write(f.size()); // The size prefix
|
||||
forAll(f, fi)
|
||||
{
|
||||
format().write(off + f[fi]);
|
||||
}
|
||||
}
|
||||
off += pp.nPoints();
|
||||
}
|
||||
|
||||
format().flush();
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writePolys()
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
//
|
||||
|
||||
format().tag(vtkFileTag::POLYS);
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
//
|
||||
{
|
||||
// payload count
|
||||
uint64_t payLoad = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
const face& f = pp.localFaces()[facei];
|
||||
payLoad += f.size();
|
||||
}
|
||||
}
|
||||
|
||||
format().openDataArray<label>("connectivity")
|
||||
.closeTag();
|
||||
|
||||
// payload size
|
||||
format().writeSize(payLoad * sizeof(label));
|
||||
|
||||
label off = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
const face& f = pp.localFaces()[facei];
|
||||
forAll(f, fi)
|
||||
{
|
||||
format().write(off + f[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
off += pp.nPoints();
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
format()
|
||||
.endDataArray();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'offsets' (connectivity offsets)
|
||||
//
|
||||
{
|
||||
format()
|
||||
.openDataArray<label>("offsets")
|
||||
.closeTag();
|
||||
|
||||
// payload size
|
||||
format().writeSize(nFaces_ * sizeof(label));
|
||||
|
||||
label off = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
off += pp[facei].size();
|
||||
|
||||
format().write(off);
|
||||
}
|
||||
}
|
||||
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
format().endTag(vtkFileTag::POLYS);
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writeMesh()
|
||||
{
|
||||
writePoints();
|
||||
if (legacy_)
|
||||
{
|
||||
writePolysLegacy();
|
||||
}
|
||||
else
|
||||
{
|
||||
writePolys();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::foamVtkOutput::patchWriter::patchWriter
|
||||
@ -38,84 +238,56 @@ Foam::foamVtkOutput::patchWriter::patchWriter
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
legacy_(outOpts.legacy()),
|
||||
format_(),
|
||||
nearCellValue_(nearCellValue),
|
||||
patchIDs_(patchIDs),
|
||||
os_()
|
||||
os_(),
|
||||
nPoints_(0),
|
||||
nFaces_(0)
|
||||
{
|
||||
outputOptions opts(outOpts);
|
||||
opts.legacy(true); // Legacy only, no append
|
||||
opts.append(false); // No append
|
||||
|
||||
os_.open((baseName + (opts.legacy() ? ".vtk" : ".vtp")).c_str());
|
||||
os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str());
|
||||
format_ = opts.newFormatter(os_);
|
||||
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
if (opts.legacy())
|
||||
{
|
||||
foamVtkOutput::legacy::fileHeader
|
||||
(
|
||||
format(),
|
||||
(
|
||||
patchIDs_.size() == 1
|
||||
? patches[patchIDs_.first()].name()
|
||||
: "patches"
|
||||
)
|
||||
) << "DATASET POLYDATA" << nl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Write topology
|
||||
nPoints_ = 0;
|
||||
nFaces_ = 0;
|
||||
label nFaceVerts = 0;
|
||||
const word& title =
|
||||
(
|
||||
patchIDs_.size() == 1
|
||||
? patches[patchIDs_.first()].name()
|
||||
: "patches"
|
||||
);
|
||||
|
||||
// Basic sizes
|
||||
nPoints_ = nFaces_ = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
nPoints_ += pp.nPoints();
|
||||
nFaces_ += pp.size();
|
||||
|
||||
nFaceVerts += pp.size();
|
||||
forAll(pp, facei)
|
||||
{
|
||||
nFaceVerts += pp[facei].size();
|
||||
}
|
||||
nFaces_ += pp.size();
|
||||
}
|
||||
|
||||
os_ << "POINTS " << nPoints_ << " float" << nl;
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
if (legacy_)
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
|
||||
foamVtkOutput::writeList(format(), pp.localPoints());
|
||||
legacy::fileHeader(format(), title, vtkFileTag::POLY_DATA);
|
||||
}
|
||||
format().flush();
|
||||
|
||||
os_ << "POLYGONS " << nFaces_ << ' ' << nFaceVerts << nl;
|
||||
|
||||
label off = 0;
|
||||
forAll(patchIDs_, i)
|
||||
else
|
||||
{
|
||||
const polyPatch& pp = patches[patchIDs_[i]];
|
||||
// XML (inline)
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
const face& f = pp.localFaces()[facei];
|
||||
|
||||
format().write(f.size());
|
||||
forAll(f, fi)
|
||||
{
|
||||
format().write(off + f[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
off += pp.nPoints();
|
||||
format()
|
||||
.xmlHeader()
|
||||
.xmlComment(title)
|
||||
.beginVTKFile(vtkFileTag::POLY_DATA, "0.1");
|
||||
}
|
||||
format().flush();
|
||||
|
||||
beginPiece();
|
||||
writeMesh();
|
||||
}
|
||||
|
||||
|
||||
@ -129,40 +301,107 @@ Foam::foamVtkOutput::patchWriter::~patchWriter()
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::beginCellData(label nFields)
|
||||
{
|
||||
foamVtkOutput::legacy::cellDataHeader(os(), nFaces_, nFields);
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader
|
||||
(
|
||||
os(),
|
||||
vtkFileTag::CELL_DATA,
|
||||
nFaces_,
|
||||
nFields
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::endCellData()
|
||||
{}
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::beginPointData(label nFields)
|
||||
{
|
||||
foamVtkOutput::legacy::pointDataHeader(os(), nPoints_, nFields);
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader
|
||||
(
|
||||
os(),
|
||||
vtkFileTag::POINT_DATA,
|
||||
nPoints_,
|
||||
nFields
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::POINT_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::endPointData()
|
||||
{}
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::POINT_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writeFooter()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
// slight cheat. </Piece> too
|
||||
format().endTag(vtkFileTag::PIECE);
|
||||
|
||||
format().endTag(vtkFileTag::POLY_DATA)
|
||||
.endVTKFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::patchWriter::writePatchIDs()
|
||||
{
|
||||
os_ << "patchID 1 " << nFaces_ << " float" << nl;
|
||||
// Patch ids first
|
||||
const uint64_t payLoad = nFaces_ * sizeof(label);
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::intField(os_, "patchID", 1, nFaces_);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<label>("patchID")
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const label patchId = patchIDs_[i];
|
||||
|
||||
const polyPatch& pp = mesh_.boundaryMesh()[patchId];
|
||||
const label sz = mesh_.boundaryMesh()[patchId].size();
|
||||
|
||||
forAll(pp, facei)
|
||||
for (label facei = 0; facei < sz; ++facei)
|
||||
{
|
||||
format().write(patchId);
|
||||
}
|
||||
}
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -59,20 +59,51 @@ namespace foamVtkOutput
|
||||
|
||||
class patchWriter
|
||||
{
|
||||
//- Reference to the OpenFOAM mesh (or subset)
|
||||
const fvMesh& mesh_;
|
||||
// Private Member Data
|
||||
|
||||
autoPtr<foamVtkOutput::formatter> format_;
|
||||
//- Reference to the OpenFOAM mesh (or subset)
|
||||
const fvMesh& mesh_;
|
||||
|
||||
const bool nearCellValue_;
|
||||
//- Commonly used query
|
||||
const bool legacy_;
|
||||
|
||||
const labelList patchIDs_;
|
||||
autoPtr<foamVtkOutput::formatter> format_;
|
||||
|
||||
std::ofstream os_;
|
||||
const bool nearCellValue_;
|
||||
|
||||
label nPoints_;
|
||||
const labelList patchIDs_;
|
||||
|
||||
std::ofstream os_;
|
||||
|
||||
label nPoints_;
|
||||
|
||||
label nFaces_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Begin piece
|
||||
void beginPiece();
|
||||
|
||||
//- Write patch points
|
||||
void writePoints();
|
||||
|
||||
//- Write patch faces
|
||||
void writePolysLegacy();
|
||||
|
||||
//- Write patch faces
|
||||
void writePolys();
|
||||
|
||||
//- Write mesh topology
|
||||
void writeMesh();
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
patchWriter(const patchWriter&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const patchWriter&) = delete;
|
||||
|
||||
label nFaces_;
|
||||
|
||||
public:
|
||||
|
||||
@ -132,6 +163,10 @@ public:
|
||||
//- Write cellIDs
|
||||
void writePatchIDs();
|
||||
|
||||
//- Write file footer
|
||||
void writeFooter();
|
||||
|
||||
|
||||
//- Write volFields
|
||||
template<class Type, template<class> class PatchField>
|
||||
void write
|
||||
|
||||
@ -34,13 +34,24 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
const UPtrList<const GeometricField<Type, PatchField, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const uint64_t payLoad(nFaces_ * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, fieldi)
|
||||
{
|
||||
const auto& fld = flds[fieldi];
|
||||
|
||||
os_ << fld.name() << ' '
|
||||
<< int(pTraits<Type>::nComponents) << ' '
|
||||
<< nFaces_ << " float" << nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os_, fld.name(), nCmpt, nFaces_);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
@ -57,6 +68,11 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,13 +83,24 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
const UPtrList<const GeometricField<Type, PatchField, pointMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const uint64_t payLoad(nPoints_ * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, fieldi)
|
||||
{
|
||||
const auto& fld = flds[fieldi];
|
||||
|
||||
os_ << fld.name() << ' '
|
||||
<< int(pTraits<Type>::nComponents) << ' '
|
||||
<< nPoints_ << " float" << nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os_, fld.name(), nCmpt, nPoints_);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
@ -81,7 +108,13 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
|
||||
foamVtkOutput::writeList(format(), pfld.patchInternalField()());
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,15 +126,24 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const uint64_t payLoad(nPoints_ * nCmpt * sizeof(float));
|
||||
|
||||
forAll(flds, fieldi)
|
||||
{
|
||||
const auto& fld = flds[fieldi];
|
||||
|
||||
os_ << fld.name() << ' '
|
||||
<< int(pTraits<Type>::nComponents) << ' '
|
||||
<< nPoints_ << " float" << nl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os_, fld.name(), nCmpt, nPoints_);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nPoints_);
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
@ -121,7 +163,13 @@ void Foam::foamVtkOutput::patchWriter::write
|
||||
foamVtkOutput::writeList(format(), tfield());
|
||||
}
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,158 @@ License
|
||||
#include "foamVtkSurfaceMeshWriter.H"
|
||||
#include "foamVtkOutput.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::beginPiece()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.openTag(vtkFileTag::PIECE)
|
||||
( "NumberOfPoints", pp_.nPoints() )
|
||||
( "NumberOfPolys", pp_.size() )
|
||||
.closeTag();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::writePoints()
|
||||
{
|
||||
// payload count
|
||||
const uint64_t payLoad = (pp_.nPoints()*3*sizeof(float));
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::beginPoints(os_, pp_.nPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::POINTS)
|
||||
.openDataArray<float, 3>(vtkFileTag::POINTS)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
foamVtkOutput::writeList(format(), pp_.localPoints());
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.endDataArray()
|
||||
.endTag(vtkFileTag::POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::writePolysLegacy()
|
||||
{
|
||||
// connectivity count without additional storage (done internally)
|
||||
uint64_t nConnectivity = 0;
|
||||
forAll(pp_, facei)
|
||||
{
|
||||
nConnectivity += pp_[facei].size();
|
||||
}
|
||||
|
||||
legacy::beginPolys(os_, pp_.size(), nConnectivity);
|
||||
|
||||
|
||||
// legacy: size + connectivity together
|
||||
// [nPts, id1, id2, ..., nPts, id1, id2, ...]
|
||||
|
||||
forAll(pp_, facei)
|
||||
{
|
||||
const face& f = pp_.localFaces()[facei];
|
||||
|
||||
format().write(f.size()); // The size prefix
|
||||
foamVtkOutput::writeList(format(), f);
|
||||
}
|
||||
|
||||
format().flush();
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::writePolys()
|
||||
{
|
||||
//
|
||||
// 'connectivity'
|
||||
//
|
||||
|
||||
format().tag(vtkFileTag::POLYS);
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
//
|
||||
{
|
||||
// payload count
|
||||
uint64_t payLoad = 0;
|
||||
forAll(pp_, facei)
|
||||
{
|
||||
payLoad += pp_[facei].size();
|
||||
}
|
||||
|
||||
format().openDataArray<label>("connectivity")
|
||||
.closeTag();
|
||||
|
||||
// payload size
|
||||
format().writeSize(payLoad * sizeof(label));
|
||||
|
||||
forAll(pp_, facei)
|
||||
{
|
||||
const face& f = pp_.localFaces()[facei];
|
||||
foamVtkOutput::writeList(format(), f);
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
format()
|
||||
.endDataArray();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'offsets' (connectivity offsets)
|
||||
//
|
||||
{
|
||||
format()
|
||||
.openDataArray<label>("offsets")
|
||||
.closeTag();
|
||||
|
||||
// payload size
|
||||
format().writeSize(pp_.size() * sizeof(label));
|
||||
|
||||
label off = 0;
|
||||
forAll(pp_, facei)
|
||||
{
|
||||
off += pp_[facei].size();
|
||||
|
||||
format().write(off);
|
||||
}
|
||||
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
format().endTag(vtkFileTag::POLYS);
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::writeMesh()
|
||||
{
|
||||
writePoints();
|
||||
if (legacy_)
|
||||
{
|
||||
writePolysLegacy();
|
||||
}
|
||||
else
|
||||
{
|
||||
writePolys();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::foamVtkOutput::surfaceMeshWriter::surfaceMeshWriter
|
||||
@ -37,46 +189,33 @@ Foam::foamVtkOutput::surfaceMeshWriter::surfaceMeshWriter
|
||||
)
|
||||
:
|
||||
pp_(pp),
|
||||
legacy_(outOpts.legacy()),
|
||||
format_(),
|
||||
os_()
|
||||
{
|
||||
outputOptions opts(outOpts);
|
||||
opts.legacy(true); // Legacy only, no append
|
||||
opts.legacy(true); // No append supported
|
||||
|
||||
os_.open((baseName + (opts.legacy() ? ".vtk" : ".vtp")).c_str());
|
||||
os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str());
|
||||
format_ = opts.newFormatter(os_);
|
||||
|
||||
if (opts.legacy())
|
||||
if (legacy_)
|
||||
{
|
||||
foamVtkOutput::legacy::fileHeader(format(), name)
|
||||
<< "DATASET POLYDATA" << nl;
|
||||
legacy::fileHeader(format(), name, vtkFileTag::POLY_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XML (inline)
|
||||
|
||||
format()
|
||||
.xmlHeader()
|
||||
.xmlComment(name)
|
||||
.beginVTKFile(vtkFileTag::POLY_DATA, "0.1");
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Write topology
|
||||
label nFaceVerts = pp.size();
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
nFaceVerts += pp[facei].size();
|
||||
}
|
||||
|
||||
os_ << "POINTS " << pp.nPoints() << " float" << nl;
|
||||
|
||||
foamVtkOutput::writeList(format(), pp.localPoints());
|
||||
format().flush();
|
||||
|
||||
os_ << "POLYGONS " << pp.size() << ' ' << nFaceVerts << nl;
|
||||
|
||||
forAll(pp, facei)
|
||||
{
|
||||
const face& f = pp.localFaces()[facei];
|
||||
|
||||
format().write(f.size());
|
||||
foamVtkOutput::writeList(format(), f);
|
||||
}
|
||||
format().flush();
|
||||
beginPiece();
|
||||
writeMesh();
|
||||
}
|
||||
|
||||
|
||||
@ -90,12 +229,37 @@ Foam::foamVtkOutput::surfaceMeshWriter::~surfaceMeshWriter()
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::beginCellData(label nFields)
|
||||
{
|
||||
foamVtkOutput::legacy::cellDataHeader(os(), pp_.size(), nFields);
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader(os(), vtkFileTag::CELL_DATA, pp_.size(), nFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::endCellData()
|
||||
{}
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::CELL_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamVtkOutput::surfaceMeshWriter::writeFooter()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
// slight cheat. </Piece> too
|
||||
format().endTag(vtkFileTag::PIECE);
|
||||
|
||||
format().endTag(vtkFileTag::POLY_DATA)
|
||||
.endVTKFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -58,12 +58,41 @@ namespace foamVtkOutput
|
||||
|
||||
class surfaceMeshWriter
|
||||
{
|
||||
const indirectPrimitivePatch& pp_;
|
||||
// Private Member Data
|
||||
|
||||
autoPtr<foamVtkOutput::formatter> format_;
|
||||
const indirectPrimitivePatch& pp_;
|
||||
|
||||
std::ofstream os_;
|
||||
//- Commonly used query
|
||||
const bool legacy_;
|
||||
|
||||
autoPtr<foamVtkOutput::formatter> format_;
|
||||
|
||||
std::ofstream os_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Begin piece
|
||||
void beginPiece();
|
||||
|
||||
//- Write patch points
|
||||
void writePoints();
|
||||
|
||||
//- Write patch faces
|
||||
void writePolysLegacy();
|
||||
|
||||
//- Write patch faces
|
||||
void writePolys();
|
||||
|
||||
//- Write mesh topology
|
||||
void writeMesh();
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
surfaceMeshWriter(const surfaceMeshWriter&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const surfaceMeshWriter&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
@ -95,19 +124,25 @@ public:
|
||||
return format_();
|
||||
}
|
||||
|
||||
//- Open write for CellData of count fields.
|
||||
// The parameters are only used for the legacy format.
|
||||
void beginCellData(label nFields);
|
||||
|
||||
//- Close write for CellData
|
||||
void endCellData();
|
||||
|
||||
//- Write file footer
|
||||
void writeFooter();
|
||||
|
||||
//- Extract face data
|
||||
|
||||
//- Get face field
|
||||
template<class Type>
|
||||
tmp<Field<Type>> getFaceField
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
|
||||
) const;
|
||||
|
||||
//- Write surfaceFields
|
||||
//- Write surface fields
|
||||
template<class Type>
|
||||
void write
|
||||
(
|
||||
|
||||
@ -50,7 +50,7 @@ Foam::foamVtkOutput::surfaceMeshWriter::getFaceField
|
||||
}
|
||||
else
|
||||
{
|
||||
label localFacei = facei - patches[patchi].start();
|
||||
const label localFacei = facei - patches[patchi].start();
|
||||
fld[i] = sfld.boundaryField()[patchi][localFacei];
|
||||
}
|
||||
}
|
||||
@ -68,18 +68,32 @@ void Foam::foamVtkOutput::surfaceMeshWriter::write
|
||||
>& sflds
|
||||
)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
const uint64_t payLoad(pp_.size() * nCmpt * sizeof(float));
|
||||
|
||||
forAll(sflds, fieldi)
|
||||
{
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld =
|
||||
sflds[fieldi];
|
||||
const auto& fld = sflds[fieldi];
|
||||
|
||||
os_ << fld.name() << ' '
|
||||
<< int(pTraits<Type>::nComponents) << ' '
|
||||
<< pp_.size() << " float" << std::endl;
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::floatField(os(), fld.name(), nCmpt, pp_.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), getFaceField(fld)());
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,47 +41,98 @@ void Foam::foamVtkOutput::writeSurfFields
|
||||
)
|
||||
{
|
||||
outputOptions opts(outOpts);
|
||||
opts.legacy(true); // Legacy only, no append
|
||||
opts.append(false); // No append supported
|
||||
|
||||
std::ofstream os((baseName + (opts.legacy() ? ".vtk" : ".vtp")).c_str());
|
||||
const bool legacy_(opts.legacy());
|
||||
|
||||
std::ofstream os((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str());
|
||||
autoPtr<foamVtkOutput::formatter> format = opts.newFormatter(os);
|
||||
|
||||
if (opts.legacy())
|
||||
// Same payload size for points and vector fields!
|
||||
const int nCmpt(3); // vector
|
||||
const uint64_t payLoad(mesh.nFaces() * 3 * sizeof(float));
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
foamVtkOutput::legacy::fileHeader(format(), "surfaceFields")
|
||||
<< "DATASET POLYDATA" << nl;
|
||||
legacy::fileHeader(format(), "surfaceFields", vtkFileTag::POLY_DATA);
|
||||
legacy::beginPoints(os, mesh.nFaces());
|
||||
}
|
||||
else
|
||||
{
|
||||
// XML (inline)
|
||||
|
||||
format()
|
||||
.xmlHeader()
|
||||
.xmlComment("surfaceFields")
|
||||
.beginVTKFile(vtkFileTag::POLY_DATA, "0.1");
|
||||
|
||||
// Tricky - hide in beginPiece()
|
||||
format()
|
||||
.openTag(vtkFileTag::PIECE)
|
||||
( "NumberOfPoints", mesh.nFaces() )
|
||||
.closeTag();
|
||||
|
||||
format().tag(vtkFileTag::POINTS)
|
||||
.openDataArray<float,3>(vtkFileTag::POINTS)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
const pointField& fc = mesh.faceCentres();
|
||||
|
||||
os << "POINTS " << mesh.nFaces() << " float" << nl;
|
||||
|
||||
format().writeSize(payLoad);
|
||||
foamVtkOutput::writeList(format(), fc);
|
||||
format().flush();
|
||||
|
||||
foamVtkOutput::legacy::pointDataHeader
|
||||
(
|
||||
os,
|
||||
mesh.nFaces(),
|
||||
surfVectorFields.size()
|
||||
);
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.endDataArray()
|
||||
.endTag(vtkFileTag::POINTS);
|
||||
}
|
||||
|
||||
|
||||
// Fields
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::dataHeader
|
||||
(
|
||||
os,
|
||||
vtkFileTag::POINT_DATA,
|
||||
mesh.nFaces(),
|
||||
surfVectorFields.size()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().tag(vtkFileTag::POINT_DATA);
|
||||
}
|
||||
|
||||
// surfVectorFields
|
||||
forAll(surfVectorFields, fieldi)
|
||||
{
|
||||
const surfaceVectorField& svf = surfVectorFields[fieldi];
|
||||
const auto& fld = surfVectorFields[fieldi];
|
||||
|
||||
os << svf.name() << " 3 " << mesh.nFaces() << " float" << nl;
|
||||
for (label facei=0; facei < mesh.nInternalFaces(); ++facei)
|
||||
if (legacy_)
|
||||
{
|
||||
foamVtkOutput::write(format(), svf[facei]);
|
||||
legacy::floatField(os, fld.name(), nCmpt, mesh.nFaces());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fld.name())
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
forAll(svf.boundaryField(), patchi)
|
||||
format().writeSize(payLoad);
|
||||
|
||||
for (label facei=0; facei < mesh.nInternalFaces(); ++facei)
|
||||
{
|
||||
foamVtkOutput::write(format(), fld[facei]);
|
||||
}
|
||||
|
||||
forAll(fld.boundaryField(), patchi)
|
||||
{
|
||||
const fvPatch& pp = mesh.boundary()[patchi];
|
||||
const fvsPatchVectorField& pf = svf.boundaryField()[patchi];
|
||||
const auto& pf = fld.boundaryField()[patchi];
|
||||
|
||||
if (isA<emptyFvsPatchVectorField>(pf))
|
||||
{
|
||||
@ -98,6 +149,22 @@ void Foam::foamVtkOutput::writeSurfFields
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endTag(vtkFileTag::POINT_DATA);
|
||||
|
||||
// slight cheat. </Piece> too
|
||||
format().endTag(vtkFileTag::PIECE);
|
||||
|
||||
format().endTag(vtkFileTag::POLY_DATA)
|
||||
.endVTKFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ InNamespace
|
||||
Foam::foamVtkOutput
|
||||
|
||||
Description
|
||||
Write a patch with its data.
|
||||
Write surface fields as vectors
|
||||
|
||||
SourceFiles
|
||||
foamVtkWriteSurfFields.C
|
||||
|
||||
Reference in New Issue
Block a user