diff --git a/applications/test/vtmWriter/Make/files b/applications/test/vtmWriter/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..4a16ec021696d6f9178cb8107131bef8f6d59662 --- /dev/null +++ b/applications/test/vtmWriter/Make/files @@ -0,0 +1,3 @@ +Test-vtmWriter.C + +EXE = $(FOAM_APPBIN)/Test-vtmWriter diff --git a/applications/test/vtmWriter/Make/options b/applications/test/vtmWriter/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..7ce182425d9bee4bef91ba2a36b6b8475fc1aeb2 --- /dev/null +++ b/applications/test/vtmWriter/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/fileFormats/lnInclude + +EXE_LIBS = \ + -lfileFormats diff --git a/applications/test/vtmWriter/Test-vtmWriter.C b/applications/test/vtmWriter/Test-vtmWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..234268d779fbb329a2174dca704c77879de9b670 --- /dev/null +++ b/applications/test/vtmWriter/Test-vtmWriter.C @@ -0,0 +1,159 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-vtmWriter + +Description + Basic functionality tests for vtk::vtmWriter + +\*---------------------------------------------------------------------------*/ + +#include "foamVtmWriter.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + vtk::vtmWriter writer1; + { + fileName base = "region1_0001"; + + writer1.beginBlock("internal"); + writer1.append_vtu + ( + base/"internal" + ); + writer1.endBlock("internal"); + + { + writer1.beginBlock("boundary"); + writer1.append_vtp + ( + base/"patch0" + ); + writer1.append(""); // bad entry + writer1.append_vtp + ( + base/"patch1" + ); + writer1.append_vtp + ( + base/"patch2" + ); + } + + writer1.endBlock("boundary"); + + { + writer1.beginBlock("empty"); + writer1.endBlock("empty"); + } + { + writer1.beginBlock("dangling1"); + writer1.beginBlock("dangling2"); + } + } + + Info<< nl << "vtm information" << nl; + writer1.dump(Info), + Info<< nl; + +// writer1.repair(); +// +// Info<< nl << "vtm information - after repair" << nl; +// writer1.dump(Info), +// Info<< nl; + + writer1.repair(true); + +// Info<< nl << "vtm information - after repair(collapse)" << nl; +// writer1.dump(Info), +// Info<< nl; +// +// Info<< nl << "vtm information - after repair(collapse)" << nl; +// writer1.dump(Info), +// Info<< nl; + + Info<< nl << "Write to file" << nl; + writer1.write("vtmWriter1.vtm"); + + + vtk::vtmWriter writer2; + { + fileName base = "region2_0001"; + + writer2.beginBlock("internal"); + writer2.append_vtu + ( + base/"internal" + ); + writer2.endBlock("internal"); + + { + writer2.beginBlock("boundary"); + writer2.append_vtp + ( + base/"patch0" + ); + writer2.append(""); // bad entry + writer2.append_vtp + ( + base/"patch1" + ); + writer2.append_vtp + ( + base/"patch2" + ); + } + + writer2.endBlock("boundary"); + + // These should be automatically skiped + writer2.endBlock(); + writer2.endBlock(); + writer2.endBlock(); + writer2.endBlock(); + } + + Info<< nl << "vtm information" << nl; + writer2.dump(Info); + + writer2.repair(true); + + + vtk::vtmWriter writer3; + + writer3.add("some-region1", writer1); + writer3.add("some-region2", writer2); + + Info<< nl << "Combined:" << nl; + writer3.dump(Info); + + return 0; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/Make/files b/src/fileFormats/Make/files index 678c9c418ee58f37c6fb651391858e8483a02c2d..640d98882bf31900f33ff30ca6f13cf793f55e11 100644 --- a/src/fileFormats/Make/files +++ b/src/fileFormats/Make/files @@ -17,6 +17,7 @@ stl/STLAsciiParseManual.C stl/STLAsciiParseRagel.C vtk/file/foamVtkFileWriter.C +vtk/file/foamVtmWriter.C vtk/core/foamVtkCore.C vtk/core/foamVtkPTraits.C diff --git a/src/fileFormats/vtk/file/foamVtmWriter.C b/src/fileFormats/vtk/file/foamVtmWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..d935c22c762dd45b175fc057501eaa3ed5f2c592 --- /dev/null +++ b/src/fileFormats/vtk/file/foamVtmWriter.C @@ -0,0 +1,694 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include <fstream> +#include "foamVtmWriter.H" +#include "Time.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * * * * Local Class * * * * * * * * * * * * * * * // + +void Foam::vtk::vtmWriter::vtmEntry::clear() +{ + type_ = NONE; + name_.clear(); + file_.clear(); +} + + +bool Foam::vtk::vtmWriter::vtmEntry::good() const +{ + return + ( + type_ == vtmEntry::BEGIN_BLOCK + || type_ == vtmEntry::END_BLOCK + || (type_ == vtmEntry::DATA && file_.size()) + ); +} + + +bool Foam::vtk::vtmWriter::vtmEntry::write(vtk::formatter& format) const +{ + if (type_ == vtmEntry::BEGIN_BLOCK) + { + format.openTag(vtk::fileTag::BLOCK); + if (name_.size()) + { + format.xmlAttr("name", name_); + } + format.closeTag(); + + return true; + } + else if (type_ == vtmEntry::END_BLOCK) + { + format.endBlock(); + return true; + } + else if (type_ == vtmEntry::DATA && file_.size()) + { + format.openTag(vtk::fileTag::DATA_SET); + + if (name_.size()) + { + format.xmlAttr("name", name_); + } + + format.xmlAttr("file", file_); + + format.closeTag(true); // Empty tag. ie, <DataSet ... /> + return true; + } + + return false; +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::vtk::vtmWriter::pruneEmpty() +{ + const label nEntries = entries_.size(); + + label dst=0; + + for (label src=0; src < nEntries; ++src) + { + if (entries_[src].good()) + { + if (dst != src) + { + entries_[dst] = std::move(entries_[src]); + } + ++dst; + } + } + + const bool changed = (dst != nEntries); + entries_.resize(dst); + + return changed; +} + + +bool Foam::vtk::vtmWriter::pruneEmptyBlocks() +{ + bool pruned = false; + + const label nEntries = entries_.size(); + + while (true) + { + bool changed = false; + + for (label i=0; i < nEntries; ++i) + { + vtmEntry& e = entries_[i]; + + if (e.isType(vtmEntry::BEGIN_BLOCK)) + { + for (label j=i+1; j < nEntries; ++j) + { + if (entries_[j].isType(vtmEntry::END_BLOCK)) + { + e.clear(); + entries_[j].clear(); + + changed = true; + break; + } + else if (!entries_[j].isType(vtmEntry::NONE)) + { + break; + } + } + } + } + + if (changed) + { + pruned = true; + } + else + { + break; + } + } + + // Collapse single-entry blocks when the names allow it + + // Transcribe, removing NONE entries + pruneEmpty(); + + return pruned; +} + + +bool Foam::vtk::vtmWriter::collapseBlocks() +{ + bool collapsed = false; + + const label nEntries = entries_.size(); + + for (label i=0; i < nEntries-2; ++i) + { + vtmEntry& b = entries_[i]; // begin + vtmEntry& d = entries_[i+1]; // data + vtmEntry& e = entries_[i+2]; // end + + if + ( + b.isType(vtmEntry::BEGIN_BLOCK) + && e.isType(vtmEntry::END_BLOCK) + && d.isType(vtmEntry::DATA) + && (d.name_.empty() || d.name_ == b.name_) + ) + { + d.name_ = std::move(b.name_); + + b.clear(); + e.clear(); + + collapsed = true; + } + } + + pruneEmpty(); + + return collapsed; +} + + +void Foam::vtk::vtmWriter::repair(bool collapse) +{ + // Add or remove END_BLOCK + + label depth = 0; + label nEntries = 0; + + for (vtmEntry& e : entries_) + { + if (e.isType(vtmEntry::BEGIN_BLOCK)) + { + ++depth; + } + else if (e.isType(vtmEntry::END_BLOCK)) + { + --depth; + + if (depth < 0) + { + // Truncate now and exit + entries_.resize(nEntries); + break; + } + } + else if (e.isType(vtmEntry::DATA)) + { + if (e.file_.empty()) + { + // Bad entry - reset to NONE + e.clear(); + } + } + + ++nEntries; + } + + // Close any dangling blocks + while (depth--) + { + entries_.append(vtmEntry::endblock()); + } + + blocks_.clear(); + pruneEmpty(); + + if (collapse) + { + pruneEmptyBlocks(); + collapseBlocks(); + } +} + + +void Foam::vtk::vtmWriter::dump(Ostream& os) const +{ + label depth = 0; + + // Output format is a mix of dictionary and JSON + // the only purpose being for diagnostics + + for (const vtmEntry& e : entries_) + { + switch (e.type_) + { + case vtmEntry::NONE: + { + os.indent(); + os << "none" << nl; + break; + } + case vtmEntry::DATA: + { + os.indent(); + os << "{ \"name\" : " << e.name_ + << ", \"file\" : " << e.file_ << " }" << nl; + break; + } + case vtmEntry::BEGIN_BLOCK: + { + ++depth; + os.beginBlock(e.name_); + break; + } + case vtmEntry::END_BLOCK: + { + --depth; + os.endBlock(); + os << nl; + break; + } + } + } + + for (label i=0; i < depth; ++i) + { + os.decrIndent(); + } + + if (depth > 0) + { + os << "# Had " << depth << " unclosed blocks" << nl; + } + if (depth < 0) + { + os << "# Had " << (-depth) << " too many end blocks" << nl; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::vtmWriter::vtmWriter() +: + vtmWriter(true, false) +{} + + +Foam::vtk::vtmWriter::vtmWriter(bool autoName) +: + vtmWriter(autoName, false) +{} + + +Foam::vtk::vtmWriter::vtmWriter(bool autoName, bool autoCollapse) +: + autoName_(autoName), + autoCollapse_(autoCollapse), + hasTime_(false), + entries_(), + blocks_(), + timeValue_(Zero) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::vtmWriter::clear() +{ + entries_.clear(); + blocks_.clear(); + + timeValue_ = Zero; + hasTime_ = false; +} + + +bool Foam::vtk::vtmWriter::empty() const +{ + for (const auto& e : entries_) + { + if (e.isType(vtmEntry::DATA) && e.name_.size()) + { + return false; + } + } + + return true; +} + + +Foam::label Foam::vtk::vtmWriter::size() const +{ + label ndata = 0; + + for (const auto& e : entries_) + { + if (e.isType(vtmEntry::DATA) && e.file_.size()) + { + ++ndata; + } + } + + return ndata; +} + + +void Foam::vtk::vtmWriter::setTime(scalar timeValue) +{ + timeValue_ = timeValue; + hasTime_ = true; +} + + +void Foam::vtk::vtmWriter::setTime(const Time& t) +{ + timeValue_ = t.value(); + hasTime_ = true; +} + + +Foam::label Foam::vtk::vtmWriter::beginBlock(const word& blockName) +{ + entries_.append(vtmEntry::block(blockName)); + blocks_.append(blockName); + + return blocks_.size(); +} + + +Foam::label Foam::vtk::vtmWriter::endBlock(const word& blockName) +{ + label nblock = blocks_.size(); + + if (nblock) + { + const word curr(blocks_.remove()); + + // Verify expected end tag + if (!blockName.empty() && blockName != curr) + { + WarningInFunction + << "expecting to end block '" << blockName + << "' but found '" << curr << "' instead" + << endl; + } + + entries_.append(vtmEntry::endblock()); + } + + return blocks_.size(); +} + + +bool Foam::vtk::vtmWriter::append(const fileName& file) +{ + if (autoName_) + { + return append(fileName::nameLessExt(file), file); + } + else + { + return append(word::null, file); + } +} + + +bool Foam::vtk::vtmWriter::append +( + const fileName& file, + vtk::fileTag contentType +) +{ + if (autoName_) + { + return append(fileName::nameLessExt(file), file, contentType); + } + else + { + return append(word::null, file, contentType); + } +} + + +bool Foam::vtk::vtmWriter::append +( + const word& name, + const fileName& file +) +{ + if (file.empty()) + { + return false; + } + + entries_.append(vtmEntry::entry(name, file)); + return true; +} + + +bool Foam::vtk::vtmWriter::append +( + const word& name, + const fileName& file, + vtk::fileTag contentType +) +{ + if (file.empty()) + { + return false; + } + + if (file.hasExt(vtk::fileExtension[contentType])) + { + entries_.append(vtmEntry::entry(name, file)); + } + else + { + entries_.append + ( + vtmEntry::entry + ( + name, + file + "." + vtk::fileExtension[contentType] + ) + ); + } + + return true; +} + + +void Foam::vtk::vtmWriter::add +( + const word& blockName, + const fileName& prefix, + const vtmWriter& other +) +{ + // Standard sanity repair (block ending), prune empty entries + repair(); + + beginBlock(blockName); + + label depth = 0; + bool good = true; + + for (const vtmEntry& e : other.entries_) + { + switch (e.type_) + { + case vtmEntry::NONE: + { + break; + } + case vtmEntry::DATA: + { + if (e.good()) + { + entries_.append(e); + + if (prefix.size()) + { + fileName& f = entries_.last().file_; + + f = prefix/f; + } + } + + break; + } + case vtmEntry::BEGIN_BLOCK: + { + ++depth; + entries_.append(e); + break; + } + case vtmEntry::END_BLOCK: + { + good = (depth > 0); + --depth; + if (good) + { + entries_.append(e); + } + break; + } + } + + if (!good) break; + } + + while (depth--) + { + entries_.append(vtmEntry::endblock()); + } + + entries_.append(vtmEntry::endblock()); + + if (!hasTime_ && other.hasTime_) + { + hasTime_ = true; + timeValue_ = other.timeValue_; + } +} + + +void Foam::vtk::vtmWriter::add +( + const word& blockName, + const vtmWriter& other +) +{ + add(blockName, fileName::null, other); +} + + +Foam::label Foam::vtk::vtmWriter::write(const fileName& file) +{ + std::ofstream os_; + + mkDir(file.path()); + + if (file.hasExt(ext())) + { + os_.open(file); + } + else + { + os_.open(file + "." + ext()); + } + + auto format = vtk::newFormatter(os_, formatType::INLINE_ASCII); + + + // Contents Header + { + format().xmlHeader(); + + if (hasTime_) + { + format().xmlComment + ( + "time='" + Foam::name(timeValue_) + "'" + ); + } + + format().beginVTKFile<vtk::fileTag::MULTI_BLOCK>(); + } + + + // Walk the block and dataset contents + + label depth = 0; + label ndata = 0; + + for (const vtmEntry& e : entries_) + { + switch (e.type_) + { + case vtmEntry::DATA: + { + if (e.file_.empty()) + { + continue; // Empty dataset is junk - skip + } + ++ndata; + break; + } + case vtmEntry::BEGIN_BLOCK: + { + ++depth; + break; + } + case vtmEntry::END_BLOCK: + { + --depth; + break; + } + default: + { + continue; + break; + } + } + + if (depth < 0) + { + // Too many end blocks - stop output now. Should we warn? + break; + } + e.write(format()); + } + + // Close any dangling blocks + while (depth--) + { + format().endBlock(); + } + + format().endTag(vtk::fileTag::MULTI_BLOCK); + + + // FieldData for TimeValue + if (hasTime_) + { + format() + .beginFieldData() + .writeTimeValue(timeValue_) + .endFieldData(); + } + + format().endVTKFile(); + + format.clear(); + os_.close(); + + return ndata; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/file/foamVtmWriter.H b/src/fileFormats/vtk/file/foamVtmWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..24b9bed0fd880f7567412cdffadc87664f6688f8 --- /dev/null +++ b/src/fileFormats/vtk/file/foamVtmWriter.H @@ -0,0 +1,342 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::vtk::vtmWriter + +Description + Provides a means of accumulating file entries for generating + a vtkMultiBlockDataSet (.vtm) file. + + For example, to generate the following content: + \verbatim + <?xml version='1.0'?> + <VTKFile type='vtkMultiBlockDataSet' ...> + <vtkMultiBlockDataSet> + <DataSet name='internal' file='internal.vtu' /> + <Block name='boundary'> + <DataSet name='inlet' file='boundary/inlet.vtp' /> + <DataSet name='outlet' file='boundary/outlet.vtp' /> + </Block> + </vtkMultiBlockDataSet> + <FieldData> + <DataArray type='Float32' Name='TimeValue' ...> + 12.345 + </DataArray> + </FieldData> + </VTKFile> + \endverbatim + + The following code would be used: + \code + vtm.clear(); + vtm.setTime(12.345); + + vtm.append("internal", "internal.vtu"); + + vtm.beginBlock("boundary"); + vtm.append("boundary/inlet.vtp"); + vtm.append("boundary/outlet.vtp"); + + vtm.write("outputName"); + \endcode + +SourceFiles + foamVtmWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtmWriter_H +#define foamVtmWriter_H + +#include "foamVtkOutputOptions.H" +#include "DynamicList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declarations +class Time; + +namespace vtk +{ + +/*---------------------------------------------------------------------------*\ + Class vtk::vtmWriter Declaration +\*---------------------------------------------------------------------------*/ + +class vtmWriter +{ + //- Simple structure for containing entries + struct vtmEntry + { + enum Type + { + NONE = 0, + DATA = 'D', + BEGIN_BLOCK = '{', + END_BLOCK = '}' + }; + + //- The entry type + int type_; + + //- The 'name' entry (to describe block or data) + string name_; + + //- The 'file' entry (data only) + fileName file_; + + // Constructors + + vtmEntry(const vtmEntry&) = default; + vtmEntry(vtmEntry&&) = default; + vtmEntry& operator=(const vtmEntry&) = default; + vtmEntry& operator=(vtmEntry&&) = default; + + //- Construct null + vtmEntry() + : + type_(NONE) + {} + + //- Construct from components + vtmEntry(int what, const string& name, const fileName& file) + : + type_(what), name_(name), file_(file) + {} + + + // Factory Methods + + static vtmEntry block(const string& name) + { + return vtmEntry(BEGIN_BLOCK, name, ""); + } + + static vtmEntry endblock() + { + return vtmEntry(END_BLOCK, "", ""); + } + + static vtmEntry entry(const fileName& file) + { + return vtmEntry(DATA, "", file); + } + + static vtmEntry entry(const string& name, const fileName& file) + { + return vtmEntry(DATA, name, file); + } + + + // Member Functions + + //- Test the type + bool isType(Type what) const + { + return type_ == what; + } + + //- Reset to NONE + void clear(); + + //- True if the entry is good. + bool good() const; + + //- Output valid entry as XML + bool write(vtk::formatter& format) const; + }; + + + // Private Member Data + + //- Auto-generate names from 'file' entry? + bool autoName_; + + //- Collapse empty blocks and combine block/dataset etc. + bool autoCollapse_; + + //- Has a TimeValue for FieldData? + bool hasTime_; + + //- A vtm file entry: begin/end block, dataset + DynamicList<vtmEntry> entries_; + + //- LIFO stack of current block names + DynamicList<word> blocks_; + + //- TimeValue for FieldData + scalar timeValue_; + + + // Private Member Functions + + //- Remove NONE entries + bool pruneEmpty(); + + //- Remove empty blocks + bool pruneEmptyBlocks(); + + //- Collapse block if it has a single dataset and the names allow it + bool collapseBlocks(); + + +public: + + // Constructors + + //- Construct null, with autoName on + vtmWriter(); + + //- Construct with specified behaviour for autoName + explicit vtmWriter(bool autoName); + + //- Construct with specified behaviour for autoName, autoCollapse + vtmWriter(bool autoName, bool autoCollapse); + + + //- Destructor + ~vtmWriter() = default; + + + // Member Functions + + //- File extension (always "vtm") + inline static word ext(); + + //- If there are no data sets + bool empty() const; + + //- The number of data sets + label size() const; + + + // Content Management + + //- Clear all entries and reset output + void clear(); + + //- Define "TimeValue" for FieldData (name as per Catalyst output) + void setTime(scalar timeValue); + + //- Define "TimeValue" for FieldData (name as per Catalyst output) + void setTime(const Time& t); + + + //- Start a new block, optionally with a name + // \return block depth + label beginBlock(const word& blockName = word::null); + + //- End the previous block, optionally with name checking + // \return block depth + label endBlock(const word& blockName = word::null); + + + //- Add a file. The name is either empty or created with autoName + // \return True if file is non-empty + bool append(const fileName& file); + + //- Add a file with name + // \return True if file is non-empty + bool append(const word& name, const fileName& file); + + //- Add a file with given contentType extension + //- The name is either empty or created with autoName + // \return True if file is non-empty + bool append(const fileName& file, vtk::fileTag contentType); + + //- Add a file with name, with given contentType extension + // \return True if file is non-empty + bool append + ( + const word& name, + const fileName& file, + vtk::fileTag contentType + ); + + //- Add a (.vtp) file + // \return True if file is non-empty + inline bool append_vtp(const fileName& file); + + //- Add a (.vtp) file with name + // \return True if file is non-empty + inline bool append_vtp(const word& name, const fileName& file); + + //- Add a (.vtu) file + // \return True if file is non-empty + inline bool append_vtu(const fileName& file); + + //- Add a (.vtu) file with name + // \return True if file is non-empty + inline bool append_vtu(const word& name, const fileName& file); + + + // Content Management + + //- Sanity fixes on the data + void repair(bool collapse=false); + + //- Add in content from another vtm and place under the given block + //- name. + void add(const word& blockName, const vtmWriter& other); + + //- Add in content from another vtm and place under the given block + //- name. Adjust the added 'file' entries to include the given prefix. + void add + ( + const word& blockName, + const fileName& prefix, + const vtmWriter& other + ); + + // Writing + + //- Open file for writing (creates parent directory) and write the + //- blocks and TimeValue. + // The file name is with/without an extension. + // \return number of data sets + label write(const fileName& file); + + //- Print debug view of block and dataset contents + void dump(Ostream& os) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "foamVtmWriterI.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/file/foamVtmWriterI.H b/src/fileFormats/vtk/file/foamVtmWriterI.H new file mode 100644 index 0000000000000000000000000000000000000000..90351d70eefe418fc606542ba27e7a5ddcbf003a --- /dev/null +++ b/src/fileFormats/vtk/file/foamVtmWriterI.H @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline Foam::word Foam::vtk::vtmWriter::ext() +{ + return vtk::fileExtension[vtk::fileTag::MULTI_BLOCK]; +} + + +inline bool Foam::vtk::vtmWriter::append_vtp(const fileName& file) +{ + return append(file, vtk::fileTag::POLY_DATA); +} + + +inline bool Foam::vtk::vtmWriter::append_vtp +( + const word& name, + const fileName& file +) +{ + return append(name, file, vtk::fileTag::POLY_DATA); +} + + +inline bool Foam::vtk::vtmWriter::append_vtu(const fileName& file) +{ + return append(file, vtk::fileTag::UNSTRUCTURED_GRID); +} + + +inline bool Foam::vtk::vtmWriter::append_vtu +( + const word& name, + const fileName& file +) +{ + return append(name, file, vtk::fileTag::UNSTRUCTURED_GRID); +} + + +// ************************************************************************* //