Merge branch 'feature-paraview-vtk' into 'develop'

Feature paraview vtk

See merge request !116
This commit is contained in:
Andrew Heather
2017-06-14 14:16:18 +01:00
163 changed files with 12446 additions and 9478 deletions

View File

@ -1,7 +1,3 @@
writePointSet.C
writeFuns.C
writePatch.C
setSet.C setSet.C
EXE = $(FOAM_APPBIN)/setSet EXE = $(FOAM_APPBIN)/setSet

View File

@ -1,4 +1,5 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
$(COMP_FLAGS) $(COMP_FLAGS)

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,8 +44,9 @@ Description
#include "OFstream.H" #include "OFstream.H"
#include "IFstream.H" #include "IFstream.H"
#include "demandDrivenData.H" #include "demandDrivenData.H"
#include "writePatch.H" #include "foamVtkWriteCellSetFaces.H"
#include "writePointSet.H" #include "foamVtkWriteFaceSet.H"
#include "foamVtkWritePointSet.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "cellZoneSet.H" #include "cellZoneSet.H"
#include "faceZoneSet.H" #include "faceZoneSet.H"
@ -75,104 +76,39 @@ void writeVTK
( (
const polyMesh& mesh, const polyMesh& mesh,
const topoSet& currentSet, const topoSet& currentSet,
const fileName& vtkName const fileName& vtkBaseName
) )
{ {
if (isA<faceSet>(currentSet)) if (isA<faceSet>(currentSet))
{ {
// Faces of set with OpenFOAM faceID as value // Faces of set with OpenFOAM faceID as value
vtk::writeFaceSet
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
( (
true, mesh,
currentSet.name(), currentSet,
fp, mesh.time().path()/vtkBaseName,
"faceID", vtk::formatType::LEGACY_BINARY
faceValues,
mesh.time().path()/vtkName
); );
} }
else if (isA<cellSet>(currentSet)) else if (isA<cellSet>(currentSet))
{ {
// External faces of cellset with OpenFOAM cellID as value // External faces of cellset with OpenFOAM cellID as value
vtk::writeCellSetFaces
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
( (
true, mesh,
currentSet.name(), currentSet,
fp, mesh.time().path()/vtkBaseName,
"cellID", vtk::formatType::LEGACY_BINARY
faceValues,
mesh.time().path()/vtkName
); );
} }
else if (isA<pointSet>(currentSet)) else if (isA<pointSet>(currentSet))
{ {
writePointSet vtk::writePointSet
( (
true,
mesh, mesh,
currentSet, currentSet,
mesh.time().path()/vtkName mesh.time().path()/vtkBaseName,
vtk::formatType::LEGACY_BINARY
); );
} }
else else
@ -187,58 +123,58 @@ void writeVTK
void printHelp(Ostream& os) void printHelp(Ostream& os)
{ {
os << "Please type 'help', 'list', 'quit', 'time ddd'" os << "Please type 'help', 'list', 'quit', 'time ddd'"
<< " or a set command after prompt." << endl << " or a set command after prompt." << nl
<< "'list' will show all current cell/face/point sets." << endl << "'list' will show all current cell/face/point sets." << nl
<< "'time ddd' will change the current time." << endl << "'time ddd' will change the current time." << nl
<< endl << nl
<< "A set command should be of the following form" << endl << "A set command should be of the following form" << nl
<< endl << nl
<< " cellSet|faceSet|pointSet <setName> <action> <source>" << " cellSet|faceSet|pointSet <setName> <action> <source>"
<< endl << nl
<< endl << nl
<< "The <action> is one of" << endl << "The <action> is one of" << nl
<< " list - prints the contents of the set" << endl << " list - prints the contents of the set" << nl
<< " clear - clears the set" << endl << " clear - clears the set" << nl
<< " invert - inverts the set" << endl << " invert - inverts the set" << nl
<< " remove - remove the set" << endl << " remove - remove the set" << nl
<< " new <source> - sets to set to the source set" << endl << " new <source> - sets to set to the source set" << nl
<< " add <source> - adds all elements from the source set" << endl << " add <source> - adds all elements from the source set" << nl
<< " delete <source> - deletes ,," << endl << " delete <source> - deletes ,," << nl
<< " subset <source> - combines current set with the source set" << " subset <source> - combines current set with the source set"
<< endl << nl
<< endl << nl
<< "The sources come in various forms. Type a wrong source" << "The sources come in various forms. Type a wrong source"
<< " to see all the types available." << endl << " to see all the types available." << nl
<< endl << nl
<< "Example: pick up all cells connected by point or face to patch" << "Example: pick up all cells connected by point or face to patch"
<< " movingWall" << endl << " movingWall" << nl
<< endl << nl
<< "Pick up all faces of patch:" << endl << "Pick up all faces of patch:" << nl
<< " faceSet f0 new patchToFace movingWall" << endl << " faceSet f0 new patchToFace movingWall" << nl
<< "Add faces 0,1,2:" << endl << "Add faces 0,1,2:" << nl
<< " faceSet f0 add labelToFace (0 1 2)" << endl << " faceSet f0 add labelToFace (0 1 2)" << nl
<< "Pick up all points used by faces in faceSet f0:" << endl << "Pick up all points used by faces in faceSet f0:" << nl
<< " pointSet p0 new faceToPoint f0 all" << endl << " pointSet p0 new faceToPoint f0 all" << nl
<< "Pick up cell which has any face in f0:" << endl << "Pick up cell which has any face in f0:" << nl
<< " cellSet c0 new faceToCell f0 any" << endl << " cellSet c0 new faceToCell f0 any" << nl
<< "Add cells which have any point in p0:" << endl << "Add cells which have any point in p0:" << nl
<< " cellSet c0 add pointToCell p0 any" << endl << " cellSet c0 add pointToCell p0 any" << nl
<< "List set:" << endl << "List set:" << nl
<< " cellSet c0 list" << endl << " cellSet c0 list" << nl
<< endl << nl
<< "Zones can be set using zoneSets from corresponding sets:" << endl << "Zones can be set using zoneSets from corresponding sets:" << nl
<< " cellZoneSet c0Zone new setToCellZone c0" << endl << " cellZoneSet c0Zone new setToCellZone c0" << nl
<< " faceZoneSet f0Zone new setToFaceZone f0" << endl << " faceZoneSet f0Zone new setToFaceZone f0" << nl
<< endl << nl
<< "or if orientation is important:" << endl << "or if orientation is important:" << nl
<< " faceZoneSet f0Zone new setsToFaceZone f0 c0" << endl << " faceZoneSet f0Zone new setsToFaceZone f0 c0" << nl
<< endl << nl
<< "ZoneSets can be manipulated using the general actions:" << endl << "ZoneSets can be manipulated using the general actions:" << nl
<< " list - prints the contents of the set" << endl << " list - prints the contents of the set" << nl
<< " clear - clears the set" << endl << " clear - clears the set" << nl
<< " invert - inverts the set (undefined orientation)" << " invert - inverts the set (undefined orientation)"
<< endl << nl
<< " remove - remove the set" << endl << " remove - remove the set" << nl
<< endl; << endl;
} }
@ -577,7 +513,6 @@ bool doCommand
"VTK"/currentSet.name()/currentSet.name() "VTK"/currentSet.name()/currentSet.name()
+ "_" + "_"
+ name(mesh.time().timeIndex()) + name(mesh.time().timeIndex())
+ ".vtk"
); );
Info<< " Writing " << currentSet.name() Info<< " Writing " << currentSet.name()

View File

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

View File

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

View File

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

View File

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

View File

@ -173,8 +173,7 @@ int main(int argc, char *argv[])
( (
"name", "name",
"subdir", "subdir",
"define sub-directory name to use for ensight data " "sub-directory name for ensight output (default: 'EnSight')"
"(default: 'EnSight')"
); );
argList::addOption argList::addOption
( (

View File

@ -128,8 +128,7 @@ int main(int argc, char *argv[])
( (
"name", "name",
"subdir", "subdir",
"define sub-directory name to use for Ensight data " "sub-directory name for ensight output (default: 'Ensight')"
"(default: \"Ensight\")"
); );
argList::addOption argList::addOption
( (

View File

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

View File

@ -1,3 +1,4 @@
foamVtkLagrangianWriter.C
foamToVTK.C foamToVTK.C
EXE = $(FOAM_APPBIN)/foamToVTK EXE = $(FOAM_APPBIN)/foamToVTK

View File

@ -1,12 +1,13 @@
EXE_INC = \ EXE_INC = \
-IfoamToVTK/lnInclude \ -I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfoamToVTK \ -lconversion \
-ldynamicMesh \ -ldynamicMesh \
-llagrangian \ -llagrangian \
-lgenericPatchFields -lgenericPatchFields

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::lagrangianWriter Foam::vtk::lagrangianWriter
Description Description
Write fields (internal). Write fields (internal).
@ -33,32 +33,42 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef lagrangianWriter_H #ifndef foamVtkLagrangianWriter_H
#define lagrangianWriter_H #define foamVtkLagrangianWriter_H
#include "OFstream.H" #include "OFstream.H"
#include "Cloud.H" #include "Cloud.H"
#include "volFields.H" #include "volFields.H"
#include "pointFields.H" #include "pointFields.H"
#include "foamVtkOutputOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
class volPointInterpolation; class volPointInterpolation;
namespace vtk
{
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class lagrangianWriter Declaration Class lagrangianWriter Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class lagrangianWriter class lagrangianWriter
{ {
// Private Member Data
//- Reference to the OpenFOAM mesh (or subset)
const fvMesh& mesh_; const fvMesh& mesh_;
const bool binary_; //- Commonly used query
const bool legacy_;
const fileName fName_; //- Write lagrangian as cell data (verts) or point data?
const bool useVerts_;
autoPtr<vtk::formatter> format_;
const word cloudName_; const word cloudName_;
@ -67,6 +77,28 @@ class lagrangianWriter
label nParcels_; label nParcels_;
// Private Member Functions
//- Begin piece
void beginPiece();
//- Write positions
void writePoints();
//- Write vertex (cells)
void writeVertsLegacy();
//- Write vertex (cells)
void writeVerts();
//- Disallow default bitwise copy construct
lagrangianWriter(const lagrangianWriter&) = delete;
//- Disallow default bitwise assignment
void operator=(const lagrangianWriter&) = delete;
public: public:
// Constructors // Constructors
@ -74,37 +106,56 @@ public:
//- Construct from components //- Construct from components
lagrangianWriter lagrangianWriter
( (
const fvMesh&, const fvMesh& mesh,
const bool binary, const word& cloudName,
const fileName&, const fileName& baseName,
const word&, const vtk::outputOptions outOpts,
const bool dummyCloud const bool dummyCloud = false
); );
//- Destructor
~lagrangianWriter();
// Member Functions // Member Functions
std::ofstream& os() inline std::ofstream& os()
{ {
return 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 //- Write IOField
template<class Type> template<class Type>
void writeIOField(const wordList&); void writeIOField(const wordList& objectNames);
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace vtk
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "lagrangianWriterTemplates.C" #include "foamVtkLagrangianWriterTemplates.C"
#endif #endif

View File

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

View File

@ -48,7 +48,7 @@ namespace Foam
template<class GeoField> template<class GeoField>
void readFields void readFields
( (
const meshSubsetHelper&, const meshSubsetHelper& helper,
const typename GeoField::Mesh& mesh, const typename GeoField::Mesh& mesh,
const IOobjectList& objects, const IOobjectList& objects,
const HashSet<word>& selectedFields, const HashSet<word>& selectedFields,

View File

@ -12,6 +12,7 @@ link_directories(
include_directories( include_directories(
$ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude $ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude
$ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/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 $ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude
${PROJECT_SOURCE_DIR}/../vtkPVFoam ${PROJECT_SOURCE_DIR}/../vtkPVFoam
${PROJECT_SOURCE_DIR}/../../foamPv/lnInclude ${PROJECT_SOURCE_DIR}/../../foamPv/lnInclude
@ -64,6 +65,7 @@ target_link_libraries(
LINK_PUBLIC LINK_PUBLIC
vtkPVFoam-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR} vtkPVFoam-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}
foamPv-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR} foamPv-pv${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}
conversion
finiteVolume finiteVolume
OpenFOAM OpenFOAM
) )

View File

@ -27,6 +27,8 @@
</Documentation> </Documentation>
</DoubleVectorProperty> </DoubleVectorProperty>
<!-- General Controls -->
<!-- Refresh (push button) --> <!-- Refresh (push button) -->
<Property <Property
name="Refresh" name="Refresh"
@ -35,12 +37,10 @@
<Documentation>Rescan for updated times/fields.</Documentation> <Documentation>Rescan for updated times/fields.</Documentation>
</Property> </Property>
<!-- General Controls -->
<!-- Skip Zero Time (check-box) --> <!-- Skip Zero Time (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="ZeroTime" name="ZeroTime"
label="Skip Zero Time" label="Skip 0/ time"
command="SetSkipZeroTime" command="SetSkipZeroTime"
default_values="1" default_values="1"
number_of_elements="1" number_of_elements="1"
@ -54,26 +54,28 @@
<!-- Include Sets (check-box) --> <!-- Include Sets (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="IncludeSets" name="IncludeSets"
label="With Sets"
command="SetIncludeSets" command="SetIncludeSets"
default_values="0" default_values="0"
number_of_elements="1" number_of_elements="1"
panel_visibility="default"> panel_visibility="default">
<BooleanDomain name="bool"/> <BooleanDomain name="bool"/>
<Documentation> <Documentation>
Search the polyMesh/sets/ directory Search the polyMesh/sets/ directory for {cell,face,point} sets
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
<!-- Include Zones (check-box) --> <!-- Include Zones (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="IncludeZones" name="IncludeZones"
label="With Zones"
command="SetIncludeZones" command="SetIncludeZones"
default_values="0" default_values="0"
number_of_elements="1" number_of_elements="1"
panel_visibility="default"> panel_visibility="default">
<BooleanDomain name="bool"/> <BooleanDomain name="bool"/>
<Documentation> <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. The polyMesh/ directory is only checked on startup.
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
@ -88,7 +90,7 @@
panel_visibility="default"> panel_visibility="default">
<BooleanDomain name="bool"/> <BooleanDomain name="bool"/>
<Documentation> <Documentation>
Show patchGroups only. Display patchGroups only instead of individual patches.
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
@ -109,6 +111,7 @@
<!-- Interpolate Fields (check-box) --> <!-- Interpolate Fields (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="InterpolateFields" name="InterpolateFields"
label="cell-to-point"
command="SetInterpolateVolFields" command="SetInterpolateVolFields"
default_values="1" default_values="1"
number_of_elements="1" number_of_elements="1"
@ -122,6 +125,7 @@
<!-- Extrapolate Patches (check-box) --> <!-- Extrapolate Patches (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="ExtrapolatePatches" name="ExtrapolatePatches"
label="field-to-patch"
command="SetExtrapolatePatches" command="SetExtrapolatePatches"
default_values="0" default_values="0"
number_of_elements="1" number_of_elements="1"
@ -132,7 +136,7 @@
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
<!-- Force GUI update (check-box) --> <!-- Force GUI update (push button) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="UpdateGUI" name="UpdateGUI"
command="SetUpdateGUI" command="SetUpdateGUI"
@ -148,7 +152,7 @@
<!-- Use VTK Polyhedron (check-box) --> <!-- Use VTK Polyhedron (check-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="UseVTKPolyhedron" name="UseVTKPolyhedron"
label="Use VTK Polyhedron" label="VTK Polyhedra"
command="SetUseVTKPolyhedron" command="SetUseVTKPolyhedron"
default_values="0" default_values="0"
number_of_elements="1" number_of_elements="1"
@ -159,16 +163,22 @@
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
<!-- Cache Mesh (check-box) --> <!-- Mesh Caching (combo-box) -->
<IntVectorProperty animateable="0" <IntVectorProperty animateable="0"
name="CacheMesh" name="MeshCaching"
command="SetCacheMesh" command="SetMeshCaching"
default_values="1" default_values="3"
number_of_elements="1" number_of_elements="1"
panel_visibility="default"> 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> <Documentation>
Cache the fvMesh in memory. Mesh caching styles.
Caching the OpenFOAM fvMesh reduces disk access.
Caching the VTK mesh reduces transcription overhead.
</Documentation> </Documentation>
</IntVectorProperty> </IntVectorProperty>
@ -185,7 +195,7 @@
<Property name="ShowPatchNames"/> <Property name="ShowPatchNames"/>
<Property name="UpdateGUI"/> <Property name="UpdateGUI"/>
<Property name="UseVTKPolyhedron"/> <Property name="UseVTKPolyhedron"/>
<Property name="CacheMesh"/> <Property name="MeshCaching"/>
</PropertyGroup> </PropertyGroup>
<!-- Parts Selections --> <!-- Parts Selections -->

View File

@ -26,6 +26,7 @@ License
#include "pqFoamReaderControls.h" #include "pqFoamReaderControls.h"
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox>
#include <QFrame> #include <QFrame>
#include <QGridLayout> #include <QGridLayout>
#include <QPushButton> #include <QPushButton>
@ -37,18 +38,31 @@ License
#include "vtkSMIntVectorProperty.h" #include "vtkSMIntVectorProperty.h"
#include "vtkSMPropertyGroup.h" #include "vtkSMPropertyGroup.h"
#include "vtkSMSourceProxy.h" #include "vtkSMSourceProxy.h"
#include "vtkSMEnumerationDomain.h"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// file-scope // 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 vtkSMProperty* prop
) )
{ {
QString tip; widget->setFocusPolicy(Qt::NoFocus); // avoid dotted border
vtkSMDocumentation* doc = prop->GetDocumentation(); vtkSMDocumentation* doc = prop->GetDocumentation();
if (doc) if (doc)
@ -56,21 +70,33 @@ static QAbstractButton* setButtonProperties
const char* txt = doc->GetDescription(); const char* txt = doc->GetDescription();
if (txt) 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()); b->setText(prop->GetXMLLabel());
if (tip.size())
{
b->setToolTip(tip);
}
b->setFocusPolicy(Qt::NoFocus); // avoid dotted border
vtkSMIntVectorProperty* intProp = vtkSMIntVectorProperty* intProp =
vtkSMIntVectorProperty::SafeDownCast(prop); vtkSMIntVectorProperty::SafeDownCast(prop);
// initial checked state for integer (bool) properties // Initial checked state for integer (bool) properties
if (intProp) if (intProp)
{ {
b->setChecked(intProp->GetElement(0)); 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 static vtkSMIntVectorProperty* lookupIntProp
( (
vtkSMPropertyGroup* group, vtkSMPropertyGroup* group,
@ -102,12 +188,12 @@ static vtkSMIntVectorProperty* lookupIntProp
void pqFoamReaderControls::fireCommand void pqFoamReaderControls::fireCommand
( (
vtkSMIntVectorProperty* prop, vtkSMIntVectorProperty* prop,
bool checked int val
) )
{ {
vtkSMProxy* pxy = this->proxy(); vtkSMProxy* pxy = this->proxy();
prop->SetElement(0, checked); // Toogle bool prop->SetElement(0, val); // Set int value, toogle bool, etc
// Fire off command // Fire off command
prop->Modified(); 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")), showGroupsOnly_(lookupIntProp(group, "ShowGroupsOnly")),
includeSets_(lookupIntProp(group, "IncludeSets")), includeSets_(lookupIntProp(group, "IncludeSets")),
includeZones_(lookupIntProp(group, "IncludeZones")), includeZones_(lookupIntProp(group, "IncludeZones")),
cacheMesh_(lookupIntProp(group, "CacheMesh")) meshCaching_(lookupIntProp(group, "MeshCaching"))
{ {
typedef vtkSMIntVectorProperty intProp; typedef vtkSMIntVectorProperty intProp;
QGridLayout* form = new QGridLayout(this); QGridLayout* form = new QGridLayout(this);
const int nCols = 3;
// ROW // ROW
// ~~~ // ~~~
int row = 0; int row = 0;
@ -222,17 +310,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, zeroTime); setButtonProperties(b, zeroTime);
form->addWidget(b, row, 1, Qt::AlignLeft); form->addWidget(b, row, 1, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(toggled(bool)), zeroTime); addPropertyLink
(
b, "checked", SIGNAL(toggled(bool)), zeroTime
);
} }
// LINE // LINE
// ~~~~ addHline(form, ++row, nCols);
++row;
{
QFrame* hline = new QFrame(this);
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
form->addWidget(hline, row, 0, 1, 4);
}
// ROW // ROW
// ~~~ // ~~~
@ -244,8 +329,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, includeSets_); setButtonProperties(b, includeSets_);
form->addWidget(b, row, 0, Qt::AlignLeft); form->addWidget(b, row, 0, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(toggled(bool)), includeSets_); addPropertyLink
connect(b, SIGNAL(toggled(bool)), this, SLOT(includeSets(bool))); (
b, "checked", SIGNAL(toggled(bool)), includeSets_
);
connect
(
b, SIGNAL(toggled(bool)), this, SLOT(includeSets(bool))
);
} }
if (showGroupsOnly_) if (showGroupsOnly_)
@ -254,8 +345,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, showGroupsOnly_); setButtonProperties(b, showGroupsOnly_);
form->addWidget(b, row, 1, Qt::AlignLeft); form->addWidget(b, row, 1, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(toggled(bool)), showGroupsOnly_); addPropertyLink
connect(b, SIGNAL(toggled(bool)), this, SLOT(showGroupsOnly(bool))); (
b, "checked", SIGNAL(toggled(bool)), showGroupsOnly_
);
connect
(
b, SIGNAL(toggled(bool)), this, SLOT(showGroupsOnly(bool))
);
} }
@ -269,8 +366,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, includeZones_); setButtonProperties(b, includeZones_);
form->addWidget(b, row, 0, Qt::AlignLeft); form->addWidget(b, row, 0, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(toggled(bool)), includeZones_); addPropertyLink
connect(b, SIGNAL(toggled(bool)), this, SLOT(includeZones(bool))); (
b, "checked", SIGNAL(toggled(bool)), includeZones_
);
connect
(
b, SIGNAL(toggled(bool)), this, SLOT(includeZones(bool))
);
} }
if (showPatchNames_) if (showPatchNames_)
@ -279,17 +382,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, showPatchNames_); setButtonProperties(b, showPatchNames_);
form->addWidget(b, row, 1, Qt::AlignLeft); 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 // LINE
// ~~~~ addHline(form, ++row, nCols);
++row;
{
QFrame* hline = new QFrame(this);
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
form->addWidget(hline, row, 0, 1, 4);
}
// ROW // ROW
// ~~~ // ~~~
@ -302,7 +402,10 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, interpolate); setButtonProperties(b, interpolate);
form->addWidget(b, row, 0, Qt::AlignLeft); 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"); intProp* extrapolate = lookupIntProp(group, "ExtrapolatePatches");
@ -312,17 +415,14 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, extrapolate); setButtonProperties(b, extrapolate);
form->addWidget(b, row, 1, Qt::AlignLeft); form->addWidget(b, row, 1, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(toggled(bool)), extrapolate); addPropertyLink
(
b, "checked", SIGNAL(toggled(bool)), extrapolate
);
} }
// LINE // LINE
// ~~~~ addHline(form, ++row, nCols);
++row;
{
QFrame* hline = new QFrame(this);
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
form->addWidget(hline, row, 0, 1, 4);
}
// ROW // ROW
// ~~~ // ~~~
@ -335,7 +435,10 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, updateGui); setButtonProperties(b, updateGui);
form->addWidget(b, row, 0, Qt::AlignLeft); form->addWidget(b, row, 0, Qt::AlignLeft);
addPropertyLink(b, "checked", SIGNAL(clicked()), updateGui); addPropertyLink
(
b, "checked", SIGNAL(clicked()), updateGui
);
} }
intProp* usePolyhedron = lookupIntProp(group, "UseVTKPolyhedron"); intProp* usePolyhedron = lookupIntProp(group, "UseVTKPolyhedron");
@ -345,16 +448,29 @@ pqFoamReaderControls::pqFoamReaderControls
setButtonProperties(b, usePolyhedron); setButtonProperties(b, usePolyhedron);
form->addWidget(b, row, 1, Qt::AlignLeft); 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); QComboBox* b = new QComboBox(this);
setButtonProperties(b, cacheMesh_);
form->addWidget(b, row, 2, Qt::AlignLeft); 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))
);
} }
} }

View File

@ -69,8 +69,8 @@ class pqFoamReaderControls
//- IncludeZones (bool property) //- IncludeZones (bool property)
vtkSMIntVectorProperty* includeZones_; vtkSMIntVectorProperty* includeZones_;
//- CacheMesh (bool property) //- MeshCaching (enum property)
vtkSMIntVectorProperty* cacheMesh_; vtkSMIntVectorProperty* meshCaching_;
// Private Member Functions // Private Member Functions
@ -78,8 +78,8 @@ class pqFoamReaderControls
//- Update property //- Update property
void fireCommand(vtkSMProperty* prop); void fireCommand(vtkSMProperty* prop);
//- Toggle and update bool property //- Update int property or toggle bool property
void fireCommand(vtkSMIntVectorProperty* prop, bool checked); void fireCommand(vtkSMIntVectorProperty* prop, int val);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
@ -102,7 +102,7 @@ protected slots:
// Protected Member Functions // Protected Member Functions
void refreshPressed(); void refreshPressed();
void cacheMesh(bool checked); void cacheMesh(int idx);
void showPatchNames(bool checked); void showPatchNames(bool checked);
void showGroupsOnly(bool checked); void showGroupsOnly(bool checked);
void includeSets(bool checked); void includeSets(bool checked);

View File

@ -39,6 +39,7 @@ License
#include "vtkSMRenderViewProxy.h" #include "vtkSMRenderViewProxy.h"
#include "vtkStreamingDemandDrivenPipeline.h" #include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStringArray.h" #include "vtkStringArray.h"
#include "vtkSmartPointer.h"
// OpenFOAM includes // OpenFOAM includes
#include "vtkPVFoam.H" #include "vtkPVFoam.H"
@ -46,7 +47,7 @@ License
// STL includes // STL includes
#include <vector> #include <vector>
#undef EXPERIMENTAL_TIME_CACHING #undef VTKPVFOAM_DUALPORT
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -61,27 +62,26 @@ vtkPVFoamReader::vtkPVFoamReader()
vtkDebugMacro(<<"Constructor"); vtkDebugMacro(<<"Constructor");
SetNumberOfInputPorts(0); SetNumberOfInputPorts(0);
FileName = nullptr; FileName = nullptr;
backend_ = nullptr; backend_ = nullptr;
output0_ = nullptr;
#ifdef VTKPVFOAM_DUALPORT #ifdef VTKPVFOAM_DUALPORT
// Add second output for the Lagrangian // Add second output for the Lagrangian
this->SetNumberOfOutputPorts(2); this->SetNumberOfOutputPorts(2);
vtkMultiBlockDataSet *lagrangian = vtkMultiBlockDataSet::New();
auto lagrangian = vtkSmartPointer<vtkMultiBlockDataSet>::New();
lagrangian->ReleaseData(); lagrangian->ReleaseData();
this->GetExecutive()->SetOutputData(1, lagrangian); this->GetExecutive()->SetOutputData(1, lagrangian);
lagrangian->Delete();
#endif #endif
TimeStepRange[0] = 0; TimeStepRange[0] = 0;
TimeStepRange[1] = 0; TimeStepRange[1] = 0;
CacheMesh = true; MeshCaching = 3; // fvMesh+vtk
SkipZeroTime = false; SkipZeroTime = true;
ExtrapolatePatches = false; ExtrapolatePatches = false;
UseVTKPolyhedron = false; UseVTKPolyhedron = false;
IncludeSets = false; IncludeSets = false;
@ -146,15 +146,9 @@ vtkPVFoamReader::~vtkPVFoamReader()
if (FileName) if (FileName)
{ {
delete [] FileName; delete[] FileName;
} }
if (output0_)
{
output0_->Delete();
}
PartSelection->RemoveAllObservers(); PartSelection->RemoveAllObservers();
VolFieldSelection->RemoveAllObservers(); VolFieldSelection->RemoveAllObservers();
PointFieldSelection->RemoveAllObservers(); PointFieldSelection->RemoveAllObservers();
@ -218,7 +212,7 @@ int vtkPVFoamReader::RequestInformation
{ {
vtkErrorMacro("could not find valid OpenFOAM mesh"); 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_; delete backend_;
backend_ = nullptr; backend_ = nullptr;
return 0; return 0;
@ -255,7 +249,7 @@ int vtkPVFoamReader::RequestInformation
<<"time-range " << times.front() << ':' << times.back() << "\n" <<"time-range " << times.front() << ':' << times.back() << "\n"
<<"times " << times.size() << "("; <<"times " << times.size() << "(";
for (const double& val : times) for (auto val : times)
{ {
cout<< ' ' << val; cout<< ' ' << val;
} }
@ -291,12 +285,12 @@ int vtkPVFoamReader::RequestData
if (!FileName) if (!FileName)
{ {
vtkErrorMacro("FileName has to be specified!"); vtkErrorMacro("FileName must be specified!");
return 0; return 0;
} }
if (!backend_) if (!backend_)
{ {
// catch some previous error // Catch some previous error
vtkErrorMacro("Reader failed - perhaps no mesh?"); vtkErrorMacro("Reader failed - perhaps no mesh?");
return 0; return 0;
} }
@ -326,7 +320,8 @@ int vtkPVFoamReader::RequestData
{ {
vtkInformation *outInfo = outputVector->GetInformationObject(infoI); vtkInformation *outInfo = outputVector->GetInformationObject(infoI);
int nsteps = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); const int nsteps =
outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
if 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 #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 #else
backend_->Update(output, output); backend_->Update(output, nullptr);
#endif #endif
updatePatchNamesView(ShowPatchNames); updatePatchNamesView(ShowPatchNames);
#endif backend_->UpdateFinalize();
// Do any cleanup on the OpenFOAM side
backend_->CleanUp();
return 1; return 1;
} }
@ -525,13 +467,11 @@ void vtkPVFoamReader::updatePatchNamesView(const bool show)
} }
// Get all the pqRenderView instances // Get all the pqRenderView instances
QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); for (auto view : smModel->findItems<pqRenderView*>())
for (int viewI=0; viewI < renderViews.size(); ++viewI)
{ {
backend_->renderPatchNames backend_->renderPatchNames
( (
renderViews[viewI]->getRenderViewProxy()->GetRenderer(), view->getRenderViewProxy()->GetRenderer(),
show show
); );
} }

View File

@ -46,6 +46,7 @@ SourceFiles
// VTK forward declarations // VTK forward declarations
class vtkDataArraySelection; class vtkDataArraySelection;
class vtkCallbackCommand; class vtkCallbackCommand;
template<class T> class vtkSmartPointer;
// OpenFOAM forward declarations // OpenFOAM forward declarations
namespace Foam namespace Foam
@ -82,9 +83,9 @@ public:
virtual void PrintInfo(); virtual void PrintInfo();
// Description: // Description:
// OpenFOAM mesh caching control // Mesh caching control (0:none,1:fvMesh,3:fvMesh+vtk)
vtkSetMacro(CacheMesh, bool); vtkSetMacro(MeshCaching, int);
vtkGetMacro(CacheMesh, bool); vtkGetMacro(MeshCaching, int);
// Description: // Description:
// OpenFOAM refresh times/fields // OpenFOAM refresh times/fields
@ -231,7 +232,7 @@ private:
void updatePatchNamesView(const bool show); void updatePatchNamesView(const bool show);
int TimeStepRange[2]; int TimeStepRange[2];
bool CacheMesh; int MeshCaching;
bool SkipZeroTime; bool SkipZeroTime;
bool ExtrapolatePatches; bool ExtrapolatePatches;
@ -250,9 +251,6 @@ private:
vtkDataArraySelection* PointFieldSelection; vtkDataArraySelection* PointFieldSelection;
vtkDataArraySelection* LagrangianFieldSelection; vtkDataArraySelection* LagrangianFieldSelection;
//- Cached data for output port0 (experimental!)
vtkMultiBlockDataSet* output0_;
//- Backend portion of the reader //- Backend portion of the reader
Foam::vtkPVFoam* backend_; Foam::vtkPVFoam* backend_;
}; };

View File

@ -37,24 +37,50 @@ License
#include "vtkRenderer.h" #include "vtkRenderer.h"
#include "vtkTextActor.h" #include "vtkTextActor.h"
#include "vtkTextProperty.h" #include "vtkTextProperty.h"
#include "vtkSmartPointer.h"
#include "vtkInformation.h"
// Templates (only needed here)
#include "vtkPVFoamUpdateTemplates.C"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(vtkPVFoam, 0); 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 * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
vtkTextActor* Foam::vtkPVFoam::createTextActor namespace Foam
(
const string& s,
const point& pt
)
{ {
vtkTextActor* txt = vtkTextActor::New(); // 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()); txt->SetInput(s.c_str());
// Set text properties // Set text properties
@ -71,6 +97,7 @@ vtkTextActor* Foam::vtkPVFoam::createTextActor
txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z());
return txt; return txt;
}
} }
@ -79,40 +106,79 @@ vtkTextActor* Foam::vtkPVFoam::createTextActor
void Foam::vtkPVFoam::resetCounters() void Foam::vtkPVFoam::resetCounters()
{ {
// Reset array range information (ids and sizes) // Reset array range information (ids and sizes)
arrayRangeVolume_.reset(); rangeVolume_.reset();
arrayRangePatches_.reset(); rangePatches_.reset();
arrayRangeLagrangian_.reset(); rangeLagrangian_.reset();
arrayRangeCellZones_.reset(); rangeCellZones_.reset();
arrayRangeFaceZones_.reset(); rangeFaceZones_.reset();
arrayRangePointZones_.reset(); rangePointZones_.reset();
arrayRangeCellSets_.reset(); rangeCellSets_.reset();
arrayRangeFaceSets_.reset(); rangeFaceSets_.reset();
arrayRangePointSets_.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) const auto blockNo = output->GetNumberOfBlocks();
vtkSmartPointer<vtkMultiBlockDataSet> block;
int datasetNo = 0;
for (auto partId : selector)
{ {
regionPolyDecomp_[i].clear(); if (selectedPartIds_.found(partId))
{
const auto& longName = selectedPartIds_[partId];
const word shortName = getFoamName(longName);
auto iter = cache.find(longName);
if (iter.found() && iter.object().dataset)
{
auto dataset = iter.object().dataset;
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()
);
} }
forAll(zonePolyDecomp_, i) block->SetBlock(datasetNo, dataset);
{ block->GetMetaData(datasetNo)->Set
zonePolyDecomp_[i].clear(); (
vtkCompositeDataSet::NAME(),
shortName.c_str()
);
++datasetNo;
}
}
} }
forAll(csetPolyDecomp_, i) return datasetNo;
{
csetPolyDecomp_[i].clear();
}
if (!reader_->GetCacheMesh())
{
delete meshPtr_;
meshPtr_ = nullptr;
}
} }
@ -151,27 +217,14 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
<< ", nearestIndex = " << nearestIndex << endl; << ", nearestIndex = " << nearestIndex << endl;
} }
// See what has changed
// see what has changed
if (timeIndex_ != nearestIndex) if (timeIndex_ != nearestIndex)
{ {
timeIndex_ = nearestIndex; timeIndex_ = nearestIndex;
runTime.setTime(Times[nearestIndex], nearestIndex); runTime.setTime(Times[nearestIndex], nearestIndex);
// the fields change each time // When the changes, so do the fields
fieldsChanged_ = true; meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE;
if (meshPtr_)
{
if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
{
meshChanged_ = true;
}
}
else
{
meshChanged_ = true;
}
reader_->UpdateProgress(0.05); reader_->UpdateProgress(0.05);
@ -184,63 +237,16 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
Info<< "<end> setTime() - selectedTime=" Info<< "<end> setTime() - selectedTime="
<< Times[nearestIndex].name() << " index=" << timeIndex_ << Times[nearestIndex].name() << " index=" << timeIndex_
<< "/" << Times.size() << "/" << Times.size()
<< " meshChanged=" << Switch(meshChanged_) << " meshUpdateState=" << updateStateName(meshState_) << endl;
<< " fieldsChanged=" << Switch(fieldsChanged_) << endl;
} }
return nearestIndex; return nearestIndex;
} }
void Foam::vtkPVFoam::updateMeshPartsStatus() Foam::word Foam::vtkPVFoam::getReaderPartName(const int partId) const
{ {
if (debug) return getFoamName(reader_->GetPartArrayName(partId));
{
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));
} }
@ -258,17 +264,17 @@ Foam::vtkPVFoam::vtkPVFoam
meshRegion_(polyMesh::defaultRegion), meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir), meshDir_(polyMesh::meshSubDir),
timeIndex_(-1), timeIndex_(-1),
meshChanged_(true), decomposePoly_(false),
fieldsChanged_(true), meshState_(polyMesh::TOPO_CHANGE),
arrayRangeVolume_("unzoned"), rangeVolume_("unzoned"),
arrayRangePatches_("patches"), rangePatches_("patch"),
arrayRangeLagrangian_("lagrangian"), rangeLagrangian_("lagrangian"),
arrayRangeCellZones_("cellZone"), rangeCellZones_("cellZone"),
arrayRangeFaceZones_("faceZone"), rangeFaceZones_("faceZone"),
arrayRangePointZones_("pointZone"), rangePointZones_("pointZone"),
arrayRangeCellSets_("cellSet"), rangeCellSets_("cellSet"),
arrayRangeFaceSets_("faceSet"), rangeFaceSets_("faceSet"),
arrayRangePointSets_("pointSet") rangePointSets_("pointSet")
{ {
if (debug) if (debug)
{ {
@ -393,16 +399,16 @@ void Foam::vtkPVFoam::updateInfo()
// time of the vtkDataArraySelection, but the qt/paraview proxy // time of the vtkDataArraySelection, but the qt/paraview proxy
// layer doesn't care about that anyhow. // layer doesn't care about that anyhow.
stringList enabledEntries; HashSet<string> enabled;
if (!partSelection->GetNumberOfArrays() && !meshPtr_) if (!partSelection->GetNumberOfArrays() && !meshPtr_)
{ {
// enable 'internalMesh' on the first call // Fake enable 'internalMesh' on the first call
enabledEntries = { "internalMesh" }; enabled = { "internalMesh" };
} }
else else
{ {
// preserve the enabled selections // preserve the enabled selections
enabledEntries = getSelectedArrayEntries(partSelection); enabled = getSelectedArraySet(partSelection);
} }
// Clear current mesh parts list // Clear current mesh parts list
@ -410,21 +416,27 @@ void Foam::vtkPVFoam::updateInfo()
// Update mesh parts list - add Lagrangian at the bottom // Update mesh parts list - add Lagrangian at the bottom
updateInfoInternalMesh(partSelection); updateInfoInternalMesh(partSelection);
updateInfoPatches(partSelection, enabledEntries); updateInfoPatches(partSelection, enabled);
updateInfoSets(partSelection); updateInfoSets(partSelection);
updateInfoZones(partSelection); updateInfoZones(partSelection);
updateInfoLagrangian(partSelection); updateInfoLagrangian(partSelection);
// restore the enabled selections // Adjust/restore the enabled selections
setSelectedArrayEntries(partSelection, enabledEntries); setSelectedArrayEntries(partSelection, enabled);
if (meshChanged_)
{
fieldsChanged_ = true;
}
// Update volume, point and lagrangian fields // Update volume, point and lagrangian fields
updateInfoFields(); updateInfoFields<fvPatchField, volMesh>
(
reader_->GetVolFieldSelection()
);
updateInfoFields<pointPatchField, pointMesh>
(
reader_->GetPointFieldSelection()
);
updateInfoLagrangianFields
(
reader_->GetLagrangianFieldSelection()
);
if (debug) if (debug)
{ {
@ -433,15 +445,97 @@ void Foam::vtkPVFoam::updateInfo()
} }
void Foam::vtkPVFoam::updateFoamMesh() void Foam::vtkPVFoam::Update
(
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* outputLagrangian
)
{ {
if (debug)
{
cout<< "<beg> Foam::vtkPVFoam::Update\n";
output->Print(cout);
if (outputLagrangian) outputLagrangian->Print(cout);
printMemory();
}
reader_->UpdateProgress(0.1);
const int caching = reader_->GetMeshCaching();
const bool oldDecomp = decomposePoly_;
decomposePoly_ = !reader_->GetUseVTKPolyhedron();
// Set up mesh parts selection(s)
// Update cached, saved, unneed values.
{
vtkDataArraySelection* selection = reader_->GetPartSelection();
const int n = selection->GetNumberOfArrays();
selectedPartIds_.clear();
HashSet<string> nowActive;
for (int id=0; id < n; ++id)
{
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;
}
}
// Dispose of unneeded components
cachedVtp_.retain(nowActive);
cachedVtu_.retain(nowActive);
if
(
!caching
|| meshState_ == polyMesh::TOPO_CHANGE
|| meshState_ == polyMesh::TOPO_PATCH_CHANGE
)
{
// 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();
}
}
}
reader_->UpdateProgress(0.15);
// Update the OpenFOAM mesh
{
if (debug) if (debug)
{ {
Info<< "<beg> updateFoamMesh" << endl; Info<< "<beg> updateFoamMesh" << endl;
printMemory(); printMemory();
} }
if (!reader_->GetCacheMesh()) if (!caching)
{ {
delete meshPtr_; delete meshPtr_;
meshPtr_ = nullptr; meshPtr_ = nullptr;
@ -453,9 +547,7 @@ void Foam::vtkPVFoam::updateFoamMesh()
if (debug) if (debug)
{ {
Info<< "Creating OpenFOAM mesh for region " << meshRegion_ Info<< "Creating OpenFOAM mesh for region " << meshRegion_
<< " at time=" << dbPtr_().timeName() << " at time=" << dbPtr_().timeName() << endl;
<< endl;
} }
meshPtr_ = new fvMesh meshPtr_ = new fvMesh
@ -469,7 +561,7 @@ void Foam::vtkPVFoam::updateFoamMesh()
) )
); );
meshChanged_ = true; meshState_ = polyMesh::TOPO_CHANGE; // New mesh
} }
else else
{ {
@ -484,84 +576,89 @@ void Foam::vtkPVFoam::updateFoamMesh()
Info<< "<end> updateFoamMesh" << endl; Info<< "<end> updateFoamMesh" << endl;
printMemory(); printMemory();
} }
}
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);
// Set up mesh parts selection(s)
updateMeshPartsStatus();
reader_->UpdateProgress(0.15);
// Update the OpenFOAM mesh
updateFoamMesh();
reader_->UpdateProgress(0.4); reader_->UpdateProgress(0.4);
// Convert meshes - start port0 at block=0 convertMeshVolume();
int blockNo = 0; convertMeshPatches();
convertMeshVolume(output, blockNo);
convertMeshPatches(output, blockNo);
reader_->UpdateProgress(0.6); reader_->UpdateProgress(0.6);
if (reader_->GetIncludeZones()) if (reader_->GetIncludeZones())
{ {
convertMeshCellZones(output, blockNo); convertMeshCellZones();
convertMeshFaceZones(output, blockNo); convertMeshFaceZones();
convertMeshPointZones(output, blockNo); convertMeshPointZones();
reader_->UpdateProgress(0.65); reader_->UpdateProgress(0.65);
} }
if (reader_->GetIncludeSets()) if (reader_->GetIncludeSets())
{ {
convertMeshCellSets(output, blockNo); convertMeshCellSets();
convertMeshFaceSets(output, blockNo); convertMeshFaceSets();
convertMeshPointSets(output, blockNo); convertMeshPointSets();
reader_->UpdateProgress(0.7); reader_->UpdateProgress(0.7);
} }
#ifdef VTKPVFOAM_DUALPORT convertMeshLagrangian();
// restart port1 at block=0
blockNo = 0;
#endif
convertMeshLagrangian(lagrangianOutput, blockNo);
reader_->UpdateProgress(0.8); reader_->UpdateProgress(0.8);
// Update fields // Update fields
convertVolFields(output); convertVolFields();
convertPointFields(output); convertPointFields();
convertLagrangianFields(lagrangianOutput); 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) if (debug)
{ {
Info<< "done reader part" << nl << endl; Info<< "done reader part" << nl << endl;
} }
reader_->UpdateProgress(0.95); 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 if (!reader_->GetMeshCaching())
reduceMemory(); {
delete meshPtr_;
meshPtr_ = nullptr;
}
reader_->UpdateProgress(1.0); reader_->UpdateProgress(1.0);
} }
@ -640,20 +737,19 @@ void Foam::vtkPVFoam::renderPatchNames
{ {
// always remove old actors first // always remove old actors first
forAll(patchTextActorsPtrs_, patchi) forAll(patchTextActors_, patchi)
{ {
renderer->RemoveViewProp(patchTextActorsPtrs_[patchi]); renderer->RemoveViewProp(patchTextActors_[patchi]);
patchTextActorsPtrs_[patchi]->Delete();
} }
patchTextActorsPtrs_.clear(); patchTextActors_.clear();
if (show && meshPtr_) if (show && meshPtr_)
{ {
// get the display patches, strip off any suffix // get the display patches, strip off any prefix/suffix
hashedWordList selectedPatches = getSelected hashedWordList selectedPatches = getSelected
( (
reader_->GetPartSelection(), reader_->GetPartSelection(),
arrayRangePatches_ rangePatches_
); );
if (selectedPatches.empty()) if (selectedPatches.empty())
@ -750,7 +846,7 @@ void Foam::vtkPVFoam::renderPatchNames
} }
// Set the size of the patch labels to max number of zones // Set the size of the patch labels to max number of zones
patchTextActorsPtrs_.setSize(displayZoneI); patchTextActors_.setSize(displayZoneI);
if (debug) if (debug)
{ {
@ -783,7 +879,7 @@ void Foam::vtkPVFoam::renderPatchNames
} }
// Into a list for later removal // Into a list for later removal
patchTextActorsPtrs_[displayZoneI++] = createTextActor patchTextActors_[displayZoneI++] = createTextActor
( (
pp.name(), pp.name(),
zoneCentre[patchi][globalZoneI] zoneCentre[patchi][globalZoneI]
@ -792,13 +888,13 @@ void Foam::vtkPVFoam::renderPatchNames
} }
// Resize the patch names list to the actual number of patch names added // Resize the patch names list to the actual number of patch names added
patchTextActorsPtrs_.setSize(displayZoneI); patchTextActors_.setSize(displayZoneI);
} }
// Add text to each renderer // Add text to each renderer
forAll(patchTextActorsPtrs_, actori) forAll(patchTextActors_, actori)
{ {
renderer->AddViewProp(patchTextActorsPtrs_[actori]); renderer->AddViewProp(patchTextActors_[actori]);
} }
} }

View File

@ -25,7 +25,25 @@ Class
Foam::vtkPVFoam Foam::vtkPVFoam
Description 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 SourceFiles
vtkPVFoam.C vtkPVFoam.C
@ -35,7 +53,6 @@ SourceFiles
vtkPVFoamMeshVolume.C vtkPVFoamMeshVolume.C
vtkPVFoamTemplates.C vtkPVFoamTemplates.C
vtkPVFoamUpdateInfo.C vtkPVFoamUpdateInfo.C
vtkPVFoamUtils.C
vtkPVFoamFieldTemplates.C vtkPVFoamFieldTemplates.C
vtkPVFoamUpdateTemplates.C vtkPVFoamUpdateTemplates.C
@ -55,22 +72,24 @@ SourceFiles
#include "PrimitivePatchInterpolation.H" #include "PrimitivePatchInterpolation.H"
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
#include "foamPvCore.H" #include "foamPvCore.H"
#include "foamVtkMeshMaps.H"
#undef VTKPVFOAM_DUALPORT #include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkUnstructuredGrid.h"
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // // * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * //
class vtkCellArray;
class vtkDataArraySelection; class vtkDataArraySelection;
class vtkDataSet; class vtkDataSet;
class vtkFloatArray; class vtkFloatArray;
class vtkPoints; class vtkIndent;
class vtkMultiBlockDataSet;
class vtkPVFoamReader; class vtkPVFoamReader;
class vtkRenderer; class vtkRenderer;
class vtkTextActor; class vtkTextActor;
class vtkMultiBlockDataSet;
class vtkPolyData;
class vtkUnstructuredGrid;
class vtkIndent;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -83,6 +102,7 @@ class Time;
class fvMesh; class fvMesh;
class IOobjectList; class IOobjectList;
class polyPatch; class polyPatch;
class fvMeshSubset;
template<class Type> class IOField; template<class Type> class IOField;
template<class Type> class Field; template<class Type> class Field;
@ -102,66 +122,101 @@ class vtkPVFoam
// Private classes // Private classes
//- Bookkeeping for polyhedral cell decomposition //- Bookkeeping for internal caching.
// hide in extra pointMap (cellSet/cellZone) for now // Retain an original copy of the geometry as well as a shallow copy
class polyDecomp // with the output fields.
// The original copy is reused for different timestep
template<class DataType>
class foamVtkCaching
{ {
labelList superCells_;
labelList addPointCellLabels_;
labelList pointMap_;
public: public:
typedef DataType dataType;
polyDecomp() //- The geometry, without any cell/point data
{} vtkSmartPointer<dataType> vtkgeom;
//- Label of original cell for decomposed cells //- The shallow-copy of geometry, plus additional data
labelList& superCells() vtkSmartPointer<dataType> dataset;
//- Number of points associated with geometry
inline uint64_t nPoints() const
{ {
return superCells_; return vtkgeom ? vtkgeom->GetNumberOfPoints() : 0;
} }
//- Label of original cell for decomposed cells //- Clear geometry and dataset
const labelList& superCells() const void clearGeom()
{ {
return superCells_; vtkgeom = nullptr;
dataset = nullptr;
} }
//- Cell-centre labels for additional points of decomposed cells //- Return a shallow copy of vtkgeom for manipulation
labelList& addPointCellLabels() vtkSmartPointer<dataType> getCopy() const
{ {
return addPointCellLabels_; auto copy = vtkSmartPointer<dataType>::New();
copy->ShallowCopy(vtkgeom);
return copy;
} }
//- Cell-centre labels for additional points of decomposed cells //- Make a shallow copy of vtkgeom into dataset
const labelList& addPointCellLabels() const void reuse()
{ {
return addPointCellLabels_; dataset = vtkSmartPointer<dataType>::New();
dataset->ShallowCopy(vtkgeom);
} }
//- Point labels for subsetted meshes //- Set the geometry and make a shallow copy to dataset
labelList& pointMap() void set(vtkSmartPointer<dataType> geom)
{ {
return pointMap_; vtkgeom = geom;
reuse();
} }
//- Point labels for subsetted meshes //- Report basic information to output
const labelList& pointMap() const void PrintSelf(std::ostream& os) const
{ {
return pointMap_; os << "geom" << nl;
if (vtkgeom)
{
vtkgeom->PrintSelf(std::cout, vtkIndent(2));
} }
else
//- Clear
void clear()
{ {
superCells_.clear(); os << "nullptr";
addPointCellLabels_.clear(); }
pointMap_.clear(); 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 // Private Data
//- Access to the controlling vtkPVFoamReader //- Access to the controlling vtkPVFoamReader
@ -182,72 +237,74 @@ class vtkPVFoam
//- The time index //- The time index
int timeIndex_; int timeIndex_;
//- Previous/current decomposition request
bool decomposePoly_;
//- Track changes in mesh geometry //- Track changes in mesh geometry
bool meshChanged_; enum polyMesh::readUpdateState meshState_;
//- Track changes in fields //- The index of selected parts mapped to their names
bool fieldsChanged_; Map<string> selectedPartIds_;
//- Selected geometrical parts (internalMesh, patches, ...) //- Any information for 2D (VTP) geometries
boolList partStatus_; HashTable<foamVtpData, string> cachedVtp_;
//- Datasets corresponding to selected geometrical pieces //- Cell maps and other information for 3D (VTU) geometries
// a negative number indicates that no vtkmesh exists for this piece HashTable<foamVtuData, string> cachedVtu_;
labelList partDataset_;
//- First instance and size of various mesh parts //- First instance and size of various mesh parts
// used to index into partStatus_ and partDataset_ // used to index into selectedPartIds and thus indirectly into
arrayRange arrayRangeVolume_; // cachedVtp, cachedVtu
arrayRange arrayRangePatches_; arrayRange rangeVolume_;
arrayRange arrayRangeLagrangian_; arrayRange rangePatches_;
arrayRange arrayRangeCellZones_; arrayRange rangeLagrangian_;
arrayRange arrayRangeFaceZones_; arrayRange rangeCellZones_;
arrayRange arrayRangePointZones_; arrayRange rangeFaceZones_;
arrayRange arrayRangeCellSets_; arrayRange rangePointZones_;
arrayRange arrayRangeFaceSets_; arrayRange rangeCellSets_;
arrayRange arrayRangePointSets_; arrayRange rangeFaceSets_;
arrayRange rangePointSets_;
//- 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_;
//- List of patch names for rendering to window //- List of patch names for rendering to window
List<vtkTextActor*> patchTextActorsPtrs_; List<vtkSmartPointer<vtkTextActor>> patchTextActors_;
// Private Member Functions // Private Member Functions
//- Create a text actor template<class Container>
static vtkTextActor* createTextActor(const string& s, const point& pt); bool addOutputBlock
(
vtkMultiBlockDataSet* output,
const HashTable<Container, string>& cache,
const arrayRange& selector,
const bool singleDataset = false
) const;
//- Reset data counters //- Reset data counters
void resetCounters(); void resetCounters();
// Update information helper functions // Update information helper functions
//- Update the mesh parts selected in the GUI
void updateMeshPartsStatus();
//- Internal mesh info //- Internal mesh info
void updateInfoInternalMesh(vtkDataArraySelection*); void updateInfoInternalMesh(vtkDataArraySelection* select);
//- Lagrangian info //- Lagrangian info
void updateInfoLagrangian(vtkDataArraySelection*); void updateInfoLagrangian(vtkDataArraySelection* select);
//- Patch info //- Patch info, modifies enabledEntries
void updateInfoPatches(vtkDataArraySelection*, stringList&); void updateInfoPatches
(
vtkDataArraySelection* select,
HashSet<string>& enabledEntries
);
//- Set info //- Set info
void updateInfoSets(vtkDataArraySelection*); void updateInfoSets(vtkDataArraySelection* select);
//- Zone info //- Zone info
void updateInfoZones(vtkDataArraySelection*); void updateInfoZones(vtkDataArraySelection* select);
//- Get non-empty zone names for zoneType from file //- Get non-empty zone names for zoneType from file
wordList getZoneNames(const word& zoneType) const; wordList getZoneNames(const word& zoneType) const;
@ -259,9 +316,6 @@ class vtkPVFoam
const ZoneMesh<ZoneType, polyMesh>& zmesh const ZoneMesh<ZoneType, polyMesh>& zmesh
); );
//- Field (volume, point, lagrangian) info
void updateInfoFields();
//- Field info //- Field info
template<template<class> class patchType, class meshType> template<template<class> class patchType, class meshType>
void updateInfoFields void updateInfoFields
@ -273,105 +327,171 @@ class vtkPVFoam
void updateInfoLagrangianFields(vtkDataArraySelection* select); void updateInfoLagrangianFields(vtkDataArraySelection* select);
// Update helper functions
//- OpenFOAM mesh
void updateFoamMesh();
//- Reduce memory footprint after conversion
void reduceMemory();
// Mesh conversion functions // Mesh conversion functions
//- Convert volume mesh //- Convert InternalMesh
void convertMeshVolume(vtkMultiBlockDataSet* output, int& blockNo); void convertMeshVolume();
//- Convert Lagrangian points //- Convert Lagrangian points
void convertMeshLagrangian(vtkMultiBlockDataSet* output, int& blockNo); void convertMeshLagrangian();
//- Convert mesh patches //- Convert mesh patches.
void convertMeshPatches(vtkMultiBlockDataSet* output, int& blockNo); // 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 //- Convert cell zones
void convertMeshCellZones(vtkMultiBlockDataSet* output, int& blockNo); void convertMeshCellZones();
//- Convert face zones
void convertMeshFaceZones(vtkMultiBlockDataSet* output, int& blockNo);
//- Convert point zones
void convertMeshPointZones(vtkMultiBlockDataSet* output, int& blockNo);
//- Convert cell sets //- Convert cell sets
void convertMeshCellSets(vtkMultiBlockDataSet* output, int& blockNo); void convertMeshCellSets();
//- Convert face zones
void convertMeshFaceZones();
//- Convert face sets //- 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 //- Convert point sets
void convertMeshPointSets(vtkMultiBlockDataSet* output, int& blockNo); // The pointMap (cached data) contains the point-labels.
void convertMeshPointSets();
// Add mesh functions // Add mesh functions
//- Volume meshes as vtkUnstructuredGrid //- Generate vtk points for the current mesh points/decomposition
vtkUnstructuredGrid* volumeVTKMesh static vtkSmartPointer<vtkPoints> movePoints
( (
const fvMesh& mesh, const fvMesh& mesh,
polyDecomp& decompInfo 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,
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 //- Lagrangian positions as vtkPolyData
vtkPolyData* lagrangianVTKMesh vtkSmartPointer<vtkPolyData> lagrangianVTKMesh
( (
const polyMesh& mesh, const polyMesh& mesh,
const word& cloudName 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 //- Patches (mesh or primitive) as vtkPolyData
template<class PatchType> template<class PatchType>
vtkPolyData* patchVTKMesh static vtkSmartPointer<vtkPolyData> patchVTKMesh
( (
const word& name,
const PatchType& p const PatchType& p
); );
// Field conversion functions // Field conversion functions
//- Convert Field to VTK field //- Copy list to pre-allocated vtk array.
// \return number of input items copied
template<class Type> template<class Type>
vtkFloatArray* convertFieldToVTK static label transcribeFloatData
(
vtkFloatArray* array,
const UList<Type>& input,
const label start = 0
);
//- Create named field initialized to zero
template<class Type>
static vtkSmartPointer<vtkFloatArray> zeroVTKField
( (
const word& name, 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 //- Face set/zone field
template<class Type> template<class Type>
vtkFloatArray* convertFaceFieldToVTK vtkSmartPointer<vtkFloatArray> convertFaceFieldToVTK
( (
const GeometricField<Type, fvPatchField, volMesh>& fld, const GeometricField<Type, fvPatchField, volMesh>& fld,
const labelUList& faceLabels const labelUList& faceLabels
); ) const;
//- Volume field //- Volume field
template<class Type> template<class Type>
vtkFloatArray* convertVolFieldToVTK vtkSmartPointer<vtkFloatArray> convertVolFieldToVTK
( (
const GeometricField<Type, fvPatchField, volMesh>& fld, const GeometricField<Type, fvPatchField, volMesh>& fld,
const polyDecomp& decompInfo const foamVtuData& vtuData
); ) const;
//- Convert volume fields //- Convert volume fields
void convertVolFields(vtkMultiBlockDataSet* output); void convertVolFields();
//- Convert point fields //- Convert point fields
void convertPointFields(vtkMultiBlockDataSet* output); void convertPointFields();
//- Convert Lagrangian fields //- Convert Lagrangian fields
void convertLagrangianFields(vtkMultiBlockDataSet* output); void convertLagrangianFields();
// Convert OpenFOAM fields // Convert OpenFOAM fields
@ -381,8 +501,7 @@ class vtkPVFoam
void convertVolField void convertVolField
( (
const PtrList<patchInterpolator>& patchInterpList, const PtrList<patchInterpolator>& patchInterpList,
const GeometricField<Type, fvPatchField, volMesh>& fld, const GeometricField<Type, fvPatchField, volMesh>& fld
vtkMultiBlockDataSet* output
); );
//- Volume fields - all types //- Volume fields - all types
@ -391,8 +510,7 @@ class vtkPVFoam
( (
const fvMesh& mesh, const fvMesh& mesh,
const PtrList<patchInterpolator>& patchInterpList, const PtrList<patchInterpolator>& patchInterpList,
const IOobjectList& objects, const IOobjectList& objects
vtkMultiBlockDataSet* output
); );
//- Volume internal fields (DimensionedField)- all types //- Volume internal fields (DimensionedField)- all types
@ -401,8 +519,7 @@ class vtkPVFoam
( (
const fvMesh& mesh, const fvMesh& mesh,
const PtrList<patchInterpolator>& patchInterpList, const PtrList<patchInterpolator>& patchInterpList,
const IOobjectList& objects, const IOobjectList& objects
vtkMultiBlockDataSet* output
); );
//- Volume field - all selected parts //- Volume field - all selected parts
@ -411,9 +528,7 @@ class vtkPVFoam
( (
const GeometricField<Type, fvPatchField, volMesh>& fld, const GeometricField<Type, fvPatchField, volMesh>& fld,
autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr, autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr,
vtkMultiBlockDataSet* output, const arrayRange& range
const arrayRange& range,
const List<polyDecomp>& decompLst
); );
//- Lagrangian fields - all types //- Lagrangian fields - all types
@ -421,8 +536,7 @@ class vtkPVFoam
void convertLagrangianFields void convertLagrangianFields
( (
const IOobjectList& objects, const IOobjectList& objects,
vtkMultiBlockDataSet* output, vtkPolyData* vtkmesh
const label datasetNo
); );
//- Point fields - all types //- Point fields - all types
@ -430,8 +544,7 @@ class vtkPVFoam
void convertPointFields void convertPointFields
( (
const pointMesh& pMesh, const pointMesh& pMesh,
const IOobjectList& objects, const IOobjectList& objectst
vtkMultiBlockDataSet* output
); );
//- Point field - all selected parts //- Point field - all selected parts
@ -439,33 +552,23 @@ class vtkPVFoam
void convertPointFieldBlock void convertPointFieldBlock
( (
const GeometricField<Type, pointPatchField, pointMesh>& pfld, const GeometricField<Type, pointPatchField, pointMesh>& pfld,
vtkMultiBlockDataSet* output, const arrayRange& range
const arrayRange& range,
const List<polyDecomp>& decompLst
); );
//- Point field //- Point field
template<class Type> template<class Type>
void convertPointField vtkSmartPointer<vtkFloatArray> convertPointField
( (
vtkUnstructuredGrid* vtkmesh,
const GeometricField<Type, pointPatchField, pointMesh>& pfld, const GeometricField<Type, pointPatchField, pointMesh>& pfld,
const GeometricField<Type, fvPatchField, volMesh>& vfld, const GeometricField<Type, fvPatchField, volMesh>& vfld,
const polyDecomp& decomp const foamVtuData& vtuData
); );
// GUI selection helper functions // 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 //- Get the first word from the reader 'parts' selection
word getPartName(const int partId); word getReaderPartName(const int partId) const;
// Constructors // Constructors
@ -506,19 +609,19 @@ public:
void Update void Update
( (
vtkMultiBlockDataSet* output, vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* lagrangianOutput vtkMultiBlockDataSet* outputLagrangian
); );
//- Clean any storage //- Final part of Update(), after any last minute rendering.
void CleanUp(); void UpdateFinalize();
//- Add/remove patch names to/from the view
void renderPatchNames(vtkRenderer* renderer, const bool show);
//- Return a list of selected times. //- Return a list of selected times.
// Use STL container since these values are used by the plugin // Use STL container since these values are used by the plugin
std::vector<double> findTimes(const bool skipZero = false) const; 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, //- Set the runTime to the first plausible request time,
// returns the timeIndex // returns the timeIndex
// sets to "constant" on error // sets to "constant" on error

View File

@ -40,32 +40,7 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtkPVFoam::pruneObjectList void Foam::vtkPVFoam::convertVolFields()
(
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
)
{ {
const fvMesh& mesh = *meshPtr_; const fvMesh& mesh = *meshPtr_;
@ -83,7 +58,7 @@ void Foam::vtkPVFoam::convertVolFields
// Get objects (fields) for this time - only keep selected fields // Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db // the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName()); IOobjectList objects(mesh, dbPtr_().timeName());
pruneObjectList(objects, selectedFields); objects.filterKeys(selectedFields);
if (objects.empty()) if (objects.empty())
{ {
@ -92,8 +67,8 @@ void Foam::vtkPVFoam::convertVolFields
if (debug) if (debug)
{ {
Info<< "<beg> convert volume fields" << endl; Info<< "<beg> " << FUNCTION_NAME << endl;
forAllConstIter(IOobjectList, objects, iter) forAllConstIters(objects, iter)
{ {
Info<< " " << iter()->name() Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl; << " == " << iter()->objectPath() << endl;
@ -121,30 +96,27 @@ void Foam::vtkPVFoam::convertVolFields
} }
} }
convertVolFields<scalar>(mesh, interpLst, objects, output); convertVolFields<scalar>(mesh, interpLst, objects);
convertVolFields<vector>(mesh, interpLst, objects, output); convertVolFields<vector>(mesh, interpLst, objects);
convertVolFields<sphericalTensor>(mesh, interpLst, objects, output); convertVolFields<sphericalTensor>(mesh, interpLst, objects);
convertVolFields<symmTensor>(mesh, interpLst, objects, output); convertVolFields<symmTensor>(mesh, interpLst, objects);
convertVolFields<tensor>(mesh, interpLst, objects, output); convertVolFields<tensor>(mesh, interpLst, objects);
convertDimFields<scalar>(mesh, interpLst, objects, output); convertDimFields<scalar>(mesh, interpLst, objects);
convertDimFields<vector>(mesh, interpLst, objects, output); convertDimFields<vector>(mesh, interpLst, objects);
convertDimFields<sphericalTensor>(mesh, interpLst, objects, output); convertDimFields<sphericalTensor>(mesh, interpLst, objects);
convertDimFields<symmTensor>(mesh, interpLst, objects, output); convertDimFields<symmTensor>(mesh, interpLst, objects);
convertDimFields<tensor>(mesh, interpLst, objects, output); convertDimFields<tensor>(mesh, interpLst, objects);
if (debug) if (debug)
{ {
Info<< "<end> convert volume fields" << endl; Info<< "<end> " << FUNCTION_NAME << endl;
printMemory(); printMemory();
} }
} }
void Foam::vtkPVFoam::convertPointFields void Foam::vtkPVFoam::convertPointFields()
(
vtkMultiBlockDataSet* output
)
{ {
const fvMesh& mesh = *meshPtr_; const fvMesh& mesh = *meshPtr_;
@ -165,7 +137,7 @@ void Foam::vtkPVFoam::convertPointFields
// Get objects (fields) for this time - only keep selected fields // Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db // the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName()); IOobjectList objects(mesh, dbPtr_().timeName());
pruneObjectList(objects, selectedFields); objects.filterKeys(selectedFields);
if (objects.empty()) if (objects.empty())
{ {
@ -175,7 +147,7 @@ void Foam::vtkPVFoam::convertPointFields
if (debug) if (debug)
{ {
Info<< "<beg> convert volume -> point fields" << endl; Info<< "<beg> convert volume -> point fields" << endl;
forAllConstIter(IOobjectList, objects, iter) forAllConstIters(objects, iter)
{ {
Info<< " " << iter()->name() Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl; << " == " << iter()->objectPath() << endl;
@ -186,11 +158,11 @@ void Foam::vtkPVFoam::convertPointFields
// Construct interpolation on the raw mesh // Construct interpolation on the raw mesh
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& pMesh = pointMesh::New(mesh);
convertPointFields<scalar>(pMesh, objects, output); convertPointFields<scalar>(pMesh, objects);
convertPointFields<vector>(pMesh, objects, output); convertPointFields<vector>(pMesh, objects);
convertPointFields<sphericalTensor>(pMesh, objects, output); convertPointFields<sphericalTensor>(pMesh, objects);
convertPointFields<symmTensor>(pMesh, objects, output); convertPointFields<symmTensor>(pMesh, objects);
convertPointFields<tensor>(pMesh, objects, output); convertPointFields<tensor>(pMesh, objects);
if (debug) if (debug)
{ {
@ -200,12 +172,9 @@ void Foam::vtkPVFoam::convertPointFields
} }
void Foam::vtkPVFoam::convertLagrangianFields void Foam::vtkPVFoam::convertLagrangianFields()
(
vtkMultiBlockDataSet* output
)
{ {
arrayRange& range = arrayRangeLagrangian_; const arrayRange& range = rangeLagrangian_;
const fvMesh& mesh = *meshPtr_; const fvMesh& mesh = *meshPtr_;
hashedWordList selectedFields = getSelected hashedWordList selectedFields = getSelected
@ -220,20 +189,28 @@ void Foam::vtkPVFoam::convertLagrangianFields
if (debug) if (debug)
{ {
Info<< "<beg> convert Lagrangian fields" << endl; Info<< "<beg> " << FUNCTION_NAME << endl;
printMemory(); printMemory();
} }
for (int partId = range.start(); partId < range.end(); ++partId) for (auto partId : range)
{ {
const word cloudName = getPartName(partId); if (!selectedPartIds_.found(partId))
const label datasetNo = partDataset_[partId];
if (!partStatus_[partId] || datasetNo < 0)
{ {
continue; continue;
} }
const auto& longName = selectedPartIds_[partId];
const word cloudName = getFoamName(longName);
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 // Get the Lagrangian fields for this time and this cloud
// but only keep selected fields // but only keep selected fields
// the region name is already in the mesh db // the region name is already in the mesh db
@ -243,7 +220,7 @@ void Foam::vtkPVFoam::convertLagrangianFields
dbPtr_().timeName(), dbPtr_().timeName(),
cloud::prefix/cloudName cloud::prefix/cloudName
); );
pruneObjectList(objects, selectedFields); objects.filterKeys(selectedFields);
if (objects.empty()) if (objects.empty())
{ {
@ -253,24 +230,24 @@ void Foam::vtkPVFoam::convertLagrangianFields
if (debug) if (debug)
{ {
Info<< "converting OpenFOAM lagrangian fields" << endl; Info<< "converting OpenFOAM lagrangian fields" << endl;
forAllConstIter(IOobjectList, objects, iter) forAllConstIters(objects, iter)
{ {
Info<< " " << iter()->name() Info<< " " << iter()->name()
<< " == " << iter()->objectPath() << endl; << " == " << iter()->objectPath() << endl;
} }
} }
convertLagrangianFields<label>(objects, output, datasetNo); convertLagrangianFields<label>(objects, dataset);
convertLagrangianFields<scalar>(objects, output, datasetNo); convertLagrangianFields<scalar>(objects, dataset);
convertLagrangianFields<vector>(objects, output, datasetNo); convertLagrangianFields<vector>(objects, dataset);
convertLagrangianFields<sphericalTensor>(objects, output, datasetNo); convertLagrangianFields<sphericalTensor>(objects, dataset);
convertLagrangianFields<symmTensor>(objects, output, datasetNo); convertLagrangianFields<symmTensor>(objects, dataset);
convertLagrangianFields<tensor>(objects, output, datasetNo); convertLagrangianFields<tensor>(objects, dataset);
} }
if (debug) if (debug)
{ {
Info<< "<end> convert Lagrangian fields" << endl; Info<< "<end> " << FUNCTION_NAME << endl;
printMemory(); printMemory();
} }
} }

View File

@ -35,16 +35,17 @@ License
#include "vtkCellArray.h" #include "vtkCellArray.h"
#include "vtkPoints.h" #include "vtkPoints.h"
#include "vtkPolyData.h" #include "vtkPolyData.h"
#include "vtkSmartPointer.h"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
vtkPolyData* Foam::vtkPVFoam::lagrangianVTKMesh vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
( (
const polyMesh& mesh, const polyMesh& mesh,
const word& cloudName const word& cloudName
) ) const
{ {
vtkPolyData* vtkmesh = nullptr; vtkSmartPointer<vtkPolyData> vtkmesh;
if (debug) if (debug)
{ {
@ -72,27 +73,19 @@ vtkPolyData* Foam::vtkPVFoam::lagrangianVTKMesh
Info<< "cloud with " << parcels.size() << " parcels" << endl; Info<< "cloud with " << parcels.size() << " parcels" << endl;
} }
vtkmesh = vtkPolyData::New(); auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkPoints* vtkpoints = vtkPoints::New(); vtkpoints->SetNumberOfPoints(parcels.size());
vtkCellArray* vtkcells = vtkCellArray::New();
vtkpoints->Allocate(parcels.size());
vtkcells->Allocate(parcels.size());
vtkIdType particleId = 0; vtkIdType particleId = 0;
forAllConstIter(Cloud<passiveParticle>, parcels, iter) forAllConstIters(parcels, iter)
{ {
vtkpoints->InsertNextPoint(iter().position().v_); vtkpoints->SetPoint(particleId, iter().position().v_);
++particleId;
vtkcells->InsertNextCell(1, &particleId);
particleId++;
} }
vtkmesh = vtkSmartPointer<vtkPolyData>::New();
vtkmesh->SetPoints(vtkpoints); vtkmesh->SetPoints(vtkpoints);
vtkpoints->Delete(); vtkmesh->SetVerts(foamPvCore::identityVertices(parcels.size()));
vtkmesh->SetVerts(vtkcells);
vtkcells->Delete();
} }
if (debug) if (debug)

View File

@ -28,397 +28,188 @@ License
// OpenFOAM includes // OpenFOAM includes
#include "fvMesh.H" #include "fvMesh.H"
#include "cellModeller.H" #include "fvMeshSubset.H"
#include "foamVtkAdaptors.H"
#include "foamVtuSizing.H"
// VTK includes // VTK includes
#include "vtkCellArray.h"
#include "vtkIdTypeArray.h"
#include "vtkUnstructuredGrid.h" #include "vtkUnstructuredGrid.h"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
vtkUnstructuredGrid* Foam::vtkPVFoam::volumeVTKMesh vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePoints
( (
const fvMesh& mesh, const fvMesh& mesh,
polyDecomp& decompInfo const foamVtuData& vtuData
) )
{ {
const cellModel& tet = *(cellModeller::lookup("tet")); // Convert OpenFOAM mesh vertices to VTK
const cellModel& pyr = *(cellModeller::lookup("pyr")); auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
const cellModel& prism = *(cellModeller::lookup("prism"));
const cellModel& wedge = *(cellModeller::lookup("wedge"));
const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
const cellModel& hex = *(cellModeller::lookup("hex"));
vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New(); // Normal points
const pointField& points = mesh.points();
// Additional cell centres
const labelList& addPoints = vtuData.additionalIds();
vtkpoints->SetNumberOfPoints(points.size() + addPoints.size());
// Normal points
label pointi = 0;
forAll(points, i)
{
vtkpoints->SetPoint(pointi++, points[i].v_);
}
// Cell centres
forAll(addPoints, i)
{
vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_);
}
return vtkpoints;
}
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();
// Normal points
const pointField& points = mesh.points();
// Additional cell centres
const labelList& addPoints = vtuData.additionalIds();
vtkpoints->SetNumberOfPoints(pointMap.size() + addPoints.size());
// Normal points
label pointi = 0;
forAll(pointMap, i)
{
vtkpoints->SetPoint(pointi++, points[pointMap[i]].v_);
}
// Cell centres
forAll(addPoints, i)
{
vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_);
}
return vtkpoints;
}
vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
(
const fvMesh& mesh,
foamVtuData& vtuData,
const bool decompPoly
)
{
if (debug) if (debug)
{ {
Info<< "<beg> volumeVTKMesh" << endl; Info<< "<beg> " << FUNCTION_NAME << endl;
printMemory(); printMemory();
} }
const cellShapeList& cellShapes = mesh.cellShapes(); vtk::vtuSizing sizing(mesh, decompPoly);
// Number of additional points needed by the decomposition of polyhedra auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New();
label nAddPoints = 0;
// Number of additional cells generated by the decomposition of polyhedra auto cells = vtkSmartPointer<vtkCellArray>::New();
label nAddCells = 0; auto faces = vtkSmartPointer<vtkIdTypeArray>::New();
// face owner is needed to determine the face orientation auto cellLocations = vtkSmartPointer<vtkIdTypeArray>::New();
const labelList& owner = mesh.faceOwner(); auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
labelList& superCells = decompInfo.superCells(); UList<uint8_t> cellTypesUL =
labelList& addPointCellLabels = decompInfo.addPointCellLabels(); vtkUList
// Scan for cells which need to be decomposed and count additional points
// and cells
if (!reader_->GetUseVTKPolyhedron())
{
forAll(cellShapes, celli)
{
const cellModel& model = cellShapes[celli].model();
if
( (
model != hex cellTypes,
&& model != wedge sizing.nFieldCells()
&& model != prism );
&& model != pyr
&& model != tet
&& model != tetWedge
)
{
const cell& cFaces = mesh.cells()[celli];
forAll(cFaces, cFacei) UList<vtkIdType> cellsUL =
{ vtkUList
const face& f = mesh.faces()[cFaces[cFacei]]; (
cells,
sizing.nFieldCells(),
sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS)
);
label nQuads = 0; UList<vtkIdType> cellLocationsUL =
label nTris = 0; vtkUList
f.nTrianglesQuads(mesh.points(), nTris, nQuads); (
cellLocations,
sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS_OFFSETS)
);
nAddCells += nQuads + nTris; UList<vtkIdType> facesUL =
} vtkUList
(
faces,
sizing.sizeInternal(vtk::vtuSizing::slotType::FACES)
);
nAddCells--; UList<vtkIdType> faceLocationsUL =
nAddPoints++; vtkUList
} (
} faceLocations,
} sizing.sizeInternal(vtk::vtuSizing::slotType::FACES_OFFSETS)
);
// Set size of additional point addressing array
// (from added point to original cell)
addPointCellLabels.setSize(nAddPoints);
// Set size of additional cells mapping array sizing.populateInternal
// (from added cell to original cell) (
mesh,
cellTypesUL,
cellsUL,
cellLocationsUL,
facesUL,
faceLocationsUL,
static_cast<foamVtkMeshMaps&>(vtuData)
);
superCells.setSize(mesh.nCells() + nAddCells); auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
// Convert OpenFOAM mesh vertices to VTK // Convert OpenFOAM mesh vertices to VTK
vtkPoints* vtkpoints = vtkPoints::New(); // - can only do this *after* populating the decompInfo with cell-ids
vtkpoints->Allocate(mesh.nPoints() + nAddPoints); // for any additional points (ie, mesh cell-centres)
vtkmesh->SetPoints(movePoints(mesh, vtuData));
const Foam::pointField& points = mesh.points(); if (facesUL.size())
forAll(points, i)
{ {
vtkpoints->InsertNextPoint(points[i].v_); vtkmesh->SetCells
}
vtkmesh->Allocate(mesh.nCells() + nAddCells);
// Set counters for additional points and additional cells
label addPointi = 0, addCelli = 0;
// 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);
forAll(cellShapes, celli)
{
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, cellTypes,
4, cellLocations,
nodeIds cells,
faceLocations,
faces
); );
} }
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 else
{ {
// fairly immaterial if we reverse the list vtkmesh->SetCells
// 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, cellTypes,
5, cellLocations,
nodeIds cells,
nullptr,
nullptr
); );
} }
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->SetPoints(vtkpoints);
vtkpoints->Delete();
if (debug) if (debug)
{ {
Info<<"nCells=" << mesh.nCells() <<" nPoints=" << mesh.nPoints() Info<< "<end> " << FUNCTION_NAME << endl;
<<" nAddCells=" << nAddCells <<" nAddPoints=" << nAddPoints
<< nl
<< "<end> volumeVTKMesh" << endl;
printMemory(); 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_);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -28,67 +28,91 @@ License
// OpenFOAM includes // OpenFOAM includes
#include "polyPatch.H" #include "polyPatch.H"
#include "primitivePatch.H" #include "primitivePatch.H"
#include "foamVtkAdaptors.H"
// VTK includes // VTK includes
#include "vtkCellArray.h" #include "vtkCellArray.h"
#include "vtkPoints.h" #include "vtkPoints.h"
#include "vtkPolyData.h" #include "vtkPolyData.h"
#include "vtkSmartPointer.h"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class PatchType> template<class PatchType>
vtkPolyData* Foam::vtkPVFoam::patchVTKMesh vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePatchPoints
( (
const word& name,
const PatchType& p const PatchType& p
) )
{ {
vtkPolyData* vtkmesh = vtkPolyData::New();
if (debug)
{
Info<< "<beg> patchVTKMesh - " << name << endl;
printMemory();
}
// Convert OpenFOAM mesh vertices to VTK // Convert OpenFOAM mesh vertices to VTK
const Foam::pointField& points = p.localPoints(); const pointField& points = p.localPoints();
vtkPoints* vtkpoints = vtkPoints::New(); auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkpoints->Allocate(points.size());
vtkpoints->SetNumberOfPoints(points.size());
forAll(points, i) forAll(points, i)
{ {
vtkpoints->InsertNextPoint(points[i].v_); vtkpoints->SetPoint(i, points[i].v_);
} }
vtkmesh->SetPoints(vtkpoints); return vtkpoints;
vtkpoints->Delete(); }
// Add faces as polygons
template<class PatchType>
vtkSmartPointer<vtkCellArray> Foam::vtkPVFoam::patchFacesVTKCells
(
const PatchType& p
)
{
// Faces as polygons
const faceList& faces = p.localFaces(); const faceList& faces = p.localFaces();
vtkCellArray* vtkcells = vtkCellArray::New(); label nAlloc = faces.size();
vtkcells->Allocate(faces.size()); forAll(faces, facei)
{
nAlloc += faces[facei].size();
}
auto cells = vtkSmartPointer<vtkCellArray>::New();
UList<vtkIdType> cellsUL =
vtkUList
(
cells,
faces.size(),
nAlloc
);
// Cell connectivity for polygons
// [size, verts..., size, verts... ]
label idx = 0;
forAll(faces, facei) forAll(faces, facei)
{ {
const face& f = faces[facei]; const face& f = faces[facei];
vtkIdType nodeIds[f.size()];
cellsUL[idx++] = f.size();
forAll(f, fp) forAll(f, fp)
{ {
nodeIds[fp] = f[fp]; cellsUL[idx++] = f[fp];
} }
vtkcells->InsertNextCell(f.size(), nodeIds);
} }
vtkmesh->SetPolys(vtkcells); return cells;
vtkcells->Delete(); }
if (debug)
{ template<class PatchType>
Info<< "<end> patchVTKMesh - " << name << endl; vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::patchVTKMesh
printMemory(); (
} const PatchType& p
)
{
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
vtkmesh->SetPoints(movePatchPoints(p));
vtkmesh->SetPolys(patchFacesVTKCells(p));
return vtkmesh; return vtkmesh;
} }

View File

@ -39,10 +39,6 @@ License
// VTK includes // VTK includes
#include "vtkDataArraySelection.h" #include "vtkDataArraySelection.h"
// Templates (only needed here)
#include "vtkPVFoamUpdateTemplates.C"
// * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -89,11 +85,11 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames
wordList names(zmesh.size()); wordList names(zmesh.size());
label nZone = 0; 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); names.setSize(nZone);
@ -128,9 +124,9 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames(const word& zoneType) const
zonesEntries zones(ioObj); zonesEntries zones(ioObj);
names.setSize(zones.size()); 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 void Foam::vtkPVFoam::updateInfoInternalMesh
( (
vtkDataArraySelection* arraySelection vtkDataArraySelection* select
) )
{ {
if (debug) if (debug)
@ -150,12 +146,8 @@ void Foam::vtkPVFoam::updateInfoInternalMesh
// Determine mesh parts (internalMesh, patches...) // Determine mesh parts (internalMesh, patches...)
//- Add internal mesh as first entry //- Add internal mesh as first entry
arrayRangeVolume_.reset(arraySelection->GetNumberOfArrays()); rangeVolume_.reset(select->GetNumberOfArrays(), 1);
arraySelection->AddArray select->AddArray("internalMesh");
(
"internalMesh"
);
arrayRangeVolume_ += 1;
if (debug) if (debug)
{ {
@ -166,16 +158,15 @@ void Foam::vtkPVFoam::updateInfoInternalMesh
void Foam::vtkPVFoam::updateInfoLagrangian void Foam::vtkPVFoam::updateInfoLagrangian
( (
vtkDataArraySelection* arraySelection vtkDataArraySelection* select
) )
{ {
if (debug) if (debug)
{ {
Info<< "<beg> updateInfoLagrangian" << nl Info<< "<beg> " << FUNCTION_NAME << nl
<< " " << dbPtr_->timePath()/cloud::prefix << endl; << " " << dbPtr_->timePath()/cloud::prefix << endl;
} }
// use the db directly since this might be called without a mesh, // use the db directly since this might be called without a mesh,
// but the region must get added back in // but the region must get added back in
fileName lagrangianPrefix(cloud::prefix); fileName lagrangianPrefix(cloud::prefix);
@ -190,96 +181,101 @@ void Foam::vtkPVFoam::updateInfoLagrangian
readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY) readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
); );
arrayRangeLagrangian_.reset(arraySelection->GetNumberOfArrays()); rangeLagrangian_.reset(select->GetNumberOfArrays());
forAll(cloudDirs, cloudi)
int nClouds = 0;
forAll(cloudDirs, cloudI)
{ {
// Add cloud to GUI list // Add cloud to GUI list
arraySelection->AddArray select->AddArray
( (
(cloudDirs[cloudI] + " - lagrangian").c_str() ("lagrangian/" + cloudDirs[cloudi]).c_str()
); );
++rangeLagrangian_;
++nClouds;
} }
arrayRangeLagrangian_ += nClouds;
if (debug) if (debug)
{ {
Info<< "<end> updateInfoLagrangian" << endl; Info<< "<end> " << FUNCTION_NAME << endl;
} }
} }
void Foam::vtkPVFoam::updateInfoPatches void Foam::vtkPVFoam::updateInfoPatches
( (
vtkDataArraySelection* arraySelection, vtkDataArraySelection* select,
stringList& enabledEntries HashSet<string>& enabledEntries
) )
{ {
if (debug) if (debug)
{ {
Info<< "<beg> updateInfoPatches" Info<< "<beg> " << FUNCTION_NAME
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
} }
rangePatches_.reset(select->GetNumberOfArrays());
HashSet<string> enabledEntriesSet(enabledEntries);
arrayRangePatches_.reset(arraySelection->GetNumberOfArrays());
int nPatches = 0;
if (meshPtr_) if (meshPtr_)
{ {
const polyBoundaryMesh& patches = meshPtr_->boundaryMesh(); const polyBoundaryMesh& patches = meshPtr_->boundaryMesh();
const HashTable<labelList>& groups = patches.groupPatchIDs(); 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) forAllConstIters(groups, iter)
{ {
const word& groupName = iter.key(); const auto& groupName = iter.key();
const labelList& patchIDs = iter.object(); const auto& patchIDs = iter.object();
label nFaces = 0; label nFaces = 0;
forAll(patchIDs, i) for (auto patchId : patchIDs)
{ {
nFaces += patches[patchIDs[i]].size(); nFaces += patches[patchId].size();
}
if (!nFaces)
{
// Skip if group has no faces
continue;
} }
// Valid patch if nFace > 0 - add patch to GUI list // Valid patch if nFace > 0 - add patch to GUI list
if (nFaces) const string dpyName = "group/" + groupName;
{ displayNames.append(dpyName);
string vtkGrpName = groupName + " - group";
arraySelection->AddArray(vtkGrpName.c_str());
++nPatches; // Optionally replace group with patch name selections
// - must remove the group from the select itself, otherwise
if (enabledEntriesSet.found(vtkGrpName)) // it can toggle on, but not toggle off very well
if
(
!reader_->GetShowGroupsOnly()
&& enabledEntries.erase(dpyName)
)
{ {
if (!reader_->GetShowGroupsOnly()) for (auto patchId : patchIDs)
{ {
enabledEntriesSet.erase(vtkGrpName); const polyPatch& pp = patches[patchId];
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
if (pp.size()) if (pp.size())
{ {
string vtkPatchName = pp.name() + " - patch"; enabledEntries.insert
enabledEntriesSet.insert(vtkPatchName); (
} "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()) if (!reader_->GetShowGroupsOnly())
{ {
@ -290,12 +286,11 @@ void Foam::vtkPVFoam::updateInfoPatches
if (pp.size()) if (pp.size())
{ {
// Add patch to GUI list // Add patch to GUI list
arraySelection->AddArray select->AddArray
( (
(pp.name() + " - patch").c_str() ("patch/" + pp.name()).c_str()
); );
++rangePatches_;
++nPatches;
} }
} }
} }
@ -320,94 +315,76 @@ void Foam::vtkPVFoam::updateInfoPatches
false 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)) if (ioObj.typeHeaderOk<polyBoundaryMesh>(true, false))
{ {
polyBoundaryMeshEntries patchEntries(ioObj); polyBoundaryMeshEntries patchEntries(ioObj);
// Read patches, determine sizes and patch groups
// Read patches and determine sizes
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wordList names(patchEntries.size()); wordList names(patchEntries.size());
labelList sizes(patchEntries.size()); labelList sizes(patchEntries.size());
HashTable<labelHashSet> groups(2*patchEntries.size());
forAll(patchEntries, patchi) forAll(patchEntries, patchi)
{ {
const dictionary& patchDict = patchEntries[patchi].dict(); const dictionary& patchDict = patchEntries[patchi].dict();
wordList groupNames;
sizes[patchi] = readLabel(patchDict.lookup("nFaces")); sizes[patchi] = readLabel(patchDict.lookup("nFaces"));
names[patchi] = patchEntries[patchi].keyword(); names[patchi] = patchEntries[patchi].keyword();
if
(
sizes[patchi] // Valid patch if nFace > 0
&& patchDict.readIfPresent("inGroups", groupNames)
)
{
forAll(groupNames, groupI)
{
groups(groupNames[groupI]).insert(patchi);
}
}
} }
// Add (non-zero) patch groups to the list of mesh parts // Add (non-zero) patch groups to the list of mesh parts
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DynamicList<string> displayNames(groups.size());
HashTable<labelList> groups(patchEntries.size());
forAll(patchEntries, patchi)
{
const dictionary& patchDict = patchEntries[patchi].dict();
wordList groupNames;
patchDict.readIfPresent("inGroups", groupNames);
forAll(groupNames, groupI)
{
HashTable<labelList>::iterator iter = groups.find
(
groupNames[groupI]
);
if (iter != groups.end())
{
iter().append(patchi);
}
else
{
groups.insert(groupNames[groupI], labelList{patchi});
}
}
}
forAllConstIters(groups, iter) forAllConstIters(groups, iter)
{ {
const word& groupName = iter.key(); const auto& groupName = iter.key();
const labelList& patchIDs = iter.object(); const auto& patchIDs = iter.object();
label nFaces = 0; const string dpyName = "group/" + groupName;
forAll(patchIDs, i) displayNames.append(dpyName);
{
nFaces += sizes[patchIDs[i]];
}
// Valid patch if nFace > 0 - add patch to GUI list // Optionally replace group with patch name selections
if (nFaces) // - 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"; for (auto patchId : patchIDs)
arraySelection->AddArray(vtkGrpName.c_str());
++nPatches;
if (enabledEntriesSet.found(vtkGrpName))
{ {
if (!reader_->GetShowGroupsOnly()) enabledEntries.insert
{ (
enabledEntriesSet.erase(vtkGrpName); "patch/" + names[patchId]
forAll(patchIDs, i) );
{
if (sizes[patchIDs[i]])
{
string vtkPatchName =
names[patchIDs[i]] + " - patch";
enabledEntriesSet.insert(vtkPatchName);
}
}
}
} }
} }
} }
// 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 // 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 // Valid patch if nFace > 0 - add patch to GUI list
if (sizes[patchi]) if (sizes[patchi])
{ {
arraySelection->AddArray select->AddArray
( (
(names[patchi] + " - patch").c_str() ("patch/" + names[patchi]).c_str()
); );
++rangePatches_;
++nPatches;
} }
} }
} }
} }
} }
arrayRangePatches_ += nPatches;
// Update enabled entries in case of group selection
enabledEntries = enabledEntriesSet.toc();
if (debug) if (debug)
{ {
Info<< "<end> updateInfoPatches" << endl; Info<< "<end> " << FUNCTION_NAME << endl;
} }
} }
void Foam::vtkPVFoam::updateInfoZones void Foam::vtkPVFoam::updateInfoZones
( (
vtkDataArraySelection* arraySelection vtkDataArraySelection* select
) )
{ {
if (!reader_->GetIncludeZones()) if (!reader_->GetIncludeZones())
@ -472,15 +444,15 @@ void Foam::vtkPVFoam::updateInfoZones
namesLst = getZoneNames("cellZones"); namesLst = getZoneNames("cellZones");
} }
arrayRangeCellZones_.reset(arraySelection->GetNumberOfArrays()); rangeCellZones_.reset(select->GetNumberOfArrays());
forAll(namesLst, elemI) 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"); namesLst = getZoneNames("faceZones");
} }
arrayRangeFaceZones_.reset(arraySelection->GetNumberOfArrays()); rangeFaceZones_.reset(select->GetNumberOfArrays());
forAll(namesLst, elemI) 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"); namesLst = getZoneNames("pointZones");
} }
arrayRangePointZones_.reset(arraySelection->GetNumberOfArrays()); rangePointZones_.reset(select->GetNumberOfArrays());
forAll(namesLst, elemI) forAll(namesLst, elemI)
{ {
arraySelection->AddArray select->AddArray
( (
(namesLst[elemI] + " - pointZone").c_str() ("pointZone/" + namesLst[elemI]).c_str()
); );
++rangePointZones_;
} }
arrayRangePointZones_ += namesLst.size();
if (debug) if (debug)
{ {
@ -537,7 +509,7 @@ void Foam::vtkPVFoam::updateInfoZones
void Foam::vtkPVFoam::updateInfoSets void Foam::vtkPVFoam::updateInfoSets
( (
vtkDataArraySelection* arraySelection vtkDataArraySelection* select
) )
{ {
if (!reader_->GetIncludeSets()) if (!reader_->GetIncludeSets())
@ -577,28 +549,28 @@ void Foam::vtkPVFoam::updateInfoSets
} }
arrayRangeCellSets_.reset(arraySelection->GetNumberOfArrays()); rangeCellSets_.reset(select->GetNumberOfArrays());
arrayRangeCellSets_ += addToSelection<cellSet> rangeCellSets_ += addToSelection<cellSet>
( (
arraySelection, select,
objects, objects,
" - cellSet" "cellSet/"
); );
arrayRangeFaceSets_.reset(arraySelection->GetNumberOfArrays()); rangeFaceSets_.reset(select->GetNumberOfArrays());
arrayRangeFaceSets_ += addToSelection<faceSet> rangeFaceSets_ += addToSelection<faceSet>
( (
arraySelection, select,
objects, objects,
" - faceSet" "faceSet/"
); );
arrayRangePointSets_.reset(arraySelection->GetNumberOfArrays()); rangePointSets_.reset(select->GetNumberOfArrays());
arrayRangePointSets_ += addToSelection<pointSet> rangePointSets_ += addToSelection<pointSet>
( (
arraySelection, select,
objects, objects,
" - pointSet" "pointSet/"
); );
if (debug) 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 void Foam::vtkPVFoam::updateInfoLagrangianFields
( (
vtkDataArraySelection* select vtkDataArraySelection* select
@ -635,22 +590,23 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
Info<< "<beg> updateInfoLagrangianFields" << endl; Info<< "<beg> updateInfoLagrangianFields" << endl;
} }
// preserve the enabled selections // Preserve the enabled selections
stringList enabledEntries = getSelectedArrayEntries(select); HashSet<string> enabled = getSelectedArraySet(select);
select->RemoveAllArrays(); select->RemoveAllArrays();
// TODO - currently only get fields from ONE cloud // TODO - currently only get fields from ONE cloud
// have to decide if the second set of fields get mixed in // have to decide if the second set of fields get mixed in
// or dealt with separately // or dealt with separately
const arrayRange& range = arrayRangeLagrangian_; const arrayRange& range = rangeLagrangian_;
if (range.empty()) if (range.empty())
{ {
return; return;
} }
int partId = range.start(); // Add Lagrangian fields even if particles are not enabled?
word cloudName = getPartName(partId); const int partId = range.start();
const word cloudName = getReaderPartName(partId);
// use the db directly since this might be called without a mesh, // use the db directly since this might be called without a mesh,
// but the region must get added back in // but the region must get added back in
@ -674,26 +630,8 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
addToSelection<IOField<symmTensor>>(select, objects); addToSelection<IOField<symmTensor>>(select, objects);
addToSelection<IOField<tensor>>(select, objects); addToSelection<IOField<tensor>>(select, objects);
// restore the enabled selections // Restore the enabled selections
setSelectedArrayEntries(select, enabledEntries); setSelectedArrayEntries(select, enabled);
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;
}
}
if (debug) if (debug)
{ {

View File

@ -45,16 +45,16 @@ void Foam::vtkPVFoam::updateInfoFields
<< endl; << endl;
} }
stringList enabledEntries; HashSet<string> enabled;
if (!select->GetNumberOfArrays() && !meshPtr_) if (!select->GetNumberOfArrays() && !meshPtr_)
{ {
// enable 'p' and 'U' only on the first call // Enable 'p' and 'U' only on the first call
enabledEntries = { "p", "U" }; enabled = { "p", "U" };
} }
else else
{ {
// preserve the enabled selections // Preserve the enabled selections
enabledEntries = getSelectedArrayEntries(select); enabled = getSelectedArraySet(select);
} }
select->RemoveAllArrays(); select->RemoveAllArrays();
@ -126,8 +126,8 @@ void Foam::vtkPVFoam::updateInfoFields
); );
// restore the enabled selections // Restore the enabled selections
setSelectedArrayEntries(select, enabledEntries); setSelectedArrayEntries(select, enabled);
if (debug) if (debug)
{ {

View File

@ -40,13 +40,14 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// file-scope // file-scope
static QAbstractButton* setButtonProperties // Widget properties
static QWidget* setWidgetProperties
( (
QAbstractButton* b, QWidget* widget,
vtkSMProperty* prop vtkSMProperty* prop
) )
{ {
QString tip; widget->setFocusPolicy(Qt::NoFocus); // avoid dotted border
vtkSMDocumentation* doc = prop->GetDocumentation(); vtkSMDocumentation* doc = prop->GetDocumentation();
if (doc) if (doc)
@ -54,22 +55,33 @@ static QAbstractButton* setButtonProperties
const char* txt = doc->GetDescription(); const char* txt = doc->GetDescription();
if (txt) if (txt)
{ {
tip = QString(txt).simplified(); QString tip = QString(txt).simplified();
}
}
b->setText(prop->GetXMLLabel());
if (tip.size()) if (tip.size())
{ {
b->setToolTip(tip); widget->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* intProp =
vtkSMIntVectorProperty::SafeDownCast(prop); vtkSMIntVectorProperty::SafeDownCast(prop);
// initial checked state for integer (bool) properties // Initial checked state for integer (bool) properties
if (intProp) if (intProp)
{ {
b->setChecked(intProp->GetElement(0)); b->setChecked(intProp->GetElement(0));
@ -111,12 +123,12 @@ void pqFoamBlockMeshControls::fireCommand(vtkSMProperty* prop)
void pqFoamBlockMeshControls::fireCommand void pqFoamBlockMeshControls::fireCommand
( (
vtkSMIntVectorProperty* prop, vtkSMIntVectorProperty* prop,
bool checked int val
) )
{ {
vtkSMProxy* pxy = this->proxy(); vtkSMProxy* pxy = this->proxy();
prop->SetElement(0, checked); // Toogle bool prop->SetElement(0, val); // Set int value, toogle bool, etc
// Fire off command // Fire off command
prop->Modified(); prop->Modified();
@ -200,7 +212,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls
setButtonProperties(b, refresh_); setButtonProperties(b, refresh_);
form->addWidget(b, 0, 0, Qt::AlignLeft); form->addWidget(b, 0, 0, Qt::AlignLeft);
connect(b, SIGNAL(clicked()), this, SLOT(refreshPressed())); connect
(
b, SIGNAL(clicked()), this, SLOT(refreshPressed())
);
} }
if (showPatchNames_) if (showPatchNames_)
@ -209,7 +224,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls
setButtonProperties(b, showPatchNames_); setButtonProperties(b, showPatchNames_);
form->addWidget(b, 0, 1, Qt::AlignLeft); 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_) if (showPointNumbers_)
@ -218,7 +236,10 @@ pqFoamBlockMeshControls::pqFoamBlockMeshControls
setButtonProperties(b, showPointNumbers_); setButtonProperties(b, showPointNumbers_);
form->addWidget(b, 0, 2, Qt::AlignLeft); 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))
);
} }
} }

View File

@ -71,8 +71,8 @@ class pqFoamBlockMeshControls
//- Update property //- Update property
void fireCommand(vtkSMProperty* prop); void fireCommand(vtkSMProperty* prop);
//- Toggle and update bool property //- Update int property or toggle bool property
void fireCommand(vtkSMIntVectorProperty* prop, bool checked); void fireCommand(vtkSMIntVectorProperty* prop, int val);
//- Update "BlockArrayStatus", "CurvedEdgesArrayStatus" information //- Update "BlockArrayStatus", "CurvedEdgesArrayStatus" information
void updateParts(); void updateParts();

View File

@ -106,7 +106,7 @@ vtkPVblockMeshReader::~vtkPVblockMeshReader()
if (FileName) if (FileName)
{ {
delete [] FileName; delete[] FileName;
} }
BlockSelection->RemoveAllObservers(); BlockSelection->RemoveAllObservers();
@ -165,20 +165,19 @@ int vtkPVblockMeshReader::RequestData
if (!FileName) if (!FileName)
{ {
vtkErrorMacro("FileName has to be specified!"); vtkErrorMacro("FileName must be specified!");
return 0; return 0;
} }
// Catch previous error
if (!backend_) if (!backend_)
{ {
vtkErrorMacro("Reader failed - perhaps no mesh?"); // Catch some previous error
vtkErrorMacro("Reader failed - perhaps no blockMesh?");
return 0; return 0;
} }
if (Foam::vtkPVblockMesh::debug) if (Foam::vtkPVblockMesh::debug)
{ {
cout<<"REQUEST_DATA:\n"; cout<<"RequestData:\n";
outputVector->GetInformationObject(0)->Print(cout); 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); backend_->Update(output);
updatePatchNamesView(ShowPatchNames); updatePatchNamesView(ShowPatchNames);
updatePointNumbersView(ShowPointNumbers); updatePointNumbersView(ShowPointNumbers);
// Do any cleanup on the OpenFOAM side backend_->UpdateFinalize();
backend_->CleanUp();
return 1; return 1;
} }
@ -263,12 +255,11 @@ void vtkPVblockMeshReader::updatePatchNamesView(const bool show)
} }
// Get all the pqRenderView instances // Get all the pqRenderView instances
QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); for (auto view : smModel->findItems<pqRenderView*>())
for (int viewI=0; viewI<renderViews.size(); ++viewI)
{ {
backend_->renderPatchNames backend_->renderPatchNames
( (
renderViews[viewI]->getRenderViewProxy()->GetRenderer(), view->getRenderViewProxy()->GetRenderer(),
show show
); );
} }
@ -295,12 +286,11 @@ void vtkPVblockMeshReader::updatePointNumbersView(const bool show)
} }
// Get all the pqRenderView instances // Get all the pqRenderView instances
QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>(); for (auto view : smModel->findItems<pqRenderView*>())
for (int viewI=0; viewI<renderViews.size(); ++viewI)
{ {
backend_->renderPointNumbers backend_->renderPointNumbers
( (
renderViews[viewI]->getRenderViewProxy()->GetRenderer(), view->getRenderViewProxy()->GetRenderer(),
show show
); );
} }

View File

@ -39,6 +39,7 @@ License
#include "vtkRenderer.h" #include "vtkRenderer.h"
#include "vtkTextActor.h" #include "vtkTextActor.h"
#include "vtkTextProperty.h" #include "vtkTextProperty.h"
#include "vtkSmartPointer.h"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -47,16 +48,20 @@ namespace Foam
defineTypeNameAndDebug(vtkPVblockMesh, 0); defineTypeNameAndDebug(vtkPVblockMesh, 0);
} }
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
vtkTextActor* Foam::vtkPVblockMesh::createTextActor namespace Foam
(
const string& s,
const point& pt
)
{ {
vtkTextActor* txt = vtkTextActor::New(); // 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()); txt->SetInput(s.c_str());
// Set text properties // Set text properties
@ -73,6 +78,7 @@ vtkTextActor* Foam::vtkPVblockMesh::createTextActor
txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z()); txt->GetPositionCoordinate()->SetValue(pt.x(), pt.y(), pt.z());
return txt; return txt;
}
} }
@ -81,9 +87,9 @@ vtkTextActor* Foam::vtkPVblockMesh::createTextActor
void Foam::vtkPVblockMesh::resetCounters() void Foam::vtkPVblockMesh::resetCounters()
{ {
// Reset mesh part ids and sizes // Reset mesh part ids and sizes
arrayRangeBlocks_.reset(); rangeBlocks_.reset();
arrayRangeEdges_.reset(); rangeEdges_.reset();
arrayRangeCorners_.reset(); rangeCorners_.reset();
} }
@ -92,15 +98,13 @@ void Foam::vtkPVblockMesh::updateInfoBlocks
vtkDataArraySelection* select vtkDataArraySelection* select
) )
{ {
arrayRange& range = arrayRangeBlocks_;
if (debug) if (debug)
{ {
Info<< "<beg> updateInfoBlocks" Info<< "<beg> updateInfoBlocks"
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
} }
range.reset(select->GetNumberOfArrays()); rangeBlocks_.reset(select->GetNumberOfArrays());
const blockMesh& blkMesh = *meshPtr_; const blockMesh& blkMesh = *meshPtr_;
@ -122,10 +126,9 @@ void Foam::vtkPVblockMesh::updateInfoBlocks
// Add "blockId" or "blockId - zoneName" to GUI list // Add "blockId" or "blockId - zoneName" to GUI list
select->AddArray(ostr.str().c_str()); select->AddArray(ostr.str().c_str());
++rangeBlocks_;
} }
range += nBlocks;
if (debug) if (debug)
{ {
Info<< "<end> updateInfoBlocks" << endl; Info<< "<end> updateInfoBlocks" << endl;
@ -138,15 +141,13 @@ void Foam::vtkPVblockMesh::updateInfoEdges
vtkDataArraySelection* select vtkDataArraySelection* select
) )
{ {
arrayRange& range = arrayRangeEdges_;
if (debug) if (debug)
{ {
Info<< "<beg> updateInfoEdges" Info<< "<beg> updateInfoEdges"
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
} }
range.reset(select->GetNumberOfArrays()); rangeEdges_.reset(select->GetNumberOfArrays());
const blockMesh& blkMesh = *meshPtr_; const blockMesh& blkMesh = *meshPtr_;
const blockEdgeList& edges = blkMesh.edges(); const blockEdgeList& edges = blkMesh.edges();
@ -161,10 +162,9 @@ void Foam::vtkPVblockMesh::updateInfoEdges
// Add "beg:end - type" to GUI list // Add "beg:end - type" to GUI list
select->AddArray(ostr.str().c_str()); select->AddArray(ostr.str().c_str());
++rangeEdges_;
} }
range += edges.size();
if (debug) if (debug)
{ {
Info<< "<end> updateInfoEdges" << endl; Info<< "<end> updateInfoEdges" << endl;
@ -185,9 +185,9 @@ Foam::vtkPVblockMesh::vtkPVblockMesh
meshPtr_(nullptr), meshPtr_(nullptr),
meshRegion_(polyMesh::defaultRegion), meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir), meshDir_(polyMesh::meshSubDir),
arrayRangeBlocks_("block"), rangeBlocks_("block"),
arrayRangeEdges_("edges"), rangeEdges_("edges"),
arrayRangeCorners_("corners") rangeCorners_("corners")
{ {
if (debug) if (debug)
{ {
@ -302,14 +302,15 @@ void Foam::vtkPVblockMesh::updateInfo()
vtkDataArraySelection* blockSelection = reader_->GetBlockSelection(); vtkDataArraySelection* blockSelection = reader_->GetBlockSelection();
vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection(); vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection();
// preserve the enabled selections if possible
stringList enabledParts;
stringList enabledEdges;
const bool firstTime = (!blockSelection->GetNumberOfArrays() && !meshPtr_); const bool firstTime = (!blockSelection->GetNumberOfArrays() && !meshPtr_);
// Preserve the enabled selections if possible
HashSet<string> enabledParts;
HashSet<string> enabledEdges;
if (!firstTime) if (!firstTime)
{ {
enabledParts = getSelectedArrayEntries(blockSelection); enabledParts = getSelectedArraySet(blockSelection);
enabledEdges = getSelectedArrayEntries(edgeSelection); enabledEdges = getSelectedArraySet(edgeSelection);
} }
// Clear current mesh parts list // Clear current mesh parts list
@ -325,7 +326,7 @@ void Foam::vtkPVblockMesh::updateInfo()
// Update curved edges list // Update curved edges list
updateInfoEdges(edgeSelection); updateInfoEdges(edgeSelection);
// restore the enabled selections // Restore the enabled selections
if (!firstTime) if (!firstTime)
{ {
setSelectedArrayEntries(blockSelection, enabledParts); setSelectedArrayEntries(blockSelection, enabledParts);
@ -405,14 +406,6 @@ void Foam::vtkPVblockMesh::Update
{ {
reader_->UpdateProgress(0.1); 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 // Update the OpenFOAM mesh
updateFoamMesh(); updateFoamMesh();
reader_->UpdateProgress(0.5); reader_->UpdateProgress(0.5);
@ -425,11 +418,10 @@ void Foam::vtkPVblockMesh::Update
convertMeshEdges(output, blockNo); convertMeshEdges(output, blockNo);
reader_->UpdateProgress(0.8); reader_->UpdateProgress(0.8);
} }
void Foam::vtkPVblockMesh::CleanUp() void Foam::vtkPVblockMesh::UpdateFinalize()
{ {
reader_->UpdateProgress(1.0); reader_->UpdateProgress(1.0);
} }
@ -442,12 +434,11 @@ void Foam::vtkPVblockMesh::renderPatchNames
) )
{ {
// always remove old actors first // always remove old actors first
forAll(patchTextActorsPtrs_, actori) forAll(patchTextActors_, actori)
{ {
renderer->RemoveViewProp(patchTextActorsPtrs_[actori]); renderer->RemoveViewProp(patchTextActors_[actori]);
patchTextActorsPtrs_[actori]->Delete();
} }
patchTextActorsPtrs_.clear(); patchTextActors_.clear();
// the number of text actors // the number of text actors
label nActors = 0; label nActors = 0;
@ -465,7 +456,7 @@ void Foam::vtkPVblockMesh::renderPatchNames
} }
// 8 sides per block is plenty // 8 sides per block is plenty
patchTextActorsPtrs_.setSize(8*blkMesh.size()); patchTextActors_.setSize(8*blkMesh.size());
// Collect all variables // Collect all variables
dictionary varDict(meshDescription.subOrEmptyDict("namedVertices")); dictionary varDict(meshDescription.subOrEmptyDict("namedVertices"));
@ -501,33 +492,33 @@ void Foam::vtkPVblockMesh::renderPatchNames
const face& f = patchFaces[facei]; const face& f = patchFaces[facei];
// Into a list for later removal // Into a list for later removal
patchTextActorsPtrs_[nActors++] = createTextActor patchTextActors_[nActors++] = createTextActor
( (
patchName, patchName,
f.centre(cornerPts) * scaleFactor f.centre(cornerPts) * scaleFactor
); );
if (nActors == patchTextActorsPtrs_.size()) if (nActors == patchTextActors_.size())
{ {
// hit max allocated space - bail out // hit max allocated space - bail out
break; break;
} }
} }
if (nActors == patchTextActorsPtrs_.size()) if (nActors == patchTextActors_.size())
{ {
// hit max allocated space - bail out // hit max allocated space - bail out
break; break;
} }
} }
patchTextActorsPtrs_.setSize(nActors); patchTextActors_.setSize(nActors);
} }
// Add text to each renderer // 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 // always remove old actors first
forAll(pointTextActorsPtrs_, actori) forAll(pointTextActors_, actori)
{ {
renderer->RemoveViewProp(pointTextActorsPtrs_[actori]); renderer->RemoveViewProp(pointTextActors_[actori]);
pointTextActorsPtrs_[actori]->Delete();
} }
pointTextActorsPtrs_.clear(); pointTextActors_.clear();
if (show && meshPtr_) if (show && meshPtr_)
{ {
@ -553,7 +543,7 @@ void Foam::vtkPVblockMesh::renderPointNumbers
const pointField& cornerPts = blkMesh.vertices(); const pointField& cornerPts = blkMesh.vertices();
const scalar scaleFactor = blkMesh.scaleFactor(); const scalar scaleFactor = blkMesh.scaleFactor();
pointTextActorsPtrs_.setSize(cornerPts.size()); pointTextActors_.setSize(cornerPts.size());
forAll(cornerPts, pointi) forAll(cornerPts, pointi)
{ {
// Display either pointi as a number or with its name // Display either pointi as a number or with its name
@ -562,7 +552,7 @@ void Foam::vtkPVblockMesh::renderPointNumbers
blockVertex::write(os, pointi, blkMesh.meshDict()); blockVertex::write(os, pointi, blkMesh.meshDict());
// Into a list for later removal // Into a list for later removal
pointTextActorsPtrs_[pointi] = createTextActor pointTextActors_[pointi] = createTextActor
( (
os.str(), os.str(),
cornerPts[pointi]*scaleFactor cornerPts[pointi]*scaleFactor
@ -571,9 +561,9 @@ void Foam::vtkPVblockMesh::renderPointNumbers
} }
// Add text to each renderer // Add text to each renderer
forAll(pointTextActorsPtrs_, actori) forAll(pointTextActors_, actori)
{ {
renderer->AddViewProp(pointTextActorsPtrs_[actori]); renderer->AddViewProp(pointTextActors_[actori]);
} }
} }

View File

@ -25,13 +25,18 @@ Class
Foam::vtkPVblockMesh Foam::vtkPVblockMesh
Description 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 SourceFiles
vtkPVblockMesh.C vtkPVblockMesh.C
vtkPVblockMeshConvert.C vtkPVblockMeshConvert.C
vtkPVblockMeshUpdate.C
vtkPVblockMeshUtils.C
// Needed by VTK: // Needed by VTK:
vtkDataArrayTemplateImplicit.txx vtkDataArrayTemplateImplicit.txx
@ -56,6 +61,8 @@ class vtkPolyData;
class vtkUnstructuredGrid; class vtkUnstructuredGrid;
class vtkIndent; class vtkIndent;
template<class T> class vtkSmartPointer;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -93,34 +100,25 @@ class vtkPVblockMesh
//- The mesh directory for the region //- The mesh directory for the region
fileName meshDir_; fileName meshDir_;
//- Selected geometrical parts
boolList blockStatus_;
//- Selected curved edges
boolList edgeStatus_;
//- First instance and size of bleckMesh blocks //- First instance and size of bleckMesh blocks
// used to index into blockStatus_ // used to index into blockStatus_
arrayRange arrayRangeBlocks_; arrayRange rangeBlocks_;
//- First instance and size of CurvedEdges (only partially used) //- First instance and size of CurvedEdges (only partially used)
arrayRange arrayRangeEdges_; arrayRange rangeEdges_;
//- First instance and size of block corners (only partially used) //- First instance and size of block corners (only partially used)
arrayRange arrayRangeCorners_; arrayRange rangeCorners_;
//- List of patch names for rendering to window //- List of patch names for rendering to window
List<vtkTextActor*> patchTextActorsPtrs_; List<vtkSmartPointer<vtkTextActor>> patchTextActors_;
//- List of point numbers for rendering to window //- List of point numbers for rendering to window
List<vtkTextActor*> pointTextActorsPtrs_; List<vtkSmartPointer<vtkTextActor>> pointTextActors_;
// Private Member Functions // Private Member Functions
//- Create a text actor
static vtkTextActor* createTextActor(const string& s, const point& pt);
//- Reset data counters //- Reset data counters
void resetCounters(); void resetCounters();
@ -178,14 +176,15 @@ public:
void Update(vtkMultiBlockDataSet* output); void Update(vtkMultiBlockDataSet* output);
//- Clean any storage //- Final part of Update(), after any last minute rendering.
void CleanUp(); void UpdateFinalize();
//- Add/remove patch names to/from the view //- 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 //- Add/remove point numbers to/from the view
void renderPointNumbers(vtkRenderer*, const bool show); void renderPointNumbers(vtkRenderer* renderer, const bool show);
// Access // Access

View File

@ -37,28 +37,9 @@ License
#include "vtkPoints.h" #include "vtkPoints.h"
#include "vtkPolyData.h" #include "vtkPolyData.h"
#include "vtkUnstructuredGrid.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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtkPVblockMesh::convertMeshBlocks void Foam::vtkPVblockMesh::convertMeshBlocks
@ -67,56 +48,52 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
int& blockNo 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) if (debug)
{ {
Info<< "<beg> convertMeshBlocks" << endl; Info<< "<beg> convertMeshBlocks" << endl;
} }
int blockI = 0; const Map<string> blockStatus = getSelectedArrayMap
const scalar scaleFactor = blkMesh.scaleFactor();
for
( (
int partId = range.start(); reader_->GetBlockSelection()
partId < range.end(); );
++partId, ++blockI
) 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; continue;
} }
const auto& longName = blockStatus[partId];
const blockDescriptor& blockDef = blkMesh[blockI]; const blockDescriptor& blockDef = blkMesh[blockId];
// Convert OpenFOAM mesh vertices to VTK
vtkPoints *vtkpoints = vtkPoints::New();
vtkpoints->Allocate(blockDef.nPoints());
const labelList& blockLabels = blockDef.blockShape(); 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, pointi,
blockPoints[blockLabels[ptI]], blkPoints[blockLabels[pointi]].v_
scaleFactor
); );
nodeIds[pointi] = pointi;
nodeIds[ptI] = ptI;
} }
vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New(); auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
vtkmesh->Allocate(1); vtkmesh->Allocate(1);
vtkmesh->InsertNextCell vtkmesh->InsertNextCell
( (
@ -126,16 +103,9 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
); );
vtkmesh->SetPoints(vtkpoints); vtkmesh->SetPoints(vtkpoints);
vtkpoints->Delete();
addToBlock addToBlock(output, vtkmesh, range, datasetNo, longName);
( ++datasetNo;
output, vtkmesh, range, datasetNo,
selection->GetArrayName(partId)
);
vtkmesh->Delete();
datasetNo++;
} }
@ -158,34 +128,34 @@ void Foam::vtkPVblockMesh::convertMeshEdges
int& blockNo int& blockNo
) )
{ {
vtkDataArraySelection* selection = reader_->GetCurvedEdgesSelection(); const Map<string> edgeStatus = getSelectedArrayMap
arrayRange& range = arrayRangeEdges_; (
reader_->GetCurvedEdgesSelection()
);
arrayRange& range = rangeEdges_;
range.block(blockNo); // set output block range.block(blockNo); // set output block
label datasetNo = 0; // restart at dataset 0 label datasetNo = 0; // restart at dataset 0
const blockMesh& blkMesh = *meshPtr_; const blockMesh& blkMesh = *meshPtr_;
const blockEdgeList& edges = blkMesh.edges(); const blockEdgeList& edges = blkMesh.edges();
int edgeI = 0;
const scalar scaleFactor = blkMesh.scaleFactor(); const scalar scaleFactor = blkMesh.scaleFactor();
for int edgeId = -1;
( for (auto partId : range)
int partId = range.start();
partId < range.end();
++partId, ++edgeI
)
{ {
if (!edgeStatus_[partId]) ++edgeId; // Increment first
if (!edgeStatus.found(partId))
{ {
continue; continue;
} }
const auto& longName = edgeStatus[partId];
// search each block // Search each block
forAll(blkMesh, blockI) forAll(blkMesh, blockId)
{ {
const blockDescriptor& blockDef = blkMesh[blockI]; const blockDescriptor& blockDef = blkMesh[blockId];
edgeList blkEdges = blockDef.blockShape().edges(); edgeList blkEdges = blockDef.blockShape().edges();
@ -198,7 +168,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges
label foundEdgeI = -1; label foundEdgeI = -1;
forAll(blkEdges, blkEdgeI) forAll(blkEdges, blkEdgeI)
{ {
if (edges[edgeI].compare(blkEdges[blkEdgeI])) if (edges[edgeId].compare(blkEdges[blkEdgeI]))
{ {
foundEdgeI = blkEdgeI; foundEdgeI = blkEdgeI;
break; break;
@ -209,24 +179,21 @@ void Foam::vtkPVblockMesh::convertMeshEdges
{ {
const List<point>& edgePoints = edgesPoints[foundEdgeI]; const List<point>& edgePoints = edgesPoints[foundEdgeI];
vtkPolyData* vtkmesh = vtkPolyData::New(); auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkPoints* vtkpoints = vtkPoints::New(); vtkpoints->SetNumberOfPoints(edgePoints.size());
vtkpoints->Allocate( edgePoints.size() );
vtkmesh->Allocate(1);
vtkIdType pointIds[edgePoints.size()]; vtkIdType pointIds[edgePoints.size()];
forAll(edgePoints, ptI) forAll(edgePoints, pointi)
{ {
insertNextPoint const point p = edgePoints[pointi] * scaleFactor;
(
vtkpoints, vtkpoints->SetPoint(pointi, p.v_);
edgePoints[ptI], pointIds[pointi] = pointi;
scaleFactor
);
pointIds[ptI] = ptI;
} }
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
vtkmesh->Allocate(1);
vtkmesh->InsertNextCell vtkmesh->InsertNextCell
( (
VTK_POLY_LINE, VTK_POLY_LINE,
@ -235,16 +202,9 @@ void Foam::vtkPVblockMesh::convertMeshEdges
); );
vtkmesh->SetPoints(vtkpoints); vtkmesh->SetPoints(vtkpoints);
vtkpoints->Delete();
addToBlock addToBlock(output, vtkmesh, range, datasetNo, longName);
( ++datasetNo;
output, vtkmesh, range, datasetNo,
selection->GetArrayName(partId)
);
vtkmesh->Delete();
datasetNo++;
break; break;
} }
@ -271,51 +231,34 @@ void Foam::vtkPVblockMesh::convertMeshCorners
int& blockNo int& blockNo
) )
{ {
arrayRange& range = arrayRangeCorners_; arrayRange& range = rangeCorners_;
range.block(blockNo); // set output block range.block(blockNo); // set output block
label datasetNo = 0; // restart at dataset 0 label datasetNo = 0; // restart at dataset 0
const pointField& blockPoints = meshPtr_->vertices(); const pointField blkPoints(meshPtr_->vertices() * meshPtr_->scaleFactor());
const scalar& scaleFactor = meshPtr_->scaleFactor();
if (debug) 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(); auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkPoints* vtkpoints = vtkPoints::New(); vtkpoints->SetNumberOfPoints(blkPoints.size());
vtkCellArray* vtkcells = vtkCellArray::New();
vtkpoints->Allocate( blockPoints.size() ); forAll(blkPoints, pointi)
vtkcells->Allocate( blockPoints.size() );
vtkIdType pointId = 0;
forAll(blockPoints, ptI)
{ {
insertNextPoint vtkpoints->SetPoint(pointi, blkPoints[pointi].v_);
(
vtkpoints,
blockPoints[ptI],
scaleFactor
);
vtkcells->InsertNextCell(1, &pointId); // VTK_VERTEX
pointId++;
} }
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
vtkmesh->SetPoints(vtkpoints); vtkmesh->SetPoints(vtkpoints);
vtkpoints->Delete(); vtkmesh->SetVerts(foamPvCore::identityVertices(blkPoints.size()));
vtkmesh->SetVerts(vtkcells);
vtkcells->Delete();
addToBlock(output, vtkmesh, range, datasetNo, range.name()); addToBlock(output, vtkmesh, range, datasetNo, range.name());
vtkmesh->Delete(); ++datasetNo;
datasetNo++;
} }
// anything added? // anything added?
@ -326,7 +269,7 @@ void Foam::vtkPVblockMesh::convertMeshCorners
if (debug) if (debug)
{ {
Info<< "<end> convertMeshCorners" << endl; Info<< "<end> " << FUNCTION_NAME << endl;
} }
} }

View File

@ -32,6 +32,9 @@ License
#include "vtkDataSet.h" #include "vtkDataSet.h"
#include "vtkMultiBlockDataSet.h" #include "vtkMultiBlockDataSet.h"
#include "vtkInformation.h" #include "vtkInformation.h"
#include "vtkSmartPointer.h"
#include "foamVtkAdaptors.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -54,7 +57,8 @@ void Foam::foamPvCore::addToBlock
const int blockNo = selector.block(); const int blockNo = selector.block();
vtkDataObject* dataObj = output->GetBlock(blockNo); vtkDataObject* dataObj = output->GetBlock(blockNo);
vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(dataObj); vtkSmartPointer<vtkMultiBlockDataSet> block =
vtkMultiBlockDataSet::SafeDownCast(dataObj);
if (!block) if (!block)
{ {
@ -66,9 +70,8 @@ void Foam::foamPvCore::addToBlock
return; return;
} }
block = vtkMultiBlockDataSet::New(); block = vtkSmartPointer<vtkMultiBlockDataSet>::New();
output->SetBlock(blockNo, block); output->SetBlock(blockNo, block);
block->Delete();
} }
if (debug) if (debug)
@ -81,7 +84,7 @@ void Foam::foamPvCore::addToBlock
block->SetBlock(datasetNo, dataset); block->SetBlock(datasetNo, dataset);
// name the output block when assigning dataset 0 // Name the output block when assigning dataset 0
if (datasetNo == 0) if (datasetNo == 0)
{ {
output->GetMetaData(blockNo)->Set 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 Foam::hashedWordList Foam::foamPvCore::getSelected
( (
vtkDataArraySelection* select vtkDataArraySelection* select
@ -164,7 +117,7 @@ Foam::hashedWordList Foam::foamPvCore::getSelected
{ {
if (select->GetArraySetting(i)) 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(); const int n = select->GetNumberOfArrays();
DynamicList<word> selected(n); DynamicList<word> selected(n);
for (int i = selector.start(); i < selector.end(); ++i) for (auto i : selector)
{ {
if (select->GetArraySetting(i)) if (select->GetArraySetting(i))
{ {
selected.append(getFirstWord(select->GetArrayName(i))); selected.append(getFoamName(select->GetArrayName(i)));
} }
} }
@ -193,119 +146,88 @@ Foam::hashedWordList Foam::foamPvCore::getSelected
} }
Foam::stringList Foam::foamPvCore::getSelectedArrayEntries Foam::HashSet<Foam::string>
Foam::foamPvCore::getSelectedArraySet
( (
vtkDataArraySelection* select vtkDataArraySelection* select
) )
{ {
stringList selections(select->GetNumberOfArrays());
label nElem = 0;
forAll(selections, elemI)
{
if (select->GetArraySetting(elemI))
{
selections[nElem++] = select->GetArrayName(elemI);
}
}
selections.setSize(nElem);
if (debug > 1)
{
const int n = select->GetNumberOfArrays(); const int n = select->GetNumberOfArrays();
Info<< "available("; HashSet<string> enabled(2*n);
for (int i=0; i < n; ++i) for (int i=0; i < n; ++i)
{
Info<< " \"" << select->GetArrayName(i) << "\"";
}
Info<< " )\nselected(";
forAll(selections, elemI)
{
Info<< " " << selections[elemI];
}
Info<< " )\n";
}
return selections;
}
Foam::stringList Foam::foamPvCore::getSelectedArrayEntries
(
vtkDataArraySelection* select,
const arrayRange& selector
)
{
stringList selections(selector.size());
label nElem = 0;
for (int i = selector.start(); i < selector.end(); ++i)
{ {
if (select->GetArraySetting(i)) if (select->GetArraySetting(i))
{ {
selections[nElem++] = select->GetArrayName(i); enabled.insert(select->GetArrayName(i));
} }
} }
selections.setSize(nElem);
if (debug > 1) if (debug > 1)
{ {
const int n = select->GetNumberOfArrays();
Info<< "available("; Info<< "available(";
for (int i = selector.start(); i < selector.end(); ++i) for (int i=0; i < n; ++i)
{ {
Info<< " \"" << select->GetArrayName(i) << "\""; Info<< " \"" << select->GetArrayName(i) << "\"";
} }
Info<< " )\nselected("; Info<< " )\nselected(";
forAll(selections, elemI) for (auto k : enabled)
{ {
Info<< " " << selections[elemI]; Info<< " " << k;
} }
Info<< " )\n"; Info<< " )\n";
} }
return selections; return enabled;
} }
void Foam::foamPvCore::setSelectedArrayEntries Foam::Map<Foam::string>
Foam::foamPvCore::getSelectedArrayMap
( (
vtkDataArraySelection* select, vtkDataArraySelection* select
const stringList& selections
) )
{ {
const int n = select->GetNumberOfArrays(); const int n = select->GetNumberOfArrays();
select->DisableAllArrays(); Map<string> enabled(2*n);
// Loop through entries, setting values from selectedEntries
for (int i=0; i < n; ++i) for (int i=0; i < n; ++i)
{ {
const string arrayName(select->GetArrayName(i)); if (select->GetArraySetting(i))
{
enabled.insert(i, select->GetArrayName(i));
}
}
forAll(selections, elemI) return enabled;
{
if (selections[elemI] == arrayName)
{
select->EnableArray(arrayName.c_str());
break;
}
}
}
} }
Foam::word Foam::foamPvCore::getFirstWord(const char* str) Foam::word Foam::foamPvCore::getFoamName(const std::string& str)
{ {
if (str) if (str.size())
{ {
label n = 0; std::string::size_type beg = str.rfind('/');
while (str[n] && word::valid(str[n])) if (beg == std::string::npos)
{ {
++n; beg = 0;
} }
// don't need to re-check for invalid chars else
return word(str, n, false); {
++beg;
}
std::string::size_type end = beg;
while (str[end] && word::valid(str[end]))
{
++end;
}
// Already checked for valid/invalid chars
return word(str.substr(beg, beg+end), false);
} }
else 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;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -39,16 +39,20 @@ SourceFiles
#include "pointList.H" #include "pointList.H"
#include "wordList.H" #include "wordList.H"
#include "Hash.H" #include "Hash.H"
#include "HashSet.H"
#include "Map.H"
#include "hashedWordList.H" #include "hashedWordList.H"
#include "labelRange.H"
#include "vtkPoints.h"
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // // * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * //
class vtkCellArray;
class vtkDataArraySelection; class vtkDataArraySelection;
class vtkDataSet; class vtkDataSet;
class vtkMultiBlockDataSet;
class vtkIndent; class vtkIndent;
class vtkMultiBlockDataSet;
class vtkPoints;
template<class T> class vtkSmartPointer;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -69,21 +73,20 @@ public:
//- Bookkeeping for GUI checklists and multi-block organization //- Bookkeeping for GUI checklists and multi-block organization
// Works like a SubList selection. // Works like a SubList selection.
class arrayRange class arrayRange
:
public labelRange
{ {
const char *name_; const char *name_;
int block_; int block_;
int start_;
int size_;
public: public:
//- Construct with given name for the specified block //- 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), name_(name),
block_(blockNo), block_(blockNo)
start_(0),
size_(0)
{} {}
//- Return the block holding these datasets //- Return the block holding these datasets
@ -106,47 +109,21 @@ public:
return name_; return name_;
} }
//- The array start index //- Reset the start/size directly
int start() const using labelRange::reset;
{
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 size to zero and optionally assign a new start //- Reset the size to zero and optionally assign a new start
void reset(const int startAt = 0) void reset(label startAt = 0)
{ {
start_ = startAt; clear();
size_ = 0; setStart(startAt);
} }
//- Assign new start and reset the size
void operator=(const int i)
{
reset(i);
}
//- Increment the size //- Increment the size
void operator+=(const int n) void operator+=(label n)
{ {
size_ += n; setSize(size() + n);
} }
}; // End class arrayRange }; // End class arrayRange
@ -183,48 +160,26 @@ public:
const std::string& datasetName 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 //- Add objects of Type to array selection
template<class Type> template<class Type>
static label addToSelection static label addToSelection
( (
vtkDataArraySelection* select, vtkDataArraySelection* select,
const IOobjectList& objects, const IOobjectList& objects,
const string& suffix = string::null const std::string& prefix = string::null
); );
//- Retrieve the current selections into a boolList //- Retrieve the current selections as a hashedWordList,
static int getSelected // while stripping off any prefix or suffix
(
boolList& lst,
vtkDataArraySelection* select
);
//- Retrieve the current selections as a wordHashSet
static hashedWordList getSelected static hashedWordList getSelected
( (
vtkDataArraySelection* select 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 static hashedWordList getSelected
( (
vtkDataArraySelection* select, vtkDataArraySelection* select,
@ -232,35 +187,42 @@ public:
); );
//- Retrieve the current selections //- Retrieve the currently enabled selections as hashset
static stringList getSelectedArrayEntries static HashSet<string> getSelectedArraySet
( (
vtkDataArraySelection* select vtkDataArraySelection* select
); );
//- Retrieve a sub-list of the current selections //- Retrieve the currently enabled selections as id/name map
static stringList getSelectedArrayEntries static Map<string> getSelectedArrayMap
( (
vtkDataArraySelection* select, vtkDataArraySelection* select
const arrayRange& selector
); );
//- Enable the selection(s)
//- Set selection(s) template<class AnyValue, class AnyHasher>
static void setSelectedArrayEntries static void setSelectedArrayEntries
( (
vtkDataArraySelection* select, vtkDataArraySelection* select,
const stringList& selections const HashTable<AnyValue, string, AnyHasher>& enabled
); );
//- Extract up to the first non-word characters //- Extract the first word characters after a slash
static word getFirstWord(const char* str); static word getFoamName(const std::string& str);
//- Simple memory used debugging information //- Simple memory used debugging information
static void printMemory(); static void printMemory();
//- Return an identity list of VTK_VERTEX
static vtkSmartPointer<vtkCellArray> identityVertices
(
const label size
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
}; // End class foamPvCore }; // End class foamPvCore

View File

@ -25,55 +25,28 @@ License
#include "IOobjectList.H" #include "IOobjectList.H"
#include "vtkDataArraySelection.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> template<class Type>
Foam::label Foam::foamPvCore::addToSelection Foam::label Foam::foamPvCore::addToSelection
( (
vtkDataArraySelection *select, vtkDataArraySelection *select,
const IOobjectList& objects, const IOobjectList& objects,
const string& suffix const std::string& prefix
) )
{ {
const wordList names = objects.sortedNames(Type::typeName); const wordList names = objects.sortedNames(Type::typeName);
forAll(names, i) forAll(names, i)
{ {
if (suffix.empty()) if (prefix.empty())
{ {
select->AddArray(names[i].c_str()); select->AddArray(names[i].c_str());
} }
else 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);
}
}
}
// ************************************************************************* // // ************************************************************************* //

View File

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

View File

@ -1,5 +1,6 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude -I$(LIB_SRC)/finiteVolume/lnInclude

View File

@ -158,6 +158,9 @@ int main(int argc, char *argv[])
} }
if if
(
!args.optionFound("triSurface")
&&
( (
!MeshedSurface<face>::canRead(importName, true) !MeshedSurface<face>::canRead(importName, true)
|| ||
@ -166,6 +169,7 @@ int main(int argc, char *argv[])
&& !MeshedSurface<face>::canWriteType(exportName.ext(), true) && !MeshedSurface<face>::canWriteType(exportName.ext(), true)
) )
) )
)
{ {
return 1; return 1;
} }

View File

@ -26,10 +26,10 @@
# paraFoam # paraFoam
# #
# Description # Description
# start paraview with the OpenFOAM libraries # Start paraview with the OpenFOAM libraries and reader modules.
# #
# Note # Note
# combining -block or -builtin options with the -region option yields # Combining -block or -builtin options with -region option yields
# undefined behaviour # undefined behaviour
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
usage() { usage() {
@ -37,7 +37,7 @@ usage() {
while [ "$#" -ge 1 ]; do echo "$1"; shift; done while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE cat<<USAGE
Usage: ${0##*/} [OPTION] [PARAVIEW_OPTION] Usage: ${0##*/} [OPTION] [--] [PARAVIEW_OPTION]
options: options:
-block use blockMesh reader (uses .blockMesh extension) -block use blockMesh reader (uses .blockMesh extension)
-case <dir> specify alternative case directory, default is the cwd -case <dir> specify alternative case directory, default is the cwd
@ -46,10 +46,10 @@ options:
-touchAll create .blockMesh, .OpenFOAM files (and for all regions) -touchAll create .blockMesh, .OpenFOAM files (and for all regions)
-vtk | -builtin use VTK builtin OpenFOAM reader (uses .foam extension) -vtk | -builtin use VTK builtin OpenFOAM reader (uses .foam extension)
-help print the usage -help print the usage
--help paraview help
Paraview options start with a double dashes. Start paraview with the OpenFOAM libraries and reader modules.
Note that paraview options begin with double dashes.
* start paraview with the OpenFOAM libraries
paraview=$(command -v paraview) paraview=$(command -v paraview)
@ -57,12 +57,9 @@ USAGE
exit 1 exit 1
} }
# We want to do nice exit when running paraview to give paraview opportunity # Do a nice exit to give paraview an opportunity to clean up
# to clean up
unset FOAM_ABORT unset FOAM_ABORT
unset regionName optTouch
# Hack: change all locale to 'C' i.e. using '.' for decimal point. This is # 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 # only needed temporarily until paraview is locale aware. (git version is
# already 2010-07) # already 2010-07)
@ -73,18 +70,19 @@ extension=OpenFOAM
plugin=PVFoamReader plugin=PVFoamReader
# Parse options # Parse options
unset regionName optTouch
while [ "$#" -gt 0 ] while [ "$#" -gt 0 ]
do do
case "$1" in case "$1" in
-h | -help) -h | -help)
usage usage
;; ;;
-block | -blockMesh) -block*)
extension=blockMesh extension=blockMesh
plugin=PVblockMeshReader plugin=PVblockMeshReader
shift shift
;; ;;
-builtin | -vtk) -vtk | -built*)
extension=foam extension=foam
unset plugin unset plugin
shift shift
@ -113,6 +111,11 @@ do
shift shift
break # Stop here, treat balance as paraview options 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 break # Stop here, treat this and balance as paraview options
;; ;;
@ -253,6 +256,8 @@ then
# Has --data=.., send directly to paraview # Has --data=.., send directly to paraview
exec paraview "$@" exec paraview "$@"
echo "Error: could not exec paraview" 1>&2
exit 1 # This should not have happened
else else

View File

@ -52,7 +52,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# USER EDITABLE PART: Changes made here may be lost with the next upgrade # 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 setenv ParaView_MAJOR detect # Automatically determine major version
set cmake_version=cmake-system set cmake_version=cmake-system

View File

@ -2563,8 +2563,8 @@ _of_foamToVTK()
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}" 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 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 -pointSet -region -roots -time " local optsWithArgs="-case -cellSet -decomposeParDict -excludePatches -faceSet -fields -name -pointSet -region -roots -time "
case ${prev} in case ${prev} in
-case) -case)

View File

@ -55,7 +55,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# USER EDITABLE PART: Changes made here may be lost with the next upgrade # 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 ParaView_MAJOR=detect # Automatically determine major version
cmake_version=cmake-system cmake_version=cmake-system

View File

@ -24,7 +24,13 @@ starcd/STARCDMeshWriter.C
polyDualMesh/polyDualMesh.C polyDualMesh/polyDualMesh.C
vtk/part/foamVtkCells.C vtk/output/foamVtkInternalWriter.H
vtk/output/foamVtkOutput.C 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 LIB = $(FOAM_LIBBIN)/libconversion

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -22,48 +22,78 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::surfaceMeshWriter Foam::vtk::surfaceMeshWriter
Description Description
Write faces with fields Write faces with fields
SourceFiles SourceFiles
surfaceMeshWriter.C foamVtkSurfaceMeshWriter.C
surfaceMeshWriterTemplates.C foamVtkSurfaceMeshWriterTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef surfaceMeshWriter_H #ifndef foamVtkSurfaceMeshWriter_H
#define surfaceMeshWriter_H #define foamVtkSurfaceMeshWriter_H
#include "pointMesh.H" #include "pointMesh.H"
#include "OFstream.H" #include "OFstream.H"
#include "volFields.H" #include "volFields.H"
#include "surfaceFields.H" #include "surfaceFields.H"
#include "indirectPrimitivePatch.H" #include "indirectPrimitivePatch.H"
#include "foamVtkOutputOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
class volPointInterpolation; class volPointInterpolation;
namespace vtk
{
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class surfaceMeshWriter Declaration Class surfaceMeshWriter Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class surfaceMeshWriter class surfaceMeshWriter
{ {
const bool binary_; // Private Member Data
const indirectPrimitivePatch& pp_; const indirectPrimitivePatch& pp_;
const fileName fName_; //- Commonly used query
const bool legacy_;
autoPtr<vtk::formatter> format_;
std::ofstream os_; std::ofstream os_;
// Private Member Functions
//- Begin piece
void beginPiece();
//- Write patch points
void writePoints();
//- Write patch faces
void writePolysLegacy();
//- Write patch faces
void writePolys();
//- Write mesh topology
void writeMesh();
//- Disallow default bitwise copy construct
surfaceMeshWriter(const surfaceMeshWriter&) = delete;
//- Disallow default bitwise assignment
void operator=(const surfaceMeshWriter&) = delete;
public: public:
// Constructors // Constructors
@ -71,47 +101,81 @@ public:
//- Construct from components //- Construct from components
surfaceMeshWriter surfaceMeshWriter
( (
const bool binary,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const word& name, const word& name,
const fileName& const fileName& baseName,
const vtk::outputOptions outOpts
); );
//- Destructor
~surfaceMeshWriter();
// Member Functions // Member Functions
std::ofstream& os() inline std::ofstream& os()
{ {
return 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> template<class Type>
tmp<Field<Type>> getFaceField tmp<Field<Type>> getFaceField
( (
const GeometricField<Type, fvsPatchField, surfaceMesh>& const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
) const; ) 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> template<class Type>
void write void write
( (
const UPtrList const UPtrList
< <
const GeometricField<Type, fvsPatchField, surfaceMesh> const GeometricField<Type, fvsPatchField, surfaceMesh>
>& >& sflds
); );
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace vtk
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "surfaceMeshWriterTemplates.C" #include "foamVtkSurfaceMeshWriterTemplates.C"
#endif #endif

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,14 +23,13 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "surfaceMeshWriter.H" #include "foamVtkSurfaceMeshWriter.H"
#include "writeFuns.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::surfaceMeshWriter::getFaceField Foam::vtk::surfaceMeshWriter::getFaceField
( (
const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
) const ) const
@ -42,9 +41,8 @@ Foam::surfaceMeshWriter::getFaceField
forAll(pp_.addressing(), i) forAll(pp_.addressing(), i)
{ {
label facei = pp_.addressing()[i]; const label facei = pp_.addressing()[i];
const label patchi = patches.whichPatch(facei);
label patchi = patches.whichPatch(facei);
if (patchi == -1) if (patchi == -1)
{ {
@ -52,7 +50,7 @@ Foam::surfaceMeshWriter::getFaceField
} }
else else
{ {
label localFacei = facei - patches[patchi].start(); const label localFacei = facei - patches[patchi].start();
fld[i] = sfld.boundaryField()[patchi][localFacei]; fld[i] = sfld.boundaryField()[patchi][localFacei];
} }
} }
@ -62,7 +60,38 @@ Foam::surfaceMeshWriter::getFaceField
template<class Type> 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 const UPtrList
< <
@ -70,18 +99,9 @@ void Foam::surfaceMeshWriter::write
>& sflds >& sflds
) )
{ {
forAll(sflds, fieldi) for (const auto& field : sflds)
{ {
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld = write(field);
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);
} }
} }

View File

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

View File

@ -21,38 +21,42 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InClass InNamespace
Foam::writeSurfFields Foam::vtk
Description Description
Write a patch with its data. Write surface fields as vectors
SourceFiles SourceFiles
writeSurfFields.C foamVtkWriteSurfFields.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef writeSurfFields_H #ifndef foamVtkWriteSurfFields_H
#define writeSurfFields_H #define foamVtkWriteSurfFields_H
#include "fvMesh.H" #include "fvMesh.H"
#include "surfaceMesh.H" #include "surfaceMesh.H"
#include "surfaceFieldsFwd.H" #include "surfaceFieldsFwd.H"
#include "foamVtkOutputOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace vtk
{
// Write surface vector fields //- Write surface vector fields
void writeSurfFields void writeSurfFields
( (
const bool binary, const fvMesh& mesh,
const fvMesh&, const fileName& baseName,
const fileName& fileName, const vtk::outputOptions outOpts,
const UPtrList<const surfaceVectorField>& surfVectorFields const UPtrList<const surfaceVectorField>& surfVectorFields
); );
} // End namespace vtk
} // End namespace Foam } // End namespace Foam

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd. \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,33 +23,21 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
inline bool Foam::foamVtkOutputOptions::legacy() const #include "foamVtkMeshMaps.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::foamVtkMeshMaps::renumberCells(const UList<label>& mapping)
{ {
return (type_ & LEGACY); inplaceRenumber(mapping, cellMap_);
inplaceRenumber(mapping, additionalIds_);
} }
inline bool Foam::foamVtkOutputOptions::xml() const void Foam::foamVtkMeshMaps::renumberPoints(const UList<label>& mapping)
{ {
return !legacy(); inplaceRenumber(mapping, pointMap_);
}
inline bool Foam::foamVtkOutputOptions::append() const
{
return (type_ & APPEND);
}
inline bool Foam::foamVtkOutputOptions::insitu() const
{
return !(type_ & APPEND);
}
inline bool Foam::foamVtkOutputOptions::ascii() const
{
return !(type_ & (BINARY | BASE64));
} }

View File

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

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,56 +23,73 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "surfaceMeshWriter.H" #include "foamVtkMeshMaps.H"
#include "writeFuns.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceMeshWriter::surfaceMeshWriter inline Foam::foamVtkMeshMaps::foamVtkMeshMaps(const label size)
(
const bool binary,
const indirectPrimitivePatch& pp,
const word& name,
const fileName& fName
)
: :
binary_(binary), cellMap_(size),
pp_(pp), pointMap_(size),
fName_(fName), additionalIds_(size)
os_(fName.c_str()) {}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
inline Foam::foamVtkMeshMaps::~foamVtkMeshMaps()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline void Foam::foamVtkMeshMaps::clear()
{ {
// Write header cellMap_.clear();
writeFuns::writeHeader(os_, binary_, name); pointMap_.clear();
additionalIds_.clear();
os_ << "DATASET POLYDATA" << std::endl; }
// Write topology
label nFaceVerts = 0;
forAll(pp, facei)
{
nFaceVerts += pp[facei].size() + 1;
}
os_ << "POINTS " << pp.nPoints() << " float" << std::endl;
DynamicList<floatScalar> ptField(3*pp.nPoints());
writeFuns::insert(pp.localPoints(), ptField);
writeFuns::write(os_, binary, ptField);
os_ << "POLYGONS " << pp.size() << ' ' << nFaceVerts << std::endl; inline const Foam::labelList&
Foam::foamVtkMeshMaps::cellMap() const
{
return cellMap_;
}
DynamicList<label> vertLabels(nFaceVerts);
forAll(pp, facei) inline Foam::DynamicList<Foam::label>&
{ Foam::foamVtkMeshMaps::cellMap()
const face& f = pp.localFaces()[facei]; {
return cellMap_;
}
vertLabels.append(f.size());
writeFuns::insert(f, vertLabels); inline const Foam::labelList&
} Foam::foamVtkMeshMaps::pointMap() const
writeFuns::write(os_, binary_, vertLabels); {
return pointMap_;
}
inline Foam::DynamicList<Foam::label>&
Foam::foamVtkMeshMaps::pointMap()
{
return pointMap_;
}
inline const Foam::labelList&
Foam::foamVtkMeshMaps::additionalIds() const
{
return additionalIds_;
}
inline Foam::DynamicList<Foam::label>&
Foam::foamVtkMeshMaps::additionalIds()
{
return additionalIds_;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More