diff --git a/applications/utilities/mesh/manipulation/setSet/Make/files b/applications/utilities/mesh/manipulation/setSet/Make/files index e6da558d1db1d047602ccb934d17d2a94d462431..75c578a1e54aefab9c857379dc148d97746adb56 100644 --- a/applications/utilities/mesh/manipulation/setSet/Make/files +++ b/applications/utilities/mesh/manipulation/setSet/Make/files @@ -1,7 +1,3 @@ -writePointSet.C -writeFuns.C -writePatch.C setSet.C EXE = $(FOAM_APPBIN)/setSet - diff --git a/applications/utilities/mesh/manipulation/setSet/Make/options b/applications/utilities/mesh/manipulation/setSet/Make/options index febadade7b4bed3e02b5fef45eed79f404ab0453..7c01749935ced7aef267f83ae15977f8e0cccb51 100644 --- a/applications/utilities/mesh/manipulation/setSet/Make/options +++ b/applications/utilities/mesh/manipulation/setSet/Make/options @@ -1,4 +1,5 @@ EXE_INC = \ + -I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ $(COMP_FLAGS) diff --git a/applications/utilities/mesh/manipulation/setSet/setSet.C b/applications/utilities/mesh/manipulation/setSet/setSet.C index 1dffb5849e9efee00bb84be724b5a1fe96a08265..8ce92fc9b752a4443d0a3739ea643f1c128afd99 100644 --- a/applications/utilities/mesh/manipulation/setSet/setSet.C +++ b/applications/utilities/mesh/manipulation/setSet/setSet.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,8 +44,9 @@ Description #include "OFstream.H" #include "IFstream.H" #include "demandDrivenData.H" -#include "writePatch.H" -#include "writePointSet.H" +#include "foamVtkWriteCellSetFaces.H" +#include "foamVtkWriteFaceSet.H" +#include "foamVtkWritePointSet.H" #include "IOobjectList.H" #include "cellZoneSet.H" #include "faceZoneSet.H" @@ -75,104 +76,39 @@ void writeVTK ( const polyMesh& mesh, const topoSet& currentSet, - const fileName& vtkName + const fileName& vtkBaseName ) { if (isA<faceSet>(currentSet)) { // Faces of set with OpenFOAM faceID as value - - faceList setFaces(currentSet.size()); - labelList faceValues(currentSet.size()); - label setFacei = 0; - - forAllConstIter(topoSet, currentSet, iter) - { - setFaces[setFacei] = mesh.faces()[iter.key()]; - faceValues[setFacei] = iter.key(); - setFacei++; - } - - primitiveFacePatch fp(setFaces, mesh.points()); - - writePatch + vtk::writeFaceSet ( - true, - currentSet.name(), - fp, - "faceID", - faceValues, - mesh.time().path()/vtkName + mesh, + currentSet, + mesh.time().path()/vtkBaseName, + vtk::formatType::LEGACY_BINARY ); } else if (isA<cellSet>(currentSet)) { // External faces of cellset with OpenFOAM cellID as value - - Map<label> cellFaces(currentSet.size()); - - forAllConstIter(cellSet, currentSet, iter) - { - label celli = iter.key(); - - const cell& cFaces = mesh.cells()[celli]; - - forAll(cFaces, i) - { - label facei = cFaces[i]; - - if (mesh.isInternalFace(facei)) - { - label otherCelli = mesh.faceOwner()[facei]; - - if (otherCelli == celli) - { - otherCelli = mesh.faceNeighbour()[facei]; - } - - if (!currentSet.found(otherCelli)) - { - cellFaces.insert(facei, celli); - } - } - else - { - cellFaces.insert(facei, celli); - } - } - } - - faceList setFaces(cellFaces.size()); - labelList faceValues(cellFaces.size()); - label setFacei = 0; - - forAllConstIter(Map<label>, cellFaces, iter) - { - setFaces[setFacei] = mesh.faces()[iter.key()]; - faceValues[setFacei] = iter(); // Cell ID - setFacei++; - } - - primitiveFacePatch fp(setFaces, mesh.points()); - - writePatch + vtk::writeCellSetFaces ( - true, - currentSet.name(), - fp, - "cellID", - faceValues, - mesh.time().path()/vtkName + mesh, + currentSet, + mesh.time().path()/vtkBaseName, + vtk::formatType::LEGACY_BINARY ); } else if (isA<pointSet>(currentSet)) { - writePointSet + vtk::writePointSet ( - true, mesh, currentSet, - mesh.time().path()/vtkName + mesh.time().path()/vtkBaseName, + vtk::formatType::LEGACY_BINARY ); } else @@ -187,58 +123,58 @@ void writeVTK void printHelp(Ostream& os) { os << "Please type 'help', 'list', 'quit', 'time ddd'" - << " or a set command after prompt." << endl - << "'list' will show all current cell/face/point sets." << endl - << "'time ddd' will change the current time." << endl - << endl - << "A set command should be of the following form" << endl - << endl + << " or a set command after prompt." << nl + << "'list' will show all current cell/face/point sets." << nl + << "'time ddd' will change the current time." << nl + << nl + << "A set command should be of the following form" << nl + << nl << " cellSet|faceSet|pointSet <setName> <action> <source>" - << endl - << endl - << "The <action> is one of" << endl - << " list - prints the contents of the set" << endl - << " clear - clears the set" << endl - << " invert - inverts the set" << endl - << " remove - remove the set" << endl - << " new <source> - sets to set to the source set" << endl - << " add <source> - adds all elements from the source set" << endl - << " delete <source> - deletes ,," << endl + << nl + << nl + << "The <action> is one of" << nl + << " list - prints the contents of the set" << nl + << " clear - clears the set" << nl + << " invert - inverts the set" << nl + << " remove - remove the set" << nl + << " new <source> - sets to set to the source set" << nl + << " add <source> - adds all elements from the source set" << nl + << " delete <source> - deletes ,," << nl << " subset <source> - combines current set with the source set" - << endl - << endl + << nl + << nl << "The sources come in various forms. Type a wrong source" - << " to see all the types available." << endl - << endl + << " to see all the types available." << nl + << nl << "Example: pick up all cells connected by point or face to patch" - << " movingWall" << endl - << endl - << "Pick up all faces of patch:" << endl - << " faceSet f0 new patchToFace movingWall" << endl - << "Add faces 0,1,2:" << endl - << " faceSet f0 add labelToFace (0 1 2)" << endl - << "Pick up all points used by faces in faceSet f0:" << endl - << " pointSet p0 new faceToPoint f0 all" << endl - << "Pick up cell which has any face in f0:" << endl - << " cellSet c0 new faceToCell f0 any" << endl - << "Add cells which have any point in p0:" << endl - << " cellSet c0 add pointToCell p0 any" << endl - << "List set:" << endl - << " cellSet c0 list" << endl - << endl - << "Zones can be set using zoneSets from corresponding sets:" << endl - << " cellZoneSet c0Zone new setToCellZone c0" << endl - << " faceZoneSet f0Zone new setToFaceZone f0" << endl - << endl - << "or if orientation is important:" << endl - << " faceZoneSet f0Zone new setsToFaceZone f0 c0" << endl - << endl - << "ZoneSets can be manipulated using the general actions:" << endl - << " list - prints the contents of the set" << endl - << " clear - clears the set" << endl + << " movingWall" << nl + << nl + << "Pick up all faces of patch:" << nl + << " faceSet f0 new patchToFace movingWall" << nl + << "Add faces 0,1,2:" << nl + << " faceSet f0 add labelToFace (0 1 2)" << nl + << "Pick up all points used by faces in faceSet f0:" << nl + << " pointSet p0 new faceToPoint f0 all" << nl + << "Pick up cell which has any face in f0:" << nl + << " cellSet c0 new faceToCell f0 any" << nl + << "Add cells which have any point in p0:" << nl + << " cellSet c0 add pointToCell p0 any" << nl + << "List set:" << nl + << " cellSet c0 list" << nl + << nl + << "Zones can be set using zoneSets from corresponding sets:" << nl + << " cellZoneSet c0Zone new setToCellZone c0" << nl + << " faceZoneSet f0Zone new setToFaceZone f0" << nl + << nl + << "or if orientation is important:" << nl + << " faceZoneSet f0Zone new setsToFaceZone f0 c0" << nl + << nl + << "ZoneSets can be manipulated using the general actions:" << nl + << " list - prints the contents of the set" << nl + << " clear - clears the set" << nl << " invert - inverts the set (undefined orientation)" - << endl - << " remove - remove the set" << endl + << nl + << " remove - remove the set" << nl << endl; } @@ -577,7 +513,6 @@ bool doCommand "VTK"/currentSet.name()/currentSet.name() + "_" + name(mesh.time().timeIndex()) - + ".vtk" ); Info<< " Writing " << currentSet.name() diff --git a/applications/utilities/mesh/manipulation/setSet/writeFuns.C b/applications/utilities/mesh/manipulation/setSet/writeFuns.C deleted file mode 100644 index 2a104cb01ecfa72cbb1c2a41f1bbaec0275c3be0..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/manipulation/setSet/writeFuns.C +++ /dev/null @@ -1,225 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "writeFuns.H" -#include "endian.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -void Foam::writeFuns::swapWord(int32_t& word32) -{ - char* mem = reinterpret_cast<char*>(&word32); - - char a = mem[0]; - mem[0] = mem[3]; - mem[3] = a; - - a = mem[1]; - mem[1] = mem[2]; - mem[2] = a; -} - - -void Foam::writeFuns::swapWords(const label nWords, int32_t* words32) -{ - for (label i=0; i<nWords; i++) - { - swapWord(words32[i]); - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - List<floatScalar>& fField -) -{ - if (binary) - { - #ifdef WM_LITTLE_ENDIAN - swapWords(fField.size(), reinterpret_cast<int32_t*>(fField.begin())); - #endif - - os.write - ( - reinterpret_cast<char*>(fField.begin()), - fField.size()*sizeof(float) - ); - - os << std::endl; - } - else - { - forAll(fField, i) - { - os << fField[i] << ' '; - - if (i > 0 && (i % 10) == 0) - { - os << std::endl; - } - } - os << std::endl; - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - DynamicList<floatScalar>& fField -) -{ - List<floatScalar>& fld = fField.shrink(); - write(os, binary, fld); -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - labelList& elems -) -{ - if (binary) - { - #ifdef WM_LITTLE_ENDIAN - swapWords - ( - (sizeof(label)/4)*elems.size(), - reinterpret_cast<int32_t*>(elems.begin()) - ); - #endif - os.write - ( - reinterpret_cast<char*>(elems.begin()), - elems.size()*sizeof(label) - ); - - os << std::endl; - } - else - { - forAll(elems, i) - { - os << elems[i] << ' '; - - if (i > 0 && (i % 10) == 0) - { - os << std::endl; - } - } - os << std::endl; - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - DynamicList<label>& elems -) -{ - labelList& fld = elems.shrink(); - write(os, binary, fld); -} - - -void Foam::writeFuns::insert(const point& pt, DynamicList<floatScalar>& dest) -{ - dest.append(float(pt.x())); - dest.append(float(pt.y())); - dest.append(float(pt.z())); -} - - -void Foam::writeFuns::insert(const labelList& source, DynamicList<label>& dest) -{ - forAll(source, i) - { - dest.append(source[i]); - } -} - - -void Foam::writeFuns::insert -( - const List<scalar>& source, - DynamicList<floatScalar>& dest -) -{ - forAll(source, i) - { - dest.append(float(source[i])); - } -} - - -void Foam::writeFuns::insert -( - const labelList& map, - const List<scalar>& source, - DynamicList<floatScalar>& dest -) -{ - forAll(map, i) - { - dest.append(float(source[map[i]])); - } -} - - -void Foam::writeFuns::insert -( - const List<point>& source, - DynamicList<floatScalar>& dest -) -{ - forAll(source, i) - { - insert(source[i], dest); - } -} - -void Foam::writeFuns::insert -( - const labelList& map, - const List<point>& source, - DynamicList<floatScalar>& dest -) -{ - forAll(map, i) - { - insert(source[map[i]], dest); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/setSet/writeFuns.H b/applications/utilities/mesh/manipulation/setSet/writeFuns.H deleted file mode 100644 index 51c1ed8509fb0027d435848c1cf5f05b5a8d96b0..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/manipulation/setSet/writeFuns.H +++ /dev/null @@ -1,127 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ 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::writeFuns - -Description - Various functions for collecting and writing binary data. - - The LITTLE_ENDIAN is based on 32bit words. - It is not clear how 64bit labels should be handled, currently they are - split into two 32bit words and swapWord applied to these two. - - writeFuns should be a namespace rather than a class. - -SourceFiles - writeFuns.C - -\*---------------------------------------------------------------------------*/ - -#ifndef writeFuns_H -#define writeFuns_H - -#include "labelList.H" -#include "floatScalar.H" -#include "OFstream.H" -#include "DynamicList.H" -#include "point.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class writeFuns Declaration -\*---------------------------------------------------------------------------*/ - -class writeFuns -{ - // Private member functions - - //- Swap halves of word - static void swapWord(int32_t& word32); - - //- Swap halves of word - static void swapWords(const label nWords, int32_t* words32); - - -public: - - //- Write floats ascii or binary. - // If binary optionally in-place swaps argument - static void write(std::ostream&, const bool, DynamicList<floatScalar>&); - - //- Write labels ascii or binary. - // If binary optionally in-place swaps argument - static void write(std::ostream&, const bool, DynamicList<label>&); - - //- Write floats ascii or binary. - // If binary optionally in-place swaps argument - static void write(std::ostream&, const bool, List<floatScalar>&); - - //- Write labels ascii or binary. - // If binary optionally in-place swaps argument - static void write(std::ostream&, const bool, labelList&); - - //- Append point to given DynamicList - static void insert(const point&, DynamicList<floatScalar>& dest); - - //- Append elements of labelList to given DynamicList - static void insert(const labelList&, DynamicList<label>&); - - //- Append elements of scalarList to given DynamicList - static void insert(const List<scalar>&, DynamicList<floatScalar>&); - - //- Append elements of scalarList to given DynamicList using map - static void insert - ( - const labelList& map, - const List<scalar>& source, - DynamicList<floatScalar>& - ); - - //- Append points to given DynamicList of floats - static void insert(const List<point>& source, DynamicList<floatScalar>&); - - //- Append points to given DynamicList of floats using map - static void insert - ( - const labelList& map, - const List<point>& source, - DynamicList<floatScalar>& - ); -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/setSet/writePatch.C b/applications/utilities/mesh/manipulation/setSet/writePatch.C deleted file mode 100644 index 6a3269956662854835e10013e0a3e53fc927a85c..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/manipulation/setSet/writePatch.C +++ /dev/null @@ -1,127 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "writePatch.H" -#include "OFstream.H" -#include "writeFuns.H" -#include "primitiveFacePatch.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // - -void writePatch -( - const bool binary, - const word& setName, - const primitiveFacePatch& fp, - const word& fieldName, - labelList& fieldValues, - const fileName& fileName -) -{ - std::ofstream pStream(fileName.c_str()); - - pStream - << "# vtk DataFile Version 2.0" << std::endl - << setName << std::endl; - if (binary) - { - pStream << "BINARY" << std::endl; - } - else - { - pStream << "ASCII" << std::endl; - } - pStream << "DATASET POLYDATA" << std::endl; - - - //------------------------------------------------------------------ - // - // Write topology - // - //------------------------------------------------------------------ - - - // Write points and faces as polygons - - pStream << "POINTS " << fp.nPoints() << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*fp.nPoints()); - - writeFuns::insert(fp.localPoints(), ptField); - - writeFuns::write(pStream, binary, ptField); - - - label nFaceVerts = 0; - - forAll(fp.localFaces(), facei) - { - nFaceVerts += fp.localFaces()[facei].size() + 1; - } - pStream << "POLYGONS " << fp.size() << ' ' << nFaceVerts - << std::endl; - - - DynamicList<label> vertLabels(nFaceVerts); - - forAll(fp.localFaces(), facei) - { - const face& f = fp.localFaces()[facei]; - - vertLabels.append(f.size()); - - writeFuns::insert(f, vertLabels); - } - writeFuns::write(pStream, binary, vertLabels); - - - //----------------------------------------------------------------- - // - // Write data - // - //----------------------------------------------------------------- - - // Write faceID - - pStream - << "CELL_DATA " << fp.size() << std::endl - << "FIELD attributes 1" << std::endl; - - // Cell ids first - pStream << fieldName << " 1 " << fp.size() << " int" << std::endl; - - writeFuns::write(pStream, binary, fieldValues); -} - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/setSet/writePointSet.C b/applications/utilities/mesh/manipulation/setSet/writePointSet.C deleted file mode 100644 index 653839da35de5be73f6220cdfce0cc1e581d3b2b..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/manipulation/setSet/writePointSet.C +++ /dev/null @@ -1,105 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ 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 "writePointSet.H" -#include "OFstream.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // - -void writePointSet -( - const bool binary, - const primitiveMesh& mesh, - const topoSet& set, - const fileName& fileName -) -{ - std::ofstream pStream(fileName.c_str()); - - pStream - << "# vtk DataFile Version 2.0" << std::endl - << set.name() << std::endl; - if (binary) - { - pStream << "BINARY" << std::endl; - } - else - { - pStream << "ASCII" << std::endl; - } - pStream << "DATASET POLYDATA" << std::endl; - - - //------------------------------------------------------------------ - // - // Write topology - // - //------------------------------------------------------------------ - - - labelList pointLabels(set.toc()); - - pointField setPoints(mesh.points(), pointLabels); - - // Write points - - pStream << "POINTS " << pointLabels.size() << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*pointLabels.size()); - - writeFuns::insert(setPoints, ptField); - - writeFuns::write(pStream, binary, ptField); - - - //----------------------------------------------------------------- - // - // Write data - // - //----------------------------------------------------------------- - - // Write pointID - - pStream - << "POINT_DATA " << pointLabels.size() << std::endl - << "FIELD attributes 1" << std::endl; - - // Cell ids first - pStream << "pointID 1 " << pointLabels.size() << " int" << std::endl; - - writeFuns::write(pStream, binary, pointLabels); -} - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index 705c8e6650438da90a436c50c5a3f7410ebe6de2..bf15ffef0aa542b36f3e73cd1e86a235c159ab04 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -173,8 +173,7 @@ int main(int argc, char *argv[]) ( "name", "subdir", - "define sub-directory name to use for ensight data " - "(default: 'EnSight')" + "sub-directory name for ensight output (default: 'EnSight')" ); argList::addOption ( diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C index ab2e67e855e76b05d0753575cb18d612c93dee74..f6fdfae977fa30a64eb97c7af50d9c4b90628d5c 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C @@ -128,8 +128,7 @@ int main(int argc, char *argv[]) ( "name", "subdir", - "define sub-directory name to use for Ensight data " - "(default: \"Ensight\")" + "sub-directory name for ensight output (default: 'Ensight')" ); argList::addOption ( diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/Allwmake b/applications/utilities/postProcessing/dataConversion/foamToVTK/Allwmake deleted file mode 100755 index 81e0196f99b5ec655b542da25f8471c882e135fd..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/Allwmake +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -cd ${0%/*} || exit 1 # Run from this directory - -# Parse arguments for library compilation -. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments - -wmake $targetType foamToVTK -wmake $targetType - -#------------------------------------------------------------------------------ diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/files b/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/files index f10482758a05b8e8333e0cea08e1c2c52d71edf4..aaec9f26ab05eec617f82b9c505be4af6616b175 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/files +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/files @@ -1,3 +1,4 @@ +foamVtkLagrangianWriter.C foamToVTK.C EXE = $(FOAM_APPBIN)/foamToVTK diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/options b/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/options index c2445fd549946f440c1fa285d82253acae97ac3e..541ffa86aeb80f7e4034004d2d545ef581454bb3 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/Make/options @@ -1,12 +1,13 @@ EXE_INC = \ - -IfoamToVTK/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/conversion/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude EXE_LIBS = \ - -lfoamToVTK \ + -lconversion \ -ldynamicMesh \ -llagrangian \ -lgenericPatchFields diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C index dcf612a663ef2440b4b53943ce2c3ab24f4ab796..a012136f01328080fe6f2b3ecb56c829c5fea2ea 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,7 +28,7 @@ Group grpPostProcessingUtilities Description - Legacy VTK file format writer. + VTK file format writer. - Handles volFields, pointFields, surfaceScalarField, surfaceVectorField fields. @@ -46,6 +46,9 @@ Usage - \par -ascii Write VTK data in ASCII format instead of binary. + - \par -xml + Write VTK data in XML format instead of legacy format + - \par -mesh \<name\> Use a different mesh name (instead of -region) @@ -103,7 +106,7 @@ Usage use the time index in the VTK file name instead of the time index Note - mesh subset is handled by vtkMesh. Slight inconsistency in + mesh subset is handled by meshSubsetHelper. Slight inconsistency in interpolation: on the internal field it interpolates the whole volField to the whole-mesh pointField and then selects only those values it needs for the subMesh (using the fvMeshSubset cellMap(), pointMap() @@ -119,10 +122,7 @@ Note \verbatim <?xml version="1.0"?> - <VTKFile type="Collection" - version="0.1" - byte_order="LittleEndian" - compressor="vtkZLibDataCompressor"> + <VTKFile type="Collection" version="0.1" byte_order="LittleEndian"> <Collection> <DataSet timestep="50" file="pitzDaily_2.vtu"/> <DataSet timestep="100" file="pitzDaily_3.vtu"/> @@ -154,25 +154,26 @@ Note #include "passiveParticle.H" #include "stringListOps.H" -#include "vtkMesh.H" +#include "meshSubsetHelper.H" #include "readFields.H" -#include "writeFuns.H" - -#include "internalWriter.H" -#include "patchWriter.H" -#include "lagrangianWriter.H" - -#include "writeFaceSet.H" -#include "writePointSet.H" -#include "surfaceMeshWriter.H" -#include "writeSurfFields.H" +#include "faceSet.H" +#include "pointSet.H" + +#include "foamVtkOutputOptions.H" +#include "foamVtkInternalWriter.H" +#include "foamVtkPatchWriter.H" +#include "foamVtkSurfaceMeshWriter.H" +#include "foamVtkLagrangianWriter.H" +#include "foamVtkWriteFaceSet.H" +#include "foamVtkWritePointSet.H" +#include "foamVtkWriteSurfFields.H" #include "memInfo.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class GeoField> -void print(const char* msg, Ostream& os, const PtrList<const GeoField>& flds) +void print(const char* msg, Ostream& os, const UPtrList<const GeoField>& flds) { if (flds.size()) { @@ -234,17 +235,78 @@ labelList getSelectedPatches } +// +// Process args for output options +// Default from foamVtkOutputOptions is inline ASCII xml +// +vtk::outputOptions getOutputOptions(const argList& args) +{ + vtk::outputOptions opts; + + if (args.optionFound("xml")) + { + opts.ascii(args.optionFound("ascii")); + } + else + { + opts.legacy(true); + + if (!args.optionFound("ascii")) + { + if (sizeof(floatScalar) != 4 || sizeof(label) != 4) + { + opts.ascii(true); + + WarningInFunction + << "Using ASCII rather than legacy binary VTK format since " + << "floatScalar and/or label are not 4 bytes in size." + << nl << endl; + } + else + { + opts.ascii(false); + } + } + } + + return opts; +} + + +fileName relativeName(const fileName& parent, const fileName& file) +{ + string::size_type next = parent.size(); + if + ( + file.startsWith(parent) + && next < file.size() + && file[next] == '/' + ) + { + return file.substr(next+1); + } + else + { + return file; + } +} + + +fileName relativeName(const Time& runTime, const fileName& file) +{ + return relativeName(runTime.path(), file); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { - argList::addNote - ( - "legacy VTK file format writer" - ); + argList::addNote("VTK file format writer"); timeSelector::addOptions(); #include "addRegionOption.H" + argList::addOption ( "fields", @@ -275,6 +337,11 @@ int main(int argc, char *argv[]) "write in ASCII format instead of binary" ); argList::addBoolOption + ( + "xml", + "write VTK xml instead of legacy format" + ); + argList::addBoolOption ( "poly", "write polyhedral cells without tet/pyramid decomposition" @@ -299,7 +366,6 @@ int main(int argc, char *argv[]) "noLagrangian", "suppress writing lagrangian positions and fields" ); - argList::addBoolOption ( "noPointValues", @@ -329,7 +395,13 @@ int main(int argc, char *argv[]) argList::addBoolOption ( "useTimeName", - "use the time name instead of the time index when naming the files" + "use time name instead of the time index when naming files" + ); + argList::addOption + ( + "name", + "subdir", + "sub-directory name for VTK output (default: 'VTK')" ); #include "setRootCase.H" @@ -345,23 +417,11 @@ int main(int argc, char *argv[]) const bool doWriteInternal = !args.optionFound("noInternal"); const bool doFaceZones = !args.optionFound("noFaceZones"); const bool doLinks = !args.optionFound("noLinks"); - bool binary = !args.optionFound("ascii"); const bool useTimeName = args.optionFound("useTimeName"); const bool noLagrangian = args.optionFound("noLagrangian"); + const bool nearCellValue = args.optionFound("nearCellValue"); - // Decomposition of polyhedral cells into tets/pyramids cells - vtkTopo::decomposePoly = decomposePoly; - - if (binary && (sizeof(floatScalar) != 4 || sizeof(label) != 4)) - { - WarningInFunction - << "Using ASCII rather than binary VTK format because " - "floatScalar and/or label are not 4 bytes in size." - << nl << endl; - binary = false; - } - - const bool nearCellValue = args.optionFound("nearCellValue"); + const vtk::outputOptions fmtType = getOutputOptions(args); if (nearCellValue) { @@ -374,8 +434,9 @@ int main(int argc, char *argv[]) if (noPointValues) { - WarningInFunction - << "Outputting cell values only" << nl << endl; + Info<< "Outputting cell values only." + << " Point fields disabled by '-noPointValues' option" + << nl; } const bool allPatches = args.optionFound("allPatches"); @@ -388,11 +449,9 @@ int main(int argc, char *argv[]) Info<< "Not including patches " << excludePatches << nl << endl; } - word cellSetName; - word faceSetName; - word pointSetName; string vtkName = runTime.caseName(); + word cellSetName; if (args.optionReadIfPresent("cellSet", cellSetName)) { vtkName = cellSetName; @@ -407,14 +466,20 @@ int main(int argc, char *argv[]) vtkName = vtkName.substr(i); } } + + word faceSetName; args.optionReadIfPresent("faceSet", faceSetName); + + word pointSetName; args.optionReadIfPresent("pointSet", pointSetName); + // Define sub-directory name to use for VTK data. + const word vtkDirName = args.optionLookupOrDefault<word>("name", "VTK"); #include "createNamedMesh.H" // VTK/ directory in the case - fileName fvPath(runTime.path()/"VTK"); + fileName fvPath(runTime.path()/vtkDirName); // Directory of mesh (region0 gets filtered out) fileName regionPrefix; @@ -450,9 +515,11 @@ int main(int argc, char *argv[]) instantList timeDirs = timeSelector::select0(runTime, args); - // Mesh wrapper: does subsetting and decomposition - vtkMesh vMesh(mesh, cellSetName); + meshSubsetHelper meshRef(mesh, meshSubsetHelper::SET, cellSetName); + + // Collect decomposition information etc. + vtk::vtuCells vtuMeshCells(fmtType, decomposePoly); Info<< "VTK mesh topology: " << timer.cpuTimeIncrement() << " s, " @@ -471,20 +538,19 @@ int main(int argc, char *argv[]) // Check for new polyMesh/ and update mesh, fvMeshSubset and cell // decomposition. - polyMesh::readUpdateState meshState = vMesh.readUpdate(); - - const fvMesh& mesh = vMesh.mesh(); + polyMesh::readUpdateState meshState = meshRef.readUpdate(); + const fvMesh& mesh = meshRef.mesh(); if ( meshState == polyMesh::TOPO_CHANGE || meshState == polyMesh::TOPO_PATCH_CHANGE ) { - Info<< " Read new mesh" << nl << endl; + // Trigger change for vtk cells too + vtuMeshCells.clear(); } - // If faceSet: write faceSet only (as polydata) if (faceSetName.size()) { @@ -499,12 +565,17 @@ int main(int argc, char *argv[]) fvPath/set.name()/set.name() + "_" + timeDesc - + ".vtk" ); + Info<< " faceSet : " + << relativeName(runTime, outputName) << nl; - Info<< " faceSet : " << outputName << endl; - - writeFaceSet(binary, vMesh.mesh(), set, outputName); + vtk::writeFaceSet + ( + meshRef.mesh(), + set, + outputName, + fmtType + ); continue; } @@ -522,12 +593,17 @@ int main(int argc, char *argv[]) fvPath/set.name()/set.name() + "_" + timeDesc - + ".vtk" ); + Info<< " pointSet : " + << relativeName(runTime, outputName) << nl; - Info<< " pointSet : " << outputName << endl; - - writePointSet(binary, vMesh.mesh(), set, outputName); + vtk::writePointSet + ( + meshRef.mesh(), + set, + outputName, + fmtType + ); continue; } @@ -536,7 +612,7 @@ int main(int argc, char *argv[]) IOobjectList objects(mesh, runTime.timeName()); HashSet<word> selectedFields; - bool specifiedFields = args.optionReadIfPresent + const bool specifiedFields = args.optionReadIfPresent ( "fields", selectedFields @@ -544,247 +620,303 @@ int main(int argc, char *argv[]) // Construct the vol fields (on the original mesh if subsetted) - PtrList<const volScalarField> vsf; - PtrList<const volVectorField> vvf; - PtrList<const volSphericalTensorField> vSpheretf; - PtrList<const volSymmTensorField> vSymmtf; - PtrList<const volTensorField> vtf; + PtrList<const volScalarField> vScalarFld; + PtrList<const volVectorField> vVectorFld; + PtrList<const volSphericalTensorField> vSphTensorf; + PtrList<const volSymmTensorField> vSymTensorFld; + PtrList<const volTensorField> vTensorFld; if (!specifiedFields || selectedFields.size()) { - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vsf); - print(" volScalarFields :", Info, vsf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + vScalarFld + ); + print(" volScalar :", Info, vScalarFld); - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vvf); - print(" volVectorFields :", Info, vvf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + vVectorFld + ); + print(" volVector :", Info, vVectorFld); readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - vSpheretf + vSphTensorf ); - print(" volSphericalTensorFields :", Info, vSpheretf); + print(" volSphericalTensor :", Info, vSphTensorf); readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - vSymmtf + vSymTensorFld ); - print(" volSymmTensorFields :", Info, vSymmtf); + print(" volSymmTensor :", Info, vSymTensorFld); - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vtf); - print(" volTensorFields :", Info, vtf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + vTensorFld + ); + print(" volTensor :", Info, vTensorFld); } - label nVolFields = - vsf.size() - + vvf.size() - + vSpheretf.size() - + vSymmtf.size() - + vtf.size(); + const label nVolFields = + ( + vScalarFld.size() + + vVectorFld.size() + + vSphTensorf.size() + + vSymTensorFld.size() + + vTensorFld.size() + ); // Construct dimensioned fields - PtrList<const volScalarField::Internal> dsf; - PtrList<const volVectorField::Internal> dvf; - PtrList<const volSphericalTensorField::Internal> dSpheretf; - PtrList<const volSymmTensorField::Internal> dSymmtf; - PtrList<const volTensorField::Internal> dtf; + PtrList<const volScalarField::Internal> dScalarFld; + PtrList<const volVectorField::Internal> dVectorFld; + PtrList<const volSphericalTensorField::Internal> dSphTensorFld; + PtrList<const volSymmTensorField::Internal> dSymTensorFld; + PtrList<const volTensorField::Internal> dTensorFld; if (!specifiedFields || selectedFields.size()) { - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dsf); - print(" volScalarFields::Internal :", Info, dsf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + dScalarFld + ); + print(" volScalar::Internal :", Info, dScalarFld); - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dvf); - print(" volVectorFields::Internal :", Info, dvf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + dVectorFld + ); + print(" volVector::Internal :", Info, dVectorFld); readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - dSpheretf + dSphTensorFld ); - print(" volSphericalTensorFields::Internal :", Info, dSpheretf); + print(" volSphericalTensor::Internal :", Info, dSphTensorFld); readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - dSymmtf + dSymTensorFld ); - print(" volSymmTensorFields::Internal :", Info, dSymmtf); + print(" volSymmTensor::Internal :", Info, dSymTensorFld); - readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dtf); - print(" volTensorFields::Internal :", Info, dtf); + readFields + ( + meshRef, + meshRef.baseMesh(), + objects, + selectedFields, + dTensorFld + ); + print(" volTensor::Internal :", Info, dTensorFld); } - label nDimFields = - dsf.size() - + dvf.size() - + dSpheretf.size() - + dSymmtf.size() - + dtf.size(); - + const label nDimFields = + ( + dScalarFld.size() + + dVectorFld.size() + + dSphTensorFld.size() + + dSymTensorFld.size() + + dTensorFld.size() + ); - // Construct pointMesh only if necessary since constructs edge - // addressing (expensive on polyhedral meshes) - if (noPointValues) - { - Info<< " pointScalarFields : switched off" - << " (\"-noPointValues\" (at your option)\n"; - Info<< " pointVectorFields : switched off" - << " (\"-noPointValues\" (at your option)\n"; - } - PtrList<const pointScalarField> psf; - PtrList<const pointVectorField> pvf; - PtrList<const pointSphericalTensorField> pSpheretf; - PtrList<const pointSymmTensorField> pSymmtf; - PtrList<const pointTensorField> ptf; + PtrList<const pointScalarField> pScalarFld; + PtrList<const pointVectorField> pVectorFld; + PtrList<const pointSphericalTensorField> pSphTensorFld; + PtrList<const pointSymmTensorField> pSymTensorFld; + PtrList<const pointTensorField> pTensorFld; + // Construct pointMesh only if necessary since it constructs edge + // addressing (expensive on polyhedral meshes) if (!noPointValues && !(specifiedFields && selectedFields.empty())) { readFields ( - vMesh, - pointMesh::New(vMesh.baseMesh()), + meshRef, + pointMesh::New(meshRef.baseMesh()), objects, selectedFields, - psf + pScalarFld ); - print(" pointScalarFields :", Info, psf); + print(" pointScalar :", Info, pScalarFld); readFields ( - vMesh, - pointMesh::New(vMesh.baseMesh()), + meshRef, + pointMesh::New(meshRef.baseMesh()), objects, selectedFields, - pvf + pVectorFld ); - print(" pointVectorFields :", Info, pvf); + print(" pointVector :", Info, pVectorFld); readFields ( - vMesh, - pointMesh::New(vMesh.baseMesh()), + meshRef, + pointMesh::New(meshRef.baseMesh()), objects, selectedFields, - pSpheretf + pSphTensorFld ); - print(" pointSphericalTensorFields :", Info, pSpheretf); + print(" pointSphTensor : ", Info, pSphTensorFld); readFields ( - vMesh, - pointMesh::New(vMesh.baseMesh()), + meshRef, + pointMesh::New(meshRef.baseMesh()), objects, selectedFields, - pSymmtf + pSymTensorFld ); - print(" pointSymmTensorFields :", Info, pSymmtf); + print(" pointSymmTensor :", Info, pSymTensorFld); readFields ( - vMesh, - pointMesh::New(vMesh.baseMesh()), + meshRef, + pointMesh::New(meshRef.baseMesh()), objects, selectedFields, - ptf + pTensorFld ); - print(" pointTensorFields :", Info, ptf); + print(" pointTensor :", Info, pTensorFld); } - Info<< endl; - label nPointFields = - psf.size() - + pvf.size() - + pSpheretf.size() - + pSymmtf.size() - + ptf.size(); + const label nPointFields = + pScalarFld.size() + + pVectorFld.size() + + pSphTensorFld.size() + + pSymTensorFld.size() + + pTensorFld.size(); if (doWriteInternal) { + if (vtuMeshCells.empty()) + { + vtuMeshCells.reset(meshRef.mesh()); + + // Convert cellMap, addPointCellLabels to global cell ids + if (meshRef.useSubMesh()) + { + vtuMeshCells.renumberCells + ( + meshRef.subsetter().cellMap() + ); + } + } + // Create file and write header - fileName vtkFileName + fileName outputName ( fvPath/vtkName + "_" + timeDesc - + ".vtk" ); - - Info<< " Internal : " << vtkFileName << endl; + Info<< " Internal : " + << relativeName(runTime, outputName) << endl; // Write mesh - internalWriter writer(vMesh, binary, vtkFileName); - - // VolFields + cellID - writeFuns::writeCellDataHeader + vtk::internalWriter writer ( - writer.os(), - vMesh.nFieldCells(), - 1 + nVolFields + nDimFields + meshRef.baseMesh(), + vtuMeshCells, + outputName, + fmtType ); - // Write cellID field - writer.writeCellIDs(); - - // Write volFields - writer.write(vsf); - writer.write(vvf); - writer.write(vSpheretf); - writer.write(vSymmtf); - writer.write(vtf); - - // Write dimensionedFields - writer.write<scalar, volMesh>(dsf); - writer.write<vector, volMesh>(dvf); - writer.write<sphericalTensor, volMesh>(dSpheretf); - writer.write<symmTensor, volMesh>(dSymmtf); - writer.write<tensor, volMesh>(dtf); + // CellData + { + writer.beginCellData(1 + nVolFields + nDimFields); + + // Write cellID field + writer.writeCellIDs(); + + // Write volFields + writer.write(vScalarFld); + writer.write(vVectorFld); + writer.write(vSphTensorf); + writer.write(vSymTensorFld); + writer.write(vTensorFld); + + // Write dimensionedFields + writer.write(dScalarFld); + writer.write(dVectorFld); + writer.write(dSphTensorFld); + writer.write(dSymTensorFld); + writer.write(dTensorFld); + + writer.endCellData(); + } + // PointData if (!noPointValues) { - writeFuns::writePointDataHeader - ( - writer.os(), - vMesh.nFieldPoints(), - nVolFields + nDimFields + nPointFields - ); + writer.beginPointData(nVolFields + nDimFields + nPointFields); // pointFields - writer.write(psf); - writer.write(pvf); - writer.write(pSpheretf); - writer.write(pSymmtf); - writer.write(ptf); + writer.write(pScalarFld); + writer.write(pVectorFld); + writer.write(pSphTensorFld); + writer.write(pSymTensorFld); + writer.write(pTensorFld); // Interpolated volFields volPointInterpolation pInterp(mesh); - writer.write(pInterp, vsf); - writer.write(pInterp, vvf); - writer.write(pInterp, vSpheretf); - writer.write(pInterp, vSymmtf); - writer.write(pInterp, vtf); - - writer.write<scalar, volMesh>(pInterp, dsf); - writer.write<vector, volMesh>(pInterp, dvf); - writer.write<sphericalTensor, volMesh>(pInterp, dSpheretf); - writer.write<symmTensor, volMesh>(pInterp, dSymmtf); - writer.write<tensor, volMesh>(pInterp, dtf); + + writer.write(pInterp, vScalarFld); + writer.write(pInterp, vVectorFld); + writer.write(pInterp, vSphTensorf); + writer.write(pInterp, vSymTensorFld); + writer.write(pInterp, vTensorFld); + + writer.write(pInterp, dScalarFld); + writer.write(pInterp, dVectorFld); + writer.write(pInterp, dSphTensorFld); + writer.write(pInterp, dSymTensorFld); + writer.write(pInterp, dTensorFld); + + writer.endPointData(); } + + writer.writeFooter(); } //--------------------------------------------------------------------- @@ -795,63 +927,65 @@ int main(int argc, char *argv[]) if (args.optionFound("surfaceFields")) { - PtrList<const surfaceScalarField> ssf; + PtrList<const surfaceScalarField> sScalarFld; readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - ssf + sScalarFld ); - print(" surfScalarFields :", Info, ssf); + print(" surfScalar :", Info, sScalarFld); - PtrList<const surfaceVectorField> svf; + PtrList<const surfaceVectorField> sVectorFld; readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - svf + sVectorFld ); - print(" surfVectorFields :", Info, svf); + print(" surfVector :", Info, sVectorFld); - if (ssf.size() + svf.size() > 0) + if (sScalarFld.size()) { - // Rework the scalar fields into vectorfields. - label sz = svf.size(); + // Rework the scalar fields into vector fields. + const label sz = sVectorFld.size(); - svf.setSize(sz+ssf.size()); + sVectorFld.setSize(sz + sScalarFld.size()); surfaceVectorField n(mesh.Sf()/mesh.magSf()); - forAll(ssf, i) + forAll(sScalarFld, i) { - surfaceVectorField* ssfiPtr = (ssf[i]*n).ptr(); - ssfiPtr->rename(ssf[i].name()); - svf.set(sz+i, ssfiPtr); + surfaceVectorField* ssfPtr = (sScalarFld[i]*n).ptr(); + ssfPtr->rename(sScalarFld[i].name()); + sVectorFld.set(sz+i, ssfPtr); } - ssf.clear(); + sScalarFld.clear(); + } + if (sVectorFld.size()) + { mkDir(fvPath / "surfaceFields"); - fileName surfFileName + fileName outputName ( fvPath - /"surfaceFields" - /"surfaceFields" - + "_" - + timeDesc - + ".vtk" + / "surfaceFields" + / "surfaceFields" + + "_" + + timeDesc ); - writeSurfFields + vtk::writeSurfFields ( - binary, - vMesh.mesh(), - surfFileName, - svf + meshRef.mesh(), + outputName, + fmtType, + sVectorFld ); } } @@ -869,73 +1003,61 @@ int main(int argc, char *argv[]) { mkDir(fvPath/"allPatches"); - fileName outputName; - - if (vMesh.useSubMesh()) - { - outputName = - fvPath/"allPatches"/cellSetName - + "_" - + timeDesc - + ".vtk"; - } - else - { - outputName = - fvPath/"allPatches"/"allPatches" - + "_" - + timeDesc - + ".vtk"; - } - - Info<< " Combined patches : " << outputName << endl; + fileName outputName + ( + fvPath/"allPatches" + / (meshRef.useSubMesh() ? cellSetName : "allPatches") + + "_" + + timeDesc + ); + Info<< " Combined patches : " + << relativeName(runTime, outputName) << nl; - patchWriter writer + vtk::patchWriter writer ( - vMesh.mesh(), - binary, - nearCellValue, + meshRef.mesh(), outputName, + fmtType, + nearCellValue, getSelectedPatches(patches, excludePatches) ); - // VolFields + patchID - writeFuns::writeCellDataHeader - ( - writer.os(), - writer.nFaces(), - 1+nVolFields - ); + // CellData + { + writer.beginCellData(1 + nVolFields); - // Write patchID field - writer.writePatchIDs(); + // Write patchID field + writer.writePatchIDs(); - // Write volFields - writer.write(vsf); - writer.write(vvf); - writer.write(vSpheretf); - writer.write(vSymmtf); - writer.write(vtf); + // Write volFields + writer.write(vScalarFld); + writer.write(vVectorFld); + writer.write(vSphTensorf); + writer.write(vSymTensorFld); + writer.write(vTensorFld); + writer.endCellData(); + } + + // PointData if (!noPointValues) { - writeFuns::writePointDataHeader - ( - writer.os(), - writer.nPoints(), - nPointFields - ); + writer.beginPointData(nPointFields); // Write pointFields - writer.write(psf); - writer.write(pvf); - writer.write(pSpheretf); - writer.write(pSymmtf); - writer.write(ptf); - - // no interpolated volFields since I cannot be bothered to - // create the patchInterpolation for all subpatches. + writer.write(pScalarFld); + writer.write(pVectorFld); + writer.write(pSphTensorFld); + writer.write(pSymTensorFld); + writer.write(pTensorFld); + + // no interpolated volFields to avoid creating + // patchInterpolation for all subpatches. + + writer.endPointData(); } + + writer.writeFooter(); } else { @@ -943,91 +1065,78 @@ int main(int argc, char *argv[]) { const polyPatch& pp = patches[patchi]; - if (!findStrings(excludePatches, pp.name())) + if (findStrings(excludePatches, pp.name())) { - mkDir(fvPath/pp.name()); + // Skip excluded patch + continue; + } - fileName outputName; + mkDir(fvPath/pp.name()); - if (vMesh.useSubMesh()) - { - outputName = - fvPath/pp.name()/cellSetName - + "_" - + timeDesc - + ".vtk"; - } - else - { - outputName = - fvPath/pp.name()/pp.name() - + "_" - + timeDesc - + ".vtk"; - } + fileName outputName + ( + fvPath/pp.name() + / (meshRef.useSubMesh() ? cellSetName : pp.name()) + + "_" + + timeDesc + ); + Info<< " Patch : " + << relativeName(runTime, outputName) << nl; + + vtk::patchWriter writer + ( + meshRef.mesh(), + outputName, + fmtType, + nearCellValue, + labelList{patchi} + ); - Info<< " Patch : " << outputName << endl; + if (!isA<emptyPolyPatch>(pp)) + { + // VolFields + patchID + writer.beginCellData(1+nVolFields); - patchWriter writer - ( - vMesh.mesh(), - binary, - nearCellValue, - outputName, - labelList{patchi} - ); + // Write patchID field + writer.writePatchIDs(); - if (!isA<emptyPolyPatch>(pp)) + // Write volFields + writer.write(vScalarFld); + writer.write(vVectorFld); + writer.write(vSphTensorf); + writer.write(vSymTensorFld); + writer.write(vTensorFld); + + writer.endCellData(); + + if (!noPointValues) { - // VolFields + patchID - writeFuns::writeCellDataHeader + writer.beginPointData(nVolFields + nPointFields); + + // Write pointFields + writer.write(pScalarFld); + writer.write(pVectorFld); + writer.write(pSphTensorFld); + writer.write(pSymTensorFld); + writer.write(pTensorFld); + + PrimitivePatchInterpolation<primitivePatch> pInter ( - writer.os(), - writer.nFaces(), - 1+nVolFields + pp ); - // Write patchID field - writer.writePatchIDs(); - - // Write volFields - writer.write(vsf); - writer.write(vvf); - writer.write(vSpheretf); - writer.write(vSymmtf); - writer.write(vtf); - - if (!noPointValues) - { - writeFuns::writePointDataHeader - ( - writer.os(), - writer.nPoints(), - nVolFields - + nPointFields - ); - - // Write pointFields - writer.write(psf); - writer.write(pvf); - writer.write(pSpheretf); - writer.write(pSymmtf); - writer.write(ptf); - - PrimitivePatchInterpolation<primitivePatch> pInter - ( - pp - ); - - // Write interpolated volFields - writer.write(pInter, vsf); - writer.write(pInter, vvf); - writer.write(pInter, vSpheretf); - writer.write(pInter, vSymmtf); - writer.write(pInter, vtf); - } + // Write interpolated volFields + writer.write(pInter, vScalarFld); + writer.write(pInter, vVectorFld); + writer.write(pInter, vSphTensorf); + writer.write(pInter, vSymTensorFld); + writer.write(pInter, vTensorFld); + + writer.endPointData(); } } + + writer.writeFooter(); } } @@ -1039,27 +1148,27 @@ int main(int argc, char *argv[]) if (doFaceZones) { - PtrList<const surfaceScalarField> ssf; + PtrList<const surfaceScalarField> sScalarFld; readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - ssf + sScalarFld ); - print(" surfScalarFields :", Info, ssf); + print(" surfScalar :", Info, sScalarFld); - PtrList<const surfaceVectorField> svf; + PtrList<const surfaceVectorField> sVectorFld; readFields ( - vMesh, - vMesh.baseMesh(), + meshRef, + meshRef.baseMesh(), objects, selectedFields, - svf + sVectorFld ); - print(" surfVectorFields :", Info, svf); + print(" surfVector :", Info, sVectorFld); const faceZoneMesh& zones = mesh.faceZones(); @@ -1069,26 +1178,15 @@ int main(int argc, char *argv[]) mkDir(fvPath/fz.name()); - fileName outputName; - - if (vMesh.useSubMesh()) - { - outputName = - fvPath/fz.name()/cellSetName - + "_" - + timeDesc - + ".vtk"; - } - else - { - outputName = - fvPath/fz.name()/fz.name() - + "_" - + timeDesc - + ".vtk"; - } - - Info<< " FaceZone : " << outputName << endl; + fileName outputName = + ( + fvPath/fz.name() + / (meshRef.useSubMesh() ? cellSetName : fz.name()) + + "_" + + timeDesc + ); + Info<< " FaceZone : " + << relativeName(runTime, outputName) << nl; indirectPrimitivePatch pp ( @@ -1096,29 +1194,27 @@ int main(int argc, char *argv[]) mesh.points() ); - surfaceMeshWriter writer + vtk::surfaceMeshWriter writer ( - binary, pp, fz.name(), - outputName + outputName, + fmtType ); // Number of fields - writeFuns::writeCellDataHeader - ( - writer.os(), - pp.size(), - ssf.size()+svf.size() - ); + writer.beginCellData(sScalarFld.size() + sVectorFld.size()); + + writer.write(sScalarFld); + writer.write(sVectorFld); + + writer.endCellData(); - writer.write(ssf); - writer.write(svf); + writer.writeFooter(); } } - //--------------------------------------------------------------------- // // Write lagrangian data @@ -1135,10 +1231,10 @@ int main(int argc, char *argv[]) fileName outputName ( fvPath/cloud::prefix/cloudName/cloudName - + "_" + timeDesc + ".vtk" + + "_" + timeDesc ); - - Info<< " Lagrangian: " << outputName << endl; + Info<< " Lagrangian: " + << relativeName(runTime, outputName) << nl; IOobjectList sprayObjs ( @@ -1185,17 +1281,16 @@ int main(int argc, char *argv[]) Info<< " tensors :"; print(Info, tensorNames); - lagrangianWriter writer + vtk::lagrangianWriter writer ( - vMesh.mesh(), - binary, - outputName, + meshRef.mesh(), cloudName, - false + outputName, + fmtType ); // Write number of fields - writer.writeParcelHeader + writer.beginParcelData ( labelNames.size() + scalarNames.size() @@ -1212,20 +1307,28 @@ int main(int argc, char *argv[]) writer.writeIOField<sphericalTensor>(sphereNames); writer.writeIOField<symmTensor>(symmNames); writer.writeIOField<tensor>(tensorNames); + + writer.endParcelData(); + + writer.writeFooter(); } else { - lagrangianWriter writer + vtk::lagrangianWriter writer ( - vMesh.mesh(), - binary, - outputName, + meshRef.mesh(), cloudName, + outputName, + fmtType, true ); // Write number of fields - writer.writeParcelHeader(0); + writer.beginParcelData(0); + + writer.endParcelData(); + + writer.writeFooter(); } } @@ -1243,18 +1346,19 @@ int main(int argc, char *argv[]) if (Pstream::parRun() && doLinks) { - mkDir(runTime.path()/".."/"VTK"); - chDir(runTime.path()/".."/"VTK"); + mkDir(runTime.path()/".."/vtkDirName); + chDir(runTime.path()/".."/vtkDirName); - Info<< "Linking all processor files to " << runTime.path()/".."/"VTK" + Info<< "Linking all processor files to " + << runTime.path()/".."/vtkDirName << endl; // Get list of vtk files fileName procVTK ( fileName("..") - /"processor" + name(Pstream::myProcNo()) - /"VTK" + / "processor" + Foam::name(Pstream::myProcNo()) + / vtkDirName ); fileNameList dirs(readDir(procVTK, fileName::DIRECTORY)); @@ -1272,17 +1376,21 @@ int main(int argc, char *argv[]) if (exists(procFile)) { - string cmd - ( - "ln -s " - + procFile - + " " - + "processor" - + name(Pstream::myProcNo()) - + "_" - + procFile.name() - ); - if (Foam::system(cmd.c_str()) == -1) + // Could likely also use Foam::ln() directly + List<string> cmd + { + "ln", + "-s", + procFile, + ( + "processor" + + Foam::name(Pstream::myProcNo()) + + "_" + + procFile.name() + ) + }; + + if (Foam::system(cmd) == -1) { WarningInFunction << "Could not execute command " << cmd << endl; diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files deleted file mode 100644 index 02de5b47e6254aab58ae3557c2f7e2342b7df753..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files +++ /dev/null @@ -1,13 +0,0 @@ -surfaceMeshWriter.C -internalWriter.C -lagrangianWriter.C -patchWriter.C -writeFuns.C -writeFaceSet.C -writePointSet.C -writeSurfFields.C -vtkTopo.C - -writeVTK/writeVTK.C - -LIB = $(FOAM_LIBBIN)/libfoamToVTK diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/options b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/options deleted file mode 100644 index f10e4ec1d6bc0688e938d10ec287995f5efb0119..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/options +++ /dev/null @@ -1,10 +0,0 @@ -EXE_INC = \ - -I$(LIB_SRC)/lagrangian/basic/lnInclude \ - -I$(LIB_SRC)/finiteVolume/lnInclude \ - -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/meshTools/lnInclude - -LIB_LIBS = \ - -ldynamicMesh \ - -llagrangian \ - -lgenericPatchFields diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.C deleted file mode 100644 index 4db9f9c06938a851a387505af3adb8b6cbd24ab0..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.C +++ /dev/null @@ -1,165 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "internalWriter.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::internalWriter::internalWriter -( - const vtkMesh& vMesh, - const bool binary, - const fileName& fName -) -: - vMesh_(vMesh), - binary_(binary), - fName_(fName), - os_(fName.c_str()) -{ - const fvMesh& mesh = vMesh_.mesh(); - const vtkTopo& topo = vMesh_.topo(); - - // Write header - writeFuns::writeHeader(os_, binary_, mesh.time().caseName()); - os_ << "DATASET UNSTRUCTURED_GRID" << std::endl; - - - //------------------------------------------------------------------ - // - // Write topology - // - //------------------------------------------------------------------ - - const labelList& addPointCellLabels = topo.addPointCellLabels(); - const label nTotPoints = mesh.nPoints() + addPointCellLabels.size(); - - os_ << "POINTS " << nTotPoints << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*nTotPoints); - - writeFuns::insert(mesh.points(), ptField); - - const pointField& ctrs = mesh.cellCentres(); - forAll(addPointCellLabels, api) - { - writeFuns::insert(ctrs[addPointCellLabels[api]], ptField); - } - writeFuns::write(os_, binary_, ptField); - - - // - // Write cells - // - - const labelListList& vtkVertLabels = topo.vertLabels(); - - // Count total number of vertices referenced. - label nFaceVerts = 0; - - forAll(vtkVertLabels, celli) - { - nFaceVerts += vtkVertLabels[celli].size() + 1; - } - - os_ << "CELLS " << vtkVertLabels.size() << ' ' << nFaceVerts << std::endl; - - DynamicList<label> vertLabels(nFaceVerts); - - forAll(vtkVertLabels, celli) - { - const labelList& vtkVerts = vtkVertLabels[celli]; - - vertLabels.append(vtkVerts.size()); - - writeFuns::insert(vtkVerts, vertLabels); - } - writeFuns::write(os_, binary_, vertLabels); - - - const labelList& vtkCellTypes = topo.cellTypes(); - - os_ << "CELL_TYPES " << vtkCellTypes.size() << std::endl; - - // Make copy since writing might swap stuff. - DynamicList<label> cellTypes(vtkCellTypes.size()); - - writeFuns::insert(vtkCellTypes, cellTypes); - - writeFuns::write(os_, binary_, cellTypes); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::internalWriter::writeCellIDs() -{ - const fvMesh& mesh = vMesh_.mesh(); - const vtkTopo& topo = vMesh_.topo(); - const labelList& vtkCellTypes = topo.cellTypes(); - const labelList& superCells = topo.superCells(); - - // Cell ids first - os_ << "cellID 1 " << vtkCellTypes.size() << " int" << std::endl; - - labelList cellId(vtkCellTypes.size()); - label labelI = 0; - - - if (vMesh_.useSubMesh()) - { - const labelList& cMap = vMesh_.subsetter().cellMap(); - - forAll(mesh.cells(), celli) - { - cellId[labelI++] = cMap[celli]; - } - forAll(superCells, superCelli) - { - label origCelli = cMap[superCells[superCelli]]; - - cellId[labelI++] = origCelli; - } - } - else - { - forAll(mesh.cells(), celli) - { - cellId[labelI++] = celli; - } - forAll(superCells, superCelli) - { - label origCelli = superCells[superCelli]; - - cellId[labelI++] = origCelli; - } - } - - writeFuns::write(os_, binary_, cellId); -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriterTemplates.C deleted file mode 100644 index f5e3b1aa39507e7bf3d7c76fb5a8695564d8161f..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriterTemplates.C +++ /dev/null @@ -1,99 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "internalWriter.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template<class Type, template<class> class PatchField, class GeoMesh> -void Foam::internalWriter::write -( - const UPtrList<const GeometricField<Type, PatchField, GeoMesh>>& flds -) -{ - forAll(flds, i) - { - writeFuns::write(os_, binary_, flds[i], vMesh_); - } -} - - -template<class Type, class GeoMesh> -void Foam::internalWriter::write -( - const PtrList<const DimensionedField<Type, volMesh>>& flds -) -{ - forAll(flds, i) - { - writeFuns::write(os_, binary_, flds[i], vMesh_); - } -} - - -template<class Type> -void Foam::internalWriter::write -( - const volPointInterpolation& pInterp, - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds -) -{ - forAll(flds, i) - { - writeFuns::write - ( - os_, - binary_, - flds[i], - pInterp.interpolate(flds[i])(), - vMesh_ - ); - } -} - - -template<class Type, class GeoMesh> -void Foam::internalWriter::write -( - const volPointInterpolation& pInterp, - const PtrList<const DimensionedField<Type, volMesh>>& flds -) -{ - forAll(flds, i) - { - writeFuns::write - ( - os_, - binary_, - flds[i], - pInterp.interpolate(flds[i])(), - vMesh_ - ); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C deleted file mode 100644 index 6eab8f164666e4767559491354f705df14cc4418..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C +++ /dev/null @@ -1,87 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "lagrangianWriter.H" -#include "writeFuns.H" -#include "Cloud.H" -#include "passiveParticle.H" - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::lagrangianWriter::lagrangianWriter -( - const fvMesh& mesh, - const bool binary, - const fileName& fName, - const word& cloudName, - const bool dummyCloud -) -: - mesh_(mesh), - binary_(binary), - fName_(fName), - cloudName_(cloudName), - os_(fName.c_str()) -{ - // Write header - writeFuns::writeHeader(os_, binary_, mesh_.time().caseName()); - os_ << "DATASET POLYDATA" << std::endl; - - if (dummyCloud) - { - nParcels_ = 0; - - os_ << "POINTS " << nParcels_ << " float" << std::endl; - } - else - { - Cloud<passiveParticle> parcels(mesh, cloudName_, false); - - nParcels_ = parcels.size(); - - os_ << "POINTS " << nParcels_ << " float" << std::endl; - - DynamicList<floatScalar> partField(3*parcels.size()); - - forAllConstIter(Cloud<passiveParticle>, parcels, elmnt) - { - writeFuns::insert(elmnt().position(), partField); - } - writeFuns::write(os_, binary_, partField); - } -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::lagrangianWriter::writeParcelHeader(const label nFields) -{ - os_ << "POINT_DATA " << nParcels_ << std::endl - << "FIELD attributes " << nFields - << std::endl; -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C deleted file mode 100644 index 86cec10dc3ee015598988d5ee2b71c5ed036fc0c..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C +++ /dev/null @@ -1,65 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "lagrangianWriter.H" -#include "writeFuns.H" -#include "IOField.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template<class Type> -void Foam::lagrangianWriter::writeIOField(const wordList& objects) -{ - forAll(objects, i) - { - const word& object = objects[i]; - - IOobject header - ( - object, - mesh_.time().timeName(), - cloud::prefix/cloudName_, - mesh_, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ); - - IOField<Type> fld(header); - - os_ << object << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << fld.size() << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*fld.size()); - - writeFuns::insert(fld, fField); - - writeFuns::write(os_, binary_, fField); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C deleted file mode 100644 index d099745aa259b8f59f9029a52af2b1725a8859c3..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C +++ /dev/null @@ -1,136 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "patchWriter.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::patchWriter::patchWriter -( - const fvMesh& mesh, - const bool binary, - const bool nearCellValue, - const fileName& fName, - const labelList& patchIDs -) -: - mesh_(mesh), - binary_(binary), - nearCellValue_(nearCellValue), - fName_(fName), - patchIDs_(patchIDs), - os_(fName.c_str()) -{ - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - - // Write header - if (patchIDs_.size() == 1) - { - writeFuns::writeHeader(os_, binary_, patches[patchIDs_[0]].name()); - } - else - { - writeFuns::writeHeader(os_, binary_, "patches"); - } - os_ << "DATASET POLYDATA" << std::endl; - - // Write topology - nPoints_ = 0; - nFaces_ = 0; - label nFaceVerts = 0; - - forAll(patchIDs_, i) - { - const polyPatch& pp = patches[patchIDs_[i]]; - - nPoints_ += pp.nPoints(); - nFaces_ += pp.size(); - - forAll(pp, facei) - { - nFaceVerts += pp[facei].size() + 1; - } - } - - os_ << "POINTS " << nPoints_ << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*nPoints_); - - forAll(patchIDs_, i) - { - const polyPatch& pp = patches[patchIDs_[i]]; - - writeFuns::insert(pp.localPoints(), ptField); - } - writeFuns::write(os_, binary_, ptField); - - os_ << "POLYGONS " << nFaces_ << ' ' << nFaceVerts << std::endl; - - DynamicList<label> vertLabels(nFaceVerts); - - label offset = 0; - - forAll(patchIDs_, i) - { - const polyPatch& pp = patches[patchIDs_[i]]; - - forAll(pp, facei) - { - const face& f = pp.localFaces()[facei]; - - vertLabels.append(f.size()); - writeFuns::insert(f + offset, vertLabels); - } - offset += pp.nPoints(); - } - writeFuns::write(os_, binary_, vertLabels); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::patchWriter::writePatchIDs() -{ - DynamicList<floatScalar> fField(nFaces_); - - os_ << "patchID 1 " << nFaces_ << " float" << std::endl; - - forAll(patchIDs_, i) - { - label patchi = patchIDs_[i]; - - const polyPatch& pp = mesh_.boundaryMesh()[patchi]; - - if (!isA<emptyPolyPatch>(pp)) - { - writeFuns::insert(scalarField(pp.size(), patchi), fField); - } - } - writeFuns::write(os_, binary_, fField); -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H deleted file mode 100644 index aab8075da87052a6ebc22fdc00cbf041e8aede05..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H +++ /dev/null @@ -1,153 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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::patchWriter - -Description - Write patch fields - -SourceFiles - patchWriter.C - patchWriterTemplates.C - -\*---------------------------------------------------------------------------*/ - -#ifndef patchWriter_H -#define patchWriter_H - -#include "pointMesh.H" -#include "OFstream.H" -#include "volFields.H" -#include "pointFields.H" -#include "indirectPrimitivePatch.H" -#include "PrimitivePatchInterpolation.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -class volPointInterpolation; - -/*---------------------------------------------------------------------------*\ - Class patchWriter Declaration -\*---------------------------------------------------------------------------*/ - -class patchWriter -{ - //- Reference to the OpenFOAM mesh (or subset) - const fvMesh& mesh_; - - const bool binary_; - - const bool nearCellValue_; - - const fileName fName_; - - const labelList patchIDs_; - - std::ofstream os_; - - label nPoints_; - - label nFaces_; - -public: - - // Constructors - - //- Construct from components - patchWriter - ( - const fvMesh&, - const bool binary, - const bool nearCellValue, - const fileName&, - const labelList& patchIDs - ); - - - // Member Functions - - std::ofstream& os() - { - return os_; - } - - label nPoints() const - { - return nPoints_; - } - - label nFaces() const - { - return nFaces_; - } - - //- Write cellIDs - void writePatchIDs(); - - //- Write volFields - template<class Type> - void write - ( - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& - ); - - //- Write pointFields - template<class Type> - void write - ( - const UPtrList - < - const GeometricField<Type, pointPatchField, pointMesh> - >& - ); - - //- Interpolate and write volFields - template<class Type> - void write - ( - const PrimitivePatchInterpolation<primitivePatch>&, - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& - ); -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifdef NoRepository - #include "patchWriterTemplates.C" -#endif - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriterTemplates.C deleted file mode 100644 index 567b1db68c65aa2d558817cd6f459b4feb2d3b9b..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriterTemplates.C +++ /dev/null @@ -1,145 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "patchWriter.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template<class Type> -void Foam::patchWriter::write -( - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds -) -{ - forAll(flds, fieldi) - { - const GeometricField<Type, fvPatchField, volMesh>& fld = flds[fieldi]; - - os_ << fld.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nFaces_ << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nFaces_); - - forAll(patchIDs_, j) - { - label patchi = patchIDs_[j]; - - const fvPatchField<Type>& pfld = fld.boundaryField()[patchi]; - - if (nearCellValue_) - { - writeFuns::insert(pfld.patchInternalField()(), fField); - } - else - { - writeFuns::insert(pfld, fField); - } - } - writeFuns::write(os_, binary_, fField); - } -} - - -template<class Type> -void Foam::patchWriter::write -( - const UPtrList<const GeometricField<Type, pointPatchField, pointMesh>>& flds -) -{ - forAll(flds, fieldi) - { - const GeometricField<Type, pointPatchField, pointMesh>& fld = - flds[fieldi]; - - os_ << fld.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nPoints_ << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nPoints_); - - forAll(patchIDs_, j) - { - label patchi = patchIDs_[j]; - - const pointPatchField<Type>& pfld = fld.boundaryField()[patchi]; - - writeFuns::insert(pfld.patchInternalField()(), fField); - } - writeFuns::write(os_, binary_, fField); - } -} - - -template<class Type> -void Foam::patchWriter::write -( - const PrimitivePatchInterpolation<primitivePatch>& pInter, - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds -) -{ - forAll(flds, fieldi) - { - const GeometricField<Type, fvPatchField, volMesh>& fld = flds[fieldi]; - - os_ << fld.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nPoints_ << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nPoints_); - - forAll(patchIDs_, j) - { - label patchi = patchIDs_[j]; - - const fvPatchField<Type>& pfld = fld.boundaryField()[patchi]; - - if (nearCellValue_) - { - writeFuns::insert - ( - pInter.faceToPointInterpolate - ( - pfld.patchInternalField()() - )(), - fField - ); - } - else - { - writeFuns::insert - ( - pInter.faceToPointInterpolate(pfld)(), - fField - ); - } - } - writeFuns::write(os_, binary_, fField); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H deleted file mode 100644 index f0a80db4ead04f7e4e1c13d77c488225d5acb809..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H +++ /dev/null @@ -1,137 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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::vtkMesh - -Description - Encapsulation of VTK mesh data. Holds mesh or meshsubset and - polyhedral-cell decomposition on it. - -SourceFiles - vtkMesh.C - -\*---------------------------------------------------------------------------*/ - -#ifndef vtkMesh_H -#define vtkMesh_H - -#include "meshSubsetHelper.H" -#include "vtkTopo.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class vtkMesh Declaration -\*---------------------------------------------------------------------------*/ - -class vtkMesh -: - public meshSubsetHelper -{ - // Private data - - //- Current decomposition of topology - mutable autoPtr<vtkTopo> topoPtr_; - - - // Private Member Functions - - //- Disallow default bitwise copy construct - vtkMesh(const vtkMesh&) = delete; - - //- Disallow default bitwise assignment - void operator=(const vtkMesh&) = delete; - - -public: - - // Constructors - - //- Construct from components - vtkMesh(fvMesh& baseMesh, const word& setName = word::null) - : - meshSubsetHelper(baseMesh, meshSubsetHelper::SET, setName) - {} - - - // Member Functions - - // Access - - //- Topology - const vtkTopo& topo() const - { - if (topoPtr_.empty()) - { - topoPtr_.reset(new vtkTopo(mesh())); - } - return topoPtr_(); - } - - - //- Number of field cells - label nFieldCells() const - { - return topo().cellTypes().size(); - } - - - //- Number of field points - label nFieldPoints() const - { - return mesh().nPoints() + topo().addPointCellLabels().size(); - } - - - // Edit - - //- Read mesh, forcing topo update if necessary - polyMesh::readUpdateState readUpdate() - { - polyMesh::readUpdateState meshState - = meshSubsetHelper::readUpdate(); - - if (meshState != polyMesh::UNCHANGED) - { - topoPtr_.clear(); - } - - return meshState; - } - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.C deleted file mode 100644 index dc6ece136be09e7b2d4fa2171099b75e6526a2f9..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.C +++ /dev/null @@ -1,373 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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/>. - -Description - Note: bug in vtk displaying wedges? Seems to display ok if we decompose - them. Should be thoroughly tested! - (they appear rarely in polyhedral meshes, do appear in some cut meshes) - -\*---------------------------------------------------------------------------*/ - -#include "vtkTopo.H" -#include "polyMesh.H" -#include "cellShape.H" -#include "cellModeller.H" -#include "Swap.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -bool Foam::vtkTopo::decomposePoly = true; - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::vtkTopo::vtkTopo(const polyMesh& mesh) -: - mesh_(mesh), - vertLabels_(), - cellTypes_(), - addPointCellLabels_(), - superCells_() -{ - const cellModel& tet = *(cellModeller::lookup("tet")); - const cellModel& pyr = *(cellModeller::lookup("pyr")); - const cellModel& prism = *(cellModeller::lookup("prism")); - const cellModel& wedge = *(cellModeller::lookup("wedge")); - const cellModel& tetWedge = *(cellModeller::lookup("tetWedge")); - const cellModel& hex = *(cellModeller::lookup("hex")); - - const cellShapeList& cellShapes = mesh_.cellShapes(); - - // Number of additional points needed by the decomposition of polyhedra - label nAddPoints = 0; - - // Number of additional cells generated by the decomposition of polyhedra - label nAddCells = 0; - - // face owner is needed to determine the face orientation - const labelList& owner = mesh.faceOwner(); - - // Scan for cells which need to be decomposed and count additional points - // and cells - if (decomposePoly) - { - forAll(cellShapes, celli) - { - const cellModel& model = cellShapes[celli].model(); - - if - ( - model != hex - && model != wedge // See above. - && model != prism - && model != pyr - && model != tet - && model != tetWedge - ) - { - const cell& cFaces = mesh_.cells()[celli]; - - forAll(cFaces, cFacei) - { - const face& f = mesh_.faces()[cFaces[cFacei]]; - - label nQuads = 0; - label nTris = 0; - f.nTrianglesQuads(mesh_.points(), nTris, nQuads); - - nAddCells += nQuads + nTris; - } - - nAddCells--; - nAddPoints++; - } - } - } - - - // Set size of additional point addressing array - // (from added point to original cell) - addPointCellLabels_.setSize(nAddPoints); - - // Set size of additional cells mapping array - // (from added cell to original cell) - superCells_.setSize(nAddCells); - - // List of vertex labels in VTK ordering - vertLabels_.setSize(cellShapes.size() + nAddCells); - - // Label of vtk type - cellTypes_.setSize(cellShapes.size() + nAddCells); - - // Set counters for additional points and additional cells - label addPointi = 0, addCelli = 0; - - forAll(cellShapes, celli) - { - const cellShape& cellShape = cellShapes[celli]; - const cellModel& cellModel = cellShape.model(); - - labelList& vtkVerts = vertLabels_[celli]; - - if (cellModel == tet) - { - vtkVerts = cellShape; - - cellTypes_[celli] = VTK_TETRA; - } - else if (cellModel == pyr) - { - vtkVerts = cellShape; - - cellTypes_[celli] = VTK_PYRAMID; - } - else if (cellModel == prism) - { - // VTK has a different node order for VTK_WEDGE - // their triangles point outwards! - vtkVerts = cellShape; - - Foam::Swap(vtkVerts[1], vtkVerts[2]); - Foam::Swap(vtkVerts[4], vtkVerts[5]); - - cellTypes_[celli] = VTK_WEDGE; - } - else if (cellModel == tetWedge && decomposePoly) - { - // Treat as squeezed prism (VTK_WEDGE) - vtkVerts.setSize(6); - vtkVerts[0] = cellShape[0]; - vtkVerts[1] = cellShape[2]; - vtkVerts[2] = cellShape[1]; - vtkVerts[3] = cellShape[3]; - vtkVerts[4] = cellShape[4]; - vtkVerts[5] = cellShape[3]; - - cellTypes_[celli] = VTK_WEDGE; - } - else if (cellModel == wedge) - { - // Treat as squeezed hex - vtkVerts.setSize(8); - vtkVerts[0] = cellShape[0]; - vtkVerts[1] = cellShape[1]; - vtkVerts[2] = cellShape[2]; - vtkVerts[3] = cellShape[2]; - vtkVerts[4] = cellShape[3]; - vtkVerts[5] = cellShape[4]; - vtkVerts[6] = cellShape[5]; - vtkVerts[7] = cellShape[6]; - - cellTypes_[celli] = VTK_HEXAHEDRON; - } - else if (cellModel == hex) - { - vtkVerts = cellShape; - - cellTypes_[celli] = VTK_HEXAHEDRON; - } - else if (decomposePoly) - { - // Polyhedral cell. Decompose into tets + pyramids. - - // Mapping from additional point to cell - addPointCellLabels_[addPointi] = celli; - - // The new vertex from the cell-centre - const label newVertexLabel = mesh_.nPoints() + addPointi; - - // Whether to insert cell in place of original or not. - bool substituteCell = true; - - const labelList& cFaces = mesh_.cells()[celli]; - forAll(cFaces, cFacei) - { - const face& f = mesh_.faces()[cFaces[cFacei]]; - const bool isOwner = (owner[cFaces[cFacei]] == celli); - - // Number of triangles and quads in decomposition - label nTris = 0; - label nQuads = 0; - f.nTrianglesQuads(mesh_.points(), nTris, nQuads); - - // Do actual decomposition into triFcs and quadFcs. - faceList triFcs(nTris); - faceList quadFcs(nQuads); - label trii = 0; - label quadi = 0; - f.trianglesQuads(mesh_.points(), trii, quadi, triFcs, quadFcs); - - forAll(quadFcs, quadI) - { - label thisCelli; - - if (substituteCell) - { - thisCelli = celli; - substituteCell = false; - } - else - { - thisCelli = mesh_.nCells() + addCelli; - superCells_[addCelli++] = celli; - } - - labelList& addVtkVerts = vertLabels_[thisCelli]; - - addVtkVerts.setSize(5); - - const face& quad = quadFcs[quadI]; - - // Ensure we have the correct orientation for the - // base of the primitive cell shape. - // If the cell is face owner, the orientation needs to be - // flipped. - // At the moment, VTK doesn't actually seem to care if - // negative cells are defined, but we'll do it anyhow - // (for safety). - if (isOwner) - { - addVtkVerts[0] = quad[3]; - addVtkVerts[1] = quad[2]; - addVtkVerts[2] = quad[1]; - addVtkVerts[3] = quad[0]; - } - else - { - addVtkVerts[0] = quad[0]; - addVtkVerts[1] = quad[1]; - addVtkVerts[2] = quad[2]; - addVtkVerts[3] = quad[3]; - } - addVtkVerts[4] = newVertexLabel; - - cellTypes_[thisCelli] = VTK_PYRAMID; - } - - forAll(triFcs, triI) - { - label thisCelli; - - if (substituteCell) - { - thisCelli = celli; - substituteCell = false; - } - else - { - thisCelli = mesh_.nCells() + addCelli; - superCells_[addCelli++] = celli; - } - - - labelList& addVtkVerts = vertLabels_[thisCelli]; - - const face& tri = triFcs[triI]; - - addVtkVerts.setSize(4); - - // See note above about the orientation. - if (isOwner) - { - addVtkVerts[0] = tri[2]; - addVtkVerts[1] = tri[1]; - addVtkVerts[2] = tri[0]; - } - else - { - addVtkVerts[0] = tri[0]; - addVtkVerts[1] = tri[1]; - addVtkVerts[2] = tri[2]; - } - addVtkVerts[3] = newVertexLabel; - - cellTypes_[thisCelli] = VTK_TETRA; - } - } - - addPointi++; - } - else - { - // Polyhedral cell - not decomposed - cellTypes_[celli] = VTK_POLYHEDRON; - - const labelList& cFaces = mesh_.cells()[celli]; - - // space for the number of faces and size of each face - label nData = 1 + cFaces.size(); - - // count total number of face points - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - nData += f.size(); // space for the face labels - } - - vtkVerts.setSize(nData); - - nData = 0; - vtkVerts[nData++] = cFaces.size(); - - // build face stream - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - const bool isOwner = (owner[cFaces[cFacei]] == celli); - - // number of labels for this face - vtkVerts[nData++] = f.size(); - - if (isOwner) - { - forAll(f, fp) - { - vtkVerts[nData++] = f[fp]; - } - } - else - { - // fairly immaterial if we reverse the list - // or use face::reverseFace() - forAllReverse(f, fp) - { - vtkVerts[nData++] = f[fp]; - } - } - } - } - } - - if (decomposePoly) - { - Pout<< " Original cells:" << mesh_.nCells() - << " points:" << mesh_.nPoints() - << " Additional cells:" << superCells_.size() - << " additional points:" << addPointCellLabels_.size() - << nl << endl; - } - -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.H deleted file mode 100644 index c6f9a4eea9ab2fc45c7cc599a2c69d89938fa43c..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkTopo.H +++ /dev/null @@ -1,139 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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::vtkTopo - -Description - Polyhedral cell decomposition for VTK. - -SourceFiles - vtkTopo.C - -\*---------------------------------------------------------------------------*/ - -#ifndef vtkTopo_H -#define vtkTopo_H - -#include "labelList.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// Forward declaration of classes -class polyMesh; - -/*---------------------------------------------------------------------------*\ - Class vtkTopo Declaration -\*---------------------------------------------------------------------------*/ - -class vtkTopo -{ - // Private data - - const polyMesh& mesh_; - - //- Vertices per cell (including added cells) in vtk ordering - labelListList vertLabels_; - - //- Cell types (including added cells) in vtk numbering - labelList cellTypes_; - - labelList addPointCellLabels_; - - labelList superCells_; - - - // Private Member Functions - - //- Disallow default bitwise copy construct - vtkTopo(const vtkTopo&); - - //- Disallow default bitwise assignment - void operator=(const vtkTopo&); - - -public: - - // Public static data - - //- Equivalent to enumeration in "vtkCellType.h" - enum vtkTypes - { - VTK_TRIANGLE = 5, - VTK_POLYGON = 7, - VTK_QUAD = 9, - - VTK_TETRA = 10, - VTK_HEXAHEDRON = 12, - VTK_WEDGE = 13, - VTK_PYRAMID = 14, - VTK_POLYHEDRON = 42 - }; - - //- Enable/disable polyhedron decomposition. Default = true - static bool decomposePoly; - - - // Constructors - - //- Construct from components - vtkTopo(const polyMesh&); - - // Member Functions - - // Access - - const labelListList& vertLabels() const - { - return vertLabels_; - } - - const labelList& cellTypes() const - { - return cellTypes_; - } - - const labelList& addPointCellLabels() const - { - return addPointCellLabels_; - } - - const labelList& superCells() const - { - return superCells_; - } -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C deleted file mode 100644 index 0556b7aaf27e0022b82cbb587dea9f818f9409e3..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C +++ /dev/null @@ -1,127 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "writeFaceSet.H" -#include "OFstream.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // - -void Foam::writeFaceSet -( - const bool binary, - const fvMesh& mesh, - const faceSet& set, - const fileName& fileName -) -{ - const faceList& faces = mesh.faces(); - - std::ofstream ostr(fileName.c_str()); - - writeFuns::writeHeader - ( - ostr, - binary, - set.name() - ); - - ostr<< "DATASET POLYDATA" << std::endl; - - //------------------------------------------------------------------ - // - // Write topology - // - //------------------------------------------------------------------ - - - // Construct primitivePatch of faces in faceSet. - - faceList setFaces(set.size()); - labelList setFaceLabels(set.size()); - label setFacei = 0; - - forAllConstIter(faceSet, set, iter) - { - setFaceLabels[setFacei] = iter.key(); - setFaces[setFacei] = faces[iter.key()]; - setFacei++; - } - primitiveFacePatch fp(setFaces, mesh.points()); - - - // Write points and faces as polygons - - ostr<< "POINTS " << fp.nPoints() << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*fp.nPoints()); - - writeFuns::insert(fp.localPoints(), ptField); - - writeFuns::write(ostr, binary, ptField); - - - label nFaceVerts = 0; - - forAll(fp.localFaces(), facei) - { - nFaceVerts += fp.localFaces()[facei].size() + 1; - } - ostr<< "POLYGONS " << fp.size() << ' ' << nFaceVerts << std::endl; - - - DynamicList<label> vertLabels(nFaceVerts); - - forAll(fp.localFaces(), facei) - { - const face& f = fp.localFaces()[facei]; - - vertLabels.append(f.size()); - - writeFuns::insert(f, vertLabels); - } - writeFuns::write(ostr, binary, vertLabels); - - - //----------------------------------------------------------------- - // - // Write data - // - //----------------------------------------------------------------- - - // Write faceID - - ostr - << "CELL_DATA " << fp.size() << std::endl - << "FIELD attributes 1" << std::endl; - - // Cell ids first - ostr<< "faceID 1 " << fp.size() << " int" << std::endl; - - writeFuns::write(ostr, binary, setFaceLabels); -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.C deleted file mode 100644 index 24eef341f641234798bf037d68f45b757178d7b7..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.C +++ /dev/null @@ -1,264 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "writeFuns.H" -#include "vtkTopo.H" -#include "endian.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -void Foam::writeFuns::swapWord(label& word32) -{ - char* mem = reinterpret_cast<char*>(&word32); - - char a = mem[0]; - mem[0] = mem[3]; - mem[3] = a; - - a = mem[1]; - mem[1] = mem[2]; - mem[2] = a; -} - - -void Foam::writeFuns::swapWords(const label nWords, label* words32) -{ - for (label i = 0; i < nWords; i++) - { - swapWord(words32[i]); - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - List<floatScalar>& fField -) -{ - if (binary) - { - #ifdef WM_LITTLE_ENDIAN - swapWords(fField.size(), reinterpret_cast<label*>(fField.begin())); - #endif - os.write - ( - reinterpret_cast<char*>(fField.begin()), - fField.size()*sizeof(float) - ); - - os << std::endl; - } - else - { - forAll(fField, i) - { - os << fField[i]; - - if (i > 0 && (i % 10) == 0) - { - os << std::endl; - } - else - { - os << ' '; - } - } - os << std::endl; - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - DynamicList<floatScalar>& fField -) -{ - List<floatScalar>& fld = fField.shrink(); - - write(os, binary, fld); -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - labelList& elems -) -{ - if (binary) - { - #ifdef WM_LITTLE_ENDIAN - swapWords(elems.size(), reinterpret_cast<label*>(elems.begin())); - #endif - os.write - ( - reinterpret_cast<char*>(elems.begin()), - elems.size()*sizeof(label) - ); - - os << std::endl; - } - else - { - forAll(elems, i) - { - os << elems[i]; - - if (i > 0 && (i % 10) == 0) - { - os << std::endl; - } - else - { - os << ' '; - } - } - os << std::endl; - } -} - - -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - DynamicList<label>& elems -) -{ - labelList& fld = elems.shrink(); - - write(os, binary, fld); -} - - -void Foam::writeFuns::writeHeader -( - std::ostream& os, - const bool binary, - const std::string& title -) -{ - os << "# vtk DataFile Version 2.0" << std::endl - << title << std::endl; - - if (binary) - { - os << "BINARY" << std::endl; - } - else - { - os << "ASCII" << std::endl; - } -} - - -void Foam::writeFuns::writeCellDataHeader -( - std::ostream& os, - const label nCells, - const label nFields -) -{ - os << "CELL_DATA " << nCells << std::endl - << "FIELD attributes " << nFields << std::endl; -} - - -void Foam::writeFuns::writePointDataHeader -( - std::ostream& os, - const label nPoints, - const label nFields -) -{ - os << "POINT_DATA " << nPoints << std::endl - << "FIELD attributes " << nFields << std::endl; -} - - -void Foam::writeFuns::insert(const scalar src, DynamicList<floatScalar>& dest) -{ - dest.append(float(src)); -} - - -void Foam::writeFuns::insert(const vector& src, DynamicList<floatScalar>& dest) -{ - for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt) - { - dest.append(float(src[cmpt])); - } -} - - -void Foam::writeFuns::insert -( - const sphericalTensor& src, - DynamicList<floatScalar>& dest -) -{ - for (direction cmpt = 0; cmpt < sphericalTensor::nComponents; ++cmpt) - { - dest.append(float(src[cmpt])); - } -} - - -void Foam::writeFuns::insert -( - const symmTensor& src, - DynamicList<floatScalar>& dest -) -{ - dest.append(float(src.xx())); - dest.append(float(src.yy())); - dest.append(float(src.zz())); - dest.append(float(src.xy())); - dest.append(float(src.yz())); - dest.append(float(src.xz())); -} - - -void Foam::writeFuns::insert(const tensor& src, DynamicList<floatScalar>& dest) -{ - for (direction cmpt = 0; cmpt < tensor::nComponents; ++cmpt) - { - dest.append(float(src[cmpt])); - } -} - - -void Foam::writeFuns::insert(const labelList& src, DynamicList<label>& dest) -{ - dest.append(src); -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.H deleted file mode 100644 index 60fe2a6d01034da4ee0de19da4cecd93b346e354..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFuns.H +++ /dev/null @@ -1,161 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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::writeFuns - -Description - Various functions for collecting and writing binary data. - -SourceFiles - writeFuns.C - -\*---------------------------------------------------------------------------*/ - -#ifndef writeFuns_H -#define writeFuns_H - -#include "floatScalar.H" -#include "DynamicList.H" -#include "volFieldsFwd.H" -#include "pointFieldsFwd.H" -#include "vtkMesh.H" -#include "volPointInterpolation.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class writeFuns Declaration -\*---------------------------------------------------------------------------*/ - -class writeFuns -{ - // Private Member Functions - - // Swap halves of word. - - static void swapWord(label& word32); - static void swapWords(const label nWords, label* words32); - - -public: - - // Write ascii or binary. If binary optionally in-place swaps argument - - static void write(std::ostream&, const bool, List<floatScalar>&); - static void write(std::ostream&, const bool, DynamicList<floatScalar>&); - static void write(std::ostream&, const bool, labelList&); - static void write(std::ostream&, const bool, DynamicList<label>&); - - - // Write header - - static void writeHeader - ( - std::ostream&, - const bool isBinary, - const std::string& title - ); - static void writeCellDataHeader - ( - std::ostream&, - const label nCells, - const label nFields - ); - static void writePointDataHeader - ( - std::ostream&, - const label nPoints, - const label nFields - ); - - - // Convert to VTK and store - - static void insert(const scalar, DynamicList<floatScalar>&); - static void insert(const point&, DynamicList<floatScalar>&); - static void insert(const sphericalTensor&, DynamicList<floatScalar>&); - static void insert(const symmTensor&, DynamicList<floatScalar>&); - static void insert(const tensor&, DynamicList<floatScalar>&); - - - //- Append elements to DynamicList - static void insert(const labelList&, DynamicList<label>&); - - template<class Type> - static void insert(const List<Type>&, DynamicList<floatScalar>&); - - //- Write volField with cell values (including decomposed cells) - template<class Type> - static void write - ( - std::ostream&, - const bool binary, - const DimensionedField<Type, volMesh>&, - const vtkMesh& - ); - - //- Write pointField on all mesh points. Interpolate to cell centre - // for decomposed cell centres. - template<class Type> - static void write - ( - std::ostream&, - const bool binary, - const GeometricField<Type, pointPatchField, pointMesh>&, - const vtkMesh& - ); - - //- Write interpolated field on points and original cell values on - // decomposed cell centres. - template<class Type> - static void write - ( - std::ostream&, - const bool binary, - const DimensionedField<Type, volMesh>&, - const DimensionedField<Type, pointMesh>&, - const vtkMesh& - ); - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifdef NoRepository - #include "writeFunsTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFunsTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFunsTemplates.C deleted file mode 100644 index 8929a1ad80eeab28e2509d1964b2f6d22d3a18a5..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFunsTemplates.C +++ /dev/null @@ -1,146 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "writeFuns.H" -#include "interpolatePointToCell.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Store List in dest -template<class Type> -void Foam::writeFuns::insert -( - const List<Type>& source, - DynamicList<floatScalar>& dest -) -{ - forAll(source, i) - { - insert(source[i], dest); - } -} - - -template<class Type> -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - const DimensionedField<Type, volMesh>& df, - const vtkMesh& vMesh -) -{ - const fvMesh& mesh = vMesh.mesh(); - - const labelList& superCells = vMesh.topo().superCells(); - - label nValues = mesh.nCells() + superCells.size(); - - os << df.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nValues << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nValues); - - insert(df.field(), fField); - - forAll(superCells, superCelli) - { - label origCelli = superCells[superCelli]; - - insert(df[origCelli], fField); - } - write(os, binary, fField); -} - - -template<class Type> -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - const GeometricField<Type, pointPatchField, pointMesh>& pvf, - const vtkMesh& vMesh -) -{ - const fvMesh& mesh = vMesh.mesh(); - const vtkTopo& topo = vMesh.topo(); - - const labelList& addPointCellLabels = topo.addPointCellLabels(); - const label nTotPoints = mesh.nPoints() + addPointCellLabels.size(); - - os << pvf.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nTotPoints << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nTotPoints); - - insert(pvf, fField); - - forAll(addPointCellLabels, api) - { - label origCelli = addPointCellLabels[api]; - - insert(interpolatePointToCell(pvf, origCelli), fField); - } - write(os, binary, fField); -} - - -template<class Type> -void Foam::writeFuns::write -( - std::ostream& os, - const bool binary, - const DimensionedField<Type, volMesh>& vvf, - const DimensionedField<Type, pointMesh>& pvf, - const vtkMesh& vMesh -) -{ - const fvMesh& mesh = vMesh.mesh(); - const vtkTopo& topo = vMesh.topo(); - - const labelList& addPointCellLabels = topo.addPointCellLabels(); - const label nTotPoints = mesh.nPoints() + addPointCellLabels.size(); - - os << vvf.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << nTotPoints << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*nTotPoints); - - insert(pvf, fField); - - forAll(addPointCellLabels, api) - { - label origCelli = addPointCellLabels[api]; - - insert(vvf[origCelli], fField); - } - write(os, binary, fField); -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C deleted file mode 100644 index e5fffb536671144a864004b16ee89eac11416612..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C +++ /dev/null @@ -1,103 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ 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 "writePointSet.H" -#include "OFstream.H" -#include "writeFuns.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // - -void writePointSet -( - const bool binary, - const fvMesh& mesh, - const pointSet& set, - const fileName& fileName -) -{ - std::ofstream ostr(fileName.c_str()); - - writeFuns::writeHeader - ( - ostr, - binary, - set.name() - ); - - ostr<< "DATASET POLYDATA" << std::endl; - - //------------------------------------------------------------------ - // - // Write topology - // - //------------------------------------------------------------------ - - - // Write points - - ostr<< "POINTS " << set.size() << " float" << std::endl; - - DynamicList<floatScalar> ptField(3*set.size()); - - writeFuns::insert - ( - UIndirectList<point>(mesh.points(), set.toc())(), - ptField - ); - - writeFuns::write(ostr, binary, ptField); - - - //----------------------------------------------------------------- - // - // Write data - // - //----------------------------------------------------------------- - - // Write faceID - - ostr - << "POINT_DATA " << set.size() << std::endl - << "FIELD attributes 1" << std::endl; - - // Cell ids first - ostr<< "pointID 1 " << set.size() << " int" << std::endl; - - labelList pointIDs(set.toc()); - - writeFuns::write(ostr, binary, pointIDs); -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H deleted file mode 100644 index d1ad15efe6d7b7b95946f479e695765eebb3aea8..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H +++ /dev/null @@ -1,63 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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/>. - -InClass - Foam::writePointSet - -Description - Write pointSet to vtk polydata file. Only one data which is original - pointID. - -SourceFiles - writePointSet.C - -\*---------------------------------------------------------------------------*/ - -#ifndef writePointSet_H -#define writePointSet_H - -#include "fvMesh.H" -#include "pointSet.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// Write lagrangian fields. -void writePointSet -( - const bool binary, - const fvMesh& mesh, - const pointSet& set, - const fileName& fileName -); - -} // End namespace Foam - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C deleted file mode 100644 index 9dc889adf4be77423e75cb965625c3cc7b52c590..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C +++ /dev/null @@ -1,113 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. -------------------------------------------------------------------------------- -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 "writeSurfFields.H" -#include "OFstream.H" -#include "floatScalar.H" -#include "writeFuns.H" -#include "emptyFvsPatchFields.H" -#include "fvsPatchFields.H" - -// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // - -void Foam::writeSurfFields -( - const bool binary, - const fvMesh& mesh, - const fileName& fileName, - const UPtrList<const surfaceVectorField>& surfVectorFields -) -{ - std::ofstream str(fileName.c_str()); - - writeFuns::writeHeader - ( - str, - binary, - "surfaceFields" - ); - - str << "DATASET POLYDATA" << std::endl; - - const pointField& fc = mesh.faceCentres(); - - str << "POINTS " << mesh.nFaces() << " float" << std::endl; - - DynamicList<floatScalar> pField(3*mesh.nFaces()); - - for (label facei = 0; facei < mesh.nFaces(); facei++) - { - writeFuns::insert(fc[facei], pField); - } - - writeFuns::write(str, binary, pField); - - str << "POINT_DATA " << mesh.nFaces() << std::endl - << "FIELD attributes " << surfVectorFields.size() << std::endl; - - // surfVectorFields - forAll(surfVectorFields, fieldi) - { - const surfaceVectorField& svf = surfVectorFields[fieldi]; - - str << svf.name() << " 3 " - << mesh.nFaces() << " float" << std::endl; - - DynamicList<floatScalar> fField(3*mesh.nFaces()); - - for (label facei = 0; facei < mesh.nInternalFaces(); facei++) - { - writeFuns::insert(svf[facei], fField); - } - - forAll(svf.boundaryField(), patchi) - { - const fvsPatchVectorField& pf = svf.boundaryField()[patchi]; - - const fvPatch& pp = mesh.boundary()[patchi]; - - if (isA<emptyFvsPatchVectorField>(pf)) - { - // Note: loop over polypatch size, not fvpatch size. - forAll(pp.patch(), i) - { - writeFuns::insert(vector::zero, fField); - } - } - else - { - forAll(pf, i) - { - writeFuns::insert(pf[i], fField); - } - } - } - - writeFuns::write(str, binary, fField); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/controlDict b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/controlDict deleted file mode 100644 index 2888266a2ff183dbfe84755dd70695941550f7f0..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/controlDict +++ /dev/null @@ -1,81 +0,0 @@ -/*--------------------------------*- C++ -*----------------------------------*\ -| ========= | | -| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: plus | -| \\ / A nd | Web: www.OpenFOAM.com | -| \\/ M anipulation | | -\*---------------------------------------------------------------------------*/ -FoamFile -{ - version 2.0; - format ascii; - class dictionary; - object controlDict; -} -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// So we get a decent warning if we have multiple functionObject entries -// with the same name. -#inputMode error; - -application icoFoam; - -startFrom startTime; - -startTime 0; - -stopAt endTime; - -endTime 0.5; - -deltaT 0.005; - -writeControl timeStep; - -writeInterval 20; - -purgeWrite 0; - -writeFormat ascii; - -writePrecision 6; - -writeCompression off; - -timeFormat general; - -timePrecision 6; - -runTimeModifiable yes; - -functions -{ - writeVTK - { - type writeVTK; - - // Where to load it from - libs ("libfoamToVTK.so"); - - // When to write: - // timeStep (with optional writeInterval) - // writeTime (with optional writeInterval) - // adjustableTime - // runTime - // clockTime - // cpuTime - writeControl writeTime; - - // Write every writeInterval (only valid for timeStemp, writeTime) - writeInterval 1; - - // Interval of time (valid for adjustableTime, runTime, clockTime, - // cpuTime) - writeInterval 1; - - // Objects to write - objectNames (); - } -} - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.C deleted file mode 100644 index 2e7fa177c3f64ad8ba3e2e54f19555c70ab308e6..0000000000000000000000000000000000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.C +++ /dev/null @@ -1,156 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation - \\/ 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 "writeVTK.H" -#include "dictionary.H" -#include "Time.H" -#include "vtkMesh.H" -#include "internalWriter.H" -#include "addToRunTimeSelectionTable.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ -namespace functionObjects -{ - defineTypeNameAndDebug(writeVTK, 0); - addToRunTimeSelectionTable(functionObject, writeVTK, dictionary); -} -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::functionObjects::writeVTK::writeVTK -( - const word& name, - const Time& runTime, - const dictionary& dict -) -: - fvMeshFunctionObject(name, runTime, dict), - objectNames_() -{ - read(dict); -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::functionObjects::writeVTK::~writeVTK() -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -bool Foam::functionObjects::writeVTK::read(const dictionary& dict) -{ - dict.lookup("objects") >> objectNames_; - - return true; -} - - -bool Foam::functionObjects::writeVTK::execute() -{ - return true; -} - - -bool Foam::functionObjects::writeVTK::write() -{ - Info<< type() << " " << name() << " output:" << nl; - - Info<< "Time: " << time_.timeName() << endl; - - word timeDesc = time_.timeName(); - - // VTK/ directory in the case - fileName fvPath(time_.path()/"VTK"); - - mkDir(fvPath); - - string vtkName = time_.caseName(); - - if (Pstream::parRun()) - { - // Strip off leading casename, leaving just processor_DDD ending. - string::size_type i = vtkName.rfind("processor"); - - if (i != string::npos) - { - vtkName = vtkName.substr(i); - } - } - - // Create file and write header - fileName vtkFileName - ( - fvPath/vtkName - + "_" - + timeDesc - + ".vtk" - ); - - Info<< " Internal : " << vtkFileName << endl; - - vtkMesh vMesh(const_cast<fvMesh&>(mesh_)); - - // Write mesh - internalWriter writer(vMesh, false, vtkFileName); - - UPtrList<const volScalarField> vsf(lookupFields<volScalarField>()); - UPtrList<const volVectorField> vvf(lookupFields<volVectorField>()); - UPtrList<const volSphericalTensorField> vsptf - ( - lookupFields<volSphericalTensorField>() - ); - UPtrList<const volSymmTensorField> vstf(lookupFields<volSymmTensorField>()); - UPtrList<const volTensorField> vtf(lookupFields<volTensorField>()); - - // Write header for cellID and volFields - writeFuns::writeCellDataHeader - ( - writer.os(), - vMesh.nFieldCells(), - 1 + vsf.size() + vvf.size() + vsptf.size() + vstf.size() + vtf.size() - ); - - // Write cellID field - writer.writeCellIDs(); - - // Write volFields - writer.write(vsf); - writer.write(vvf); - writer.write(vsptf); - writer.write(vstf); - writer.write(vtf); - - return true; -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..959485fb1985279c91a269d8fa08e312ab5848bd --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C @@ -0,0 +1,279 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkLagrangianWriter.H" +#include "Cloud.H" +#include "passiveParticle.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::vtk::lagrangianWriter::beginPiece() +{ + if (!legacy_) + { + if (useVerts_) + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(fileAttr::NUMBER_OF_POINTS, nParcels_) + .xmlAttr(fileAttr::NUMBER_OF_VERTS, nParcels_) + .closeTag(); + } + else + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(fileAttr::NUMBER_OF_POINTS, nParcels_) + .closeTag(); + } + } +} + + +void Foam::vtk::lagrangianWriter::writePoints() +{ + Cloud<passiveParticle> parcels(mesh_, cloudName_, false); + nParcels_ = parcels.size(); + + const uint64_t payLoad = (nParcels_ * 3 * sizeof(float)); + + if (legacy_) + { + legacy::beginPoints(os_, nParcels_); + } + else + { + beginPiece(); // Tricky - hide in here + + format().tag(vtk::fileTag::POINTS) + .openDataArray<float,3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + } + + format().writeSize(payLoad); + + forAllConstIters(parcels, iter) + { + const point& pt = iter().position(); + + vtk::write(format(), pt); + } + format().flush(); + + if (!legacy_) + { + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + } +} + + +void Foam::vtk::lagrangianWriter::writeVertsLegacy() +{ + os_ << "VERTICES " << nParcels_ << ' ' << 2*nParcels_ << nl; + + // legacy has cells + connectivity together + // count the number of vertices referenced + + for (label i=0; i < nParcels_; ++i) + { + format().write(1); // Number of vertices for this cell (==1) + format().write(i); + } + format().flush(); +} + + +void Foam::vtk::lagrangianWriter::writeVerts() +{ + format().tag(vtk::fileTag::VERTS); + + // Same payload throughout + const uint64_t payLoad = (nParcels_ * sizeof(label)); + + // + // 'connectivity' + // = linear mapping onto points + // + { + format().openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + format().writeSize(payLoad); + for (label i=0; i < nParcels_; ++i) + { + format().write(i); + } + format().flush(); + + format().endDataArray(); + } + + + // + // 'offsets' (connectivity offsets) + // = linear mapping onto points (with 1 offset) + // + { + format().openDataArray<label>(vtk::dataArrayAttr::OFFSETS) + .closeTag(); + + format().writeSize(payLoad); + for (label i=0; i < nParcels_; ++i) + { + format().write(i+1); + } + format().flush(); + + format().endDataArray(); + } + + format().endTag(vtk::fileTag::VERTS); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::lagrangianWriter::lagrangianWriter +( + const fvMesh& mesh, + const word& cloudName, + const fileName& baseName, + const vtk::outputOptions outOpts, + const bool dummyCloud +) +: + mesh_(mesh), + legacy_(outOpts.legacy()), + useVerts_(false), + format_(), + cloudName_(cloudName), + os_(), + nParcels_(0) +{ + + outputOptions opts(outOpts); + opts.append(false); // No append supported + + os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + format_ = opts.newFormatter(os_); + + const auto& title = mesh_.time().caseName(); + + if (legacy_) + { + legacy::fileHeader(format(), title, vtk::fileTag::POLY_DATA); + + if (dummyCloud) + { + legacy::beginPoints(os_, nParcels_); + } + else + { + writePoints(); + if (useVerts_) writeVertsLegacy(); + } + } + else + { + // XML (inline) + + format() + .xmlHeader() + .xmlComment(title) + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + + if (dummyCloud) + { + beginPiece(); + } + else + { + writePoints(); + if (useVerts_) writeVerts(); + } + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::lagrangianWriter::~lagrangianWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::lagrangianWriter::beginParcelData(label nFields) +{ + const vtk::fileTag dataType = + ( + useVerts_ + ? vtk::fileTag::CELL_DATA + : vtk::fileTag::POINT_DATA + ); + + if (legacy_) + { + legacy::dataHeader(os_, dataType, nParcels_, nFields); + } + else + { + format().tag(dataType); + } +} + + +void Foam::vtk::lagrangianWriter::endParcelData() +{ + const vtk::fileTag dataType = + ( + useVerts_ + ? vtk::fileTag::CELL_DATA + : vtk::fileTag::POINT_DATA + ); + + if (!legacy_) + { + format().endTag(dataType); + } +} + + +void Foam::vtk::lagrangianWriter::writeFooter() +{ + if (!legacy_) + { + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H similarity index 56% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H rename to applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H index 24dd4a322872c92eb6f2dfa32474c7c676e728d3..5457ce8c605808ee295644f32313294f7b0b916d 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::lagrangianWriter + Foam::vtk::lagrangianWriter Description Write fields (internal). @@ -33,38 +33,70 @@ SourceFiles \*---------------------------------------------------------------------------*/ -#ifndef lagrangianWriter_H -#define lagrangianWriter_H +#ifndef foamVtkLagrangianWriter_H +#define foamVtkLagrangianWriter_H #include "OFstream.H" #include "Cloud.H" #include "volFields.H" #include "pointFields.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { - class volPointInterpolation; +namespace vtk +{ + /*---------------------------------------------------------------------------*\ - Class lagrangianWriter Declaration + Class lagrangianWriter Declaration \*---------------------------------------------------------------------------*/ class lagrangianWriter { - const fvMesh& mesh_; + // Private Member Data + + //- Reference to the OpenFOAM mesh (or subset) + const fvMesh& mesh_; + + //- Commonly used query + const bool legacy_; + + //- Write lagrangian as cell data (verts) or point data? + const bool useVerts_; + + autoPtr<vtk::formatter> format_; + + const word cloudName_; + + std::ofstream os_; + + label nParcels_; + + + // Private Member Functions - const bool binary_; + //- Begin piece + void beginPiece(); - const fileName fName_; + //- Write positions + void writePoints(); - const word cloudName_; + //- Write vertex (cells) + void writeVertsLegacy(); - std::ofstream os_; + //- Write vertex (cells) + void writeVerts(); - label nParcels_; + + //- Disallow default bitwise copy construct + lagrangianWriter(const lagrangianWriter&) = delete; + + //- Disallow default bitwise assignment + void operator=(const lagrangianWriter&) = delete; public: @@ -74,37 +106,56 @@ public: //- Construct from components lagrangianWriter ( - const fvMesh&, - const bool binary, - const fileName&, - const word&, - const bool dummyCloud + const fvMesh& mesh, + const word& cloudName, + const fileName& baseName, + const vtk::outputOptions outOpts, + const bool dummyCloud = false ); + //- Destructor + ~lagrangianWriter(); + + // Member Functions - std::ofstream& os() + inline std::ofstream& os() { return os_; } - void writeParcelHeader(const label nFields); + inline vtk::formatter& format() + { + return format_(); + } + + inline label nParcels() const + { + return nParcels_; + } + + void beginParcelData(label nFields); + void endParcelData(); + + //- Write file footer + void writeFooter(); //- Write IOField template<class Type> - void writeIOField(const wordList&); + void writeIOField(const wordList& objectNames); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "lagrangianWriterTemplates.C" + #include "foamVtkLagrangianWriterTemplates.C" #endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..bc3a2fd63084c8bdef404b89557312948ab570fc --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkLagrangianWriter.H" +#include "IOField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +void Foam::vtk::lagrangianWriter::writeIOField +( + const wordList& objectNames +) +{ + const int nCmpt(pTraits<Type>::nComponents); + + const bool useIntField = + std::is_integral<typename pTraits<Type>::cmptType>(); + + for (const word& fldName : objectNames) + { + IOobject header + ( + fldName, + mesh_.time().timeName(), + cloud::prefix/cloudName_, + mesh_, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false // no register + ); + + IOField<Type> fld(header); + + if (useIntField) + { + const uint64_t payLoad(fld.size() * nCmpt * sizeof(label)); + + if (legacy_) + { + legacy::intField(os(), fldName, nCmpt, fld.size()); + } + else + { + format().openDataArray<label, nCmpt>(fldName) + .closeTag(); + } + + format().writeSize(payLoad); + + // Ensure consistent output width + for (const Type& val : fld) + { + for (int cmpt=0; cmpt < nCmpt; ++cmpt) + { + format().write(label(component(val, cmpt))); + } + } + } + else + { + const uint64_t payLoad(fld.size() * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), fldName, nCmpt, fld.size()); + } + else + { + format().openDataArray<float, nCmpt>(fldName) + .closeTag(); + } + + format().writeSize(payLoad); + vtk::writeList(format(), fld); + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C similarity index 100% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C rename to applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H similarity index 98% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H rename to applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H index 510bd11d2536419dea3c29bfce016e2dbd5ddd8e..085570d6855aa8c8a80dcd94cebecec692a2e15f 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H @@ -48,7 +48,7 @@ namespace Foam template<class GeoField> void readFields ( - const meshSubsetHelper&, + const meshSubsetHelper& helper, const typename GeoField::Mesh& mesh, const IOobjectList& objects, const HashSet<word>& selectedFields, diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/CMakeLists.txt b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/CMakeLists.txt index ce13bed97aa657f75ad7cfb49f190c5c78ed5971..f2fd631fd1be82cf9a709cc513d42d9d034f0b16 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/CMakeLists.txt +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/CMakeLists.txt @@ -12,6 +12,7 @@ link_directories( include_directories( $ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude $ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude + $ENV{WM_PROJECT_DIR}/src/conversion/lnInclude $ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude ${PROJECT_SOURCE_DIR}/../vtkPVFoam ${PROJECT_SOURCE_DIR}/../../foamPv/lnInclude @@ -64,6 +65,7 @@ target_link_libraries( LINK_PUBLIC vtkPVFoam-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR} foamPv-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR} + conversion finiteVolume OpenFOAM ) diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml index a82c81850fa35a282bd566069b67469b21018d01..7daa151df4183f9d93a55e01cdb078341b7dbaf0 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml @@ -27,6 +27,8 @@ </Documentation> </DoubleVectorProperty> +<!-- General Controls --> + <!-- Refresh (push button) --> <Property name="Refresh" @@ -35,12 +37,10 @@ <Documentation>Rescan for updated times/fields.</Documentation> </Property> -<!-- General Controls --> - <!-- Skip Zero Time (check-box) --> <IntVectorProperty animateable="0" name="ZeroTime" - label="Skip Zero Time" + label="Skip 0/ time" command="SetSkipZeroTime" default_values="1" number_of_elements="1" @@ -54,26 +54,28 @@ <!-- Include Sets (check-box) --> <IntVectorProperty animateable="0" name="IncludeSets" + label="With Sets" command="SetIncludeSets" default_values="0" number_of_elements="1" panel_visibility="default"> <BooleanDomain name="bool"/> <Documentation> - Search the polyMesh/sets/ directory + Search the polyMesh/sets/ directory for {cell,face,point} sets </Documentation> </IntVectorProperty> <!-- Include Zones (check-box) --> <IntVectorProperty animateable="0" name="IncludeZones" + label="With Zones" command="SetIncludeZones" default_values="0" number_of_elements="1" panel_visibility="default"> <BooleanDomain name="bool"/> <Documentation> - ZoneMesh information is used to find {cell,face,point}Zones. + ZoneMesh information is used to find {cell,face,point} zones. The polyMesh/ directory is only checked on startup. </Documentation> </IntVectorProperty> @@ -88,7 +90,7 @@ panel_visibility="default"> <BooleanDomain name="bool"/> <Documentation> - Show patchGroups only. + Display patchGroups only instead of individual patches. </Documentation> </IntVectorProperty> @@ -109,6 +111,7 @@ <!-- Interpolate Fields (check-box) --> <IntVectorProperty animateable="0" name="InterpolateFields" + label="cell-to-point" command="SetInterpolateVolFields" default_values="1" number_of_elements="1" @@ -122,6 +125,7 @@ <!-- Extrapolate Patches (check-box) --> <IntVectorProperty animateable="0" name="ExtrapolatePatches" + label="field-to-patch" command="SetExtrapolatePatches" default_values="0" number_of_elements="1" @@ -132,7 +136,7 @@ </Documentation> </IntVectorProperty> - <!-- Force GUI update (check-box) --> + <!-- Force GUI update (push button) --> <IntVectorProperty animateable="0" name="UpdateGUI" command="SetUpdateGUI" @@ -148,7 +152,7 @@ <!-- Use VTK Polyhedron (check-box) --> <IntVectorProperty animateable="0" name="UseVTKPolyhedron" - label="Use VTK Polyhedron" + label="VTK Polyhedra" command="SetUseVTKPolyhedron" default_values="0" number_of_elements="1" @@ -159,16 +163,22 @@ </Documentation> </IntVectorProperty> - <!-- Cache Mesh (check-box) --> + <!-- Mesh Caching (combo-box) --> <IntVectorProperty animateable="0" - name="CacheMesh" - command="SetCacheMesh" - default_values="1" + name="MeshCaching" + command="SetMeshCaching" + default_values="3" number_of_elements="1" panel_visibility="default"> - <BooleanDomain name="bool"/> + <EnumerationDomain name="enum"> + <Entry text="No caching" value="0" /> + <Entry text="Cache fvMesh" value="1" /> + <Entry text="Cache vtk,fvMesh" value="3" /> + </EnumerationDomain> <Documentation> - Cache the fvMesh in memory. + Mesh caching styles. + Caching the OpenFOAM fvMesh reduces disk access. + Caching the VTK mesh reduces transcription overhead. </Documentation> </IntVectorProperty> @@ -185,7 +195,7 @@ <Property name="ShowPatchNames"/> <Property name="UpdateGUI"/> <Property name="UseVTKPolyhedron"/> - <Property name="CacheMesh"/> + <Property name="MeshCaching"/> </PropertyGroup> <!-- Parts Selections --> diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx index 3b6fe3da972e3c0e8d2b5607122c23a7ab5bacee..3cc3b19577317e86908f4902b457d91f2c0621e0 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx @@ -26,6 +26,7 @@ License #include "pqFoamReaderControls.h" #include <QCheckBox> +#include <QComboBox> #include <QFrame> #include <QGridLayout> #include <QPushButton> @@ -37,18 +38,31 @@ License #include "vtkSMIntVectorProperty.h" #include "vtkSMPropertyGroup.h" #include "vtkSMSourceProxy.h" +#include "vtkSMEnumerationDomain.h" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // file-scope -static QAbstractButton* setButtonProperties +// Add horizontal divider to layout +static void addHline(QGridLayout* layout, int row, int nCols) +{ + QFrame* hline = new QFrame(layout->parentWidget()); + hline->setFrameStyle(QFrame::HLine | QFrame::Sunken); + + layout->addWidget(hline, row, 0, 1, nCols); +} + + +// file-scope +// Widget properties +static QWidget* setWidgetProperties ( - QAbstractButton* b, + QWidget* widget, vtkSMProperty* prop ) { - QString tip; + widget->setFocusPolicy(Qt::NoFocus); // avoid dotted border vtkSMDocumentation* doc = prop->GetDocumentation(); if (doc) @@ -56,21 +70,33 @@ static QAbstractButton* setButtonProperties const char* txt = doc->GetDescription(); if (txt) { - tip = QString(txt).simplified(); + QString tip = QString(txt).simplified(); + if (tip.size()) + { + widget->setToolTip(tip); + } } } + return widget; +} + + +// file-scope +// Button properties +static QAbstractButton* setButtonProperties +( + QAbstractButton* b, + vtkSMProperty* prop +) +{ + setWidgetProperties(b, prop); b->setText(prop->GetXMLLabel()); - if (tip.size()) - { - b->setToolTip(tip); - } - b->setFocusPolicy(Qt::NoFocus); // avoid dotted border vtkSMIntVectorProperty* intProp = vtkSMIntVectorProperty::SafeDownCast(prop); - // initial checked state for integer (bool) properties + // Initial checked state for integer (bool) properties if (intProp) { b->setChecked(intProp->GetElement(0)); @@ -80,6 +106,66 @@ static QAbstractButton* setButtonProperties } +// file-scope +// Fill combo-box from XML enumeration +static QComboBox* setComboBoxContent +( + QComboBox* b, + vtkSMIntVectorProperty* prop +) +{ + vtkSMEnumerationDomain* propEnum = + vtkSMEnumerationDomain::SafeDownCast + ( + prop->FindDomain("vtkSMEnumerationDomain") + ); + + if (propEnum) + { + unsigned int n = propEnum->GetNumberOfEntries(); + for (unsigned int idx=0; idx < n; ++idx) + { + const int val = propEnum->GetEntryValue(idx); + const char* txt = propEnum->GetEntryText(idx); + + b->insertItem(val, txt); + } + + // Set default + const int val = prop->GetElement(0); + unsigned int idx = 0; + if (!propEnum->IsInDomain(val, idx)) + { + idx = 0; + } + b->setCurrentIndex(idx); + } + + return b; +} + + +// file-scope +// Translate a combo-box index to a lookup value +static int comboBoxValue(vtkSMIntVectorProperty* prop, int idx) +{ + vtkSMEnumerationDomain* propEnum = + vtkSMEnumerationDomain::SafeDownCast + ( + prop->FindDomain("vtkSMEnumerationDomain") + ); + + if (propEnum) + { + return propEnum->GetEntryValue(idx); + } + else + { + return idx; + } +} + + static vtkSMIntVectorProperty* lookupIntProp ( vtkSMPropertyGroup* group, @@ -102,12 +188,12 @@ static vtkSMIntVectorProperty* lookupIntProp void pqFoamReaderControls::fireCommand ( vtkSMIntVectorProperty* prop, - bool checked + int val ) { vtkSMProxy* pxy = this->proxy(); - prop->SetElement(0, checked); // Toogle bool + prop->SetElement(0, val); // Set int value, toogle bool, etc // Fire off command prop->Modified(); @@ -140,9 +226,9 @@ void pqFoamReaderControls::refreshPressed() } -void pqFoamReaderControls::cacheMesh(bool checked) +void pqFoamReaderControls::cacheMesh(int idx) { - fireCommand(cacheMesh_, checked); + fireCommand(meshCaching_, comboBoxValue(meshCaching_, idx)); } @@ -196,12 +282,14 @@ pqFoamReaderControls::pqFoamReaderControls showGroupsOnly_(lookupIntProp(group, "ShowGroupsOnly")), includeSets_(lookupIntProp(group, "IncludeSets")), includeZones_(lookupIntProp(group, "IncludeZones")), - cacheMesh_(lookupIntProp(group, "CacheMesh")) + meshCaching_(lookupIntProp(group, "MeshCaching")) { typedef vtkSMIntVectorProperty intProp; QGridLayout* form = new QGridLayout(this); + const int nCols = 3; + // ROW // ~~~ int row = 0; @@ -222,17 +310,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, zeroTime); form->addWidget(b, row, 1, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), zeroTime); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), zeroTime + ); } // LINE - // ~~~~ - ++row; - { - QFrame* hline = new QFrame(this); - hline->setFrameStyle(QFrame::HLine | QFrame::Sunken); - form->addWidget(hline, row, 0, 1, 4); - } + addHline(form, ++row, nCols); // ROW // ~~~ @@ -244,8 +329,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, includeSets_); form->addWidget(b, row, 0, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), includeSets_); - connect(b, SIGNAL(toggled(bool)), this, SLOT(includeSets(bool))); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), includeSets_ + ); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(includeSets(bool)) + ); } if (showGroupsOnly_) @@ -254,8 +345,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, showGroupsOnly_); form->addWidget(b, row, 1, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), showGroupsOnly_); - connect(b, SIGNAL(toggled(bool)), this, SLOT(showGroupsOnly(bool))); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), showGroupsOnly_ + ); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(showGroupsOnly(bool)) + ); } @@ -269,8 +366,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, includeZones_); form->addWidget(b, row, 0, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), includeZones_); - connect(b, SIGNAL(toggled(bool)), this, SLOT(includeZones(bool))); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), includeZones_ + ); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(includeZones(bool)) + ); } if (showPatchNames_) @@ -279,17 +382,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, showPatchNames_); form->addWidget(b, row, 1, Qt::AlignLeft); - connect(b, SIGNAL(toggled(bool)), this, SLOT(showPatchNames(bool))); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(showPatchNames(bool)) + ); } // LINE - // ~~~~ - ++row; - { - QFrame* hline = new QFrame(this); - hline->setFrameStyle(QFrame::HLine | QFrame::Sunken); - form->addWidget(hline, row, 0, 1, 4); - } + addHline(form, ++row, nCols); // ROW // ~~~ @@ -302,7 +402,10 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, interpolate); form->addWidget(b, row, 0, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), interpolate); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), interpolate + ); } intProp* extrapolate = lookupIntProp(group, "ExtrapolatePatches"); @@ -312,17 +415,14 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, extrapolate); form->addWidget(b, row, 1, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), extrapolate); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), extrapolate + ); } // LINE - // ~~~~ - ++row; - { - QFrame* hline = new QFrame(this); - hline->setFrameStyle(QFrame::HLine | QFrame::Sunken); - form->addWidget(hline, row, 0, 1, 4); - } + addHline(form, ++row, nCols); // ROW // ~~~ @@ -335,7 +435,10 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, updateGui); form->addWidget(b, row, 0, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(clicked()), updateGui); + addPropertyLink + ( + b, "checked", SIGNAL(clicked()), updateGui + ); } intProp* usePolyhedron = lookupIntProp(group, "UseVTKPolyhedron"); @@ -345,16 +448,29 @@ pqFoamReaderControls::pqFoamReaderControls setButtonProperties(b, usePolyhedron); form->addWidget(b, row, 1, Qt::AlignLeft); - addPropertyLink(b, "checked", SIGNAL(toggled(bool)), usePolyhedron); + addPropertyLink + ( + b, "checked", SIGNAL(toggled(bool)), usePolyhedron + ); } - if (cacheMesh_) + if (meshCaching_) { - QCheckBox* b = new QCheckBox(this); - setButtonProperties(b, cacheMesh_); + QComboBox* b = new QComboBox(this); form->addWidget(b, row, 2, Qt::AlignLeft); - connect(b, SIGNAL(toggled(bool)), this, SLOT(cacheMesh(bool))); + setWidgetProperties(b, meshCaching_); + setComboBoxContent(b, meshCaching_); + + addPropertyLink + ( + b, "indexChanged", SIGNAL(currentIndexChanged(int)), meshCaching_ + ); + + connect + ( + b, SIGNAL(currentIndexChanged(int)), this, SLOT(cacheMesh(int)) + ); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h index fc3c8d4044b7eca2ba4cb6ffccf73f6dc5624d64..ba0a7a9f6718be5eb153aa826333a0d93a983682 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h @@ -69,8 +69,8 @@ class pqFoamReaderControls //- IncludeZones (bool property) vtkSMIntVectorProperty* includeZones_; - //- CacheMesh (bool property) - vtkSMIntVectorProperty* cacheMesh_; + //- MeshCaching (enum property) + vtkSMIntVectorProperty* meshCaching_; // Private Member Functions @@ -78,8 +78,8 @@ class pqFoamReaderControls //- Update property void fireCommand(vtkSMProperty* prop); - //- Toggle and update bool property - void fireCommand(vtkSMIntVectorProperty* prop, bool checked); + //- Update int property or toggle bool property + void fireCommand(vtkSMIntVectorProperty* prop, int val); //- Disallow default bitwise copy construct @@ -102,7 +102,7 @@ protected slots: // Protected Member Functions void refreshPressed(); - void cacheMesh(bool checked); + void cacheMesh(int idx); void showPatchNames(bool checked); void showGroupsOnly(bool checked); void includeSets(bool checked); diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx index 46c01d92f7dfb5bff0a28e31fb9dd764374eda30..c6ec1e676cd5fa567bee9614c8237c870ec17a6c 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx @@ -39,6 +39,7 @@ License #include "vtkSMRenderViewProxy.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkStringArray.h" +#include "vtkSmartPointer.h" // OpenFOAM includes #include "vtkPVFoam.H" @@ -46,7 +47,7 @@ License // STL includes #include <vector> -#undef EXPERIMENTAL_TIME_CACHING +#undef VTKPVFOAM_DUALPORT // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -61,27 +62,26 @@ vtkPVFoamReader::vtkPVFoamReader() vtkDebugMacro(<<"Constructor"); SetNumberOfInputPorts(0); - FileName = nullptr; backend_ = nullptr; - output0_ = nullptr; #ifdef VTKPVFOAM_DUALPORT // Add second output for the Lagrangian this->SetNumberOfOutputPorts(2); - vtkMultiBlockDataSet *lagrangian = vtkMultiBlockDataSet::New(); + + auto lagrangian = vtkSmartPointer<vtkMultiBlockDataSet>::New(); + lagrangian->ReleaseData(); this->GetExecutive()->SetOutputData(1, lagrangian); - lagrangian->Delete(); #endif TimeStepRange[0] = 0; TimeStepRange[1] = 0; - CacheMesh = true; + MeshCaching = 3; // fvMesh+vtk - SkipZeroTime = false; + SkipZeroTime = true; ExtrapolatePatches = false; UseVTKPolyhedron = false; IncludeSets = false; @@ -146,15 +146,9 @@ vtkPVFoamReader::~vtkPVFoamReader() if (FileName) { - delete [] FileName; - } - - if (output0_) - { - output0_->Delete(); + delete[] FileName; } - PartSelection->RemoveAllObservers(); VolFieldSelection->RemoveAllObservers(); PointFieldSelection->RemoveAllObservers(); @@ -218,7 +212,7 @@ int vtkPVFoamReader::RequestInformation { vtkErrorMacro("could not find valid OpenFOAM mesh"); - // delete foamData and flag it as fatal error + // delete backend handler and flag it as fatal error delete backend_; backend_ = nullptr; return 0; @@ -255,7 +249,7 @@ int vtkPVFoamReader::RequestInformation <<"time-range " << times.front() << ':' << times.back() << "\n" <<"times " << times.size() << "("; - for (const double& val : times) + for (auto val : times) { cout<< ' ' << val; } @@ -291,12 +285,12 @@ int vtkPVFoamReader::RequestData if (!FileName) { - vtkErrorMacro("FileName has to be specified!"); + vtkErrorMacro("FileName must be specified!"); return 0; } if (!backend_) { - // catch some previous error + // Catch some previous error vtkErrorMacro("Reader failed - perhaps no mesh?"); return 0; } @@ -326,7 +320,8 @@ int vtkPVFoamReader::RequestData { vtkInformation *outInfo = outputVector->GetInformationObject(infoI); - int nsteps = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); + const int nsteps = + outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); if ( @@ -361,76 +356,23 @@ int vtkPVFoamReader::RequestData ) ); - if (Foam::vtkPVFoam::debug) - { - cout<< "update output with " - << output->GetNumberOfBlocks() << " blocks\n"; - } - - -#ifdef EXPERIMENTAL_TIME_CACHING - bool needsUpdate = false; - - if (!output0_) - { - output0_ = vtkMultiBlockDataSet::New(); - needsUpdate = true; - } - - // This experimental bit of code seems to work for the geometry, - // but trashes the fields and still triggers the GeometryFilter - if (needsUpdate) - { - backend_->Update(output); - output0_->ShallowCopy(output); - } - else - { - output->ShallowCopy(output0_); - } - - if (Foam::vtkPVFoam::debug) - { - if (needsUpdate) - { - cout<< "full UPDATE ---------\n"; - } - else - { - cout<< "cached UPDATE ---------\n"; - } - - cout<< "UPDATED output: "; - output->Print(cout); - - cout<< "UPDATED output0_: "; - output0_->Print(cout); - } - -#else - #ifdef VTKPVFOAM_DUALPORT - backend_->Update + vtkMultiBlockDataSet* output1 = vtkMultiBlockDataSet::SafeDownCast ( - output, - vtkMultiBlockDataSet::SafeDownCast + outputVector->GetInformationObject(1)->Get ( - outputVector->GetInformationObject(1)->Get - ( - vtkMultiBlockDataSet::DATA_OBJECT() - ) - ); + vtkMultiBlockDataSet::DATA_OBJECT() + ) ); + + backend_->Update(output, output1); #else - backend_->Update(output, output); + backend_->Update(output, nullptr); #endif updatePatchNamesView(ShowPatchNames); -#endif - - // Do any cleanup on the OpenFOAM side - backend_->CleanUp(); + backend_->UpdateFinalize(); return 1; } @@ -525,13 +467,11 @@ void vtkPVFoamReader::updatePatchNamesView(const bool show) } // Get all the pqRenderView instances - QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); - - for (int viewI=0; viewI < renderViews.size(); ++viewI) + for (auto view : smModel->findItems<pqRenderView*>()) { backend_->renderPatchNames ( - renderViews[viewI]->getRenderViewProxy()->GetRenderer(), + view->getRenderViewProxy()->GetRenderer(), show ); } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h index 0de09a5547b4da6319fa38959f4a7955fd08d56f..550c1167bbb887c1bfc8c81b607e3cf72e634b8a 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h @@ -46,6 +46,7 @@ SourceFiles // VTK forward declarations class vtkDataArraySelection; class vtkCallbackCommand; +template<class T> class vtkSmartPointer; // OpenFOAM forward declarations namespace Foam @@ -82,9 +83,9 @@ public: virtual void PrintInfo(); // Description: - // OpenFOAM mesh caching control - vtkSetMacro(CacheMesh, bool); - vtkGetMacro(CacheMesh, bool); + // Mesh caching control (0:none,1:fvMesh,3:fvMesh+vtk) + vtkSetMacro(MeshCaching, int); + vtkGetMacro(MeshCaching, int); // Description: // OpenFOAM refresh times/fields @@ -231,7 +232,7 @@ private: void updatePatchNamesView(const bool show); int TimeStepRange[2]; - bool CacheMesh; + int MeshCaching; bool SkipZeroTime; bool ExtrapolatePatches; @@ -250,9 +251,6 @@ private: vtkDataArraySelection* PointFieldSelection; vtkDataArraySelection* LagrangianFieldSelection; - //- Cached data for output port0 (experimental!) - vtkMultiBlockDataSet* output0_; - //- Backend portion of the reader Foam::vtkPVFoam* backend_; }; diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C index c20a9655780968ec46788d4a6850eff433777dd0..67857bc0bf1a87d049bc137026b9ab263ad2f498 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C @@ -37,40 +37,67 @@ License #include "vtkRenderer.h" #include "vtkTextActor.h" #include "vtkTextProperty.h" +#include "vtkSmartPointer.h" +#include "vtkInformation.h" + +// Templates (only needed here) +#include "vtkPVFoamUpdateTemplates.C" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(vtkPVFoam, 0); + + // file-scope + static word updateStateName(polyMesh::readUpdateState state) + { + switch (state) + { + case polyMesh::UNCHANGED: return "UNCHANGED"; + case polyMesh::POINTS_MOVED: return "POINTS_MOVED"; + case polyMesh::TOPO_CHANGE: return "TOPO_CHANGE"; + case polyMesh::TOPO_PATCH_CHANGE: return "TOPO_PATCH_CHANGE"; + }; + + return "UNKNOWN"; + } } // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -vtkTextActor* Foam::vtkPVFoam::createTextActor -( - const string& s, - const point& pt -) +namespace Foam { - vtkTextActor* txt = vtkTextActor::New(); - txt->SetInput(s.c_str()); - - // Set text properties - vtkTextProperty* tprop = txt->GetTextProperty(); - tprop->SetFontFamilyToArial(); - tprop->BoldOn(); - tprop->ShadowOff(); - tprop->SetLineSpacing(1.0); - tprop->SetFontSize(14); - tprop->SetColor(1.0, 0.0, 1.0); - tprop->SetJustificationToCentered(); - - txt->GetPositionCoordinate()->SetCoordinateSystemToWorld(); - txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); - - return txt; + // file-scope + + //- Create a text actor + vtkSmartPointer<vtkTextActor> createTextActor + ( + const std::string& s, + const Foam::point& pt + ) + { + vtkSmartPointer<vtkTextActor> txt = + vtkSmartPointer<vtkTextActor>::New(); + + txt->SetInput(s.c_str()); + + // Set text properties + vtkTextProperty* tprop = txt->GetTextProperty(); + tprop->SetFontFamilyToArial(); + tprop->BoldOn(); + tprop->ShadowOff(); + tprop->SetLineSpacing(1.0); + tprop->SetFontSize(14); + tprop->SetColor(1.0, 0.0, 1.0); + tprop->SetJustificationToCentered(); + + txt->GetPositionCoordinate()->SetCoordinateSystemToWorld(); + txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); + + return txt; + } } @@ -79,40 +106,79 @@ vtkTextActor* Foam::vtkPVFoam::createTextActor void Foam::vtkPVFoam::resetCounters() { // Reset array range information (ids and sizes) - arrayRangeVolume_.reset(); - arrayRangePatches_.reset(); - arrayRangeLagrangian_.reset(); - arrayRangeCellZones_.reset(); - arrayRangeFaceZones_.reset(); - arrayRangePointZones_.reset(); - arrayRangeCellSets_.reset(); - arrayRangeFaceSets_.reset(); - arrayRangePointSets_.reset(); + rangeVolume_.reset(); + rangePatches_.reset(); + rangeLagrangian_.reset(); + rangeCellZones_.reset(); + rangeFaceZones_.reset(); + rangePointZones_.reset(); + rangeCellSets_.reset(); + rangeFaceSets_.reset(); + rangePointSets_.reset(); } -void Foam::vtkPVFoam::reduceMemory() +template<class Container> +bool Foam::vtkPVFoam::addOutputBlock +( + vtkMultiBlockDataSet* output, + const HashTable<Container, string>& cache, + const arrayRange& selector, + const bool singleDataset +) const { - forAll(regionPolyDecomp_, i) - { - regionPolyDecomp_[i].clear(); - } + const auto blockNo = output->GetNumberOfBlocks(); + vtkSmartPointer<vtkMultiBlockDataSet> block; + int datasetNo = 0; - forAll(zonePolyDecomp_, i) + for (auto partId : selector) { - zonePolyDecomp_[i].clear(); - } + if (selectedPartIds_.found(partId)) + { + const auto& longName = selectedPartIds_[partId]; + const word shortName = getFoamName(longName); - forAll(csetPolyDecomp_, i) - { - csetPolyDecomp_[i].clear(); - } + auto iter = cache.find(longName); + if (iter.found() && iter.object().dataset) + { + auto dataset = iter.object().dataset; - if (!reader_->GetCacheMesh()) - { - delete meshPtr_; - meshPtr_ = nullptr; + if (singleDataset) + { + output->SetBlock(blockNo, dataset); + output->GetMetaData(blockNo)->Set + ( + vtkCompositeDataSet::NAME(), + shortName.c_str() + ); + + ++datasetNo; + break; + } + else if (datasetNo == 0) + { + block = vtkSmartPointer<vtkMultiBlockDataSet>::New(); + output->SetBlock(blockNo, block); + output->GetMetaData(blockNo)->Set + ( + vtkCompositeDataSet::NAME(), + selector.name() + ); + } + + block->SetBlock(datasetNo, dataset); + block->GetMetaData(datasetNo)->Set + ( + vtkCompositeDataSet::NAME(), + shortName.c_str() + ); + + ++datasetNo; + } + } } + + return datasetNo; } @@ -151,27 +217,14 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[]) << ", nearestIndex = " << nearestIndex << endl; } - - // see what has changed + // See what has changed if (timeIndex_ != nearestIndex) { timeIndex_ = nearestIndex; runTime.setTime(Times[nearestIndex], nearestIndex); - // the fields change each time - fieldsChanged_ = true; - - if (meshPtr_) - { - if (meshPtr_->readUpdate() != polyMesh::UNCHANGED) - { - meshChanged_ = true; - } - } - else - { - meshChanged_ = true; - } + // When the changes, so do the fields + meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE; reader_->UpdateProgress(0.05); @@ -184,63 +237,16 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[]) Info<< "<end> setTime() - selectedTime=" << Times[nearestIndex].name() << " index=" << timeIndex_ << "/" << Times.size() - << " meshChanged=" << Switch(meshChanged_) - << " fieldsChanged=" << Switch(fieldsChanged_) << endl; + << " meshUpdateState=" << updateStateName(meshState_) << endl; } return nearestIndex; } -void Foam::vtkPVFoam::updateMeshPartsStatus() +Foam::word Foam::vtkPVFoam::getReaderPartName(const int partId) const { - if (debug) - { - Info<< "<beg> updateMeshPartsStatus" << endl; - } - - vtkDataArraySelection* selection = reader_->GetPartSelection(); - label nElem = selection->GetNumberOfArrays(); - - if (partStatus_.size() != nElem) - { - partStatus_.setSize(nElem); - partStatus_ = false; - meshChanged_ = true; - } - - // this needs fixing if we wish to re-use the datasets - partDataset_.setSize(nElem); - partDataset_ = -1; - - // Read the selected mesh parts (zones, patches ...) and add to list - forAll(partStatus_, partId) - { - const int setting = selection->GetArraySetting(partId); - - if (partStatus_[partId] != setting) - { - partStatus_[partId] = setting; - meshChanged_ = true; - } - - if (debug > 1) - { - Info<< " part[" << partId << "] = " - << partStatus_[partId] - << " : " << selection->GetArrayName(partId) << endl; - } - } - if (debug) - { - Info<< "<end> updateMeshPartsStatus" << endl; - } -} - - -Foam::word Foam::vtkPVFoam::getPartName(const int partId) -{ - return getFirstWord(reader_->GetPartArrayName(partId)); + return getFoamName(reader_->GetPartArrayName(partId)); } @@ -258,17 +264,17 @@ Foam::vtkPVFoam::vtkPVFoam meshRegion_(polyMesh::defaultRegion), meshDir_(polyMesh::meshSubDir), timeIndex_(-1), - meshChanged_(true), - fieldsChanged_(true), - arrayRangeVolume_("unzoned"), - arrayRangePatches_("patches"), - arrayRangeLagrangian_("lagrangian"), - arrayRangeCellZones_("cellZone"), - arrayRangeFaceZones_("faceZone"), - arrayRangePointZones_("pointZone"), - arrayRangeCellSets_("cellSet"), - arrayRangeFaceSets_("faceSet"), - arrayRangePointSets_("pointSet") + decomposePoly_(false), + meshState_(polyMesh::TOPO_CHANGE), + rangeVolume_("unzoned"), + rangePatches_("patch"), + rangeLagrangian_("lagrangian"), + rangeCellZones_("cellZone"), + rangeFaceZones_("faceZone"), + rangePointZones_("pointZone"), + rangeCellSets_("cellSet"), + rangeFaceSets_("faceSet"), + rangePointSets_("pointSet") { if (debug) { @@ -393,16 +399,16 @@ void Foam::vtkPVFoam::updateInfo() // time of the vtkDataArraySelection, but the qt/paraview proxy // layer doesn't care about that anyhow. - stringList enabledEntries; + HashSet<string> enabled; if (!partSelection->GetNumberOfArrays() && !meshPtr_) { - // enable 'internalMesh' on the first call - enabledEntries = { "internalMesh" }; + // Fake enable 'internalMesh' on the first call + enabled = { "internalMesh" }; } else { // preserve the enabled selections - enabledEntries = getSelectedArrayEntries(partSelection); + enabled = getSelectedArraySet(partSelection); } // Clear current mesh parts list @@ -410,21 +416,27 @@ void Foam::vtkPVFoam::updateInfo() // Update mesh parts list - add Lagrangian at the bottom updateInfoInternalMesh(partSelection); - updateInfoPatches(partSelection, enabledEntries); + updateInfoPatches(partSelection, enabled); updateInfoSets(partSelection); updateInfoZones(partSelection); updateInfoLagrangian(partSelection); - // restore the enabled selections - setSelectedArrayEntries(partSelection, enabledEntries); - - if (meshChanged_) - { - fieldsChanged_ = true; - } + // Adjust/restore the enabled selections + setSelectedArrayEntries(partSelection, enabled); // Update volume, point and lagrangian fields - updateInfoFields(); + updateInfoFields<fvPatchField, volMesh> + ( + reader_->GetVolFieldSelection() + ); + updateInfoFields<pointPatchField, pointMesh> + ( + reader_->GetPointFieldSelection() + ); + updateInfoLagrangianFields + ( + reader_->GetLagrangianFieldSelection() + ); if (debug) { @@ -433,135 +445,220 @@ void Foam::vtkPVFoam::updateInfo() } -void Foam::vtkPVFoam::updateFoamMesh() +void Foam::vtkPVFoam::Update +( + vtkMultiBlockDataSet* output, + vtkMultiBlockDataSet* outputLagrangian +) { if (debug) { - Info<< "<beg> updateFoamMesh" << endl; + cout<< "<beg> Foam::vtkPVFoam::Update\n"; + output->Print(cout); + if (outputLagrangian) outputLagrangian->Print(cout); printMemory(); } + reader_->UpdateProgress(0.1); - if (!reader_->GetCacheMesh()) - { - delete meshPtr_; - meshPtr_ = nullptr; - } + const int caching = reader_->GetMeshCaching(); + const bool oldDecomp = decomposePoly_; + decomposePoly_ = !reader_->GetUseVTKPolyhedron(); - // Check to see if the OpenFOAM mesh has been created - if (!meshPtr_) + // Set up mesh parts selection(s) + // Update cached, saved, unneed values. { - if (debug) + vtkDataArraySelection* selection = reader_->GetPartSelection(); + const int n = selection->GetNumberOfArrays(); + + selectedPartIds_.clear(); + HashSet<string> nowActive; + + for (int id=0; id < n; ++id) { - Info<< "Creating OpenFOAM mesh for region " << meshRegion_ - << " at time=" << dbPtr_().timeName() - << endl; + const string str(selection->GetArrayName(id)); + const bool status = selection->GetArraySetting(id); + + if (status) + { + selectedPartIds_.set(id, str); // id -> name + nowActive.set(str); + } + if (debug > 1) + { + Info<< " part[" << id << "] = " << status + << " : " << str << nl; + } } - meshPtr_ = new fvMesh - ( - IOobject - ( - meshRegion_, - dbPtr_().timeName(), - dbPtr_(), - IOobject::MUST_READ - ) - ); + // Dispose of unneeded components + cachedVtp_.retain(nowActive); + cachedVtu_.retain(nowActive); - meshChanged_ = true; - } - else - { - if (debug) + if + ( + !caching + || meshState_ == polyMesh::TOPO_CHANGE + || meshState_ == polyMesh::TOPO_PATCH_CHANGE + ) { - Info<< "Using existing OpenFOAM mesh" << endl; + // Eliminate cached values that would be unreliable + forAllIters(cachedVtp_, iter) + { + iter.object().clearGeom(); + iter.object().clear(); + } + forAllIters(cachedVtu_, iter) + { + iter.object().clearGeom(); + iter.object().clear(); + } + } + else if (oldDecomp != decomposePoly_) + { + // poly-decompose changed - dispose of cached values + forAllIters(cachedVtu_, iter) + { + iter.object().clearGeom(); + iter.object().clear(); + } } } - if (debug) + reader_->UpdateProgress(0.15); + + // Update the OpenFOAM mesh { - Info<< "<end> updateFoamMesh" << endl; - printMemory(); - } -} + if (debug) + { + Info<< "<beg> updateFoamMesh" << endl; + printMemory(); + } + if (!caching) + { + delete meshPtr_; + meshPtr_ = nullptr; + } -void Foam::vtkPVFoam::Update -( - vtkMultiBlockDataSet* output, - vtkMultiBlockDataSet* lagrangianOutput -) -{ - if (debug) - { - cout<< "<beg> Foam::vtkPVFoam::Update - output with " - << output->GetNumberOfBlocks() << " and " - << lagrangianOutput->GetNumberOfBlocks() << " blocks\n"; - output->Print(cout); - lagrangianOutput->Print(cout); - printMemory(); - } - reader_->UpdateProgress(0.1); + // Check to see if the OpenFOAM mesh has been created + if (!meshPtr_) + { + if (debug) + { + Info<< "Creating OpenFOAM mesh for region " << meshRegion_ + << " at time=" << dbPtr_().timeName() << endl; + } - // Set up mesh parts selection(s) - updateMeshPartsStatus(); + meshPtr_ = new fvMesh + ( + IOobject + ( + meshRegion_, + dbPtr_().timeName(), + dbPtr_(), + IOobject::MUST_READ + ) + ); + + meshState_ = polyMesh::TOPO_CHANGE; // New mesh + } + else + { + if (debug) + { + Info<< "Using existing OpenFOAM mesh" << endl; + } + } - reader_->UpdateProgress(0.15); + if (debug) + { + Info<< "<end> updateFoamMesh" << endl; + printMemory(); + } + } - // Update the OpenFOAM mesh - updateFoamMesh(); reader_->UpdateProgress(0.4); - // Convert meshes - start port0 at block=0 - int blockNo = 0; - - convertMeshVolume(output, blockNo); - convertMeshPatches(output, blockNo); + convertMeshVolume(); + convertMeshPatches(); reader_->UpdateProgress(0.6); if (reader_->GetIncludeZones()) { - convertMeshCellZones(output, blockNo); - convertMeshFaceZones(output, blockNo); - convertMeshPointZones(output, blockNo); + convertMeshCellZones(); + convertMeshFaceZones(); + convertMeshPointZones(); reader_->UpdateProgress(0.65); } if (reader_->GetIncludeSets()) { - convertMeshCellSets(output, blockNo); - convertMeshFaceSets(output, blockNo); - convertMeshPointSets(output, blockNo); + convertMeshCellSets(); + convertMeshFaceSets(); + convertMeshPointSets(); reader_->UpdateProgress(0.7); } -#ifdef VTKPVFOAM_DUALPORT - // restart port1 at block=0 - blockNo = 0; -#endif - convertMeshLagrangian(lagrangianOutput, blockNo); + convertMeshLagrangian(); reader_->UpdateProgress(0.8); // Update fields - convertVolFields(output); - convertPointFields(output); - convertLagrangianFields(lagrangianOutput); + convertVolFields(); + convertPointFields(); + convertLagrangianFields(); + + + // Assemble multiblock output + addOutputBlock(output, cachedVtu_, rangeVolume_, true); // One dataset + addOutputBlock(output, cachedVtp_, rangePatches_); + addOutputBlock(output, cachedVtu_, rangeCellZones_); + addOutputBlock(output, cachedVtp_, rangeFaceZones_); + addOutputBlock(output, cachedVtp_, rangePointZones_); + addOutputBlock(output, cachedVtu_, rangeCellSets_); + addOutputBlock(output, cachedVtp_, rangeFaceSets_); + addOutputBlock(output, cachedVtp_, rangePointSets_); + addOutputBlock + ( + (outputLagrangian ? outputLagrangian : output), + cachedVtp_, + rangeLagrangian_ + ); + if (debug) { Info<< "done reader part" << nl << endl; } reader_->UpdateProgress(0.95); - meshChanged_ = fieldsChanged_ = false; + meshState_ = polyMesh::UNCHANGED; + + if (caching & 2) + { + // Suppress caching of Lagrangian since it normally always changes. + cachedVtp_.filterKeys + ( + [](const word& k){ return k.startsWith("lagrangian/"); }, + true // prune + ); + } + else + { + cachedVtp_.clear(); + cachedVtu_.clear(); + } } -void Foam::vtkPVFoam::CleanUp() +void Foam::vtkPVFoam::UpdateFinalize() { - // reclaim some memory - reduceMemory(); + if (!reader_->GetMeshCaching()) + { + delete meshPtr_; + meshPtr_ = nullptr; + } + reader_->UpdateProgress(1.0); } @@ -640,20 +737,19 @@ void Foam::vtkPVFoam::renderPatchNames { // always remove old actors first - forAll(patchTextActorsPtrs_, patchi) + forAll(patchTextActors_, patchi) { - renderer->RemoveViewProp(patchTextActorsPtrs_[patchi]); - patchTextActorsPtrs_[patchi]->Delete(); + renderer->RemoveViewProp(patchTextActors_[patchi]); } - patchTextActorsPtrs_.clear(); + patchTextActors_.clear(); if (show && meshPtr_) { - // get the display patches, strip off any suffix + // get the display patches, strip off any prefix/suffix hashedWordList selectedPatches = getSelected ( reader_->GetPartSelection(), - arrayRangePatches_ + rangePatches_ ); if (selectedPatches.empty()) @@ -750,7 +846,7 @@ void Foam::vtkPVFoam::renderPatchNames } // Set the size of the patch labels to max number of zones - patchTextActorsPtrs_.setSize(displayZoneI); + patchTextActors_.setSize(displayZoneI); if (debug) { @@ -783,7 +879,7 @@ void Foam::vtkPVFoam::renderPatchNames } // Into a list for later removal - patchTextActorsPtrs_[displayZoneI++] = createTextActor + patchTextActors_[displayZoneI++] = createTextActor ( pp.name(), zoneCentre[patchi][globalZoneI] @@ -792,13 +888,13 @@ void Foam::vtkPVFoam::renderPatchNames } // Resize the patch names list to the actual number of patch names added - patchTextActorsPtrs_.setSize(displayZoneI); + patchTextActors_.setSize(displayZoneI); } // Add text to each renderer - forAll(patchTextActorsPtrs_, actori) + forAll(patchTextActors_, actori) { - renderer->AddViewProp(patchTextActorsPtrs_[actori]); + renderer->AddViewProp(patchTextActors_[actori]); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H index 3f0a1ad55d700ca1d6df81dbb4bac32e427bbe52..55ec9d73e1e3916ea309d99687662028d039e677 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H @@ -25,7 +25,25 @@ Class Foam::vtkPVFoam Description - Provides a reader interface for OpenFOAM to VTK interaction. + The backend for the vtkPVFoamReader reader module - + providing a paraview reader interface for OpenFOAM meshes and fields. + + Similar, and sometimes better, functionality may be provided by the + native VTK OpenFOAM reader. OpenCFD has recently (2017) been working + on improving the native VTK OpenFOAM reader for the benefit of everyone. + + In some areas the reader module lacks compared to the native reader + (notably the ability to work on decomosed datasets), but provides + additional handling of sets,zones,groups. Some features have also since + been adapted to the native reader. Additionally, the reader module + provides a useful platform for testing new ideas. + +Note + The reader module allows two levels of caching. The OpenFOAM fvMesh + can be cached in memory, for faster loading of fields. Additionally, + the translated VTK geometries are held in a local cache. The cached + VTK geometries should incur no additional overhead since they use + the VTK reference counting for their storage management. SourceFiles vtkPVFoam.C @@ -35,7 +53,6 @@ SourceFiles vtkPVFoamMeshVolume.C vtkPVFoamTemplates.C vtkPVFoamUpdateInfo.C - vtkPVFoamUtils.C vtkPVFoamFieldTemplates.C vtkPVFoamUpdateTemplates.C @@ -55,22 +72,24 @@ SourceFiles #include "PrimitivePatchInterpolation.H" #include "volPointInterpolation.H" #include "foamPvCore.H" +#include "foamVtkMeshMaps.H" -#undef VTKPVFOAM_DUALPORT +#include "vtkPoints.h" +#include "vtkPolyData.h" +#include "vtkSmartPointer.h" +#include "vtkUnstructuredGrid.h" // * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // +class vtkCellArray; class vtkDataArraySelection; class vtkDataSet; class vtkFloatArray; -class vtkPoints; +class vtkIndent; +class vtkMultiBlockDataSet; class vtkPVFoamReader; class vtkRenderer; class vtkTextActor; -class vtkMultiBlockDataSet; -class vtkPolyData; -class vtkUnstructuredGrid; -class vtkIndent; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -83,6 +102,7 @@ class Time; class fvMesh; class IOobjectList; class polyPatch; +class fvMeshSubset; template<class Type> class IOField; template<class Type> class Field; @@ -102,66 +122,101 @@ class vtkPVFoam // Private classes - //- Bookkeeping for polyhedral cell decomposition - // hide in extra pointMap (cellSet/cellZone) for now - class polyDecomp + //- Bookkeeping for internal caching. + // Retain an original copy of the geometry as well as a shallow copy + // with the output fields. + // The original copy is reused for different timestep + template<class DataType> + class foamVtkCaching { - labelList superCells_; - labelList addPointCellLabels_; - labelList pointMap_; - public: + typedef DataType dataType; - polyDecomp() - {} + //- The geometry, without any cell/point data + vtkSmartPointer<dataType> vtkgeom; - //- Label of original cell for decomposed cells - labelList& superCells() - { - return superCells_; - } + //- The shallow-copy of geometry, plus additional data + vtkSmartPointer<dataType> dataset; - //- Label of original cell for decomposed cells - const labelList& superCells() const + //- Number of points associated with geometry + inline uint64_t nPoints() const { - return superCells_; + return vtkgeom ? vtkgeom->GetNumberOfPoints() : 0; } - //- Cell-centre labels for additional points of decomposed cells - labelList& addPointCellLabels() + //- Clear geometry and dataset + void clearGeom() { - return addPointCellLabels_; + vtkgeom = nullptr; + dataset = nullptr; } - //- Cell-centre labels for additional points of decomposed cells - const labelList& addPointCellLabels() const + //- Return a shallow copy of vtkgeom for manipulation + vtkSmartPointer<dataType> getCopy() const { - return addPointCellLabels_; + auto copy = vtkSmartPointer<dataType>::New(); + copy->ShallowCopy(vtkgeom); + return copy; } - //- Point labels for subsetted meshes - labelList& pointMap() + //- Make a shallow copy of vtkgeom into dataset + void reuse() { - return pointMap_; + dataset = vtkSmartPointer<dataType>::New(); + dataset->ShallowCopy(vtkgeom); } - //- Point labels for subsetted meshes - const labelList& pointMap() const + //- Set the geometry and make a shallow copy to dataset + void set(vtkSmartPointer<dataType> geom) { - return pointMap_; + vtkgeom = geom; + reuse(); } - - //- Clear - void clear() + //- Report basic information to output + void PrintSelf(std::ostream& os) const { - superCells_.clear(); - addPointCellLabels_.clear(); - pointMap_.clear(); + os << "geom" << nl; + if (vtkgeom) + { + vtkgeom->PrintSelf(std::cout, vtkIndent(2)); + } + else + { + os << "nullptr"; + } + os << nl; + + os << "copy" << nl; + if (dataset) + { + dataset->PrintSelf(std::cout, vtkIndent(2)); + } + else + { + os << "nullptr"; + } + os << nl; } }; + //- Bookkeeping for vtkPolyData + class foamVtpData + : + public foamVtkCaching<vtkPolyData>, + public foamVtkMeshMaps + {}; + + + //- Bookkeeping for vtkUnstructuredGrid + class foamVtuData + : + public foamVtkCaching<vtkUnstructuredGrid>, + public foamVtkMeshMaps + {}; + + // Private Data //- Access to the controlling vtkPVFoamReader @@ -182,72 +237,74 @@ class vtkPVFoam //- The time index int timeIndex_; + //- Previous/current decomposition request + bool decomposePoly_; + //- Track changes in mesh geometry - bool meshChanged_; + enum polyMesh::readUpdateState meshState_; - //- Track changes in fields - bool fieldsChanged_; + //- The index of selected parts mapped to their names + Map<string> selectedPartIds_; - //- Selected geometrical parts (internalMesh, patches, ...) - boolList partStatus_; + //- Any information for 2D (VTP) geometries + HashTable<foamVtpData, string> cachedVtp_; - //- Datasets corresponding to selected geometrical pieces - // a negative number indicates that no vtkmesh exists for this piece - labelList partDataset_; + //- Cell maps and other information for 3D (VTU) geometries + HashTable<foamVtuData, string> cachedVtu_; //- First instance and size of various mesh parts - // used to index into partStatus_ and partDataset_ - arrayRange arrayRangeVolume_; - arrayRange arrayRangePatches_; - arrayRange arrayRangeLagrangian_; - arrayRange arrayRangeCellZones_; - arrayRange arrayRangeFaceZones_; - arrayRange arrayRangePointZones_; - arrayRange arrayRangeCellSets_; - arrayRange arrayRangeFaceSets_; - arrayRange arrayRangePointSets_; - - //- Decomposed cells information (mesh regions) - // TODO: regions - List<polyDecomp> regionPolyDecomp_; - - //- Decomposed cells information (cellZone meshes) - List<polyDecomp> zonePolyDecomp_; - - //- Decomposed cells information (cellSet meshes) - List<polyDecomp> csetPolyDecomp_; + // used to index into selectedPartIds and thus indirectly into + // cachedVtp, cachedVtu + arrayRange rangeVolume_; + arrayRange rangePatches_; + arrayRange rangeLagrangian_; + arrayRange rangeCellZones_; + arrayRange rangeFaceZones_; + arrayRange rangePointZones_; + arrayRange rangeCellSets_; + arrayRange rangeFaceSets_; + arrayRange rangePointSets_; //- List of patch names for rendering to window - List<vtkTextActor*> patchTextActorsPtrs_; + List<vtkSmartPointer<vtkTextActor>> patchTextActors_; // Private Member Functions - //- Create a text actor - static vtkTextActor* createTextActor(const string& s, const point& pt); + template<class Container> + bool addOutputBlock + ( + vtkMultiBlockDataSet* output, + const HashTable<Container, string>& cache, + const arrayRange& selector, + const bool singleDataset = false + ) const; + //- Reset data counters void resetCounters(); // Update information helper functions - //- Update the mesh parts selected in the GUI - void updateMeshPartsStatus(); - //- Internal mesh info - void updateInfoInternalMesh(vtkDataArraySelection*); + void updateInfoInternalMesh(vtkDataArraySelection* select); //- Lagrangian info - void updateInfoLagrangian(vtkDataArraySelection*); + void updateInfoLagrangian(vtkDataArraySelection* select); - //- Patch info - void updateInfoPatches(vtkDataArraySelection*, stringList&); + //- Patch info, modifies enabledEntries + void updateInfoPatches + ( + vtkDataArraySelection* select, + HashSet<string>& enabledEntries + ); //- Set info - void updateInfoSets(vtkDataArraySelection*); + void updateInfoSets(vtkDataArraySelection* select); //- Zone info - void updateInfoZones(vtkDataArraySelection*); + void updateInfoZones(vtkDataArraySelection* select); + //- Get non-empty zone names for zoneType from file wordList getZoneNames(const word& zoneType) const; @@ -259,9 +316,6 @@ class vtkPVFoam const ZoneMesh<ZoneType, polyMesh>& zmesh ); - //- Field (volume, point, lagrangian) info - void updateInfoFields(); - //- Field info template<template<class> class patchType, class meshType> void updateInfoFields @@ -273,105 +327,171 @@ class vtkPVFoam void updateInfoLagrangianFields(vtkDataArraySelection* select); - // Update helper functions - - //- OpenFOAM mesh - void updateFoamMesh(); - - //- Reduce memory footprint after conversion - void reduceMemory(); - - // Mesh conversion functions - //- Convert volume mesh - void convertMeshVolume(vtkMultiBlockDataSet* output, int& blockNo); + //- Convert InternalMesh + void convertMeshVolume(); //- Convert Lagrangian points - void convertMeshLagrangian(vtkMultiBlockDataSet* output, int& blockNo); + void convertMeshLagrangian(); - //- Convert mesh patches - void convertMeshPatches(vtkMultiBlockDataSet* output, int& blockNo); + //- Convert mesh patches. + // The additionalIds (cached data) contain the patch Ids. + // There will be several for groups, but only one for regular patches. + void convertMeshPatches(); //- Convert cell zones - void convertMeshCellZones(vtkMultiBlockDataSet* output, int& blockNo); - - //- Convert face zones - void convertMeshFaceZones(vtkMultiBlockDataSet* output, int& blockNo); - - //- Convert point zones - void convertMeshPointZones(vtkMultiBlockDataSet* output, int& blockNo); + void convertMeshCellZones(); //- Convert cell sets - void convertMeshCellSets(vtkMultiBlockDataSet* output, int& blockNo); + void convertMeshCellSets(); + + //- Convert face zones + void convertMeshFaceZones(); //- Convert face sets - void convertMeshFaceSets(vtkMultiBlockDataSet* output, int& blockNo); + // The cellMap (cached data) contains the face-labels. + void convertMeshFaceSets(); + + //- Convert point zones + // The pointMap (cached data) contains the point-labels. + void convertMeshPointZones(); //- Convert point sets - void convertMeshPointSets(vtkMultiBlockDataSet* output, int& blockNo); + // The pointMap (cached data) contains the point-labels. + void convertMeshPointSets(); // Add mesh functions - //- Volume meshes as vtkUnstructuredGrid - vtkUnstructuredGrid* volumeVTKMesh + //- Generate vtk points for the current mesh points/decomposition + static vtkSmartPointer<vtkPoints> movePoints + ( + const fvMesh& mesh, + const foamVtuData& vtuData + ); + + //- Generate vtk points for the current mesh points/decomposition, + // using the provided pointMap + static vtkSmartPointer<vtkPoints> movePoints + ( + const fvMesh& mesh, + const foamVtuData& vtuData, + const labelUList& pointMap + ); + + //- Volume mesh as vtkUnstructuredGrid + static vtkSmartPointer<vtkUnstructuredGrid> volumeVTKMesh ( const fvMesh& mesh, - polyDecomp& decompInfo + foamVtuData& vtuData, + const bool decompPoly ); + //- Subsetted mesh as vtkUnstructuredGrid + static vtkSmartPointer<vtkUnstructuredGrid> volumeVTKSubsetMesh + ( + const fvMeshSubset& subsetter, + foamVtuData& vtuData, + const bool decompPoly + ); + + //- Volume mesh as vtkUnstructuredGrid + vtkSmartPointer<vtkUnstructuredGrid> volumeVTKMesh + ( + const fvMesh& mesh, + foamVtuData& vtuData + ) const; + + //- Subsetted mesh as vtkUnstructuredGrid + vtkSmartPointer<vtkUnstructuredGrid> volumeVTKSubsetMesh + ( + const fvMeshSubset& subsetter, + foamVtuData& vtuData + ) const; + //- Lagrangian positions as vtkPolyData - vtkPolyData* lagrangianVTKMesh + vtkSmartPointer<vtkPolyData> lagrangianVTKMesh ( const polyMesh& mesh, const word& cloudName + ) const; + + //- Patch points + template<class PatchType> + static vtkSmartPointer<vtkPoints> movePatchPoints + ( + const PatchType& p + ); + + //- Patch faces as vtk-cells + template<class PatchType> + static vtkSmartPointer<vtkCellArray> patchFacesVTKCells + ( + const PatchType& p ); //- Patches (mesh or primitive) as vtkPolyData template<class PatchType> - vtkPolyData* patchVTKMesh + static vtkSmartPointer<vtkPolyData> patchVTKMesh ( - const word& name, const PatchType& p ); // Field conversion functions - //- Convert Field to VTK field + //- Copy list to pre-allocated vtk array. + // \return number of input items copied + template<class Type> + static label transcribeFloatData + ( + vtkFloatArray* array, + const UList<Type>& input, + const label start = 0 + ); + + //- Create named field initialized to zero template<class Type> - vtkFloatArray* convertFieldToVTK + static vtkSmartPointer<vtkFloatArray> zeroVTKField ( const word& name, - const Field<Type>& fld + const label size ); + //- Convert float data to VTK field + template<class Type> + vtkSmartPointer<vtkFloatArray> convertFieldToVTK + ( + const word& name, + const UList<Type>& fld + ) const; + //- Face set/zone field template<class Type> - vtkFloatArray* convertFaceFieldToVTK + vtkSmartPointer<vtkFloatArray> convertFaceFieldToVTK ( const GeometricField<Type, fvPatchField, volMesh>& fld, const labelUList& faceLabels - ); + ) const; //- Volume field template<class Type> - vtkFloatArray* convertVolFieldToVTK + vtkSmartPointer<vtkFloatArray> convertVolFieldToVTK ( const GeometricField<Type, fvPatchField, volMesh>& fld, - const polyDecomp& decompInfo - ); + const foamVtuData& vtuData + ) const; //- Convert volume fields - void convertVolFields(vtkMultiBlockDataSet* output); + void convertVolFields(); //- Convert point fields - void convertPointFields(vtkMultiBlockDataSet* output); + void convertPointFields(); //- Convert Lagrangian fields - void convertLagrangianFields(vtkMultiBlockDataSet* output); + void convertLagrangianFields(); // Convert OpenFOAM fields @@ -381,8 +501,7 @@ class vtkPVFoam void convertVolField ( const PtrList<patchInterpolator>& patchInterpList, - const GeometricField<Type, fvPatchField, volMesh>& fld, - vtkMultiBlockDataSet* output + const GeometricField<Type, fvPatchField, volMesh>& fld ); //- Volume fields - all types @@ -391,8 +510,7 @@ class vtkPVFoam ( const fvMesh& mesh, const PtrList<patchInterpolator>& patchInterpList, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objects ); //- Volume internal fields (DimensionedField)- all types @@ -401,8 +519,7 @@ class vtkPVFoam ( const fvMesh& mesh, const PtrList<patchInterpolator>& patchInterpList, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objects ); //- Volume field - all selected parts @@ -411,9 +528,7 @@ class vtkPVFoam ( const GeometricField<Type, fvPatchField, volMesh>& fld, autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr, - vtkMultiBlockDataSet* output, - const arrayRange& range, - const List<polyDecomp>& decompLst + const arrayRange& range ); //- Lagrangian fields - all types @@ -421,8 +536,7 @@ class vtkPVFoam void convertLagrangianFields ( const IOobjectList& objects, - vtkMultiBlockDataSet* output, - const label datasetNo + vtkPolyData* vtkmesh ); //- Point fields - all types @@ -430,8 +544,7 @@ class vtkPVFoam void convertPointFields ( const pointMesh& pMesh, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objectst ); //- Point field - all selected parts @@ -439,33 +552,23 @@ class vtkPVFoam void convertPointFieldBlock ( const GeometricField<Type, pointPatchField, pointMesh>& pfld, - vtkMultiBlockDataSet* output, - const arrayRange& range, - const List<polyDecomp>& decompLst + const arrayRange& range ); //- Point field template<class Type> - void convertPointField + vtkSmartPointer<vtkFloatArray> convertPointField ( - vtkUnstructuredGrid* vtkmesh, const GeometricField<Type, pointPatchField, pointMesh>& pfld, const GeometricField<Type, fvPatchField, volMesh>& vfld, - const polyDecomp& decomp + const foamVtuData& vtuData ); // GUI selection helper functions - //- Only retain specified fields - static void pruneObjectList - ( - IOobjectList& objects, - const hashedWordList& retain - ); - //- Get the first word from the reader 'parts' selection - word getPartName(const int partId); + word getReaderPartName(const int partId) const; // Constructors @@ -506,19 +609,19 @@ public: void Update ( vtkMultiBlockDataSet* output, - vtkMultiBlockDataSet* lagrangianOutput + vtkMultiBlockDataSet* outputLagrangian ); - //- Clean any storage - void CleanUp(); + //- Final part of Update(), after any last minute rendering. + void UpdateFinalize(); + + //- Add/remove patch names to/from the view + void renderPatchNames(vtkRenderer* renderer, const bool show); //- Return a list of selected times. // Use STL container since these values are used by the plugin std::vector<double> findTimes(const bool skipZero = false) const; - //- Add/remove patch names to/from the view - void renderPatchNames(vtkRenderer*, const bool show); - //- Set the runTime to the first plausible request time, // returns the timeIndex // sets to "constant" on error diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C index c6b9e3b86c211b6bfb3d9a37cff8ac574e8ecd9f..fdab4abe23ba496bce96e8885cb57cc2e3f22ba4 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C @@ -30,6 +30,7 @@ InClass #define vtkPVFoamFieldTemplates_C // OpenFOAM includes +#include "error.H" #include "emptyFvPatchField.H" #include "wallPolyPatch.H" #include "faceSet.H" @@ -42,6 +43,7 @@ InClass #include "vtkFloatArray.h" #include "vtkCellData.h" #include "vtkPointData.h" +#include "vtkSmartPointer.h" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // @@ -52,8 +54,7 @@ template<class Type> void Foam::vtkPVFoam::convertVolField ( const PtrList<patchInterpolator>& patchInterpList, - const GeometricField<Type, fvPatchField, volMesh>& fld, - vtkMultiBlockDataSet* output + const GeometricField<Type, fvPatchField, volMesh>& fld ) { const fvMesh& mesh = fld.mesh(); @@ -77,138 +78,129 @@ void Foam::vtkPVFoam::convertVolField ); } - // Convert activated internalMesh regions - convertVolFieldBlock - ( - fld, - ptfPtr, - output, - arrayRangeVolume_, - regionPolyDecomp_ - ); - - // Convert activated cellZones - convertVolFieldBlock - ( - fld, - ptfPtr, - output, - arrayRangeCellZones_, - zonePolyDecomp_ - ); - - // Convert activated cellSets - convertVolFieldBlock - ( - fld, - ptfPtr, - output, - arrayRangeCellSets_, - csetPolyDecomp_ - ); - - - // - // Convert patches - if activated - // - for - ( - int partId = arrayRangePatches_.start(); - partId < arrayRangePatches_.end(); - ++partId - ) - { - const word patchName = getPartName(partId); - const label datasetNo = partDataset_[partId]; - const label patchId = patches.findPatchID(patchName); + convertVolFieldBlock(fld, ptfPtr, rangeVolume_); // internalMesh + convertVolFieldBlock(fld, ptfPtr, rangeCellZones_); // cellZones + convertVolFieldBlock(fld, ptfPtr, rangeCellSets_); // cellSets - if (!partStatus_[partId] || patchId < 0) + // Patches - currently skip field conversion for groups + for (auto partId : rangePatches_) + { + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; - vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData> - ( - output, arrayRangePatches_, datasetNo - ); + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) + { + // Should not happen, but for safety require a vtk geometry + continue; + } + foamVtpData& vtpData = iter.object(); + auto dataset = vtpData.dataset; - if (!vtkmesh) + const labelList& patchIds = vtpData.additionalIds(); + if (patchIds.empty()) { continue; } - const fvPatchField<Type>& ptf = fld.boundaryField()[patchId]; + // This is slightly roundabout, but we deal with groups and with + // single patches. + // For groups (spanning several patches) it is fairly messy to + // get interpolated point fields. We would need to create a indirect + // patch each time to obtain the mesh points. We thus skip that. + // + // To improve code reuse, we allocate the CellData as a zeroed-field + // ahead of time. - if + vtkSmartPointer<vtkFloatArray> cdata = zeroVTKField<Type> ( - isType<emptyFvPatchField<Type>>(ptf) - || - ( - extrapPatch - && !polyPatch::constraintType(patches[patchId].type()) - ) - ) - { - fvPatch p(ptf.patch().patch(), mesh.boundary()); + fld.name(), + dataset->GetNumberOfPolys() + ); - tmp<Field<Type>> tpptf - ( - fvPatchField<Type>(p, fld).patchInternalField() - ); + vtkSmartPointer<vtkFloatArray> pdata; + const bool allowPdata = (interpField && patchIds.size() == 1); - vtkFloatArray* cdata = convertFieldToVTK(fld.name(), tpptf()); - vtkmesh->GetCellData()->AddArray(cdata); - cdata->Delete(); + label coffset = 0; // the write offset into cell-data + for (label patchId : patchIds) + { + const fvPatchField<Type>& ptf = fld.boundaryField()[patchId]; - if (patchId < patchInterpList.size()) + if + ( + isType<emptyFvPatchField<Type>>(ptf) + || + ( + extrapPatch + && !polyPatch::constraintType(patches[patchId].type()) + ) + ) { - vtkFloatArray* pdata = convertFieldToVTK + fvPatch p(ptf.patch().patch(), mesh.boundary()); + + tmp<Field<Type>> tpptf ( - fld.name(), - patchInterpList[patchId].faceToPointInterpolate(tpptf)() + fvPatchField<Type>(p, fld).patchInternalField() ); - vtkmesh->GetPointData()->AddArray(pdata); - pdata->Delete(); - } - } - else - { - vtkFloatArray* cdata = convertFieldToVTK(fld.name(), ptf); - vtkmesh->GetCellData()->AddArray(cdata); - cdata->Delete(); + coffset += transcribeFloatData(cdata, tpptf(), coffset); - if (patchId < patchInterpList.size()) + if (allowPdata && patchId < patchInterpList.size()) + { + pdata = convertFieldToVTK + ( + fld.name(), + patchInterpList[patchId].faceToPointInterpolate(tpptf)() + ); + } + } + else { - vtkFloatArray* pdata = convertFieldToVTK - ( - fld.name(), - patchInterpList[patchId].faceToPointInterpolate(ptf)() - ); - - vtkmesh->GetPointData()->AddArray(pdata); - pdata->Delete(); + coffset += transcribeFloatData(cdata, ptf, coffset); + + if (allowPdata && patchId < patchInterpList.size()) + { + pdata = convertFieldToVTK + ( + fld.name(), + patchInterpList[patchId].faceToPointInterpolate(ptf)() + ); + } } } + + if (cdata) + { + dataset->GetCellData()->AddArray(cdata); + } + if (pdata) + { + dataset->GetPointData()->AddArray(pdata); + } } - // - // Convert face zones - if activated - // - for - ( - int partId = arrayRangeFaceZones_.start(); - partId < arrayRangeFaceZones_.end(); - ++partId - ) + + // Face Zones + for (auto partId : rangeFaceZones_) { - const word zoneName = getPartName(partId); - const label datasetNo = partDataset_[partId]; + if (!selectedPartIds_.found(partId)) + { + continue; + } + const auto& longName = selectedPartIds_[partId]; + const word zoneName = getFoamName(longName); - if (!partStatus_[partId] || datasetNo < 0) + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) { + // Should not happen, but for safety require a vtk geometry continue; } + foamVtpData& vtpData = iter.object(); + auto dataset = vtpData.dataset; const faceZoneMesh& zMesh = mesh.faceZones(); const label zoneId = zMesh.findZoneID(zoneName); @@ -218,66 +210,47 @@ void Foam::vtkPVFoam::convertVolField continue; } - vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData> - ( - output, arrayRangeFaceZones_, datasetNo - ); - - if (vtkmesh) - { - vtkFloatArray* cdata = convertFaceFieldToVTK + vtkSmartPointer<vtkFloatArray> cdata = + convertFaceFieldToVTK ( fld, zMesh[zoneId] ); - vtkmesh->GetCellData()->AddArray(cdata); - cdata->Delete(); - } + dataset->GetCellData()->AddArray(cdata); - // TODO: points + // TODO: point data } - // - // Convert face sets - if activated - // - for - ( - int partId = arrayRangeFaceSets_.start(); - partId < arrayRangeFaceSets_.end(); - ++partId - ) - { - const word selectName = getPartName(partId); - const label datasetNo = partDataset_[partId]; - if (!partStatus_[partId]) + // Face Sets + for (auto partId : rangeFaceSets_) + { + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; + const word selectName = getFoamName(longName); - vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData> - ( - output, arrayRangeFaceSets_, datasetNo - ); - - if (!vtkmesh) + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) { + // Should not happen, but for safety require a vtk geometry continue; } + foamVtpData& vtpData = iter.object(); + auto dataset = vtpData.dataset; - const faceSet fSet(mesh, selectName); - - vtkFloatArray* cdata = convertFaceFieldToVTK + vtkSmartPointer<vtkFloatArray> cdata = convertFaceFieldToVTK ( fld, - fSet.sortedToc() + vtpData.cellMap() ); - vtkmesh->GetCellData()->AddArray(cdata); - cdata->Delete(); + dataset->GetCellData()->AddArray(cdata); - // TODO: points + // TODO: point data } } @@ -287,31 +260,24 @@ void Foam::vtkPVFoam::convertVolFields ( const fvMesh& mesh, const PtrList<patchInterpolator>& patchInterpList, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objects ) { - forAllConstIter(IOobjectList, objects, iter) + typedef GeometricField<Type, fvPatchField, volMesh> FieldType; + + forAllConstIters(objects, iter) { - // restrict to GeometricField<Type, ...> - if - ( - iter()->headerClassName() - != GeometricField<Type, fvPatchField, volMesh>::typeName - ) - { - continue; - } + // Restrict to GeometricField<Type, ...> + const auto& ioobj = *(iter.object()); - // Load field - GeometricField<Type, fvPatchField, volMesh> fld - ( - *iter(), - mesh - ); + if (ioobj.headerClassName() == FieldType::typeName) + { + // Load field + FieldType fld(ioobj, mesh); - // Convert - convertVolField(patchInterpList, fld, output); + // Convert + convertVolField(patchInterpList, fld); + } } } @@ -321,26 +287,24 @@ void Foam::vtkPVFoam::convertDimFields ( const fvMesh& mesh, const PtrList<patchInterpolator>& patchInterpList, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objects ) { + typedef DimensionedField<Type, volMesh> FieldType; typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; - forAllConstIter(IOobjectList, objects, iter) + forAllConstIters(objects, iter) { - // restrict to DimensionedField<Type, ...> - if - ( - iter()->headerClassName() - != DimensionedField<Type, volMesh>::typeName - ) + // Restrict to DimensionedField<Type, ...> + const auto& ioobj = *(iter.object()); + + if (ioobj.headerClassName() != FieldType::typeName) { continue; } // Load field - DimensionedField<Type, volMesh> dimFld(*iter(), mesh); + FieldType dimFld(ioobj, mesh); // Construct volField with zero-gradient patch fields @@ -372,7 +336,7 @@ void Foam::vtkPVFoam::convertDimFields ); volFld.correctBoundaryConditions(); - convertVolField(patchInterpList, volFld, output); + convertVolField(patchInterpList, volFld); } } @@ -382,70 +346,70 @@ void Foam::vtkPVFoam::convertVolFieldBlock ( const GeometricField<Type, fvPatchField, volMesh>& fld, autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr, - vtkMultiBlockDataSet* output, - const arrayRange& range, - const List<polyDecomp>& decompLst + const arrayRange& range ) { - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const label datasetNo = partDataset_[partId]; - - if (!partStatus_[partId]) + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; - vtkUnstructuredGrid* vtkmesh = - getDataFromBlock<vtkUnstructuredGrid>(output, range, datasetNo); - - if (!vtkmesh) + auto iter = cachedVtu_.find(longName); + if (!iter.found() || !iter.object().dataset) { + // Should not happen, but for safety require a vtk geometry continue; } + foamVtuData& vtuData = iter.object(); + auto dataset = vtuData.dataset; - vtkFloatArray* cdata = convertVolFieldToVTK + vtkSmartPointer<vtkFloatArray> cdata = convertVolFieldToVTK ( fld, - decompLst[datasetNo] + vtuData ); - - vtkmesh->GetCellData()->AddArray(cdata); - cdata->Delete(); + dataset->GetCellData()->AddArray(cdata); if (ptfPtr.valid()) { - convertPointField(vtkmesh, ptfPtr(), fld, decompLst[datasetNo]); + vtkSmartPointer<vtkFloatArray> pdata = convertPointField + ( + ptfPtr(), + fld, + vtuData + ); + dataset->GetPointData()->AddArray(pdata); } } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + // // point-fields // - template<class Type> void Foam::vtkPVFoam::convertPointFields ( const pointMesh& pMesh, - const IOobjectList& objects, - vtkMultiBlockDataSet* output + const IOobjectList& objects ) { const polyMesh& mesh = pMesh.mesh(); - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - forAllConstIter(IOobjectList, objects, iter) + typedef GeometricField<Type, pointPatchField, pointMesh> FieldType; + + forAllConstIters(objects, iter) { - const word& fieldName = iter()->name(); - // restrict to this GeometricField<Type, ...> - if - ( - iter()->headerClassName() - != GeometricField<Type, pointPatchField, pointMesh>::typeName - ) + // Restrict to this GeometricField<Type, ...> + const auto& ioobj = *(iter.object()); + + const word& fieldName = ioobj.name(); + if (ioobj.headerClassName() != FieldType::typeName) { continue; } @@ -455,112 +419,88 @@ void Foam::vtkPVFoam::convertPointFields Info<< "convertPointFields : " << fieldName << endl; } - GeometricField<Type, pointPatchField, pointMesh> pfld(*iter(), pMesh); + FieldType pfld(ioobj, pMesh); + convertPointFieldBlock(pfld, rangeVolume_); // internalMesh + convertPointFieldBlock(pfld, rangeCellZones_); // cellZones + convertPointFieldBlock(pfld, rangeCellSets_); // cellSets - // Convert activated internalMesh regions - convertPointFieldBlock - ( - pfld, - output, - arrayRangeVolume_, - regionPolyDecomp_ - ); - - // Convert activated cellZones - convertPointFieldBlock - ( - pfld, - output, - arrayRangeCellZones_, - zonePolyDecomp_ - ); - - // Convert activated cellSets - convertPointFieldBlock - ( - pfld, - output, - arrayRangeCellSets_, - csetPolyDecomp_ - ); - - - // - // Convert patches - if activated - // - for - ( - int partId = arrayRangePatches_.start(); - partId < arrayRangePatches_.end(); - ++partId - ) + // Patches - currently skip field conversion for groups + for (auto partId : rangePatches_) { - const word patchName = getPartName(partId); - const label datasetNo = partDataset_[partId]; - const label patchId = patches.findPatchID(patchName); + if (!selectedPartIds_.found(partId)) + { + continue; + } + const auto& longName = selectedPartIds_[partId]; + + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) + { + // Should not happen, but for safety require a vtk geometry + continue; + } + foamVtpData& vtpData = iter.object(); + auto dataset = vtpData.dataset; - if (!partStatus_[partId] || patchId < 0) + const labelList& patchIds = vtpData.additionalIds(); + if (patchIds.size() != 1) { continue; } - vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData> + const label patchId = patchIds[0]; + + vtkSmartPointer<vtkFloatArray> pdata = convertFieldToVTK ( - output, arrayRangePatches_, datasetNo + fieldName, + pfld.boundaryField()[patchId].patchInternalField()() ); - if (vtkmesh) + dataset->GetPointData()->AddArray(pdata); + } + + // Face Zones + for (auto partId : rangeFaceZones_) + { + if (!selectedPartIds_.found(partId)) { - vtkFloatArray* pdata = convertFieldToVTK - ( - fieldName, - pfld.boundaryField()[patchId].patchInternalField()() - ); + continue; + } + const auto& longName = selectedPartIds_[partId]; + const word zoneName = getFoamName(longName); - vtkmesh->GetPointData()->AddArray(pdata); - pdata->Delete(); + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) + { + // Should not happen, but for safety require a vtk geometry + continue; } - } + foamVtpData& vtpData = iter.object(); + auto dataset = vtpData.dataset; - // - // Convert faceZones - if activated - // - for - ( - int partId = arrayRangeFaceZones_.start(); - partId < arrayRangeFaceZones_.end(); - ++partId - ) - { - const word zoneName = getPartName(partId); - const label datasetNo = partDataset_[partId]; const label zoneId = mesh.faceZones().findZoneID(zoneName); - if (!partStatus_[partId] || zoneId < 0) + if (zoneId < 0) { continue; } - vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData> + // Extract the field on the zone + Field<Type> znfld ( - output, arrayRangeFaceZones_, datasetNo + pfld.primitiveField(), + mesh.faceZones()[zoneId]().meshPoints() ); - if (vtkmesh) - { - // Extract the field on the zone - Field<Type> znfld + vtkSmartPointer<vtkFloatArray> pdata = + convertFieldToVTK ( - pfld.primitiveField(), - mesh.faceZones()[zoneId]().meshPoints() + fieldName, + znfld ); - vtkFloatArray* pdata = convertFieldToVTK(fieldName, znfld); - - vtkmesh->GetPointData()->AddArray(pdata); - pdata->Delete(); - } + dataset->GetPointData()->AddArray(pdata); } } } @@ -570,75 +510,67 @@ template<class Type> void Foam::vtkPVFoam::convertPointFieldBlock ( const GeometricField<Type, pointPatchField, pointMesh>& pfld, - vtkMultiBlockDataSet* output, - const arrayRange& range, - const List<polyDecomp>& decompLst + const arrayRange& range ) { - for (int partId = range.start(); partId < range.end(); ++partId) - { - const label datasetNo = partDataset_[partId]; - - if (!partStatus_[partId]) - { - continue; - } - - vtkUnstructuredGrid* vtkmesh = getDataFromBlock<vtkUnstructuredGrid> - ( - output, range, datasetNo - ); - - if (vtkmesh) - { - convertPointField - ( - vtkmesh, - pfld, - GeometricField<Type, fvPatchField, volMesh>::null(), - decompLst[datasetNo] - ); - } - } + for (auto partId : range) + { + if (!selectedPartIds_.found(partId)) + { + continue; + } + const auto& longName = selectedPartIds_[partId]; + + auto iter = cachedVtu_.find(longName); + if (!iter.found() || !iter.object().dataset) + { + // Should not happen, but for safety require a vtk geometry + continue; + } + foamVtuData& vtuData = iter.object(); + auto dataset = vtuData.dataset; + + vtkSmartPointer<vtkFloatArray> pdata = convertPointField + ( + pfld, + GeometricField<Type, fvPatchField, volMesh>::null(), + vtuData + ); + + dataset->GetPointData()->AddArray(pdata); + } } template<class Type> -void Foam::vtkPVFoam::convertPointField +vtkSmartPointer<vtkFloatArray> Foam::vtkPVFoam::convertPointField ( - vtkUnstructuredGrid* vtkmesh, const GeometricField<Type, pointPatchField, pointMesh>& pfld, const GeometricField<Type, fvPatchField, volMesh>& vfld, - const polyDecomp& decomp + const foamVtuData& vtuData ) { - if (!vtkmesh) - { - return; - } - - const label nComp = pTraits<Type>::nComponents; - const labelUList& addPointCellLabels = decomp.addPointCellLabels(); - const labelUList& pointMap = decomp.pointMap(); + const int nComp(pTraits<Type>::nComponents); + const labelUList& addPointCellLabels = vtuData.additionalIds(); + const labelUList& pointMap = vtuData.pointMap(); - // use a pointMap or address directly into mesh + // Use a pointMap or address directly into mesh const label nPoints = (pointMap.size() ? pointMap.size() : pfld.size()); - vtkFloatArray* fldData = vtkFloatArray::New(); - fldData->SetNumberOfTuples(nPoints + addPointCellLabels.size()); - fldData->SetNumberOfComponents(nComp); - fldData->Allocate(nComp*(nPoints + addPointCellLabels.size())); + auto data = vtkSmartPointer<vtkFloatArray>::New(); + data->SetNumberOfComponents(nComp); + data->SetNumberOfTuples(nPoints + addPointCellLabels.size()); // Note: using the name of the original volField // not the name generated by the interpolation "volPointInterpolate(<name>)" - if (&vfld != &GeometricField<Type, fvPatchField, volMesh>::null()) + if (notNull(vfld)) { - fldData->SetName(vfld.name().c_str()); + data->SetName(vfld.name().c_str()); } else { - fldData->SetName(pfld.name().c_str()); + data->SetName(pfld.name().c_str()); } if (debug) @@ -652,6 +584,7 @@ void Foam::vtkPVFoam::convertPointField float vec[nComp]; + label pointi = 0; if (pointMap.size()) { forAll(pointMap, i) @@ -663,7 +596,7 @@ void Foam::vtkPVFoam::convertPointField } foamPvFields::remapTuple<Type>(vec); - fldData->InsertTuple(i, vec); + data->SetTuple(pointi++, vec); } } else @@ -677,14 +610,13 @@ void Foam::vtkPVFoam::convertPointField } foamPvFields::remapTuple<Type>(vec); - fldData->InsertTuple(i, vec); + data->SetTuple(pointi++, vec); } } - // continue insertion from here - label i = nPoints; + // Continue with additional points - if (&vfld != &GeometricField<Type, fvPatchField, volMesh>::null()) + if (notNull(vfld)) { forAll(addPointCellLabels, apI) { @@ -695,7 +627,7 @@ void Foam::vtkPVFoam::convertPointField } foamPvFields::remapTuple<Type>(vec); - fldData->InsertTuple(i++, vec); + data->SetTuple(pointi++, vec); } } else @@ -709,12 +641,11 @@ void Foam::vtkPVFoam::convertPointField } foamPvFields::remapTuple<Type>(vec); - fldData->InsertTuple(i++, vec); + data->SetTuple(pointi++, vec); } } - vtkmesh->GetPointData()->AddArray(fldData); - fldData->Delete(); + return data; } @@ -727,28 +658,28 @@ template<class Type> void Foam::vtkPVFoam::convertLagrangianFields ( const IOobjectList& objects, - vtkMultiBlockDataSet* output, - const label datasetNo + vtkPolyData* vtkmesh ) { - const arrayRange& range = arrayRangeLagrangian_; - - forAllConstIter(IOobjectList, objects, iter) + forAllConstIters(objects, iter) { - // restrict to this IOField<Type> - if (iter()->headerClassName() == IOField<Type>::typeName) + // Restrict to IOField<Type> + const auto& ioobj = *(iter.object()); + + if (ioobj.headerClassName() == IOField<Type>::typeName) { - vtkPolyData* vtkmesh = - getDataFromBlock<vtkPolyData>(output, range, datasetNo); + IOField<Type> fld(ioobj); - if (vtkmesh) - { - IOField<Type> fld(*iter()); + vtkSmartPointer<vtkFloatArray> data = + convertFieldToVTK + ( + ioobj.name(), + fld + ); - vtkFloatArray* fldData = convertFieldToVTK(fld.name(), fld); - vtkmesh->GetPointData()->AddArray(fldData); - fldData->Delete(); - } + // Provide identical data as cell and as point data + vtkmesh->GetCellData()->AddArray(data); + vtkmesh->GetPointData()->AddArray(data); } } } @@ -760,87 +691,160 @@ void Foam::vtkPVFoam::convertLagrangianFields // template<class Type> -vtkFloatArray* Foam::vtkPVFoam::convertFieldToVTK +vtkSmartPointer<vtkFloatArray> +Foam::vtkPVFoam::zeroVTKField ( const word& name, - const Field<Type>& fld + const label size ) { - if (debug) + auto data = vtkSmartPointer<vtkFloatArray>::New(); + + data->SetName(name.c_str()); + data->SetNumberOfComponents(int(pTraits<Type>::nComponents)); + data->SetNumberOfTuples(size); + + data->Fill(0); + + return data; +} + + +template<class Type> +Foam::label Foam::vtkPVFoam::transcribeFloatData +( + vtkFloatArray* array, + const UList<Type>& input, + const label start +) +{ + const int nComp(pTraits<Type>::nComponents); + + if (array->GetNumberOfComponents() != nComp) { - Info<< "convert Field<" << pTraits<Type>::typeName << "> " - << name - << " size=" << fld.size() - << " nComp=" << label(pTraits<Type>::nComponents) << endl; + FatalErrorInFunction + << "vtk array '" << array->GetName() + << "' has mismatch in number of components for type '" + << pTraits<Type>::typeName + << "' : target array has " << array->GetNumberOfComponents() + << " components instead of " << nComp + << endl; } - const label nComp = pTraits<Type>::nComponents; + const vtkIdType maxSize = array->GetNumberOfTuples(); + const vtkIdType endPos = vtkIdType(start) + vtkIdType(input.size()); - vtkFloatArray* fldData = vtkFloatArray::New(); - fldData->SetNumberOfTuples(fld.size()); - fldData->SetNumberOfComponents(nComp); - fldData->Allocate(nComp*fld.size()); - fldData->SetName(name.c_str()); + if (start < 0 || vtkIdType(start) >= maxSize) + { + WarningInFunction + << "vtk array '" << array->GetName() + << "' copy with out-of-range (0-" << long(maxSize-1) << ")" + << " starting location" + << endl; - float vec[nComp]; - forAll(fld, i) + return 0; + } + else if (endPos > maxSize) + { + WarningInFunction + << "vtk array '" << array->GetName() + << "' copy ends out-of-range (" << long(maxSize) << ")" + << " using sizing (start,size) = (" + << start << "," << input.size() << ")" + << endl; + + return 0; + } + + float scratch[nComp]; + forAll(input, idx) { - const Type& t = fld[i]; + const Type& t = input[idx]; for (direction d=0; d<nComp; ++d) { - vec[d] = component(t, d); + scratch[d] = component(t, d); } - foamPvFields::remapTuple<Type>(vec); + foamPvFields::remapTuple<Type>(scratch); - fldData->InsertTuple(i, vec); + array->SetTuple(start+idx, scratch); } - return fldData; + return input.size(); } template<class Type> -vtkFloatArray* Foam::vtkPVFoam::convertFaceFieldToVTK +vtkSmartPointer<vtkFloatArray> +Foam::vtkPVFoam::convertFieldToVTK +( + const word& name, + const UList<Type>& fld +) const +{ + const int nComp(pTraits<Type>::nComponents); + + if (debug) + { + Info<< "convert UList<" << pTraits<Type>::typeName << "> " + << name + << " size=" << fld.size() + << " nComp=" << nComp << endl; + } + + auto data = vtkSmartPointer<vtkFloatArray>::New(); + + data->SetName(name.c_str()); + data->SetNumberOfComponents(nComp); + data->SetNumberOfTuples(fld.size()); + + transcribeFloatData(data, fld); + + return data; +} + + +template<class Type> +vtkSmartPointer<vtkFloatArray> +Foam::vtkPVFoam::convertFaceFieldToVTK ( const GeometricField<Type, fvPatchField, volMesh>& fld, const labelUList& faceLabels -) +) const { if (debug) { Info<< "convert face field: " << fld.name() << " size=" << faceLabels.size() - << " nComp=" << label(pTraits<Type>::nComponents) << endl; + << " nComp=" << int(pTraits<Type>::nComponents) << endl; } const fvMesh& mesh = fld.mesh(); - const label nComp = pTraits<Type>::nComponents; + const int nComp(pTraits<Type>::nComponents); const label nInternalFaces = mesh.nInternalFaces(); const labelList& faceOwner = mesh.faceOwner(); const labelList& faceNeigh = mesh.faceNeighbour(); - vtkFloatArray* fldData = vtkFloatArray::New(); - fldData->SetNumberOfTuples(faceLabels.size()); - fldData->SetNumberOfComponents(nComp); - fldData->Allocate(nComp*faceLabels.size()); - fldData->SetName(fld.name().c_str()); + auto data = vtkSmartPointer<vtkFloatArray>::New(); + data->SetName(fld.name().c_str()); + data->SetNumberOfComponents(nComp); + data->SetNumberOfTuples(faceLabels.size()); - float vec[nComp]; + float scratch[nComp]; - // for interior faces: average owner/neighbour - // for boundary faces: owner - forAll(faceLabels, facei) + // Interior faces: average owner/neighbour + // Boundary faces: the owner value + forAll(faceLabels, idx) { - const label faceNo = faceLabels[facei]; + const label faceNo = faceLabels[idx]; if (faceNo < nInternalFaces) { Type t = 0.5*(fld[faceOwner[faceNo]] + fld[faceNeigh[faceNo]]); for (direction d=0; d<nComp; ++d) { - vec[d] = component(t, d); + scratch[d] = component(t, d); } } else @@ -848,58 +852,58 @@ vtkFloatArray* Foam::vtkPVFoam::convertFaceFieldToVTK const Type& t = fld[faceOwner[faceNo]]; for (direction d=0; d<nComp; ++d) { - vec[d] = component(t, d); + scratch[d] = component(t, d); } } - foamPvFields::remapTuple<Type>(vec); + foamPvFields::remapTuple<Type>(scratch); - fldData->InsertTuple(facei, vec); + data->SetTuple(idx, scratch); } - return fldData; + return data; } template<class Type> -vtkFloatArray* Foam::vtkPVFoam::convertVolFieldToVTK +vtkSmartPointer<vtkFloatArray> +Foam::vtkPVFoam::convertVolFieldToVTK ( const GeometricField<Type, fvPatchField, volMesh>& fld, - const polyDecomp& decompInfo -) + const foamVtuData& vtuData +) const { - const label nComp = pTraits<Type>::nComponents; - const labelList& superCells = decompInfo.superCells(); + const int nComp(pTraits<Type>::nComponents); + const labelUList& cellMap = vtuData.cellMap(); - vtkFloatArray* fldData = vtkFloatArray::New(); - fldData->SetNumberOfTuples(superCells.size()); - fldData->SetNumberOfComponents(nComp); - fldData->Allocate(nComp*superCells.size()); - fldData->SetName(fld.name().c_str()); + auto data = vtkSmartPointer<vtkFloatArray>::New(); + data->SetName(fld.name().c_str()); + data->SetNumberOfComponents(nComp); + data->SetNumberOfTuples(cellMap.size()); if (debug) { Info<< "convert volField: " << fld.name() - << " size=" << superCells.size() + << " size=" << cellMap.size() << " (" << fld.size() << " + " - << (superCells.size() - fld.size()) + << (cellMap.size() - fld.size()) << ") nComp=" << nComp << endl; } - float vec[nComp]; - forAll(superCells, i) + float scratch[nComp]; + forAll(cellMap, idx) { - const Type& t = fld[superCells[i]]; + const Type& t = fld[cellMap[idx]]; for (direction d=0; d<nComp; ++d) { - vec[d] = component(t, d); + scratch[d] = component(t, d); } - foamPvFields::remapTuple<Type>(vec); + foamPvFields::remapTuple<Type>(scratch); - fldData->InsertTuple(i, vec); + data->SetTuple(idx, scratch); } - return fldData; + return data; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C index 880ca89a4fb310b08c879702b1d9c0ff47c298d5..9da212916f2e3ab1d1b0be919c5916f277155b16 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C @@ -40,32 +40,7 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::vtkPVFoam::pruneObjectList -( - IOobjectList& objects, - const hashedWordList& retain -) -{ - if (retain.empty()) - { - objects.clear(); - } - - // only retain specified fields - forAllIter(IOobjectList, objects, iter) - { - if (!retain.found(iter()->name())) - { - objects.erase(iter); - } - } -} - - -void Foam::vtkPVFoam::convertVolFields -( - vtkMultiBlockDataSet* output -) +void Foam::vtkPVFoam::convertVolFields() { const fvMesh& mesh = *meshPtr_; @@ -83,7 +58,7 @@ void Foam::vtkPVFoam::convertVolFields // Get objects (fields) for this time - only keep selected fields // the region name is already in the mesh db IOobjectList objects(mesh, dbPtr_().timeName()); - pruneObjectList(objects, selectedFields); + objects.filterKeys(selectedFields); if (objects.empty()) { @@ -92,8 +67,8 @@ void Foam::vtkPVFoam::convertVolFields if (debug) { - Info<< "<beg> convert volume fields" << endl; - forAllConstIter(IOobjectList, objects, iter) + Info<< "<beg> " << FUNCTION_NAME << endl; + forAllConstIters(objects, iter) { Info<< " " << iter()->name() << " == " << iter()->objectPath() << endl; @@ -121,30 +96,27 @@ void Foam::vtkPVFoam::convertVolFields } } - convertVolFields<scalar>(mesh, interpLst, objects, output); - convertVolFields<vector>(mesh, interpLst, objects, output); - convertVolFields<sphericalTensor>(mesh, interpLst, objects, output); - convertVolFields<symmTensor>(mesh, interpLst, objects, output); - convertVolFields<tensor>(mesh, interpLst, objects, output); + convertVolFields<scalar>(mesh, interpLst, objects); + convertVolFields<vector>(mesh, interpLst, objects); + convertVolFields<sphericalTensor>(mesh, interpLst, objects); + convertVolFields<symmTensor>(mesh, interpLst, objects); + convertVolFields<tensor>(mesh, interpLst, objects); - convertDimFields<scalar>(mesh, interpLst, objects, output); - convertDimFields<vector>(mesh, interpLst, objects, output); - convertDimFields<sphericalTensor>(mesh, interpLst, objects, output); - convertDimFields<symmTensor>(mesh, interpLst, objects, output); - convertDimFields<tensor>(mesh, interpLst, objects, output); + convertDimFields<scalar>(mesh, interpLst, objects); + convertDimFields<vector>(mesh, interpLst, objects); + convertDimFields<sphericalTensor>(mesh, interpLst, objects); + convertDimFields<symmTensor>(mesh, interpLst, objects); + convertDimFields<tensor>(mesh, interpLst, objects); if (debug) { - Info<< "<end> convert volume fields" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertPointFields -( - vtkMultiBlockDataSet* output -) +void Foam::vtkPVFoam::convertPointFields() { const fvMesh& mesh = *meshPtr_; @@ -165,7 +137,7 @@ void Foam::vtkPVFoam::convertPointFields // Get objects (fields) for this time - only keep selected fields // the region name is already in the mesh db IOobjectList objects(mesh, dbPtr_().timeName()); - pruneObjectList(objects, selectedFields); + objects.filterKeys(selectedFields); if (objects.empty()) { @@ -175,7 +147,7 @@ void Foam::vtkPVFoam::convertPointFields if (debug) { Info<< "<beg> convert volume -> point fields" << endl; - forAllConstIter(IOobjectList, objects, iter) + forAllConstIters(objects, iter) { Info<< " " << iter()->name() << " == " << iter()->objectPath() << endl; @@ -186,11 +158,11 @@ void Foam::vtkPVFoam::convertPointFields // Construct interpolation on the raw mesh const pointMesh& pMesh = pointMesh::New(mesh); - convertPointFields<scalar>(pMesh, objects, output); - convertPointFields<vector>(pMesh, objects, output); - convertPointFields<sphericalTensor>(pMesh, objects, output); - convertPointFields<symmTensor>(pMesh, objects, output); - convertPointFields<tensor>(pMesh, objects, output); + convertPointFields<scalar>(pMesh, objects); + convertPointFields<vector>(pMesh, objects); + convertPointFields<sphericalTensor>(pMesh, objects); + convertPointFields<symmTensor>(pMesh, objects); + convertPointFields<tensor>(pMesh, objects); if (debug) { @@ -200,12 +172,9 @@ void Foam::vtkPVFoam::convertPointFields } -void Foam::vtkPVFoam::convertLagrangianFields -( - vtkMultiBlockDataSet* output -) +void Foam::vtkPVFoam::convertLagrangianFields() { - arrayRange& range = arrayRangeLagrangian_; + const arrayRange& range = rangeLagrangian_; const fvMesh& mesh = *meshPtr_; hashedWordList selectedFields = getSelected @@ -220,19 +189,27 @@ void Foam::vtkPVFoam::convertLagrangianFields if (debug) { - Info<< "<beg> convert Lagrangian fields" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word cloudName = getPartName(partId); - const label datasetNo = partDataset_[partId]; + if (!selectedPartIds_.found(partId)) + { + continue; + } + + const auto& longName = selectedPartIds_[partId]; + const word cloudName = getFoamName(longName); - if (!partStatus_[partId] || datasetNo < 0) + auto iter = cachedVtp_.find(longName); + if (!iter.found() || !iter.object().dataset) { + // Should not happen, but for safety require a vtk geometry continue; } + auto dataset = iter.object().dataset; // Get the Lagrangian fields for this time and this cloud // but only keep selected fields @@ -243,7 +220,7 @@ void Foam::vtkPVFoam::convertLagrangianFields dbPtr_().timeName(), cloud::prefix/cloudName ); - pruneObjectList(objects, selectedFields); + objects.filterKeys(selectedFields); if (objects.empty()) { @@ -253,24 +230,24 @@ void Foam::vtkPVFoam::convertLagrangianFields if (debug) { Info<< "converting OpenFOAM lagrangian fields" << endl; - forAllConstIter(IOobjectList, objects, iter) + forAllConstIters(objects, iter) { Info<< " " << iter()->name() << " == " << iter()->objectPath() << endl; } } - convertLagrangianFields<label>(objects, output, datasetNo); - convertLagrangianFields<scalar>(objects, output, datasetNo); - convertLagrangianFields<vector>(objects, output, datasetNo); - convertLagrangianFields<sphericalTensor>(objects, output, datasetNo); - convertLagrangianFields<symmTensor>(objects, output, datasetNo); - convertLagrangianFields<tensor>(objects, output, datasetNo); + convertLagrangianFields<label>(objects, dataset); + convertLagrangianFields<scalar>(objects, dataset); + convertLagrangianFields<vector>(objects, dataset); + convertLagrangianFields<sphericalTensor>(objects, dataset); + convertLagrangianFields<symmTensor>(objects, dataset); + convertLagrangianFields<tensor>(objects, dataset); } if (debug) { - Info<< "<end> convert Lagrangian fields" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMesh.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMesh.C index 954866c540f4da18a5100a253d87dc73f97eb680..3ddd5d09569a9e533155a441273a2c48999b59b8 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMesh.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMesh.C @@ -38,230 +38,255 @@ License #include "vtkMultiBlockDataSet.h" #include "vtkPolyData.h" #include "vtkUnstructuredGrid.h" +#include "vtkSmartPointer.h" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::vtkPVFoam::convertMeshVolume -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshVolume() { - arrayRange& range = arrayRangeVolume_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeVolume_; const fvMesh& mesh = *meshPtr_; - // resize for decomposed polyhedra - regionPolyDecomp_.setSize(range.size()); - if (debug) { - Info<< "<beg> convertMeshVolume" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } // Convert the internalMesh // this looks like more than one part, but it isn't - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word partName = "internalMesh"; - - if (!partStatus_[partId]) + if (selectedPartIds_.found(partId)) { - continue; - } + const auto& longName = selectedPartIds_[partId]; + foamVtuData& vtuData = cachedVtu_(longName); - vtkUnstructuredGrid* vtkmesh = volumeVTKMesh - ( - mesh, - regionPolyDecomp_[datasetNo] - ); + vtkSmartPointer<vtkUnstructuredGrid> vtkgeom; + if (vtuData.nPoints()) + { + if (meshState_ == polyMesh::UNCHANGED) + { + if (debug) + { + Info<< "reuse " << longName << nl; + } + vtuData.reuse(); // reuse + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + if (debug) + { + Info<< "move points " << longName << nl; + } + vtkgeom = vtuData.getCopy(); + vtkgeom->SetPoints(movePoints(mesh, vtuData)); + } + } - if (vtkmesh) - { - addToBlock(output, vtkmesh, range, datasetNo, partName); - vtkmesh->Delete(); + if (!vtkgeom) + { + // Nothing usable from cache - create new geometry + vtkgeom = volumeVTKMesh(mesh, vtuData); + } - partDataset_[partId] = datasetNo++; + vtuData.set(vtkgeom); } } - // anything added? - if (datasetNo) - { - ++blockNo; - } - if (debug) { - Info<< "<end> convertMeshVolume" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshLagrangian -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshLagrangian() { - arrayRange& range = arrayRangeLagrangian_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeLagrangian_; const fvMesh& mesh = *meshPtr_; if (debug) { - Info<< "<beg> convertMeshLagrangian" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word cloudName = getPartName(partId); - - if (!partStatus_[partId]) - { - continue; - } - - vtkPolyData* vtkmesh = lagrangianVTKMesh(mesh, cloudName); - - if (vtkmesh) + if (selectedPartIds_.found(partId)) { - addToBlock(output, vtkmesh, range, datasetNo, cloudName); - vtkmesh->Delete(); + const auto& longName = selectedPartIds_[partId]; + const word cloudName = getFoamName(longName); - partDataset_[partId] = datasetNo++; + // Direct conversion, no caching for Lagrangian + cachedVtp_(longName).set + ( + lagrangianVTKMesh(mesh, cloudName) + ); } } - // anything added? - if (datasetNo) - { - ++blockNo; - } - if (debug) { - Info<< "<end> convertMeshLagrangian" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshPatches -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshPatches() { - arrayRange& range = arrayRangePatches_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangePatches_; const fvMesh& mesh = *meshPtr_; const polyBoundaryMesh& patches = mesh.boundaryMesh(); if (debug) { - Info<< "<beg> convertMeshPatches" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - if (!partStatus_[partId]) + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; + const word partName = getFoamName(longName); + foamVtpData& vtpData = cachedVtp_(longName); - const word patchName = getPartName(partId); - - labelHashSet - patchIds(patches.patchSet(List<wordRe>(1, wordRe(patchName)))); - - if (debug) + vtkSmartPointer<vtkPolyData> vtkgeom; + if (vtpData.nPoints()) { - Info<< "Creating VTK mesh for patches [" << patchIds <<"] " - << patchName << endl; - } + if (meshState_ == polyMesh::UNCHANGED) + { + // Without movement is easy. + if (debug) + { + Info<< "reuse " << longName << nl; + } + vtpData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + // Point movement on single patch is OK - vtkPolyData* vtkmesh = nullptr; - if (patchIds.size() == 1) - { - vtkmesh = patchVTKMesh(patchName, patches[patchIds.begin().key()]); + const labelList& patchIds = vtpData.additionalIds(); + if (patchIds.size() == 1) + { + vtkgeom = vtpData.getCopy(); + vtkgeom->SetPoints(movePatchPoints(patches[patchIds[0]])); + continue; + } + } } - else + + if (longName.startsWith("group/")) { // Patch group. Collect patch faces. + + vtpData.clear(); // Remove any old mappings + + const labelList& patchIds = + patches.groupPatchIDs().lookup(partName, labelList()); + + if (debug) + { + Info<< "Creating VTK mesh for patches [" << patchIds <<"] " + << longName << endl; + } + + // Store good patch ids as additionalIds + vtpData.additionalIds().reserve(patchIds.size()); + label sz = 0; - forAllConstIter(labelHashSet, patchIds, iter) + for (auto id : patchIds) { - sz += patches[iter.key()].size(); + const label n = patches[id].size(); + + if (n) + { + vtpData.additionalIds().append(id); + sz += n; + } } - labelList faceLabels(sz); - sz = 0; - forAllConstIter(labelHashSet, patchIds, iter) + Foam::sort(vtpData.additionalIds()); + + // Temporarily (mis)use cellMap for face labels + DynamicList<label>& faceLabels = vtpData.cellMap(); + faceLabels.reserve(sz); + + for (auto id : vtpData.additionalIds()) { - const polyPatch& pp = patches[iter.key()]; + const auto& pp = patches[id]; forAll(pp, i) { - faceLabels[sz++] = pp.start()+i; + faceLabels.append(pp.start()+i); } } - uindirectPrimitivePatch pp - ( - UIndirectList<face> + if (faceLabels.size()) + { + uindirectPrimitivePatch pp ( - mesh.faces(), - faceLabels - ), - mesh.points() - ); + UIndirectList<face>(mesh.faces(), faceLabels), + mesh.points() + ); - vtkmesh = patchVTKMesh(patchName, pp); - } + vtkgeom = patchVTKMesh(pp); + } - if (vtkmesh) + faceLabels.clear(); // Unneeded + } + else { - addToBlock(output, vtkmesh, range, datasetNo, patchName); - vtkmesh->Delete(); + vtpData.clear(); // Remove any old mappings + + const label patchId = patches.findPatchID(partName); - partDataset_[partId] = datasetNo++; + if (debug) + { + Info<< "Creating VTK mesh for patch [" << patchId <<"] " + << partName << endl; + } + + if (patchId >= 0) + { + // Store good patch id as additionalIds + vtpData.additionalIds() = {patchId}; + + vtkgeom = patchVTKMesh(patches[patchId]); + } } - } - // anything added? - if (datasetNo) - { - ++blockNo; + if (vtkgeom) + { + vtpData.set(vtkgeom); + } + else + { + cachedVtp_.erase(longName); + } } if (debug) { - Info<< "<end> convertMeshPatches" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshCellZones -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshCellZones() { - arrayRange& range = arrayRangeCellZones_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeCellZones_; const fvMesh& mesh = *meshPtr_; - // resize for decomposed polyhedra - zonePolyDecomp_.setSize(range.size()); - if (range.empty()) { return; @@ -269,17 +294,23 @@ void Foam::vtkPVFoam::convertMeshCellZones if (debug) { - Info<< "<beg> convertMeshCellZones" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } const cellZoneMesh& zMesh = mesh.cellZones(); - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word zoneName = getPartName(partId); + if (!selectedPartIds_.found(partId)) + { + continue; + } + + const auto& longName = selectedPartIds_[partId]; + const word zoneName = getFoamName(longName); const label zoneId = zMesh.findZoneID(zoneName); - if (!partStatus_[partId] || zoneId < 0) + if (zoneId < 0) { continue; } @@ -290,144 +321,129 @@ void Foam::vtkPVFoam::convertMeshCellZones << zoneName << endl; } - fvMeshSubset subsetter(mesh); - subsetter.setLargeCellSubset(zMesh[zoneId]); - - vtkUnstructuredGrid* vtkmesh = volumeVTKMesh - ( - subsetter.subMesh(), - zonePolyDecomp_[datasetNo] - ); + foamVtuData& vtuData = cachedVtu_(longName); - if (vtkmesh) + vtkSmartPointer<vtkUnstructuredGrid> vtkgeom; + if (vtuData.nPoints() && vtuData.pointMap().size()) { - // superCells + addPointCellLabels must contain global cell ids - inplaceRenumber - ( - subsetter.cellMap(), - zonePolyDecomp_[datasetNo].superCells() - ); - inplaceRenumber - ( - subsetter.cellMap(), - zonePolyDecomp_[datasetNo].addPointCellLabels() - ); - - // copy pointMap as well, otherwise pointFields fail - zonePolyDecomp_[datasetNo].pointMap() = subsetter.pointMap(); + if (meshState_ == polyMesh::UNCHANGED) + { + if (debug) + { + Info<< "reuse " << longName << nl; + } + vtuData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + if (debug) + { + Info<< "move points " << longName << nl; + } + vtkgeom = vtuData.getCopy(); + vtkgeom->SetPoints + ( + movePoints(mesh, vtuData, vtuData.pointMap()) + ); + } + } - addToBlock(output, vtkmesh, range, datasetNo, zoneName); - vtkmesh->Delete(); + if (!vtkgeom) + { + fvMeshSubset subsetter(mesh); + subsetter.setLargeCellSubset(zMesh[zoneId]); - partDataset_[partId] = datasetNo++; + vtkgeom = volumeVTKSubsetMesh(subsetter, vtuData); } - } - // anything added? - if (datasetNo) - { - ++blockNo; + vtuData.set(vtkgeom); } if (debug) { - Info<< "<end> convertMeshCellZones" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshCellSets -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshCellSets() { - arrayRange& range = arrayRangeCellSets_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeCellSets_; const fvMesh& mesh = *meshPtr_; - // resize for decomposed polyhedra - csetPolyDecomp_.setSize(range.size()); - if (debug) { - Info<< "<beg> convertMeshCellSets" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word partName = getPartName(partId); - - if (!partStatus_[partId]) + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; + const word partName = getFoamName(longName); + if (debug) { Info<< "Creating VTK mesh for cellSet=" << partName << endl; } - const cellSet cSet(mesh, partName); - fvMeshSubset subsetter(mesh); - subsetter.setLargeCellSubset(cSet); + foamVtuData& vtuData = cachedVtu_(longName); - vtkUnstructuredGrid* vtkmesh = volumeVTKMesh - ( - subsetter.subMesh(), - csetPolyDecomp_[datasetNo] - ); - - if (vtkmesh) + vtkSmartPointer<vtkUnstructuredGrid> vtkgeom; + if (vtuData.nPoints() && vtuData.pointMap().size()) { - // superCells + addPointCellLabels must contain global cell ids - inplaceRenumber - ( - subsetter.cellMap(), - csetPolyDecomp_[datasetNo].superCells() - ); - inplaceRenumber - ( - subsetter.cellMap(), - csetPolyDecomp_[datasetNo].addPointCellLabels() - ); - - // copy pointMap as well, otherwise pointFields fail - csetPolyDecomp_[datasetNo].pointMap() = subsetter.pointMap(); + if (meshState_ == polyMesh::UNCHANGED) + { + if (debug) + { + Info<< "reuse " << longName << nl; + } + vtuData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + if (debug) + { + Info<< "move points " << longName << nl; + } + vtkgeom = vtuData.getCopy(); + vtkgeom->SetPoints + ( + movePoints(mesh, vtuData, vtuData.pointMap()) + ); + } + } - addToBlock(output, vtkmesh, range, datasetNo, partName); - vtkmesh->Delete(); + if (!vtkgeom) + { + fvMeshSubset subsetter(mesh); + subsetter.setLargeCellSubset(cellSet(mesh, partName)); - partDataset_[partId] = datasetNo++; + vtkgeom = volumeVTKSubsetMesh(subsetter, vtuData); } - } - // anything added? - if (datasetNo) - { - ++blockNo; + vtuData.set(vtkgeom); } if (debug) { - Info<< "<end> convertMeshCellSets" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshFaceZones -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshFaceZones() { - arrayRange& range = arrayRangeFaceZones_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeFaceZones_; const fvMesh& mesh = *meshPtr_; if (range.empty()) @@ -437,257 +453,311 @@ void Foam::vtkPVFoam::convertMeshFaceZones if (debug) { - Info<< "<beg> convertMeshFaceZones" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } const faceZoneMesh& zMesh = mesh.faceZones(); - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word zoneName = getPartName(partId); + if (!selectedPartIds_.found(partId)) + { + continue; + } + + const auto& longName = selectedPartIds_[partId]; + const word zoneName = getFoamName(longName); const label zoneId = zMesh.findZoneID(zoneName); - if (!partStatus_[partId] || zoneId < 0) + if (zoneId < 0) { continue; } - if (debug) { Info<< "Creating VTKmesh for faceZone[" << zoneId << "] " << zoneName << endl; } - vtkPolyData* vtkmesh = patchVTKMesh(zoneName, zMesh[zoneId]()); + foamVtpData& vtpData = cachedVtp_(longName); - if (vtkmesh) + vtkSmartPointer<vtkPolyData> vtkgeom; + if (vtpData.nPoints()) { - addToBlock(output, vtkmesh, range, datasetNo, zoneName); - vtkmesh->Delete(); + if (meshState_ == polyMesh::UNCHANGED) + { + // Without movement is easy. + if (debug) + { + Info<<"reuse " << longName << nl; + } + vtpData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + // Need point maps etc - not worth it at the moment + } + } - partDataset_[partId] = datasetNo++; + if (!vtkgeom) + { + vtpData.clear(); // No additional ids, maps + + const primitiveFacePatch& pp = zMesh[zoneId](); + vtkgeom = patchVTKMesh(pp); } - } - // anything added? - if (datasetNo) - { - ++blockNo; + vtpData.set(vtkgeom); } if (debug) { - Info<< "<end> convertMeshFaceZones" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshFaceSets -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshFaceSets() { - arrayRange& range = arrayRangeFaceSets_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangeFaceSets_; const fvMesh& mesh = *meshPtr_; if (debug) { - Info<< "<beg> convertMeshFaceSets" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - const word partName = getPartName(partId); - - if (!partStatus_[partId]) + if (!selectedPartIds_.found(partId)) { continue; } + const auto& longName = selectedPartIds_[partId]; + const word partName = getFoamName(longName); + if (debug) { Info<< "Creating VTK mesh for faceSet=" << partName << endl; } - // faces in sorted order for more reliability - uindirectPrimitivePatch p - ( - UIndirectList<face> - ( - mesh.faces(), - faceSet(mesh, partName).sortedToc() - ), - mesh.points() - ); + foamVtpData& vtpData = cachedVtp_(longName); - if (p.empty()) + vtkSmartPointer<vtkPolyData> vtkgeom; + if (vtpData.nPoints()) { - continue; + if (meshState_ == polyMesh::UNCHANGED) + { + // Without movement is easy. + if (debug) + { + Info<<"reuse " << longName << nl; + } + vtpData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + // Need point maps etc - not worth it at the moment + } } - vtkPolyData* vtkmesh = patchVTKMesh("faceSet:" + partName, p); - if (vtkmesh) + if (!vtkgeom) { - addToBlock(output, vtkmesh, range, datasetNo, partName); - vtkmesh->Delete(); + vtpData.clear(); // No other additional ids, maps - partDataset_[partId] = datasetNo++; + // Misuse cellMap for face labels - sorted order for reliability + vtpData.cellMap() = faceSet(mesh, partName).sortedToc(); + + if (vtpData.cellMap().size()) + { + uindirectPrimitivePatch pp + ( + UIndirectList<face>(mesh.faces(), vtpData.cellMap()), + mesh.points() + ); + + vtkgeom = patchVTKMesh(pp); + } } - } - // anything added? - if (datasetNo) - { - ++blockNo; + if (vtkgeom) + { + vtpData.set(vtkgeom); + } + else + { + cachedVtp_.erase(longName); + } } if (debug) { - Info<< "<end> convertMeshFaceSets" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } -void Foam::vtkPVFoam::convertMeshPointZones -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshPointZones() { - arrayRange& range = arrayRangePointZones_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangePointZones_; const fvMesh& mesh = *meshPtr_; if (debug) { - Info<< "<beg> convertMeshPointZones" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } if (range.size()) { const pointZoneMesh& zMesh = mesh.pointZones(); - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - word zoneName = getPartName(partId); - label zoneId = zMesh.findZoneID(zoneName); + if (!selectedPartIds_.found(partId)) + { + continue; + } + + const auto& longName = selectedPartIds_[partId]; + const word zoneName = getFoamName(longName); + const label zoneId = zMesh.findZoneID(zoneName); - if (!partStatus_[partId] || zoneId < 0) + if (zoneId < 0) { continue; } - const labelUList& pointLabels = zMesh[zoneId]; + foamVtpData& vtpData = cachedVtp_(longName); - vtkPoints* vtkpoints = vtkPoints::New(); - vtkpoints->Allocate(pointLabels.size()); + vtkSmartPointer<vtkPolyData> vtkgeom; + if (vtpData.nPoints() && vtpData.pointMap().size()) + { + if (meshState_ == polyMesh::UNCHANGED) + { + if (debug) + { + Info<< "reusing " << longName << nl; + } + vtpData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + if (debug) + { + Info<< "move points " << longName << nl; + } + vtkgeom = vtpData.getCopy(); + } + } - const pointField& meshPoints = mesh.points(); - forAll(pointLabels, pointi) + if (!vtkgeom) { - vtkpoints->InsertNextPoint(meshPoints[pointLabels[pointi]].v_); + // First time, or topo change + vtkgeom = vtkSmartPointer<vtkPolyData>::New(); + vtpData.pointMap() = zMesh[zoneId]; } - vtkPolyData* vtkmesh = vtkPolyData::New(); - vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); + const pointField& points = mesh.points(); + const labelUList& pointMap = vtpData.pointMap(); - if (vtkmesh) - { - addToBlock(output, vtkmesh, range, datasetNo, zoneName); - vtkmesh->Delete(); + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); - partDataset_[partId] = datasetNo++; + vtkpoints->SetNumberOfPoints(pointMap.size()); + forAll(pointMap, pointi) + { + vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_); } - } - } - // anything added? - if (datasetNo) - { - ++blockNo; + vtkgeom->SetPoints(vtkpoints); + vtpData.set(vtkgeom); + } } if (debug) { - Info<< "<end> convertMeshPointZones" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } - -void Foam::vtkPVFoam::convertMeshPointSets -( - vtkMultiBlockDataSet* output, - int& blockNo -) +void Foam::vtkPVFoam::convertMeshPointSets() { - arrayRange& range = arrayRangePointSets_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 + const arrayRange& range = rangePointSets_; const fvMesh& mesh = *meshPtr_; if (debug) { - Info<< "<beg> convertMeshPointSets" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; printMemory(); } - for (int partId = range.start(); partId < range.end(); ++partId) + for (auto partId : range) { - word partName = getPartName(partId); - - if (!partStatus_[partId]) + if (!selectedPartIds_.found(partId)) { continue; } - if (debug) - { - Info<< "Creating VTK mesh for pointSet=" << partName << endl; - } + const auto& longName = selectedPartIds_[partId]; + const word partName = getFoamName(longName); - const pointSet pSet(mesh, partName); + foamVtpData& vtpData = cachedVtp_(longName); - vtkPoints* vtkpoints = vtkPoints::New(); - vtkpoints->Allocate(pSet.size()); + vtkSmartPointer<vtkPolyData> vtkgeom; + if (vtpData.nPoints() && vtpData.pointMap().size()) + { + if (meshState_ == polyMesh::UNCHANGED) + { + if (debug) + { + Info<< "reusing " << longName << nl; + } + vtpData.reuse(); + continue; + } + else if (meshState_ == polyMesh::POINTS_MOVED) + { + if (debug) + { + Info<< "move points " << longName << nl; + } + vtkgeom = vtpData.getCopy(); + } + } - const pointField& meshPoints = mesh.points(); - forAllConstIter(pointSet, pSet, iter) + if (!vtkgeom) { - vtkpoints->InsertNextPoint(meshPoints[iter.key()].v_); + // First time, or topo change + vtkgeom = vtkSmartPointer<vtkPolyData>::New(); + vtpData.pointMap() = pointSet(mesh, partName).sortedToc(); } - vtkPolyData* vtkmesh = vtkPolyData::New(); - vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); + const pointField& points = mesh.points(); + const labelUList& pointMap = vtpData.pointMap(); - if (vtkmesh) - { - addToBlock(output, vtkmesh, range, datasetNo, partName); - vtkmesh->Delete(); + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); - partDataset_[partId] = datasetNo++; + vtkpoints->SetNumberOfPoints(pointMap.size()); + forAll(pointMap, pointi) + { + vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_); } - } - // anything added? - if (datasetNo) - { - ++blockNo; + vtkgeom->SetPoints(vtkpoints); + vtpData.set(vtkgeom); } if (debug) { - Info<< "<end> convertMeshPointSets" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshLagrangian.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshLagrangian.C index 4527d841c56dac7b91639698e968d4527478eeaf..c08e17559c5355fb432600bdbba21d04abdffc1c 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshLagrangian.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshLagrangian.C @@ -35,16 +35,17 @@ License #include "vtkCellArray.h" #include "vtkPoints.h" #include "vtkPolyData.h" +#include "vtkSmartPointer.h" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -vtkPolyData* Foam::vtkPVFoam::lagrangianVTKMesh +vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh ( const polyMesh& mesh, const word& cloudName -) +) const { - vtkPolyData* vtkmesh = nullptr; + vtkSmartPointer<vtkPolyData> vtkmesh; if (debug) { @@ -72,27 +73,19 @@ vtkPolyData* Foam::vtkPVFoam::lagrangianVTKMesh Info<< "cloud with " << parcels.size() << " parcels" << endl; } - vtkmesh = vtkPolyData::New(); - vtkPoints* vtkpoints = vtkPoints::New(); - vtkCellArray* vtkcells = vtkCellArray::New(); - - vtkpoints->Allocate(parcels.size()); - vtkcells->Allocate(parcels.size()); + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); + vtkpoints->SetNumberOfPoints(parcels.size()); vtkIdType particleId = 0; - forAllConstIter(Cloud<passiveParticle>, parcels, iter) + forAllConstIters(parcels, iter) { - vtkpoints->InsertNextPoint(iter().position().v_); - - vtkcells->InsertNextCell(1, &particleId); - particleId++; + vtkpoints->SetPoint(particleId, iter().position().v_); + ++particleId; } + vtkmesh = vtkSmartPointer<vtkPolyData>::New(); vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); - - vtkmesh->SetVerts(vtkcells); - vtkcells->Delete(); + vtkmesh->SetVerts(foamPvCore::identityVertices(parcels.size())); } if (debug) diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshVolume.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshVolume.C index 6321e3cdfafa4355be5378d4d16bd423192f1a33..18beae4583e23308ffccc604ece0a8a66191f0d5 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshVolume.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamMeshVolume.C @@ -28,397 +28,188 @@ License // OpenFOAM includes #include "fvMesh.H" -#include "cellModeller.H" +#include "fvMeshSubset.H" +#include "foamVtkAdaptors.H" +#include "foamVtuSizing.H" // VTK includes -#include "vtkCellArray.h" -#include "vtkIdTypeArray.h" #include "vtkUnstructuredGrid.h" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -vtkUnstructuredGrid* Foam::vtkPVFoam::volumeVTKMesh +vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePoints ( const fvMesh& mesh, - polyDecomp& decompInfo + const foamVtuData& vtuData ) { - const cellModel& tet = *(cellModeller::lookup("tet")); - const cellModel& pyr = *(cellModeller::lookup("pyr")); - const cellModel& prism = *(cellModeller::lookup("prism")); - const cellModel& wedge = *(cellModeller::lookup("wedge")); - const cellModel& tetWedge = *(cellModeller::lookup("tetWedge")); - const cellModel& hex = *(cellModeller::lookup("hex")); + // Convert OpenFOAM mesh vertices to VTK + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); - vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New(); + // Normal points + const pointField& points = mesh.points(); - if (debug) + // Additional cell centres + const labelList& addPoints = vtuData.additionalIds(); + + vtkpoints->SetNumberOfPoints(points.size() + addPoints.size()); + + // Normal points + label pointi = 0; + forAll(points, i) { - Info<< "<beg> volumeVTKMesh" << endl; - printMemory(); + vtkpoints->SetPoint(pointi++, points[i].v_); + } + + // Cell centres + forAll(addPoints, i) + { + vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_); } - const cellShapeList& cellShapes = mesh.cellShapes(); + return vtkpoints; +} + - // Number of additional points needed by the decomposition of polyhedra - label nAddPoints = 0; +vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePoints +( + const fvMesh& mesh, + const foamVtuData& vtuData, + const labelUList& pointMap +) +{ + // Convert OpenFOAM mesh vertices to VTK + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); - // Number of additional cells generated by the decomposition of polyhedra - label nAddCells = 0; + // Normal points + const pointField& points = mesh.points(); - // face owner is needed to determine the face orientation - const labelList& owner = mesh.faceOwner(); + // Additional cell centres + const labelList& addPoints = vtuData.additionalIds(); - labelList& superCells = decompInfo.superCells(); - labelList& addPointCellLabels = decompInfo.addPointCellLabels(); + vtkpoints->SetNumberOfPoints(pointMap.size() + addPoints.size()); - // Scan for cells which need to be decomposed and count additional points - // and cells - if (!reader_->GetUseVTKPolyhedron()) + // Normal points + label pointi = 0; + forAll(pointMap, i) { - forAll(cellShapes, celli) - { - const cellModel& model = cellShapes[celli].model(); - - if - ( - model != hex - && model != wedge - && model != prism - && model != pyr - && model != tet - && model != tetWedge - ) - { - const cell& cFaces = mesh.cells()[celli]; - - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - - label nQuads = 0; - label nTris = 0; - f.nTrianglesQuads(mesh.points(), nTris, nQuads); - - nAddCells += nQuads + nTris; - } - - nAddCells--; - nAddPoints++; - } - } + vtkpoints->SetPoint(pointi++, points[pointMap[i]].v_); } - // Set size of additional point addressing array - // (from added point to original cell) - addPointCellLabels.setSize(nAddPoints); - - // Set size of additional cells mapping array - // (from added cell to original cell) - - superCells.setSize(mesh.nCells() + nAddCells); + // Cell centres + forAll(addPoints, i) + { + vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_); + } - // Convert OpenFOAM mesh vertices to VTK - vtkPoints* vtkpoints = vtkPoints::New(); - vtkpoints->Allocate(mesh.nPoints() + nAddPoints); + return vtkpoints; +} - const Foam::pointField& points = mesh.points(); - forAll(points, i) +vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh +( + const fvMesh& mesh, + foamVtuData& vtuData, + const bool decompPoly +) +{ + if (debug) { - vtkpoints->InsertNextPoint(points[i].v_); + Info<< "<beg> " << FUNCTION_NAME << endl; + printMemory(); } - vtkmesh->Allocate(mesh.nCells() + nAddCells); - - // Set counters for additional points and additional cells - label addPointi = 0, addCelli = 0; + vtk::vtuSizing sizing(mesh, decompPoly); + + auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New(); + + auto cells = vtkSmartPointer<vtkCellArray>::New(); + auto faces = vtkSmartPointer<vtkIdTypeArray>::New(); + + auto cellLocations = vtkSmartPointer<vtkIdTypeArray>::New(); + auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New(); + + UList<uint8_t> cellTypesUL = + vtkUList + ( + cellTypes, + sizing.nFieldCells() + ); + + UList<vtkIdType> cellsUL = + vtkUList + ( + cells, + sizing.nFieldCells(), + sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS) + ); + + UList<vtkIdType> cellLocationsUL = + vtkUList + ( + cellLocations, + sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS_OFFSETS) + ); + + UList<vtkIdType> facesUL = + vtkUList + ( + faces, + sizing.sizeInternal(vtk::vtuSizing::slotType::FACES) + ); + + UList<vtkIdType> faceLocationsUL = + vtkUList + ( + faceLocations, + sizing.sizeInternal(vtk::vtuSizing::slotType::FACES_OFFSETS) + ); + + + sizing.populateInternal + ( + mesh, + cellTypesUL, + cellsUL, + cellLocationsUL, + facesUL, + faceLocationsUL, + static_cast<foamVtkMeshMaps&>(vtuData) + ); + + auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New(); - // Create storage for points - needed for mapping from OpenFOAM to VTK - // data types - max 'order' = hex = 8 points - vtkIdType nodeIds[8]; - - // face-stream for a polyhedral cell - // [numFace0Pts, id1, id2, id3, numFace1Pts, id1, id2, id3, ...] - DynamicList<vtkIdType> faceStream(256); + // Convert OpenFOAM mesh vertices to VTK + // - can only do this *after* populating the decompInfo with cell-ids + // for any additional points (ie, mesh cell-centres) + vtkmesh->SetPoints(movePoints(mesh, vtuData)); - forAll(cellShapes, celli) + if (facesUL.size()) { - const cellShape& cellShape = cellShapes[celli]; - const cellModel& cellModel = cellShape.model(); - - superCells[addCelli++] = celli; - - if (cellModel == tet) - { - for (int j = 0; j < 4; j++) - { - nodeIds[j] = cellShape[j]; - } - vtkmesh->InsertNextCell - ( - VTK_TETRA, - 4, - nodeIds - ); - } - else if (cellModel == pyr) - { - for (int j = 0; j < 5; j++) - { - nodeIds[j] = cellShape[j]; - } - vtkmesh->InsertNextCell - ( - VTK_PYRAMID, - 5, - nodeIds - ); - } - else if (cellModel == prism) - { - // VTK has a different node order for VTK_WEDGE - // their triangles point outwards! - nodeIds[0] = cellShape[0]; - nodeIds[1] = cellShape[2]; - nodeIds[2] = cellShape[1]; - nodeIds[3] = cellShape[3]; - nodeIds[4] = cellShape[5]; - nodeIds[5] = cellShape[4]; - - vtkmesh->InsertNextCell - ( - VTK_WEDGE, - 6, - nodeIds - ); - } - else if (cellModel == tetWedge && !reader_->GetUseVTKPolyhedron()) - { - // Treat as squeezed prism (VTK_WEDGE) - - nodeIds[0] = cellShape[0]; - nodeIds[1] = cellShape[2]; - nodeIds[2] = cellShape[1]; - nodeIds[3] = cellShape[3]; - nodeIds[4] = cellShape[4]; - nodeIds[5] = cellShape[3]; - - vtkmesh->InsertNextCell - ( - VTK_WEDGE, - 6, - nodeIds - ); - } - else if (cellModel == wedge) - { - // Treat as squeezed hex - - nodeIds[0] = cellShape[0]; - nodeIds[1] = cellShape[1]; - nodeIds[2] = cellShape[2]; - nodeIds[3] = cellShape[2]; - nodeIds[4] = cellShape[3]; - nodeIds[5] = cellShape[4]; - nodeIds[6] = cellShape[5]; - nodeIds[7] = cellShape[6]; - - vtkmesh->InsertNextCell - ( - VTK_HEXAHEDRON, - 8, - nodeIds - ); - } - else if (cellModel == hex) - { - for (int j = 0; j < 8; j++) - { - nodeIds[j] = cellShape[j]; - } - vtkmesh->InsertNextCell - ( - VTK_HEXAHEDRON, - 8, - nodeIds - ); - } - else if (reader_->GetUseVTKPolyhedron()) - { - // Polyhedral cell - use VTK_POLYHEDRON - const labelList& cFaces = mesh.cells()[celli]; - - vtkIdType nFaces = cFaces.size(); - vtkIdType nLabels = nFaces; - - // count size for face stream - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - nLabels += f.size(); - } - - // build face-stream - // [numFace0Pts, id1, id2, id3, numFace1Pts, id1, id2, id3, ...] - // point Ids are global - faceStream.clear(); - faceStream.reserve(nLabels + nFaces); - - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - const bool isOwner = (owner[cFaces[cFacei]] == celli); - const label nFacePoints = f.size(); - - // number of labels for this face - faceStream.append(nFacePoints); - - if (isOwner) - { - forAll(f, fp) - { - faceStream.append(f[fp]); - } - } - else - { - // fairly immaterial if we reverse the list - // or use face::reverseFace() - forAllReverse(f, fp) - { - faceStream.append(f[fp]); - } - } - } - - vtkmesh->InsertNextCell(VTK_POLYHEDRON, nFaces, faceStream.data()); - } - else - { - // Polyhedral cell. Decompose into tets + prisms. - - // Mapping from additional point to cell - addPointCellLabels[addPointi] = celli; - - // The new vertex from the cell-centre - const label newVertexLabel = mesh.nPoints() + addPointi; - vtkpoints->InsertNextPoint(mesh.C()[celli].v_); - - // Whether to insert cell in place of original or not. - bool substituteCell = true; - - const labelList& cFaces = mesh.cells()[celli]; - forAll(cFaces, cFacei) - { - const face& f = mesh.faces()[cFaces[cFacei]]; - const bool isOwner = (owner[cFaces[cFacei]] == celli); - - // Number of triangles and quads in decomposition - label nTris = 0; - label nQuads = 0; - f.nTrianglesQuads(mesh.points(), nTris, nQuads); - - // Do actual decomposition into triFcs and quadFcs. - faceList triFcs(nTris); - faceList quadFcs(nQuads); - label trii = 0; - label quadi = 0; - f.trianglesQuads(mesh.points(), trii, quadi, triFcs, quadFcs); - - forAll(quadFcs, quadI) - { - if (substituteCell) - { - substituteCell = false; - } - else - { - superCells[addCelli++] = celli; - } - - const face& quad = quadFcs[quadI]; - - // Ensure we have the correct orientation for the - // base of the primitive cell shape. - // If the cell is face owner, the orientation needs to be - // flipped. - // At the moment, VTK doesn't actually seem to care if - // negative cells are defined, but we'll do it anyhow - // (for safety). - if (isOwner) - { - nodeIds[0] = quad[3]; - nodeIds[1] = quad[2]; - nodeIds[2] = quad[1]; - nodeIds[3] = quad[0]; - } - else - { - nodeIds[0] = quad[0]; - nodeIds[1] = quad[1]; - nodeIds[2] = quad[2]; - nodeIds[3] = quad[3]; - } - nodeIds[4] = newVertexLabel; - vtkmesh->InsertNextCell - ( - VTK_PYRAMID, - 5, - nodeIds - ); - } - - forAll(triFcs, triI) - { - if (substituteCell) - { - substituteCell = false; - } - else - { - superCells[addCelli++] = celli; - } - - const face& tri = triFcs[triI]; - - // See note above about the orientation. - if (isOwner) - { - nodeIds[0] = tri[2]; - nodeIds[1] = tri[1]; - nodeIds[2] = tri[0]; - } - else - { - nodeIds[0] = tri[0]; - nodeIds[1] = tri[1]; - nodeIds[2] = tri[2]; - } - nodeIds[3] = newVertexLabel; - - vtkmesh->InsertNextCell - ( - VTK_TETRA, - 4, - nodeIds - ); - } - } - - addPointi++; - } + vtkmesh->SetCells + ( + cellTypes, + cellLocations, + cells, + faceLocations, + faces + ); + } + else + { + vtkmesh->SetCells + ( + cellTypes, + cellLocations, + cells, + nullptr, + nullptr + ); } - - vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); if (debug) { - Info<<"nCells=" << mesh.nCells() <<" nPoints=" << mesh.nPoints() - <<" nAddCells=" << nAddCells <<" nAddPoints=" << nAddPoints - << nl - << "<end> volumeVTKMesh" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; printMemory(); } @@ -426,4 +217,48 @@ vtkUnstructuredGrid* Foam::vtkPVFoam::volumeVTKMesh } +vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKSubsetMesh +( + const fvMeshSubset& subsetter, + foamVtuData& vtuData, + const bool decompPoly +) +{ + vtkSmartPointer<vtkUnstructuredGrid> vtkmesh = volumeVTKMesh + ( + subsetter.subMesh(), + vtuData, + decompPoly + ); + + // Convert cellMap, addPointCellLabels to global cell ids + vtuData.renumberCells(subsetter.cellMap()); + + // Copy pointMap as well, otherwise pointFields fail + vtuData.pointMap() = subsetter.pointMap(); + + return vtkmesh; +} + + +vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh +( + const fvMesh& mesh, + foamVtuData& vtuData +) const +{ + return volumeVTKMesh(mesh, vtuData, this->decomposePoly_); +} + + +vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKSubsetMesh +( + const fvMeshSubset& subsetter, + foamVtuData& vtuData +) const +{ + return volumeVTKSubsetMesh(subsetter, vtuData, this->decomposePoly_); +} + + // ************************************************************************* // diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamTemplates.C index 388f1bb79404b7dc0f3bd954c513115a6e886af4..ec64378d2f37b454211a0f009b086e4329a92741 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamTemplates.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamTemplates.C @@ -28,67 +28,91 @@ License // OpenFOAM includes #include "polyPatch.H" #include "primitivePatch.H" +#include "foamVtkAdaptors.H" // VTK includes #include "vtkCellArray.h" #include "vtkPoints.h" #include "vtkPolyData.h" +#include "vtkSmartPointer.h" -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // template<class PatchType> -vtkPolyData* Foam::vtkPVFoam::patchVTKMesh +vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePatchPoints ( - const word& name, const PatchType& p ) { - vtkPolyData* vtkmesh = vtkPolyData::New(); + // Convert OpenFOAM mesh vertices to VTK + const pointField& points = p.localPoints(); + + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); - if (debug) + vtkpoints->SetNumberOfPoints(points.size()); + forAll(points, i) { - Info<< "<beg> patchVTKMesh - " << name << endl; - printMemory(); + vtkpoints->SetPoint(i, points[i].v_); } - // Convert OpenFOAM mesh vertices to VTK - const Foam::pointField& points = p.localPoints(); + return vtkpoints; +} - vtkPoints* vtkpoints = vtkPoints::New(); - vtkpoints->Allocate(points.size()); - forAll(points, i) + +template<class PatchType> +vtkSmartPointer<vtkCellArray> Foam::vtkPVFoam::patchFacesVTKCells +( + const PatchType& p +) +{ + // Faces as polygons + const faceList& faces = p.localFaces(); + + label nAlloc = faces.size(); + forAll(faces, facei) { - vtkpoints->InsertNextPoint(points[i].v_); + nAlloc += faces[facei].size(); } - vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); + auto cells = vtkSmartPointer<vtkCellArray>::New(); - // Add faces as polygons - const faceList& faces = p.localFaces(); + UList<vtkIdType> cellsUL = + vtkUList + ( + cells, + faces.size(), + nAlloc + ); - vtkCellArray* vtkcells = vtkCellArray::New(); - vtkcells->Allocate(faces.size()); + // Cell connectivity for polygons + // [size, verts..., size, verts... ] + label idx = 0; forAll(faces, facei) { const face& f = faces[facei]; - vtkIdType nodeIds[f.size()]; + + cellsUL[idx++] = f.size(); forAll(f, fp) { - nodeIds[fp] = f[fp]; + cellsUL[idx++] = f[fp]; } - vtkcells->InsertNextCell(f.size(), nodeIds); } - vtkmesh->SetPolys(vtkcells); - vtkcells->Delete(); + return cells; +} - if (debug) - { - Info<< "<end> patchVTKMesh - " << name << endl; - printMemory(); - } + +template<class PatchType> +vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::patchVTKMesh +( + const PatchType& p +) +{ + auto vtkmesh = vtkSmartPointer<vtkPolyData>::New(); + + vtkmesh->SetPoints(movePatchPoints(p)); + vtkmesh->SetPolys(patchFacesVTKCells(p)); return vtkmesh; } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C index 52030e9c81028cc99803b5967695cb830f5094ab..f71354aaa1d390b33e64099f617712c32533e6a8 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C @@ -39,10 +39,6 @@ License // VTK includes #include "vtkDataArraySelection.h" -// Templates (only needed here) -#include "vtkPVFoamUpdateTemplates.C" - - // * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * // namespace Foam @@ -89,11 +85,11 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames wordList names(zmesh.size()); label nZone = 0; - forAll(zmesh, zoneI) + forAll(zmesh, zonei) { - if (!zmesh[zoneI].empty()) + if (!zmesh[zonei].empty()) { - names[nZone++] = zmesh[zoneI].name(); + names[nZone++] = zmesh[zonei].name(); } } names.setSize(nZone); @@ -128,9 +124,9 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames(const word& zoneType) const zonesEntries zones(ioObj); names.setSize(zones.size()); - forAll(zones, zoneI) + forAll(zones, zonei) { - names[zoneI] = zones[zoneI].keyword(); + names[zonei] = zones[zonei].keyword(); } } @@ -140,7 +136,7 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames(const word& zoneType) const void Foam::vtkPVFoam::updateInfoInternalMesh ( - vtkDataArraySelection* arraySelection + vtkDataArraySelection* select ) { if (debug) @@ -150,12 +146,8 @@ void Foam::vtkPVFoam::updateInfoInternalMesh // Determine mesh parts (internalMesh, patches...) //- Add internal mesh as first entry - arrayRangeVolume_.reset(arraySelection->GetNumberOfArrays()); - arraySelection->AddArray - ( - "internalMesh" - ); - arrayRangeVolume_ += 1; + rangeVolume_.reset(select->GetNumberOfArrays(), 1); + select->AddArray("internalMesh"); if (debug) { @@ -166,16 +158,15 @@ void Foam::vtkPVFoam::updateInfoInternalMesh void Foam::vtkPVFoam::updateInfoLagrangian ( - vtkDataArraySelection* arraySelection + vtkDataArraySelection* select ) { if (debug) { - Info<< "<beg> updateInfoLagrangian" << nl + Info<< "<beg> " << FUNCTION_NAME << nl << " " << dbPtr_->timePath()/cloud::prefix << endl; } - // use the db directly since this might be called without a mesh, // but the region must get added back in fileName lagrangianPrefix(cloud::prefix); @@ -190,96 +181,101 @@ void Foam::vtkPVFoam::updateInfoLagrangian readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY) ); - arrayRangeLagrangian_.reset(arraySelection->GetNumberOfArrays()); - - int nClouds = 0; - forAll(cloudDirs, cloudI) + rangeLagrangian_.reset(select->GetNumberOfArrays()); + forAll(cloudDirs, cloudi) { // Add cloud to GUI list - arraySelection->AddArray + select->AddArray ( - (cloudDirs[cloudI] + " - lagrangian").c_str() + ("lagrangian/" + cloudDirs[cloudi]).c_str() ); - - ++nClouds; + ++rangeLagrangian_; } - arrayRangeLagrangian_ += nClouds; if (debug) { - Info<< "<end> updateInfoLagrangian" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; } } void Foam::vtkPVFoam::updateInfoPatches ( - vtkDataArraySelection* arraySelection, - stringList& enabledEntries + vtkDataArraySelection* select, + HashSet<string>& enabledEntries ) { if (debug) { - Info<< "<beg> updateInfoPatches" + Info<< "<beg> " << FUNCTION_NAME << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; } + rangePatches_.reset(select->GetNumberOfArrays()); - HashSet<string> enabledEntriesSet(enabledEntries); - - arrayRangePatches_.reset(arraySelection->GetNumberOfArrays()); - - int nPatches = 0; if (meshPtr_) { const polyBoundaryMesh& patches = meshPtr_->boundaryMesh(); const HashTable<labelList>& groups = patches.groupPatchIDs(); - const wordList allPatchNames = patches.names(); + DynamicList<string> displayNames(groups.size()); - // Add patch groups - // ~~~~~~~~~~~~~~~~ + // Add (non-zero) patch groups to the list of mesh parts + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ forAllConstIters(groups, iter) { - const word& groupName = iter.key(); - const labelList& patchIDs = iter.object(); + const auto& groupName = iter.key(); + const auto& patchIDs = iter.object(); label nFaces = 0; - forAll(patchIDs, i) + for (auto patchId : patchIDs) { - nFaces += patches[patchIDs[i]].size(); + nFaces += patches[patchId].size(); } - // Valid patch if nFace > 0 - add patch to GUI list - if (nFaces) + if (!nFaces) { - string vtkGrpName = groupName + " - group"; - arraySelection->AddArray(vtkGrpName.c_str()); + // Skip if group has no faces + continue; + } - ++nPatches; + // Valid patch if nFace > 0 - add patch to GUI list + const string dpyName = "group/" + groupName; + displayNames.append(dpyName); - if (enabledEntriesSet.found(vtkGrpName)) + // Optionally replace group with patch name selections + // - must remove the group from the select itself, otherwise + // it can toggle on, but not toggle off very well + if + ( + !reader_->GetShowGroupsOnly() + && enabledEntries.erase(dpyName) + ) + { + for (auto patchId : patchIDs) { - if (!reader_->GetShowGroupsOnly()) + const polyPatch& pp = patches[patchId]; + if (pp.size()) { - enabledEntriesSet.erase(vtkGrpName); - forAll(patchIDs, i) - { - const polyPatch& pp = patches[patchIDs[i]]; - if (pp.size()) - { - string vtkPatchName = pp.name() + " - patch"; - enabledEntriesSet.insert(vtkPatchName); - } - } + enabledEntries.insert + ( + "patch/" + pp.name() + ); } } } } + // Sort group names + Foam::sort(displayNames); + for (const auto& name : displayNames) + { + select->AddArray(name.c_str()); + ++rangePatches_; + } - // Add patches - // ~~~~~~~~~~~ + // Add (non-zero) patches to the list of mesh parts + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (!reader_->GetShowGroupsOnly()) { @@ -290,12 +286,11 @@ void Foam::vtkPVFoam::updateInfoPatches if (pp.size()) { // Add patch to GUI list - arraySelection->AddArray + select->AddArray ( - (pp.name() + " - patch").c_str() + ("patch/" + pp.name()).c_str() ); - - ++nPatches; + ++rangePatches_; } } } @@ -320,94 +315,76 @@ void Foam::vtkPVFoam::updateInfoPatches false ); - // this should only ever fail if the mesh region doesn't exist + // This should only ever fail if the mesh region doesn't exist if (ioObj.typeHeaderOk<polyBoundaryMesh>(true, false)) { polyBoundaryMeshEntries patchEntries(ioObj); - - // Read patches and determine sizes - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + // Read patches, determine sizes and patch groups wordList names(patchEntries.size()); labelList sizes(patchEntries.size()); + HashTable<labelHashSet> groups(2*patchEntries.size()); forAll(patchEntries, patchi) { const dictionary& patchDict = patchEntries[patchi].dict(); + wordList groupNames; sizes[patchi] = readLabel(patchDict.lookup("nFaces")); names[patchi] = patchEntries[patchi].keyword(); - } - - - // Add (non-zero) patch groups to the list of mesh parts - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - HashTable<labelList> groups(patchEntries.size()); - forAll(patchEntries, patchi) - { - const dictionary& patchDict = patchEntries[patchi].dict(); - - wordList groupNames; - patchDict.readIfPresent("inGroups", groupNames); - - forAll(groupNames, groupI) + if + ( + sizes[patchi] // Valid patch if nFace > 0 + && patchDict.readIfPresent("inGroups", groupNames) + ) { - HashTable<labelList>::iterator iter = groups.find - ( - groupNames[groupI] - ); - if (iter != groups.end()) + forAll(groupNames, groupI) { - iter().append(patchi); - } - else - { - groups.insert(groupNames[groupI], labelList{patchi}); + groups(groupNames[groupI]).insert(patchi); } } } - forAllConstIters(groups, iter) - { - const word& groupName = iter.key(); - const labelList& patchIDs = iter.object(); - label nFaces = 0; - forAll(patchIDs, i) - { - nFaces += sizes[patchIDs[i]]; - } + // Add (non-zero) patch groups to the list of mesh parts + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + DynamicList<string> displayNames(groups.size()); - // Valid patch if nFace > 0 - add patch to GUI list - if (nFaces) + forAllConstIters(groups, iter) + { + const auto& groupName = iter.key(); + const auto& patchIDs = iter.object(); + + const string dpyName = "group/" + groupName; + displayNames.append(dpyName); + + // Optionally replace group with patch name selections + // - must remove the group from the select itself, otherwise + // it can toggle on, but not toggle off very well + if + ( + !reader_->GetShowGroupsOnly() + && enabledEntries.erase(dpyName) + ) { - string vtkGrpName = groupName + " - group"; - arraySelection->AddArray(vtkGrpName.c_str()); - - ++nPatches; - - if (enabledEntriesSet.found(vtkGrpName)) + for (auto patchId : patchIDs) { - if (!reader_->GetShowGroupsOnly()) - { - enabledEntriesSet.erase(vtkGrpName); - forAll(patchIDs, i) - { - if (sizes[patchIDs[i]]) - { - string vtkPatchName = - names[patchIDs[i]] + " - patch"; - enabledEntriesSet.insert(vtkPatchName); - } - } - } + enabledEntries.insert + ( + "patch/" + names[patchId] + ); } } } + // Sort group names + Foam::sort(displayNames); + for (const auto& name : displayNames) + { + select->AddArray(name.c_str()); + ++rangePatches_; + } // Add (non-zero) patches to the list of mesh parts // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -419,32 +396,27 @@ void Foam::vtkPVFoam::updateInfoPatches // Valid patch if nFace > 0 - add patch to GUI list if (sizes[patchi]) { - arraySelection->AddArray + select->AddArray ( - (names[patchi] + " - patch").c_str() + ("patch/" + names[patchi]).c_str() ); - - ++nPatches; + ++rangePatches_; } } } } } - arrayRangePatches_ += nPatches; - - // Update enabled entries in case of group selection - enabledEntries = enabledEntriesSet.toc(); if (debug) { - Info<< "<end> updateInfoPatches" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; } } void Foam::vtkPVFoam::updateInfoZones ( - vtkDataArraySelection* arraySelection + vtkDataArraySelection* select ) { if (!reader_->GetIncludeZones()) @@ -472,15 +444,15 @@ void Foam::vtkPVFoam::updateInfoZones namesLst = getZoneNames("cellZones"); } - arrayRangeCellZones_.reset(arraySelection->GetNumberOfArrays()); + rangeCellZones_.reset(select->GetNumberOfArrays()); forAll(namesLst, elemI) { - arraySelection->AddArray + select->AddArray ( - (namesLst[elemI] + " - cellZone").c_str() + ("cellZone/" + namesLst[elemI]).c_str() ); + ++rangeCellZones_; } - arrayRangeCellZones_ += namesLst.size(); // @@ -495,15 +467,15 @@ void Foam::vtkPVFoam::updateInfoZones namesLst = getZoneNames("faceZones"); } - arrayRangeFaceZones_.reset(arraySelection->GetNumberOfArrays()); + rangeFaceZones_.reset(select->GetNumberOfArrays()); forAll(namesLst, elemI) { - arraySelection->AddArray + select->AddArray ( - (namesLst[elemI] + " - faceZone").c_str() + ("faceZone/" + namesLst[elemI]).c_str() ); + ++rangeFaceZones_; } - arrayRangeFaceZones_ += namesLst.size(); // @@ -518,15 +490,15 @@ void Foam::vtkPVFoam::updateInfoZones namesLst = getZoneNames("pointZones"); } - arrayRangePointZones_.reset(arraySelection->GetNumberOfArrays()); + rangePointZones_.reset(select->GetNumberOfArrays()); forAll(namesLst, elemI) { - arraySelection->AddArray + select->AddArray ( - (namesLst[elemI] + " - pointZone").c_str() + ("pointZone/" + namesLst[elemI]).c_str() ); + ++rangePointZones_; } - arrayRangePointZones_ += namesLst.size(); if (debug) { @@ -537,7 +509,7 @@ void Foam::vtkPVFoam::updateInfoZones void Foam::vtkPVFoam::updateInfoSets ( - vtkDataArraySelection* arraySelection + vtkDataArraySelection* select ) { if (!reader_->GetIncludeSets()) @@ -577,28 +549,28 @@ void Foam::vtkPVFoam::updateInfoSets } - arrayRangeCellSets_.reset(arraySelection->GetNumberOfArrays()); - arrayRangeCellSets_ += addToSelection<cellSet> + rangeCellSets_.reset(select->GetNumberOfArrays()); + rangeCellSets_ += addToSelection<cellSet> ( - arraySelection, + select, objects, - " - cellSet" + "cellSet/" ); - arrayRangeFaceSets_.reset(arraySelection->GetNumberOfArrays()); - arrayRangeFaceSets_ += addToSelection<faceSet> + rangeFaceSets_.reset(select->GetNumberOfArrays()); + rangeFaceSets_ += addToSelection<faceSet> ( - arraySelection, + select, objects, - " - faceSet" + "faceSet/" ); - arrayRangePointSets_.reset(arraySelection->GetNumberOfArrays()); - arrayRangePointSets_ += addToSelection<pointSet> + rangePointSets_.reset(select->GetNumberOfArrays()); + rangePointSets_ += addToSelection<pointSet> ( - arraySelection, + select, objects, - " - pointSet" + "pointSet/" ); if (debug) @@ -608,23 +580,6 @@ void Foam::vtkPVFoam::updateInfoSets } -void Foam::vtkPVFoam::updateInfoFields() -{ - updateInfoFields<fvPatchField, volMesh> - ( - reader_->GetVolFieldSelection() - ); - updateInfoFields<pointPatchField, pointMesh> - ( - reader_->GetPointFieldSelection() - ); - updateInfoLagrangianFields - ( - reader_->GetLagrangianFieldSelection() - ); -} - - void Foam::vtkPVFoam::updateInfoLagrangianFields ( vtkDataArraySelection* select @@ -635,22 +590,23 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields Info<< "<beg> updateInfoLagrangianFields" << endl; } - // preserve the enabled selections - stringList enabledEntries = getSelectedArrayEntries(select); + // Preserve the enabled selections + HashSet<string> enabled = getSelectedArraySet(select); select->RemoveAllArrays(); // TODO - currently only get fields from ONE cloud // have to decide if the second set of fields get mixed in // or dealt with separately - const arrayRange& range = arrayRangeLagrangian_; + const arrayRange& range = rangeLagrangian_; if (range.empty()) { return; } - int partId = range.start(); - word cloudName = getPartName(partId); + // Add Lagrangian fields even if particles are not enabled? + const int partId = range.start(); + const word cloudName = getReaderPartName(partId); // use the db directly since this might be called without a mesh, // but the region must get added back in @@ -674,26 +630,8 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields addToSelection<IOField<symmTensor>>(select, objects); addToSelection<IOField<tensor>>(select, objects); - // restore the enabled selections - setSelectedArrayEntries(select, enabledEntries); - - if (debug > 1) - { - boolList status; - const label nElem = getSelected(status, select); - - forAll(status, i) - { - Info<< " lagrangian[" << i << "] = " - << status[i] - << " : " << select->GetArrayName(i) << nl; - } - - if (!nElem) - { - Info<< " lagrangian[none]" << nl; - } - } + // Restore the enabled selections + setSelectedArrayEntries(select, enabled); if (debug) { diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateTemplates.C index 1d2b429467b24ad68675c71543ff0232a93e6f44..4f11fdb1d6fb5caa5d75554d7efdcc420626366a 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateTemplates.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateTemplates.C @@ -45,16 +45,16 @@ void Foam::vtkPVFoam::updateInfoFields << endl; } - stringList enabledEntries; + HashSet<string> enabled; if (!select->GetNumberOfArrays() && !meshPtr_) { - // enable 'p' and 'U' only on the first call - enabledEntries = { "p", "U" }; + // Enable 'p' and 'U' only on the first call + enabled = { "p", "U" }; } else { - // preserve the enabled selections - enabledEntries = getSelectedArrayEntries(select); + // Preserve the enabled selections + enabled = getSelectedArraySet(select); } select->RemoveAllArrays(); @@ -126,8 +126,8 @@ void Foam::vtkPVFoam::updateInfoFields ); - // restore the enabled selections - setSelectedArrayEntries(select, enabledEntries); + // Restore the enabled selections + setSelectedArrayEntries(select, enabled); if (debug) { diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.cxx index ab4a6517066433378fa09cf288e8f54d28b683df..ec60272d5a97d675cf81e4eed774b4834c3f8e21 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.cxx +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.cxx @@ -40,13 +40,14 @@ License // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // file-scope -static QAbstractButton* setButtonProperties +// Widget properties +static QWidget* setWidgetProperties ( - QAbstractButton* b, + QWidget* widget, vtkSMProperty* prop ) { - QString tip; + widget->setFocusPolicy(Qt::NoFocus); // avoid dotted border vtkSMDocumentation* doc = prop->GetDocumentation(); if (doc) @@ -54,22 +55,33 @@ static QAbstractButton* setButtonProperties const char* txt = doc->GetDescription(); if (txt) { - tip = QString(txt).simplified(); + QString tip = QString(txt).simplified(); + if (tip.size()) + { + widget->setToolTip(tip); + } } } - b->setText(prop->GetXMLLabel()); - if (tip.size()) - { - b->setToolTip(tip); - } - b->setFocusPolicy(Qt::NoFocus); // avoid dotted border + return widget; +} +// file-scope +// Button properties +static QAbstractButton* setButtonProperties +( + QAbstractButton* b, + vtkSMProperty* prop +) +{ + setWidgetProperties(b, prop); + b->setText(prop->GetXMLLabel()); + vtkSMIntVectorProperty* intProp = vtkSMIntVectorProperty::SafeDownCast(prop); - // initial checked state for integer (bool) properties + // Initial checked state for integer (bool) properties if (intProp) { b->setChecked(intProp->GetElement(0)); @@ -111,12 +123,12 @@ void pqFoamBlockMeshControls::fireCommand(vtkSMProperty* prop) void pqFoamBlockMeshControls::fireCommand ( vtkSMIntVectorProperty* prop, - bool checked + int val ) { vtkSMProxy* pxy = this->proxy(); - prop->SetElement(0, checked); // Toogle bool + prop->SetElement(0, val); // Set int value, toogle bool, etc // Fire off command prop->Modified(); @@ -200,7 +212,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls setButtonProperties(b, refresh_); form->addWidget(b, 0, 0, Qt::AlignLeft); - connect(b, SIGNAL(clicked()), this, SLOT(refreshPressed())); + connect + ( + b, SIGNAL(clicked()), this, SLOT(refreshPressed()) + ); } if (showPatchNames_) @@ -209,7 +224,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls setButtonProperties(b, showPatchNames_); form->addWidget(b, 0, 1, Qt::AlignLeft); - connect(b, SIGNAL(toggled(bool)), this, SLOT(showPatchNames(bool))); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(showPatchNames(bool)) + ); } if (showPointNumbers_) @@ -218,7 +236,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls setButtonProperties(b, showPointNumbers_); form->addWidget(b, 0, 2, Qt::AlignLeft); - connect(b, SIGNAL(toggled(bool)), this, SLOT(showPointNumbers(bool))); + connect + ( + b, SIGNAL(toggled(bool)), this, SLOT(showPointNumbers(bool)) + ); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.h b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.h index a46cdc30528cdfdfa4fd47b1453a065d31be4467..89d7e945db90579a201d85334cbc7e6df028ebba 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.h +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/pqFoamBlockMeshControls.h @@ -71,8 +71,8 @@ class pqFoamBlockMeshControls //- Update property void fireCommand(vtkSMProperty* prop); - //- Toggle and update bool property - void fireCommand(vtkSMIntVectorProperty* prop, bool checked); + //- Update int property or toggle bool property + void fireCommand(vtkSMIntVectorProperty* prop, int val); //- Update "BlockArrayStatus", "CurvedEdgesArrayStatus" information void updateParts(); diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/vtkPVblockMeshReader.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/vtkPVblockMeshReader.cxx index 2c8c1ce453d2ca3c3a763cfcbe7af46d9904782f..ed0271d0a14558e543bb0d5a9f7a1026a8539b37 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/vtkPVblockMeshReader.cxx +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/PVblockMeshReader/vtkPVblockMeshReader.cxx @@ -106,7 +106,7 @@ vtkPVblockMeshReader::~vtkPVblockMeshReader() if (FileName) { - delete [] FileName; + delete[] FileName; } BlockSelection->RemoveAllObservers(); @@ -165,20 +165,19 @@ int vtkPVblockMeshReader::RequestData if (!FileName) { - vtkErrorMacro("FileName has to be specified!"); + vtkErrorMacro("FileName must be specified!"); return 0; } - - // Catch previous error if (!backend_) { - vtkErrorMacro("Reader failed - perhaps no mesh?"); + // Catch some previous error + vtkErrorMacro("Reader failed - perhaps no blockMesh?"); return 0; } if (Foam::vtkPVblockMesh::debug) { - cout<<"REQUEST_DATA:\n"; + cout<<"RequestData:\n"; outputVector->GetInformationObject(0)->Print(cout); } @@ -190,19 +189,12 @@ int vtkPVblockMeshReader::RequestData ) ); - if (Foam::vtkPVblockMesh::debug) - { - cout<< "update output with " - << output->GetNumberOfBlocks() << " blocks\n"; - } - backend_->Update(output); updatePatchNamesView(ShowPatchNames); updatePointNumbersView(ShowPointNumbers); - // Do any cleanup on the OpenFOAM side - backend_->CleanUp(); + backend_->UpdateFinalize(); return 1; } @@ -263,12 +255,11 @@ void vtkPVblockMeshReader::updatePatchNamesView(const bool show) } // Get all the pqRenderView instances - QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); - for (int viewI=0; viewI<renderViews.size(); ++viewI) + for (auto view : smModel->findItems<pqRenderView*>()) { backend_->renderPatchNames ( - renderViews[viewI]->getRenderViewProxy()->GetRenderer(), + view->getRenderViewProxy()->GetRenderer(), show ); } @@ -295,12 +286,11 @@ void vtkPVblockMeshReader::updatePointNumbersView(const bool show) } // Get all the pqRenderView instances - QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); - for (int viewI=0; viewI<renderViews.size(); ++viewI) + for (auto view : smModel->findItems<pqRenderView*>()) { backend_->renderPointNumbers ( - renderViews[viewI]->getRenderViewProxy()->GetRenderer(), + view->getRenderViewProxy()->GetRenderer(), show ); } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C index 39c60bb7380df4a11f67d1b48a7f2f7fd6dfadd3..70ccb1f42067c5a509ced280f7b6be1663a715b4 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C @@ -39,6 +39,7 @@ License #include "vtkRenderer.h" #include "vtkTextActor.h" #include "vtkTextProperty.h" +#include "vtkSmartPointer.h" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -47,32 +48,37 @@ namespace Foam defineTypeNameAndDebug(vtkPVblockMesh, 0); } - // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -vtkTextActor* Foam::vtkPVblockMesh::createTextActor -( - const string& s, - const point& pt -) +namespace Foam { - vtkTextActor* txt = vtkTextActor::New(); - txt->SetInput(s.c_str()); - - // Set text properties - vtkTextProperty* tprop = txt->GetTextProperty(); - tprop->SetFontFamilyToArial(); - tprop->BoldOn(); - tprop->ShadowOff(); - tprop->SetLineSpacing(1.0); - tprop->SetFontSize(14); - tprop->SetColor(1.0, 0.0, 1.0); - tprop->SetJustificationToCentered(); - - txt->GetPositionCoordinate()->SetCoordinateSystemToWorld(); - txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); - - return txt; + // file-scope + //- Create a text actor + static vtkSmartPointer<vtkTextActor> createTextActor + ( + const std::string& s, + const Foam::point& pt + ) + { + auto txt = vtkSmartPointer<vtkTextActor>::New(); + + txt->SetInput(s.c_str()); + + // Set text properties + vtkTextProperty* tprop = txt->GetTextProperty(); + tprop->SetFontFamilyToArial(); + tprop->BoldOn(); + tprop->ShadowOff(); + tprop->SetLineSpacing(1.0); + tprop->SetFontSize(14); + tprop->SetColor(1.0, 0.0, 1.0); + tprop->SetJustificationToCentered(); + + txt->GetPositionCoordinate()->SetCoordinateSystemToWorld(); + txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); + + return txt; + } } @@ -81,9 +87,9 @@ vtkTextActor* Foam::vtkPVblockMesh::createTextActor void Foam::vtkPVblockMesh::resetCounters() { // Reset mesh part ids and sizes - arrayRangeBlocks_.reset(); - arrayRangeEdges_.reset(); - arrayRangeCorners_.reset(); + rangeBlocks_.reset(); + rangeEdges_.reset(); + rangeCorners_.reset(); } @@ -92,15 +98,13 @@ void Foam::vtkPVblockMesh::updateInfoBlocks vtkDataArraySelection* select ) { - arrayRange& range = arrayRangeBlocks_; - if (debug) { Info<< "<beg> updateInfoBlocks" << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; } - range.reset(select->GetNumberOfArrays()); + rangeBlocks_.reset(select->GetNumberOfArrays()); const blockMesh& blkMesh = *meshPtr_; @@ -122,10 +126,9 @@ void Foam::vtkPVblockMesh::updateInfoBlocks // Add "blockId" or "blockId - zoneName" to GUI list select->AddArray(ostr.str().c_str()); + ++rangeBlocks_; } - range += nBlocks; - if (debug) { Info<< "<end> updateInfoBlocks" << endl; @@ -138,15 +141,13 @@ void Foam::vtkPVblockMesh::updateInfoEdges vtkDataArraySelection* select ) { - arrayRange& range = arrayRangeEdges_; - if (debug) { Info<< "<beg> updateInfoEdges" << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; } - range.reset(select->GetNumberOfArrays()); + rangeEdges_.reset(select->GetNumberOfArrays()); const blockMesh& blkMesh = *meshPtr_; const blockEdgeList& edges = blkMesh.edges(); @@ -161,10 +162,9 @@ void Foam::vtkPVblockMesh::updateInfoEdges // Add "beg:end - type" to GUI list select->AddArray(ostr.str().c_str()); + ++rangeEdges_; } - range += edges.size(); - if (debug) { Info<< "<end> updateInfoEdges" << endl; @@ -185,9 +185,9 @@ Foam::vtkPVblockMesh::vtkPVblockMesh meshPtr_(nullptr), meshRegion_(polyMesh::defaultRegion), meshDir_(polyMesh::meshSubDir), - arrayRangeBlocks_("block"), - arrayRangeEdges_("edges"), - arrayRangeCorners_("corners") + rangeBlocks_("block"), + rangeEdges_("edges"), + rangeCorners_("corners") { if (debug) { @@ -302,14 +302,15 @@ void Foam::vtkPVblockMesh::updateInfo() vtkDataArraySelection* blockSelection = reader_->GetBlockSelection(); vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection(); - // preserve the enabled selections if possible - stringList enabledParts; - stringList enabledEdges; const bool firstTime = (!blockSelection->GetNumberOfArrays() && !meshPtr_); + + // Preserve the enabled selections if possible + HashSet<string> enabledParts; + HashSet<string> enabledEdges; if (!firstTime) { - enabledParts = getSelectedArrayEntries(blockSelection); - enabledEdges = getSelectedArrayEntries(edgeSelection); + enabledParts = getSelectedArraySet(blockSelection); + enabledEdges = getSelectedArraySet(edgeSelection); } // Clear current mesh parts list @@ -325,7 +326,7 @@ void Foam::vtkPVblockMesh::updateInfo() // Update curved edges list updateInfoEdges(edgeSelection); - // restore the enabled selections + // Restore the enabled selections if (!firstTime) { setSelectedArrayEntries(blockSelection, enabledParts); @@ -405,14 +406,6 @@ void Foam::vtkPVblockMesh::Update { reader_->UpdateProgress(0.1); - // Set up mesh parts selection(s) - getSelected(blockStatus_, reader_->GetBlockSelection()); - - // Set up curved edges selection(s) - getSelected(edgeStatus_, reader_->GetCurvedEdgesSelection()); - - reader_->UpdateProgress(0.2); - // Update the OpenFOAM mesh updateFoamMesh(); reader_->UpdateProgress(0.5); @@ -425,11 +418,10 @@ void Foam::vtkPVblockMesh::Update convertMeshEdges(output, blockNo); reader_->UpdateProgress(0.8); - } -void Foam::vtkPVblockMesh::CleanUp() +void Foam::vtkPVblockMesh::UpdateFinalize() { reader_->UpdateProgress(1.0); } @@ -442,12 +434,11 @@ void Foam::vtkPVblockMesh::renderPatchNames ) { // always remove old actors first - forAll(patchTextActorsPtrs_, actori) + forAll(patchTextActors_, actori) { - renderer->RemoveViewProp(patchTextActorsPtrs_[actori]); - patchTextActorsPtrs_[actori]->Delete(); + renderer->RemoveViewProp(patchTextActors_[actori]); } - patchTextActorsPtrs_.clear(); + patchTextActors_.clear(); // the number of text actors label nActors = 0; @@ -465,7 +456,7 @@ void Foam::vtkPVblockMesh::renderPatchNames } // 8 sides per block is plenty - patchTextActorsPtrs_.setSize(8*blkMesh.size()); + patchTextActors_.setSize(8*blkMesh.size()); // Collect all variables dictionary varDict(meshDescription.subOrEmptyDict("namedVertices")); @@ -501,33 +492,33 @@ void Foam::vtkPVblockMesh::renderPatchNames const face& f = patchFaces[facei]; // Into a list for later removal - patchTextActorsPtrs_[nActors++] = createTextActor + patchTextActors_[nActors++] = createTextActor ( patchName, f.centre(cornerPts) * scaleFactor ); - if (nActors == patchTextActorsPtrs_.size()) + if (nActors == patchTextActors_.size()) { // hit max allocated space - bail out break; } } - if (nActors == patchTextActorsPtrs_.size()) + if (nActors == patchTextActors_.size()) { // hit max allocated space - bail out break; } } - patchTextActorsPtrs_.setSize(nActors); + patchTextActors_.setSize(nActors); } // Add text to each renderer - forAll(patchTextActorsPtrs_, actori) + forAll(patchTextActors_, actori) { - renderer->AddViewProp(patchTextActorsPtrs_[actori]); + renderer->AddViewProp(patchTextActors_[actori]); } } @@ -540,12 +531,11 @@ void Foam::vtkPVblockMesh::renderPointNumbers { // always remove old actors first - forAll(pointTextActorsPtrs_, actori) + forAll(pointTextActors_, actori) { - renderer->RemoveViewProp(pointTextActorsPtrs_[actori]); - pointTextActorsPtrs_[actori]->Delete(); + renderer->RemoveViewProp(pointTextActors_[actori]); } - pointTextActorsPtrs_.clear(); + pointTextActors_.clear(); if (show && meshPtr_) { @@ -553,7 +543,7 @@ void Foam::vtkPVblockMesh::renderPointNumbers const pointField& cornerPts = blkMesh.vertices(); const scalar scaleFactor = blkMesh.scaleFactor(); - pointTextActorsPtrs_.setSize(cornerPts.size()); + pointTextActors_.setSize(cornerPts.size()); forAll(cornerPts, pointi) { // Display either pointi as a number or with its name @@ -562,7 +552,7 @@ void Foam::vtkPVblockMesh::renderPointNumbers blockVertex::write(os, pointi, blkMesh.meshDict()); // Into a list for later removal - pointTextActorsPtrs_[pointi] = createTextActor + pointTextActors_[pointi] = createTextActor ( os.str(), cornerPts[pointi]*scaleFactor @@ -571,9 +561,9 @@ void Foam::vtkPVblockMesh::renderPointNumbers } // Add text to each renderer - forAll(pointTextActorsPtrs_, actori) + forAll(pointTextActors_, actori) { - renderer->AddViewProp(pointTextActorsPtrs_[actori]); + renderer->AddViewProp(pointTextActors_[actori]); } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.H b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.H index a22316c84afce69d88d71c5559185a980c524ae9..1a85c655298d1756ee480940e0116ee484bdbd24 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.H +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.H @@ -25,13 +25,18 @@ Class Foam::vtkPVblockMesh Description - Provides a reader interface for OpenFOAM blockMesh to VTK interaction + The backend for the vtkPVblockMeshReader reader module - + providing a paraview reader interface for OpenFOAM blockMesh. + + The block reader module can assist when creating a blockMeshDict + for use with the blockMesh utility. As well as blocks, it can be + used to visualize edges,corners and patch names. + + There is no native VTK equivalent for this functionality. SourceFiles vtkPVblockMesh.C vtkPVblockMeshConvert.C - vtkPVblockMeshUpdate.C - vtkPVblockMeshUtils.C // Needed by VTK: vtkDataArrayTemplateImplicit.txx @@ -56,6 +61,8 @@ class vtkPolyData; class vtkUnstructuredGrid; class vtkIndent; +template<class T> class vtkSmartPointer; + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -93,34 +100,25 @@ class vtkPVblockMesh //- The mesh directory for the region fileName meshDir_; - //- Selected geometrical parts - boolList blockStatus_; - - //- Selected curved edges - boolList edgeStatus_; - //- First instance and size of bleckMesh blocks // used to index into blockStatus_ - arrayRange arrayRangeBlocks_; + arrayRange rangeBlocks_; //- First instance and size of CurvedEdges (only partially used) - arrayRange arrayRangeEdges_; + arrayRange rangeEdges_; //- First instance and size of block corners (only partially used) - arrayRange arrayRangeCorners_; + arrayRange rangeCorners_; //- List of patch names for rendering to window - List<vtkTextActor*> patchTextActorsPtrs_; + List<vtkSmartPointer<vtkTextActor>> patchTextActors_; //- List of point numbers for rendering to window - List<vtkTextActor*> pointTextActorsPtrs_; + List<vtkSmartPointer<vtkTextActor>> pointTextActors_; // Private Member Functions - //- Create a text actor - static vtkTextActor* createTextActor(const string& s, const point& pt); - //- Reset data counters void resetCounters(); @@ -178,14 +176,15 @@ public: void Update(vtkMultiBlockDataSet* output); - //- Clean any storage - void CleanUp(); + //- Final part of Update(), after any last minute rendering. + void UpdateFinalize(); //- Add/remove patch names to/from the view - void renderPatchNames(vtkRenderer*, const bool show); + void renderPatchNames(vtkRenderer* renderer, const bool show); //- Add/remove point numbers to/from the view - void renderPointNumbers(vtkRenderer*, const bool show); + void renderPointNumbers(vtkRenderer* renderer, const bool show); + // Access diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMeshConvert.C b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMeshConvert.C index 51f8f4c90cac535258a505349f9858f331de50e4..032a5b011a957bfe6c243a61ae06a78e867fbd6a 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMeshConvert.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMeshConvert.C @@ -37,28 +37,9 @@ License #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkUnstructuredGrid.h" +#include "vtkSmartPointer.h" -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -//! \cond fileScope -inline static void insertNextPoint -( - vtkPoints *points, - const Foam::point& p, - const Foam::scalar scaleFactor -) -{ - points->InsertNextPoint - ( - p.x()*scaleFactor, - p.y()*scaleFactor, - p.z()*scaleFactor - ); -} - -//! \endcond - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::vtkPVblockMesh::convertMeshBlocks @@ -67,56 +48,52 @@ void Foam::vtkPVblockMesh::convertMeshBlocks int& blockNo ) { - vtkDataArraySelection* selection = reader_->GetBlockSelection(); - arrayRange& range = arrayRangeBlocks_; - range.block(blockNo); // set output block - label datasetNo = 0; // restart at dataset 0 - - const blockMesh& blkMesh = *meshPtr_; - const Foam::pointField& blockPoints = blkMesh.vertices(); - if (debug) { Info<< "<beg> convertMeshBlocks" << endl; } - int blockI = 0; - const scalar scaleFactor = blkMesh.scaleFactor(); - - for + const Map<string> blockStatus = getSelectedArrayMap ( - int partId = range.start(); - partId < range.end(); - ++partId, ++blockI - ) + reader_->GetBlockSelection() + ); + + arrayRange& range = rangeBlocks_; + range.block(blockNo); // set output block + label datasetNo = 0; // restart at dataset 0 + + const blockMesh& blkMesh = *meshPtr_; + const pointField blkPoints(blkMesh.vertices() * blkMesh.scaleFactor()); + + vtkIdType nodeIds[8]; // Space for VTK_HEXAHEDRON vertices + int blockId = -1; + for (auto partId : range) { - if (!blockStatus_[partId]) + ++blockId; // Increment first + if (!blockStatus.found(partId)) { continue; } + const auto& longName = blockStatus[partId]; - const blockDescriptor& blockDef = blkMesh[blockI]; - - // Convert OpenFOAM mesh vertices to VTK - vtkPoints *vtkpoints = vtkPoints::New(); - vtkpoints->Allocate(blockDef.nPoints()); + const blockDescriptor& blockDef = blkMesh[blockId]; const labelList& blockLabels = blockDef.blockShape(); - vtkIdType nodeIds[8]; + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); + vtkpoints->SetNumberOfPoints(blockLabels.size()); - forAll(blockLabels, ptI) + forAll(blockLabels, pointi) { - insertNextPoint + vtkpoints->SetPoint ( - vtkpoints, - blockPoints[blockLabels[ptI]], - scaleFactor + pointi, + blkPoints[blockLabels[pointi]].v_ ); - - nodeIds[ptI] = ptI; + nodeIds[pointi] = pointi; } - vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New(); + auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New(); + vtkmesh->Allocate(1); vtkmesh->InsertNextCell ( @@ -126,16 +103,9 @@ void Foam::vtkPVblockMesh::convertMeshBlocks ); vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); - - addToBlock - ( - output, vtkmesh, range, datasetNo, - selection->GetArrayName(partId) - ); - vtkmesh->Delete(); - datasetNo++; + addToBlock(output, vtkmesh, range, datasetNo, longName); + ++datasetNo; } @@ -158,34 +128,34 @@ void Foam::vtkPVblockMesh::convertMeshEdges int& blockNo ) { - vtkDataArraySelection* selection = reader_->GetCurvedEdgesSelection(); - arrayRange& range = arrayRangeEdges_; + const Map<string> edgeStatus = getSelectedArrayMap + ( + reader_->GetCurvedEdgesSelection() + ); + + arrayRange& range = rangeEdges_; range.block(blockNo); // set output block label datasetNo = 0; // restart at dataset 0 const blockMesh& blkMesh = *meshPtr_; const blockEdgeList& edges = blkMesh.edges(); - - int edgeI = 0; const scalar scaleFactor = blkMesh.scaleFactor(); - for - ( - int partId = range.start(); - partId < range.end(); - ++partId, ++edgeI - ) + int edgeId = -1; + for (auto partId : range) { - if (!edgeStatus_[partId]) + ++edgeId; // Increment first + if (!edgeStatus.found(partId)) { continue; } + const auto& longName = edgeStatus[partId]; - // search each block - forAll(blkMesh, blockI) + // Search each block + forAll(blkMesh, blockId) { - const blockDescriptor& blockDef = blkMesh[blockI]; + const blockDescriptor& blockDef = blkMesh[blockId]; edgeList blkEdges = blockDef.blockShape().edges(); @@ -198,7 +168,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges label foundEdgeI = -1; forAll(blkEdges, blkEdgeI) { - if (edges[edgeI].compare(blkEdges[blkEdgeI])) + if (edges[edgeId].compare(blkEdges[blkEdgeI])) { foundEdgeI = blkEdgeI; break; @@ -209,24 +179,21 @@ void Foam::vtkPVblockMesh::convertMeshEdges { const List<point>& edgePoints = edgesPoints[foundEdgeI]; - vtkPolyData* vtkmesh = vtkPolyData::New(); - vtkPoints* vtkpoints = vtkPoints::New(); - - vtkpoints->Allocate( edgePoints.size() ); - vtkmesh->Allocate(1); + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); + vtkpoints->SetNumberOfPoints(edgePoints.size()); vtkIdType pointIds[edgePoints.size()]; - forAll(edgePoints, ptI) + forAll(edgePoints, pointi) { - insertNextPoint - ( - vtkpoints, - edgePoints[ptI], - scaleFactor - ); - pointIds[ptI] = ptI; + const point p = edgePoints[pointi] * scaleFactor; + + vtkpoints->SetPoint(pointi, p.v_); + pointIds[pointi] = pointi; } + auto vtkmesh = vtkSmartPointer<vtkPolyData>::New(); + + vtkmesh->Allocate(1); vtkmesh->InsertNextCell ( VTK_POLY_LINE, @@ -235,16 +202,9 @@ void Foam::vtkPVblockMesh::convertMeshEdges ); vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); - - addToBlock - ( - output, vtkmesh, range, datasetNo, - selection->GetArrayName(partId) - ); - vtkmesh->Delete(); - datasetNo++; + addToBlock(output, vtkmesh, range, datasetNo, longName); + ++datasetNo; break; } @@ -271,51 +231,34 @@ void Foam::vtkPVblockMesh::convertMeshCorners int& blockNo ) { - arrayRange& range = arrayRangeCorners_; + arrayRange& range = rangeCorners_; range.block(blockNo); // set output block label datasetNo = 0; // restart at dataset 0 - const pointField& blockPoints = meshPtr_->vertices(); - const scalar& scaleFactor = meshPtr_->scaleFactor(); + const pointField blkPoints(meshPtr_->vertices() * meshPtr_->scaleFactor()); if (debug) { - Info<< "<beg> convertMeshCorners" << endl; + Info<< "<beg> " << FUNCTION_NAME << endl; } - if (true) // or some flag or other condition + if (true) // Or some flag or other condition { - vtkPolyData* vtkmesh = vtkPolyData::New(); - vtkPoints* vtkpoints = vtkPoints::New(); - vtkCellArray* vtkcells = vtkCellArray::New(); - - vtkpoints->Allocate( blockPoints.size() ); - vtkcells->Allocate( blockPoints.size() ); + auto vtkpoints = vtkSmartPointer<vtkPoints>::New(); + vtkpoints->SetNumberOfPoints(blkPoints.size()); - vtkIdType pointId = 0; - forAll(blockPoints, ptI) + forAll(blkPoints, pointi) { - insertNextPoint - ( - vtkpoints, - blockPoints[ptI], - scaleFactor - ); - - vtkcells->InsertNextCell(1, &pointId); // VTK_VERTEX - pointId++; + vtkpoints->SetPoint(pointi, blkPoints[pointi].v_); } - vtkmesh->SetPoints(vtkpoints); - vtkpoints->Delete(); + auto vtkmesh = vtkSmartPointer<vtkPolyData>::New(); - vtkmesh->SetVerts(vtkcells); - vtkcells->Delete(); + vtkmesh->SetPoints(vtkpoints); + vtkmesh->SetVerts(foamPvCore::identityVertices(blkPoints.size())); addToBlock(output, vtkmesh, range, datasetNo, range.name()); - vtkmesh->Delete(); - - datasetNo++; + ++datasetNo; } // anything added? @@ -326,7 +269,7 @@ void Foam::vtkPVblockMesh::convertMeshCorners if (debug) { - Info<< "<end> convertMeshCorners" << endl; + Info<< "<end> " << FUNCTION_NAME << endl; } } diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.C b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.C index 478cff22a4dc7d99b7cefd666f18964cade030c6..57e52af03dbed1396cf74dc95d89fa9a85c2e041 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.C @@ -32,6 +32,9 @@ License #include "vtkDataSet.h" #include "vtkMultiBlockDataSet.h" #include "vtkInformation.h" +#include "vtkSmartPointer.h" + +#include "foamVtkAdaptors.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -54,7 +57,8 @@ void Foam::foamPvCore::addToBlock const int blockNo = selector.block(); vtkDataObject* dataObj = output->GetBlock(blockNo); - vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(dataObj); + vtkSmartPointer<vtkMultiBlockDataSet> block = + vtkMultiBlockDataSet::SafeDownCast(dataObj); if (!block) { @@ -66,9 +70,8 @@ void Foam::foamPvCore::addToBlock return; } - block = vtkMultiBlockDataSet::New(); + block = vtkSmartPointer<vtkMultiBlockDataSet>::New(); output->SetBlock(blockNo, block); - block->Delete(); } if (debug) @@ -81,7 +84,7 @@ void Foam::foamPvCore::addToBlock block->SetBlock(datasetNo, dataset); - // name the output block when assigning dataset 0 + // Name the output block when assigning dataset 0 if (datasetNo == 0) { output->GetMetaData(blockNo)->Set @@ -102,56 +105,6 @@ void Foam::foamPvCore::addToBlock } -int Foam::foamPvCore::getNumberOfDataSets -( - vtkMultiBlockDataSet* output, - const arrayRange& selector -) -{ - const int blockNo = selector.block(); - - vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast - ( - output->GetBlock(blockNo) - ); - - if (block) - { - return block->GetNumberOfBlocks(); - } - - return 0; -} - - -int Foam::foamPvCore::getSelected -( - boolList& status, - vtkDataArraySelection* selection -) -{ - const int n = selection->GetNumberOfArrays(); - if (status.size() != n) - { - status.setSize(n); - status = false; - } - - int count = 0; - forAll(status, i) - { - const bool setting = selection->GetArraySetting(i); - if (setting) - { - ++count; - } - status[i] = setting; - } - - return count; -} - - Foam::hashedWordList Foam::foamPvCore::getSelected ( vtkDataArraySelection* select @@ -164,7 +117,7 @@ Foam::hashedWordList Foam::foamPvCore::getSelected { if (select->GetArraySetting(i)) { - selected.append(getFirstWord(select->GetArrayName(i))); + selected.append(getFoamName(select->GetArrayName(i))); } } @@ -181,11 +134,11 @@ Foam::hashedWordList Foam::foamPvCore::getSelected const int n = select->GetNumberOfArrays(); DynamicList<word> selected(n); - for (int i = selector.start(); i < selector.end(); ++i) + for (auto i : selector) { if (select->GetArraySetting(i)) { - selected.append(getFirstWord(select->GetArrayName(i))); + selected.append(getFoamName(select->GetArrayName(i))); } } @@ -193,22 +146,22 @@ Foam::hashedWordList Foam::foamPvCore::getSelected } -Foam::stringList Foam::foamPvCore::getSelectedArrayEntries +Foam::HashSet<Foam::string> +Foam::foamPvCore::getSelectedArraySet ( vtkDataArraySelection* select ) { - stringList selections(select->GetNumberOfArrays()); - label nElem = 0; + const int n = select->GetNumberOfArrays(); + HashSet<string> enabled(2*n); - forAll(selections, elemI) + for (int i=0; i < n; ++i) { - if (select->GetArraySetting(elemI)) + if (select->GetArraySetting(i)) { - selections[nElem++] = select->GetArrayName(elemI); + enabled.insert(select->GetArrayName(i)); } } - selections.setSize(nElem); if (debug > 1) { @@ -220,92 +173,61 @@ Foam::stringList Foam::foamPvCore::getSelectedArrayEntries } Info<< " )\nselected("; - forAll(selections, elemI) + for (auto k : enabled) { - Info<< " " << selections[elemI]; + Info<< " " << k; } Info<< " )\n"; } - return selections; + return enabled; } -Foam::stringList Foam::foamPvCore::getSelectedArrayEntries +Foam::Map<Foam::string> +Foam::foamPvCore::getSelectedArrayMap ( - vtkDataArraySelection* select, - const arrayRange& selector + vtkDataArraySelection* select ) { - stringList selections(selector.size()); - label nElem = 0; + const int n = select->GetNumberOfArrays(); + Map<string> enabled(2*n); - for (int i = selector.start(); i < selector.end(); ++i) + for (int i=0; i < n; ++i) { if (select->GetArraySetting(i)) { - selections[nElem++] = select->GetArrayName(i); - } - } - selections.setSize(nElem); - - if (debug > 1) - { - Info<< "available("; - for (int i = selector.start(); i < selector.end(); ++i) - { - Info<< " \"" << select->GetArrayName(i) << "\""; + enabled.insert(i, select->GetArrayName(i)); } - Info<< " )\nselected("; - - forAll(selections, elemI) - { - Info<< " " << selections[elemI]; - } - Info<< " )\n"; } - return selections; + return enabled; } -void Foam::foamPvCore::setSelectedArrayEntries -( - vtkDataArraySelection* select, - const stringList& selections -) +Foam::word Foam::foamPvCore::getFoamName(const std::string& str) { - const int n = select->GetNumberOfArrays(); - select->DisableAllArrays(); - - // Loop through entries, setting values from selectedEntries - for (int i=0; i < n; ++i) + if (str.size()) { - const string arrayName(select->GetArrayName(i)); - - forAll(selections, elemI) + std::string::size_type beg = str.rfind('/'); + if (beg == std::string::npos) { - if (selections[elemI] == arrayName) - { - select->EnableArray(arrayName.c_str()); - break; - } + beg = 0; + } + else + { + ++beg; } - } -} + std::string::size_type end = beg; -Foam::word Foam::foamPvCore::getFirstWord(const char* str) -{ - if (str) - { - label n = 0; - while (str[n] && word::valid(str[n])) + while (str[end] && word::valid(str[end])) { - ++n; + ++end; } - // don't need to re-check for invalid chars - return word(str, n, false); + + // Already checked for valid/invalid chars + return word(str.substr(beg, beg+end), false); } else { @@ -324,4 +246,30 @@ void Foam::foamPvCore::printMemory() } } + +vtkSmartPointer<vtkCellArray> Foam::foamPvCore::identityVertices +( + const label size +) +{ + // VTK_VERTEX + auto cells = vtkSmartPointer<vtkCellArray>::New(); + + UList<vtkIdType> cellsUL = vtkUList(cells, size, 2*size); + + // Cell connectivity for vertex + // [size, ids.., size, ids...] + // which means + // [1, id, 1, id, ...] + label idx = 0; + for (label id=0; id < size; ++id) + { + cellsUL[idx++] = 1; + cellsUL[idx++] = id; + } + + return cells; +} + + // ************************************************************************* // diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H index f6203690fd54f7eeb730faea212b19c9ef51c937..3bbc92855e52f4c6c21b7be82807c7553582b44a 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H @@ -39,16 +39,20 @@ SourceFiles #include "pointList.H" #include "wordList.H" #include "Hash.H" +#include "HashSet.H" +#include "Map.H" #include "hashedWordList.H" - -#include "vtkPoints.h" +#include "labelRange.H" // * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // +class vtkCellArray; class vtkDataArraySelection; class vtkDataSet; -class vtkMultiBlockDataSet; class vtkIndent; +class vtkMultiBlockDataSet; +class vtkPoints; +template<class T> class vtkSmartPointer; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -69,21 +73,20 @@ public: //- Bookkeeping for GUI checklists and multi-block organization // Works like a SubList selection. class arrayRange + : + public labelRange { const char *name_; int block_; - int start_; - int size_; public: //- Construct with given name for the specified block - arrayRange(const char *name, const int blockNo=0) + arrayRange(const char *name, int blockNo=0) : + labelRange(), name_(name), - block_(blockNo), - start_(0), - size_(0) + block_(blockNo) {} //- Return the block holding these datasets @@ -106,47 +109,21 @@ public: return name_; } - //- The array start index - int start() const - { - return start_; - } - - //- The array end index - int end() const - { - return start_ + size_; - } - - //- The sub-list size - int size() const - { - return size_; - } - - //- True if the sub-list is empty - bool empty() const - { - return !size_; - } + //- Reset the start/size directly + using labelRange::reset; //- Reset the size to zero and optionally assign a new start - void reset(const int startAt = 0) + void reset(label startAt = 0) { - start_ = startAt; - size_ = 0; + clear(); + setStart(startAt); } - //- Assign new start and reset the size - void operator=(const int i) - { - reset(i); - } //- Increment the size - void operator+=(const int n) + void operator+=(label n) { - size_ += n; + setSize(size() + n); } }; // End class arrayRange @@ -183,48 +160,26 @@ public: const std::string& datasetName ); - //- Convenience method for the VTK multiblock API - // Always returns a nullptr if datasetNo is negative - template<class Type=vtkDataSet> - static Type* getDataFromBlock - ( - vtkMultiBlockDataSet* output, - const arrayRange& selector, - const label datasetNo - ); - - //- Convenience method for the VTK multiblock API - static int getNumberOfDataSets - ( - vtkMultiBlockDataSet* output, - const arrayRange& selector - ); - //- Add objects of Type to array selection template<class Type> static label addToSelection ( vtkDataArraySelection* select, const IOobjectList& objects, - const string& suffix = string::null + const std::string& prefix = string::null ); - //- Retrieve the current selections into a boolList - static int getSelected - ( - boolList& lst, - vtkDataArraySelection* select - ); - - //- Retrieve the current selections as a wordHashSet + //- Retrieve the current selections as a hashedWordList, + // while stripping off any prefix or suffix static hashedWordList getSelected ( vtkDataArraySelection* select ); - //- Retrieve a sub-list of the current selections + //- Retrieve a sub-list of the current selections as a hashedWordList, + // while stripping off any prefix or suffix static hashedWordList getSelected ( vtkDataArraySelection* select, @@ -232,35 +187,42 @@ public: ); - //- Retrieve the current selections - static stringList getSelectedArrayEntries + //- Retrieve the currently enabled selections as hashset + static HashSet<string> getSelectedArraySet ( vtkDataArraySelection* select ); - //- Retrieve a sub-list of the current selections - static stringList getSelectedArrayEntries + //- Retrieve the currently enabled selections as id/name map + static Map<string> getSelectedArrayMap ( - vtkDataArraySelection* select, - const arrayRange& selector + vtkDataArraySelection* select ); - - //- Set selection(s) + //- Enable the selection(s) + template<class AnyValue, class AnyHasher> static void setSelectedArrayEntries ( vtkDataArraySelection* select, - const stringList& selections + const HashTable<AnyValue, string, AnyHasher>& enabled ); - //- Extract up to the first non-word characters - static word getFirstWord(const char* str); + //- Extract the first word characters after a slash + static word getFoamName(const std::string& str); + //- Simple memory used debugging information static void printMemory(); + //- Return an identity list of VTK_VERTEX + static vtkSmartPointer<vtkCellArray> identityVertices + ( + const label size + ); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // }; // End class foamPvCore diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C index e5d1353699ea5fa62a738e42b2f069b60449082f..54eeee88c09bb8d06756afcade39996a2c85f461 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C @@ -25,55 +25,28 @@ License #include "IOobjectList.H" #include "vtkDataArraySelection.h" -#include "vtkMultiBlockDataSet.h" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -template<class Type> -Type* Foam::foamPvCore::getDataFromBlock -( - vtkMultiBlockDataSet* output, - const arrayRange& selector, - const label datasetNo -) -{ - const int blockNo = selector.block(); - - vtkMultiBlockDataSet* block = - ( - datasetNo < 0 - ? nullptr - : vtkMultiBlockDataSet::SafeDownCast(output->GetBlock(blockNo)) - ); - - if (block) - { - return Type::SafeDownCast(block->GetBlock(datasetNo)); - } - - return nullptr; -} - - template<class Type> Foam::label Foam::foamPvCore::addToSelection ( vtkDataArraySelection *select, const IOobjectList& objects, - const string& suffix + const std::string& prefix ) { const wordList names = objects.sortedNames(Type::typeName); forAll(names, i) { - if (suffix.empty()) + if (prefix.empty()) { select->AddArray(names[i].c_str()); } else { - select->AddArray((names[i] + suffix).c_str()); + select->AddArray((prefix + names[i]).c_str()); } } @@ -81,4 +54,27 @@ Foam::label Foam::foamPvCore::addToSelection } +template<class AnyValue, class AnyHasher> +void Foam::foamPvCore::setSelectedArrayEntries +( + vtkDataArraySelection* select, + const HashTable<AnyValue, string, AnyHasher>& enabled +) +{ + const int n = select->GetNumberOfArrays(); + // disable everything not explicitly enabled + select->DisableAllArrays(); + + // Loop through entries, enabling as required + for (int i=0; i < n; ++i) + { + const char* arrayName = select->GetArrayName(i); + if (enabled.found(arrayName)) + { + select->EnableArray(arrayName); + } + } +} + + // ************************************************************************* // diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamVtkAdaptors.H b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamVtkAdaptors.H new file mode 100644 index 0000000000000000000000000000000000000000..89146bc8895389068b65d41b64bce9e4d295b5d5 --- /dev/null +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamVtkAdaptors.H @@ -0,0 +1,115 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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/>. + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkAdaptors_H +#define foamVtkAdaptors_H + +// OpenFOAM includes +#include "labelList.H" + +// VTK includes +#include "vtkCellArray.h" +#include "vtkIdTypeArray.h" +#include "vtkSmartPointer.h" +#include "vtkUnsignedCharArray.h" +#include "vtkAOSDataArrayTemplate.h" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + //- Attach a smart pointer, or generate a non-null one. + template<class T> + inline vtkSmartPointer<T> nonNullSmartPointer(T* ptr) + { + return vtkSmartPointer<T>(ptr ? ptr : T::New()); + } + + + //- Helper to wrap vtkUnsignedCharArray as a UList + inline UList<uint8_t> vtkUList + ( + vtkUnsignedCharArray* array, + const label size + ) + { + array->SetNumberOfComponents(1); + array->SetNumberOfTuples(size); + + UList<uint8_t> list + ( + array->WritePointer(0, size), + size + ); + + return list; + } + + + //- Helper to wrap vtkIdTypeArray as a UList + inline UList<vtkIdType> vtkUList + ( + vtkIdTypeArray* array, + const label size + ) + { + array->SetNumberOfComponents(1); + array->SetNumberOfTuples(size); + + UList<vtkIdType> list + ( + array->WritePointer(0, size), + size + ); + + return list; + } + + + //- Special helper to wrap vtkCellArray as a UList + inline UList<vtkIdType> vtkUList + ( + vtkCellArray* cells, + const label nCells, + const label size + ) + { + cells->GetData()->SetNumberOfTuples(size); + + UList<vtkIdType> list + ( + cells->WritePointer(nCells, size), + size + ); + + return list; + } +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/lagrangian/steadyParticleTracks/Make/options b/applications/utilities/postProcessing/lagrangian/steadyParticleTracks/Make/options index 004f0474b8f682bfba1ee2725cacf8198cafef9e..6898c7800d9047ca992caa070b69b84a8c02f243 100644 --- a/applications/utilities/postProcessing/lagrangian/steadyParticleTracks/Make/options +++ b/applications/utilities/postProcessing/lagrangian/steadyParticleTracks/Make/options @@ -1,5 +1,6 @@ EXE_INC = \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude diff --git a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C index 5f1c5e9a33dbc2e94e984b654889927c1cbd41a3..abdeec1c89fa66a0cc7a2bf492c60da9686dee07 100644 --- a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C +++ b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C @@ -159,12 +159,16 @@ int main(int argc, char *argv[]) if ( - !MeshedSurface<face>::canRead(importName, true) - || - ( - !optStdout - && !MeshedSurface<face>::canWriteType(exportName.ext(), true) - ) + !args.optionFound("triSurface") + && + ( + !MeshedSurface<face>::canRead(importName, true) + || + ( + !optStdout + && !MeshedSurface<face>::canWriteType(exportName.ext(), true) + ) + ) ) { return 1; diff --git a/bin/paraFoam b/bin/paraFoam index dcfe4cf1d9cf6c0e23243acd10e68097cfebf1e4..0015e73952bca7d06a7cbdb3a8fe0ec4ef9f4a5c 100755 --- a/bin/paraFoam +++ b/bin/paraFoam @@ -26,10 +26,10 @@ # paraFoam # # Description -# start paraview with the OpenFOAM libraries +# Start paraview with the OpenFOAM libraries and reader modules. # # Note -# combining -block or -builtin options with the -region option yields +# Combining -block or -builtin options with -region option yields # undefined behaviour #------------------------------------------------------------------------------ usage() { @@ -37,7 +37,7 @@ usage() { while [ "$#" -ge 1 ]; do echo "$1"; shift; done cat<<USAGE -Usage: ${0##*/} [OPTION] [PARAVIEW_OPTION] +Usage: ${0##*/} [OPTION] [--] [PARAVIEW_OPTION] options: -block use blockMesh reader (uses .blockMesh extension) -case <dir> specify alternative case directory, default is the cwd @@ -46,10 +46,10 @@ options: -touchAll create .blockMesh, .OpenFOAM files (and for all regions) -vtk | -builtin use VTK builtin OpenFOAM reader (uses .foam extension) -help print the usage + --help paraview help -Paraview options start with a double dashes. - -* start paraview with the OpenFOAM libraries +Start paraview with the OpenFOAM libraries and reader modules. +Note that paraview options begin with double dashes. paraview=$(command -v paraview) @@ -57,12 +57,9 @@ USAGE exit 1 } -# We want to do nice exit when running paraview to give paraview opportunity -# to clean up +# Do a nice exit to give paraview an opportunity to clean up unset FOAM_ABORT -unset regionName optTouch - # Hack: change all locale to 'C' i.e. using '.' for decimal point. This is # only needed temporarily until paraview is locale aware. (git version is # already 2010-07) @@ -73,18 +70,19 @@ extension=OpenFOAM plugin=PVFoamReader # Parse options +unset regionName optTouch while [ "$#" -gt 0 ] do case "$1" in -h | -help) usage ;; - -block | -blockMesh) + -block*) extension=blockMesh plugin=PVblockMeshReader shift ;; - -builtin | -vtk) + -vtk | -built*) extension=foam unset plugin shift @@ -113,6 +111,11 @@ do shift break # Stop here, treat balance as paraview options ;; + --help) # Emit paraview help directly + exec paraview "$@" + echo "Error: could not exec paraview" 1>&2 + exit 1 # This should not have happened + ;; --*) break # Stop here, treat this and balance as paraview options ;; @@ -253,6 +256,8 @@ then # Has --data=.., send directly to paraview exec paraview "$@" + echo "Error: could not exec paraview" 1>&2 + exit 1 # This should not have happened else diff --git a/etc/caseDicts/surface/surfaceFeatureExtractDict.cfg b/etc/caseDicts/surface/surfaceFeatureExtractDict.cfg index 683d8acd59648b913a43b305f5269d1d60df9384..14af1b9e48472ade3f43611e78cbd320a9489455 100644 --- a/etc/caseDicts/surface/surfaceFeatureExtractDict.cfg +++ b/etc/caseDicts/surface/surfaceFeatureExtractDict.cfg @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: plus | +| \\ / O peration | Version: plus | | \\ / A nd | Web: www.OpenFOAM.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ diff --git a/etc/config.csh/paraview b/etc/config.csh/paraview index cbc37767026f08f60796b704faa1eba8f7af9279..fa0cea0f4953c0384fb0e42af91407e241ac0df4 100644 --- a/etc/config.csh/paraview +++ b/etc/config.csh/paraview @@ -52,7 +52,7 @@ #------------------------------------------------------------------------------ # USER EDITABLE PART: Changes made here may be lost with the next upgrade -setenv ParaView_VERSION 5.3.0 +setenv ParaView_VERSION 5.4.0 setenv ParaView_MAJOR detect # Automatically determine major version set cmake_version=cmake-system diff --git a/etc/config.sh/bashcompletion b/etc/config.sh/bashcompletion index b7b919e15d5f7f4d3be431880c5bd3594b2e12c7..464fb2f1ef7c5ea5028874b67e1b5a9b593865cc 100644 --- a/etc/config.sh/bashcompletion +++ b/etc/config.sh/bashcompletion @@ -2563,8 +2563,8 @@ _of_foamToVTK() local cur="${COMP_WORDS[COMP_CWORD]}" local prev="${COMP_WORDS[COMP_CWORD-1]}" - local opts="-allPatches -ascii -constant -latestTime -nearCellValue -newTimes -noFaceZones -noFunctionObjects -noInternal -noLagrangian -noLinks -noPointValues -noZero -parallel -poly -surfaceFields -useTimeName -srcDoc -doc -help " - local optsWithArgs="-case -cellSet -decomposeParDict -excludePatches -faceSet -fields -pointSet -region -roots -time " + local opts="-allPatches -ascii -constant -latestTime -nearCellValue -newTimes -noFaceZones -noFunctionObjects -noInternal -noLagrangian -noLinks -noPointValues -noZero -parallel -poly -surfaceFields -useTimeName -xml -srcDoc -doc -help " + local optsWithArgs="-case -cellSet -decomposeParDict -excludePatches -faceSet -fields -name -pointSet -region -roots -time " case ${prev} in -case) diff --git a/etc/config.sh/paraview b/etc/config.sh/paraview index 6c66ddcc3e34405d0b013dfabec3eb4a1d475129..b2a1cc161aa7e23abba8c5d16f15a786acf373b4 100644 --- a/etc/config.sh/paraview +++ b/etc/config.sh/paraview @@ -55,7 +55,7 @@ #------------------------------------------------------------------------------ # USER EDITABLE PART: Changes made here may be lost with the next upgrade -ParaView_VERSION=5.3.0 +ParaView_VERSION=5.4.0 ParaView_MAJOR=detect # Automatically determine major version cmake_version=cmake-system diff --git a/src/conversion/Make/files b/src/conversion/Make/files index 3f2c0a0c98c7e6ccb2679829519124f5f4fadf6b..a5b3ffea227982dfd421d5a8be97c62626c2d953 100644 --- a/src/conversion/Make/files +++ b/src/conversion/Make/files @@ -24,7 +24,13 @@ starcd/STARCDMeshWriter.C polyDualMesh/polyDualMesh.C -vtk/part/foamVtkCells.C -vtk/output/foamVtkOutput.C +vtk/output/foamVtkInternalWriter.H +vtk/output/foamVtkPatchWriter.H +vtk/output/foamVtkSurfaceMeshWriter.C +vtk/output/foamVtkWriteSurfFields.C + +vtk/part/foamVtkMeshMaps.C +vtk/part/foamVtuCells.C +vtk/part/foamVtuSizing.C LIB = $(FOAM_LIBBIN)/libconversion diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.C b/src/conversion/vtk/output/foamVtkInternalWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..49bf062e8273aea0e407a27d7df3b77ccf93590f --- /dev/null +++ b/src/conversion/vtk/output/foamVtkInternalWriter.C @@ -0,0 +1,380 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkInternalWriter.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::vtk::internalWriter::beginPiece() +{ + if (!legacy_) + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, vtuCells_.nFieldPoints()) + .xmlAttr(vtk::fileAttr::NUMBER_OF_CELLS, vtuCells_.nFieldCells()) + .closeTag(); + } +} + + +void Foam::vtk::internalWriter::writePoints() +{ + // payload size + const uint64_t payLoad = (vtuCells_.nFieldPoints() * 3 * sizeof(float)); + + if (legacy_) + { + legacy::beginPoints(os_, vtuCells_.nFieldPoints()); + } + else + { + format() + .tag(vtk::fileTag::POINTS) + .openDataArray<float,3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + } + + format().writeSize(payLoad); + + vtk::writeList(format(), mesh_.points()); + vtk::writeList + ( + format(), + mesh_.cellCentres(), + vtuCells_.addPointCellLabels() + ); + + format().flush(); + + if (!legacy_) + { + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + } +} + + +void Foam::vtk::internalWriter::writeCellsLegacy() +{ + const List<uint8_t>& cellTypes = vtuCells_.cellTypes(); + const labelList& vertLabels = vtuCells_.vertLabels(); + + os_ << "CELLS " << vtuCells_.nFieldCells() << ' ' + << vertLabels.size() << nl; + + vtk::writeList(format(), vertLabels); + format().flush(); + + os_ << "CELL_TYPES " << cellTypes.size() << nl; + + // No nComponents for char, so cannot use vtk::writeList + forAll(cellTypes, i) + { + format().write(cellTypes[i]); + } + format().flush(); +} + + +void Foam::vtk::internalWriter::writeCells() +{ + format().tag(vtk::fileTag::CELLS); + + // + // 'connectivity' + // + { + const labelList& vertLabels = vtuCells_.vertLabels(); + const uint64_t payLoad = vertLabels.size() * sizeof(label); + + format().openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + format().writeSize(payLoad); + vtk::writeList(format(), vertLabels); + format().flush(); + + format().endDataArray(); + } + + + // + // 'offsets' (connectivity offsets) + // + { + const labelList& vertOffsets = vtuCells_.vertOffsets(); + const uint64_t payLoad = vertOffsets.size() * sizeof(label); + + format().openDataArray<label>(vtk::dataArrayAttr::OFFSETS) + .closeTag(); + + format().writeSize(payLoad); + vtk::writeList(format(), vertOffsets); + format().flush(); + + format().endDataArray(); + } + + + // + // 'types' (cell types) + // + { + const List<uint8_t>& cellTypes = vtuCells_.cellTypes(); + const uint64_t payLoad = cellTypes.size() * sizeof(uint8_t); + + format().openDataArray<uint8_t>(vtk::dataArrayAttr::TYPES) + .closeTag(); + + format().writeSize(payLoad); + forAll(cellTypes, i) + { + // No nComponents for char, cannot use vtk::writeList here + format().write(cellTypes[i]); + } + format().flush(); + + format().endDataArray(); + } + + + // + // can quit here if there are NO face streams + // + if (vtuCells_.faceLabels().empty()) + { + format().endTag(vtk::fileTag::CELLS); + + return; + } + + + // -------------------------------------------------- + + // + // 'faces' (face streams) + // + { + const labelList& faceLabels = vtuCells_.faceLabels(); + const uint64_t payLoad = faceLabels.size() * sizeof(label); + + format().openDataArray<label>(vtk::dataArrayAttr::FACES) + .closeTag(); + + format().writeSize(payLoad); + vtk::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 = vtuCells_.faceOffsets(); + const uint64_t payLoad = faceOffsets.size() * sizeof(label); + + format().openDataArray<label>(vtk::dataArrayAttr::FACEOFFSETS) + .closeTag(); + + format().writeSize(payLoad); + vtk::writeList(format(), faceOffsets); + format().flush(); + + format().endDataArray(); + } + + format().endTag(vtk::fileTag::CELLS); +} + + +void Foam::vtk::internalWriter::writeMesh() +{ + writePoints(); + if (legacy_) + { + writeCellsLegacy(); + } + else + { + writeCells(); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::internalWriter::internalWriter +( + const fvMesh& mesh, + const vtk::vtuCells& cells, + const fileName& baseName, + const vtk::outputOptions outOpts +) +: + mesh_(mesh), + legacy_(outOpts.legacy()), + format_(), + vtuCells_(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, vtk::fileTag::UNSTRUCTURED_GRID); + } + else + { + // XML (inline) + + format() + .xmlHeader() + .xmlComment(title) + .beginVTKFile(vtk::fileTag::UNSTRUCTURED_GRID, "0.1"); + } + + beginPiece(); + writeMesh(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::internalWriter::~internalWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +void Foam::vtk::internalWriter::beginCellData(label nFields) +{ + if (legacy_) + { + legacy::dataHeader + ( + os(), + vtk::fileTag::CELL_DATA, + vtuCells_.nFieldCells(), + nFields + ); + } + else + { + format().tag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::internalWriter::endCellData() +{ + if (!legacy_) + { + format().endTag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::internalWriter::beginPointData(label nFields) +{ + if (legacy_) + { + legacy::dataHeader + ( + os(), + vtk::fileTag::POINT_DATA, + vtuCells_.nFieldPoints(), + nFields + ); + } + else + { + format().tag(vtk::fileTag::POINT_DATA); + } +} + + +void Foam::vtk::internalWriter::endPointData() +{ + if (!legacy_) + { + format().endTag(vtk::fileTag::POINT_DATA); + } +} + + +void Foam::vtk::internalWriter::writeFooter() +{ + if (!legacy_) + { + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::UNSTRUCTURED_GRID) + .endVTKFile(); + } +} + + +void Foam::vtk::internalWriter::writeCellIDs() +{ + // Cell ids first + const labelList& cellMap = vtuCells_.cellMap(); + const uint64_t payLoad = vtuCells_.nFieldCells() * sizeof(label); + + if (legacy_) + { + os_ << "cellID 1 " << vtuCells_.nFieldCells() << " int" << nl; + } + else + { + format().openDataArray<label>("cellID") + .closeTag(); + } + + format().writeSize(payLoad); + + vtk::writeList(format(), cellMap); + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.H b/src/conversion/vtk/output/foamVtkInternalWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..7fd4aa4f5dafbcc2625254d4b253157474830940 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkInternalWriter.H @@ -0,0 +1,255 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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::internalWriter + +Description + Write fields (internal). + +SourceFiles + foamVtkInternalWriter.C + foamVtkInternalWriterTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkInternalWriter_H +#define foamVtkInternalWriter_H + +#include "OFstream.H" +#include "volFields.H" +#include "pointFields.H" + +#include "foamVtkOutputFields.H" +#include "foamVtkOutputOptions.H" +#include "foamVtuCells.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +class volPointInterpolation; + +namespace vtk +{ + +/*---------------------------------------------------------------------------*\ + Class internalWriter Declaration +\*---------------------------------------------------------------------------*/ + +class internalWriter +{ + // Private Member Data + + //- Reference to the OpenFOAM mesh (or subset) + const fvMesh& mesh_; + + //- Commonly used query + const bool legacy_; + + autoPtr<vtk::formatter> format_; + + //- The volume cells (internalMesh) + const vtuCells& vtuCells_; + + 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 + + //- Construct from components + internalWriter + ( + const fvMesh& mesh, + const vtk::vtuCells& cells, + const fileName& baseName, + const vtk::outputOptions outOpts + ); + + + //- Destructor + ~internalWriter(); + + + // Member Functions + + inline std::ofstream& os() + { + return os_; + } + + inline vtk::formatter& format() + { + 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(); + + //- Open write for PointData of count fields + // The parameters are only used for the legacy format. + void beginPointData(label nFields); + + //- Close write for PointData + void endPointData(); + + + //- Write cellIDs + void writeCellIDs(); + + //- Write file footer + void writeFooter(); + + + // Write fields (individually) + + //- Write the internal field + template<class Type> + void write(const DimensionedField<Type, volMesh>& field); + + //- Write the volume field (internal part) + template<class Type, template<class> class PatchField> + void write(const GeometricField<Type, PatchField, volMesh>& field); + + //- Write the point field + // Interpolate to originating cell centre for decomposed cells. + template<class Type, template<class> class PatchField> + void write + ( + const GeometricField<Type, PatchField, pointMesh>& field + ); + + //- Write point-interpolated internal field + template<class Type> + void write + ( + const volPointInterpolation& pInterp, + const DimensionedField<Type, volMesh>& vfield + ); + + //- Write point-interpolated volume field + template<class Type> + void write + ( + const volPointInterpolation& pInterp, + const GeometricField<Type, fvPatchField, volMesh>& vfield + ); + + + // Write fields (collectively) + + //- Write multiple internal fields + template<class Type> + void write + ( + const UPtrList + < + const DimensionedField<Type, volMesh> + >& flds + ); + + //- Write multiple volume/point fields + template<class Type, template<class> class PatchField, class GeoMesh> + void write + ( + const UPtrList + < + const GeometricField<Type, PatchField, GeoMesh> + >& flds + ); + + + //- Write multiple point-interpolated internal fields + template<class Type> + void write + ( + const volPointInterpolation& pInterp, + const UPtrList + < + const DimensionedField<Type, volMesh> + >& flds + ); + + //- Write multiple point-interpolated volume fields + template<class Type> + void write + ( + const volPointInterpolation& pInterp, + const UPtrList + < + const GeometricField<Type, fvPatchField, volMesh> + >& flds + ); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "foamVtkInternalWriterTemplates.C" +#endif + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..77689e5ec7b8d37391168db0ae145d2e91955e88 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C @@ -0,0 +1,256 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkInternalWriter.H" +#include "foamVtkOutput.H" +#include "volPointInterpolation.H" +#include "interpolatePointToCell.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +void Foam::vtk::internalWriter::write +( + const DimensionedField<Type, volMesh>& field +) +{ + const labelList& cellMap = vtuCells_.cellMap(); + + const int nCmpt(pTraits<Type>::nComponents); + // const uint64_t payLoad(cellMap.size() * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), field.name(), nCmpt, cellMap.size()); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + // writeField includes payload size, and flush + vtk::writeField(format(), field, cellMap); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type, template<class> class PatchField> +void Foam::vtk::internalWriter::write +( + const GeometricField<Type, PatchField, volMesh>& field +) +{ + write(field.internalField()); +} + + +template<class Type, template<class> class PatchField> +void Foam::vtk::internalWriter::write +( + const GeometricField<Type, PatchField, pointMesh>& field +) +{ + const labelList& addPointCellLabels = vtuCells_.addPointCellLabels(); + + const int nCmpt(pTraits<Type>::nComponents); + const label nVals(vtuCells_.nFieldPoints()); + + // Only needed for non-legacy + const uint64_t payLoad(nVals * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), field.name(), nCmpt, nVals); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + format().writeSize(payLoad); + vtk::writeList(format(), field); + + for (const label cellId : addPointCellLabels) + { + const Type val = interpolatePointToCell(field, cellId); + vtk::write(format(), val); + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type> +void Foam::vtk::internalWriter::write +( + const volPointInterpolation& pInterp, + const DimensionedField<Type, volMesh>& vfield +) +{ + typedef DimensionedField<Type, pointMesh> PointFieldType; + + // Use tmp intermediate. Compiler sometimes weird otherwise. + tmp<PointFieldType> tfield = pInterp.interpolate(vfield); + const PointFieldType& pfield = tfield(); + + const labelList& addPointCellLabels = vtuCells_.addPointCellLabels(); + + const int nCmpt(pTraits<Type>::nComponents); + const label nVals(vtuCells_.nFieldPoints()); + + // Only needed for non-legacy + const uint64_t payLoad(nVals * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), vfield.name(), nCmpt, nVals); + } + else + { + format().openDataArray<float, nCmpt>(vfield.name()) + .closeTag(); + } + + format().writeSize(payLoad); + vtk::writeList(format(), pfield); + vtk::writeList(format(), vfield, addPointCellLabels); + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type> +void Foam::vtk::internalWriter::write +( + const volPointInterpolation& pInterp, + const GeometricField<Type, fvPatchField, volMesh>& vfield +) +{ + typedef GeometricField<Type, pointPatchField, pointMesh> PointFieldType; + + // Use tmp intermediate. Compiler sometimes weird otherwise. + tmp<PointFieldType> tfield = pInterp.interpolate(vfield); + const PointFieldType& pfield = tfield(); + + const labelList& addPointCellLabels = vtuCells_.addPointCellLabels(); + + const int nCmpt(pTraits<Type>::nComponents); + const label nVals(vtuCells_.nFieldPoints()); + + // Only needed for non-legacy + const uint64_t payLoad(nVals * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), vfield.name(), nCmpt, nVals); + } + else + { + format().openDataArray<float, nCmpt>(vfield.name()) + .closeTag(); + } + + format().writeSize(payLoad); + vtk::writeList(format(), pfield); + vtk::writeList(format(), vfield, addPointCellLabels); + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type> +void Foam::vtk::internalWriter::write +( + const UPtrList<const DimensionedField<Type, volMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(field); + } +} + + +template<class Type, template<class> class PatchField, class GeoMesh> +void Foam::vtk::internalWriter::write +( + const UPtrList<const GeometricField<Type, PatchField, GeoMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(field); + } +} + + +template<class Type> +void Foam::vtk::internalWriter::write +( + const volPointInterpolation& pInterp, + const UPtrList<const DimensionedField<Type, volMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(pInterp, field); + } +} + + +template<class Type> +void Foam::vtk::internalWriter::write +( + const volPointInterpolation& pInterp, + const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(pInterp, field); + } +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkOutput.C b/src/conversion/vtk/output/foamVtkOutput.C deleted file mode 100644 index fc2d29884189feb9a38640cb1c92a0ee61e950b2..0000000000000000000000000000000000000000 --- a/src/conversion/vtk/output/foamVtkOutput.C +++ /dev/null @@ -1,119 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 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 "foamVtkOutput.H" -#include "foamVtkAsciiFormatter.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -const Foam::word Foam::foamVtkOutput::legacy::EXT = "vtk"; - - -//! \cond fileScope -static inline std::ostream& legacyDataHeader -( - std::ostream& os, - const char* tag, - const Foam::label nItems, - const Foam::label nFields -) -{ - os << tag << ' ' << nItems << '\n' - << "FIELD attributes " << nFields << '\n'; - - return os; -} -//! \endcond - - -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -Foam::label Foam::foamVtkOutput::writeVtmFile -( - std::ostream& os, - const UList<fileName>& files -) -{ - const word& content = "vtkMultiBlockDataSet"; - - foamVtkAsciiFormatter vtmFile(os); - - vtmFile - .xmlHeader() - .beginVTKFile(content, "1.0"); - - forAll(files, i) - { - vtmFile - .openTag("DataSet") - ( "index", i ) - ( "file", files[i] ) - .closeTag(true); - } - - vtmFile.endTag(content).endVTKFile(); - - return files.size(); -} - - -std::ostream& Foam::foamVtkOutput::legacy::writeHeader -( - 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; -} - - -std::ostream& Foam::foamVtkOutput::legacy::writeCellDataHeader -( - std::ostream& os, - const label nCells, - const label nFields -) -{ - return legacyDataHeader(os, "CELL_DATA", nCells, nFields); -} - - -std::ostream& Foam::foamVtkOutput::legacy::writePointDataHeader -( - std::ostream& os, - const label nPoints, - const label nFields -) -{ - return legacyDataHeader(os, "POINT_DATA", nPoints, nFields); -} - - -// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkOutput.H b/src/conversion/vtk/output/foamVtkOutput.H deleted file mode 100644 index f0897d6675ca1658d6287ac3f1a98f7b260d14aa..0000000000000000000000000000000000000000 --- a/src/conversion/vtk/output/foamVtkOutput.H +++ /dev/null @@ -1,222 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016 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 - foamVtkOutput - -Description - A collection of functions for writing vtk file content. - -SourceFiles - foamVtkOutput.C - foamVtkOutputTemplates.C - -\*---------------------------------------------------------------------------*/ - -#ifndef foamVtkOutput_H -#define foamVtkOutput_H - -#include "floatScalar.H" -#include "volFields.H" -#include "foamVtkFormatter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class foamVtkOutput Declaration -\*---------------------------------------------------------------------------*/ - -class foamVtkOutput -{ - // Private Member Functions - - //- Disallow construction - foamVtkOutput() = delete; - -public: - - // Public typedefs - - //- Use UInt64 for header data - typedef foamVtkFormatter::headerType headerType; - - - // Forward declarations - class legacy; - - - // Static Members - - //- Write vtm datasets for specified files - static Foam::label writeVtmFile - ( - std::ostream& os, - const UList<fileName>& files - ); - - - //- Write a value component-wise. - template<class Type> - inline static void write(foamVtkFormatter&, const Type&); - - - //- Write a list of values. - // The output does not include the payload size. - template<class Type> - static void writeList - ( - foamVtkFormatter&, - const UList<Type>& - ); - - - //- Write a list of values via indirect addressing. - // The output does not include the payload size. - template<class Type> - static void writeList - ( - foamVtkFormatter&, - const UList<Type>&, - const UList<label>& addressing - ); - - - //- Write volField with cell values (including decomposed cells). - // The output includes the payload size and flush. - template<class Type> - static void writeField - ( - foamVtkFormatter&, - const GeometricField<Type, fvPatchField, volMesh>&, - const UList<label>& superCells - ); - -}; - - -/*---------------------------------------------------------------------------*\ - Class foamVtkOutput::legacy Declaration -\*---------------------------------------------------------------------------*/ - -//- Basic support for legacy files -class foamVtkOutput::legacy -{ - // Private Member Functions - - //- Disallow construction - legacy() = delete; - -public: - - // Static data members - - //- file extension for legacy files (vtk) - static const Foam::word EXT; - - - // Static Members - - //- Emit header for legacy file - static std::ostream& writeHeader - ( - std::ostream&, - const std::string& title, - const bool binary = false - ); - - - //- Emit header for legacy CELL_DATA - static std::ostream& writeCellDataHeader - ( - std::ostream& os, - const label nCells, - const label nFields - ); - - - //- Emit header for legacy POINT_DATA - static std::ostream& writePointDataHeader - ( - std::ostream& os, - const label nPoints, - const label nFields - ); - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - - -//- Template specialization for label -template<> -inline void Foam::foamVtkOutput::write<label> -( - foamVtkFormatter& fmt, - const label& val -) -{ - fmt.write(val); -} - - -//- Template specialization for float -template<> -inline void Foam::foamVtkOutput::write<float> -( - foamVtkFormatter& fmt, - const float& val -) -{ - fmt.write(val); -} - - -//- Template specialization for double -template<> -inline void Foam::foamVtkOutput::write<double> -( - foamVtkFormatter& fmt, - const double& val -) -{ - fmt.write(val); -} - -} // End namespace Foam - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#ifdef NoRepository - #include "foamVtkOutputTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkOutputFields.H b/src/conversion/vtk/output/foamVtkOutputFields.H new file mode 100644 index 0000000000000000000000000000000000000000..116aadbfeb18d24b860d67b8ff3dcff96cc6bcd6 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkOutputFields.H @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2107 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/>. + +InNamespace + Foam::vtk + +Description + Additional functions for writing fields in VTK format. + +SourceFiles + foamVtkOutputFieldsTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkOutputFields_H +#define foamVtkOutputFields_H + +#include "foamVtkOutput.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace vtk +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + //- Write DimensionedField for mesh + // The output includes the payload size and flush. + template<class Type> + void writeField + ( + vtk::formatter& fmt, + const DimensionedField<Type, volMesh>& fld + ); + + //- Write DimensionedField based on the cellMap + // The output includes the payload size and flush. + template<class Type> + void writeField + ( + vtk::formatter& fmt, + const DimensionedField<Type, volMesh>& fld, + const UList<label>& cellMap + ); + + //- Write internalField for mesh + // The output includes the payload size and flush. + template<class Type> + void writeField + ( + vtk::formatter& fmt, + const GeometricField<Type, fvPatchField, volMesh>& fld + ); + + //- Write internalField based on the cellMap + // The output includes the payload size and flush. + template<class Type> + void writeField + ( + vtk::formatter& fmt, + const GeometricField<Type, fvPatchField, volMesh>& fld, + const UList<label>& cellMap + ); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "foamVtkOutputFieldsTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C b/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..b462922416f9e86b88cf2b5fdd3de074b3b05b41 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkOutputFieldsTemplates.C @@ -0,0 +1,107 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2107 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +template<class Type> +void Foam::vtk::writeField +( + vtk::formatter& fmt, + const DimensionedField<Type, volMesh>& fld +) +{ + const uint64_t payLoad = + ( + fld.size() * pTraits<Type>::nComponents * sizeof(float) + ); + + fmt.writeSize(payLoad); + writeList(fmt, fld); + + fmt.flush(); +} + + +template<class Type> +void Foam::vtk::writeField +( + vtk::formatter& fmt, + const DimensionedField<Type, volMesh>& fld, + const UList<label>& cellMap +) +{ + const uint64_t payLoad = + ( + cellMap.size() * pTraits<Type>::nComponents * sizeof(float) + ); + + fmt.writeSize(payLoad); + writeList(fmt, fld, cellMap); + + fmt.flush(); +} + + +template<class Type> +void Foam::vtk::writeField +( + vtk::formatter& fmt, + const GeometricField<Type, fvPatchField, volMesh>& fld +) +{ + const uint64_t payLoad = + ( + fld.size() * pTraits<Type>::nComponents * sizeof(float) + ); + + fmt.writeSize(payLoad); + writeList(fmt, fld.internalField()); + + fmt.flush(); +} + + +template<class Type> +void Foam::vtk::writeField +( + vtk::formatter& fmt, + const GeometricField<Type, fvPatchField, volMesh>& fld, + const UList<label>& cellMap +) +{ + const uint64_t payLoad = + ( + cellMap.size() * pTraits<Type>::nComponents * sizeof(float) + ); + + fmt.writeSize(payLoad); + writeList(fmt, fld.internalField(), cellMap); + + fmt.flush(); +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.C b/src/conversion/vtk/output/foamVtkPatchWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..fcbe032cfd25baef27eacd90e8145d1d4230614b --- /dev/null +++ b/src/conversion/vtk/output/foamVtkPatchWriter.C @@ -0,0 +1,404 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkPatchWriter.H" +#include "foamVtkOutput.H" + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::vtk::patchWriter::beginPiece() +{ + if (!legacy_) + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, nPoints_) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POLYS, nFaces_) + .closeTag(); + } +} + + +void Foam::vtk::patchWriter::writePoints() +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + const uint64_t payLoad = (nPoints_*3*sizeof(float)); + + if (legacy_) + { + legacy::beginPoints(os_, nPoints_); + } + else + { + format().tag(vtk::fileTag::POINTS) + .openDataArray<float, 3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + } + + format().writeSize(payLoad); + + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + vtk::writeList(format(), pp.localPoints()); + } + format().flush(); + + if (!legacy_) + { + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + } +} + + +void Foam::vtk::patchWriter::writePolysLegacy() +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + // connectivity count without additional storage (done internally) + uint64_t nConnectivity = 0; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + 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; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + 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::vtk::patchWriter::writePolys() +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + // + // 'connectivity' + // + + format().tag(vtk::fileTag::POLYS); + + // + // 'connectivity' + // + { + // payload count + uint64_t payLoad = 0; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + forAll(pp, facei) + { + payLoad += pp[facei].size(); + } + } + + format().openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + // payload size + format().writeSize(payLoad * sizeof(label)); + + label off = 0; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + 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>(vtk::dataArrayAttr::OFFSETS) + .closeTag(); + + // payload size + format().writeSize(nFaces_ * sizeof(label)); + + label off = 0; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + forAll(pp, facei) + { + off += pp[facei].size(); + + format().write(off); + } + } + + format().flush(); + format().endDataArray(); + } + + format().endTag(vtk::fileTag::POLYS); +} + + +void Foam::vtk::patchWriter::writeMesh() +{ + writePoints(); + if (legacy_) + { + writePolysLegacy(); + } + else + { + writePolys(); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::patchWriter::patchWriter +( + const fvMesh& mesh, + const fileName& baseName, + const vtk::outputOptions outOpts, + const bool nearCellValue, + const labelList& patchIDs +) +: + mesh_(mesh), + legacy_(outOpts.legacy()), + format_(), + nearCellValue_(nearCellValue), + patchIDs_(patchIDs), + os_(), + nPoints_(0), + nFaces_(0) +{ + outputOptions opts(outOpts); + opts.append(false); // No append + + os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + format_ = opts.newFormatter(os_); + + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + const word& title = + ( + patchIDs_.size() == 1 + ? patches[patchIDs_.first()].name() + : "patches" + ); + + // Basic sizes + nPoints_ = nFaces_ = 0; + for (const label patchId : patchIDs_) + { + const polyPatch& pp = patches[patchId]; + + nPoints_ += pp.nPoints(); + nFaces_ += pp.size(); + } + + + if (legacy_) + { + legacy::fileHeader(format(), title, vtk::fileTag::POLY_DATA); + } + else + { + // XML (inline) + + format() + .xmlHeader() + .xmlComment(title) + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + } + + beginPiece(); + writeMesh(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::patchWriter::~patchWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::patchWriter::beginCellData(label nFields) +{ + if (legacy_) + { + legacy::dataHeader + ( + os(), + vtk::fileTag::CELL_DATA, + nFaces_, + nFields + ); + } + else + { + format().tag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::patchWriter::endCellData() +{ + if (!legacy_) + { + format().endTag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::patchWriter::beginPointData(label nFields) +{ + if (legacy_) + { + legacy::dataHeader + ( + os(), + vtk::fileTag::POINT_DATA, + nPoints_, + nFields + ); + } + else + { + format().tag(vtk::fileTag::POINT_DATA); + } +} + + +void Foam::vtk::patchWriter::endPointData() +{ + if (!legacy_) + { + format().endTag(vtk::fileTag::POINT_DATA); + } +} + + +void Foam::vtk::patchWriter::writeFooter() +{ + if (!legacy_) + { + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); + } +} + + +void Foam::vtk::patchWriter::writePatchIDs() +{ + // 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); + + for (const label patchId : patchIDs_) + { + const label sz = mesh_.boundaryMesh()[patchId].size(); + + for (label facei = 0; facei < sz; ++facei) + { + format().write(patchId); + } + } + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.H b/src/conversion/vtk/output/foamVtkPatchWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..627b84788210de52f8f06eca2580a9332bf52349 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkPatchWriter.H @@ -0,0 +1,230 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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::patchWriter + +Description + Write patch fields + +SourceFiles + foamVtkPatchWriter.C + foamVtkPatchWriterTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkPatchWriter_H +#define foamVtkPatchWriter_H + +#include "pointMesh.H" +#include "OFstream.H" +#include "volFields.H" +#include "pointFields.H" +#include "indirectPrimitivePatch.H" +#include "PrimitivePatchInterpolation.H" +#include "foamVtkOutputOptions.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +class volPointInterpolation; + +namespace vtk +{ + +/*---------------------------------------------------------------------------*\ + Class patchWriter Declaration +\*---------------------------------------------------------------------------*/ + +class patchWriter +{ + // Private Member Data + + //- Reference to the OpenFOAM mesh (or subset) + const fvMesh& mesh_; + + //- Commonly used query + const bool legacy_; + + autoPtr<vtk::formatter> format_; + + const bool nearCellValue_; + + 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; + + +public: + + // Constructors + + //- Construct from components + patchWriter + ( + const fvMesh& mesh, + const fileName& baseName, + const vtk::outputOptions outOpts, + const bool nearCellValue, + const labelList& patchIDs + ); + + + //- Destructor + ~patchWriter(); + + + // Member Functions + + inline std::ofstream& os() + { + return os_; + } + + inline vtk::formatter& format() + { + return format_(); + } + + inline label nPoints() const + { + return nPoints_; + } + + inline label nFaces() const + { + return nFaces_; + } + + //- 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(); + + //- Open write for PointData of count fields + // The parameters are only used for the legacy format. + void beginPointData(label nFields); + + //- Close write for PointData + void endPointData(); + + //- Write cellIDs + void writePatchIDs(); + + //- Write file footer + void writeFooter(); + + + // Write fields (individually) + + //- Write volume field + template<class Type, template<class> class PatchField> + void write(const GeometricField<Type, PatchField, volMesh>& field); + + //- Write point fields + template<class Type, template<class> class PatchField> + void write(const GeometricField<Type, PatchField, pointMesh>& field); + + //- Write point-interpolated volume field + template<class Type> + void write + ( + const PrimitivePatchInterpolation<primitivePatch>& pInterp, + const GeometricField<Type, fvPatchField, volMesh>& field + ); + + + // Write fields (collectively) + + //- Write multiple volume/point fields + template<class Type, template<class> class PatchField, class GeoMesh> + void write + ( + const UPtrList + < + const GeometricField<Type, PatchField, GeoMesh> + >& flds + ); + + //- Write multiple point-interpolated volume fields + template<class Type> + void write + ( + const PrimitivePatchInterpolation<primitivePatch>& pInterp, + const UPtrList + < + const GeometricField<Type, fvPatchField, volMesh> + >& flds + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "foamVtkPatchWriterTemplates.C" +#endif + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C b/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..9c77912499fce907fe916f401ee10ae7b1fe4ab7 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkPatchWriterTemplates.C @@ -0,0 +1,189 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkPatchWriter.H" +#include "foamVtkOutput.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type, template<class> class PatchField> +void Foam::vtk::patchWriter::write +( + const GeometricField<Type, PatchField, volMesh>& field +) +{ + const int nCmpt(pTraits<Type>::nComponents); + const uint64_t payLoad(nFaces_ * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os_, field.name(), nCmpt, nFaces_); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + format().writeSize(payLoad); + + for (const label patchId : patchIDs_) + { + const auto& pfld = field.boundaryField()[patchId]; + + if (nearCellValue_) + { + vtk::writeList(format(), pfld.patchInternalField()()); + } + else + { + vtk::writeList(format(), pfld); + } + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type, template<class> class PatchField> +void Foam::vtk::patchWriter::write +( + const GeometricField<Type, PatchField, pointMesh>& field +) +{ + const int nCmpt(pTraits<Type>::nComponents); + const uint64_t payLoad(nPoints_ * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os_, field.name(), nCmpt, nPoints_); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + format().writeSize(payLoad); + + for (const label patchId : patchIDs_) + { + const auto& pfld = field.boundaryField()[patchId]; + + vtk::writeList(format(), pfld.patchInternalField()()); + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type> +void Foam::vtk::patchWriter::write +( + const PrimitivePatchInterpolation<primitivePatch>& pInter, + const GeometricField<Type, fvPatchField, volMesh>& field +) +{ + const int nCmpt(pTraits<Type>::nComponents); + const uint64_t payLoad(nPoints_ * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os_, field.name(), nCmpt, nPoints_); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + format().writeSize(payLoad); + + for (const label patchId : patchIDs_) + { + const auto& pfld = field.boundaryField()[patchId]; + + if (nearCellValue_) + { + auto tfield = + pInter.faceToPointInterpolate(pfld.patchInternalField()()); + + vtk::writeList(format(), tfield()); + } + else + { + auto tfield = pInter.faceToPointInterpolate(pfld); + + vtk::writeList(format(), tfield()); + } + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type, template<class> class PatchField, class GeoMesh> +void Foam::vtk::patchWriter::write +( + const UPtrList<const GeometricField<Type, PatchField, GeoMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(field); + } +} + + +template<class Type> +void Foam::vtk::patchWriter::write +( + const PrimitivePatchInterpolation<primitivePatch>& pInter, + const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds +) +{ + for (const auto& field : flds) + { + write(pInter, field); + } +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..df54f039cda22b571fb51747c7222a90f4520993 --- /dev/null +++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.C @@ -0,0 +1,264 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkSurfaceMeshWriter.H" +#include "foamVtkOutput.H" + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::vtk::surfaceMeshWriter::beginPiece() +{ + if (!legacy_) + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, pp_.nPoints()) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POLYS, pp_.size()) + .closeTag(); + } +} + + +void Foam::vtk::surfaceMeshWriter::writePoints() +{ + const uint64_t payLoad = (pp_.nPoints()*3*sizeof(float)); + + if (legacy_) + { + legacy::beginPoints(os_, pp_.nPoints()); + } + else + { + format().tag(vtk::fileTag::POINTS) + .openDataArray<float, 3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + } + + format().writeSize(payLoad); + + vtk::writeList(format(), pp_.localPoints()); + format().flush(); + + if (!legacy_) + { + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + } +} + + +void Foam::vtk::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 + vtk::writeList(format(), f); + } + + format().flush(); +} + + +void Foam::vtk::surfaceMeshWriter::writePolys() +{ + // + // 'connectivity' + // + + format().tag(vtk::fileTag::POLYS); + + // + // 'connectivity' + // + { + // payload count + uint64_t payLoad = 0; + forAll(pp_, facei) + { + payLoad += pp_[facei].size(); + } + + format().openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + // payload size + format().writeSize(payLoad * sizeof(label)); + + forAll(pp_, facei) + { + const face& f = pp_.localFaces()[facei]; + vtk::writeList(format(), f); + } + + format().flush(); + + format() + .endDataArray(); + } + + + // + // 'offsets' (connectivity offsets) + // + { + format() + .openDataArray<label>(vtk::dataArrayAttr::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(vtk::fileTag::POLYS); +} + + +void Foam::vtk::surfaceMeshWriter::writeMesh() +{ + writePoints(); + if (legacy_) + { + writePolysLegacy(); + } + else + { + writePolys(); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::surfaceMeshWriter::surfaceMeshWriter +( + const indirectPrimitivePatch& pp, + const word& name, + const fileName& baseName, + const vtk::outputOptions outOpts +) +: + pp_(pp), + legacy_(outOpts.legacy()), + format_(), + os_() +{ + outputOptions opts(outOpts); + opts.legacy(true); // No append supported + + os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + format_ = opts.newFormatter(os_); + + if (legacy_) + { + legacy::fileHeader(format(), name, vtk::fileTag::POLY_DATA); + } + else + { + // XML (inline) + + format() + .xmlHeader() + .xmlComment(name) + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + + } + + beginPiece(); + writeMesh(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::surfaceMeshWriter::~surfaceMeshWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::surfaceMeshWriter::beginCellData(label nFields) +{ + if (legacy_) + { + legacy::dataHeader(os(), vtk::fileTag::CELL_DATA, pp_.size(), nFields); + } + else + { + format().tag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::surfaceMeshWriter::endCellData() +{ + if (!legacy_) + { + format().endTag(vtk::fileTag::CELL_DATA); + } +} + + +void Foam::vtk::surfaceMeshWriter::writeFooter() +{ + if (!legacy_) + { + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H similarity index 57% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H rename to src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H index 0a5589c26e7edbe6866388d9bb55936b45d02d37..bf5de51327b169a3c16847ba095683a739482bb0 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H +++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -22,47 +22,77 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::surfaceMeshWriter + Foam::vtk::surfaceMeshWriter Description Write faces with fields SourceFiles - surfaceMeshWriter.C - surfaceMeshWriterTemplates.C + foamVtkSurfaceMeshWriter.C + foamVtkSurfaceMeshWriterTemplates.C \*---------------------------------------------------------------------------*/ -#ifndef surfaceMeshWriter_H -#define surfaceMeshWriter_H +#ifndef foamVtkSurfaceMeshWriter_H +#define foamVtkSurfaceMeshWriter_H #include "pointMesh.H" #include "OFstream.H" #include "volFields.H" #include "surfaceFields.H" #include "indirectPrimitivePatch.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { - class volPointInterpolation; +namespace vtk +{ + /*---------------------------------------------------------------------------*\ Class surfaceMeshWriter Declaration \*---------------------------------------------------------------------------*/ class surfaceMeshWriter { - const bool binary_; + // Private Member Data + + const indirectPrimitivePatch& pp_; + + //- Commonly used query + const bool legacy_; + + autoPtr<vtk::formatter> format_; + + std::ofstream os_; + - const indirectPrimitivePatch& pp_; + // Private Member Functions - const fileName fName_; + //- Begin piece + void beginPiece(); - std::ofstream os_; + //- 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: @@ -71,47 +101,81 @@ public: //- Construct from components surfaceMeshWriter ( - const bool binary, const indirectPrimitivePatch& pp, const word& name, - const fileName& + const fileName& baseName, + const vtk::outputOptions outOpts ); + //- Destructor + ~surfaceMeshWriter(); + + // Member Functions - std::ofstream& os() + inline std::ofstream& os() { return os_; } - //- Extract face data + inline vtk::formatter& format() + { + 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(); + + + //- Get face field (internal face or boundary face) template<class Type> tmp<Field<Type>> getFaceField ( - const GeometricField<Type, fvsPatchField, surfaceMesh>& + const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld ) const; - //- Write surfaceFields + + // Write fields (individually) + + //- Write surface field + template<class Type> + void write + ( + const GeometricField<Type, fvsPatchField, surfaceMesh>& field + ); + + + // Write fields (collectively) + + //- Write surface fields template<class Type> void write ( const UPtrList < const GeometricField<Type, fvsPatchField, surfaceMesh> - >& + >& sflds ); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "surfaceMeshWriterTemplates.C" + #include "foamVtkSurfaceMeshWriterTemplates.C" #endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C b/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C similarity index 65% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C rename to src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C index 92d878f2292b534fe915f2c5e8bae4ed2056fff2..1b459b3bd9626b616669276d1843d7670da733f4 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C +++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriterTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,14 +23,13 @@ License \*---------------------------------------------------------------------------*/ -#include "surfaceMeshWriter.H" -#include "writeFuns.H" +#include "foamVtkSurfaceMeshWriter.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class Type> Foam::tmp<Foam::Field<Type>> -Foam::surfaceMeshWriter::getFaceField +Foam::vtk::surfaceMeshWriter::getFaceField ( const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld ) const @@ -42,9 +41,8 @@ Foam::surfaceMeshWriter::getFaceField forAll(pp_.addressing(), i) { - label facei = pp_.addressing()[i]; - - label patchi = patches.whichPatch(facei); + const label facei = pp_.addressing()[i]; + const label patchi = patches.whichPatch(facei); if (patchi == -1) { @@ -52,7 +50,7 @@ Foam::surfaceMeshWriter::getFaceField } else { - label localFacei = facei - patches[patchi].start(); + const label localFacei = facei - patches[patchi].start(); fld[i] = sfld.boundaryField()[patchi][localFacei]; } } @@ -62,7 +60,38 @@ Foam::surfaceMeshWriter::getFaceField template<class Type> -void Foam::surfaceMeshWriter::write +void Foam::vtk::surfaceMeshWriter::write +( + const GeometricField<Type, fvsPatchField, surfaceMesh>& field +) +{ + const int nCmpt(pTraits<Type>::nComponents); + const uint64_t payLoad(pp_.size() * nCmpt * sizeof(float)); + + if (legacy_) + { + legacy::floatField(os(), field.name(), nCmpt, pp_.size()); + } + else + { + format().openDataArray<float, nCmpt>(field.name()) + .closeTag(); + } + + format().writeSize(payLoad); + vtk::writeList(format(), getFaceField(field)()); + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } +} + + +template<class Type> +void Foam::vtk::surfaceMeshWriter::write ( const UPtrList < @@ -70,18 +99,9 @@ void Foam::surfaceMeshWriter::write >& sflds ) { - forAll(sflds, fieldi) + for (const auto& field : sflds) { - const GeometricField<Type, fvsPatchField, surfaceMesh>& fld = - sflds[fieldi]; - - os_ << fld.name() << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << pp_.size() << " float" << std::endl; - - DynamicList<floatScalar> fField(pTraits<Type>::nComponents*pp_.size()); - writeFuns::insert(getFaceField(fld)(), fField); - writeFuns::write(os_, binary_, fField); + write(field); } } diff --git a/src/conversion/vtk/output/foamVtkWriteSurfFields.C b/src/conversion/vtk/output/foamVtkWriteSurfFields.C new file mode 100644 index 0000000000000000000000000000000000000000..40c99456a1c6bd0bf4df0184966afb643f5a4f1e --- /dev/null +++ b/src/conversion/vtk/output/foamVtkWriteSurfFields.C @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkWriteSurfFields.H" +#include "OFstream.H" +#include "emptyFvsPatchFields.H" +#include "fvsPatchFields.H" +#include "surfaceFields.H" +#include "foamVtkOutput.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void Foam::vtk::writeSurfFields +( + const fvMesh& mesh, + const fileName& baseName, + const vtk::outputOptions outOpts, + const UPtrList<const surfaceVectorField>& surfVectorFields +) +{ + outputOptions opts(outOpts); + opts.append(false); // No append supported + + const bool legacy_(opts.legacy()); + + std::ofstream os((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + autoPtr<vtk::formatter> format = opts.newFormatter(os); + + // Same payload size for points and vector fields! + const int nCmpt(3); // vector + const uint64_t payLoad(mesh.nFaces() * 3 * sizeof(float)); + + if (legacy_) + { + legacy::fileHeader(format(), "surfaceFields", vtk::fileTag::POLY_DATA); + legacy::beginPoints(os, mesh.nFaces()); + } + else + { + // XML (inline) + + format() + .xmlHeader() + .xmlComment("surfaceFields") + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + + // Tricky - hide in beginPiece() + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, mesh.nFaces()) + .closeTag(); + + format().tag(vtk::fileTag::POINTS) + .openDataArray<float,3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + } + + const pointField& fc = mesh.faceCentres(); + + format().writeSize(payLoad); + vtk::writeList(format(), fc); + format().flush(); + + if (!legacy_) + { + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + } + + + // Fields + if (legacy_) + { + legacy::dataHeader + ( + os, + vtk::fileTag::POINT_DATA, + mesh.nFaces(), + surfVectorFields.size() + ); + } + else + { + format().tag(vtk::fileTag::POINT_DATA); + } + + // surfVectorFields + forAll(surfVectorFields, fieldi) + { + const auto& fld = surfVectorFields[fieldi]; + + if (legacy_) + { + legacy::floatField(os, fld.name(), nCmpt, mesh.nFaces()); + } + else + { + format().openDataArray<float, nCmpt>(fld.name()) + .closeTag(); + } + + format().writeSize(payLoad); + + for (label facei=0; facei < mesh.nInternalFaces(); ++facei) + { + vtk::write(format(), fld[facei]); + } + + forAll(fld.boundaryField(), patchi) + { + const fvPatch& pp = mesh.boundary()[patchi]; + const auto& pf = fld.boundaryField()[patchi]; + + if (isA<emptyFvsPatchVectorField>(pf)) + { + // Note: loop over polypatch size, not fvpatch size. + forAll(pp.patch(), i) + { + vtk::write(format(), vector::zero); + } + } + else + { + vtk::writeList(format(), pf); + } + } + + format().flush(); + + if (!legacy_) + { + format().endDataArray(); + } + } + + if (!legacy_) + { + format().endTag(vtk::fileTag::POINT_DATA); + + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H b/src/conversion/vtk/output/foamVtkWriteSurfFields.H similarity index 82% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H rename to src/conversion/vtk/output/foamVtkWriteSurfFields.H index 7740e15f78f48c3817ebfca37e8ab65b17eb3f44..ff7e77b00fd3886fe5f60a2e12b44c24ae523743 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H +++ b/src/conversion/vtk/output/foamVtkWriteSurfFields.H @@ -21,38 +21,42 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -InClass - Foam::writeSurfFields +InNamespace + Foam::vtk Description - Write a patch with its data. + Write surface fields as vectors SourceFiles - writeSurfFields.C + foamVtkWriteSurfFields.C \*---------------------------------------------------------------------------*/ -#ifndef writeSurfFields_H -#define writeSurfFields_H +#ifndef foamVtkWriteSurfFields_H +#define foamVtkWriteSurfFields_H #include "fvMesh.H" #include "surfaceMesh.H" #include "surfaceFieldsFwd.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +namespace vtk +{ -// Write surface vector fields +//- Write surface vector fields void writeSurfFields ( - const bool binary, - const fvMesh&, - const fileName& fileName, + const fvMesh& mesh, + const fileName& baseName, + const vtk::outputOptions outOpts, const UPtrList<const surfaceVectorField>& surfVectorFields ); +} // End namespace vtk } // End namespace Foam diff --git a/src/conversion/vtk/part/foamVtkCells.C b/src/conversion/vtk/part/foamVtkCells.C deleted file mode 100644 index 5846c8442d705359cd54460ce2668b80ca091588..0000000000000000000000000000000000000000 --- a/src/conversion/vtk/part/foamVtkCells.C +++ /dev/null @@ -1,649 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 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 "foamVtkCells.H" -#include "polyMesh.H" -#include "cellShape.H" -#include "cellModeller.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -void Foam::foamVtkCells::correct() -{ - // Clear derived data - // clearGeom(); - - const cellModel& tet = *(cellModeller::lookup("tet")); - const cellModel& pyr = *(cellModeller::lookup("pyr")); - const cellModel& prism = *(cellModeller::lookup("prism")); - const cellModel& wedge = *(cellModeller::lookup("wedge")); - const cellModel& tetWedge = *(cellModeller::lookup("tetWedge")); - const cellModel& hex = *(cellModeller::lookup("hex")); - - const cellShapeList& cellShapes = mesh_.cellShapes(); - - // face owner is needed to determine the face orientation - const labelList& owner = mesh_.faceOwner(); - - // Unique vertex labels per polyhedral - HashSet<label> hashUniqId(2*256); - - // ======================= - // PASS 1: Determine sizes - - label nVertLabels = 0; - label nFaceLabels = 0; - label nAddPoints = 0; - label nAddCells = 0; - label nAddVerts = 0; - - forAll(cellShapes, cellI) - { - const cellShape& shape = cellShapes[cellI]; - const cellModel& model = shape.model(); - - if - ( - model == tet - || model == pyr - || model == prism - || model == hex - ) - { - // normal primitives - nVertLabels += shape.size(); - } - else if (model == tetWedge && decompose_.requested()) - { - // Treat as squeezed prism (VTK_WEDGE) - nVertLabels += 6; - } - else if (model == wedge && decompose_.requested()) - { - // Treat as squeezed hex - nVertLabels += 8; - } - else if (decompose_.requested()) - { - // Polyhedral: Decompose into tets + pyramids. - - // Count vertices in first decomposed cell - bool first = true; - - const cell& cFaces = mesh_.cells()[cellI]; - forAll(cFaces, cFaceI) - { - const face& f = mesh_.faces()[cFaces[cFaceI]]; - - // Face decomposed into triangles and quads - // Tri -> Tet, Quad -> Pyr - label nTria = 0, nQuad = 0; - f.nTrianglesQuads(mesh_.points(), nTria, nQuad); - - nAddCells += nTria + nQuad; - nAddVerts += (nTria * 4) + (nQuad * 5); - - if (first) - { - const label nvrt = (nQuad ? 5 : 4); - nAddCells--; - nAddVerts -= nvrt; - nVertLabels += nvrt; - - first = false; - } - } - - ++nAddPoints; - } - else - { - // Polyhedral: Not decomposed. - - const labelList& cFaces = mesh_.cells()[cellI]; - - // establish unique node ids used (only needed for XML) - hashUniqId.clear(); - - // determing sizing for face stream - // number of faces, size of each face, vertices per face - // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] - - forAll(cFaces, cFaceI) - { - const face& f = mesh_.faces()[cFaces[cFaceI]]; - nFaceLabels += f.size(); - - forAll(f, fp) - { - hashUniqId.insert(f[fp]); - } - } - - nVertLabels += hashUniqId.size(); - nFaceLabels += 1 + cFaces.size(); - } - } - - - // - // adjust/reserve sizes - // - - // Cell types (including added cells) in vtk numbering - cellTypes_.setSize(cellShapes.size() + nAddCells); - - // List of vertex labels in VTK ordering - vertLabels_.setSize(nVertLabels + nAddVerts); - - vertOffset_.setSize(cellShapes.size() + nAddCells); - - faceLabels_.clear(); - faceOffset_.clear(); - if (nFaceLabels) - { - faceLabels_.setSize(nFaceLabels); - - // only need nCells (without nAddCells) - // set to -1 (primitive) - faceOffset_.setSize(cellShapes.size(), -1); - } - - if (decompose_.requested()) - { - decompose_.addPointCellLabels_.setSize(nAddPoints); - decompose_.superCells_.setSize(nAddCells); - } - - - // ====================== - // PASS 2: Fill in arrays - - // Need this offset later, but only for decomposed polys - const label offsetAddVerts = nVertLabels; - - // Reset counters - nVertLabels = 0; - nFaceLabels = 0; - nAddPoints = 0; - nAddCells = 0; - nAddVerts = 0; - - forAll(cellShapes, cellI) - { - const cellShape& shape = cellShapes[cellI]; - const cellModel& model = shape.model(); - - if (model == tet) - { - cellTypes_[cellI] = foamVtkCore::VTK_TETRA; - forAll(shape, i) - { - vertLabels_[nVertLabels++] = shape[i]; - } - vertOffset_[cellI] = nVertLabels; - } - else if (model == pyr) - { - cellTypes_[cellI] = foamVtkCore::VTK_PYRAMID; - forAll(shape, i) - { - vertLabels_[nVertLabels++] = shape[i]; - } - vertOffset_[cellI] = nVertLabels; - } - else if (model == hex) - { - cellTypes_[cellI] = foamVtkCore::VTK_HEXAHEDRON; - forAll(shape, i) - { - vertLabels_[nVertLabels++] = shape[i]; - } - vertOffset_[cellI] = nVertLabels; - } - else if (model == prism) - { - cellTypes_[cellI] = foamVtkCore::VTK_WEDGE; - - // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5) - vertLabels_[nVertLabels++] = shape[0]; - vertLabels_[nVertLabels++] = shape[2]; - vertLabels_[nVertLabels++] = shape[1]; - vertLabels_[nVertLabels++] = shape[3]; - vertLabels_[nVertLabels++] = shape[5]; - vertLabels_[nVertLabels++] = shape[4]; - - vertOffset_[cellI] = nVertLabels; - } - else if (model == tetWedge && decompose_.requested()) - { - // Treat as squeezed prism (VTK_WEDGE) - cellTypes_[cellI] = foamVtkCore::VTK_WEDGE; - - vertLabels_[nVertLabels++] = shape[0]; - vertLabels_[nVertLabels++] = shape[2]; - vertLabels_[nVertLabels++] = shape[1]; - vertLabels_[nVertLabels++] = shape[3]; - vertLabels_[nVertLabels++] = shape[4]; - vertLabels_[nVertLabels++] = shape[3]; - - vertOffset_[cellI] = nVertLabels; - } - else if (model == wedge && decompose_.requested()) - { - // Treat as squeezed hex - cellTypes_[cellI] = foamVtkCore::VTK_HEXAHEDRON; - - vertLabels_[nVertLabels++] = shape[0]; - vertLabels_[nVertLabels++] = shape[1]; - vertLabels_[nVertLabels++] = shape[2]; - vertLabels_[nVertLabels++] = shape[2]; - vertLabels_[nVertLabels++] = shape[3]; - vertLabels_[nVertLabels++] = shape[4]; - vertLabels_[nVertLabels++] = shape[5]; - vertLabels_[nVertLabels++] = shape[6]; - - vertOffset_[cellI] = nVertLabels; - } - else if (decompose_.requested()) - { - // Polyhedral cell - decompose into tet/pyr. - - // Ensure we have the correct orientation for the base of the - // primitive cell shape. - // If the cell is face owner, the orientation needs to be flipped - // to avoid defining negative cells. - // VTK doesn't seem to care, but we'll do it anyhow for safety. - - // The new vertex from the cell-centre - const label newVertexLabel = mesh_.nPoints() + nAddPoints; - - // Mapping from additional point to cell - decompose_.addPointCellLabels_[nAddPoints++] = cellI; - - // Whether to insert cell in place of original or not. - bool first = true; - - const labelList& cFaces = mesh_.cells()[cellI]; - forAll(cFaces, cFaceI) - { - const face& f = mesh_.faces()[cFaces[cFaceI]]; - const bool isOwner = (owner[cFaces[cFaceI]] == cellI); - - // Count triangles/quads in decomposition - label nTria = 0; - label nQuad = 0; - f.nTrianglesQuads(mesh_.points(), nTria, nQuad); - - // Do actual decomposition - faceList faces3(nTria); - faceList faces4(nQuad); - nTria = 0, nQuad = 0; - f.trianglesQuads(mesh_.points(), nTria, nQuad, faces3, faces4); - - forAll(faces4, fci) - { - const face& quad = faces4[fci]; - - label celLoc; - label vrtLoc; - - if (first) - { - celLoc = cellI; - vrtLoc = nVertLabels; - nVertLabels += 5; - - vertOffset_[celLoc] = nVertLabels; - first = false; - } - else - { - celLoc = mesh_.nCells() + nAddCells; - vrtLoc = offsetAddVerts + nAddVerts; - nAddVerts += 5; - - vertOffset_[celLoc] = nAddVerts; - decompose_.superCells_[nAddCells++] = cellI; - } - - cellTypes_[celLoc] = foamVtkCore::VTK_PYRAMID; - - // See note above about the orientation. - if (isOwner) - { - vertLabels_[vrtLoc++] = quad[3]; - vertLabels_[vrtLoc++] = quad[2]; - vertLabels_[vrtLoc++] = quad[1]; - vertLabels_[vrtLoc++] = quad[0]; - } - else - { - vertLabels_[vrtLoc++] = quad[0]; - vertLabels_[vrtLoc++] = quad[1]; - vertLabels_[vrtLoc++] = quad[2]; - vertLabels_[vrtLoc++] = quad[3]; - } - - vertLabels_[vrtLoc++] = newVertexLabel; - } - - forAll(faces3, fci) - { - const face& tria = faces3[fci]; - - label celLoc; - label vrtLoc; - - if (first) - { - celLoc = cellI; - vrtLoc = nVertLabels; - nVertLabels += 4; - - vertOffset_[celLoc] = nVertLabels; - first = false; - } - else - { - celLoc = mesh_.nCells() + nAddCells; - vrtLoc = offsetAddVerts + nAddVerts; - nAddVerts += 4; - - vertOffset_[celLoc] = nAddVerts; - decompose_.superCells_[nAddCells++] = cellI; - } - - cellTypes_[celLoc] = foamVtkCore::VTK_TETRA; - - // See note above about the orientation. - if (isOwner) - { - vertLabels_[vrtLoc++] = tria[2]; - vertLabels_[vrtLoc++] = tria[1]; - vertLabels_[vrtLoc++] = tria[0]; - } - else - { - vertLabels_[vrtLoc++] = tria[0]; - vertLabels_[vrtLoc++] = tria[1]; - vertLabels_[vrtLoc++] = tria[2]; - } - vertLabels_[vrtLoc++] = newVertexLabel; - } - } - } - else - { - // Polyhedral cell - not decomposed - - hashUniqId.clear(); // unique node ids used (only needed for XML) - - // face-stream - // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] - - cellTypes_[cellI] = foamVtkCore::VTK_POLYHEDRON; - const labelList& cFaces = mesh_.cells()[cellI]; - - faceLabels_[nFaceLabels++] = cFaces.size(); - - forAll(cFaces, cFaceI) - { - const face& f = mesh_.faces()[cFaces[cFaceI]]; - const bool isOwner = (owner[cFaces[cFaceI]] == cellI); - - forAll(f, fp) - { - hashUniqId.insert(f[fp]); - } - - // number of labels for this face - faceLabels_[nFaceLabels++] = f.size(); - - if (isOwner) - { - forAll(f, fp) - { - faceLabels_[nFaceLabels++] = f[fp]; - } - } - else - { - // fairly immaterial if we reverse the list - // or use face::reverseFace() - forAllReverse(f, fp) - { - faceLabels_[nFaceLabels++] = f[fp]; - } - } - } - - faceOffset_[cellI] = nFaceLabels; - - const labelList uniq = hashUniqId.sortedToc(); - forAll(uniq, i) - { - vertLabels_[nVertLabels++] = uniq[i]; - } - - vertOffset_[cellI] = nVertLabels; - } - } - - // =========================================== - // PASS 3: Repair offsets for additional cells - -// Info<<"vertOffset: " << vertOffset_.size() << " VS. " << (mesh_.nCells()) << endl; -// Info<<"nAddCells: " << nAddCells << " VS. " << (mesh_.nCells()) << endl; - - if (nAddCells) - { - const label beg = mesh_.nCells(); - const label add = vertOffset_[beg-1]; - - for (label i = beg; i < vertOffset_.size(); ++i) - { - vertOffset_[i] += add; - } - } - - // Some basic programming/sanity checks - - if ((nVertLabels + nAddVerts) != vertOffset_[mesh_.nCells()-1 + nAddCells]) - { - WarningInFunction - << "predicted offsets (" << nVertLabels << " + " << nAddVerts << ") != " - << vertOffset_[mesh_.nCells()-1 + nAddCells] - << endl; - } - - if (offsetAddVerts != vertOffset_[mesh_.nCells()-1]) - { - WarningInFunction - << "predicted regular offset " << offsetAddVerts - << " != " << vertOffset_[mesh_.nCells()] - << endl; - } - - // nFaceLabels = 0; - // nAddPoints = 0; - // nAddCells = 0; - - // Pout<<"vertLabels: " << vertLabels_.size() << " vs. " << (nVertLabels + nAddVerts) << endl; - // Pout<<"faceLabels: " << faceLabels_.size() << " vs. " << nFaceLabels << endl; -#if 0 - if (decompose_.requested()) - { - Pout<< " Original cells:" << mesh_.nCells() - << " points:" << mesh_.nPoints() - << " Additional cells:" << decompose_.superCells_.size() - << " additional points:" << decompose_.addPointCellLabels_.size() - << nl << endl; - } -#endif -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::foamVtkCells::decomp::decomp(const bool decomposePoly) -: - addPointCellLabels_(), - superCells_(), - pointMap_(), - requested_(decomposePoly) -{} - - -Foam::foamVtkCells::foamVtkCells -( - const polyMesh& mesh, - const bool decomposePoly, - const bool lazy -) -: - mesh_(mesh), - cellTypes_(), - vertLabels_(), - vertOffset_(), - faceLabels_(), - faceOffset_(), - decompose_(decomposePoly), - needsUpdate_(true) -{ - if (!lazy) - { - correct(); - } -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::foamVtkCells::decomp::~decomp() -{} - - -Foam::foamVtkCells::~foamVtkCells() -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - - -void Foam::foamVtkCells::decomp::clear() -{ - superCells_.clear(); - addPointCellLabels_.clear(); - pointMap_.clear(); -} - - -Foam::label Foam::foamVtkCells::nFieldPoints() const -{ - return mesh_.nPoints() + decompose_.addPointCellLabels_.size(); -} - - -Foam::label Foam::foamVtkCells::legacyCellPayLoad() const -{ - label payLoad = cellTypes_.size(); - - if (faceOffset_.size()) - { - // also has polys with face streams - - label begVert = 0; - label begFace = 0; - - forAll(faceOffset_, i) - { - label endFace = faceOffset_[i]; - label endVert = vertOffset_[i]; - - if (endFace > 0) - { - // poly with face stream - payLoad += endFace - begFace; - - begFace = endFace; - } - else - { - // primitive without face stream - payLoad += endVert - begVert; - } - begVert = endVert; - } - } - else if (vertOffset_.size()) - { - // primitives only, trivial - payLoad += vertOffset_[vertOffset_.size()-1]; - } - - return payLoad; -} - - -bool Foam::foamVtkCells::needsUpdate() const -{ - return needsUpdate_; -} - - -bool Foam::foamVtkCells::expire() -{ - // Clear any stored topologies - - // Clear derived data - // clearGeom(); - - // already marked as expired - if (needsUpdate_) - { - return false; - } - - needsUpdate_ = true; - return true; -} - - -bool Foam::foamVtkCells::update() -{ - if (!needsUpdate_) - { - return false; - } - - correct(); - - needsUpdate_ = false; - return true; -} - - -// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtkCells.H b/src/conversion/vtk/part/foamVtkCells.H deleted file mode 100644 index 692614a4b9b98e272062fb199751cde0c37980be..0000000000000000000000000000000000000000 --- a/src/conversion/vtk/part/foamVtkCells.H +++ /dev/null @@ -1,350 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 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::foamVtkCells - -Description - The deep-copy description of an OpenFOAM volume mesh in data structures - corresponding to an VTK UnstructuredGrid, including the possiblity of - decomposing polyhedral cells into primitive cell types. - - Knowledge of the vtkUnstructuredGrid and the corresponding \c .vtu - xml file-format aids in understanding this class. - For flexibilty, support for the legacy vtk file-format is also provided. - - Primitive cell types are straighforward, polyhedral cells are represented - by a face stream: - \verbatim - [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] - \endverbatim - - For the legacy format, the face stream is simply passed as vertex labels - (connectivity). - - For the xml format, the face stream is saved separately: - \verbatim - "connectivity" - == the unique vertex labels used by the cell (optionally sorted). - - "offsets": - == offset + sizeof(connectivity) - - "faces": - [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] - - "faceoffsets": - == faceoffsets + sizeof(faces) - \endverbatim - - The storage of "connectivity" and "offsets" strongly resembles a - CompactListList, but the "offsets" point to the end of the respective - sub-lists. - -SourceFiles - foamVtkCells.C - -\*---------------------------------------------------------------------------*/ - -#ifndef foamVtkCells_H -#define foamVtkCells_H - -#include "foamVtkCore.H" -#include "DynamicList.H" -#include "SubList.H" -#include "labelList.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// Forward declaration of classes -class polyMesh; - -/*---------------------------------------------------------------------------*\ - Class foamVtkCells Declaration -\*---------------------------------------------------------------------------*/ - -class foamVtkCells -: - public fileFormats::foamVtkCore -{ -public: - - //- Bookkeeping for polyhedral cell decomposition - class decomp - { - private: - friend foamVtkCells; - - // Private data - - //- Cell-centre labels for additional points of decomposed cells - DynamicList<label> addPointCellLabels_; - - //- Label of original cell for decomposed cells - DynamicList<label> superCells_; - - //- Point labels for subsetted meshes - DynamicList<label> pointMap_; - - //- Track if decomposition was requested - const bool requested_; - - - // Private Member Functions - - //- Disallow default bitwise copy construct - decomp(const decomp&) = delete; - - //- Disallow default bitwise assignment - void operator=(const decomp&) = delete; - - public: - - // Constructors - - //- Construct null - decomp(const bool decomposePoly = false); - - - //- Destructor - ~decomp(); - - - // Member Functions - - // Access - - //- Polyhedral decomposition requested - inline bool requested() const; - - //- Polyhedral decomposition used - inline bool used() const; - - //- Label of original cell for decomposed cells - inline const labelList& superCells() const; - - //- Cell-centre labels for additional points of decomposed cells - inline const labelList& addPointCellLabels() const; - - //- Point labels for subsetted meshes - inline const labelList& pointMap() const; - - - // Edit - - //- Clear - void clear(); - }; - - -private: - - // Private data - - //- Reference to underlying mesh or mesh sub-set - const polyMesh& mesh_; - - //- Cell types (including added cells) in vtk numbering - // Range is 1-255 - List<uint8_t> cellTypes_; - - //- Vertices per cell (including added cells) in vtk ordering - DynamicList<label> vertLabels_; - - //- Vertices per cell (including added cells) in vtk ordering - DynamicList<label> vertOffset_; - - //- Face lists per polyhedral cell - DynamicList<label> faceLabels_; - - //- Face label offsets - DynamicList<label> faceOffset_; - - //- Bookkeeping for polyhedral cell decomposition - decomp decompose_; - - //- Needs update - bool needsUpdate_; - - - - // Private Member Functions - - //- Create the geometry - void correct(); - - //- Disallow default bitwise copy construct - foamVtkCells(const foamVtkCells&) = delete; - - //- Disallow default bitwise assignment - void operator=(const foamVtkCells&) = delete; - - -public: - - // Constructors - - //- Construct from components. - // Optionally with polyhedral decomposition and/or lazy evaluation. - // A 'lazy' evaluation avoids fully creation within the constructor. - foamVtkCells - ( - const polyMesh&, - const bool decomposePoly = false, - const bool lazy = false - ); - - - //- Destructor - ~foamVtkCells(); - - - // Member Functions - - // Access - - //- Query the poly decompose flag. - inline bool decomposeRequested() const; - - //- Values for "connectivity" (XML) or basis for "CELLS" (legacy) - // In the legacy format, the size (offset) must be prefixed. - inline const labelList& vertLabels() const; - - //- Values for "offsets" (XML) - // or sizes to prefix for for "CELLS" (legacy) - inline const labelList& vertOffsets() const; - - //- Values for "types" (XML) and "CELL_TYPES" (legacy) - inline const List<uint8_t>& cellTypes() const; - - //- Values for "faces" (XML) - inline const labelList& faceLabels() const; - - //- Values for "faceoffsets" (XML) - inline const labelList& faceOffsets() const; - - //- Additional point addressing (from added point to original cell) - inline const labelList& addPointCellLabels() const; - - //- Additional cells mapping (from added cell to original cell) - inline const labelList& superCells() const; - - - //- Number of field cells - inline label nFieldCells() const; - - //- Number of field points - label nFieldPoints() const; - - //- The field size for legacy "CELLS". - // In the legacy format, the size (offset) must be prefixed. - label legacyCellPayLoad() const; - - - //- Does the mapping need an update? - bool needsUpdate() const; - - //- Mark as needing an update. - // May also free up unneeded data. - // Return false if it was already marked as expired. - bool expire(); - - //- Update the description (and decomposition) as required. - // Do nothing (and return false) if no update was required - bool update(); - - - //- The const_iterator for foamVtkCells - class const_iterator - { - friend class foamVtkCells; - - protected: - - // Protected Data - - //- Reference to parent list - const foamVtkCells& parent_; - - //- Element index - label index_; - - //- Begin of connectivity sub-list - mutable label begVert_; - - //- Begin of faces sub-list - mutable label begFace_; - - //- On-demand legacy pointer - mutable autoPtr<SubList<label>> legacy_; - - - // Constructors - - //- Construct begin/end iterator - inline const_iterator - ( - const foamVtkCells&, - bool isEnd = false - ); - - public: - - // Member operators - - //- On-demand legacy cell labels (primitive or faces) - inline const labelUList& legacyCell() const; - - //- Compare position - inline bool operator!=(const const_iterator&) const; - - //- Pre-increment iterator - inline const_iterator& operator++(); - }; - - - //- const_iterator set to the beginning - inline const_iterator begin() const; - - //- const_iterator set to beyond the end - inline const_iterator end() const; - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#include "foamVtkCellsI.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtkCellsI.H b/src/conversion/vtk/part/foamVtkCellsI.H deleted file mode 100644 index 5973f5113e8de89c3630fa095c201fed966401ca..0000000000000000000000000000000000000000 --- a/src/conversion/vtk/part/foamVtkCellsI.H +++ /dev/null @@ -1,239 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016 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 "foamVtkCells.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -inline bool Foam::foamVtkCells::decomp::requested() const -{ - return requested_; -} - - -inline bool Foam::foamVtkCells::decomp::used() const -{ - return !superCells_.empty(); -} - - -inline const Foam::labelList& -Foam::foamVtkCells::decomp::superCells() const -{ - return superCells_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::decomp::addPointCellLabels() const -{ - return addPointCellLabels_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::decomp::pointMap() const -{ - return pointMap_; -} - - -inline bool Foam::foamVtkCells::decomposeRequested() const -{ - return decompose_.requested(); -} - - -inline const Foam::labelList& -Foam::foamVtkCells::vertLabels() const -{ - return vertLabels_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::vertOffsets() const -{ - return vertOffset_; -} - - -inline const Foam::List<uint8_t>& -Foam::foamVtkCells::cellTypes() const -{ - return cellTypes_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::faceLabels() const -{ - return faceLabels_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::faceOffsets() const -{ - return faceOffset_; -} - - -inline const Foam::labelList& -Foam::foamVtkCells::addPointCellLabels() const -{ - return decompose_.addPointCellLabels(); -} - - -inline const Foam::labelList& -Foam::foamVtkCells::superCells() const -{ - return decompose_.superCells(); -} - - -inline Foam::label -Foam::foamVtkCells::nFieldCells() const -{ - return cellTypes_.size(); -} - - -inline Foam::foamVtkCells::const_iterator -Foam::foamVtkCells::begin() const -{ - return const_iterator(*this); -} - - -inline Foam::foamVtkCells::const_iterator -Foam::foamVtkCells::end() const -{ - return const_iterator(*this, true); -} - - -// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * // - -inline Foam::foamVtkCells::const_iterator::const_iterator -( - const foamVtkCells& cells, - bool isEnd -) -: - parent_(cells), - index_(0), - begVert_(0), - begFace_(0), - legacy_() -{ - if (isEnd) - { - index_ = parent_.vertOffsets().size(); - } -} - - -inline -Foam::foamVtkCells::const_iterator& -Foam::foamVtkCells::const_iterator::operator++() -{ - ++index_; - legacy_.clear(); - - return *this; -} - - -inline -const Foam::UList<Foam::label>& -Foam::foamVtkCells::const_iterator::legacyCell() const -{ - if - ( - legacy_.valid() - || index_ >= parent_.vertOffsets().size() - ) - { - return legacy_(); - } - - const label endVert = parent_.vertOffsets()[index_]; - - const label endFace = - ( - parent_.faceOffsets().size() - ? parent_.faceOffsets()[index_] - : -1 - ); - - if (endFace > 0) - { - // poly with face stream - - legacy_.reset - ( - new SubList<label> - ( - parent_.faceLabels(), - endFace - begFace_, - begFace_ - ) - ); - - begFace_ = endFace; - } - else - { - // primitive without face stream - legacy_.reset - ( - new SubList<label> - ( - parent_.vertLabels(), - endVert - begVert_, - begVert_ - ) - ); - } - - begVert_ = endVert; - - return legacy_(); -} - - -inline bool -Foam::foamVtkCells::const_iterator::operator!= -( - const const_iterator& rhs -) const -{ - return (index_ != rhs.index_); -} - - -// ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkOutputOptionsI.H b/src/conversion/vtk/part/foamVtkMeshMaps.C similarity index 70% rename from src/fileFormats/vtk/format/foamVtkOutputOptionsI.H rename to src/conversion/vtk/part/foamVtkMeshMaps.C index 0205f2f98ec87c5dba88223afb604310eb13407b..badc422df5065e3e0082cd3cf3442b181b6e22a3 100644 --- a/src/fileFormats/vtk/format/foamVtkOutputOptionsI.H +++ b/src/conversion/vtk/part/foamVtkMeshMaps.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,33 +23,21 @@ License \*---------------------------------------------------------------------------*/ -inline bool Foam::foamVtkOutputOptions::legacy() const -{ - return (type_ & LEGACY); -} - - -inline bool Foam::foamVtkOutputOptions::xml() const -{ - return !legacy(); -} - - -inline bool Foam::foamVtkOutputOptions::append() const -{ - return (type_ & APPEND); -} +#include "foamVtkMeshMaps.H" +#include "ListOps.H" +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline bool Foam::foamVtkOutputOptions::insitu() const +void Foam::foamVtkMeshMaps::renumberCells(const UList<label>& mapping) { - return !(type_ & APPEND); + inplaceRenumber(mapping, cellMap_); + inplaceRenumber(mapping, additionalIds_); } -inline bool Foam::foamVtkOutputOptions::ascii() const +void Foam::foamVtkMeshMaps::renumberPoints(const UList<label>& mapping) { - return !(type_ & (BINARY | BASE64)); + inplaceRenumber(mapping, pointMap_); } diff --git a/src/conversion/vtk/part/foamVtkMeshMaps.H b/src/conversion/vtk/part/foamVtkMeshMaps.H new file mode 100644 index 0000000000000000000000000000000000000000..737f02a2edfbf4f202eca1c291ea0af6cb4755ea --- /dev/null +++ b/src/conversion/vtk/part/foamVtkMeshMaps.H @@ -0,0 +1,143 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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::foamVtkMeshMaps + +Description + Bookkeeping for mesh subsetting and/or polyhedral cell decomposition. + Although the main use case is for handling vtk meshes, it is not specific + to VTK alone. + + The cellMap is a local-to-global lookup for normal and decomposed cells. + The pointMap is an optional local-to-global lookup for point ids. + The additional ids is typically used to store the cell-centre labels + for additional points of decomposed cells + +SourceFiles + foamVtkMeshMapsI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkMeshMaps_H +#define foamVtkMeshMaps_H + +#include "DynamicList.H" +#include "labelList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class foamVtkMeshMaps Declaration +\*---------------------------------------------------------------------------*/ + +class foamVtkMeshMaps +{ + // Private data + + //- Original cell ids for all cells (regular and decomposed) + DynamicList<label> cellMap_; + + //- Point labels for subsetted meshes + DynamicList<label> pointMap_; + + //- Any additional (user) labels. + // Eg, cell-centre labels for additional points of decomposed cells + DynamicList<label> additionalIds_; + +public: + + // Constructors + + //- Construct null + inline foamVtkMeshMaps(const label size = 0); + + + //- Destructor + inline ~foamVtkMeshMaps(); + + + // Member Functions + + // Access + + //- Original cell ids for all cells (regular and decomposed). + // A regular mesh comprising only primitive cell types, this will just + // be an identity list. However, for subsetted meshes and decomposed + // cells this becomes a useful means of mapping from the original mesh. + inline const labelList& cellMap() const; + + //- Point labels for subsetted meshes + inline const labelList& pointMap() const; + + //- Any additional (user) labels. + // Eg, cell-centre labels for additional points of decomposed cells + inline const labelList& additionalIds() const; + + + // Edit + + //- Clear + inline void clear(); + + //- Renumber cell ids (cellMap and additionalIds) to account for + // subset meshes + void renumberCells(const UList<label>& mapping); + + //- Renumber point ids (pointMap) to account for subset meshes + void renumberPoints(const UList<label>& mapping); + + + //- Original cell ids for all cells (regular and decomposed). + // For a regular mesh comprising only primitive cell types, this + // will simply be an identity list. However, for subsetted meshes + // and decomposed cells this becomes a useful means of mapping from + // the original mesh. + inline DynamicList<label>& cellMap(); + + //- Point labels for subsetted meshes + inline DynamicList<label>& pointMap(); + + //- Any additional (user) labels. + // Eg, cell-centre labels for additional points of decomposed cells + inline DynamicList<label>& additionalIds(); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "foamVtkMeshMapsI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.C b/src/conversion/vtk/part/foamVtkMeshMapsI.H similarity index 52% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.C rename to src/conversion/vtk/part/foamVtkMeshMapsI.H index 367dd92e7a57c376031e8af2e5e61e5191832dcb..5f53fb25b2edf9e442920f0e441e8cd65853f946 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.C +++ b/src/conversion/vtk/part/foamVtkMeshMapsI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,56 +23,73 @@ License \*---------------------------------------------------------------------------*/ -#include "surfaceMeshWriter.H" -#include "writeFuns.H" +#include "foamVtkMeshMaps.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::surfaceMeshWriter::surfaceMeshWriter -( - const bool binary, - const indirectPrimitivePatch& pp, - const word& name, - const fileName& fName -) +inline Foam::foamVtkMeshMaps::foamVtkMeshMaps(const label size) : - binary_(binary), - pp_(pp), - fName_(fName), - os_(fName.c_str()) + cellMap_(size), + pointMap_(size), + additionalIds_(size) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +inline Foam::foamVtkMeshMaps::~foamVtkMeshMaps() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline void Foam::foamVtkMeshMaps::clear() +{ + cellMap_.clear(); + pointMap_.clear(); + additionalIds_.clear(); +} + + +inline const Foam::labelList& +Foam::foamVtkMeshMaps::cellMap() const { - // Write header - writeFuns::writeHeader(os_, binary_, name); + return cellMap_; +} - os_ << "DATASET POLYDATA" << std::endl; - // Write topology - label nFaceVerts = 0; +inline Foam::DynamicList<Foam::label>& +Foam::foamVtkMeshMaps::cellMap() +{ + return cellMap_; +} - forAll(pp, facei) - { - nFaceVerts += pp[facei].size() + 1; - } - os_ << "POINTS " << pp.nPoints() << " float" << std::endl; +inline const Foam::labelList& +Foam::foamVtkMeshMaps::pointMap() const +{ + return pointMap_; +} - DynamicList<floatScalar> ptField(3*pp.nPoints()); - writeFuns::insert(pp.localPoints(), ptField); - writeFuns::write(os_, binary, ptField); +inline Foam::DynamicList<Foam::label>& +Foam::foamVtkMeshMaps::pointMap() +{ + return pointMap_; +} - os_ << "POLYGONS " << pp.size() << ' ' << nFaceVerts << std::endl; - DynamicList<label> vertLabels(nFaceVerts); +inline const Foam::labelList& +Foam::foamVtkMeshMaps::additionalIds() const +{ + return additionalIds_; +} - forAll(pp, facei) - { - const face& f = pp.localFaces()[facei]; - vertLabels.append(f.size()); - writeFuns::insert(f, vertLabels); - } - writeFuns::write(os_, binary_, vertLabels); +inline Foam::DynamicList<Foam::label>& +Foam::foamVtkMeshMaps::additionalIds() +{ + return additionalIds_; } diff --git a/src/conversion/vtk/part/foamVtuCells.C b/src/conversion/vtk/part/foamVtuCells.C new file mode 100644 index 0000000000000000000000000000000000000000..962fa9b0ee8d49b99e03181741cf2cc8dce9fcac --- /dev/null +++ b/src/conversion/vtk/part/foamVtuCells.C @@ -0,0 +1,186 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "polyMesh.H" +#include "foamVtuCells.H" +#include "foamVtkOutputOptions.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::vtuCells::vtuCells +( + const contentType output, + const bool decompose +) +: + vtk::vtuSizing(), + output_(output), + decomposeRequest_(decompose), + cellTypes_(), + vertLabels_(), + vertOffset_(), + faceLabels_(), + faceOffset_(), + maps_() +{} + + +Foam::vtk::vtuCells::vtuCells +( + const polyMesh& mesh, + const contentType output, + const bool decompose +) +: + vtuCells(output, decompose) +{ + reset(mesh); +} + + +Foam::vtk::vtuCells::vtuCells +( + const vtk::outputOptions outOpts, + const bool decompose +) +: + vtuCells + ( + (outOpts.legacy() ? contentType::LEGACY : contentType::XML), + decompose + ) +{} + + +Foam::vtk::vtuCells::vtuCells +( + const polyMesh& mesh, + const vtk::outputOptions outOpts, + const bool decompose +) +: + vtuCells(outOpts, decompose) +{ + reset(mesh); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::vtuCells::~vtuCells() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::vtuCells::clear() +{ + vtuSizing::clear(); + cellTypes_.clear(); + vertLabels_.clear(); + vertOffset_.clear(); + faceLabels_.clear(); + faceOffset_.clear(); + + maps_.clear(); +} + + +void Foam::vtk::vtuCells::reset(const polyMesh& mesh) +{ + vtuSizing::reset(mesh, decomposeRequest_); + + cellTypes_.setSize(nFieldCells()); + vertLabels_.setSize(sizeOf(output_, slotType::CELLS)); + vertOffset_.setSize(sizeOf(output_, slotType::CELLS_OFFSETS)); + faceLabels_.setSize(sizeOf(output_, slotType::FACES)); + faceOffset_.setSize(sizeOf(output_, slotType::FACES_OFFSETS)); + + switch (output_) + { + case contentType::LEGACY: + populateLegacy + ( + mesh, + cellTypes_, + vertLabels_, + maps_ + ); + break; + case contentType::XML: + populateXml + ( + mesh, + cellTypes_, + vertLabels_, + vertOffset_, + faceLabels_, + faceOffset_, + maps_ + ); + break; + case contentType::INTERNAL: + populateInternal + ( + mesh, + cellTypes_, + vertLabels_, + vertOffset_, + faceLabels_, + faceOffset_, + maps_ + ); + break; + } +} + + +void Foam::vtk::vtuCells::reset +( + const polyMesh& mesh, + const enum contentType output, + const bool decompose +) +{ + output_ = output; + decomposeRequest_ = decompose; + + reset(mesh); +} + + +void Foam::vtk::vtuCells::renumberCells(const UList<label>& mapping) +{ + maps_.renumberCells(mapping); +} + + +void Foam::vtk::vtuCells::renumberPoints(const UList<label>& mapping) +{ + maps_.renumberPoints(mapping); +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuCells.H b/src/conversion/vtk/part/foamVtuCells.H new file mode 100644 index 0000000000000000000000000000000000000000..6c4c71c52424a52264ba58364eb8aff8652c4087 --- /dev/null +++ b/src/conversion/vtk/part/foamVtuCells.H @@ -0,0 +1,242 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2017 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::vtuCells + +Description + A deep-copy description of an OpenFOAM volume mesh in data structures + suitable for VTK UnstructuredGrid, including the possibility of + decomposing polyhedral cells into primitive cell types. + + Knowledge of the vtkUnstructuredGrid and the corresponding \c .vtu + xml file-format aids in understanding this class. + The class can be used for the VTK xml format, legacy format, as well as a + VTK internal representation. The internal representation is somewhat + related to the xml format, but not entirely. + +SeeAlso + Foam::vtk::vtuSizing + +SourceFiles + foamVtuCells.C + foamVtuCellsI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtuCells_H +#define foamVtuCells_H + +#include "foamVtkCore.H" +#include "foamVtkMeshMaps.H" +#include "foamVtuSizing.H" +#include "DynamicList.H" +#include "labelList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class polyMesh; + +namespace vtk +{ +// Forward declaration of classes + class outputOptions; + +/*---------------------------------------------------------------------------*\ + Class Foam::vtk::vtuCells Declaration +\*---------------------------------------------------------------------------*/ + +class vtuCells +: + public vtuSizing +{ + // Private Member Data + + // Requested output types + + //- Output content type + contentType output_; + + //- Bookkeeping for polyhedral cell decomposition + bool decomposeRequest_; + + // Storage of output + + //- Cell types (including added cells) in vtk numbering + // Range is 1-255 + List<uint8_t> cellTypes_; + + //- Vertices per cell (including added cells) in vtk ordering + List<label> vertLabels_; + + //- Connectivity (vertices) offset for the end of each cell + List<label> vertOffset_; + + //- Face lists per polyhedral cell + List<label> faceLabels_; + + //- Face label offsets + List<label> faceOffset_; + + //- Bookkeeping for polyhedral cell decomposition + foamVtkMeshMaps maps_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + vtuCells(const vtuCells&) = delete; + + //- Disallow default bitwise assignment + void operator=(const vtuCells&) = delete; + + +public: + + // Constructors + + //- Construct from components. + // Optionally with polyhedral decomposition. + vtuCells + ( + const enum contentType output = contentType::XML, + const bool decompose = false + ); + + //- Construct from components and create the output information + // immediately + vtuCells + ( + const polyMesh& mesh, + const enum contentType output = contentType::XML, + const bool decompose = false + ); + + //- Construct from components. + // Optionally with polyhedral decomposition. + vtuCells + ( + const vtk::outputOptions outOpts, + const bool decompose = false + ); + + //- Construct from components and create the output information + // immediately + vtuCells + ( + const polyMesh& mesh, + const vtk::outputOptions outOpts, + const bool decompose = false + ); + + + //- Destructor + ~vtuCells(); + + + // Member Functions + + // Access + + //- The output content type + inline enum contentType content() const; + + //- Query the polyhedral decompose requested flag. + inline bool decomposeRequested() const; + + //- True if no cellTypes are populated. + inline bool empty() const; + + //- The size of populated cellTypes. + inline label size() const; + + + // Edit + + //- Reset all sizes to zero. + void clear(); + + //- Create the geometry using the previously requested output and + // decomposition types. + void reset(const polyMesh& mesh); + + //- Respecify requested output and decomposition type prior to + // creating the geometry + void reset + ( + const polyMesh& mesh, + const enum contentType output, + const bool decompose + ); + + //- Renumber cell ids to account for subset meshes + void renumberCells(const UList<label>& mapping); + + //- Renumber point ids to account for subset meshes + void renumberPoints(const UList<label>& mapping); + + + // Storage Access + + //- Values for "types" (XML) and "CELL_TYPES" (legacy) + inline const List<uint8_t>& cellTypes() const; + + //- Values for "connectivity" (XML) or "CELLS" (legacy) + inline const labelList& vertLabels() const; + + //- Values for "offsets" (XML only) + inline const labelList& vertOffsets() const; + + //- Values for "faces" (XML only) + inline const labelList& faceLabels() const; + + //- Values for "faceoffset" (XML only) + inline const labelList& faceOffsets() const; + + //- Additional point addressing (from added point to original cell) + inline const labelList& addPointCellLabels() const; + + //- Original cell ids for all cells (regular and decomposed). + inline const labelList& cellMap() const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "foamVtuCellsI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuCellsI.H b/src/conversion/vtk/part/foamVtuCellsI.H new file mode 100644 index 0000000000000000000000000000000000000000..49cbe1871750f729b28c92c8abdc193747401e29 --- /dev/null +++ b/src/conversion/vtk/part/foamVtuCellsI.H @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtuCells.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +inline enum Foam::vtk::vtuCells::contentType +Foam::vtk::vtuCells::content() const +{ + return output_; +} + + +inline bool Foam::vtk::vtuCells::decomposeRequested() const +{ + return decomposeRequest_; +} + + +inline bool Foam::vtk::vtuCells::empty() const +{ + return cellTypes_.empty(); +} + + +inline Foam::label Foam::vtk::vtuCells::size() const +{ + return cellTypes_.size(); +} + + +inline const Foam::List<uint8_t>& +Foam::vtk::vtuCells::cellTypes() const +{ + return cellTypes_; +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::vertLabels() const +{ + return vertLabels_; +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::vertOffsets() const +{ + return vertOffset_; +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::faceLabels() const +{ + return faceLabels_; +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::faceOffsets() const +{ + return faceOffset_; +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::addPointCellLabels() const +{ + return maps_.additionalIds(); +} + + +inline const Foam::labelList& +Foam::vtk::vtuCells::cellMap() const +{ + return maps_.cellMap(); +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuSizing.C b/src/conversion/vtk/part/foamVtuSizing.C new file mode 100644 index 0000000000000000000000000000000000000000..15c4429380e88b494ef97dac0814d6c67b933384 --- /dev/null +++ b/src/conversion/vtk/part/foamVtuSizing.C @@ -0,0 +1,578 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtuSizing.H" +#include "foamVtkCore.H" +#include "polyMesh.H" +#include "cellShape.H" +#include "cellModeller.H" + +// Only used in this file +#include "foamVtuSizingTemplates.C" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::vtk::vtuSizing::presizeMaps(foamVtkMeshMaps& maps) const +{ + maps.cellMap().setSize(this->nFieldCells()); + maps.additionalIds().setSize(this->nAddPoints()); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::vtk::vtuSizing::vtuSizing +( + const polyMesh& mesh, + const bool decompose +) +{ + clear(); + reset(mesh, decompose); +} + + +Foam::vtk::vtuSizing::vtuSizing() +{ + clear(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::vtk::vtuSizing::~vtuSizing() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::vtk::vtuSizing::reset +( + const polyMesh& mesh, + const bool decompose +) +{ + const cellModel& tet = *(cellModeller::lookup("tet")); + const cellModel& pyr = *(cellModeller::lookup("pyr")); + const cellModel& prism = *(cellModeller::lookup("prism")); + const cellModel& wedge = *(cellModeller::lookup("wedge")); + const cellModel& tetWedge = *(cellModeller::lookup("tetWedge")); + const cellModel& hex = *(cellModeller::lookup("hex")); + + const cellShapeList& shapes = mesh.cellShapes(); + + // Unique vertex labels per polyhedral + HashSet<label> hashUniqId(2*256); + + decompose_ = decompose; + nCells_ = mesh.nCells(); + nPoints_ = mesh.nPoints(); + nAddCells_ = 0; + nAddVerts_ = 0; + + nCellsPoly_ = nCells_; + nVertLabels_ = 0; + nFaceLabels_ = 0; + nVertPoly_ = 0; + + forAll(shapes, celli) + { + const cellShape& shape = shapes[celli]; + const cellModel& model = shape.model(); + + if + ( + model == tet + || model == pyr + || model == prism + || model == hex + ) + { + // Normal primitive - not a poly + --nCellsPoly_; + nVertLabels_ += shape.size(); + } + else if (model == tetWedge && decompose) + { + nVertLabels_ += 6; // Treat as squeezed prism (VTK_WEDGE) + } + else if (model == wedge && decompose) + { + nVertLabels_ += 8; // Treat as squeezed hex + } + else if (decompose) + { + // Polyhedral: Decompose into tets + pyramids. + ++nAddPoints_; + + // Count vertices into first decomposed cell + bool first = true; + + const cell& cFaces = mesh.cells()[celli]; + forAll(cFaces, cFaceI) + { + const face& f = mesh.faces()[cFaces[cFaceI]]; + + // Face decomposed into triangles and quads + // Tri -> Tet, Quad -> Pyr + label nTria = 0, nQuad = 0; + f.nTrianglesQuads(mesh.points(), nTria, nQuad); + + nAddCells_ += nTria + nQuad; + nAddVerts_ += (nTria * 4) + (nQuad * 5); + + if (first) + { + first = false; + --nAddCells_; + + const label nvrt = (nQuad ? 5 : 4); + nAddVerts_ -= nvrt; + nVertLabels_ += nvrt; + } + } + } + else + { + // Polyhedral: Not decomposed + + const labelList& cFaces = mesh.cells()[celli]; + + // Unique node ids used (XML/INTERNAL, not needed for LEGACY) + hashUniqId.clear(); + + // Face stream sizing: + // number of faces, size of each face, vertices per face + // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] + + forAll(cFaces, cFaceI) + { + const face& f = mesh.faces()[cFaces[cFaceI]]; + nFaceLabels_ += f.size(); + + hashUniqId.insert(f); + } + + // Legacy format only uses the face-stream. + // - track what *NOT* to use for legacy + nVertLabels_ += hashUniqId.size(); + nVertPoly_ += hashUniqId.size(); + + nFaceLabels_ += 1 + cFaces.size(); + } + } + + // decompose requested and needed + decompose_ = (decompose && nCellsPoly_); +} + + +Foam::label Foam::vtk::vtuSizing::sizeOf +( + const enum contentType output, + const enum slotType slot +) const +{ + switch (output) + { + case contentType::LEGACY: + { + switch (slot) + { + case slotType::CELLS: + // legacy uses connectivity for primitives, but directly + // stores face streams into connectivity as well. + // size-prefix per cell + return + ( + nVertLabels() + nAddVerts() - nVertPoly() // primitives + + nFaceLabels() // face-stream (poly) + + nFieldCells() // nFieldCells (size prefix) + ); + break; + + default: + break; + } + break; + } + case contentType::XML: + { + switch (slot) + { + case slotType::CELLS: + return (nVertLabels() + nAddVerts()); + break; + + case slotType::CELLS_OFFSETS: + return nFieldCells(); + break; + + case slotType::FACES: + return nFaceLabels(); + break; + + case slotType::FACES_OFFSETS: + return nFaceLabels() ? nFieldCells() : 0; + break; + } + break; + } + case contentType::INTERNAL: + { + switch (slot) + { + case slotType::CELLS: + // size-prefix per cell + return (nVertLabels() + nAddVerts() + nFieldCells()); + break; + + case slotType::CELLS_OFFSETS: + return nFieldCells(); + break; + + case slotType::FACES: + return nFaceLabels(); + break; + + case slotType::FACES_OFFSETS: + return nFaceLabels() ? nFieldCells() : 0; + break; + } + break; + } + } + + return 0; +} + + +void Foam::vtk::vtuSizing::populateLegacy +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<label>& vertLabels, + foamVtkMeshMaps& maps +) const +{ + // Leave as zero-sized so that populateArrays doesn't fill it. + List<label> unused; + + presizeMaps(maps); + + populateArrays + ( + mesh, + *this, + cellTypes, + vertLabels, + unused, // offsets + unused, // faces + unused, // facesOffsets + contentType::LEGACY, + maps.cellMap(), + maps.additionalIds() + ); +} + + +void Foam::vtk::vtuSizing::populateXml +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<label>& connectivity, + UList<label>& offsets, + UList<label>& faces, + UList<label>& facesOffsets, + foamVtkMeshMaps& maps +) const +{ + presizeMaps(maps); + + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::XML, + maps.cellMap(), + maps.additionalIds() + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<int>& connectivity, + UList<int>& offsets, + UList<int>& faces, + UList<int>& facesOffsets, + foamVtkMeshMaps& maps +) const +{ + presizeMaps(maps); + + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + maps.cellMap(), + maps.additionalIds() + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long>& connectivity, + UList<long>& offsets, + UList<long>& faces, + UList<long>& facesOffsets, + foamVtkMeshMaps& maps +) const +{ + presizeMaps(maps); + + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + maps.cellMap(), + maps.additionalIds() + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long long>& connectivity, + UList<long long>& offsets, + UList<long long>& faces, + UList<long long>& facesOffsets, + foamVtkMeshMaps& maps +) const +{ + presizeMaps(maps); + + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + maps.cellMap(), + maps.additionalIds() + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<int>& connectivity, + UList<int>& offsets, + UList<int>& faces, + UList<int>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds +) const +{ + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + cellMap, + addPointsIds + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long>& connectivity, + UList<long>& offsets, + UList<long>& faces, + UList<long>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds +) const +{ + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + cellMap, + addPointsIds + ); +} + + +void Foam::vtk::vtuSizing::populateInternal +( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long long>& connectivity, + UList<long long>& offsets, + UList<long long>& faces, + UList<long long>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds +) const +{ + populateArrays + ( + mesh, + *this, + cellTypes, + connectivity, + offsets, + faces, + facesOffsets, + contentType::INTERNAL, + cellMap, + addPointsIds + ); +} + + +void Foam::vtk::vtuSizing::clear() +{ + decompose_ = false; + nCells_ = 0; + nPoints_ = 0; + nVertLabels_ = 0; + + nFaceLabels_ = 0; + nCellsPoly_ = 0; + nVertPoly_ = 0; + + nAddCells_ = 0; + nAddPoints_ = 0; + nAddVerts_ = 0; +} + + +void Foam::vtk::vtuSizing::info(Ostream& os) const +{ + os << "nFieldCells:" << nFieldCells(); + if (nAddCells_) + { + os << " (" << nCells_ + << "+" << nAddCells_ << ")"; + } + else + { + os << " (poly:" << nCellsPoly_ << ")"; + } + + os << " nFieldPoints:" << nFieldPoints(); + if (nAddPoints_) + { + os << " (" << nPoints_ << "+" << nAddPoints_ << ")"; + } + + os << " nVertLabels:" << (nVertLabels_ + nAddVerts_); + if (nAddVerts_) + { + os << " (" << nVertLabels_ << "+" << nAddVerts_ << ")"; + } + else if (nVertPoly_) + { + os << " (poly:" << nVertPoly_ << ")"; + } + + os << " nFaceLabels:" << nFaceLabels_; + os << " legacy-count:" << sizeLegacy(); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +bool Foam::vtk::vtuSizing::operator==(const vtuSizing& rhs) const +{ + return + ( + decompose() == rhs.decompose() + && nCells() == rhs.nCells() + && nPoints() == rhs.nPoints() + && nVertLabels() == rhs.nVertLabels() + && nFaceLabels() == rhs.nFaceLabels() + && nCellsPoly() == rhs.nCellsPoly() + && nVertPoly() == rhs.nVertPoly() + && nAddCells() == rhs.nAddCells() + && nAddPoints() == rhs.nAddPoints() + && nAddVerts() == rhs.nAddVerts() + ); +} + + +bool Foam::vtk::vtuSizing::operator!=(const vtuSizing& rhs) const +{ + return !operator==(rhs); +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuSizing.H b/src/conversion/vtk/part/foamVtuSizing.H new file mode 100644 index 0000000000000000000000000000000000000000..a14209807a9a1945fb20fae37e5f7d620a021c8b --- /dev/null +++ b/src/conversion/vtk/part/foamVtuSizing.H @@ -0,0 +1,413 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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::vtuSizing + +Description + Sizing descriptions and routines for transcribing an OpenFOAM volume mesh + into a VTK unstructured grid, with possible decomposition of polyhedral + cells into primitive cell types. + + This class is intended to populate externally allocated arrays with content + that is compatible with what VTK expects. This approach allows an improved + separation of the OpenFOAM mesh description and the storage, and allows + support of alternative storage containers (eg, std::vector, vtkDataArray). + The ideal goal would be a zero-copy mechanism, but this does not work for + several reasons: + \par + - OpenFOAM and VTK have different point ordering for prism + - polyhedral decomposition + - face-stream are required for VTK + - VTK internal storage includes list size as part of the data + - VTK includes storage may be a different base size (eg, long long) + compared to the OpenFOAM label. + + \par Data Entries (slots) + + These are the storage entries normally associate with each output-type: + \table + legacy output + \c types | vtk cell type (1-255) + \c cells | nLabels and unique vertex labels used by the cell, or + | [nLabels nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] + \endtable + + \table + xml output + \c types | vtk cell type (1-255) + \c connectivity | unique vertex labels used by the cell + \c offsets | end offset for each of \c connectivity + \c faces | face stream for polyhedral cells + | [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] + \c faceoffsets | end offset for each of \c faces, with -1 for primitive cells + \endtable + + \table + internal storage + \c types | vtk cell type (1-255) + \c connectivity | nLabels and unique vertex labels used by the cell + \c location | begin location for each of \c connectivity + \c faces | face stream for polyhedral cells + | [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] + \c facelocation | begin location for each of \c faces, with -1 for primitive cells + \endtable + + The VTK storage concept for "connectivity" and "faces" somewhat resemble + a CompactListList. + +SourceFiles + foamVtuSizing.C + foamVtuSizingI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtuSizing_H +#define foamVtuSizing_H + +#include "label.H" +#include "labelList.H" +#include "foamVtkMeshMaps.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class polyMesh; + +namespace vtk +{ + +/*---------------------------------------------------------------------------*\ + Class Foam::vtk::vtuSizing Declaration +\*---------------------------------------------------------------------------*/ + +class vtuSizing +{ +public: + + // Public data + + //- Types of content that the storage may represent + enum contentType + { + LEGACY, //!< Legacy VTK content + XML, //!< XML (VTU) content + INTERNAL //!< Internal vtkUnstructuredGrid content + }; + + //- The possible storage 'slots' that can be used + enum slotType + { + CELLS, //!< Cell connectivity (ALL) + CELLS_OFFSETS, //!< End-offsets (XML) or locations (INTERNAL) for cells + FACES, //!< Face-stream (XML, INTERNAL) + FACES_OFFSETS //!< End-offsets (XML) or locations (INTERNAL) for faces + }; + + +private: + + // Private Member Data + + //- Polyhedral decomposition requested + bool decompose_; + + //- Number of cells in the mesh + label nCells_; + + //- Number of points in the mesh + label nPoints_; + + //- Number of vertex labels to represent the mesh + label nVertLabels_; + + // Polyhedrals + + //- Number of polyhedral face labels for the mesh + label nFaceLabels_; + + //- Number of polyhedral cells (informational) + label nCellsPoly_; + + //- Number of vertex labels used by polyhedrals + label nVertPoly_; + + // Decomposed polyhedrals + + //- Number of additional (decomposed) cells for the mesh + label nAddCells_; + + //- Number of additional (decomposed) points for the mesh + label nAddPoints_; + + //- Number of additional (decomposed) vertices for the mesh + label nAddVerts_; + + + // Private Member Functions + + //- set-size for cellMap and additionalIds + void presizeMaps(foamVtkMeshMaps& maps) const; + + //- Populate lists for internal VTK representation + template<class LabelType, class LabelType2> + static void populateArrays + ( + const polyMesh& mesh, + const vtk::vtuSizing& sizing, + UList<uint8_t>& cellTypes, + UList<LabelType>& vertLabels, + UList<LabelType>& vertOffset, + UList<LabelType>& faceLabels, + UList<LabelType>& faceOffset, + const enum contentType output, + UList<LabelType2>& cellMap, + UList<LabelType2>& addPointsIds + ); + + // Allow default bitwise copy/assignment + +public: + + // Constructors + + //- Construct null. + vtuSizing(); + + //- Construct sizes by analyzing the mesh, + // optionally with polyhedral decomposition. + vtuSizing(const polyMesh& mesh, const bool decompose=false); + + + //- Destructor + ~vtuSizing(); + + + // Member Functions + + // Edit + + //- Construct sizes by analyzing the mesh, + // optionally with polyhedral decomposition. + void reset(const polyMesh& mesh, const bool decompose=false); + + //- Reset all sizes to zero. + void clear(); + + + // Access + + //- Query the decompose flag + inline bool decompose() const; + + //- Number of cells for the mesh + inline label nCells() const; + + //- Number of points for the mesh + inline label nPoints() const; + + //- Number of vertex labels for the mesh + inline label nVertLabels() const; + + //- Number of polyhedral face labels for the mesh + inline label nFaceLabels() const; + + //- Number of polyhedral cells for the mesh + inline label nCellsPoly() const; + + //- Number of vertex labels for polyhedral cells of the mesh + inline label nVertPoly() const; + + //- Number of additional (decomposed) cells for the mesh + inline label nAddCells() const; + + //- Number of additional (decomposed) points for the mesh + inline label nAddPoints() const; + + //- Number of additional (decomposed) vertices for the mesh + inline label nAddVerts() const; + + + //- Number of field cells = nCells + nAddCells + inline label nFieldCells() const; + + //- Number of field points = nPoints + nAddPoints + inline label nFieldPoints() const; + + + // Derived sizes + + //- Return the required size for the storage slot + label sizeOf + ( + const enum contentType output, + const enum slotType slot + ) const; + + + //- The calculated size for legacy storage + inline label sizeLegacy() const; + + //- The calculated size for legacy storage of the specified slot + inline label sizeLegacy(const enum slotType slot) const; + + //- The calculated size for xml storage of the specified slot + inline label sizeXml(const enum slotType slot) const; + + //- The calculated size for vtk-internal storage of the specified slot + inline label sizeInternal(const enum slotType slot) const; + + + // Utilty routines + + //- Populate lists for Legacy output + void populateLegacy + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<label>& connectivity, + foamVtkMeshMaps& maps + ) const; + + //- Populate lists for XML output + void populateXml + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<label>& connectivity, + UList<label>& offsets, + UList<label>& faces, + UList<label>& facesOffsets, + foamVtkMeshMaps& maps + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<int>& connectivity, + UList<int>& offsets, + UList<int>& faces, + UList<int>& facesOffsets, + foamVtkMeshMaps& maps + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long>& connectivity, + UList<long>& offsets, + UList<long>& faces, + UList<long>& facesOffsets, + foamVtkMeshMaps& maps + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long long>& connectivity, + UList<long long>& offsets, + UList<long long>& faces, + UList<long long>& facesOffsets, + foamVtkMeshMaps& maps + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<int>& connectivity, + UList<int>& offsets, + UList<int>& faces, + UList<int>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long>& connectivity, + UList<long>& offsets, + UList<long>& faces, + UList<long>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds + ) const; + + //- Populate lists for Internal VTK format + void populateInternal + ( + const polyMesh& mesh, + UList<uint8_t>& cellTypes, + UList<long long>& connectivity, + UList<long long>& offsets, + UList<long long>& faces, + UList<long long>& facesOffsets, + UList<label>& cellMap, + UList<label>& addPointsIds + ) const; + + + // Write + + //- Report some information + void info(Ostream& os) const; + + + // Member Operators + + //- Test equality + bool operator==(const vtuSizing& rhs) const; + + //- Test inequality + bool operator!=(const vtuSizing& rhs) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "foamVtuSizingI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuSizingI.H b/src/conversion/vtk/part/foamVtuSizingI.H new file mode 100644 index 0000000000000000000000000000000000000000..6777ce7e7a91fac943560487ffe0169d9023ebc2 --- /dev/null +++ b/src/conversion/vtk/part/foamVtuSizingI.H @@ -0,0 +1,135 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "foamVtuSizing.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline bool Foam::vtk::vtuSizing::decompose() const +{ + return decompose_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nCells() const +{ + return nCells_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nPoints() const +{ + return nPoints_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nVertLabels() const +{ + return nVertLabels_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nFaceLabels() const +{ + return nFaceLabels_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nCellsPoly() const +{ + return nCellsPoly_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nVertPoly() const +{ + return nVertPoly_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nAddCells() const +{ + return nAddCells_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nAddPoints() const +{ + return nAddPoints_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nAddVerts() const +{ + return nAddVerts_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nFieldCells() const +{ + return nCells_ + nAddCells_; +} + + +inline Foam::label Foam::vtk::vtuSizing::nFieldPoints() const +{ + return nPoints_ + nAddPoints_; +} + + +inline Foam::label Foam::vtk::vtuSizing::sizeLegacy() const +{ + return sizeOf(contentType::LEGACY, slotType::CELLS); +} + + +inline Foam::label Foam::vtk::vtuSizing::sizeLegacy +( + const enum slotType slot +) const +{ + return sizeOf(contentType::LEGACY, slot); +} + + +inline Foam::label Foam::vtk::vtuSizing::sizeXml +( + const enum slotType slot +) const +{ + return sizeOf(contentType::XML, slot); +} + + +inline Foam::label Foam::vtk::vtuSizing::sizeInternal +( + const enum slotType slot +) const +{ + return sizeOf(contentType::INTERNAL, slot); +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/part/foamVtuSizingTemplates.C b/src/conversion/vtk/part/foamVtuSizingTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..0c4ffe44ac81b1cb19a244f13d6495d2bc395b06 --- /dev/null +++ b/src/conversion/vtk/part/foamVtuSizingTemplates.C @@ -0,0 +1,668 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtuSizing.H" +#include "foamVtkCore.H" +#include "polyMesh.H" +#include "cellShape.H" +#include "cellModeller.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class LabelType, class LabelType2> +void Foam::vtk::vtuSizing::populateArrays +( + const polyMesh& mesh, + const vtk::vtuSizing& sizing, + UList<uint8_t>& cellTypes, + UList<LabelType>& vertLabels, + UList<LabelType>& vertOffset, + UList<LabelType>& faceLabels, + UList<LabelType>& faceOffset, + const enum contentType output, + UList<LabelType2>& cellMap, + UList<LabelType2>& addPointsIds +) +{ + // STAGE 1: Verify storage sizes + + if (cellTypes.size() != sizing.nFieldCells()) + { + FatalErrorInFunction + << " cellTypes size=" << cellTypes.size() + << " expected " << sizing.nFieldCells() + << exit(FatalError); + } + + if (cellMap.size() != sizing.nFieldCells()) + { + FatalErrorInFunction + << " cellMap size=" << cellMap.size() + << " expected " << sizing.nFieldCells() + << exit(FatalError); + } + + if (addPointsIds.size() != sizing.nAddPoints()) + { + FatalErrorInFunction + << " addPointsIds size=" << addPointsIds.size() + << " expected " << sizing.nAddPoints() + << exit(FatalError); + } + + // Prefix vertLabels with the size too? + // Also use as the size of the prefixed information + const int prefix = (output != contentType::XML) ? 1 : 0; + + switch (output) + { + case contentType::LEGACY: + { + if (vertLabels.size() != sizing.sizeLegacy()) + { + FatalErrorInFunction + << " legacy size=" << vertLabels.size() + << " expected " << sizing.sizeLegacy() + << exit(FatalError); + } + break; + } + case contentType::XML: + { + // XML uses connectivity/offset pair. + if + ( + vertLabels.size() + != sizing.sizeXml(slotType::CELLS) + ) + { + FatalErrorInFunction + << " connectivity size=" << vertLabels.size() + << " expected " + << sizing.sizeXml(slotType::CELLS) + << exit(FatalError); + } + + if + ( + vertOffset.size() + != sizing.sizeXml(slotType::CELLS_OFFSETS) + ) + { + FatalErrorInFunction + << " offsets size=" << vertOffset.size() + << " expected " + << sizing.sizeXml(slotType::CELLS_OFFSETS) + << exit(FatalError); + } + + if (sizing.nFaceLabels()) + { + if + ( + faceLabels.size() + != sizing.sizeXml(slotType::FACES) + ) + { + FatalErrorInFunction + << " faces size=" << faceLabels.size() + << " expected " + << sizing.sizeXml(slotType::FACES) + << exit(FatalError); + } + + if + ( + faceOffset.size() + != sizing.sizeXml(slotType::FACES_OFFSETS) + ) + { + FatalErrorInFunction + << " facesOffsets size=" << faceOffset.size() + << " expected " + << sizing.sizeXml(slotType::FACES_OFFSETS) + << exit(FatalError); + } + } + break; + } + case contentType::INTERNAL: + { + // VTK-internal connectivity/offset pair. + if + ( + vertLabels.size() + != sizing.sizeInternal(slotType::CELLS) + ) + { + FatalErrorInFunction + << " connectivity size=" << vertLabels.size() + << " expected " + << sizing.sizeInternal(slotType::CELLS) + << exit(FatalError); + } + + if + ( + vertOffset.size() + != sizing.sizeInternal(slotType::CELLS_OFFSETS) + ) + { + FatalErrorInFunction + << " offsets size=" << vertOffset.size() + << " expected " + << sizing.sizeInternal(slotType::CELLS_OFFSETS) + << exit(FatalError); + } + + if (sizing.nFaceLabels()) + { + if + ( + faceLabels.size() + != sizing.sizeInternal(slotType::FACES) + ) + { + FatalErrorInFunction + << " faces size=" << faceLabels.size() + << " expected " + << sizing.sizeInternal(slotType::FACES) + << exit(FatalError); + } + + if + ( + faceOffset.size() + != sizing.sizeInternal(slotType::FACES_OFFSETS) + ) + { + FatalErrorInFunction + << " facesOffsets size=" << faceOffset.size() + << " expected " + << sizing.sizeInternal(slotType::FACES_OFFSETS) + << exit(FatalError); + } + } + break; + } + } + + + faceOffset = -1; + + const cellModel& tet = *(cellModeller::lookup("tet")); + const cellModel& pyr = *(cellModeller::lookup("pyr")); + const cellModel& prism = *(cellModeller::lookup("prism")); + const cellModel& wedge = *(cellModeller::lookup("wedge")); + const cellModel& tetWedge = *(cellModeller::lookup("tetWedge")); + const cellModel& hex = *(cellModeller::lookup("hex")); + + const cellShapeList& shapes = mesh.cellShapes(); + + // face owner is needed to determine the face orientation + const labelList& owner = mesh.faceOwner(); + + // Unique vertex labels per polyhedral + HashSet<label> hashUniqId(2*256); + + // Index into vertLabels, faceLabels for normal cells + label nVertLabels = 0; + label nFaceLabels = 0; + + // Index into vertLabels for decomposed polys + label nVertDecomp = sizing.nVertLabels() + prefix*sizing.nCells(); + + // Placement of decomposed cells + label nCellDecomp = mesh.nCells(); + + // Placement of additional point labels + label nPointDecomp = 0; + + // Non-decomposed polyhedral are represented as a face-stream. + // For legacy format, this stream replaces the normal connectivity + // information. Use references to alias where the face output should land. + + UList<LabelType>& faceOutput = + ( + output == contentType::LEGACY + ? vertLabels + : faceLabels + ); + + label& faceIndexer = + ( + output == contentType::LEGACY + ? nVertLabels + : nFaceLabels + ); + + // =========================================== + // STAGE 2: Rewrite in VTK form + // During this stage, the vertOffset contains the *size* associated with + // the per-cell vertLabels entries, and the faceOffset contains the *size* + // associated with the per-cell faceLabels. + + forAll(shapes, celli) + { + const cellShape& shape = shapes[celli]; + const cellModel& model = shape.model(); + + cellMap[celli] = celli; + + if (model == tet) + { + cellTypes[celli] = vtk::cellType::VTK_TETRA; + if (vertOffset.size()) + { + vertOffset[celli] = shape.size(); + } + if (prefix) + { + vertLabels[nVertLabels++] = shape.size(); + } + + forAll(shape, i) + { + vertLabels[nVertLabels++] = shape[i]; + } + } + else if (model == pyr) + { + cellTypes[celli] = vtk::cellType::VTK_PYRAMID; + if (vertOffset.size()) + { + vertOffset[celli] = shape.size(); + } + if (prefix) + { + vertLabels[nVertLabels++] = shape.size(); + } + + forAll(shape, i) + { + vertLabels[nVertLabels++] = shape[i]; + } + } + else if (model == hex) + { + cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; + if (vertOffset.size()) + { + vertOffset[celli] = shape.size(); + } + if (prefix) + { + vertLabels[nVertLabels++] = shape.size(); + } + + forAll(shape, i) + { + vertLabels[nVertLabels++] = shape[i]; + } + } + else if (model == prism) + { + cellTypes[celli] = vtk::cellType::VTK_WEDGE; + if (vertOffset.size()) + { + vertOffset[celli] = shape.size(); + } + if (prefix) + { + vertLabels[nVertLabels++] = shape.size(); + } + + // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5) + vertLabels[nVertLabels++] = shape[0]; + vertLabels[nVertLabels++] = shape[2]; + vertLabels[nVertLabels++] = shape[1]; + vertLabels[nVertLabels++] = shape[3]; + vertLabels[nVertLabels++] = shape[5]; + vertLabels[nVertLabels++] = shape[4]; + } + else if (model == tetWedge && sizing.decompose()) + { + // Treat as squeezed prism + cellTypes[celli] = vtk::cellType::VTK_WEDGE; + if (vertOffset.size()) + { + vertOffset[celli] = 6; + } + if (prefix) + { + vertLabels[nVertLabels++] = 6; + } + + vertLabels[nVertLabels++] = shape[0]; + vertLabels[nVertLabels++] = shape[2]; + vertLabels[nVertLabels++] = shape[1]; + vertLabels[nVertLabels++] = shape[3]; + vertLabels[nVertLabels++] = shape[4]; + vertLabels[nVertLabels++] = shape[3]; + } + else if (model == wedge && sizing.decompose()) + { + // Treat as squeezed hex + cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; + if (vertOffset.size()) + { + vertOffset[celli] = 8; + } + if (prefix) + { + vertLabels[nVertLabels++] = 8; + } + + vertLabels[nVertLabels++] = shape[0]; + vertLabels[nVertLabels++] = shape[1]; + vertLabels[nVertLabels++] = shape[2]; + vertLabels[nVertLabels++] = shape[2]; + vertLabels[nVertLabels++] = shape[3]; + vertLabels[nVertLabels++] = shape[4]; + vertLabels[nVertLabels++] = shape[5]; + vertLabels[nVertLabels++] = shape[6]; + } + else if (sizing.decompose()) + { + // Polyhedral cell - decompose into tet/pyr. + + // Ensure we have the correct orientation for the base of the + // primitive cell shape. + // If the cell is face owner, the orientation needs to be flipped + // to avoid defining negative cells. + // VTK may not care, but we'll do it anyhow for safety. + + // Mapping from additional point to cell, and the new vertex from + // the cell-centre + const label newVertexLabel = mesh.nPoints() + nPointDecomp; + + addPointsIds[nPointDecomp++] = celli; + + // Whether to insert cell in place of original or not. + bool first = true; + + const labelList& cFaces = mesh.cells()[celli]; + forAll(cFaces, cFaceI) + { + const face& f = mesh.faces()[cFaces[cFaceI]]; + const bool isOwner = (owner[cFaces[cFaceI]] == celli); + + // Count triangles/quads in decomposition + label nTria = 0, nQuad = 0; + f.nTrianglesQuads(mesh.points(), nTria, nQuad); + + // Do actual decomposition + faceList faces3(nTria); + faceList faces4(nQuad); + nTria = 0, nQuad = 0; + f.trianglesQuads(mesh.points(), nTria, nQuad, faces3, faces4); + + forAll(faces4, fci) + { + // Quad becomes a pyramid + const face& quad = faces4[fci]; + const label nShapePoints = 5; // pyr (5 vertices) + + label celLoc, vrtLoc; + if (first) + { + first = false; + celLoc = celli; + vrtLoc = nVertLabels; + nVertLabels += prefix + nShapePoints; + } + else + { + celLoc = nCellDecomp++; + vrtLoc = nVertDecomp; + nVertDecomp += prefix + nShapePoints; + } + cellMap[celLoc] = celli; + + cellTypes[celLoc] = vtk::cellType::VTK_PYRAMID; + if (vertOffset.size()) + { + vertOffset[celLoc] = nShapePoints; + } + if (prefix) + { + vertLabels[vrtLoc++] = nShapePoints; + } + + // See note above about the orientation. + if (isOwner) + { + vertLabels[vrtLoc++] = quad[3]; + vertLabels[vrtLoc++] = quad[2]; + vertLabels[vrtLoc++] = quad[1]; + vertLabels[vrtLoc++] = quad[0]; + } + else + { + vertLabels[vrtLoc++] = quad[0]; + vertLabels[vrtLoc++] = quad[1]; + vertLabels[vrtLoc++] = quad[2]; + vertLabels[vrtLoc++] = quad[3]; + } + + vertLabels[vrtLoc++] = newVertexLabel; // apex + } + + forAll(faces3, fci) + { + // Triangle becomes a tetrahedral + const face& tria = faces3[fci]; + const label nShapePoints = 4; // tet (4 vertices) + + label celLoc, vrtLoc; + if (first) + { + first = false; + celLoc = celli; + vrtLoc = nVertLabels; + nVertLabels += prefix + nShapePoints; + } + else + { + celLoc = nCellDecomp++; + vrtLoc = nVertDecomp; + nVertDecomp += prefix + nShapePoints; + } + cellMap[celLoc] = celli; + + cellTypes[celLoc] = vtk::cellType::VTK_TETRA; + if (vertOffset.size()) + { + vertOffset[celLoc] = nShapePoints; + } + if (prefix) + { + vertLabels[vrtLoc++] = nShapePoints; + } + + cellTypes[celLoc] = vtk::cellType::VTK_TETRA; + + // See note above about the orientation. + if (isOwner) + { + vertLabels[vrtLoc++] = tria[2]; + vertLabels[vrtLoc++] = tria[1]; + vertLabels[vrtLoc++] = tria[0]; + } + else + { + vertLabels[vrtLoc++] = tria[0]; + vertLabels[vrtLoc++] = tria[1]; + vertLabels[vrtLoc++] = tria[2]; + } + vertLabels[vrtLoc++] = newVertexLabel; // apex + } + } + } + else + { + // Polyhedral cell - not decomposed + hashUniqId.clear(); // unique node ids used (XML, INTERNAL) + + // face-stream + // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...] + cellTypes[celli] = vtk::cellType::VTK_POLYHEDRON; + const labelList& cFaces = mesh.cells()[celli]; + + const label startLabel = faceIndexer; + + if (output == contentType::LEGACY) + { + faceOutput[startLabel] = 0; // placeholder for size + ++faceIndexer; + } + + faceOutput[faceIndexer++] = cFaces.size(); + + forAll(cFaces, cFaceI) + { + const face& f = mesh.faces()[cFaces[cFaceI]]; + const bool isOwner = (owner[cFaces[cFaceI]] == celli); + + forAll(f, fp) + { + hashUniqId.insert(f[fp]); + } + + // number of labels for this face + faceOutput[faceIndexer++] = f.size(); + + if (isOwner) + { + forAll(f, fp) + { + faceOutput[faceIndexer++] = f[fp]; + } + } + else + { + // fairly immaterial if we reverse the list + // or use face::reverseFace() + forAllReverse(f, fp) + { + faceOutput[faceIndexer++] = f[fp]; + } + } + } + + if (output == contentType::LEGACY) + { + // Update size for legacy face stream + faceOutput[startLabel] = (faceIndexer - startLabel); + } + else + { + // Size for face stream + faceOffset[celli] = (faceIndexer - startLabel); + + vertOffset[celli] = hashUniqId.size(); + if (prefix) + { + vertLabels[nVertLabels++] = hashUniqId.size(); + } + + const labelList uniq = hashUniqId.sortedToc(); + forAll(uniq, i) + { + vertLabels[nVertLabels++] = uniq[i]; + } + } + } + } + + // =========================================== + // STAGE 3: Adjust vertOffset for all cells + // A second pass is needed for several reasons. + // - Additional (decomposed) cells are placed out of sequence + // - Internal format has the size prefixed, XML format does not. + // - XML format expects end-offsets, Internal expects begin-offsets + + switch (output) + { + case contentType::LEGACY: // nothing to do + break; + + case contentType::XML: + { + // No prefix, determine end offsets + // vertOffset[0] already contains its size + for (label i = 1; i < vertOffset.size(); ++i) + { + vertOffset[i] += vertOffset[i-1]; + } + + if (sizing.nFaceLabels()) + { + // End face offsets, leaving -1 untouched + label prev = 0; + forAll(faceOffset, i) + { + const label sz = faceOffset[i]; + if (sz > 0) + { + prev += sz; + faceOffset[i] = prev; + } + } + } + break; + } + case contentType::INTERNAL: + { + // Has prefix, determine begin offsets + label beg = 0; + forAll(vertOffset, i) + { + const label sz = vertOffset[i]; + vertOffset[i] = beg; + beg += 1 + sz; + } + + // Begin face offsets, leaving -1 untouched + if (sizing.nFaceLabels()) + { + beg = 0; + forAll(faceOffset, i) + { + const label sz = faceOffset[i]; + if (sz > 0) + { + faceOffset[i] = beg; + beg += sz; + } + } + } + break; + } + } +} + + +// ************************************************************************* // diff --git a/src/fileFormats/Make/files b/src/fileFormats/Make/files index ab7fe26dc28d14e0a433dd49fb4a3dc37aab39ab..1dd9b3469a2679b3844693cd628dfeba20f7ef7d 100644 --- a/src/fileFormats/Make/files +++ b/src/fileFormats/Make/files @@ -14,17 +14,19 @@ stl/STLCore.C stl/STLReader.C stl/STLReaderASCII.L -vtk/foamVtkCore.C -vtk/format/foamVtkAppendBase64Formatter.C -vtk/format/foamVtkAppendRawFormatter.C +vtk/core/foamVtkCore.C +vtk/core/foamVtkPTraits.C +vtk/format/foamVtkFormatter.C vtk/format/foamVtkAsciiFormatter.C vtk/format/foamVtkBase64Formatter.C +vtk/format/foamVtkAppendBase64Formatter.C +vtk/format/foamVtkAppendRawFormatter.C vtk/format/foamVtkBase64Layer.C -vtk/format/foamVtkLegacyFormatter.C -vtk/format/foamVtkFormatter.C -vtk/format/foamVtkOutputOptions.C +vtk/format/foamVtkLegacyAsciiFormatter.C +vtk/format/foamVtkLegacyRawFormatter.C +vtk/output/foamVtkOutput.C +vtk/output/foamVtkOutputOptions.C vtk/read/vtkUnstructuredReader.C -vtk/type/foamVtkPTraits.C coordSet/coordSet.C diff --git a/src/fileFormats/sampledSetWriters/vtk/vtkSetWriter.C b/src/fileFormats/sampledSetWriters/vtk/vtkSetWriter.C index 87996eeff58910db32a716548cb5572c5920979d..f48080f69dbfd9f8e103e3dfd0611151edfca089 100644 --- a/src/fileFormats/sampledSetWriters/vtk/vtkSetWriter.C +++ b/src/fileFormats/sampledSetWriters/vtk/vtkSetWriter.C @@ -79,7 +79,6 @@ void Foam::vtkSetWriter<Type>::write os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl; } - os << "POINT_DATA " << points.size() << nl << " FIELD attributes " << valueSetNames.size() << nl; diff --git a/src/fileFormats/vtk/core/foamVtkCore.C b/src/fileFormats/vtk/core/foamVtkCore.C new file mode 100644 index 0000000000000000000000000000000000000000..be0cffa033ed79ea971d761a6457c5f2b8e25ea1 --- /dev/null +++ b/src/fileFormats/vtk/core/foamVtkCore.C @@ -0,0 +1,71 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "foamVtkCore.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +const Foam::Enum<Foam::vtk::fileTag> Foam::vtk::fileTagNames +{ + { fileTag::VTK_FILE, "VTKFile" }, + { fileTag::DATA_ARRAY, "DataArray" }, + { fileTag::PIECE, "Piece" }, + { fileTag::DATA_SET, "DataSet" }, + { fileTag::POINTS, "Points" }, + { fileTag::CELLS, "Cells" }, + { fileTag::POLYS, "Polys" }, + { fileTag::VERTS, "Verts" }, + { fileTag::LINES, "Lines" }, + { fileTag::CELL_DATA, "CellData" }, + { fileTag::POINT_DATA, "PointData" }, + { fileTag::POLY_DATA, "PolyData" }, + { fileTag::UNSTRUCTURED_GRID, "UnstructuredGrid" }, +}; + + +const Foam::Enum<Foam::vtk::fileAttr> Foam::vtk::fileAttrNames +{ + { fileAttr::OFFSET, "offset" }, + { fileAttr::NUMBER_OF_COMPONENTS, "NumberOfComponents" }, + { fileAttr::NUMBER_OF_POINTS, "NumberOfPoints" }, + { fileAttr::NUMBER_OF_CELLS, "NumberOfCells" }, + { fileAttr::NUMBER_OF_POLYS, "NumberOfPolys" }, + { fileAttr::NUMBER_OF_VERTS, "NumberOfVerts" }, + { fileAttr::NUMBER_OF_LINES, "NumberOfLines" }, +}; + + +const Foam::Enum<Foam::vtk::dataArrayAttr> Foam::vtk::dataArrayAttrNames +{ + { dataArrayAttr::POINTS, "Points" }, + { dataArrayAttr::OFFSETS, "offsets" }, + { dataArrayAttr::CONNECTIVITY, "connectivity" }, + { dataArrayAttr::TYPES, "types" }, + { dataArrayAttr::FACES, "faces" }, + { dataArrayAttr::FACEOFFSETS, "faceoffsets" }, +}; + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/core/foamVtkCore.H b/src/fileFormats/vtk/core/foamVtkCore.H new file mode 100644 index 0000000000000000000000000000000000000000..d209d60c9315ac608c86e34d839dd7f495b23697 --- /dev/null +++ b/src/fileFormats/vtk/core/foamVtkCore.H @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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/>. + +Namespace + Foam::vtk + +Description + Namespace for handling VTK input/output. + +SourceFiles + foamVtkCore.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkCore_H +#define foamVtkCore_H + +#include "Enum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace vtk +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + // Enumerations + + //- The context when outputting a VTK file (XML or legacy). + enum OutputContext + { + INLINE, //<! Generate header and inline data + HEADER, //<! Generate header only + APPEND //<! Generate append-data + }; + + + //- The output format type for file contents. + // Upper bits for output type, lower bits for the format itself. + enum class formatType + { + /** 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, + }; + + //- Equivalent to enumeration in "vtkCellType.h" + enum cellType + { + VTK_EMPTY_CELL = 0, + VTK_VERTEX = 1, + VTK_POLY_VERTEX = 2, + VTK_LINE = 3, + VTK_POLY_LINE = 4, + VTK_TRIANGLE = 5, + VTK_TRIANGLE_STRIP = 6, + VTK_POLYGON = 7, + VTK_PIXEL = 8, + VTK_QUAD = 9, + VTK_TETRA = 10, + VTK_VOXEL = 11, + VTK_HEXAHEDRON = 12, + VTK_WEDGE = 13, + VTK_PYRAMID = 14, + VTK_PENTAGONAL_PRISM = 15, + VTK_HEXAGONAL_PRISM = 16, + VTK_POLYHEDRON = 42 + }; + + + //- Some common XML tags for vtk files + enum class fileTag + { + VTK_FILE, //!< "VTKFile" + DATA_ARRAY, //!< "DataArray" + PIECE, //!< "Piece" + DATA_SET, //!< "DataSet" + POINTS, //!< "Points" + CELLS, //!< "Cells" + POLYS, //!< "Polys" + VERTS, //!< "Verts" + LINES, //!< "Lines" + CELL_DATA, //!< "CellData" + POINT_DATA, //!< "PointData" + POLY_DATA, //!< "PolyData" + UNSTRUCTURED_GRID, //!< "UnstructuredGrid" + }; + + //- Strings corresponding to the vtk xml tags + extern const Foam::Enum<fileTag> fileTagNames; + + //- Some common XML attributes for vtk files + enum class fileAttr + { + OFFSET, //!< "offset" + NUMBER_OF_COMPONENTS, //!< "NumberOfComponents" + NUMBER_OF_POINTS, //!< "NumberOfPoints" + NUMBER_OF_CELLS, //!< "NumberOfCells" + NUMBER_OF_POLYS, //!< "NumberOfPolys" + NUMBER_OF_VERTS, //!< "NumberOfVerts" + NUMBER_OF_LINES, //!< "NumberOfLines" + }; + + //- Strings corresponding to the vtk xml attributes + extern const Foam::Enum<fileAttr> fileAttrNames; + + //- Some common names for XML data arrays + enum class dataArrayAttr + { + POINTS, //!< "Points" + OFFSETS, //!< "offsets" + CONNECTIVITY, //!< "connectivity" + TYPES, //!< "types" + FACES, //!< "faces" + FACEOFFSETS, //!< "faceoffsets" + }; + + //- Strings corresponding to the vtk xml attributes + extern const Foam::Enum<dataArrayAttr> dataArrayAttrNames; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/type/foamVtkPTraits.C b/src/fileFormats/vtk/core/foamVtkPTraits.C similarity index 77% rename from src/fileFormats/vtk/type/foamVtkPTraits.C rename to src/fileFormats/vtk/core/foamVtkPTraits.C index feb5e909c25c5b20d239452ce851f3ea431b18f9..0cc5ca04e49720ba33bc279637be951e5801f9ba 100644 --- a/src/fileFormats/vtk/type/foamVtkPTraits.C +++ b/src/fileFormats/vtk/core/foamVtkPTraits.C @@ -30,40 +30,40 @@ License template<> const char* const -Foam::foamVtkPTraits<uint8_t>::typeName = "UInt8"; +Foam::vtkPTraits<uint8_t>::typeName = "UInt8"; template<> const char * const -Foam::foamVtkPTraits<int32_t>::typeName = "Int32"; +Foam::vtkPTraits<int32_t>::typeName = "Int32"; template<> const char * const -Foam::foamVtkPTraits<uint32_t>::typeName = "UInt32"; +Foam::vtkPTraits<uint32_t>::typeName = "UInt32"; template<> const char * const -Foam::foamVtkPTraits<int64_t>::typeName = "Int64"; +Foam::vtkPTraits<int64_t>::typeName = "Int64"; template<> const char * const -Foam::foamVtkPTraits<uint64_t>::typeName = "UInt64"; +Foam::vtkPTraits<uint64_t>::typeName = "UInt64"; template<> const char * const -Foam::foamVtkPTraits<float>::typeName = "Float32"; +Foam::vtkPTraits<float>::typeName = "Float32"; template<> const char * const -Foam::foamVtkPTraits<double>::typeName = "Float64"; +Foam::vtkPTraits<double>::typeName = "Float64"; #ifdef WM_LITTLE_ENDIAN template<> const char* const -Foam::foamVtkPTraits<Foam::endian>::typeName = "LittleEndian"; +Foam::vtkPTraits<Foam::endian>::typeName = "LittleEndian"; #else template<> const char* const -Foam::foamVtkPTraits<Foam::endian>::typeName = "BigEndian"; +Foam::vtkPTraits<Foam::endian>::typeName = "BigEndian"; #endif diff --git a/src/fileFormats/vtk/type/foamVtkPTraits.H b/src/fileFormats/vtk/core/foamVtkPTraits.H similarity index 76% rename from src/fileFormats/vtk/type/foamVtkPTraits.H rename to src/fileFormats/vtk/core/foamVtkPTraits.H index ff77c03b8d9498f97737a2435e5235c9f6bba537..ac8df0664659fe746c0c1b32e286aca89f2975e1 100644 --- a/src/fileFormats/vtk/type/foamVtkPTraits.H +++ b/src/fileFormats/vtk/core/foamVtkPTraits.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::foamVtkPTraits + Foam::vtkPTraits Description Names for VTK primitive types. @@ -43,11 +43,11 @@ namespace Foam class endian; /*---------------------------------------------------------------------------*\ - Class foamVtkPTraits Declaration + Class vtkPTraits Declaration \*---------------------------------------------------------------------------*/ template<class PrimitiveType> -class foamVtkPTraits +class vtkPTraits { public: @@ -58,28 +58,28 @@ public: template<> -const char* const foamVtkPTraits<uint8_t>::typeName; // UInt8 +const char* const vtkPTraits<uint8_t>::typeName; // UInt8 template<> -const char* const foamVtkPTraits<int32_t>::typeName; // Int32 +const char* const vtkPTraits<int32_t>::typeName; // Int32 template<> -const char* const foamVtkPTraits<uint32_t>::typeName; // UInt32 +const char* const vtkPTraits<uint32_t>::typeName; // UInt32 template<> -const char* const foamVtkPTraits<int64_t>::typeName; // Int64 +const char* const vtkPTraits<int64_t>::typeName; // Int64 template<> -const char* const foamVtkPTraits<uint64_t>::typeName; // UInt64 +const char* const vtkPTraits<uint64_t>::typeName; // UInt64 template<> -const char* const foamVtkPTraits<float>::typeName; // Float32 +const char* const vtkPTraits<float>::typeName; // Float32 template<> -const char* const foamVtkPTraits<double>::typeName; // Float64 +const char* const vtkPTraits<double>::typeName; // Float64 template<> -const char* const foamVtkPTraits<Foam::endian>::typeName; // (Big|Little)Endian +const char* const vtkPTraits<Foam::endian>::typeName; // (Big|Little)Endian // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C index 3805b61812e783c4bddd29582c2cc442a45e815f..5527e5c35aefc28cc4ce9d9bbc34fae72e434002 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C +++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C @@ -24,15 +24,19 @@ License \*---------------------------------------------------------------------------*/ #include "foamVtkAppendBase64Formatter.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkAppendBase64Formatter::name_ = "append"; +const char* Foam::vtk::appendBase64Formatter::name_ = "append"; + +const Foam::vtk::outputOptions +Foam::vtk::appendBase64Formatter::opts_(formatType::APPEND_BASE64); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkAppendBase64Formatter::foamVtkAppendBase64Formatter +Foam::vtk::appendBase64Formatter::appendBase64Formatter ( std::ostream& os ) @@ -43,7 +47,7 @@ Foam::foamVtkAppendBase64Formatter::foamVtkAppendBase64Formatter // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkAppendBase64Formatter::~foamVtkAppendBase64Formatter() +Foam::vtk::appendBase64Formatter::~appendBase64Formatter() { base64Layer::close(); } @@ -51,7 +55,14 @@ Foam::foamVtkAppendBase64Formatter::~foamVtkAppendBase64Formatter() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkAppendBase64Formatter::name() const +const Foam::vtk::outputOptions& +Foam::vtk::appendBase64Formatter::opts() const +{ + return opts_; +} + + +const char* Foam::vtk::appendBase64Formatter::name() const { return name_; } diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H index db3e1d6694fffda7c0869e1ae43916bce97dc2fb..2df2e8ce508822ffe804bcabb6be3c69480ef591 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H +++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkAppendBase64Formatter + Foam::vtk::appendBase64Formatter Description Appended base-64 encoded binary output. @@ -42,27 +42,30 @@ SourceFiles namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkAppendBase64Formatter Declaration + Class appendBase64Formatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkAppendBase64Formatter +class appendBase64Formatter : public foamVtkBase64Layer { // Private Data Members static const char* name_; + static const outputOptions opts_; // Private Member Functions - //- Disallow default bitwise copy construct - foamVtkAppendBase64Formatter(const foamVtkAppendBase64Formatter&) = delete; + //- Disallow default bitwise copy construct + appendBase64Formatter(const appendBase64Formatter&) = delete; - //- Disallow default bitwise assignment - void operator=(const foamVtkAppendBase64Formatter&) = delete; + //- Disallow default bitwise assignment + void operator=(const appendBase64Formatter&) = delete; public: @@ -70,15 +73,18 @@ public: // Constructors //- Construct and attach to an output stream - foamVtkAppendBase64Formatter(std::ostream& os); + appendBase64Formatter(std::ostream& os); //- Destructor - virtual ~foamVtkAppendBase64Formatter(); + virtual ~appendBase64Formatter(); // Member Functions + //- The output is APPEND_BASE64. + virtual const outputOptions& opts() const; + //- Output name for XML type ("append") virtual const char* name() const; @@ -86,6 +92,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C index ae565323b8546a93739d9eca782a519a039f8b52..0ff9e5c4cd74b228be7193f07e200588ec1739df 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C @@ -24,16 +24,20 @@ License \*---------------------------------------------------------------------------*/ #include "foamVtkAppendRawFormatter.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkAppendRawFormatter::name_ = "append"; -const char* Foam::foamVtkAppendRawFormatter::encoding_ = "raw"; +const char* Foam::vtk::appendRawFormatter::name_ = "append"; +const char* Foam::vtk::appendRawFormatter::encoding_ = "raw"; + +const Foam::vtk::outputOptions +Foam::vtk::appendRawFormatter::opts_(formatType::APPEND_BINARY); // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::foamVtkAppendRawFormatter::write +void Foam::vtk::appendRawFormatter::write ( const char* s, std::streamsize n @@ -45,59 +49,66 @@ void Foam::foamVtkAppendRawFormatter::write // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkAppendRawFormatter::foamVtkAppendRawFormatter(std::ostream& os) +Foam::vtk::appendRawFormatter::appendRawFormatter(std::ostream& os) : - foamVtkFormatter(os) + formatter(os) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkAppendRawFormatter::~foamVtkAppendRawFormatter() +Foam::vtk::appendRawFormatter::~appendRawFormatter() {} // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkAppendRawFormatter::name() const +const Foam::vtk::outputOptions& +Foam::vtk::appendRawFormatter::opts() const +{ + return opts_; +} + + +const char* Foam::vtk::appendRawFormatter::name() const { return name_; } -const char* Foam::foamVtkAppendRawFormatter::encoding() const +const char* Foam::vtk::appendRawFormatter::encoding() const { return encoding_; } -void Foam::foamVtkAppendRawFormatter::writeSize(const uint64_t nBytes) +void Foam::vtk::appendRawFormatter::writeSize(const uint64_t nBytes) { write(reinterpret_cast<const char*>(&nBytes), sizeof(uint64_t)); } -void Foam::foamVtkAppendRawFormatter::write(const uint8_t val) +void Foam::vtk::appendRawFormatter::write(const uint8_t val) { write(reinterpret_cast<const char*>(&val), sizeof(uint8_t)); } -void Foam::foamVtkAppendRawFormatter::write(const label val) +void Foam::vtk::appendRawFormatter::write(const label val) { // std::cerr<<"label:" << sizeof(val) << "=" << val << '\n'; write(reinterpret_cast<const char*>(&val), sizeof(label)); } -void Foam::foamVtkAppendRawFormatter::write(const float val) +void Foam::vtk::appendRawFormatter::write(const float val) { // std::cerr<<"float:" << sizeof(val) << "=" << val << '\n'; write(reinterpret_cast<const char*>(&val), sizeof(float)); } -void Foam::foamVtkAppendRawFormatter::write(const double val) +void Foam::vtk::appendRawFormatter::write(const double val) { // std::cerr<<"double as float=" << val << '\n'; float copy(val); @@ -105,7 +116,7 @@ void Foam::foamVtkAppendRawFormatter::write(const double val) } -void Foam::foamVtkAppendRawFormatter::flush() +void Foam::vtk::appendRawFormatter::flush() {/*nop*/} diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H index 1dcb9b8d55c39a2fd3845947c0e2b8915effddbe..758fa8d93d964396e92f0f06759f519336c7f3e7 100644 --- a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkAppendRawFormatter + Foam::vtk::appendRawFormatter Description Appended raw binary output. @@ -41,27 +41,31 @@ SourceFiles namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkAppendRawFormatter Declaration + Class appendRawFormatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkAppendRawFormatter +class appendRawFormatter : - public foamVtkFormatter + public formatter { // Private Data Members static const char* name_; static const char* encoding_; + static const outputOptions opts_; + // Private Member Functions //- Disallow default bitwise copy construct - foamVtkAppendRawFormatter(const foamVtkAppendRawFormatter&) = delete; + appendRawFormatter(const appendRawFormatter&) = delete; //- Disallow default bitwise assignment - void operator=(const foamVtkAppendRawFormatter&) = delete; + void operator=(const appendRawFormatter&) = delete; protected: @@ -77,15 +81,18 @@ public: // Constructors //- Construct and attach to an output stream - foamVtkAppendRawFormatter(std::ostream& os); + appendRawFormatter(std::ostream& os); //- Destructor - virtual ~foamVtkAppendRawFormatter(); + virtual ~appendRawFormatter(); // Member Functions + //- The output is APPEND_BINARY. + virtual const outputOptions& opts() const; + //- Output name for XML type ("append") virtual const char* name() const; @@ -108,6 +115,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C index 9ed22db23303d3239a446e6328f435a7f8268c6f..1bcbc3b84cf40c8f7e8b1752bbcadb8fef62e516 100644 --- a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C @@ -24,15 +24,19 @@ License \*---------------------------------------------------------------------------*/ #include "foamVtkAsciiFormatter.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkAsciiFormatter::name_ = "ascii"; +const char* Foam::vtk::asciiFormatter::name_ = "ascii"; + +const Foam::vtk::outputOptions +Foam::vtk::asciiFormatter::opts_(formatType::INLINE_ASCII); // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -inline void Foam::foamVtkAsciiFormatter::next() +inline void Foam::vtk::asciiFormatter::next() { if (pos_ == 6) { @@ -47,7 +51,7 @@ inline void Foam::foamVtkAsciiFormatter::next() } -inline void Foam::foamVtkAsciiFormatter::done() +inline void Foam::vtk::asciiFormatter::done() { if (pos_) { @@ -59,20 +63,20 @@ inline void Foam::foamVtkAsciiFormatter::done() // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkAsciiFormatter::foamVtkAsciiFormatter(std::ostream& os) +Foam::vtk::asciiFormatter::asciiFormatter(std::ostream& os) : - foamVtkFormatter(os), + formatter(os), pos_(0) {} -Foam::foamVtkAsciiFormatter::foamVtkAsciiFormatter +Foam::vtk::asciiFormatter::asciiFormatter ( std::ostream& os, unsigned precision ) : - foamVtkFormatter(os), + formatter(os), pos_(0) { os.precision(precision); @@ -81,7 +85,7 @@ Foam::foamVtkAsciiFormatter::foamVtkAsciiFormatter // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkAsciiFormatter::~foamVtkAsciiFormatter() +Foam::vtk::asciiFormatter::~asciiFormatter() { done(); } @@ -89,58 +93,65 @@ Foam::foamVtkAsciiFormatter::~foamVtkAsciiFormatter() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkAsciiFormatter::name() const +const Foam::vtk::outputOptions& +Foam::vtk::asciiFormatter::opts() const +{ + return opts_; +} + + +const char* Foam::vtk::asciiFormatter::name() const { return name_; } -const char* Foam::foamVtkAsciiFormatter::encoding() const +const char* Foam::vtk::asciiFormatter::encoding() const { return name_; } -void Foam::foamVtkAsciiFormatter::writeSize(const uint64_t ignored) +void Foam::vtk::asciiFormatter::writeSize(const uint64_t ignored) {/*nop*/} -void Foam::foamVtkAsciiFormatter::write(const uint8_t val) +void Foam::vtk::asciiFormatter::write(const uint8_t val) { next(); os()<< int(val); } -void Foam::foamVtkAsciiFormatter::write(const label val) +void Foam::vtk::asciiFormatter::write(const label val) { next(); os()<< val; } -void Foam::foamVtkAsciiFormatter::write(const float val) +void Foam::vtk::asciiFormatter::write(const float val) { next(); os()<< val; } -void Foam::foamVtkAsciiFormatter::write(const double val) +void Foam::vtk::asciiFormatter::write(const double val) { next(); os()<< float(val); } -void Foam::foamVtkAsciiFormatter::flush() +void Foam::vtk::asciiFormatter::flush() { done(); } std::size_t -Foam::foamVtkAsciiFormatter::encodedLength(std::size_t ignored) const +Foam::vtk::asciiFormatter::encodedLength(std::size_t ignored) const { return 0; } diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H index 8b8e06b2a226c855c2243f89f4675aeb4bc2251c..bbedc55e91e138b78d834f7594cd2b4e4ef217fc 100644 --- a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H @@ -22,10 +22,10 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkAsciiFormatter + Foam::vtk::asciiFormatter Description - Inline ASCII binary output. + Inline ASCII output. Adds spaces between entries and a newline every 6 items (for consistency with what VTK itself outputs). @@ -43,18 +43,21 @@ SourceFiles namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkAsciiFormatter Declaration + Class asciiFormatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkAsciiFormatter +class asciiFormatter : - public foamVtkFormatter + public formatter { // Private Data Members static const char* name_; + static const outputOptions opts_; //- Track the current output position unsigned short pos_; @@ -70,10 +73,10 @@ class foamVtkAsciiFormatter //- Disallow default bitwise copy construct - foamVtkAsciiFormatter(const foamVtkAsciiFormatter&) = delete; + asciiFormatter(const asciiFormatter&) = delete; //- Disallow default bitwise assignment - void operator=(const foamVtkAsciiFormatter&) = delete; + void operator=(const asciiFormatter&) = delete; public: @@ -81,20 +84,22 @@ public: // Constructors //- Construct and attach to an output stream, use default precision - foamVtkAsciiFormatter(std::ostream& os); + asciiFormatter(std::ostream& os); //- Construct and attach to an output stream, use specified precision - foamVtkAsciiFormatter(std::ostream& os, unsigned precision); + asciiFormatter(std::ostream& os, unsigned precision); //- Destructor - virtual ~foamVtkAsciiFormatter(); + virtual ~asciiFormatter(); // Member Functions + //- The output is INLINE_ASCII. + virtual const outputOptions& opts() const; + //- Name for the XML output type ("ascii") - // The legacy output type is an uppercase version of this. virtual const char* name() const; //- Name for the XML append encoding - unused. @@ -120,6 +125,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkBase64Formatter.C index f87efbb19f4972a65dd02f9c40eb56800696e0bb..3e8d86be9545193e911a6850a6106342c76f4c16 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Formatter.C +++ b/src/fileFormats/vtk/format/foamVtkBase64Formatter.C @@ -24,15 +24,19 @@ License \*---------------------------------------------------------------------------*/ #include "foamVtkBase64Formatter.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkBase64Formatter::name_ = "binary"; +const char* Foam::vtk::base64Formatter::name_ = "binary"; + +const Foam::vtk::outputOptions +Foam::vtk::base64Formatter::opts_(formatType::INLINE_BASE64); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkBase64Formatter::foamVtkBase64Formatter(std::ostream& os) +Foam::vtk::base64Formatter::base64Formatter(std::ostream& os) : foamVtkBase64Layer(os) {} @@ -40,7 +44,7 @@ Foam::foamVtkBase64Formatter::foamVtkBase64Formatter(std::ostream& os) // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkBase64Formatter::~foamVtkBase64Formatter() +Foam::vtk::base64Formatter::~base64Formatter() { if (base64Layer::close()) { @@ -51,13 +55,20 @@ Foam::foamVtkBase64Formatter::~foamVtkBase64Formatter() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkBase64Formatter::name() const +const Foam::vtk::outputOptions& +Foam::vtk::base64Formatter::opts() const +{ + return opts_; +} + + +const char* Foam::vtk::base64Formatter::name() const { return name_; } -void Foam::foamVtkBase64Formatter::flush() +void Foam::vtk::base64Formatter::flush() { if (base64Layer::close()) { diff --git a/src/fileFormats/vtk/format/foamVtkBase64Formatter.H b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H index e92fa4f9e374c21c8ead9795234d6c777b8ab381..df27f23087be308cf51947694fe86c384ac265e4 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Formatter.H +++ b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkBase64Formatter + Foam::vtk::base64Formatter Description Inline base-64 encoded binary output. @@ -33,51 +33,57 @@ Description #ifndef foamVtkBase64Formatter_H #define foamVtkBase64Formatter_H +#include "foamVtkFormatter.H" #include "foamVtkBase64Layer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkBase64Formatter Declaration + Class base64Formatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkBase64Formatter +class base64Formatter : public foamVtkBase64Layer { // Private Data Members static const char* name_; - static const char* encoding_; + static const outputOptions opts_; // Private Member Functions //- Disallow default bitwise copy construct - foamVtkBase64Formatter(const foamVtkBase64Formatter&) = delete; + base64Formatter(const base64Formatter&) = delete; //- Disallow default bitwise assignment - void operator=(const foamVtkBase64Formatter&) = delete; + void operator=(const base64Formatter&) = delete; + public: // Constructors //- Construct and attach to an output stream - foamVtkBase64Formatter(std::ostream& os); + base64Formatter(std::ostream& os); //- Destructor - virtual ~foamVtkBase64Formatter(); + virtual ~base64Formatter(); // Member Functions + //- The output is INLINE_BASE64. + virtual const outputOptions& opts() const; + //- Name for the XML output type ("binary") - // The lowercase version of the Legacy output type. virtual const char* name() const; @@ -89,6 +95,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkBase64Layer.C b/src/fileFormats/vtk/format/foamVtkBase64Layer.C index d66970d522b7e356eb03e711557b66985939bcd2..500a8dce9c041f9d0f8a95d6b46ed095fbfa5c32 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Layer.C +++ b/src/fileFormats/vtk/format/foamVtkBase64Layer.C @@ -27,12 +27,12 @@ License // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkBase64Layer::encoding_ = "base64"; +const char* Foam::vtk::foamVtkBase64Layer::encoding_ = "base64"; // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::foamVtkBase64Layer::write +void Foam::vtk::foamVtkBase64Layer::write ( const char* s, std::streamsize n @@ -44,16 +44,16 @@ void Foam::foamVtkBase64Layer::write // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkBase64Layer::foamVtkBase64Layer(std::ostream& os) +Foam::vtk::foamVtkBase64Layer::foamVtkBase64Layer(std::ostream& os) : - foamVtkFormatter(os), + formatter(os), base64Layer(os) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkBase64Layer::~foamVtkBase64Layer() +Foam::vtk::foamVtkBase64Layer::~foamVtkBase64Layer() { base64Layer::close(); } @@ -61,39 +61,39 @@ Foam::foamVtkBase64Layer::~foamVtkBase64Layer() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkBase64Layer::encoding() const +const char* Foam::vtk::foamVtkBase64Layer::encoding() const { return encoding_; } -void Foam::foamVtkBase64Layer::writeSize(const uint64_t nBytes) +void Foam::vtk::foamVtkBase64Layer::writeSize(const uint64_t nBytes) { write(reinterpret_cast<const char*>(&nBytes), sizeof(uint64_t)); } -void Foam::foamVtkBase64Layer::write(const uint8_t val) +void Foam::vtk::foamVtkBase64Layer::write(const uint8_t val) { base64Layer::add(val); } -void Foam::foamVtkBase64Layer::write(const label val) +void Foam::vtk::foamVtkBase64Layer::write(const label val) { // std::cerr<<"label:" << sizeof(val) << "=" << val << '\n'; write(reinterpret_cast<const char*>(&val), sizeof(label)); } -void Foam::foamVtkBase64Layer::write(const float val) +void Foam::vtk::foamVtkBase64Layer::write(const float val) { // std::cerr<<"float:" << sizeof(val) << "=" << val << '\n'; write(reinterpret_cast<const char*>(&val), sizeof(float)); } -void Foam::foamVtkBase64Layer::write(const double val) +void Foam::vtk::foamVtkBase64Layer::write(const double val) { // std::cerr<<"double as float=" << val << '\n'; float copy(val); @@ -101,13 +101,16 @@ void Foam::foamVtkBase64Layer::write(const double val) } -void Foam::foamVtkBase64Layer::flush() +void Foam::vtk::foamVtkBase64Layer::flush() { base64Layer::close(); } -std::size_t Foam::foamVtkBase64Layer::encodedLength(std::size_t n) const +std::size_t Foam::vtk::foamVtkBase64Layer::encodedLength +( + std::size_t n +) const { return base64Layer::encodedLength(n); } diff --git a/src/fileFormats/vtk/format/foamVtkBase64Layer.H b/src/fileFormats/vtk/format/foamVtkBase64Layer.H index 61527a11bc02d6047ef6ee8b28bca8e61f978584..6bfa3652d4da34d125067278e4a3f7f6ed7a6045 100644 --- a/src/fileFormats/vtk/format/foamVtkBase64Layer.H +++ b/src/fileFormats/vtk/format/foamVtkBase64Layer.H @@ -22,10 +22,10 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkBase64Layer + Foam::vtk::foamVtkBase64Layer Description - Base-64 encoded output. + Base-64 encoded output layer - normally only used indirectly by formatters. \*---------------------------------------------------------------------------*/ @@ -39,14 +39,16 @@ Description namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkBase64Layer Declaration + Class foamVtkBase64Layer Declaration \*---------------------------------------------------------------------------*/ class foamVtkBase64Layer : - public foamVtkFormatter, + public formatter, protected base64Layer { // Private Data Members @@ -62,6 +64,7 @@ class foamVtkBase64Layer //- Disallow default bitwise assignment void operator=(const foamVtkBase64Layer&) = delete; + protected: // Protected Member Functions @@ -105,6 +108,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.C b/src/fileFormats/vtk/format/foamVtkFormatter.C index 5b9fded769abb084d5ed0f4e9e13fb16928919a1..2bb49322d38927976bc34eea1afbfbcdc61954ff 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkFormatter.C @@ -24,31 +24,21 @@ License #include "foamVtkFormatter.H" -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::foamVtkFormatter::foamVtkFormatter(std::ostream& os) -: - os_(os), - xmlTags_(), - inTag_(false) -{} - - // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkFormatter::~foamVtkFormatter() +Foam::vtk::formatter::~formatter() {} // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -std::size_t Foam::foamVtkFormatter::encodedLength(std::size_t n) const +std::size_t Foam::vtk::formatter::encodedLength(std::size_t n) const { return n; } -void Foam::foamVtkFormatter::indent() +void Foam::vtk::formatter::indent() { label n = xmlTags_.size() * 2; while (n--) @@ -58,8 +48,8 @@ void Foam::foamVtkFormatter::indent() } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlHeader() +Foam::vtk::formatter& +Foam::vtk::formatter::xmlHeader() { if (inTag_) { @@ -74,8 +64,8 @@ Foam::foamVtkFormatter::xmlHeader() } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::comment(const std::string& text) +Foam::vtk::formatter& +Foam::vtk::formatter::xmlComment(const std::string& comment) { if (inTag_) { @@ -85,34 +75,35 @@ Foam::foamVtkFormatter::comment(const std::string& text) } indent(); - os_ << "<!-- " << text << " -->" << nl; + os_ << "<!-- " << comment << " -->" << nl; return *this; } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::openTag(const word& tag) +Foam::vtk::formatter& +Foam::vtk::formatter::openTag(const word& tagName) { if (inTag_) { WarningInFunction - << "open XML tag '" << tag << "', but already within a tag!" + << "open XML tag '" << tagName + << "', but already within a tag!" << endl; } indent(); - os_ << '<' << tag; + os_ << '<' << tagName; - xmlTags_.push(tag); + xmlTags_.push(tagName); inTag_ = true; return *this; } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::closeTag(const bool isEmpty) +Foam::vtk::formatter& +Foam::vtk::formatter::closeTag(const bool isEmpty) { if (!inTag_) { @@ -135,8 +126,8 @@ Foam::foamVtkFormatter::closeTag(const bool isEmpty) } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::endTag(const word& tag) +Foam::vtk::formatter& +Foam::vtk::formatter::endTag(const word& tagName) { const word curr = xmlTags_.pop(); indent(); @@ -149,11 +140,11 @@ Foam::foamVtkFormatter::endTag(const word& tag) << endl; } - // verify inTag_ - if (!tag.empty() && tag != curr) + // verify expected end tag + if (!tagName.empty() && tagName != curr) { WarningInFunction - << "expected to end xml-tag '" << tag + << "expecting to end xml-tag '" << tagName << "' but found '" << curr << "' instead" << endl; } @@ -166,29 +157,19 @@ Foam::foamVtkFormatter::endTag(const word& tag) } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::tag(const word& tag) -{ - openTag(tag); - closeTag(); - - return *this; -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::beginVTKFile +Foam::vtk::formatter& +Foam::vtk::formatter::beginVTKFile ( const word& contentType, const word& contentVersion, const bool leaveOpen ) { - openTag("VTKFile"); + openTag(vtk::fileTag::VTK_FILE); xmlAttr("type", contentType); xmlAttr("version", contentVersion); - xmlAttr("byte_order", foamVtkPTraits<Foam::endian>::typeName); - xmlAttr("header_type", foamVtkPTraits<headerType>::typeName); + xmlAttr("byte_order", vtkPTraits<Foam::endian>::typeName); + xmlAttr("header_type", vtkPTraits<headerType>::typeName); closeTag(); openTag(contentType); @@ -201,8 +182,15 @@ Foam::foamVtkFormatter::beginVTKFile } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::beginAppendedData() +Foam::vtk::formatter& +Foam::vtk::formatter::endVTKFile() +{ + return endTag(vtk::fileTag::VTK_FILE); +} + + +Foam::vtk::formatter& +Foam::vtk::formatter::beginAppendedData() { openTag("AppendedData"); xmlAttr("encoding", encoding()); @@ -213,8 +201,17 @@ Foam::foamVtkFormatter::beginAppendedData() } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttr +Foam::vtk::formatter& +Foam::vtk::formatter::endAppendedData() +{ + flush(); // flush any pending encoded content + os_ << nl; // ensure clear separation from content. + return endTag("AppendedData"); +} + + +Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr ( const word& k, const std::string& v, @@ -234,89 +231,4 @@ Foam::foamVtkFormatter::xmlAttr } -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttr -( - const word& k, - const int32_t v, - const char quote -) -{ - return xmlAttribute(k, v, quote); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttr -( - const word& k, - const int64_t v, - const char quote -) -{ - return xmlAttribute(k, v, quote); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttr -( - const word& k, - const uint64_t v, - const char quote -) -{ - return xmlAttribute(k, v, quote); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttr -( - const word& k, - const scalar v, - const char quote -) -{ - return xmlAttribute(k, v, quote); -} - - -// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * // - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::operator()(const word& k, const std::string& v) -{ - return xmlAttr(k, v); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::operator()(const word& k, const int32_t v) -{ - return xmlAttr(k, v); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::operator()(const word& k, const int64_t v) -{ - return xmlAttr(k, v); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::operator()(const word& k, const uint64_t v) -{ - return xmlAttr(k, v); -} - - -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::operator()(const word& k, const scalar v) -{ - return xmlAttr(k, v); -} - - // ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.H b/src/fileFormats/vtk/format/foamVtkFormatter.H index 9e37f2c6253ff5a70dc48becccbcf93b2287ee93..abe6e2972d51c0b7cf451e52e60af52b61ad41a9 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkFormatter.H @@ -22,15 +22,16 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkFormatter + Foam::vtk::formatter Description Abstract class for a VTK output stream formatter. - Includes very simple support for writing XML tags. + Includes very simple support for writing XML elements. SourceFiles foamVtkFormatter.C + foamVtkFormatterTemplates.C \*---------------------------------------------------------------------------*/ @@ -43,6 +44,7 @@ SourceFiles #include "word.H" #include "UList.H" #include "LIFOStack.H" +#include "foamVtkCore.H" #include "foamVtkPTraits.H" #include <iostream> @@ -51,12 +53,16 @@ SourceFiles namespace Foam { +namespace vtk +{ + +class outputOptions; /*---------------------------------------------------------------------------*\ - Class foamVtkFormatter Declaration + Class formatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkFormatter +class formatter { // Private Data @@ -70,13 +76,15 @@ class foamVtkFormatter mutable bool inTag_; - //- Write XML attribute + // Private Member Functions + + //- Write XML attribute key/value pair template<class Type> - foamVtkFormatter& xmlAttribute + formatter& writeAttribute ( const word& k, const Type& v, - const char quote + const char quote = '\'' ); @@ -85,7 +93,7 @@ protected: // Protected Member Functions //- Construct and attach to an output stream - foamVtkFormatter(std::ostream& os); + inline formatter(std::ostream& os); public: @@ -96,20 +104,20 @@ public: //- Destructor - virtual ~foamVtkFormatter(); + virtual ~formatter(); // Member Functions + // Access + //- Access to the underlying output stream - inline std::ostream& os() - { - return os_; - } + inline std::ostream& os(); + //- The format-type / output options. + virtual const outputOptions& opts() const = 0; - //- Name for the XML output type. - // Possibly the lowercase version of the Legacy output type + //- Name for the XML output type or the legacy output type. virtual const char* name() const = 0; //- Name for the XML append encoding @@ -134,79 +142,113 @@ public: // Member Functions + // Output + //- Indent according to the currently nested XML tags void indent(); //- Write XML header - foamVtkFormatter& xmlHeader(); + // \return formatter for chaining + formatter& xmlHeader(); //- Write XML comment (at the current indentation level) - foamVtkFormatter& comment(const std::string& text); + // \return formatter for chaining + formatter& xmlComment(const std::string& comment); + + //- Open XML tag + // \return formatter for chaining + formatter& openTag(const word& tagName); //- Open XML tag - foamVtkFormatter& openTag(const word& tag); + // \return formatter for chaining + inline formatter& openTag(const vtk::fileTag& tagEnum); //- Close XML tag, optional as an empty container. // Always adds a trailing newline. - foamVtkFormatter& closeTag(const bool isEmpty = false); + // \return formatter for chaining + formatter& closeTag(const bool isEmpty = false); //- End XML tag, optional with sanity check // Always adds a trailing newline. - foamVtkFormatter& endTag(const word& tag = word::null); + // \return formatter for chaining + formatter& endTag(const word& tagName = word::null); + + //- End XML tag with sanity check + // Always adds a trailing newline. + // \return formatter for chaining + inline formatter& endTag(const vtk::fileTag& tagEnum); //- Write XML tag without any attributes. Combines openTag/closeTag. - foamVtkFormatter& tag(const word& tag); + // \return formatter for chaining + inline formatter& tag(const word& tagName); + + //- Write XML tag without any attributes. Combines openTag/closeTag. + // \return formatter for chaining + inline formatter& tag(const vtk::fileTag& tagEnum); //- 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. - foamVtkFormatter& beginVTKFile + // \return formatter for chaining + formatter& beginVTKFile ( const word& contentType, const word& contentVersion, const bool leaveOpen = false ); - //- Add a "AppendedData" XML tag with the current encoding and output + //- 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. + // \return formatter for chaining + inline formatter& beginVTKFile + ( + const vtk::fileTag& contentType, + const word& contentVersion, + const bool leaveOpen = false + ); + + //- Add a "AppendedData" XML tag with the current encoding and output // the requisite '_' prefix. - foamVtkFormatter& beginAppendedData(); + // \return formatter for chaining + formatter& beginAppendedData(); + + //- Open "DataArray" XML tag + // \return formatter for chaining + template<class Type, int nComp=0> + formatter& openDataArray(const word& dataName); //- Open "DataArray" XML tag + // \return formatter for chaining template<class Type, int nComp=0> - foamVtkFormatter& openDataArray(const word& dataName); + formatter& openDataArray(const vtk::dataArrayAttr& attrEnum); //- Insert a single "PDataArray" XML entry tag. // For some entries, the name is optional. + // \return formatter for chaining template<class Type, int nComp=0> - foamVtkFormatter& PDataArray(const word& dataName); + formatter& PDataArray(const word& dataName); //- End "DataArray" XML tag - inline foamVtkFormatter& endDataArray() - { - return endTag("DataArray"); - } + // \return formatter for chaining + inline formatter& endDataArray(); //- End "AppendedData" XML tag - inline foamVtkFormatter& endAppendedData() - { - flush(); // flush any pending encoded content - os_ << '\n'; // clear separation from content. - return endTag("AppendedData"); - } + // \return formatter for chaining + formatter& endAppendedData(); //- End "VTKFile" XML tag - inline foamVtkFormatter& endVTKFile() - { - return endTag("VTKFile"); - } + // \return formatter for chaining + formatter& endVTKFile(); //- Write XML attribute - foamVtkFormatter& xmlAttr + // \return formatter for chaining + formatter& xmlAttr ( const word& k, const std::string& v, @@ -214,7 +256,8 @@ public: ); //- Write XML attribute - foamVtkFormatter& xmlAttr + // \return formatter for chaining + inline formatter& xmlAttr ( const word& k, const int32_t v, @@ -222,7 +265,8 @@ public: ); //- Write XML attribute - foamVtkFormatter& xmlAttr + // \return formatter for chaining + inline formatter& xmlAttr ( const word& k, const int64_t v, @@ -230,7 +274,8 @@ public: ); //- Write XML attribute - foamVtkFormatter& xmlAttr + // \return formatter for chaining + inline formatter& xmlAttr ( const word& k, const uint64_t v, @@ -238,41 +283,53 @@ public: ); //- Write XML attribute - foamVtkFormatter& xmlAttr + // \return formatter for chaining + inline formatter& xmlAttr ( const word& k, const scalar v, const char quote = '\'' ); - - - // Member Operators - //- Write XML attribute - foamVtkFormatter& operator()(const word& k, const std::string& v); - - //- Write XML attribute - foamVtkFormatter& operator()(const word& k, const int32_t v); - - //- Write XML attribute - foamVtkFormatter& operator()(const word& k, const int64_t v); + // \return formatter for chaining + inline formatter& xmlAttr + ( + const vtk::fileAttr& attrEnum, + const int32_t v, + const char quote = '\'' + ); //- Write XML attribute - foamVtkFormatter& operator()(const word& k, const uint64_t v); + // \return formatter for chaining + inline formatter& xmlAttr + ( + const vtk::fileAttr& attrEnum, + const int64_t v, + const char quote = '\'' + ); //- Write XML attribute - foamVtkFormatter& operator()(const word& k, const scalar v); + // \return formatter for chaining + inline formatter& xmlAttr + ( + const vtk::fileAttr& attrEnum, + const uint64_t v, + const char quote = '\'' + ); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#include "foamVtkFormatterI.H" + #ifdef NoRepository #include "foamVtkFormatterTemplates.C" #endif diff --git a/src/fileFormats/vtk/format/foamVtkFormatterI.H b/src/fileFormats/vtk/format/foamVtkFormatterI.H new file mode 100644 index 0000000000000000000000000000000000000000..58e050bf54223b03609bab01eff9afe9f385e85a --- /dev/null +++ b/src/fileFormats/vtk/format/foamVtkFormatterI.H @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::vtk::formatter::formatter(std::ostream& os) +: + os_(os), + xmlTags_(), + inTag_(false) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline std::ostream& Foam::vtk::formatter::os() +{ + return os_; +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::openTag(const vtk::fileTag& tagEnum) +{ + return openTag(vtk::fileTagNames[tagEnum]); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::endTag(const vtk::fileTag& tagEnum) +{ + return endTag(vtk::fileTagNames[tagEnum]); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::tag(const word& tagName) +{ + openTag(tagName); + closeTag(); + + return *this; +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::tag(const vtk::fileTag& tagEnum) +{ + return tag(vtk::fileTagNames[tagEnum]); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::beginVTKFile +( + const vtk::fileTag& contentType, + const word& contentVersion, + const bool leaveOpen +) +{ + return beginVTKFile + ( + vtk::fileTagNames[contentType], + contentVersion, + leaveOpen + ); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::endDataArray() +{ + return endTag("DataArray"); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const word& k, + const int32_t v, + const char quote +) +{ + return writeAttribute(k, v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const word& k, + const int64_t v, + const char quote +) +{ + return writeAttribute(k, v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const word& k, + const uint64_t v, + const char quote +) +{ + return writeAttribute(k, v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const word& k, + const scalar v, + const char quote +) +{ + return writeAttribute(k, v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const vtk::fileAttr& attrEnum, + const int32_t v, + const char quote +) +{ + return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const vtk::fileAttr& attrEnum, + const int64_t v, + const char quote +) +{ + return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); +} + + +inline Foam::vtk::formatter& +Foam::vtk::formatter::xmlAttr +( + const vtk::fileAttr& attrEnum, + const uint64_t v, + const char quote +) +{ + return xmlAttr(vtk::fileAttrNames[attrEnum], v, quote); +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C index 1cde34a61e278147dca32ef073238687476c8672..87f4f9131b50ccfdc3fb37088d95c240e57a147e 100644 --- a/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C +++ b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,8 +27,8 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class Type> -Foam::foamVtkFormatter& -Foam::foamVtkFormatter::xmlAttribute +Foam::vtk::formatter& +Foam::vtk::formatter::writeAttribute ( const word& k, const Type& v, @@ -49,17 +49,18 @@ Foam::foamVtkFormatter::xmlAttribute template<class Type, int nComp> -Foam::foamVtkFormatter& Foam::foamVtkFormatter::openDataArray +Foam::vtk::formatter& +Foam::vtk::formatter::openDataArray ( const word& dataName ) { openTag("DataArray"); - xmlAttr("type", foamVtkPTraits<Type>::typeName); + xmlAttr("type", vtkPTraits<Type>::typeName); xmlAttr("Name", dataName); if (nComp > 1) { - xmlAttr("NumberOfComponents", nComp); + xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, nComp); } xmlAttr("format", name()); @@ -68,20 +69,32 @@ Foam::foamVtkFormatter& Foam::foamVtkFormatter::openDataArray template<class Type, int nComp> -Foam::foamVtkFormatter& Foam::foamVtkFormatter::PDataArray +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 ( const word& dataName ) { openTag("PDataArray"); - xmlAttr("type", foamVtkPTraits<Type>::typeName); + xmlAttr("type", vtkPTraits<Type>::typeName); if (dataName.size()) { xmlAttr("Name", dataName); } if (nComp > 1) { - xmlAttr("NumberOfComponents", nComp); + xmlAttr(fileAttr::NUMBER_OF_COMPONENTS, nComp); } closeTag(true); @@ -89,4 +102,5 @@ Foam::foamVtkFormatter& Foam::foamVtkFormatter::PDataArray return *this; } + // ************************************************************************* // diff --git a/src/fileFormats/vtk/foamVtkCore.C b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.C similarity index 57% rename from src/fileFormats/vtk/foamVtkCore.C rename to src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.C index 2450c02b7b2d0c1c7acc86c9a1c7f6395410bbc0..fe8728854cfdf726ed709a9db4215dbe418073cd 100644 --- a/src/fileFormats/vtk/foamVtkCore.C +++ b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,32 +23,63 @@ License \*---------------------------------------------------------------------------*/ -#include "foamVtkCore.H" +#include "foamVtkLegacyAsciiFormatter.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +const char* Foam::vtk::legacyAsciiFormatter::legacyName_ = "ASCII"; + +const Foam::vtk::outputOptions +Foam::vtk::legacyAsciiFormatter::opts_(formatType::LEGACY_ASCII); + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::fileFormats::foamVtkCore::foamVtkCore() +Foam::vtk::legacyAsciiFormatter::legacyAsciiFormatter +( + std::ostream& os +) +: + asciiFormatter(os) {} -// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // +Foam::vtk::legacyAsciiFormatter::legacyAsciiFormatter +( + std::ostream& os, + unsigned precision +) +: + asciiFormatter(os, precision) +{} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -/* -Foam::fileName Foam::fileFormats::foamVtkCore::vtkFileName -( - const fileName& base, - const enum fileExt ext -) +Foam::vtk::legacyAsciiFormatter::~legacyAsciiFormatter() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +const Foam::vtk::outputOptions& +Foam::vtk::legacyAsciiFormatter::opts() const +{ + return opts_; +} + + +const char* Foam::vtk::legacyAsciiFormatter::name() const +{ + return legacyName_; +} + + +const char* Foam::vtk::legacyAsciiFormatter::encoding() const { - return base + '.' + fileExtensions_[ext]; + return legacyName_; } -*/ // ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H new file mode 100644 index 0000000000000000000000000000000000000000..7301ef98540366f2d639cfad965aaab809a5d38a --- /dev/null +++ b/src/fileFormats/vtk/format/foamVtkLegacyAsciiFormatter.H @@ -0,0 +1,109 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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::legacyAsciiFormatter + +Description + Formatting as per Foam::vtk::asciiFormatter, but with + naming for legacy output. + +SourceFiles + foamVtkLegacyAsciiFormatter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkLegacyAsciiFormatter_H +#define foamVtkLegacyAsciiFormatter_H + +#include "foamVtkAsciiFormatter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace vtk +{ + +/*---------------------------------------------------------------------------*\ + Class legacyAsciiFormatter Declaration +\*---------------------------------------------------------------------------*/ + +class legacyAsciiFormatter +: + public asciiFormatter +{ + // Private Data Members + + static const char* legacyName_; + static const outputOptions opts_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + legacyAsciiFormatter(const legacyAsciiFormatter&) = delete; + + //- Disallow default bitwise assignment + void operator=(const legacyAsciiFormatter&) = delete; + + +public: + + // Constructors + + //- Construct and attach to an output stream, use default precision + legacyAsciiFormatter(std::ostream& os); + + //- Construct and attach to an output stream, use specified precision + legacyAsciiFormatter(std::ostream& os, unsigned precision); + + + //- Destructor + virtual ~legacyAsciiFormatter(); + + + // Member Functions + + //- The output is LEGACY_ASCII. + virtual const outputOptions& opts() const; + + //- Name for the legacy ascii output type ("ASCII") + virtual const char* name() const; + + //- Name for the XML append encoding (unused). + // Currently identical to name(), but do not rely on this. + virtual const char* encoding() const; + +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkLegacyFormatter.C b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C similarity index 74% rename from src/fileFormats/vtk/format/foamVtkLegacyFormatter.C rename to src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C index a3e87264f82fc1bc30977fa0f7dd4ed02f3a86e0..28b042c1959732dc78893606ffbac2c58fdc2762 100644 --- a/src/fileFormats/vtk/format/foamVtkLegacyFormatter.C +++ b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.C @@ -23,17 +23,21 @@ License \*---------------------------------------------------------------------------*/ -#include "foamVtkLegacyFormatter.H" +#include "foamVtkLegacyRawFormatter.H" +#include "foamVtkOutputOptions.H" #include "endian.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -const char* Foam::foamVtkLegacyFormatter::name_ = "BINARY"; +const char* Foam::vtk::legacyRawFormatter::legacyName_ = "BINARY"; + +const Foam::vtk::outputOptions +Foam::vtk::legacyRawFormatter::opts_(formatType::LEGACY_BINARY); // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::foamVtkLegacyFormatter::write +void Foam::vtk::legacyRawFormatter::write ( const char* s, std::streamsize n @@ -45,37 +49,53 @@ void Foam::foamVtkLegacyFormatter::write // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::foamVtkLegacyFormatter::foamVtkLegacyFormatter(std::ostream& os) +Foam::vtk::legacyRawFormatter::legacyRawFormatter +( + std::ostream& os +) : - foamVtkFormatter(os) + formatter(os) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::foamVtkLegacyFormatter::~foamVtkLegacyFormatter() +Foam::vtk::legacyRawFormatter::~legacyRawFormatter() {} // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const char* Foam::foamVtkLegacyFormatter::name() const +const Foam::vtk::outputOptions& +Foam::vtk::legacyRawFormatter::opts() const { - return name_; + return opts_; } -const char* Foam::foamVtkLegacyFormatter::encoding() const +const char* Foam::vtk::legacyRawFormatter::name() const { - return name_; + return legacyName_; } -void Foam::foamVtkLegacyFormatter::writeSize(const uint64_t ignored) +const char* Foam::vtk::legacyRawFormatter::encoding() const +{ + return legacyName_; +} + + +void Foam::vtk::legacyRawFormatter::writeSize +( + const uint64_t ignored +) {/*nop*/} -void Foam::foamVtkLegacyFormatter::write(const uint8_t val) +void Foam::vtk::legacyRawFormatter::write +( + const uint8_t val +) { // Legacy can only handle 32-bit integers. // Nonetheless promote to 'label' (32 or 64 bit) and deal with it later @@ -84,7 +104,10 @@ void Foam::foamVtkLegacyFormatter::write(const uint8_t val) } -void Foam::foamVtkLegacyFormatter::write(const label val) +void Foam::vtk::legacyRawFormatter::write +( + const label val +) { // std::cerr<<"label is:" << sizeof(val) << '\n'; @@ -104,7 +127,10 @@ void Foam::foamVtkLegacyFormatter::write(const label val) } -void Foam::foamVtkLegacyFormatter::write(const float val) +void Foam::vtk::legacyRawFormatter::write +( + const float val +) { // std::cerr<<"float is:" << sizeof(val) << '\n'; @@ -122,7 +148,10 @@ void Foam::foamVtkLegacyFormatter::write(const float val) } -void Foam::foamVtkLegacyFormatter::write(const double val) +void Foam::vtk::legacyRawFormatter::write +( + const double val +) { // Legacy cannot support Float64 anyhow. // std::cerr<<"write double as float:" << val << '\n'; @@ -131,7 +160,7 @@ void Foam::foamVtkLegacyFormatter::write(const double val) } -void Foam::foamVtkLegacyFormatter::flush() +void Foam::vtk::legacyRawFormatter::flush() { os()<< '\n'; } diff --git a/src/fileFormats/vtk/format/foamVtkLegacyFormatter.H b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H similarity index 80% rename from src/fileFormats/vtk/format/foamVtkLegacyFormatter.H rename to src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H index 6ec5ba7e8dd37209a9bc92c6b91fa2e479e75eac..3f24f05cb07555a57921887108f7f06f160f9403 100644 --- a/src/fileFormats/vtk/format/foamVtkLegacyFormatter.H +++ b/src/fileFormats/vtk/format/foamVtkLegacyRawFormatter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkLegacyFormatter + Foam::vtk::legacyRawFormatter Description Binary output for the VTK legacy format, always written as big-endian @@ -31,12 +31,12 @@ Description This format should never be used for OpenFOAM with 64-bit label sizes. SourceFiles - foamVtkLegacyFormatter.C + foamVtkLegacyRawFormatter.C \*---------------------------------------------------------------------------*/ -#ifndef foamVtkLegacyFormatter_H -#define foamVtkLegacyFormatter_H +#ifndef foamVtkLegacyRawFormatter_H +#define foamVtkLegacyRawFormatter_H #include "foamVtkFormatter.H" @@ -44,27 +44,30 @@ SourceFiles namespace Foam { +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkLegacyFormatter Declaration + Class legacyRawFormatter Declaration \*---------------------------------------------------------------------------*/ -class foamVtkLegacyFormatter +class legacyRawFormatter : - public foamVtkFormatter + public formatter { // Private Data Members - static const char* name_; + static const char* legacyName_; + static const outputOptions opts_; // Private Member Functions //- Disallow default bitwise copy construct - foamVtkLegacyFormatter(const foamVtkLegacyFormatter&) = delete; + legacyRawFormatter(const legacyRawFormatter&) = delete; //- Disallow default bitwise assignment - void operator=(const foamVtkLegacyFormatter&) = delete; + void operator=(const legacyRawFormatter&) = delete; protected: @@ -80,15 +83,18 @@ public: // Constructors //- Construct and attach to an output stream - foamVtkLegacyFormatter(std::ostream& os); + legacyRawFormatter(std::ostream& os); //- Destructor - virtual ~foamVtkLegacyFormatter(); + virtual ~legacyRawFormatter(); // Member Functions + //- The output is LEGACY_BINARY. + virtual const outputOptions& opts() const; + //- Name for the legacy binary output type ("BINARY") virtual const char* name() const; @@ -112,6 +118,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/format/foamVtkOutputOptions.C b/src/fileFormats/vtk/format/foamVtkOutputOptions.C deleted file mode 100644 index c88d334594d14289c27237b66c66839fb89f5def..0000000000000000000000000000000000000000 --- a/src/fileFormats/vtk/format/foamVtkOutputOptions.C +++ /dev/null @@ -1,235 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 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 "foamVtkOutputOptions.H" - -#include "foamVtkAppendBase64Formatter.H" -#include "foamVtkAppendRawFormatter.H" -#include "foamVtkAsciiFormatter.H" -#include "foamVtkBase64Formatter.H" -#include "foamVtkLegacyFormatter.H" - -#include "IOstream.H" - - -// * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * // - -Foam::foamVtkOutputOptions::foamVtkOutputOptions() -: - type_(ASCII), - precision_(IOstream::defaultPrecision()) -{} - - -// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // - -Foam::autoPtr<Foam::foamVtkFormatter> -Foam::foamVtkOutputOptions::newFormatter(std::ostream& os) const -{ - switch (type_) - { - case (LEGACY | BINARY): - return autoPtr<foamVtkFormatter> - ( - new foamVtkLegacyFormatter(os) - ); - - case BASE64: // xml insitu - return autoPtr<foamVtkFormatter> - ( - new foamVtkBase64Formatter(os) - ); - - case (APPEND | BASE64): - return autoPtr<foamVtkFormatter> - ( - new foamVtkAppendBase64Formatter(os) - ); - - case (APPEND | BINARY): - return autoPtr<foamVtkFormatter> - ( - new foamVtkAppendRawFormatter(os) - ); - - default: // ASCII (legacy or xml) must always work - return autoPtr<foamVtkFormatter> - ( - new foamVtkAsciiFormatter(os, precision_) - ); - } -} - - -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -void Foam::foamVtkOutputOptions::ascii(bool on) -{ - if (on) - { - // Force ASCII: - - if (type_ & APPEND) - { - // Append: ascii = base64 (vs raw binary) - type_ = (APPEND | BASE64); - } - else if (type_ & LEGACY) - { - // Legacy: ascii = ascii - type_ = (LEGACY | ASCII); - } - else - { - // XML: ascii = ascii - type_ = ASCII; - } - } - else - { - // Non-ASCII: - - if (type_ & APPEND) - { - // Append: binary == (raw) binary - type_ = APPEND | BINARY; - } - else if (type_ & LEGACY) - { - // Legacy: binary = binary - type_ = LEGACY | BINARY; - } - else - { - // XML: binary == (inline) binary == base64 - type_ = BASE64; - } - } -} - - -void Foam::foamVtkOutputOptions::append(bool on) -{ - if (on) - { - if (!(type_ & APPEND)) - { - // XML: base64 -> raw binary, ascii -> base64 - // Legacy: binary -> raw binary, ascii -> base64 - type_ = APPEND | ((type_ & (BASE64 | BINARY)) ? BINARY : BASE64); - } - } - else if (type_ & APPEND) - { - // Only revert back to inline XML base64 versions - // ASCII needs another step. - - type_ = BASE64; - } -} - - -void Foam::foamVtkOutputOptions::legacy(bool on) -{ - if (on) - { - if (type_ & APPEND) - { - // Append: base64 -> ascii, binary -> binary - type_ = (LEGACY | ((type_ & BINARY) ? BINARY : ASCII)); - } - else if (type_ & LEGACY) - { - // no-op - } - else - { - // XML: ascii -> ascii, base64 -> binary - type_ = (LEGACY | ((type_ & BASE64) ? BINARY : ASCII)); - } - } - else if (type_ & LEGACY) - { - // Legacy: ascii -> xml ascii, binary -> xml base64 - type_ = (type_ & BINARY) ? BASE64 : ASCII; - } -} - - -void Foam::foamVtkOutputOptions::precision(unsigned prec) const -{ - precision_ = prec; -} - - -Foam::Ostream& Foam::foamVtkOutputOptions::info(Ostream& os) const -{ - os << "type: " << type_; - - switch (type_) - { - case (LEGACY | ASCII): - os << " legacy ascii"; - break; - - case (LEGACY | BINARY): - os << " legacy binary"; - break; - - case BASE64: - os << " xml insitu base64"; - break; - - case (APPEND | BASE64): - os << " xml-append base64"; - break; - - case (APPEND | BINARY): - os << " xml-append binary"; - break; - - case ASCII: - os << " xml insitu ascii"; - break; - - case BINARY: - os << " xml insitu binary - WRONG"; - break; - - default: - os << " unknown"; - break; - } - - if (legacy()) os << " legacy"; - if (xml()) os << " xml"; - if (append()) os << " append"; - if (ascii()) os << " ascii"; - - return os; -} - - -// ************************************************************************* // diff --git a/src/fileFormats/vtk/output/foamVtkOutput.C b/src/fileFormats/vtk/output/foamVtkOutput.C new file mode 100644 index 0000000000000000000000000000000000000000..7e18f7231438a71916e30bbe4ed8335030e1022e --- /dev/null +++ b/src/fileFormats/vtk/output/foamVtkOutput.C @@ -0,0 +1,146 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtkOutput.H" + +#include "foamVtkFormatter.H" +#include "foamVtkAsciiFormatter.H" +#include "foamVtkBase64Formatter.H" +#include "foamVtkAppendBase64Formatter.H" +#include "foamVtkAppendRawFormatter.H" +#include "foamVtkLegacyAsciiFormatter.H" +#include "foamVtkLegacyRawFormatter.H" +#include "typeInfo.H" + +// * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * * // + +const Foam::Enum<Foam::vtk::fileTag> +Foam::vtk::legacy::contentNames +{ + { vtk::fileTag::POLY_DATA, "POLYDATA" }, + { vtk::fileTag::UNSTRUCTURED_GRID, "UNSTRUCTURED_GRID" }, +}; + + +const Foam::Enum<Foam::vtk::fileTag> +Foam::vtk::legacy::dataTypeNames +{ + { vtk::fileTag::CELL_DATA, "CELL_DATA" }, + { vtk::fileTag::POINT_DATA, "POINT_DATA" } +}; + + +// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::vtk::formatter> +Foam::vtk::newFormatter +( + std::ostream& os, + const enum formatType fmtType, + unsigned prec +) +{ + autoPtr<vtk::formatter> fmt; + + switch (fmtType) + { + case formatType::INLINE_ASCII: + fmt.set(new vtk::asciiFormatter(os, prec)); + break; + + case formatType::INLINE_BASE64: + fmt.set(new vtk::base64Formatter(os)); + break; + + case formatType::APPEND_BASE64: + fmt.set(new vtk::appendBase64Formatter(os)); + break; + + case formatType::APPEND_BINARY: + fmt.set(new vtk::appendRawFormatter(os)); + break; + + case formatType::LEGACY_ASCII: + fmt.set(new vtk::legacyAsciiFormatter(os, prec)); + break; + + case formatType::LEGACY_BINARY: + fmt.set(new vtk::legacyRawFormatter(os)); + break; + } + + return fmt; +} + + +Foam::label Foam::vtk::writeVtmFile +( + std::ostream& os, + const UList<fileName>& files +) +{ + const word& content = "vtkMultiBlockDataSet"; + + asciiFormatter vtmFile(os); + + vtmFile + .xmlHeader() + .beginVTKFile(content, "1.0"); + + forAll(files, i) + { + vtmFile + .openTag(vtk::fileTag::DATA_SET) + .xmlAttr("index", i) + .xmlAttr("file", files[i]) + .closeTag(true); + } + + vtmFile.endTag(content).endVTKFile(); + + return files.size(); +} + + +std::ostream& Foam::vtk::legacy::fileHeader +( + vtk::formatter& fmt, + const std::string& title, + const std::string& contentType +) +{ + std::ostream& os = fmt.os(); + + fileHeader(os, title, isType<legacyRawFormatter>(fmt)); + if (!contentType.empty()) + { + os << "DATASET " << contentType.c_str() << nl; + } + + return os; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/output/foamVtkOutput.H b/src/fileFormats/vtk/output/foamVtkOutput.H new file mode 100644 index 0000000000000000000000000000000000000000..c3632a11913c324ef48890691f1848ae41cc565c --- /dev/null +++ b/src/fileFormats/vtk/output/foamVtkOutput.H @@ -0,0 +1,236 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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/>. + +Namespace + Foam::vtk + +Description + Namespace for handling VTK output. + Contains classes and functions for writing VTK file content. + +Namespace + Foam::vtk::legacy + +Description + Namespace for legacy VTK output constants and functions. + +SourceFiles + foamVtkOutput.C + foamVtkOutputTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamVtkOutput_H +#define foamVtkOutput_H + +#include "autoPtr.H" +#include "Enum.H" +#include "foamVtkCore.H" +#include "foamVtkFormatter.H" +#include "floatScalar.H" +#include "IOstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace vtk +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + // Constants + + // General Functions + + //- Return a default asciiFormatter + autoPtr<vtk::formatter> newFormatter(std::ostream& os); + + //- Return a new formatter based on the specified format type + autoPtr<vtk::formatter> newFormatter + ( + std::ostream& os, + const enum formatType fmtType, + unsigned prec = IOstream::defaultPrecision() + ); + + + //- Write vtm datasets for specified files + label writeVtmFile(std::ostream& os, const UList<fileName>& files); + + + //- Write a value component-wise. + template<class Type> + inline void write + ( + vtk::formatter& fmt, + const Type& val + ); + + + //- Write a list of values. + // The output does not include the payload size. + template<class Type> + void writeList + ( + vtk::formatter& fmt, + const UList<Type>& lst + ); + + //- Write a list of values. + // The output does not include the payload size. + template<class Type, unsigned Size> + void writeList + ( + vtk::formatter& fmt, + const FixedList<Type, Size>& lst + ); + + + //- 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>& lst, + const UList<label>& addressing + ); + + +/*---------------------------------------------------------------------------*\ + 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 + ); + + //- 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. + // If the contentType is non-empty, it is used for "DATASET" line. + std::ostream& fileHeader + ( + vtk::formatter& fmt, + const std::string& title, + const std::string& contentType + ); + + + //- Emit header for POINTS (with trailing newline). + inline void beginPoints(std::ostream& os, const 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 + ( + std::ostream& os, + const label nPolys, + const label nConnectivity + ); + + + //- 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 + ); + + //- Start output of float field with the specified name. + inline void floatField + ( + std::ostream& os, + const word& name, + const int nCmpt, + const label nEntries + ); + + //- Start output of int field with the specified name. + inline void intField + ( + std::ostream& os, + const word& name, + const int nCmpt, + const label nEntries + ); + +} // End namespace legacy + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace vtk +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "foamVtkOutputI.H" + +#ifdef NoRepository + #include "foamVtkOutputTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/output/foamVtkOutputI.H b/src/fileFormats/vtk/output/foamVtkOutputI.H new file mode 100644 index 0000000000000000000000000000000000000000..b7717ea66d34faaa88930bde4fb797b724d16a68 --- /dev/null +++ b/src/fileFormats/vtk/output/foamVtkOutputI.H @@ -0,0 +1,146 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace vtk +{ + +//- Template specialization for label +template<> +inline void write<label>(vtk::formatter& fmt, const label& val) +{ + fmt.write(val); +} + + +//- Template specialization for float +template<> +inline void write<float>(vtk::formatter& fmt, const float& val) +{ + fmt.write(val); +} + + +//- Template specialization for double +template<> +inline void write<double>(vtk::formatter& fmt, const double& val) +{ + fmt.write(val); +} + +} // End namespace vtk +} // End namespace Foam + + +// * * * * * * * * * * * * * * 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 +) +{ + fileHeader(fmt, title, contentNames[contentTypeTag]); +} + + +inline void Foam::vtk::legacy::beginPoints +( + std::ostream& os, + const label nPoints +) +{ + os << "POINTS " << nPoints << " float" << nl; +} + + +inline void Foam::vtk::legacy::beginPolys +( + std::ostream& os, + const label nPolys, + const label nConnectivity +) +{ + os << "POLYGONS " << nPolys << ' ' << (nPolys + nConnectivity) << nl; +} + + +inline void Foam::vtk::legacy::dataHeader +( + std::ostream& os, + const vtk::fileTag& dataTypeTag, + const label nEntries, + const label nFields +) +{ + os << dataTypeNames[dataTypeTag] << ' ' << nEntries << nl + << "FIELD attributes " << nFields << nl; +} + + +inline void Foam::vtk::legacy::floatField +( + std::ostream& os, + const word& fieldName, + const int nCmpt, + const label nEntries +) +{ + os << fieldName << ' ' << nCmpt << ' ' << nEntries << " float" << nl; +} + + +inline void Foam::vtk::legacy::intField +( + std::ostream& os, + const word& fieldName, + const int nCmpt, + const label nEntries +) +{ + os << fieldName << ' ' << nCmpt << ' ' << nEntries << " int" << nl; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/output/foamVtkOutputOptions.C b/src/fileFormats/vtk/output/foamVtkOutputOptions.C new file mode 100644 index 0000000000000000000000000000000000000000..8a8c30a060ad6345ae51172eb80edfa1a871d024 --- /dev/null +++ b/src/fileFormats/vtk/output/foamVtkOutputOptions.C @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtkOutputOptions.H" + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::vtk::outputOptions& +Foam::vtk::outputOptions::ascii(bool on) +{ + if (on) + { + switch (fmtType_) + { + case formatType::INLINE_BASE64: + fmtType_ = formatType::INLINE_ASCII; + break; + + case formatType::APPEND_BINARY: + fmtType_ = formatType::APPEND_BASE64; + break; + + case formatType::LEGACY_BINARY: + fmtType_ = formatType::LEGACY_ASCII; + break; + + default: // No change + break; + } + } + else + { + switch (fmtType_) + { + case formatType::INLINE_ASCII: + fmtType_ = formatType::INLINE_BASE64; + break; + + case formatType::APPEND_BASE64: + fmtType_ = formatType::APPEND_BINARY; + break; + + case formatType::LEGACY_ASCII: + fmtType_ = formatType::LEGACY_BINARY; + break; + + default: // No change + break; + } + } + + return *this; +} + + +Foam::vtk::outputOptions& +Foam::vtk::outputOptions::append(bool on) +{ + if (on) + { + switch (fmtType_) + { + case formatType::INLINE_ASCII: + case formatType::LEGACY_ASCII: + fmtType_ = formatType::APPEND_BASE64; + break; + + case formatType::INLINE_BASE64: + case formatType::LEGACY_BINARY: + fmtType_ = formatType::APPEND_BINARY; + break; + + default: // No change + break; + } + } + else + { + switch (fmtType_) + { + case formatType::APPEND_BASE64: + fmtType_ = formatType::INLINE_ASCII; + break; + + case formatType::APPEND_BINARY: + fmtType_ = formatType::INLINE_BASE64; + break; + + default: // No change + break; + } + } + + return *this; +} + + +Foam::vtk::outputOptions& +Foam::vtk::outputOptions::legacy(bool on) +{ + if (on) + { + switch (fmtType_) + { + case formatType::INLINE_ASCII: + case formatType::APPEND_BASE64: + fmtType_ = formatType::LEGACY_ASCII; + break; + + case formatType::INLINE_BASE64: + case formatType::APPEND_BINARY: + fmtType_ = formatType::LEGACY_BINARY; + break; + + default: // no change + break; + } + } + else + { + switch (fmtType_) + { + case formatType::LEGACY_ASCII: + fmtType_ = formatType::INLINE_ASCII; + break; + + case formatType::LEGACY_BINARY: + fmtType_ = formatType::INLINE_BASE64; + break; + + default: // no change + break; + } + } + + return *this; +} + + +Foam::vtk::outputOptions& +Foam::vtk::outputOptions::precision(unsigned prec) +{ + precision_ = prec; + return *this; +} + + +Foam::string Foam::vtk::outputOptions::description() const +{ + switch (fmtType_) + { + case formatType::INLINE_ASCII: return "xml ascii"; + case formatType::INLINE_BASE64: return "xml base64"; + case formatType::APPEND_BASE64: return "xml-append base64"; + case formatType::APPEND_BINARY: return "xml-append binary"; + case formatType::LEGACY_ASCII: return "legacy ascii"; + case formatType::LEGACY_BINARY: return "legacy binary"; + } + + return ""; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/format/foamVtkOutputOptions.H b/src/fileFormats/vtk/output/foamVtkOutputOptions.H similarity index 62% rename from src/fileFormats/vtk/format/foamVtkOutputOptions.H rename to src/fileFormats/vtk/output/foamVtkOutputOptions.H index 7e0e89b24be155f760fb45f3d16e97b71b8f57de..00e715b15cb6c7a1394f78f2e37974c7c9bf950f 100644 --- a/src/fileFormats/vtk/format/foamVtkOutputOptions.H +++ b/src/fileFormats/vtk/output/foamVtkOutputOptions.H @@ -22,10 +22,15 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - foamVtkOutputOptions + Foam::vtk::outputOptions Description - Encapsulate combinations of output format options. + Encapsulated combinations of output format options. + This is primarily useful when defining the output type based on some + command-line arguments or dictionary contents. + However, it can also be a useful alternative to using the underlying + enumeration directly, since this class provides additional methods + not possible with an enum. SourceFiles foamVtkOutputOptions.C @@ -35,43 +40,33 @@ SourceFiles #ifndef foamVtkOutputOptions_H #define foamVtkOutputOptions_H -#include "autoPtr.H" -#include "foamVtkFormatter.H" +#include "foamVtkOutput.H" +#include "string.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -class Ostream; +namespace vtk +{ /*---------------------------------------------------------------------------*\ - Class foamVtkOutputOptions Declaration + Class outputOptions Declaration \*---------------------------------------------------------------------------*/ -class foamVtkOutputOptions +class outputOptions { - // Private data - - //- The supported output/format types - enum foamVtkOptionTypes - { - ASCII = 0x0000, //!< ASCII formatting for data - BINARY = 0x0001, //!< Raw binary formatting for data - BASE64 = 0x0002, //!< Base64 encoding for data - LEGACY = 0x0100, //!< Legacy vtk file format - APPEND = 0x0200 //!< XML append format - }; + // Private Member Data //- The output style tuning - enum foamVtkStyleOptions + enum styleType { - NONE = 0x0000, //!< Normal - HEADER = 0x0001 //!< Emit xml header + NONE = 0x00, //!< Normal + HEADER = 0x01 //!< Emit xml header }; - //- The output format type - unsigned short type_; + formatType fmtType_; //- ASCII write precision mutable unsigned precision_; @@ -82,18 +77,25 @@ public: // Constructors //- Construct null - XML insitu ASCII format with default precision - foamVtkOutputOptions(); + inline outputOptions(); + + //- Construct with specified format. + // This constructor should remain non-explicit. + inline outputOptions(enum formatType fmtType); // Selectors - //- Return new data formatter based on the writer options - autoPtr<foamVtkFormatter> newFormatter(std::ostream& os) const; + //- Return new formatter based on the selected output options + inline autoPtr<formatter> newFormatter(std::ostream& os) const; // Member Functions - // Access + // Access + + //- The output format type + inline formatType fmt() const; //- True if writer uses legacy file format inline bool legacy() const; @@ -110,35 +112,43 @@ public: //- True if output format is ASCII inline bool ascii() const; + //- Return the ASCII write precision + inline unsigned precision() const; + - // Edit + // Edit //- Toggle ASCII mode on/off. - // In append mode, this switches between base64 and raw binary. - // In XML mode, this switches between ASCII and base64. + // In XML append mode, this switches between base64 and raw binary. + // In XML inline mode, this switches between ASCII and base64. // In legacy mode, this switches between ASCII and binary. - void ascii(bool on); + // \return outputOptions for chaining + outputOptions& ascii(bool on); //- Toggle append mode on/off. - void append(bool on); + // \return outputOptions for chaining + outputOptions& append(bool on); //- Toggle legacy mode on/off. - void legacy(bool on); + // \return outputOptions for chaining + outputOptions& legacy(bool on); //- Set the write precision to be used for new ASCII formatters - void precision(unsigned prec) const; + // \return outputOptions for chaining + outputOptions& precision(unsigned prec); // Other - //- Report information about the options - Ostream& info(Ostream&) const; + //- A text description about the output option selected + string description() const; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace vtk } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H b/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H new file mode 100644 index 0000000000000000000000000000000000000000..c8802c3da8b5744fac2e80190ad9185b6656ce57 --- /dev/null +++ b/src/fileFormats/vtk/output/foamVtkOutputOptionsI.H @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 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 "foamVtkOutput.H" + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::vtk::outputOptions::outputOptions() +: + fmtType_(formatType::INLINE_ASCII), + precision_(IOstream::defaultPrecision()) +{} + + +inline Foam::vtk::outputOptions::outputOptions +( + enum formatType fmtType +) +: + fmtType_(fmtType), + precision_(IOstream::defaultPrecision()) +{} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +inline Foam::autoPtr<Foam::vtk::formatter> +Foam::vtk::outputOptions::newFormatter(std::ostream& os) const +{ + return vtk::newFormatter(os, fmtType_, precision_); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +inline Foam::vtk::formatType +Foam::vtk::outputOptions::fmt() const +{ + return fmtType_; +} + + +inline bool Foam::vtk::outputOptions::legacy() const +{ + return + ( + fmtType_ == formatType::LEGACY_ASCII + || fmtType_ == formatType::LEGACY_BINARY + ); +} + + +inline bool Foam::vtk::outputOptions::xml() const +{ + return !legacy(); +} + + +inline bool Foam::vtk::outputOptions::append() const +{ + return + ( + fmtType_ == formatType::APPEND_BASE64 + || fmtType_ == formatType::APPEND_BINARY + ); +} + + +inline bool Foam::vtk::outputOptions::insitu() const +{ + return !append(); +} + + +inline bool Foam::vtk::outputOptions::ascii() const +{ + return !(unsigned(fmtType_) & 0x0F); +} + + +inline unsigned Foam::vtk::outputOptions::precision() const +{ + return precision_; +} + + +// ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkOutputTemplates.C b/src/fileFormats/vtk/output/foamVtkOutputTemplates.C similarity index 68% rename from src/conversion/vtk/output/foamVtkOutputTemplates.C rename to src/fileFormats/vtk/output/foamVtkOutputTemplates.C index 03c2d56bd9d941d97e427b049914698fd179147a..f28d458378e1fc64d6f7beddd1388f61b0a4b64b 100644 --- a/src/conversion/vtk/output/foamVtkOutputTemplates.C +++ b/src/fileFormats/vtk/output/foamVtkOutputTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2107 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,15 +25,15 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - template<class Type> -inline void Foam::foamVtkOutput::write +inline void Foam::vtk::write ( - foamVtkFormatter& fmt, + vtk::formatter& fmt, const Type& val ) { - for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt) + const direction nCmpt = pTraits<Type>::nComponents; + for (direction cmpt=0; cmpt < nCmpt; ++cmpt) { fmt.write(component(val, cmpt)); } @@ -41,9 +41,9 @@ inline void Foam::foamVtkOutput::write template<class Type> -void Foam::foamVtkOutput::writeList +void Foam::vtk::writeList ( - foamVtkFormatter& fmt, + vtk::formatter& fmt, const UList<Type>& lst ) { @@ -54,40 +54,32 @@ void Foam::foamVtkOutput::writeList } -template<class Type> -void Foam::foamVtkOutput::writeList +template<class Type, unsigned Size> +void Foam::vtk::writeList ( - foamVtkFormatter& fmt, - const UList<Type>& lst, - const UList<label>& addressing + vtk::formatter& fmt, + const FixedList<Type, Size>& lst ) { - forAll(addressing, i) + for (unsigned i=0; i<Size; ++i) { - write(fmt, lst[addressing[i]]); + write(fmt, lst[i]); } } template<class Type> -void Foam::foamVtkOutput::writeField +void Foam::vtk::writeList ( - foamVtkFormatter& fmt, - const GeometricField<Type, fvPatchField, volMesh>& vf, - const UList<label>& superCells + vtk::formatter& fmt, + const UList<Type>& lst, + const UList<label>& addressing ) { - const uint64_t payLoad = - ( - (vf.size() + superCells.size()) - * pTraits<Type>::nComponents * sizeof(float) - ); - - fmt.writeSize(payLoad); - writeList(fmt, vf.internalField()); - writeList(fmt, vf, superCells); - - fmt.flush(); + forAll(addressing, i) + { + write(fmt, lst[addressing[i]]); + } } diff --git a/src/fileFormats/vtk/read/vtkUnstructuredReader.C b/src/fileFormats/vtk/read/vtkUnstructuredReader.C index 153c16578263edc40d1cbd951d702a73fd26202e..f29d57995ce3fc4909e69bc203995d75791591fb 100644 --- a/src/fileFormats/vtk/read/vtkUnstructuredReader.C +++ b/src/fileFormats/vtk/read/vtkUnstructuredReader.C @@ -125,7 +125,7 @@ void Foam::vtkUnstructuredReader::extractCells { switch (cellTypes[i]) { - case foamVtkCore::VTK_VERTEX: + case vtk::cellType::VTK_VERTEX: { warnUnhandledType(inFile, cellTypes[i], warningGiven); label nRead = cellVertData[dataIndex++]; @@ -141,7 +141,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_POLY_VERTEX: + case vtk::cellType::VTK_POLY_VERTEX: { warnUnhandledType(inFile, cellTypes[i], warningGiven); label nRead = cellVertData[dataIndex++]; @@ -149,7 +149,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_LINE: + case vtk::cellType::VTK_LINE: { //warnUnhandledType(inFile, cellTypes[i], warningGiven); label nRead = cellVertData[dataIndex++]; @@ -169,7 +169,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_POLY_LINE: + case vtk::cellType::VTK_POLY_LINE: { //warnUnhandledType(inFile, cellTypes[i], warningGiven); label nRead = cellVertData[dataIndex++]; @@ -183,7 +183,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_TRIANGLE: + case vtk::cellType::VTK_TRIANGLE: { faceMap_[facei] = i; face& f = faces_[facei++]; @@ -203,7 +203,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_QUAD: + case vtk::cellType::VTK_QUAD: { faceMap_[facei] = i; face& f = faces_[facei++]; @@ -224,7 +224,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_POLYGON: + case vtk::cellType::VTK_POLYGON: { faceMap_[facei] = i; face& f = faces_[facei++]; @@ -237,7 +237,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_TETRA: + case vtk::cellType::VTK_TETRA: { label nRead = cellVertData[dataIndex++]; if (nRead != 4) @@ -257,7 +257,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_PYRAMID: + case vtk::cellType::VTK_PYRAMID: { label nRead = cellVertData[dataIndex++]; if (nRead != 5) @@ -278,7 +278,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_WEDGE: + case vtk::cellType::VTK_WEDGE: { label nRead = cellVertData[dataIndex++]; if (nRead != 6) @@ -300,7 +300,7 @@ void Foam::vtkUnstructuredReader::extractCells } break; - case foamVtkCore::VTK_HEXAHEDRON: + case vtk::cellType::VTK_HEXAHEDRON: { label nRead = cellVertData[dataIndex++]; if (nRead != 8) diff --git a/src/fileFormats/vtk/read/vtkUnstructuredReader.H b/src/fileFormats/vtk/read/vtkUnstructuredReader.H index 48dc38890a843b60b6dd1bf2d3823afeb032999c..bee79496c65377dc40c5f219d2d3db62b29da5de 100644 --- a/src/fileFormats/vtk/read/vtkUnstructuredReader.H +++ b/src/fileFormats/vtk/read/vtkUnstructuredReader.H @@ -63,8 +63,6 @@ namespace Foam \*---------------------------------------------------------------------------*/ class vtkUnstructuredReader -: - public fileFormats::foamVtkCore { public: @@ -206,7 +204,7 @@ private: void read(ISstream& inFile); - //- Dissallow assignment + //- Disallow assignment void operator=(const vtkUnstructuredReader&); @@ -220,6 +218,7 @@ public: //- Construct from Istream, read all vtkUnstructuredReader(const objectRegistry& obr, ISstream&); + // Member Functions //- Header diff --git a/src/functionObjects/utilities/Make/files b/src/functionObjects/utilities/Make/files index e2f72c06cfe35edc354c239f6006bd35fb00082c..5cd7055b4693edf0427e31d1e210770218dc3728 100644 --- a/src/functionObjects/utilities/Make/files +++ b/src/functionObjects/utilities/Make/files @@ -2,6 +2,7 @@ abort/abort.C codedFunctionObject/codedFunctionObject.C ensightWrite/ensightWrite.C +vtkWrite/vtkWrite.C removeRegisteredObject/removeRegisteredObject.C diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H index 79c4110800b0f102a7157385fa89f2a7cc5c3ec7..ce9592f99c4112e565a4071aee8a212c9d5c738e 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.H +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H @@ -76,7 +76,6 @@ SourceFiles ensightWrite.C ensightWriteTemplates.C - \*---------------------------------------------------------------------------*/ #ifndef functionObjects_ensightWrite_H diff --git a/src/functionObjects/utilities/vtkWrite/vtkWrite.C b/src/functionObjects/utilities/vtkWrite/vtkWrite.C new file mode 100644 index 0000000000000000000000000000000000000000..af55e3f82ea9a1b704d153a6ad4c56715ea59abf --- /dev/null +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.C @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "vtkWrite.H" +#include "dictionary.H" +#include "Time.H" +#include "foamVtkInternalWriter.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + defineTypeNameAndDebug(vtkWrite, 0); + addToRunTimeSelectionTable(functionObject, vtkWrite, dictionary); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects::vtkWrite::vtkWrite +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + fvMeshFunctionObject(name, runTime, dict), + writeOpts_(vtk::formatType::INLINE_BASE64), + selectFields_(), + dirName_("VTK") +{ + read(dict); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjects::vtkWrite::~vtkWrite() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::vtkWrite::read(const dictionary& dict) +{ + fvMeshFunctionObject::read(dict); + + // + // writer options - default is xml base64 + // + writeOpts_ = vtk::formatType::INLINE_BASE64; + if (dict.lookupOrDefault<bool>("legacy", false)) + { + writeOpts_.legacy(true); + } + + writeOpts_.ascii + ( + dict.found("format") + && (IOstream::formatEnum(dict.lookup("format")) == IOstream::ASCII) + ); + + // FUTURE? + // writeOpts_.precision + // ( + // dict.lookupOrDefault + // ( + // "writePrecision", + // IOstream::defaultPrecision() + // ) + // ); + + // Info<< type() << " " << name() << " output-format: " + // << writeOpts_.description() << nl; + + // + // other options + // + dict.readIfPresent("directory", dirName_); + + writeIds_ = dict.lookupOrDefault<bool>("writeIds", false); + + + // + // output fields + // + dict.lookup("fields") >> selectFields_; + wordRes::inplaceUniq(selectFields_); + + return true; +} + + +bool Foam::functionObjects::vtkWrite::execute() +{ + return true; +} + + +bool Foam::functionObjects::vtkWrite::write() +{ + // Count number of fields to be written: only needed for legacy vtk format + label nFields = 0; + if (writeOpts_.legacy()) + { + nFields = + ( + (writeIds_ ? 1 : 0) + + countFields<volScalarField>() + + countFields<volVectorField>() + + countFields<volSphericalTensorField>() + + countFields<volSymmTensorField>() + + countFields<volTensorField>() + ); + } + + // const word timeDesc = + // useTimeName ? time_.timeName() : Foam::name(time_.timeIndex()); + + const word timeDesc = time_.timeName(); + + fileName vtkDir = dirName_; + if (!vtkDir.isAbsolute()) + { + vtkDir = time_.path()/vtkDir; + } + mkDir(vtkDir); + + string vtkName = time_.caseName(); + + if (Pstream::parRun()) + { + // Strip off leading casename, leaving just processor_DDD ending. + string::size_type i = vtkName.rfind("processor"); + + if (i != string::npos) + { + vtkName = vtkName.substr(i); + } + } + + // Create file and write header + const fileName outputName + ( + vtkDir/vtkName + + "_" + + timeDesc + ); + + Info<< name() << " output Time: " << time_.timeName() << nl + << " Internal : " << outputName << endl; + + vtk::vtuCells vtuMeshCells + ( + mesh_, + writeOpts_, + true // decompose + ); + + // Write mesh + vtk::internalWriter writer + ( + mesh_, + vtuMeshCells, + outputName, + writeOpts_ + ); + + // CellData + { + writer.beginCellData(nFields); + + // Write cellID field + if (writeIds_) + { + writer.writeCellIDs(); + } + + // Write volFields + writeFields<volScalarField>(writer); + writeFields<volVectorField>(writer); + writeFields<volSphericalTensorField>(writer); + writeFields<volSymmTensorField>(writer); + writeFields<volTensorField>(writer); + + writer.endCellData(); + } + + writer.writeFooter(); + + return true; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.H b/src/functionObjects/utilities/vtkWrite/vtkWrite.H similarity index 58% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.H rename to src/functionObjects/utilities/vtkWrite/vtkWrite.H index c15dd17f48580e76ef40512a6a613ac52d893fe2..025e92bdab21e505d14c7abad6924b92d271a468 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTK.H +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -22,71 +22,61 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::functionObjects::writeVTK + Foam::functionObjects::vtkWrite Group grpUtilitiesFunctionObjects Description - This functionObject writes objects registered to the database in VTK format - using the foamToVTK library. + This functionObject writes objects registered to the database in VTK format. - Currently only the writing of the cell-values of volFields is supported but + Currently only supports writing of the cell-values of volFields but support for other field types, patch fields, Lagrangian data etc. will be added. Example of function object specification: \verbatim - writeVTK1 - { - type writeVTK; - libs ("libutilityFunctionObjects.so"); - ... - objectNames (obj1 obj2); - } + vtkWrite1 + { + type vtkWrite; + libs ("libutilityFunctionObjects.so"); + writeControl writeTime; + writeInterval 1; + format binary; + legacy false; + ... + fields (U p); + } \endverbatim Usage \table Property | Description | Required | Default value - type | type name: writeVTK | yes | - objectNames | objects to write | yes | + type | Type name: vtkWrite | yes | + fields | Fields to output | yes | + writeControl | Output control | recommended | timeStep + directory | The output directory name | no | "VTK" + format | ASCII or binary format | no | binary + legacy | Legacy VTK output | no | false + writeIds | Write cell ids as field | no | true \endtable See also Foam::functionObjects::fvMeshFunctionObject Foam::functionObjects::timeControl - Example of function object specification to calculate Lambda2: - \verbatim - Lambda2_1 - { - type Lambda2; - functionObjectLibs ("libutilityFunctionObjects.so"); - ... - } - \endverbatim - - \heading Function object usage - \table - Property | Description | Required | Default value - type | Type name: Lambda2 | yes | - UName | Name of velocity field | no | U - resultName | Name of Lambda2 field | no | <function name> - log | Log to standard output | no | yes - \endtable - SourceFiles - writeVTK.C - IOwriteVTK.H + vtkWrite.C + vtkWriteTemplates.C \*---------------------------------------------------------------------------*/ -#ifndef functionObjects_writeVTK_H -#define functionObjects_writeVTK_H +#ifndef functionObjects_vtkWrite_H +#define functionObjects_vtkWrite_H #include "fvMeshFunctionObject.H" -#include "wordReList.H" +#include "foamVtkInternalWriter.H" +#include "wordRes.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -96,67 +86,77 @@ namespace functionObjects { /*---------------------------------------------------------------------------*\ - Class writeVTK Declaration + Class vtkWrite Declaration \*---------------------------------------------------------------------------*/ -class writeVTK +class vtkWrite : public fvMeshFunctionObject { // Private data - //- Names of objects - wordReList objectNames_; + //- VTK output options + vtk::outputOptions writeOpts_; + //- Name of fields to process + wordReList selectFields_; - //- Result name - word resultName_; + //- Output directory name + fileName dirName_; + + //- Write cell ids field + bool writeIds_; - //- Switch to send output to Info as well as to file - Switch log_; // Private Member Functions + //- Count number of selected fields for GeoField type. + // Only needed for legacy vtk format. + template<class GeoField> + label countFields() const; + + //- Write selected fields for GeoField type. template<class GeoField> - UPtrList<const GeoField> lookupFields() const; + label writeFields(vtk::internalWriter& writer, bool verbose=true) const; + //- Disallow default bitwise copy construct - writeVTK(const writeVTK&); + vtkWrite(const vtkWrite&) = delete; //- Disallow default bitwise assignment - void operator=(const writeVTK&); + void operator=(const vtkWrite&) = delete; public: //- Runtime type information - TypeName("writeVTK"); + TypeName("vtkWrite"); // Constructors //- Construct from Time and dictionary - writeVTK + vtkWrite ( const word& name, const Time& t, - const dictionary& + const dictionary& dict ); //- Destructor - virtual ~writeVTK(); + virtual ~vtkWrite(); // Member Functions - //- Read the writeVTK data - virtual bool read(const dictionary&); + //- Read the vtkWrite specification + virtual bool read(const dictionary& dict); //- Execute, currently does nothing virtual bool execute(); - //- Write the writeVTK + //- Write fields virtual bool write(); }; @@ -169,7 +169,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "writeVTKTemplates.C" + #include "vtkWriteTemplates.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTKTemplates.C b/src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C similarity index 63% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTKTemplates.C rename to src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C index e46f0333d4d02905fa08d4f11f0986c5d80bae78..1cdce49cd15a595d955244999a91238375282338 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeVTK/writeVTKTemplates.C +++ b/src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,38 +23,38 @@ License \*---------------------------------------------------------------------------*/ -#include "writeVTK.H" -#include "objectRegistry.H" -#include "DynamicList.H" - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class GeoField> -Foam::UPtrList<const GeoField> -Foam::functionObjects::writeVTK::lookupFields() const +Foam::label +Foam::functionObjects::vtkWrite::countFields() const { - DynamicList<word> allNames(obr_.toc().size()); - forAll(objectNames_, i) - { - wordList names(obr_.names<GeoField>(objectNames_[i])); + return obr_.names<GeoField>(selectFields_).size(); +} - if (names.size()) - { - allNames.append(names); - } - } - UPtrList<const GeoField> fields(allNames.size()); +template<class GeoField> +Foam::label +Foam::functionObjects::vtkWrite::writeFields +( + vtk::internalWriter& writer, + bool verbose +) const +{ + const wordList names = obr_.sortedNames<GeoField>(selectFields_); + + if (verbose && names.size()) + { + Info<< " " << GeoField::typeName + << " " << flatOutput(names) << endl; + } - forAll(allNames, i) + for (const word& fieldName : names) { - const GeoField& field = obr_.lookupObject<GeoField>(allNames[i]); - Info<< " Writing " << GeoField::typeName - << " field " << field.name() << endl; - fields.set(i, &field); + writer.write(obr_.lookupObject<GeoField>(fieldName)); } - return fields; + return names.size(); } diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index f9af11d9bef117e32cc43b44f7da06f863f18e40..1beec64e855e55a88d463127b5a86295d3601551 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -266,6 +266,10 @@ meshStructure/meshStructure.C meshStructure/topoDistanceData.C meshStructure/pointTopoDistanceData.C +output/foamVtkWriteFaceSet.C +output/foamVtkWritePointSet.C +output/foamVtkWriteCellSetFaces.C + regionCoupled/patches/regionCoupledPolyPatch/regionCoupledBase.C regionCoupled/patches/regionCoupledPolyPatch/regionCoupledPolyPatch.C regionCoupled/patches/regionCoupledPolyPatch/regionCoupledWallPolyPatch.C diff --git a/src/meshTools/output/foamVtkWriteCellSetFaces.C b/src/meshTools/output/foamVtkWriteCellSetFaces.C new file mode 100644 index 0000000000000000000000000000000000000000..a84b5d5b7068d508da4c3433364cbef5b60fb9d9 --- /dev/null +++ b/src/meshTools/output/foamVtkWriteCellSetFaces.C @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkWriteCellSetFaces.H" +#include "foamVtkOutputOptions.H" +#include "OFstream.H" +#include "primitiveMesh.H" +#include "cellSet.H" +#include "uindirectPrimitivePatch.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void Foam::vtk::writeCellSetFaces +( + const primitiveMesh& mesh, + const cellSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts +) +{ + outputOptions opts(outOpts); + opts.legacy(true); // Legacy only, no append + + const bool legacy_(opts.legacy()); + + std::ofstream os((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + + autoPtr<vtk::formatter> format = opts.newFormatter(os); + + if (legacy_) + { + legacy::fileHeader(format(), set.name(), vtk::fileTag::POLY_DATA); + } + + //------------------------------------------------------------------------- + + // External faces of cellset with OpenFOAM cellID as value + + Map<label> cellFaces(2*set.size()); + + forAllConstIters(set, iter) + { + label celli = iter.key(); + const cell& cFaces = mesh.cells()[celli]; + + forAll(cFaces, i) + { + label facei = cFaces[i]; + + if (mesh.isInternalFace(facei)) + { + label otherCelli = mesh.faceOwner()[facei]; + + if (otherCelli == celli) + { + otherCelli = mesh.faceNeighbour()[facei]; + } + + if (!set.found(otherCelli)) + { + cellFaces.insert(facei, celli); + } + } + else + { + cellFaces.insert(facei, celli); + } + } + } + + const labelList faceLabels = cellFaces.sortedToc(); + labelList faceValues(cellFaces.size()); + + forAll(faceLabels, facei) + { + faceValues[facei] = cellFaces[faceLabels[facei]]; // Cell ID + } + + uindirectPrimitivePatch pp + ( + UIndirectList<face>(mesh.faces(), faceLabels), + mesh.points() + ); + + //------------------------------------------------------------------------- + + // Write points and faces as polygons + legacy::beginPoints(os, pp.nPoints()); + + vtk::writeList(format(), pp.localPoints()); + format().flush(); + + // 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 + vtk::writeList(format(), f); + } + format().flush(); + + + // Write data - faceId/cellId + legacy::dataHeader(os, vtk::fileTag::CELL_DATA, pp.size(), 1); + + os << "cellID 1 " << pp.size() << " int" << nl; + + vtk::writeList(format(), faceValues); + format().flush(); +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H b/src/meshTools/output/foamVtkWriteCellSetFaces.H similarity index 65% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H rename to src/meshTools/output/foamVtkWriteCellSetFaces.H index 73ca4f07416e6fc9fdfff79350a6ddefdd876160..765ff60807fd28dd7c127940d5b2ed2699076913 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H +++ b/src/meshTools/output/foamVtkWriteCellSetFaces.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -21,38 +21,48 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -InClass - Foam::writeFaceSet +InNamespace + Foam::vtk Description - Write faceSet to vtk polydata file. Only one data which is original - faceID. + Write faces of cellSet to vtk polydata file. + + The data are the original cell ids SourceFiles - writeFaceSet.C + foamVtkWriteCellSetFaces.C \*---------------------------------------------------------------------------*/ -#ifndef writeFaceSet_H -#define writeFaceSet_H +#ifndef foamVtkWriteCellSetFaces_H +#define foamVtkWriteCellSetFaces_H -#include "fvMesh.H" -#include "faceSet.H" +#include "primitiveMesh.H" +#include "uindirectPrimitivePatch.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +class primitiveMesh; +class cellSet; +class fileName; + +namespace vtk +{ -// Write lagrangian fields. -void writeFaceSet +//- Write perimeter faces of cellset to vtk polydata file. +// The data are the original cell ids +void writeCellSetFaces ( - const bool binary, - const fvMesh&, - const faceSet& set, - const fileName& fileName + const primitiveMesh& mesh, + const cellSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts ); +} // End namespace vtk } // End namespace Foam diff --git a/src/meshTools/output/foamVtkWriteFaceSet.C b/src/meshTools/output/foamVtkWriteFaceSet.C new file mode 100644 index 0000000000000000000000000000000000000000..59c11329d4122d220a8915ed2cc825e63474a946 --- /dev/null +++ b/src/meshTools/output/foamVtkWriteFaceSet.C @@ -0,0 +1,108 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkWriteFaceSet.H" +#include "foamVtkOutputOptions.H" +#include "OFstream.H" +#include "primitiveMesh.H" +#include "faceSet.H" +#include "uindirectPrimitivePatch.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void Foam::vtk::writeFaceSet +( + const primitiveMesh& mesh, + const faceSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts +) +{ + outputOptions opts(outOpts); + opts.legacy(true); // Legacy only, no append + + const bool legacy_(opts.legacy()); + + std::ofstream os((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + + autoPtr<vtk::formatter> format = opts.newFormatter(os); + + if (legacy_) + { + legacy::fileHeader(format(), set.name(), vtk::fileTag::POLY_DATA); + } + + //------------------------------------------------------------------------- + + // Faces of set with OpenFOAM faceID as value + const labelList faceLabels = set.sortedToc(); + + uindirectPrimitivePatch pp + ( + UIndirectList<face>(mesh.faces(), faceLabels), + mesh.points() + ); + + //------------------------------------------------------------------------- + + // Write points and faces as polygons + legacy::beginPoints(os, pp.nPoints()); + + vtk::writeList(format(), pp.localPoints()); + format().flush(); + + // 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 + vtk::writeList(format(), f); + } + format().flush(); + + + // Write data - faceId/cellId + + legacy::dataHeader(os, vtk::fileTag::CELL_DATA, pp.size(), 1); + + os << "faceID 1 " << pp.size() << " int" << nl; + + vtk::writeList(format(), faceLabels); + format().flush(); +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/setSet/writePointSet.H b/src/meshTools/output/foamVtkWriteFaceSet.H similarity index 76% rename from applications/utilities/mesh/manipulation/setSet/writePointSet.H rename to src/meshTools/output/foamVtkWriteFaceSet.H index 983eb32aed029fff7f491aca2a7aa6348c4d848d..24ba0c3932b58e093d629d1daa46ba2433ec6584 100644 --- a/applications/utilities/mesh/manipulation/setSet/writePointSet.H +++ b/src/meshTools/output/foamVtkWriteFaceSet.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -22,38 +22,45 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. InNamespace - Foam + Foam::vtk Description - Write pointSet to vtk polydata file. Only one data which is original - pointID. + Write faceSet to vtk polydata file. + The data are the original point ids. SourceFiles - writePointSet.C + foamVtkWritePointSet.C \*---------------------------------------------------------------------------*/ -#ifndef writePointSet_H -#define writePointSet_H +#ifndef foamVtkWriteFaceSet_H +#define foamVtkWriteFaceSet_H -#include "primitiveMesh.H" -#include "pointSet.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +class primitiveMesh; +class faceSet; +class fileName; + +namespace vtk +{ //- Write pointSet to vtk polydata file. // Only one data which is original pointID. -void writePointSet +void writeFaceSet ( - const bool binary, const primitiveMesh& mesh, - const topoSet& set, - const fileName& fileName + const faceSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts ); + +} // End namespace vtk } // End namespace Foam diff --git a/src/meshTools/output/foamVtkWritePointSet.C b/src/meshTools/output/foamVtkWritePointSet.C new file mode 100644 index 0000000000000000000000000000000000000000..66cbfc8c4439d2902ce9131f1afce68a23878a99 --- /dev/null +++ b/src/meshTools/output/foamVtkWritePointSet.C @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "foamVtkWritePointSet.H" +#include "foamVtkOutputOptions.H" +#include "OFstream.H" +#include "primitiveMesh.H" +#include "pointSet.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void Foam::vtk::writePointSet +( + const primitiveMesh& mesh, + const pointSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts +) +{ + outputOptions opts(outOpts); + opts.legacy(true); // Legacy only, no append + + const bool legacy_(opts.legacy()); + + std::ofstream os((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str()); + + autoPtr<vtk::formatter> format = opts.newFormatter(os); + + if (legacy_) + { + legacy::fileHeader(format(), set.name(), vtk::fileTag::POLY_DATA); + } + + //------------------------------------------------------------------------- + + const labelList pointLabels(set.sortedToc()); + + // Write points + legacy::beginPoints(os, pointLabels.size()); + + vtk::writeList(format(), mesh.points(), pointLabels); + format().flush(); + + // Write data - pointID + legacy::dataHeader(os, vtk::fileTag::POINT_DATA, pointLabels.size(), 1); + + os << "pointID 1 " << pointLabels.size() << " int" << nl; + + vtk::writeList(format(), pointLabels); + format().flush(); +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/setSet/writePatch.H b/src/meshTools/output/foamVtkWritePointSet.H similarity index 70% rename from applications/utilities/mesh/manipulation/setSet/writePatch.H rename to src/meshTools/output/foamVtkWritePointSet.H index ccc82e835deda81369945bebcaf7053d5c3f7c8b..830dfd304a1363dab4e7fe815f9ab6c606f5dae2 100644 --- a/applications/utilities/mesh/manipulation/setSet/writePatch.H +++ b/src/meshTools/output/foamVtkWritePointSet.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -21,40 +21,46 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -InClass - Foam::writePatch +InNamespace + Foam::vtk Description - Write faceSet to vtk polydata file. Only one data which is original - faceID. + Write pointSet to vtk polydata file. + The data are the original point ids. SourceFiles - writePatch.C + foamVtkWritePointSet.C \*---------------------------------------------------------------------------*/ -#ifndef writePatch_H -#define writePatch_H +#ifndef foamVtkWritePointSet_H +#define foamVtkWritePointSet_H -#include "primitiveMesh.H" -#include "primitiveFacePatch.H" +#include "foamVtkOutputOptions.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +class primitiveMesh; +class pointSet; +class fileName; -// Write faceSet -void writePatch +namespace vtk +{ + +//- Write pointSet to vtk polydata file. +// The data are the original point ids. +void writePointSet ( - const bool binary, - const word& setName, - const primitiveFacePatch& fp, - const word& fieldName, - labelList& fieldValues, - const fileName& fileName + const primitiveMesh& mesh, + const pointSet& set, + const fileName& baseName, + const vtk::outputOptions outOpts ); + +} // End namespace vtk } // End namespace Foam diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files index 10d6171c207a6a1f0ef8349bb1d6e12fe19ad359..2bf796be62828de399df11d6bdf636011bf6fca9 100644 --- a/src/surfMesh/Make/files +++ b/src/surfMesh/Make/files @@ -37,6 +37,8 @@ $(surfaceFormats)/tri/TRIsurfaceFormatCore.C $(surfaceFormats)/tri/TRIsurfaceFormatRunTime.C $(surfaceFormats)/vtk/VTKsurfaceFormatCore.C $(surfaceFormats)/vtk/VTKsurfaceFormatRunTime.C +$(surfaceFormats)/vtp/VTPsurfaceFormatCore.C +$(surfaceFormats)/vtp/VTPsurfaceFormatRunTime.C $(surfaceFormats)/x3d/X3DsurfaceFormatCore.C $(surfaceFormats)/x3d/X3DsurfaceFormatRunTime.C diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C index b0a5d2711498e694299a1d41c2504fdd83eb5fd6..b7141105d6d5a0e974bd409778164c4b73cf9e22 100644 --- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C @@ -28,26 +28,54 @@ License #include "scalarIOField.H" #include "faceTraits.H" #include "OFstream.H" +#include "foamVtkOutput.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// File-scope constant. +// +// TODO: make this run-time selectable (ASCII | BINARY) +// - Legacy mode only + +static const Foam::vtk::formatType fmtType = + Foam::vtk::formatType::LEGACY_ASCII; + // Foam::vtk::formatType::LEGACY_BINARY; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class Face> -void Foam::fileFormats::VTKsurfaceFormat<Face>::writeHeaderPolygons +void Foam::fileFormats::VTKsurfaceFormat<Face>::writePolys ( - Ostream& os, - const UList<Face>& faceLst + vtk::formatter& format, + const UList<Face>& faces ) { - label nNodes = 0; + // connectivity count without additional storage (done internally) + label nConnectivity = 0; + for (const auto& f : faces) + { + nConnectivity += f.size(); + } - forAll(faceLst, facei) + vtk::legacy::beginPolys + ( + format.os(), + faces.size(), + nConnectivity + ); + + + // legacy: size + connectivity together + // [nPts, id1, id2, ..., nPts, id1, id2, ...] + + for (const Face& f : faces) { - nNodes += faceLst[facei].size(); + format.write(f.size()); // The size prefix + vtk::writeList(format, f); } - os << nl - << "POLYGONS " << faceLst.size() << ' ' - << faceLst.size() + nNodes << nl; + format.flush(); } @@ -115,31 +143,37 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read // Assume all faces in zone0 unless a region field is present labelList zones(faces.size(), 0); - if (reader.cellData().foundObject<scalarIOField>("region")) + + for (auto fieldName : { "region", "STLSolidLabeling" }) { - const scalarIOField& region = - reader.cellData().lookupObject<scalarIOField> - ( - "region" - ); - forAll(region, i) + const labelIOField* lptr = + reader.cellData().lookupObjectPtr<labelIOField>(fieldName); + + if (lptr) { - zones[i] = label(region[i]); + label i = 0; + for (const auto& region : *lptr) + { + zones[i++] = label(region); + } + break; } - } - else if (reader.cellData().foundObject<scalarIOField>("STLSolidLabeling")) - { - const scalarIOField& region = - reader.cellData().lookupObject<scalarIOField> - ( - "STLSolidLabeling" - ); - forAll(region, i) + + const scalarIOField* sptr = + reader.cellData().lookupObjectPtr<scalarIOField>(fieldName); + + if (sptr) { - zones[i] = label(region[i]); + label i = 0; + for (const auto& region : *sptr) + { + zones[i++] = label(region); + } + break; } } + // Create zone names const label nZones = max(zones)+1; wordList zoneNames(nZones); @@ -240,54 +274,54 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1); - OFstream os(filename); - if (!os.good()) - { - FatalErrorInFunction - << "Cannot open file for writing " << filename - << exit(FatalError); - } + std::ofstream os(filename.c_str()); + autoPtr<vtk::formatter> format = + vtk::newFormatter(os, fmtType); - writeHeader(os, pointLst); - writeHeaderPolygons(os, faceLst); + writeHeader(format(), pointLst); - label faceIndex = 0; - forAll(zones, zoneI) + if (useFaceMap) { - const surfZone& zone = zones[zoneI]; + // connectivity count without additional storage (done internally) + label nConnectivity = 0; + for (const auto& f : faceLst) + { + nConnectivity += f.size(); + } - if (useFaceMap) + vtk::legacy::beginPolys + ( + format().os(), + faceLst.size(), + nConnectivity + ); + + label faceIndex = 0; + for (const surfZone& zone : zones) { - forAll(zone, localFacei) + forAll(zone, i) { const Face& f = faceLst[faceMap[faceIndex++]]; - os << f.size(); - forAll(f, fp) - { - os << ' ' << f[fp]; - } - os << ' ' << nl; - } - } - else - { - forAll(zone, localFacei) - { - const Face& f = faceLst[faceIndex++]; - - os << f.size(); - forAll(f, fp) - { - os << ' ' << f[fp]; - } - os << ' ' << nl; + format().write(f.size()); // The size prefix + vtk::writeList(format(), f); } } + + format().flush(); + } + else + { + // Easy to write polys without a faceMap + writePolys(format(), faceLst); } - writeTail(os, zones); + // Write regions (zones) as CellData + if (zones.size() > 1) + { + writeCellData(format(), zones); + } } @@ -298,33 +332,18 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write const UnsortedMeshedSurface<Face>& surf ) { - OFstream os(filename); - if (!os.good()) - { - FatalErrorInFunction - << "Cannot open file for writing " << filename - << exit(FatalError); - } + std::ofstream os(filename.c_str()); + autoPtr<vtk::formatter> format = + vtk::newFormatter(os, fmtType); - const List<Face>& faceLst = surf.surfFaces(); + writeHeader(format(), surf.points()); - writeHeader(os, surf.points()); - writeHeaderPolygons(os, faceLst); - - forAll(faceLst, facei) - { - const Face& f = faceLst[facei]; - - os << f.size(); - forAll(f, fp) - { - os << ' ' << f[fp]; - } - os << ' ' << nl; - } + // Easy to write polys without a faceMap + writePolys(format(), surf.surfFaces()); - writeTail(os, surf.zoneIds()); + // Write regions (zones) as CellData + writeCellData(format(), surf.zoneIds()); } diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H index 437eb249212441ffc2c574e3259ad8bca6836652..9a73aceeb5adae70feb2e8e98a6f59e3a1c353a0 100644 --- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H +++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -60,8 +60,13 @@ class VTKsurfaceFormat { // Private Member Functions - //- Write header information about number of polygon points - static void writeHeaderPolygons(Ostream&, const UList<Face>&); + //- Write polygons + static void writePolys + ( + vtk::formatter& format, + const UList<Face>& faces + ); + //- Disallow default bitwise copy construct VTKsurfaceFormat(const VTKsurfaceFormat<Face>&) = delete; @@ -75,7 +80,7 @@ public: // Constructors //- Construct from file name - VTKsurfaceFormat(const fileName&); + VTKsurfaceFormat(const fileName& filename); // Selectors @@ -97,24 +102,24 @@ public: // Member Functions - // Write + // Write //- Write surface mesh components by proxy static void write ( - const fileName&, - const MeshedSurfaceProxy<Face>& + const fileName& filename, + const MeshedSurfaceProxy<Face>& surf ); //- Write UnsortedMeshedSurface, the output remains unsorted static void write ( - const fileName&, - const UnsortedMeshedSurface<Face>& + const fileName& fileName, + const UnsortedMeshedSurface<Face>& surf ); //- Read from file - virtual bool read(const fileName&); + virtual bool read(const fileName& filename); //- Write object file virtual void write(const fileName& name) const diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C index 9a28648d0c22c0310f6834c99fecfa893ed4552d..fe58168e5b23ffeb2eebb7e5c8e551fb9c905249 100644 --- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C +++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,102 +25,103 @@ License #include "VTKsurfaceFormatCore.H" #include "clock.H" +#include "foamVtkOutput.H" // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::fileFormats::VTKsurfaceFormatCore::writeHeader ( - Ostream& os, - const pointField& pointLst + vtk::formatter& format, + const pointField& pts ) { - // Write header - os << "# vtk DataFile Version 2.0" << nl - << "surface written " << clock::dateTime().c_str() << nl - << "ASCII" << nl - << nl - << "DATASET POLYDATA" << nl; - - // Write vertex coords - os << "POINTS " << pointLst.size() << " float" << nl; - forAll(pointLst, ptI) - { - const point& pt = pointLst[ptI]; + vtk::legacy::fileHeader + ( + format, + ("surface written " + clock::dateTime()), + vtk::fileTag::POLY_DATA + ); - os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl; - } + vtk::legacy::beginPoints(format.os(), pts.size()); + + vtk::writeList(format, pts); + format.flush(); } -void Foam::fileFormats::VTKsurfaceFormatCore::writeTail +void Foam::fileFormats::VTKsurfaceFormatCore::writeCellData ( - Ostream& os, - const UList<surfZone>& zoneLst + vtk::formatter& format, + const UList<surfZone>& zones ) { + // Zone ids as CellData + + // Number of faces covered by the zones label nFaces = 0; - forAll(zoneLst, zoneI) + for (const auto& z : zones) { - nFaces += zoneLst[zoneI].size(); + nFaces += z.size(); } - // Print zone numbers - os << nl - << "CELL_DATA " << nFaces << nl - << "FIELD attributes 1" << nl - << "region 1 " << nFaces << " float" << nl; - - - forAll(zoneLst, zoneI) + vtk::legacy::dataHeader + ( + format.os(), + vtk::fileTag::CELL_DATA, + nFaces, + 1 // Only one field + ); + + vtk::legacy::intField + ( + format.os(), + "region", + 1, // nComponent + nFaces + ); + + label zoneId = 0; + for (const surfZone& zone : zones) { - forAll(zoneLst[zoneI], localFacei) + forAll(zone, i) { - if (localFacei) - { - if (localFacei % 20) - { - os << ' '; - } - else - { - os << nl; - } - } - os << zoneI + 1; + format.write(zoneId); } - os << nl; + ++zoneId; } + format.flush(); } -void Foam::fileFormats::VTKsurfaceFormatCore::writeTail +void Foam::fileFormats::VTKsurfaceFormatCore::writeCellData ( - Ostream& os, + vtk::formatter& format, const labelUList& zoneIds ) { - // Print zone numbers - os << nl - << "CELL_DATA " << zoneIds.size() << nl - << "FIELD attributes 1" << nl - << "region 1 " << zoneIds.size() << " float" << nl; - - forAll(zoneIds, facei) - { - if (facei) - { - if (facei % 20) - { - os << ' '; - } - else - { - os << nl; - } - } - os << zoneIds[facei] + 1; - } - os << nl; + // Zone ids as CellData + + // 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::writeList(format, zoneIds); + format.flush(); } diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H index 946440ddb0cf3734cc1a2bf6e99d81d2b207c2ea..8b09942f87777ac28a80b2ed31d53df8c9bffd11 100644 --- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H +++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,7 +36,7 @@ SourceFiles #define VTKsurfaceFormatCore_H #include "MeshedSurface.H" -#include "Ostream.H" +#include "foamVtkFormatter.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,15 +58,24 @@ protected: //- Write header information with points static void writeHeader ( - Ostream&, - const pointField& + vtk::formatter& format, + const pointField& pts ); - //- Write trailing information with zone information - static void writeTail(Ostream&, const UList<surfZone>&); + //- Write regions (zones) information as CellData + static void writeCellData + ( + vtk::formatter& format, + const UList<surfZone>& zones + ); + + //- Write regions (zones) information as CellData + static void writeCellData + ( + vtk::formatter& format, + const labelUList& zoneIds + ); - //- Write trailing information with zone Ids - static void writeTail(Ostream&, const labelUList& zoneIds); }; diff --git a/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.C new file mode 100644 index 0000000000000000000000000000000000000000..edab56477518baca80b204c839c003f3513bc2f3 --- /dev/null +++ b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.C @@ -0,0 +1,251 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "VTPsurfaceFormat.H" +#include "OFstream.H" +#include "foamVtkOutput.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// File-scope constant. +// +// TODO: make this run-time selectable +// - No append mode supported +// - Legacy mode is dispatched via 'VTKsurfaceFormat' instead + +static const Foam::vtk::formatType fmtType = + Foam::vtk::formatType::INLINE_ASCII; + // Foam::vtk::formatType::INLINE_BASE64; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Face> +void Foam::fileFormats::VTPsurfaceFormat<Face>::writePolys +( + vtk::formatter& format, + const UList<Face>& faces +) +{ + format.tag(vtk::fileTag::POLYS); + + // + // 'connectivity' + // + { + uint64_t payLoad = 0; + for (const auto& f : faces) + { + payLoad += f.size(); + } + + format.openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + format.writeSize(payLoad * sizeof(label)); + + for (const Face& f : faces) + { + vtk::writeList(format, f); + } + + format.flush(); + format.endDataArray(); + } + + + // + // 'offsets' (connectivity offsets) + // + { + const uint64_t payLoad(faces.size() * sizeof(label)); + + format + .openDataArray<label>(vtk::dataArrayAttr::OFFSETS) + .closeTag(); + + format.writeSize(payLoad); + + label off = 0; + for (const auto& f : faces) + { + off += f.size(); + + format.write(off); + } + + format.flush(); + format.endDataArray(); + } + + format.endTag(vtk::fileTag::POLYS); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class Face> +Foam::fileFormats::VTPsurfaceFormat<Face>::VTPsurfaceFormat() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Face> +void Foam::fileFormats::VTPsurfaceFormat<Face>::write +( + const fileName& filename, + const MeshedSurfaceProxy<Face>& surf +) +{ + const pointField& pointLst = surf.points(); + const List<Face>& faceLst = surf.surfFaces(); + const List<label>& faceMap = surf.faceMap(); + + const List<surfZone>& zones = + ( + surf.surfZones().empty() + ? surfaceFormatsCore::oneZone(faceLst) + : surf.surfZones() + ); + + const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1); + + std::ofstream os(filename.c_str(), std::ios::binary); + + autoPtr<vtk::formatter> format = + vtk::newFormatter(os, fmtType); + + writeHeader(format(), pointLst, faceLst.size()); + + if (useFaceMap) + { + format().tag(vtk::fileTag::POLYS); + + // + // 'connectivity' + // + { + uint64_t payLoad = 0; + for (const auto& f : faceLst) + { + payLoad += f.size(); + } + + format().openDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY) + .closeTag(); + + format().writeSize(payLoad * sizeof(label)); + + label faceIndex = 0; + for (const surfZone& zone : zones) + { + forAll(zone, i) + { + const Face& f = faceLst[faceMap[faceIndex++]]; + + vtk::writeList(format(), f); + } + } + + format().flush(); + format().endDataArray(); + } + + + // + // 'offsets' (connectivity offsets) + // + { + const uint64_t payLoad(faceLst.size() * sizeof(label)); + + format() + .openDataArray<label>(vtk::dataArrayAttr::OFFSETS) + .closeTag(); + + format().writeSize(payLoad); + + label off = 0, faceIndex = 0; + for (const surfZone& zone : zones) + { + forAll(zone, i) + { + const Face& f = faceLst[faceMap[faceIndex++]]; + + off += f.size(); + + format().write(off); + } + } + + format().flush(); + format().endDataArray(); + } + + format().endTag(vtk::fileTag::POLYS); + } + else + { + // Easy to write polys without a faceMap + writePolys(format(), faceLst); + } + + // Write regions (zones) as CellData + if (zones.size() > 1) + { + writeCellData(format(), zones); + } + + writeFooter(format()); +} + + +template<class Face> +void Foam::fileFormats::VTPsurfaceFormat<Face>::write +( + const fileName& filename, + const UnsortedMeshedSurface<Face>& surf +) +{ + std::ofstream os(filename.c_str(), std::ios::binary); + + autoPtr<vtk::formatter> format = + vtk::newFormatter(os, fmtType); + + const List<Face>& faceLst = surf.surfFaces(); + + writeHeader(format(), surf.points(), faceLst.size()); + + // Easy to write polys without a faceMap + writePolys(format(), faceLst); + + // Write regions (zones) as CellData + writeCellData(format(), surf.zoneIds()); + + writeFooter(format()); +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.H similarity index 51% rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H rename to src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.H index b1836afb60e16c05542594272367a3ea69fdea25..ebc35eca0843a45c3592aa3e8451c1eed791f1b3 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H +++ b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormat.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -22,112 +22,109 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::internalWriter + Foam::fileFormats::VTPsurfaceFormat Description - Write fields (internal). + Provide a means of writing VTP (xml) format. + The output is never sorted by zone. SourceFiles - internalWriter.C - internalWriterTemplates.C + VTPsurfaceFormat.C \*---------------------------------------------------------------------------*/ -#ifndef internalWriter_H -#define internalWriter_H +#ifndef VTPsurfaceFormat_H +#define VTPsurfaceFormat_H -#include "OFstream.H" -#include "volFields.H" -#include "pointFields.H" -#include "vtkMesh.H" +#include "MeshedSurface.H" +#include "MeshedSurfaceProxy.H" +#include "UnsortedMeshedSurface.H" +#include "VTPsurfaceFormatCore.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { - -class volPointInterpolation; +namespace fileFormats +{ /*---------------------------------------------------------------------------*\ - Class internalWriter Declaration + Class VTPsurfaceFormat Declaration \*---------------------------------------------------------------------------*/ -class internalWriter +template<class Face> +class VTPsurfaceFormat +: + public MeshedSurface<Face>, + public VTPsurfaceFormatCore { - const vtkMesh& vMesh_; + // Private Member Functions + + //- Write polygons + static void writePolys + ( + vtk::formatter& format, + const UList<Face>& faces + ); - const bool binary_; - const fileName fName_; + //- Disallow default bitwise copy construct + VTPsurfaceFormat(const VTPsurfaceFormat<Face>&) = delete; + + //- Disallow default bitwise assignment + void operator=(const VTPsurfaceFormat<Face>&) = delete; - std::ofstream os_; public: // Constructors - //- Construct from components - internalWriter - ( - const vtkMesh&, - const bool binary, - const fileName& - ); + //- Construct null + VTPsurfaceFormat(); - // Member Functions + //- Destructor + virtual ~VTPsurfaceFormat() + {} - std::ofstream& os() - { - return os_; - } - //- Write cellIDs - void writeCellIDs(); + // Member Functions - //- Write generic GeometricFields - template<class Type, template<class> class PatchField, class GeoMesh> - void write - ( - const UPtrList<const GeometricField<Type, PatchField, GeoMesh>>& - ); + // Write - //- Write generic internal fields - template<class Type, class GeoMesh> - void write + //- Write surface mesh components by proxy + static void write ( - const PtrList<const DimensionedField<Type, volMesh>>& flds + const fileName& filename, + const MeshedSurfaceProxy<Face>& surf ); - //- Interpolate and write volFields - template<class Type> - void write + //- Write UnsortedMeshedSurface, the output remains unsorted + static void write ( - const volPointInterpolation&, - const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& + const fileName& filename, + const UnsortedMeshedSurface<Face>& surf ); - //- Interpolate and internal fields - template<class Type, class GeoMesh> - void write - ( - const volPointInterpolation&, - const PtrList<const DimensionedField<Type, volMesh>>& - ); + //- Write object file + virtual void write(const fileName& name) const + { + write(name, MeshedSurfaceProxy<Face>(*this)); + } }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace fileFormats } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "internalWriterTemplates.C" + #include "VTPsurfaceFormat.C" #endif - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif diff --git a/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.C new file mode 100644 index 0000000000000000000000000000000000000000..947b77d32fee41426770527263b7af7e13cfc91d --- /dev/null +++ b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.C @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "VTPsurfaceFormatCore.H" +#include "clock.H" +#include "foamVtkOutput.H" + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::fileFormats::VTPsurfaceFormatCore::writeHeader +( + vtk::formatter& format, + const pointField& pts, + const label nFaces +) +{ + // XML (inline) + + format + .xmlHeader() + .xmlComment("surface written " + clock::dateTime()) + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + + // <Piece> + format + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, pts.size()) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POLYS, nFaces) + .closeTag(); + + + // Points + + const uint64_t payLoad = (pts.size()*3* sizeof(float)); + + format.tag(vtk::fileTag::POINTS) + .openDataArray<float, 3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + + format.writeSize(payLoad); + vtk::writeList(format, pts); + format.flush(); + + format + .endDataArray() + .endTag(vtk::fileTag::POINTS); +} + + +void Foam::fileFormats::VTPsurfaceFormatCore::writeFooter +( + vtk::formatter& format +) +{ + // Slight cheat. </Piece> too + format.endTag(Foam::vtk::fileTag::PIECE); + + format.endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); +} + + + +void Foam::fileFormats::VTPsurfaceFormatCore::writeCellData +( + vtk::formatter& format, + const UList<surfZone>& zones +) +{ + // Zone ids as CellData + + // Number of faces covered by the zones + uint64_t payLoad = 0; + for (const auto& z : zones) + { + payLoad += z.size(); + } + + format.tag(vtk::fileTag::CELL_DATA); + format.openDataArray<label>("region") + .closeTag(); + + format.writeSize(payLoad * sizeof(label)); + + label zoneId = 0; + for (const surfZone& zone : zones) + { + forAll(zone, i) + { + format.write(zoneId); + } + ++zoneId; + } + + format.flush(); + format.endDataArray(); + + format.endTag(vtk::fileTag::CELL_DATA); +} + + +void Foam::fileFormats::VTPsurfaceFormatCore::writeCellData +( + vtk::formatter& format, + const labelUList& zoneIds +) +{ + // Zone ids as CellData + + format.tag(vtk::fileTag::CELL_DATA); + format.openDataArray<label>("region") + .closeTag(); + + const uint64_t payLoad(zoneIds.size() * sizeof(label)); + + format.writeSize(payLoad); + vtk::writeList(format, zoneIds); + + format.flush(); + format.endDataArray(); + + format.endTag(vtk::fileTag::CELL_DATA); + +} + + +// ************************************************************************* // diff --git a/src/fileFormats/vtk/foamVtkCore.H b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.H similarity index 54% rename from src/fileFormats/vtk/foamVtkCore.H rename to src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.H index adcdc00871a5300fb0e5ddb4e12345473d40b1f8..4b4a3ad85de4446b97d4a442ffaf63d5f9d48e0c 100644 --- a/src/fileFormats/vtk/foamVtkCore.H +++ b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatCore.H @@ -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) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -22,84 +22,70 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::foamVtkCore + Foam::fileFormats::VTPsurfaceFormatCore Description - Core routines for dealing with VTK files. + Internal class used by the VTPsurfaceFormat SourceFiles - foamVtkCore.C + VTPsurfaceFormatCore.C \*---------------------------------------------------------------------------*/ -#ifndef foamVtkCore_H -#define foamVtkCore_H +#ifndef VTPsurfaceFormatCore_H +#define VTPsurfaceFormatCore_H + +#include "MeshedSurface.H" +#include "foamVtkFormatter.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { - namespace fileFormats { /*---------------------------------------------------------------------------*\ - Class fileFormats::foamVtkCore Declaration + Class VTPsurfaceFormatCore Declaration \*---------------------------------------------------------------------------*/ -class foamVtkCore +class VTPsurfaceFormatCore { -public: - - // Public Data, Declarations - - //- The context when outputting a VTK file (XML or legacy). - enum OutputContext - { - INLINE, //<! Generate header and inline data - HEADER, //<! Generate header only - APPEND //<! Generate append-data - }; - - - //- Equivalent to enumeration in "vtkCellType.h" - enum vtkTypes - { - VTK_EMPTY_CELL = 0, - VTK_VERTEX = 1, - VTK_POLY_VERTEX = 2, - VTK_LINE = 3, - VTK_POLY_LINE = 4, - VTK_TRIANGLE = 5, - VTK_TRIANGLE_STRIP = 6, - VTK_POLYGON = 7, - VTK_PIXEL = 8, - VTK_QUAD = 9, - VTK_TETRA = 10, - VTK_VOXEL = 11, - VTK_HEXAHEDRON = 12, - VTK_WEDGE = 13, - VTK_PYRAMID = 14, - VTK_PENTAGONAL_PRISM = 15, - VTK_HEXAGONAL_PRISM = 16, - VTK_POLYHEDRON = 42 - }; - - protected: - // Constructors - - //- Construct null - foamVtkCore(); - + // Protected Member Functions + + //- Write file header information with points + static void writeHeader + ( + vtk::formatter& format, + const pointField& pts, + const label nFaces + ); + + //- Write file footer + static void writeFooter(vtk::formatter& format); + + + //- Write regions (zones) information as CellData + static void writeCellData + ( + vtk::formatter& format, + const UList<surfZone>& zones + ); + + //- Write regions (zones) information as CellData + static void writeCellData + ( + vtk::formatter& format, + const labelUList& zoneIds + ); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace fileFormats - } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatRunTime.C new file mode 100644 index 0000000000000000000000000000000000000000..ab9ca19e13028e38dd903f78ec4e105bb1a18ba0 --- /dev/null +++ b/src/surfMesh/surfaceFormats/vtp/VTPsurfaceFormatRunTime.C @@ -0,0 +1,98 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 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 "VTPsurfaceFormat.H" + +#include "addToRunTimeSelectionTable.H" +#include "addToMemberFunctionSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace fileFormats +{ +// write MeshedSurfaceProxy +addNamedTemplatedToMemberFunctionSelectionTable +( + MeshedSurfaceProxy, + VTPsurfaceFormat, + face, + write, + fileExtension, + vtp +); +addNamedTemplatedToMemberFunctionSelectionTable +( + MeshedSurfaceProxy, + VTPsurfaceFormat, + triFace, + write, + fileExtension, + vtp +); +addNamedTemplatedToMemberFunctionSelectionTable +( + MeshedSurfaceProxy, + VTPsurfaceFormat, + labelledTri, + write, + fileExtension, + vtp +); + +// write UnsortedMeshedSurface +addNamedTemplatedToMemberFunctionSelectionTable +( + UnsortedMeshedSurface, + VTPsurfaceFormat, + face, + write, + fileExtension, + vtp +); +addNamedTemplatedToMemberFunctionSelectionTable +( + UnsortedMeshedSurface, + VTPsurfaceFormat, + triFace, + write, + fileExtension, + vtp +); +addNamedTemplatedToMemberFunctionSelectionTable +( + UnsortedMeshedSurface, + VTPsurfaceFormat, + labelledTri, + write, + fileExtension, + vtp +); + +} +} + +// ************************************************************************* // diff --git a/src/surfMesh/triSurface/interfaces/VTK/writeVTK.C b/src/surfMesh/triSurface/interfaces/VTK/writeVTK.C index 41e33ea0c5db5f4a733f830e2bcd7e0a2adc30ef..047a5c53a755599a93bed86607c17610bb7daefd 100644 --- a/src/surfMesh/triSurface/interfaces/VTK/writeVTK.C +++ b/src/surfMesh/triSurface/interfaces/VTK/writeVTK.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,159 +24,144 @@ License \*---------------------------------------------------------------------------*/ #include "triSurface.H" +#include "foamVtkOutput.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// File-scope constant. +// +// TODO: make this run-time selectable (ASCII | BINARY) +// - Legacy mode only + +static const Foam::vtk::formatType fmtType = + Foam::vtk::formatType::LEGACY_ASCII; + // Foam::vtk::formatType::LEGACY_BINARY; -namespace Foam -{ // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void triSurface::writeVTK(const bool writeSorted, Ostream& os) const +void Foam::triSurface::writeVTK +( + const bool writeSorted, + std::ostream& os +) const { - // Write header - os << "# vtk DataFile Version 2.0" << nl - << "triSurface" << nl - << "ASCII" << nl - << "DATASET POLYDATA" - << nl; + autoPtr<vtk::formatter> format = + vtk::newFormatter(os, fmtType); - const pointField& ps = points(); + // Header + vtk::legacy::fileHeader + ( + format(), + "triSurface", + vtk::fileTag::POLY_DATA + ); - os << "POINTS " << ps.size() << " float" << nl; + const pointField& pts = this->points(); + const auto& faceLst = this->surfFaces(); - // Write vertex coords - forAll(ps, pointi) - { - if (pointi > 0 && (pointi % 10) == 0) - { - os << nl; - } - else - { - os << ' '; - } - os << ps[pointi].x() << ' ' - << ps[pointi].y() << ' ' - << ps[pointi].z(); - } - os << nl; + const label nFaces = faceLst.size(); + + // Points + vtk::legacy::beginPoints(os, pts.size()); + + vtk::writeList(format(), pts); + format().flush(); - os << "POLYGONS " << size() << ' ' << 4*size() << nl; + // connectivity count (without additional storage) + // is simply 3 * nFaces + + vtk::legacy::beginPolys(os, nFaces, 3*nFaces); labelList faceMap; surfacePatchList patches(calcPatches(faceMap)); - if (writeSorted) + const bool useFaceMap = (writeSorted && patches.size() > 1); + + if (useFaceMap) { label faceIndex = 0; - - forAll(patches, patchi) + for (const surfacePatch& patch : patches) { - // Print all faces belonging to this patch - - for - ( - label patchFacei = 0; - patchFacei < patches[patchi].size(); - patchFacei++ - ) + forAll(patch, i) { - if (faceIndex > 0 && (faceIndex % 10) == 0) - { - os << nl; - } - else - { - os << ' '; - } + const Face& f = faceLst[faceMap[faceIndex++]]; - const label facei = faceMap[faceIndex++]; - - os << "3 " - << operator[](facei)[0] << ' ' - << operator[](facei)[1] << ' ' - << operator[](facei)[2]; + format().write(3); // The size prefix + vtk::writeList(format(), f); } } - os << nl; - + format().flush(); - // Print region numbers - os << "CELL_DATA " << size() << nl; - os << "FIELD attributes 1" << nl; - os << "region 1 " << size() << " float" << nl; - - faceIndex = 0; - - forAll(patches, patchi) + // Write regions (zones) as CellData + if (patches.size() > 1) { - for + vtk::legacy::dataHeader + ( + os, + vtk::fileTag::CELL_DATA, + nFaces, + 1 // Only one field + ); + + vtk::legacy::intField ( - label patchFacei = 0; - patchFacei < patches[patchi].size(); - patchFacei++ - ) + os, + "region", + 1, // nComponent + nFaces + ); + + faceIndex = 0; + for (const surfacePatch& patch : patches) { - if (faceIndex > 0 && (faceIndex % 10) == 0) - { - os << nl; - } - else + forAll(patch, i) { - os << ' '; + const Face& f = faceLst[faceMap[faceIndex++]]; + format().write(f.region()); } - - const label facei = faceMap[faceIndex++]; - - os << operator[](facei).region(); } + format().flush(); } - os << nl; } else { - forAll(*this, facei) + // No faceMap (unsorted) + + for (const Face& f : faceLst) { - if (facei > 0 && (facei % 10) == 0) - { - os << nl; - } - else - { - os << ' '; - } - os << "3 " - << operator[](facei)[0] << ' ' - << operator[](facei)[1] << ' ' - << operator[](facei)[2]; + format().write(3); // The size prefix + vtk::writeList(format(), f); } - os << nl; + format().flush(); + - os << "CELL_DATA " << size() << nl; - os << "FIELD attributes 1" << nl; - os << "region 1 " << size() << " float" << nl; + // Write regions (zones) as CellData - forAll(*this, facei) + vtk::legacy::dataHeader + ( + os, + vtk::fileTag::CELL_DATA, + faceLst.size(), + 1 // Only one field + ); + + vtk::legacy::intField + ( + os, + "region", + 1, // nComponent + faceLst.size() + ); + + for (const Face& f : faceLst) { - if (facei > 0 && (facei % 10) == 0) - { - os << nl; - } - else - { - os << ' '; - } - os << operator[](facei).region(); + format().write(f.region()); } - os << nl; + format().flush(); } } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - // ************************************************************************* // diff --git a/src/surfMesh/triSurface/triSurface.C b/src/surfMesh/triSurface/triSurface.C index fa8c7ba874c733346007586db38076584317fb92..324c7913de7e80ce93780fdf15feed40c557f742 100644 --- a/src/surfMesh/triSurface/triSurface.C +++ b/src/surfMesh/triSurface/triSurface.C @@ -33,6 +33,7 @@ License #include "PackedBoolList.H" #include "surfZoneList.H" #include "surfaceFormatsCore.H" +#include "MeshedSurfaceProxy.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -52,7 +53,9 @@ const Foam::wordHashSet Foam::triSurface::readTypes_ const Foam::wordHashSet Foam::triSurface::writeTypes_ { - "ftr", "stl", "stlb", "gts", "obj", "off", "tri", "ac", "smesh", "vtk" + "ftr", "stl", "stlb", "gts", "obj", "off", "tri", "ac", "smesh", "vtk", + // via proxy: + "inp", "vtp" }; @@ -477,8 +480,9 @@ bool Foam::triSurface::read { FatalErrorInFunction << "unknown file extension " << ext - << ". Supported extensions are '.ftr', '.stl', '.stlb', '.gts'" - << ", '.obj', '.ac', '.off', '.nas', '.tri' and '.vtk'" + << " for reading file " << name + << ". Supported extensions:" << nl + << " " << flatOutput(readTypes_.sortedToc()) << nl << exit(FatalError); return false; @@ -504,7 +508,7 @@ void Foam::triSurface::write } else if (ext == "stlb") { - ofstream outFile(name.c_str(), std::ios::binary); + std::ofstream outFile(name.c_str(), std::ios::binary); writeSTLBINARY(outFile); } @@ -522,7 +526,27 @@ void Foam::triSurface::write } else if (ext == "vtk") { - writeVTK(sort, OFstream(name)()); + std::ofstream outFile(name.c_str(), std::ios::binary); + writeVTK(sort, outFile); + } + else if + ( + ext == "inp" // STARCD + || ext == "vtp" // VTK + ) + { + labelList faceMap; + List<surfZone> zoneLst = this->sortedZones(faceMap); + + MeshedSurfaceProxy<labelledTri> proxy + ( + this->points(), + this->surfFaces(), + zoneLst, + faceMap + ); + + proxy.write(name, ext); } else if (ext == "tri") { @@ -540,10 +564,9 @@ void Foam::triSurface::write { FatalErrorInFunction << "unknown file extension " << ext - << " for file " << name - << ". Supported extensions are '.ftr', '.stl', '.stlb', " - << "'.gts', '.obj', '.vtk'" - << ", '.off', '.smesh', '.ac' and '.tri'" + << " for writing file " << name + << ". Supported extensions:" << nl + << " " << flatOutput(writeTypes_.sortedToc()) << nl << exit(FatalError); } } diff --git a/src/surfMesh/triSurface/triSurface.H b/src/surfMesh/triSurface/triSurface.H index fa10f875578efc18023617b69c2278845ee8c10d..24f8b5183787adbfe13ccea8a4f23a415bd22f29 100644 --- a/src/surfMesh/triSurface/triSurface.H +++ b/src/surfMesh/triSurface/triSurface.H @@ -167,7 +167,7 @@ class triSurface void writeOFF(const bool writeSorted, Ostream&) const; //- Write to VTK legacy format. - void writeVTK(const bool writeSorted, Ostream&) const; + void writeVTK(const bool writeSorted, std::ostream& os) const; //- Write to Ostream in TRI (AC3D) format // Ac3d .tri format (unmerged triangle format) @@ -318,143 +318,145 @@ public: // Member Functions - // Access - - const geometricSurfacePatchList& patches() const - { - return patches_; - } - - geometricSurfacePatchList& patches() - { - return patches_; - } - - //- Return edge-face addressing sorted (for edges with more than - // 2 faces) according to the angle around the edge. - // Orientation is anticlockwise looking from - // edge.vec(localPoints()) - const labelListList& sortedEdgeFaces() const; - - //- If 2 face neighbours: label of face where ordering of edge - // is consistent with righthand walk. - // If 1 neighbour: label of only face. - // If >2 neighbours: undetermined. - const labelList& edgeOwner() const; - + // Access - //- Face area vectors (normals) - inline const vectorField& Sf() const - { - return ParentType::faceAreas(); - } + const geometricSurfacePatchList& patches() const + { + return patches_; + } - //- Face area magnitudes - inline const scalarField& magSf() const - { - return ParentType::magFaceAreas(); - } + geometricSurfacePatchList& patches() + { + return patches_; + } - //- Face centres - inline const vectorField& Cf() const - { - return ParentType::faceCentres(); - } + //- Return const access to the faces + inline const List<labelledTri>& surfFaces() const + { + return static_cast<const List<labelledTri>&>(*this); + } + //- Return edge-face addressing sorted (for edges with more than + // 2 faces) according to the angle around the edge. + // Orientation is anticlockwise looking from + // edge.vec(localPoints()) + const labelListList& sortedEdgeFaces() const; - // Interoperability with other surface mesh classes + //- If 2 face neighbours: label of face where ordering of edge + // is consistent with righthand walk. + // If 1 neighbour: label of only face. + // If >2 neighbours: undetermined. + const labelList& edgeOwner() const; - //- Sort faces according to zoneIds - // Returns a surfZoneList and sets faceMap to index within faces() - // (i.e. map from original,unsorted to sorted) - List<surfZone> sortedZones(labelList& faceMap) const; - //- Create a list of faces from the triFaces - void triFaceFaces(List<face>& plainFaceList) const; + //- Face area vectors (normals) + inline const vectorField& Sf() const + { + return ParentType::faceAreas(); + } + //- Face area magnitudes + inline const scalarField& magSf() const + { + return ParentType::magFaceAreas(); + } - // Edit + //- Face centres + inline const vectorField& Cf() const + { + return ParentType::faceCentres(); + } + + + // Interoperability with other surface mesh classes + + //- Sort faces according to zoneIds + // Returns a surfZoneList and sets faceMap to index within faces() + // (i.e. map from original,unsorted to sorted) + List<surfZone> sortedZones(labelList& faceMap) const; + + //- Create a list of faces from the triFaces + void triFaceFaces(List<face>& plainFaceList) const; - //- Move points - virtual void movePoints(const pointField&); - //- Scale points. A non-positive factor is ignored - virtual void scalePoints(const scalar); + // Edit - //- Check/remove duplicate/degenerate triangles - void checkTriangles(const bool verbose); + //- Move points + virtual void movePoints(const pointField&); - //- Check triply (or more) connected edges. - void checkEdges(const bool verbose); + //- Scale points. A non-positive factor is ignored + virtual void scalePoints(const scalar); - //- Remove non-valid triangles - void cleanup(const bool verbose); + //- Check/remove duplicate/degenerate triangles + void checkTriangles(const bool verbose); - //- Fill faceZone with currentZone for every face reachable - // from facei without crossing edge marked in borderEdge. - // Note: faceZone has to be sized nFaces before calling this fun. - void markZone - ( - const boolList& borderEdge, - const label facei, - const label currentZone, - labelList& faceZone - ) const; + //- Check triply (or more) connected edges. + void checkEdges(const bool verbose); - //- (size and) fills faceZone with zone of face. Zone is area - // reachable by edge crossing without crossing borderEdge - // (bool for every edge in surface). Returns number of zones. - label markZones - ( - const boolList& borderEdge, - labelList& faceZone - ) const; + //- Remove non-valid triangles + void cleanup(const bool verbose); - //- 'Create' sub mesh, including only faces for which - // boolList entry is true - // Sets: pointMap: from new to old localPoints - // faceMap: new to old faces - void subsetMeshMap - ( - const boolList& include, - labelList& pointMap, - labelList& faceMap - ) const; - - //- Return new surface. Returns pointMap, faceMap from - // subsetMeshMap - triSurface subsetMesh - ( - const boolList& include, - labelList& pointMap, - labelList& faceMap - ) const; + //- Fill faceZone with currentZone for every face reachable + // from facei without crossing edge marked in borderEdge. + // Note: faceZone has to be sized nFaces before calling this fun. + void markZone + ( + const boolList& borderEdge, + const label facei, + const label currentZone, + labelList& faceZone + ) const; + + //- (size and) fills faceZone with zone of face. Zone is area + // reachable by edge crossing without crossing borderEdge + // (bool for every edge in surface). Returns number of zones. + label markZones + ( + const boolList& borderEdge, + labelList& faceZone + ) const; + + //- 'Create' sub mesh, including only faces for which + // boolList entry is true + // Sets: pointMap: from new to old localPoints + // faceMap: new to old faces + void subsetMeshMap + ( + const boolList& include, + labelList& pointMap, + labelList& faceMap + ) const; + + //- Return new surface. Returns pointMap, faceMap from + // subsetMeshMap + triSurface subsetMesh + ( + const boolList& include, + labelList& pointMap, + labelList& faceMap + ) const; - //- Transfer stored faces to an Xfer container - Xfer<List<labelledTri>> xferFaces(); - - //- Transfer stored points to an Xfer container - Xfer<List<point>> xferPoints(); + //- Transfer stored faces to an Xfer container + Xfer<List<labelledTri>> xferFaces(); + //- Transfer stored points to an Xfer container + Xfer<List<point>> xferPoints(); - // Write - //- Write to Ostream in simple FOAM format - void write(Ostream&) const; + // Write - //- Generic write routine. Chooses writer based on extension. - void write(const fileName&, const bool sortByRegion = false) const; + //- Write to Ostream in simple FOAM format + void write(Ostream&) const; - //- Write to database - void write(const Time&) const; + //- Generic write routine. Chooses writer based on extension. + void write(const fileName&, const bool sortByRegion = false) const; - //- Write to Ostream in OpenDX format - void writeDX(const scalarField&, Ostream&) const; - void writeDX(const vectorField&, Ostream&) const; + //- Write to database + void write(const Time&) const; - //- Write some statistics - void writeStats(Ostream&) const; + //- Write some statistics + void writeStats(Ostream& os) const; // Member operators diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite b/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite index 34e7b14d71b4f1e12eea04845ba07454a9f3264b..2630bdc3b63debd09671c9747ef073584682e9b7 100644 --- a/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite +++ b/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite @@ -10,8 +10,8 @@ ensightWrite // Fields to output (words or regex) fields (U p "(k|epsilon|omega)"); - writeControl writeTime; - writeIterval 1; + writeControl writeTime; + writeInterval 1; } // ************************************************************************* // diff --git a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/controlDict b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/controlDict index 7ceca861c1be4f50552b4ba7b4588ed3bbced585..2f6bf243811bd5adbf5df6cc4a73fbb69a42eafe 100644 --- a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/controlDict +++ b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/controlDict @@ -50,6 +50,8 @@ runTimeModifiable true; functions { + #include "vtkWrite" } + // ************************************************************************* // diff --git a/tutorials/incompressible/simpleFoam/windAroundBuildings/system/vtkWrite b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/vtkWrite new file mode 100644 index 0000000000000000000000000000000000000000..9f729db0cba4f5feeb3aad2341dd483c75941b0c --- /dev/null +++ b/tutorials/incompressible/simpleFoam/windAroundBuildings/system/vtkWrite @@ -0,0 +1,31 @@ +// -*- C++ -*- +// Minimal example of using the vtkWrite function object. +vtkWrite +{ + type vtkWrite; + libs ("libutilityFunctionObjects.so"); + log true; + + // Fields to output (words or regex) + fields (U p "(k|epsilon|omega)"); + + //- Output format (ascii | binary) - Default=binary + // format binary; + + //- Use legacy output format - Default=false + // legacy false; + + //- Output directory name - Default="VTK" + // directory "VTK"; + + //- Write cell ids as field - Default=true + writeIds false; + + writeControl writeTime; + writeInterval 1; + + writeControl timeStep; + writeInterval 25; +} + +// ************************************************************************* //