ENH: adjust wrapping routines for new vtkCellArray definition

- the vtkCellArray internal structure was still largely oriented on
  the VTK legacy format, but has now been revised.
  https://gitlab.kitware.com/vtk/vtk/merge_requests/5682

  The `VTK_CELL_ARRAY_V2` define from vtkCellArray.h indicates
  that the newer version is being used.

* In VTK-8.2.0 and older, sizes are interwoven (prefixed) in the
  connectivity.

  Connectivity: [n1, verts..., n2, verts... ]

  When using these in vtkUnstructuredGrid, also needed a secondary
  list of offsets for each of the starting locations.

* The update version now resembles a CompactListList. For example

  Connectivity: [verts..., verts... ]
  Offsets:      [0, n1, n1+n2, n1+n2+n3... ]

  The offsets are properly handled within vtkCellArray, and dropped as
  an additional input for vtkUnstructuredGrid.
This commit is contained in:
Mark Olesen
2020-01-24 13:01:38 +01:00
parent f4ee841c6d
commit 9338f0b860
14 changed files with 648 additions and 461 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -70,8 +70,6 @@ class vtkDataSet;
class vtkCellData; class vtkCellData;
class vtkPointData; class vtkPointData;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace vtk namespace vtk
@ -185,15 +183,6 @@ namespace Tools
const label size const label size
); );
//- Wrap vtkCellArray as a UList
inline UList<vtkIdType> asUList
(
vtkCellArray* cells,
const label nCells,
const label size
);
//- Return a list of points as vtkPoints //- Return a list of points as vtkPoints
inline vtkSmartPointer<vtkPoints> Points inline vtkSmartPointer<vtkPoints> Points
( (

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,6 +25,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include <numeric>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline Foam::UList<uint8_t> Foam::vtk::Tools::asUList inline Foam::UList<uint8_t> Foam::vtk::Tools::asUList
@ -53,19 +55,6 @@ inline Foam::UList<vtkIdType> Foam::vtk::Tools::asUList
} }
inline Foam::UList<vtkIdType> Foam::vtk::Tools::asUList
(
vtkCellArray* cells,
const label nCells,
const label size
)
{
cells->GetData()->SetNumberOfTuples(size);
return UList<vtkIdType>(cells->WritePointer(nCells, size), size);
}
inline vtkSmartPointer<vtkPoints> inline vtkSmartPointer<vtkPoints>
Foam::vtk::Tools::Points(const UList<point>& pts) Foam::vtk::Tools::Points(const UList<point>& pts)
{ {
@ -150,20 +139,72 @@ inline vtkSmartPointer<vtkCellArray> Foam::vtk::Tools::identityVertices
const label size const label size
) )
{ {
// VTK_VERTEX: need 2 values (size=1 and index=id) per vertex
auto cells = vtkSmartPointer<vtkCellArray>::New(); auto cells = vtkSmartPointer<vtkCellArray>::New();
UList<vtkIdType> list = asUList(cells, size, 2*size); #ifdef VTK_CELL_ARRAY_V2
// Offsets
// [0, n1, n1+n2, n1+n2+n3... ]
auto offsets = vtkSmartPointer<vtkIdTypeArray>::New();
{
const vtkIdType nOffsets(size+1);
offsets->SetNumberOfTuples(nOffsets);
vtkIdType* iter = offsets->WritePointer(0, nOffsets);
std::iota(iter, (iter + nOffsets), vtkIdType(0));
}
auto connect = vtkSmartPointer<vtkIdTypeArray>::New();
// Connectivity
{
const vtkIdType nConnect(size);
connect->SetNumberOfTuples(nConnect);
vtkIdType* iter = connect->WritePointer(0, nConnect);
std::iota(iter, (iter + nConnect), vtkIdType(0));
}
// Move into a vtkCellArray
cells->SetData(offsets, connect);
#else
// In VTK-8.2.0 and older,
// sizes are interwoven (prefixed) in the connectivity
// Connectivity size, with prefixed size information
// Cell connectivity for vertex // Cell connectivity for vertex
// [size, ids.., size, ids...] -> therefore [1, id, 1, id, ...] // [size, ids.., size, ids...] -> therefore [1, id, 1, id, ...]
auto iter = list.begin();
for (label id=0; id < size; ++id) const vtkIdType nElem(size);
const vtkIdType nConnect(2*size);
{ {
*(iter++) = 1; cells->GetData()->SetNumberOfTuples(nConnect);
*(iter++) = id;
vtkIdType* iter = cells->WritePointer(nElem, nConnect);
// Fill in the connectivity array, with prefixed size information
for (vtkIdType id = 0; id < nElem; ++id)
{
*(iter++) = 1;
*(iter++) = id;
}
} }
#endif
return cells; return cells;
}; };

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,30 +43,99 @@ template<class Face>
vtkSmartPointer<vtkCellArray> vtkSmartPointer<vtkCellArray>
Foam::vtk::Tools::Faces(const UList<Face>& faces) Foam::vtk::Tools::Faces(const UList<Face>& faces)
{ {
label nAlloc = faces.size(); auto cells = vtkSmartPointer<vtkCellArray>::New();
for (const auto& f : faces)
#ifdef VTK_CELL_ARRAY_V2
// Offsets
// [0, n1, n1+n2, n1+n2+n3... ]
const vtkIdType nOffsets(faces.size()+1);
auto offsets = vtkSmartPointer<vtkIdTypeArray>::New();
vtkIdType nConnect(0);
{ {
nAlloc += f.size(); offsets->SetNumberOfTuples(nOffsets);
}
auto vtkcells = vtkSmartPointer<vtkCellArray>::New(); vtkIdType* iter = offsets->WritePointer(0, nOffsets);
UList<vtkIdType> list = asUList(vtkcells, faces.size(), nAlloc); // Assign offsets, determine overall connectivity size
// Cell connectivity for polygons *iter = 0;
// [size, verts..., size, verts... ] for (const auto& f : faces)
auto iter = list.begin();
for (const auto& f : faces)
{
*(iter++) = f.size();
for (const label verti : f)
{ {
*(iter++) = verti; nConnect += f.size();
*(++iter) = nConnect;
} }
} }
return vtkcells;
// Cell connectivity for polygons
// [verts..., verts... ]
auto connect = vtkSmartPointer<vtkIdTypeArray>::New();
{
connect->SetNumberOfTuples(nConnect);
vtkIdType* iter = connect->WritePointer(0, nConnect);
// Fill in the connectivity array
for (const auto& f : faces)
{
for (const label verti : f)
{
*(iter++) = verti;
}
}
}
// Move into a vtkCellArray
cells->SetData(offsets, connect);
#else
// In VTK-8.2.0 and older,
// sizes are interwoven (prefixed) in the connectivity
// Cell connectivity for polygons
// [n1, verts..., n2, verts... ]
const vtkIdType nElem(faces.size());
// Connectivity size, with prefixed size information
vtkIdType nConnect(faces.size());
for (const auto& f : faces)
{
nConnect += f.size();
}
{
cells->GetData()->SetNumberOfTuples(nConnect);
vtkIdType* iter = cells->WritePointer(nElem, nConnect);
// Fill in the connectivity array, with prefixed size information
for (const auto& f : faces)
{
*(iter++) = f.size();
for (const label verti : f)
{
*(iter++) = verti;
}
}
}
#endif
return cells;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -52,20 +52,15 @@ SourceFiles
#include "foamVtkMeshMaps.H" #include "foamVtkMeshMaps.H"
#include "foamVtuSizing.H" #include "foamVtuSizing.H"
#include "vtkSmartPointer.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkUnstructuredGrid.h" #include "vtkUnstructuredGrid.h"
#include "vtkMultiBlockDataSet.h" #include "vtkMultiBlockDataSet.h"
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class vtkCellArray; // Forward Declarations
class vtkDataSet; class vtkDataSet;
class vtkFloatArray; class vtkFloatArray;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace vtk namespace vtk

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -103,89 +103,127 @@ Foam::vtk::vtuAdaptor::internal
const bool decompPoly const bool decompPoly
) )
{ {
const vtk::vtuSizing::contentType output
(
#ifdef VTK_CELL_ARRAY_V2
vtk::vtuSizing::contentType::INTERNAL2
#else
vtk::vtuSizing::contentType::INTERNAL1
#endif
);
vtk::vtuSizing sizing(mesh, decompPoly); vtk::vtuSizing sizing(mesh, decompPoly);
auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New(); auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New();
UList<uint8_t> cellTypesUL
(
vtk::Tools::asUList(cellTypes, sizing.nFieldCells())
);
auto cells = vtkSmartPointer<vtkCellArray>::New(); auto cells = vtkSmartPointer<vtkCellArray>::New();
auto faces = vtkSmartPointer<vtkIdTypeArray>::New(); auto faces = vtkSmartPointer<vtkIdTypeArray>::New();
auto cellLocations = vtkSmartPointer<vtkIdTypeArray>::New(); auto cellOffsets = vtkSmartPointer<vtkIdTypeArray>::New();
auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New(); auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
UList<uint8_t> cellTypesUL = const auto nConnect
vtk::Tools::asUList(cellTypes, sizing.nFieldCells()); (
sizing.sizeOf(output, vtk::vtuSizing::slotType::CELLS)
);
UList<vtkIdType> cellsUL = UList<vtkIdType> cellOffsetsUL
(
vtk::Tools::asUList vtk::Tools::asUList
( (
cells, cellOffsets,
sizing.nFieldCells(), sizing.sizeOf(output, vtk::vtuSizing::slotType::CELLS_OFFSETS)
sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS) )
); );
UList<vtkIdType> cellLocationsUL = #ifdef VTK_CELL_ARRAY_V2
vtk::Tools::asUList
(
cellLocations,
sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS_OFFSETS)
);
UList<vtkIdType> facesUL = auto cellConnect = vtkSmartPointer<vtkIdTypeArray>::New();
UList<vtkIdType> cellsUL
(
vtk::Tools::asUList(cellConnect, nConnect)
);
#else
cells->GetData()->SetNumberOfTuples(sizing.nFieldCells());
UList<vtkIdType> cellsUL
(
cells->WritePointer(sizing.nFieldCells(), nConnect),
nConnect
);
#endif
UList<vtkIdType> facesUL
(
vtk::Tools::asUList vtk::Tools::asUList
( (
faces, faces,
sizing.sizeInternal(vtk::vtuSizing::slotType::FACES) sizing.sizeOf(output, vtk::vtuSizing::slotType::FACES)
); )
);
UList<vtkIdType> faceLocationsUL = UList<vtkIdType> faceLocationsUL
(
vtk::Tools::asUList vtk::Tools::asUList
( (
faceLocations, faceLocations,
sizing.sizeInternal(vtk::vtuSizing::slotType::FACES_OFFSETS) sizing.sizeOf(output, vtk::vtuSizing::slotType::FACES_OFFSETS)
); )
);
sizing.populateInternal sizing.populateInternal
( (
mesh, mesh,
cellTypesUL, cellTypesUL,
cellsUL, cellsUL, cellOffsetsUL,
cellLocationsUL, facesUL, faceLocationsUL,
facesUL, static_cast<foamVtkMeshMaps&>(*this),
faceLocationsUL, output
static_cast<foamVtkMeshMaps&>(*this)
); );
auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
// Convert OpenFOAM mesh vertices to VTK // Convert OpenFOAM mesh vertices to VTK
// - can only do this *after* populating the decompInfo with cell-ids // - can only do this *after* populating the decompInfo with cell-ids
// for any additional points (ie, mesh cell-centres) // for any additional points (ie, mesh cell-centres)
vtkmesh->SetPoints(this->points(mesh)); vtkmesh->SetPoints(this->points(mesh));
#ifdef VTK_CELL_ARRAY_V2
// Move into a vtkCellArray
cells->SetData(cellOffsets, cellConnect);
if (facesUL.size()) if (facesUL.size())
{ {
vtkmesh->SetCells vtkmesh->SetCells(cellTypes, cells, faceLocations, faces);
(
cellTypes,
cellLocations,
cells,
faceLocations,
faces
);
} }
else else
{ {
vtkmesh->SetCells vtkmesh->SetCells(cellTypes, cells, nullptr, nullptr);
(
cellTypes,
cellLocations,
cells,
nullptr,
nullptr
);
} }
#else
if (facesUL.size())
{
vtkmesh->SetCells(cellTypes, cellOffsets, cells, faceLocations, faces);
}
else
{
vtkmesh->SetCells(cellTypes, cellOffsets, cells, nullptr, nullptr);
}
#endif
return vtkmesh; return vtkmesh;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,6 +37,7 @@ Description
for additional points of decomposed cells for additional points of decomposed cells
SourceFiles SourceFiles
foamVtkMeshMaps.C
foamVtkMeshMapsI.H foamVtkMeshMapsI.H
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -74,12 +75,11 @@ public:
// Constructors // Constructors
//- Construct null //- Default construct: zero-sized, no reserved size
inline explicit foamVtkMeshMaps(const label size = 0); inline foamVtkMeshMaps();
//- Construct with reserved size
//- Destructor inline explicit foamVtkMeshMaps(const label size);
~foamVtkMeshMaps() = default;
// Member Functions // Member Functions
@ -92,17 +92,26 @@ public:
// cells this becomes a useful means of mapping from the original mesh. // cells this becomes a useful means of mapping from the original mesh.
inline const labelList& cellMap() const; inline const labelList& cellMap() const;
//- Write access to original cell ids
inline DynamicList<label>& cellMap();
//- Point labels for subsetted meshes //- Point labels for subsetted meshes
inline const labelList& pointMap() const; inline const labelList& pointMap() const;
//- Write access to point labels for subsetted meshes
inline DynamicList<label>& pointMap();
//- Any additional (user) labels. //- Any additional (user) labels.
// Eg, cell-centre labels for additional points of decomposed cells // Eg, cell-centre labels for additional points of decomposed cells
inline const labelList& additionalIds() const; inline const labelList& additionalIds() const;
//- Write access to additional (user) labels.
inline DynamicList<label>& additionalIds();
// Edit // Edit
//- Clear //- Clear sizing
inline void clear(); inline void clear();
//- Renumber cell ids (cellMap and additionalIds) to account for //- Renumber cell ids (cellMap and additionalIds) to account for
@ -111,22 +120,6 @@ public:
//- Renumber point ids (pointMap) to account for subset meshes //- Renumber point ids (pointMap) to account for subset meshes
void renumberPoints(const labelUList& mapping); void renumberPoints(const labelUList& 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();
}; };

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,6 +29,14 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::foamVtkMeshMaps::foamVtkMeshMaps()
:
cellMap_(0),
pointMap_(0),
additionalIds_(0)
{}
inline Foam::foamVtkMeshMaps::foamVtkMeshMaps(const label size) inline Foam::foamVtkMeshMaps::foamVtkMeshMaps(const label size)
: :
cellMap_(size), cellMap_(size),

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -108,15 +108,16 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh)
{ {
// vtuSizing::reset() called prior to this method // vtuSizing::reset() called prior to this method
cellTypes_.setSize(nFieldCells()); cellTypes_.resize(nFieldCells());
vertLabels_.setSize(sizeOf(output_, slotType::CELLS)); vertLabels_.resize(sizeOf(output_, slotType::CELLS));
vertOffset_.setSize(sizeOf(output_, slotType::CELLS_OFFSETS)); vertOffset_.resize(sizeOf(output_, slotType::CELLS_OFFSETS));
faceLabels_.setSize(sizeOf(output_, slotType::FACES)); faceLabels_.resize(sizeOf(output_, slotType::FACES));
faceOffset_.setSize(sizeOf(output_, slotType::FACES_OFFSETS)); faceOffset_.resize(sizeOf(output_, slotType::FACES_OFFSETS));
switch (output_) switch (output_)
{ {
case contentType::LEGACY: case contentType::LEGACY:
{
populateLegacy populateLegacy
( (
mesh, mesh,
@ -125,7 +126,10 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh)
maps_ maps_
); );
break; break;
}
case contentType::XML: case contentType::XML:
{
populateXml populateXml
( (
mesh, mesh,
@ -137,7 +141,11 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh)
maps_ maps_
); );
break; break;
case contentType::INTERNAL: }
case contentType::INTERNAL1:
case contentType::INTERNAL2:
{
populateInternal populateInternal
( (
mesh, mesh,
@ -146,9 +154,11 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh)
vertOffset_, vertOffset_,
faceLabels_, faceLabels_,
faceOffset_, faceOffset_,
maps_ maps_,
output_
); );
break; break;
}
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2019 OpenCFD Ltd. Copyright (C) 2014-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -52,7 +52,6 @@ SourceFiles
#include "foamVtkCore.H" #include "foamVtkCore.H"
#include "foamVtkMeshMaps.H" #include "foamVtkMeshMaps.H"
#include "foamVtuSizing.H" #include "foamVtuSizing.H"
#include "DynamicList.H"
#include "labelList.H" #include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -60,12 +59,12 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class polyMesh; class polyMesh;
namespace vtk namespace vtk
{ {
// Forward declarations // Forward Declarations
class outputOptions; class outputOptions;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -76,7 +75,7 @@ class vtuCells
: :
public vtuSizing public vtuSizing
{ {
// Private Member Data // Private Data
// Requested output types // Requested output types
@ -112,7 +111,7 @@ class vtuCells
// Private Member Functions // Private Member Functions
//- Create the geometry using the previously requested output and //- Create the geometry using the previously requested output and
// decomposition types. //- decomposition types.
void repopulate(const polyMesh& mesh); void repopulate(const polyMesh& mesh);
//- No copy construct //- No copy construct
@ -126,17 +125,15 @@ public:
// Constructors // Constructors
//- Construct from components. //- Default construct (XML format, no polyhedral decomposition)
// Optionally with polyhedral decomposition. explicit vtuCells
vtuCells
( (
const enum contentType output = contentType::XML, const enum contentType output = contentType::XML,
const bool decompose = false const bool decompose = false
); );
//- Construct from components and create the output information //- Construct from components, create output information immediately
//- immediately explicit vtuCells
vtuCells
( (
const polyMesh& mesh, const polyMesh& mesh,
const enum contentType output = contentType::XML, const enum contentType output = contentType::XML,
@ -145,14 +142,13 @@ public:
//- Construct from components. //- Construct from components.
// Optionally with polyhedral decomposition. // Optionally with polyhedral decomposition.
vtuCells explicit vtuCells
( (
const vtk::outputOptions opts, const vtk::outputOptions opts,
const bool decompose = false const bool decompose = false
); );
//- Construct from components, and create the output information //- Construct from components, create output information immediately
//- immediately
vtuCells vtuCells
( (
const polyMesh& mesh, const polyMesh& mesh,
@ -161,10 +157,6 @@ public:
); );
//- Destructor
~vtuCells() = default;
// Member Functions // Member Functions
// Access // Access
@ -229,7 +221,6 @@ public:
//- Original cell ids for all cells (regular and decomposed). //- Original cell ids for all cells (regular and decomposed).
inline const labelList& cellMap() const; inline const labelList& cellMap() const;
}; };

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,7 +29,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline enum Foam::vtk::vtuCells::contentType inline enum Foam::vtk::vtuCells::contentType
Foam::vtk::vtuCells::content() const Foam::vtk::vtuCells::content() const
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,14 +37,14 @@ License
void Foam::vtk::vtuSizing::presizeMaps(foamVtkMeshMaps& maps) const void Foam::vtk::vtuSizing::presizeMaps(foamVtkMeshMaps& maps) const
{ {
maps.cellMap().setSize(this->nFieldCells()); maps.cellMap().resize(this->nFieldCells());
maps.additionalIds().setSize(this->nAddPoints()); maps.additionalIds().resize(this->nAddPoints());
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::vtk::vtuSizing::vtuSizing() Foam::vtk::vtuSizing::vtuSizing() noexcept
{ {
clear(); clear();
} }
@ -63,7 +63,7 @@ Foam::vtk::vtuSizing::vtuSizing
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtk::vtuSizing::clear() void Foam::vtk::vtuSizing::clear() noexcept
{ {
decompose_ = false; decompose_ = false;
nCells_ = 0; nCells_ = 0;
@ -232,6 +232,7 @@ Foam::label Foam::vtk::vtuSizing::sizeOf
} }
break; break;
} }
case contentType::XML: case contentType::XML:
{ {
switch (slot) switch (slot)
@ -254,7 +255,8 @@ Foam::label Foam::vtk::vtuSizing::sizeOf
} }
break; break;
} }
case contentType::INTERNAL:
case contentType::INTERNAL1:
{ {
switch (slot) switch (slot)
{ {
@ -277,6 +279,29 @@ Foam::label Foam::vtk::vtuSizing::sizeOf
} }
break; break;
} }
case contentType::INTERNAL2:
{
switch (slot)
{
case slotType::CELLS:
return (nVertLabels() + nAddVerts());
break;
case slotType::CELLS_OFFSETS:
return (nFieldCells() + 1);
break;
case slotType::FACES:
return nFaceLabels();
break;
case slotType::FACES_OFFSETS:
return nFaceLabels() ? nFieldCells() : 0;
break;
}
break;
}
} }
return 0; return 0;
@ -343,175 +368,73 @@ void Foam::vtk::vtuSizing::populateXml
} }
void Foam::vtk::vtuSizing::populateInternal #undef definePopulateInternalMethod
( #define definePopulateInternalMethod(Type) \
const polyMesh& mesh, \
UList<uint8_t>& cellTypes, void Foam::vtk::vtuSizing::populateInternal \
UList<int>& connectivity, ( \
UList<int>& offsets, const polyMesh& mesh, \
UList<int>& faces, UList<uint8_t>& cellTypes, \
UList<int>& facesOffsets, UList<Type>& connectivity, \
foamVtkMeshMaps& maps UList<Type>& offsets, \
) const UList<Type>& faces, \
{ UList<Type>& facesOffsets, \
presizeMaps(maps); foamVtkMeshMaps& maps, \
const enum contentType output \
populateArrays ) const \
( { \
mesh, presizeMaps(maps); \
*this, \
cellTypes, populateArrays \
connectivity, ( \
offsets, mesh, \
faces, *this, \
facesOffsets, cellTypes, \
contentType::INTERNAL, connectivity, \
maps.cellMap(), offsets, \
maps.additionalIds() faces, \
); facesOffsets, \
} output, \
maps.cellMap(), \
maps.additionalIds() \
); \
} \
\
void Foam::vtk::vtuSizing::populateInternal \
( \
const polyMesh& mesh, \
UList<uint8_t>& cellTypes, \
UList<Type>& connectivity, \
UList<Type>& offsets, \
UList<Type>& faces, \
UList<Type>& facesOffsets, \
labelUList& cellMap, \
labelUList& addPointsIds, \
const enum contentType output \
) const \
{ \
populateArrays \
( \
mesh, \
*this, \
cellTypes, \
connectivity, \
offsets, \
faces, \
facesOffsets, \
output, \
cellMap, \
addPointsIds \
); \
}
void Foam::vtk::vtuSizing::populateInternal definePopulateInternalMethod(int);
( definePopulateInternalMethod(long);
const polyMesh& mesh, definePopulateInternalMethod(long long);
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 #undef definePopulateInternalMethod
(
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,
labelUList& cellMap,
labelUList& 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,
labelUList& cellMap,
labelUList& 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,
labelUList& cellMap,
labelUList& addPointsIds
) const
{
populateArrays
(
mesh,
*this,
cellTypes,
connectivity,
offsets,
faces,
facesOffsets,
contentType::INTERNAL,
cellMap,
addPointsIds
);
}
// * * * * * * * * * * * * * * Renumber vertices * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Renumber vertices * * * * * * * * * * * * * * //
@ -559,7 +482,7 @@ void Foam::vtk::vtuSizing::renumberVertLabelsLegacy
// Therefore anything with 18 labels or more must be a poly // Therefore anything with 18 labels or more must be a poly
auto iter = vertLabels.begin(); auto iter = vertLabels.begin();
auto last = vertLabels.end(); const auto last = vertLabels.end();
while (iter < last) while (iter < last)
{ {
@ -671,7 +594,7 @@ void Foam::vtk::vtuSizing::renumberFaceLabelsXml
// [nFaces, nFace0Pts, id1,id2,..., nFace1Pts, id1,id2,...] // [nFaces, nFace0Pts, id1,id2,..., nFace1Pts, id1,id2,...]
auto iter = faceLabels.begin(); auto iter = faceLabels.begin();
auto last = faceLabels.end(); const auto last = faceLabels.end();
while (iter < last) while (iter < last)
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -66,7 +66,7 @@ Description
\endtable \endtable
\table \table
internal storage internal1 storage (VTK-8 and earlier)
\c types | vtk cell type (1-255) \c types | vtk cell type (1-255)
\c connectivity | nLabels and unique vertex labels used by the cell \c connectivity | nLabels and unique vertex labels used by the cell
\c location | begin location for each of \c connectivity \c location | begin location for each of \c connectivity
@ -75,6 +75,16 @@ Description
\c facelocation | begin location for each of \c faces, with -1 for primitive cells \c facelocation | begin location for each of \c faces, with -1 for primitive cells
\endtable \endtable
\table
internal2 storage (with VTK_CELL_ARRAY_V2)
\c types | vtk cell type (1-255)
\c connectivity | unique vertex labels used by the cell
\c offsets | begin/end offsets for \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 The VTK storage concept for "connectivity" and "faces" somewhat resemble
a CompactListList. a CompactListList.
@ -85,6 +95,10 @@ Note
since it likely more efficient to use VTK point-blanking to mark duplicate since it likely more efficient to use VTK point-blanking to mark duplicate
points instead of merging points ourselves. points instead of merging points ourselves.
Note
The VTK_CELL_ARRAY_V2 define (from vtkCellArray.h) indicates if the new
(internal2) new format is being used.
SourceFiles SourceFiles
foamVtuSizing.C foamVtuSizing.C
foamVtuSizingI.H foamVtuSizingI.H
@ -103,7 +117,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class polyMesh; class polyMesh;
namespace vtk namespace vtk
@ -117,23 +131,25 @@ class vtuSizing
{ {
public: public:
// Public data // Public Data
//- Types of content that the storage may represent //- Types of content that the storage may represent
enum contentType enum contentType
{ {
LEGACY, //!< Legacy VTK content LEGACY, //!< Legacy VTK content
XML, //!< XML (VTU) content XML, //!< XML (VTU) content
INTERNAL //!< Internal vtkUnstructuredGrid content INTERNAL1, //!< Internal vtkUnstructuredGrid content
INTERNAL2 //!< Internal vtkUnstructuredGrid content, VTK_CELL_ARRAY_V2
}; };
//- The possible storage 'slots' that can be used //- The possible storage 'slots' that can be used
enum slotType enum slotType
{ {
CELLS, //!< Cell connectivity (ALL) CELLS, //!< Cell connectivity (ALL)
CELLS_OFFSETS, //!< End-offsets (XML) or locations (INTERNAL) for cells CELLS_OFFSETS, //!< Cell end-offsets (XML), locations (INTERNAL1)
//!< or begin/end offsets (INTERNAL2)
FACES, //!< Face-stream (XML, INTERNAL) FACES, //!< Face-stream (XML, INTERNAL)
FACES_OFFSETS //!< End-offsets (XML) or locations (INTERNAL) for faces FACES_OFFSETS //!< Faces end-offsets (XML) or locations (INTERNAL1)
}; };
@ -153,6 +169,7 @@ private:
//- Number of vertex labels to represent the mesh //- Number of vertex labels to represent the mesh
label nVertLabels_; label nVertLabels_;
// Polyhedrals // Polyhedrals
//- Number of polyhedral face labels for the mesh //- Number of polyhedral face labels for the mesh
@ -164,6 +181,7 @@ private:
//- Number of vertex labels used by polyhedrals //- Number of vertex labels used by polyhedrals
label nVertPoly_; label nVertPoly_;
// Decomposed polyhedrals // Decomposed polyhedrals
//- Number of additional (decomposed) cells for the mesh //- Number of additional (decomposed) cells for the mesh
@ -202,8 +220,8 @@ public:
// Constructors // Constructors
//- Construct null. //- Default construct
vtuSizing(); vtuSizing() noexcept;
//- Construct sizing by analyzing the mesh. //- Construct sizing by analyzing the mesh.
// No polyhedral decomposition. // No polyhedral decomposition.
@ -214,10 +232,6 @@ public:
vtuSizing(const polyMesh& mesh, const bool decompose); vtuSizing(const polyMesh& mesh, const bool decompose);
//- Destructor
~vtuSizing() = default;
// Member Functions // Member Functions
// Edit // Edit
@ -227,7 +241,7 @@ public:
void reset(const polyMesh& mesh, const bool decompose=false); void reset(const polyMesh& mesh, const bool decompose=false);
//- Reset all sizes to zero. //- Reset all sizes to zero.
void clear(); void clear() noexcept;
// Access // Access
@ -290,7 +304,10 @@ public:
inline label sizeXml(const enum slotType slot) const; inline label sizeXml(const enum slotType slot) const;
//- The calculated size for vtk-internal storage of the specified slot //- The calculated size for vtk-internal storage of the specified slot
inline label sizeInternal(const enum slotType slot) const; inline label sizeInternal1(const enum slotType slot) const;
//- The calculated size for vtk-internal storage of the specified slot
inline label sizeInternal2(const enum slotType slot) const;
// Routines for populating the output lists // Routines for populating the output lists
@ -316,80 +333,45 @@ public:
foamVtkMeshMaps& maps foamVtkMeshMaps& maps
) const; ) 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 // Internal types. The size of vtkIdType is unknown here
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 #undef declarePopulateInternalMethod
void populateInternal #define declarePopulateInternalMethod(Type) \
( \
const polyMesh& mesh, /*! Populate lists for Internal VTK format */ \
UList<uint8_t>& cellTypes, void populateInternal \
UList<long long>& connectivity, ( \
UList<long long>& offsets, const polyMesh& mesh, \
UList<long long>& faces, UList<uint8_t>& cellTypes, \
UList<long long>& facesOffsets, UList<Type>& connectivity, \
foamVtkMeshMaps& maps UList<Type>& offsets, \
) const; UList<Type>& faces, \
UList<Type>& facesOffsets, \
foamVtkMeshMaps& maps, \
const enum contentType output \
) const; \
\
/*! Populate lists for Internal VTK format */ \
void populateInternal \
( \
const polyMesh& mesh, \
UList<uint8_t>& cellTypes, \
UList<Type>& connectivity, \
UList<Type>& offsets, \
UList<Type>& faces, \
UList<Type>& facesOffsets, \
labelUList& cellMap, \
labelUList& addPointsIds, \
const enum contentType output \
) 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,
labelUList& cellMap,
labelUList& addPointsIds
) const;
//- Populate lists for Internal VTK format declarePopulateInternalMethod(int);
void populateInternal declarePopulateInternalMethod(long);
( declarePopulateInternalMethod(long long);
const polyMesh& mesh,
UList<uint8_t>& cellTypes,
UList<long>& connectivity,
UList<long>& offsets,
UList<long>& faces,
UList<long>& facesOffsets,
labelUList& cellMap,
labelUList& addPointsIds
) const;
//- Populate lists for Internal VTK format #undef declarePopulateInternalMethod
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,
labelUList& cellMap,
labelUList& addPointsIds
) const;
// Routines for renumber vertices with a global point offset // Routines for renumber vertices with a global point offset
@ -465,7 +447,6 @@ public:
//- Test inequality //- Test inequality
bool operator!=(const vtuSizing& rhs) const; bool operator!=(const vtuSizing& rhs) const;
}; };

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -125,12 +125,21 @@ inline Foam::label Foam::vtk::vtuSizing::sizeXml
} }
inline Foam::label Foam::vtk::vtuSizing::sizeInternal inline Foam::label Foam::vtk::vtuSizing::sizeInternal1
( (
const enum slotType slot const enum slotType slot
) const ) const
{ {
return sizeOf(contentType::INTERNAL, slot); return sizeOf(contentType::INTERNAL1, slot);
}
inline Foam::label Foam::vtk::vtuSizing::sizeInternal2
(
const enum slotType slot
) const
{
return sizeOf(contentType::INTERNAL2, slot);
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,6 +47,17 @@ void Foam::vtk::vtuSizing::populateArrays
UList<LabelType2>& addPointsIds UList<LabelType2>& addPointsIds
) )
{ {
// Characteristics
// Are vertLabels prefixed with the size?
// Also use as the size of the prefixed information
const int prefix =
(
output == contentType::LEGACY
|| output == contentType::INTERNAL1
) ? 1 : 0;
// STAGE 1: Verify storage sizes // STAGE 1: Verify storage sizes
if (cellTypes.size() != sizing.nFieldCells()) if (cellTypes.size() != sizing.nFieldCells())
@ -73,10 +84,6 @@ void Foam::vtk::vtuSizing::populateArrays
<< exit(FatalError); << 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) switch (output)
{ {
case contentType::LEGACY: case contentType::LEGACY:
@ -90,6 +97,7 @@ void Foam::vtk::vtuSizing::populateArrays
} }
break; break;
} }
case contentType::XML: case contentType::XML:
{ {
// XML uses connectivity/offset pair. // XML uses connectivity/offset pair.
@ -149,32 +157,33 @@ void Foam::vtk::vtuSizing::populateArrays
} }
break; break;
} }
case contentType::INTERNAL:
case contentType::INTERNAL1:
{ {
// VTK-internal connectivity/offset pair. // VTK-internal1 connectivity/offset pair.
if if
( (
vertLabels.size() vertLabels.size()
!= sizing.sizeInternal(slotType::CELLS) != sizing.sizeInternal1(slotType::CELLS)
) )
{ {
FatalErrorInFunction FatalErrorInFunction
<< " connectivity size=" << vertLabels.size() << " connectivity size=" << vertLabels.size()
<< " expected " << " expected "
<< sizing.sizeInternal(slotType::CELLS) << sizing.sizeInternal1(slotType::CELLS)
<< exit(FatalError); << exit(FatalError);
} }
if if
( (
vertOffset.size() vertOffset.size()
!= sizing.sizeInternal(slotType::CELLS_OFFSETS) != sizing.sizeInternal1(slotType::CELLS_OFFSETS)
) )
{ {
FatalErrorInFunction FatalErrorInFunction
<< " offsets size=" << vertOffset.size() << " offsets size=" << vertOffset.size()
<< " expected " << " expected "
<< sizing.sizeInternal(slotType::CELLS_OFFSETS) << sizing.sizeInternal1(slotType::CELLS_OFFSETS)
<< exit(FatalError); << exit(FatalError);
} }
@ -183,26 +192,86 @@ void Foam::vtk::vtuSizing::populateArrays
if if
( (
faceLabels.size() faceLabels.size()
!= sizing.sizeInternal(slotType::FACES) != sizing.sizeInternal1(slotType::FACES)
) )
{ {
FatalErrorInFunction FatalErrorInFunction
<< " faces size=" << faceLabels.size() << " faces size=" << faceLabels.size()
<< " expected " << " expected "
<< sizing.sizeInternal(slotType::FACES) << sizing.sizeInternal1(slotType::FACES)
<< exit(FatalError); << exit(FatalError);
} }
if if
( (
faceOffset.size() faceOffset.size()
!= sizing.sizeInternal(slotType::FACES_OFFSETS) != sizing.sizeInternal1(slotType::FACES_OFFSETS)
) )
{ {
FatalErrorInFunction FatalErrorInFunction
<< " facesOffsets size=" << faceOffset.size() << " facesOffsets size=" << faceOffset.size()
<< " expected " << " expected "
<< sizing.sizeInternal(slotType::FACES_OFFSETS) << sizing.sizeInternal1(slotType::FACES_OFFSETS)
<< exit(FatalError);
}
}
break;
}
case contentType::INTERNAL2:
{
// VTK-internal2 connectivity/offset pair.
if
(
vertLabels.size()
!= sizing.sizeInternal2(slotType::CELLS)
)
{
FatalErrorInFunction
<< " connectivity size=" << vertLabels.size()
<< " expected "
<< sizing.sizeInternal2(slotType::CELLS)
<< exit(FatalError);
}
if
(
vertOffset.size()
!= sizing.sizeInternal2(slotType::CELLS_OFFSETS)
)
{
FatalErrorInFunction
<< " offsets size=" << vertOffset.size()
<< " expected "
<< sizing.sizeInternal2(slotType::CELLS_OFFSETS)
<< exit(FatalError);
}
if (sizing.nFaceLabels())
{
if
(
faceLabels.size()
!= sizing.sizeInternal2(slotType::FACES)
)
{
FatalErrorInFunction
<< " faces size=" << faceLabels.size()
<< " expected "
<< sizing.sizeInternal2(slotType::FACES)
<< exit(FatalError);
}
if
(
faceOffset.size()
!= sizing.sizeInternal2(slotType::FACES_OFFSETS)
)
{
FatalErrorInFunction
<< " facesOffsets size=" << faceOffset.size()
<< " expected "
<< sizing.sizeInternal2(slotType::FACES_OFFSETS)
<< exit(FatalError); << exit(FatalError);
} }
} }
@ -211,8 +280,20 @@ void Foam::vtk::vtuSizing::populateArrays
} }
// Initialization
faceOffset = -1; faceOffset = -1;
// For INTERNAL2, the vertOffset is (nFieldCells+1), which means that
// the last entry is never visited. Set as zero now.
if (vertOffset.size())
{
vertOffset.first() = 0;
vertOffset.last() = 0;
}
const cellModel& tet = cellModel::ref(cellModel::TET); const cellModel& tet = cellModel::ref(cellModel::TET);
const cellModel& pyr = cellModel::ref(cellModel::PYR); const cellModel& pyr = cellModel::ref(cellModel::PYR);
const cellModel& prism = cellModel::ref(cellModel::PRISM); const cellModel& prism = cellModel::ref(cellModel::PRISM);
@ -222,11 +303,11 @@ void Foam::vtk::vtuSizing::populateArrays
const cellShapeList& shapes = mesh.cellShapes(); const cellShapeList& shapes = mesh.cellShapes();
// face owner is needed to determine the face orientation // The face owner is needed to determine the face orientation
const labelList& owner = mesh.faceOwner(); const labelList& owner = mesh.faceOwner();
// Unique vertex labels per polyhedral // Unique vertex labels per polyhedral
labelHashSet hashUniqId(2*256); labelHashSet hashUniqId(512);
// Index into vertLabels, faceLabels for normal cells // Index into vertLabels, faceLabels for normal cells
label nVertLabels = 0; label nVertLabels = 0;
@ -277,13 +358,15 @@ void Foam::vtk::vtuSizing::populateArrays
if (model == tet) if (model == tet)
{ {
cellTypes[celli] = vtk::cellType::VTK_TETRA; cellTypes[celli] = vtk::cellType::VTK_TETRA;
constexpr label nShapePoints = 4; // OR shape.size();
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = shape.size(); vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = shape.size(); vertLabels[nVertLabels++] = nShapePoints;
} }
for (const label cpi : shape) for (const label cpi : shape)
@ -294,13 +377,15 @@ void Foam::vtk::vtuSizing::populateArrays
else if (model == pyr) else if (model == pyr)
{ {
cellTypes[celli] = vtk::cellType::VTK_PYRAMID; cellTypes[celli] = vtk::cellType::VTK_PYRAMID;
constexpr label nShapePoints = 5; // OR shape.size();
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = shape.size(); vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = shape.size(); vertLabels[nVertLabels++] = nShapePoints;
} }
for (const label cpi : shape) for (const label cpi : shape)
@ -311,13 +396,15 @@ void Foam::vtk::vtuSizing::populateArrays
else if (model == hex) else if (model == hex)
{ {
cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON;
constexpr label nShapePoints = 8; // OR shape.size();
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = shape.size(); vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = shape.size(); vertLabels[nVertLabels++] = nShapePoints;
} }
for (const label cpi : shape) for (const label cpi : shape)
@ -328,13 +415,15 @@ void Foam::vtk::vtuSizing::populateArrays
else if (model == prism) else if (model == prism)
{ {
cellTypes[celli] = vtk::cellType::VTK_WEDGE; cellTypes[celli] = vtk::cellType::VTK_WEDGE;
constexpr label nShapePoints = 6; // OR shape.size();
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = shape.size(); vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = shape.size(); vertLabels[nVertLabels++] = nShapePoints;
} }
// VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5) // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5)
@ -349,13 +438,15 @@ void Foam::vtk::vtuSizing::populateArrays
{ {
// Treat as squeezed prism // Treat as squeezed prism
cellTypes[celli] = vtk::cellType::VTK_WEDGE; cellTypes[celli] = vtk::cellType::VTK_WEDGE;
constexpr label nShapePoints = 6;
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = 6; vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = 6; vertLabels[nVertLabels++] = nShapePoints;
} }
vertLabels[nVertLabels++] = shape[0]; vertLabels[nVertLabels++] = shape[0];
@ -369,13 +460,15 @@ void Foam::vtk::vtuSizing::populateArrays
{ {
// Treat as squeezed hex // Treat as squeezed hex
cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON;
constexpr label nShapePoints = 8;
if (vertOffset.size()) if (vertOffset.size())
{ {
vertOffset[celli] = 8; vertOffset[celli] = nShapePoints;
} }
if (prefix) if (prefix)
{ {
vertLabels[nVertLabels++] = 8; vertLabels[nVertLabels++] = nShapePoints;
} }
vertLabels[nVertLabels++] = shape[0]; vertLabels[nVertLabels++] = shape[0];
@ -427,7 +520,7 @@ void Foam::vtk::vtuSizing::populateArrays
{ {
// Quad becomes a pyramid // Quad becomes a pyramid
const label nShapePoints = 5; // pyr (5 vertices) constexpr label nShapePoints = 5; // pyr (5 vertices)
label celLoc, vrtLoc; label celLoc, vrtLoc;
if (first) if (first)
@ -479,7 +572,7 @@ void Foam::vtk::vtuSizing::populateArrays
{ {
// Triangle becomes a tetrahedral // Triangle becomes a tetrahedral
const label nShapePoints = 4; // tet (4 vertices) constexpr label nShapePoints = 4; // tet (4 vertices)
label celLoc, vrtLoc; label celLoc, vrtLoc;
if (first) if (first)
@ -604,8 +697,12 @@ void Foam::vtk::vtuSizing::populateArrays
// STAGE 3: Adjust vertOffset for all cells // STAGE 3: Adjust vertOffset for all cells
// A second pass is needed for several reasons. // A second pass is needed for several reasons.
// - Additional (decomposed) cells are placed out of sequence // - Additional (decomposed) cells are placed out of sequence
// - Internal format has the size prefixed, XML format does not. // - INTERNAL1 connectivity has size prefixed
// - XML format expects end-offsets, Internal expects begin-offsets //
// Cell offsets:
// - XML format expects end-offsets,
// - INTERNAL1 expects begin-offsets
// - INTERNAL2 expects begin/end-offsets
switch (output) switch (output)
{ {
@ -614,17 +711,19 @@ void Foam::vtk::vtuSizing::populateArrays
case contentType::XML: case contentType::XML:
{ {
// No prefix, determine end offsets // Transform cell sizes (vertOffset) into begin offsets
// vertOffset[0] already contains its size
// vertOffset[0] already contains its size, leave untouched
for (label i = 1; i < vertOffset.size(); ++i) for (label i = 1; i < vertOffset.size(); ++i)
{ {
vertOffset[i] += vertOffset[i-1]; vertOffset[i] += vertOffset[i-1];
} }
// The end face offsets, leaving -1 untouched
if (sizing.nFaceLabels()) if (sizing.nFaceLabels())
{ {
// End face offsets, leaving -1 untouched LabelType prev(0);
LabelType prev = 0;
for (LabelType& off : faceOffset) for (LabelType& off : faceOffset)
{ {
const auto sz = off; const auto sz = off;
@ -637,21 +736,63 @@ void Foam::vtk::vtuSizing::populateArrays
} }
break; break;
} }
case contentType::INTERNAL:
case contentType::INTERNAL1:
{ {
// Has prefix, determine begin offsets // Transform cell sizes (vertOffset) into begin offsets
label beg = 0;
for (LabelType& off : vertOffset)
{ {
const auto sz = off; LabelType beg(0);
off = beg;
beg += 1 + sz; for (LabelType& off : vertOffset)
{
const auto sz = off;
off = beg;
beg += 1 + sz; // Additional 1 to skip embedded prefix
}
} }
// Begin face offsets, leaving -1 untouched // The begin face offsets, leaving -1 untouched
if (sizing.nFaceLabels()) if (sizing.nFaceLabels())
{ {
beg = 0; LabelType beg(0);
for (LabelType& off : faceOffset)
{
const auto sz = off;
if (sz > 0)
{
off = beg;
beg += sz;
}
}
}
break;
}
case contentType::INTERNAL2:
{
// Transform cell sizes (vertOffset) into begin/end offsets
// input [n1, n2, n3, ..., 0]
// becomes [0, n1, n1+n2, n1+n2+n3, ..., nTotal]
// The last entry of vertOffset was initialized as zero and
// never revisited, so the following loop is OK
{
LabelType total(0);
for (LabelType& off : vertOffset)
{
const auto sz = off;
off = total;
total += sz;
}
}
// The begin face offsets, leaving -1 untouched
if (sizing.nFaceLabels())
{
LabelType beg(0);
for (LabelType& off : faceOffset) for (LabelType& off : faceOffset)
{ {
const auto sz = off; const auto sz = off;