This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
2010-08-26 15:22:03 +01:00

363 lines
10 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/
#include "vtkPV3Foam.H"
// Foam includes
#include "fvMesh.H"
#include "cellModeller.H"
#include "vtkPV3FoamPoints.H"
// VTK includes
#include "vtkCellArray.h"
#include "vtkUnstructuredGrid.h"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
(
const fvMesh& mesh,
polyDecomp& decompInfo
)
{
vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();
if (debug)
{
Info<< "<beg> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
printMemory();
}
// 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;
labelList& superCells = decompInfo.superCells();
labelList& addPointCellLabels = decompInfo.addPointCellLabels();
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"));
// Scan for cells which need to be decomposed and count additional points
// and cells
if (debug)
{
Info<< "... building cell-shapes" << endl;
}
const cellShapeList& cellShapes = mesh.cellShapes();
if (debug)
{
Info<< "... scanning" << endl;
}
forAll(cellShapes, cellI)
{
const cellModel& model = cellShapes[cellI].model();
if
(
model != hex
&& model != wedge
&& model != prism
&& model != pyr
&& model != tet
&& model != tetWedge
)
{
const cell& cFaces = mesh.cells()[cellI];
forAll(cFaces, cFaceI)
{
const face& f = mesh.faces()[cFaces[cFaceI]];
label nFacePoints = f.size();
label nQuads = (nFacePoints - 2)/2;
label nTris = (nFacePoints - 2)%2;
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)
if (debug)
{
Info<<" mesh nCells = " << mesh.nCells() << nl
<<" nPoints = " << mesh.nPoints() << nl
<<" nAddCells = " << nAddCells << nl
<<" nAddPoints = " << nAddPoints << endl;
}
superCells.setSize(mesh.nCells() + nAddCells);
if (debug)
{
Info<< "... converting points" << endl;
}
// Convert Foam mesh vertices to VTK
vtkPoints *vtkpoints = vtkPoints::New();
vtkpoints->Allocate( mesh.nPoints() + nAddPoints );
const Foam::pointField& points = mesh.points();
forAll(points, i)
{
vtkPV3FoamInsertNextPoint(vtkpoints, points[i]);
}
if (debug)
{
Info<< "... converting cells" << endl;
}
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 Foam to VTK
// data types - max 'order' = hex = 8 points
vtkIdType nodeIds[8];
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,
4,
nodeIds
);
}
else if (cellModel == pyr)
{
for (int j = 0; j < 5; j++)
{
nodeIds[j] = cellShape[j];
}
vtkmesh->InsertNextCell
(
VTK_PYRAMID,
5,
nodeIds
);
}
else if (cellModel == prism)
{
for (int j = 0; j < 6; j++)
{
nodeIds[j] = cellShape[j];
}
vtkmesh->InsertNextCell
(
VTK_WEDGE,
6,
nodeIds
);
}
else if (cellModel == tetWedge)
{
// Treat as squeezed prism
nodeIds[0] = cellShape[0];
nodeIds[1] = cellShape[2];
nodeIds[2] = cellShape[1];
nodeIds[3] = cellShape[3];
nodeIds[4] = cellShape[4];
nodeIds[5] = cellShape[4];
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
{
// Polyhedral cell. Decompose into tets + prisms.
// Mapping from additional point to cell
addPointCellLabels[addPointI] = cellI;
// Insert the new vertex from the cell-centre
label newVertexLabel = mesh.nPoints() + addPointI;
vtkPV3FoamInsertNextPoint(vtkpoints, mesh.C()[cellI]);
// 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]];
label nFacePoints = f.size();
label nQuads = (nFacePoints - 2)/2;
label nTris = (nFacePoints - 2)%2;
label qpi = 0;
for (label quadi=0; quadi<nQuads; quadi++)
{
label thisCellI = -1;
if (substituteCell)
{
thisCellI = cellI;
substituteCell = false;
}
else
{
thisCellI = mesh.nCells() + addCellI;
superCells[addCellI++] = cellI;
}
nodeIds[0] = f[0];
nodeIds[1] = f[qpi + 1];
nodeIds[2] = f[qpi + 2];
nodeIds[3] = f[qpi + 3];
nodeIds[4] = newVertexLabel;
vtkmesh->InsertNextCell
(
VTK_PYRAMID,
5,
nodeIds
);
qpi += 2;
}
if (nTris)
{
label thisCellI = -1;
if (substituteCell)
{
thisCellI = cellI;
substituteCell = false;
}
else
{
thisCellI = mesh.nCells() + addCellI;
superCells[addCellI++] = cellI;
}
nodeIds[0] = f[0];
nodeIds[1] = f[qpi + 1];
nodeIds[2] = f[qpi + 2];
nodeIds[3] = newVertexLabel;
vtkmesh->InsertNextCell
(
VTK_TETRA,
4,
nodeIds
);
}
}
addPointI++;
}
}
vtkmesh->SetPoints(vtkpoints);
vtkpoints->Delete();
if (debug)
{
Info<< "<end> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
printMemory();
}
return vtkmesh;
}
// ************************************************************************* //