diff --git a/src/conversion/vtk/adaptor/foamVtkTools.H b/src/conversion/vtk/adaptor/foamVtkTools.H index 3748e3f0292c885cbf3a8c5b5d5b282def2887b2..9f279076e2e4ce00d514bd745bd41a8bcdda785d 100644 --- a/src/conversion/vtk/adaptor/foamVtkTools.H +++ b/src/conversion/vtk/adaptor/foamVtkTools.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -70,8 +70,6 @@ class vtkDataSet; class vtkCellData; class vtkPointData; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - namespace Foam { namespace vtk @@ -185,15 +183,6 @@ namespace Tools 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 inline vtkSmartPointer<vtkPoints> Points ( diff --git a/src/conversion/vtk/adaptor/foamVtkToolsI.H b/src/conversion/vtk/adaptor/foamVtkToolsI.H index 17342d417b5aa75da890a4e6da724c8b6aded4af..aa2da4eeb2105174e28ffe8eb60b7d26db483990 100644 --- a/src/conversion/vtk/adaptor/foamVtkToolsI.H +++ b/src/conversion/vtk/adaptor/foamVtkToolsI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,6 +25,8 @@ License \*---------------------------------------------------------------------------*/ +#include <numeric> + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 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> Foam::vtk::Tools::Points(const UList<point>& pts) { @@ -150,20 +139,72 @@ inline vtkSmartPointer<vtkCellArray> Foam::vtk::Tools::identityVertices const label size ) { - // VTK_VERTEX: need 2 values (size=1 and index=id) per vertex 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 // [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; - *(iter++) = id; + cells->GetData()->SetNumberOfTuples(nConnect); + + 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; }; diff --git a/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C b/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C index 21334853953ac2be623f8f11fefa30ea915cdea2..4ce843d8d05b518cf76cec8786d22a2ba6a261ba 100644 --- a/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C +++ b/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,30 +43,99 @@ template<class Face> vtkSmartPointer<vtkCellArray> Foam::vtk::Tools::Faces(const UList<Face>& faces) { - label nAlloc = faces.size(); - for (const auto& f : faces) + auto cells = vtkSmartPointer<vtkCellArray>::New(); + + #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); + { + offsets->SetNumberOfTuples(nOffsets); + + vtkIdType* iter = offsets->WritePointer(0, nOffsets); + + // Assign offsets, determine overall connectivity size + + *iter = 0; + for (const auto& f : faces) + { + nConnect += f.size(); + + *(++iter) = nConnect; + } + } + + + // Cell connectivity for polygons + // [verts..., verts... ] + + auto connect = vtkSmartPointer<vtkIdTypeArray>::New(); + { - nAlloc += f.size(); + 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; + } + } } - auto vtkcells = vtkSmartPointer<vtkCellArray>::New(); + // Move into a vtkCellArray - UList<vtkIdType> list = asUList(vtkcells, faces.size(), nAlloc); + cells->SetData(offsets, connect); + + #else + + // In VTK-8.2.0 and older, + // sizes are interwoven (prefixed) in the connectivity // Cell connectivity for polygons - // [size, verts..., size, verts... ] - auto iter = list.begin(); + // [n1, verts..., n2, verts... ] + + + const vtkIdType nElem(faces.size()); + + // Connectivity size, with prefixed size information + vtkIdType nConnect(faces.size()); for (const auto& f : faces) { - *(iter++) = f.size(); + nConnect += f.size(); + } + + { + cells->GetData()->SetNumberOfTuples(nConnect); + + vtkIdType* iter = cells->WritePointer(nElem, nConnect); - for (const label verti : f) + // Fill in the connectivity array, with prefixed size information + + for (const auto& f : faces) { - *(iter++) = verti; + *(iter++) = f.size(); + + for (const label verti : f) + { + *(iter++) = verti; + } } } - return vtkcells; + #endif + + return cells; } diff --git a/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H b/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H index 3e941ad6efa03076bd832cfbb306e823e67fb8df..57a624256c4a85ddf937f7a2fd051ac8f299e751 100644 --- a/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H +++ b/src/conversion/vtk/adaptor/foamVtkVtuAdaptor.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -52,20 +52,15 @@ SourceFiles #include "foamVtkMeshMaps.H" #include "foamVtuSizing.H" -#include "vtkSmartPointer.h" -#include "vtkPoints.h" -#include "vtkPolyData.h" #include "vtkUnstructuredGrid.h" #include "vtkMultiBlockDataSet.h" -// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -class vtkCellArray; +// Forward Declarations class vtkDataSet; class vtkFloatArray; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - namespace Foam { namespace vtk diff --git a/src/conversion/vtk/adaptor/foamVtkVtuAdaptorI.H b/src/conversion/vtk/adaptor/foamVtkVtuAdaptorI.H index 39443d3156147ad45b3df6275d35e8035251ce90..e1ddefa7033f171ec96c755b095d17181a5f701c 100644 --- a/src/conversion/vtk/adaptor/foamVtkVtuAdaptorI.H +++ b/src/conversion/vtk/adaptor/foamVtkVtuAdaptorI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -103,89 +103,127 @@ Foam::vtk::vtuAdaptor::internal 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); + auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New(); + auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New(); + UList<uint8_t> cellTypesUL + ( + vtk::Tools::asUList(cellTypes, sizing.nFieldCells()) + ); + auto cells = vtkSmartPointer<vtkCellArray>::New(); auto faces = vtkSmartPointer<vtkIdTypeArray>::New(); - auto cellLocations = vtkSmartPointer<vtkIdTypeArray>::New(); + auto cellOffsets = vtkSmartPointer<vtkIdTypeArray>::New(); auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New(); - UList<uint8_t> cellTypesUL = - vtk::Tools::asUList(cellTypes, sizing.nFieldCells()); + const auto nConnect + ( + sizing.sizeOf(output, vtk::vtuSizing::slotType::CELLS) + ); - UList<vtkIdType> cellsUL = + UList<vtkIdType> cellOffsetsUL + ( vtk::Tools::asUList ( - cells, - sizing.nFieldCells(), - sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS) - ); + cellOffsets, + sizing.sizeOf(output, vtk::vtuSizing::slotType::CELLS_OFFSETS) + ) + ); - UList<vtkIdType> cellLocationsUL = - vtk::Tools::asUList - ( - cellLocations, - sizing.sizeInternal(vtk::vtuSizing::slotType::CELLS_OFFSETS) - ); + #ifdef VTK_CELL_ARRAY_V2 + + 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 = + UList<vtkIdType> facesUL + ( vtk::Tools::asUList ( faces, - sizing.sizeInternal(vtk::vtuSizing::slotType::FACES) - ); + sizing.sizeOf(output, vtk::vtuSizing::slotType::FACES) + ) + ); - UList<vtkIdType> faceLocationsUL = + UList<vtkIdType> faceLocationsUL + ( vtk::Tools::asUList ( faceLocations, - sizing.sizeInternal(vtk::vtuSizing::slotType::FACES_OFFSETS) - ); + sizing.sizeOf(output, vtk::vtuSizing::slotType::FACES_OFFSETS) + ) + ); sizing.populateInternal ( mesh, cellTypesUL, - cellsUL, - cellLocationsUL, - facesUL, - faceLocationsUL, - static_cast<foamVtkMeshMaps&>(*this) + cellsUL, cellOffsetsUL, + facesUL, faceLocationsUL, + static_cast<foamVtkMeshMaps&>(*this), + output ); - auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New(); // Convert OpenFOAM mesh vertices to VTK // - can only do this *after* populating the decompInfo with cell-ids // for any additional points (ie, mesh cell-centres) vtkmesh->SetPoints(this->points(mesh)); + #ifdef VTK_CELL_ARRAY_V2 + + // Move into a vtkCellArray + cells->SetData(cellOffsets, cellConnect); + if (facesUL.size()) { - vtkmesh->SetCells - ( - cellTypes, - cellLocations, - cells, - faceLocations, - faces - ); + vtkmesh->SetCells(cellTypes, cells, faceLocations, faces); } else { - vtkmesh->SetCells - ( - cellTypes, - cellLocations, - cells, - nullptr, - nullptr - ); + vtkmesh->SetCells(cellTypes, 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; } diff --git a/src/fileFormats/vtk/part/foamVtkMeshMaps.H b/src/fileFormats/vtk/part/foamVtkMeshMaps.H index 95650b0bf6b7253373afc521e9c92d9a01b97148..9ef2c6a20481fd1d9e5b11e82d08ea7f3f0d987d 100644 --- a/src/fileFormats/vtk/part/foamVtkMeshMaps.H +++ b/src/fileFormats/vtk/part/foamVtkMeshMaps.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,6 +37,7 @@ Description for additional points of decomposed cells SourceFiles + foamVtkMeshMaps.C foamVtkMeshMapsI.H \*---------------------------------------------------------------------------*/ @@ -74,12 +75,11 @@ public: // Constructors - //- Construct null - inline explicit foamVtkMeshMaps(const label size = 0); + //- Default construct: zero-sized, no reserved size + inline foamVtkMeshMaps(); - - //- Destructor - ~foamVtkMeshMaps() = default; + //- Construct with reserved size + inline explicit foamVtkMeshMaps(const label size); // Member Functions @@ -92,17 +92,26 @@ public: // cells this becomes a useful means of mapping from the original mesh. inline const labelList& cellMap() const; + //- Write access to original cell ids + inline DynamicList<label>& cellMap(); + //- Point labels for subsetted meshes inline const labelList& pointMap() const; + //- Write access to point labels for subsetted meshes + inline DynamicList<label>& pointMap(); + //- Any additional (user) labels. // Eg, cell-centre labels for additional points of decomposed cells inline const labelList& additionalIds() const; + //- Write access to additional (user) labels. + inline DynamicList<label>& additionalIds(); + // Edit - //- Clear + //- Clear sizing inline void clear(); //- Renumber cell ids (cellMap and additionalIds) to account for @@ -111,22 +120,6 @@ public: //- Renumber point ids (pointMap) to account for subset meshes 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(); - }; diff --git a/src/fileFormats/vtk/part/foamVtkMeshMapsI.H b/src/fileFormats/vtk/part/foamVtkMeshMapsI.H index 2a6f5374ef43d9dac5fe421fbd24fe7e2b30e055..3934a7f9461e5ce08df0a882b44fb445fc13df2c 100644 --- a/src/fileFormats/vtk/part/foamVtkMeshMapsI.H +++ b/src/fileFormats/vtk/part/foamVtkMeshMapsI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,6 +29,14 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +inline Foam::foamVtkMeshMaps::foamVtkMeshMaps() +: + cellMap_(0), + pointMap_(0), + additionalIds_(0) +{} + + inline Foam::foamVtkMeshMaps::foamVtkMeshMaps(const label size) : cellMap_(size), diff --git a/src/fileFormats/vtk/part/foamVtuCells.C b/src/fileFormats/vtk/part/foamVtuCells.C index 4376337b970e5d51d42469436efb90f699193362..1bbf7c8d520f75d237f73e730b8d0fd4dd7c6b1a 100644 --- a/src/fileFormats/vtk/part/foamVtuCells.C +++ b/src/fileFormats/vtk/part/foamVtuCells.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2018 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License 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 - 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)); + cellTypes_.resize(nFieldCells()); + vertLabels_.resize(sizeOf(output_, slotType::CELLS)); + vertOffset_.resize(sizeOf(output_, slotType::CELLS_OFFSETS)); + faceLabels_.resize(sizeOf(output_, slotType::FACES)); + faceOffset_.resize(sizeOf(output_, slotType::FACES_OFFSETS)); switch (output_) { case contentType::LEGACY: + { populateLegacy ( mesh, @@ -125,7 +126,10 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh) maps_ ); break; + } + case contentType::XML: + { populateXml ( mesh, @@ -137,7 +141,11 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh) maps_ ); break; - case contentType::INTERNAL: + } + + case contentType::INTERNAL1: + case contentType::INTERNAL2: + { populateInternal ( mesh, @@ -146,9 +154,11 @@ void Foam::vtk::vtuCells::repopulate(const polyMesh& mesh) vertOffset_, faceLabels_, faceOffset_, - maps_ + maps_, + output_ ); break; + } } } diff --git a/src/fileFormats/vtk/part/foamVtuCells.H b/src/fileFormats/vtk/part/foamVtuCells.H index 6a65f6cdb0325e625cce6b0b211337872b75e357..10ae1d2acd0e37872ef888aeb6969a1ef8012c86 100644 --- a/src/fileFormats/vtk/part/foamVtuCells.H +++ b/src/fileFormats/vtk/part/foamVtuCells.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2019 OpenCFD Ltd. + Copyright (C) 2014-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -52,7 +52,6 @@ SourceFiles #include "foamVtkCore.H" #include "foamVtkMeshMaps.H" #include "foamVtuSizing.H" -#include "DynamicList.H" #include "labelList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -60,12 +59,12 @@ SourceFiles namespace Foam { -// Forward declarations +// Forward Declarations class polyMesh; namespace vtk { -// Forward declarations +// Forward Declarations class outputOptions; /*---------------------------------------------------------------------------*\ @@ -76,7 +75,7 @@ class vtuCells : public vtuSizing { - // Private Member Data + // Private Data // Requested output types @@ -112,7 +111,7 @@ class vtuCells // Private Member Functions //- Create the geometry using the previously requested output and - // decomposition types. + //- decomposition types. void repopulate(const polyMesh& mesh); //- No copy construct @@ -126,17 +125,15 @@ public: // Constructors - //- Construct from components. - // Optionally with polyhedral decomposition. - vtuCells + //- Default construct (XML format, no polyhedral decomposition) + explicit vtuCells ( const enum contentType output = contentType::XML, const bool decompose = false ); - //- Construct from components and create the output information - //- immediately - vtuCells + //- Construct from components, create output information immediately + explicit vtuCells ( const polyMesh& mesh, const enum contentType output = contentType::XML, @@ -145,14 +142,13 @@ public: //- Construct from components. // Optionally with polyhedral decomposition. - vtuCells + explicit vtuCells ( const vtk::outputOptions opts, const bool decompose = false ); - //- Construct from components, and create the output information - //- immediately + //- Construct from components, create output information immediately vtuCells ( const polyMesh& mesh, @@ -161,10 +157,6 @@ public: ); - //- Destructor - ~vtuCells() = default; - - // Member Functions // Access @@ -229,7 +221,6 @@ public: //- Original cell ids for all cells (regular and decomposed). inline const labelList& cellMap() const; - }; diff --git a/src/fileFormats/vtk/part/foamVtuCellsI.H b/src/fileFormats/vtk/part/foamVtuCellsI.H index 40d484c676cd8b43a506a0ee48f11c3925265f98..e6c4d91436e0e041bf3d470eaba1eb9fad9b5f41 100644 --- a/src/fileFormats/vtk/part/foamVtuCellsI.H +++ b/src/fileFormats/vtk/part/foamVtuCellsI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,7 +29,6 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - inline enum Foam::vtk::vtuCells::contentType Foam::vtk::vtuCells::content() const { diff --git a/src/fileFormats/vtk/part/foamVtuSizing.C b/src/fileFormats/vtk/part/foamVtuSizing.C index f51254eac9edb335aa32fd4e12030f806114d3c5..369b358b1ea16d39245896eae9fb928c5b1527f8 100644 --- a/src/fileFormats/vtk/part/foamVtuSizing.C +++ b/src/fileFormats/vtk/part/foamVtuSizing.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2018 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,14 +37,14 @@ License void Foam::vtk::vtuSizing::presizeMaps(foamVtkMeshMaps& maps) const { - maps.cellMap().setSize(this->nFieldCells()); - maps.additionalIds().setSize(this->nAddPoints()); + maps.cellMap().resize(this->nFieldCells()); + maps.additionalIds().resize(this->nAddPoints()); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::vtk::vtuSizing::vtuSizing() +Foam::vtk::vtuSizing::vtuSizing() noexcept { clear(); } @@ -63,7 +63,7 @@ Foam::vtk::vtuSizing::vtuSizing // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::vtk::vtuSizing::clear() +void Foam::vtk::vtuSizing::clear() noexcept { decompose_ = false; nCells_ = 0; @@ -232,6 +232,7 @@ Foam::label Foam::vtk::vtuSizing::sizeOf } break; } + case contentType::XML: { switch (slot) @@ -254,7 +255,8 @@ Foam::label Foam::vtk::vtuSizing::sizeOf } break; } - case contentType::INTERNAL: + + case contentType::INTERNAL1: { switch (slot) { @@ -277,6 +279,29 @@ Foam::label Foam::vtk::vtuSizing::sizeOf } 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; @@ -343,175 +368,73 @@ void Foam::vtk::vtuSizing::populateXml } -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, - labelUList& cellMap, - labelUList& addPointsIds -) const -{ - populateArrays - ( - mesh, - *this, - cellTypes, - connectivity, - offsets, - faces, - facesOffsets, - contentType::INTERNAL, - cellMap, - addPointsIds - ); -} +#undef definePopulateInternalMethod +#define definePopulateInternalMethod(Type) \ + \ + void Foam::vtk::vtuSizing::populateInternal \ + ( \ + const polyMesh& mesh, \ + UList<uint8_t>& cellTypes, \ + UList<Type>& connectivity, \ + UList<Type>& offsets, \ + UList<Type>& faces, \ + UList<Type>& facesOffsets, \ + foamVtkMeshMaps& maps, \ + const enum contentType output \ + ) const \ + { \ + presizeMaps(maps); \ + \ + populateArrays \ + ( \ + mesh, \ + *this, \ + cellTypes, \ + connectivity, \ + offsets, \ + 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 -( - 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 - ); -} +definePopulateInternalMethod(int); +definePopulateInternalMethod(long); +definePopulateInternalMethod(long long); -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 - ); -} +#undef definePopulateInternalMethod // * * * * * * * * * * * * * * Renumber vertices * * * * * * * * * * * * * * // @@ -559,7 +482,7 @@ void Foam::vtk::vtuSizing::renumberVertLabelsLegacy // Therefore anything with 18 labels or more must be a poly auto iter = vertLabels.begin(); - auto last = vertLabels.end(); + const auto last = vertLabels.end(); while (iter < last) { @@ -671,7 +594,7 @@ void Foam::vtk::vtuSizing::renumberFaceLabelsXml // [nFaces, nFace0Pts, id1,id2,..., nFace1Pts, id1,id2,...] auto iter = faceLabels.begin(); - auto last = faceLabels.end(); + const auto last = faceLabels.end(); while (iter < last) { diff --git a/src/fileFormats/vtk/part/foamVtuSizing.H b/src/fileFormats/vtk/part/foamVtuSizing.H index 544cdd138179964b3170b17d8729506626bbda81..d8c97aa4b2834ce86cb4fd4a41c04d6d1064ed0b 100644 --- a/src/fileFormats/vtk/part/foamVtuSizing.H +++ b/src/fileFormats/vtk/part/foamVtuSizing.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2018 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -66,7 +66,7 @@ Description \endtable \table - internal storage + internal1 storage (VTK-8 and earlier) \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 @@ -75,6 +75,16 @@ Description \c facelocation | begin location for each of \c faces, with -1 for primitive cells \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 a CompactListList. @@ -85,6 +95,10 @@ Note since it likely more efficient to use VTK point-blanking to mark duplicate 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 foamVtuSizing.C foamVtuSizingI.H @@ -103,7 +117,7 @@ SourceFiles namespace Foam { -// Forward declarations +// Forward Declarations class polyMesh; namespace vtk @@ -117,23 +131,25 @@ class vtuSizing { public: - // Public data + // Public Data //- Types of content that the storage may represent enum contentType { LEGACY, //!< Legacy VTK 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 enum slotType { 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_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 label nVertLabels_; + // Polyhedrals //- Number of polyhedral face labels for the mesh @@ -164,6 +181,7 @@ private: //- Number of vertex labels used by polyhedrals label nVertPoly_; + // Decomposed polyhedrals //- Number of additional (decomposed) cells for the mesh @@ -202,8 +220,8 @@ public: // Constructors - //- Construct null. - vtuSizing(); + //- Default construct + vtuSizing() noexcept; //- Construct sizing by analyzing the mesh. // No polyhedral decomposition. @@ -214,10 +232,6 @@ public: vtuSizing(const polyMesh& mesh, const bool decompose); - //- Destructor - ~vtuSizing() = default; - - // Member Functions // Edit @@ -227,7 +241,7 @@ public: void reset(const polyMesh& mesh, const bool decompose=false); //- Reset all sizes to zero. - void clear(); + void clear() noexcept; // Access @@ -290,7 +304,10 @@ public: 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; + 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 @@ -316,80 +333,45 @@ public: 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, - labelUList& cellMap, - labelUList& 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, - labelUList& cellMap, - labelUList& 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, - labelUList& cellMap, - labelUList& addPointsIds - ) const; + // Internal types. The size of vtkIdType is unknown here + +#undef declarePopulateInternalMethod +#define declarePopulateInternalMethod(Type) \ + \ + /*! 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, \ + 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 + + + declarePopulateInternalMethod(int); + declarePopulateInternalMethod(long); + declarePopulateInternalMethod(long long); + + #undef declarePopulateInternalMethod // Routines for renumber vertices with a global point offset @@ -465,7 +447,6 @@ public: //- Test inequality bool operator!=(const vtuSizing& rhs) const; - }; diff --git a/src/fileFormats/vtk/part/foamVtuSizingI.H b/src/fileFormats/vtk/part/foamVtuSizingI.H index 9d5dfdc49a25238455d0c409644653d2da2499da..e3c2cc55e8083d19d5d9f4b665cc605ada94f9be 100644 --- a/src/fileFormats/vtk/part/foamVtuSizingI.H +++ b/src/fileFormats/vtk/part/foamVtuSizingI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2018 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License 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 { - 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); } diff --git a/src/fileFormats/vtk/part/foamVtuSizingTemplates.C b/src/fileFormats/vtk/part/foamVtuSizingTemplates.C index c7c40aad3d8166557826bb4849d662191217a53a..0e640b16d184cb0f1c1197c83ec8efb788e14756 100644 --- a/src/fileFormats/vtk/part/foamVtuSizingTemplates.C +++ b/src/fileFormats/vtk/part/foamVtuSizingTemplates.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2017 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,6 +47,17 @@ void Foam::vtk::vtuSizing::populateArrays 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 if (cellTypes.size() != sizing.nFieldCells()) @@ -73,10 +84,6 @@ void Foam::vtk::vtuSizing::populateArrays << 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: @@ -90,6 +97,7 @@ void Foam::vtk::vtuSizing::populateArrays } break; } + case contentType::XML: { // XML uses connectivity/offset pair. @@ -149,32 +157,33 @@ void Foam::vtk::vtuSizing::populateArrays } break; } - case contentType::INTERNAL: + + case contentType::INTERNAL1: { - // VTK-internal connectivity/offset pair. + // VTK-internal1 connectivity/offset pair. if ( vertLabels.size() - != sizing.sizeInternal(slotType::CELLS) + != sizing.sizeInternal1(slotType::CELLS) ) { FatalErrorInFunction << " connectivity size=" << vertLabels.size() << " expected " - << sizing.sizeInternal(slotType::CELLS) + << sizing.sizeInternal1(slotType::CELLS) << exit(FatalError); } if ( vertOffset.size() - != sizing.sizeInternal(slotType::CELLS_OFFSETS) + != sizing.sizeInternal1(slotType::CELLS_OFFSETS) ) { FatalErrorInFunction << " offsets size=" << vertOffset.size() << " expected " - << sizing.sizeInternal(slotType::CELLS_OFFSETS) + << sizing.sizeInternal1(slotType::CELLS_OFFSETS) << exit(FatalError); } @@ -183,26 +192,86 @@ void Foam::vtk::vtuSizing::populateArrays if ( faceLabels.size() - != sizing.sizeInternal(slotType::FACES) + != sizing.sizeInternal1(slotType::FACES) ) { FatalErrorInFunction << " faces size=" << faceLabels.size() << " expected " - << sizing.sizeInternal(slotType::FACES) + << sizing.sizeInternal1(slotType::FACES) << exit(FatalError); } if ( faceOffset.size() - != sizing.sizeInternal(slotType::FACES_OFFSETS) + != sizing.sizeInternal1(slotType::FACES_OFFSETS) ) { FatalErrorInFunction << " facesOffsets size=" << faceOffset.size() << " 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); } } @@ -211,8 +280,20 @@ void Foam::vtk::vtuSizing::populateArrays } + // Initialization + 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& pyr = cellModel::ref(cellModel::PYR); const cellModel& prism = cellModel::ref(cellModel::PRISM); @@ -222,11 +303,11 @@ void Foam::vtk::vtuSizing::populateArrays 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(); // Unique vertex labels per polyhedral - labelHashSet hashUniqId(2*256); + labelHashSet hashUniqId(512); // Index into vertLabels, faceLabels for normal cells label nVertLabels = 0; @@ -277,13 +358,15 @@ void Foam::vtk::vtuSizing::populateArrays if (model == tet) { cellTypes[celli] = vtk::cellType::VTK_TETRA; + constexpr label nShapePoints = 4; // OR shape.size(); + if (vertOffset.size()) { - vertOffset[celli] = shape.size(); + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = shape.size(); + vertLabels[nVertLabels++] = nShapePoints; } for (const label cpi : shape) @@ -294,13 +377,15 @@ void Foam::vtk::vtuSizing::populateArrays else if (model == pyr) { cellTypes[celli] = vtk::cellType::VTK_PYRAMID; + constexpr label nShapePoints = 5; // OR shape.size(); + if (vertOffset.size()) { - vertOffset[celli] = shape.size(); + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = shape.size(); + vertLabels[nVertLabels++] = nShapePoints; } for (const label cpi : shape) @@ -311,13 +396,15 @@ void Foam::vtk::vtuSizing::populateArrays else if (model == hex) { cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; + constexpr label nShapePoints = 8; // OR shape.size(); + if (vertOffset.size()) { - vertOffset[celli] = shape.size(); + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = shape.size(); + vertLabels[nVertLabels++] = nShapePoints; } for (const label cpi : shape) @@ -328,13 +415,15 @@ void Foam::vtk::vtuSizing::populateArrays else if (model == prism) { cellTypes[celli] = vtk::cellType::VTK_WEDGE; + constexpr label nShapePoints = 6; // OR shape.size(); + if (vertOffset.size()) { - vertOffset[celli] = shape.size(); + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = shape.size(); + vertLabels[nVertLabels++] = nShapePoints; } // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5) @@ -349,13 +438,15 @@ void Foam::vtk::vtuSizing::populateArrays { // Treat as squeezed prism cellTypes[celli] = vtk::cellType::VTK_WEDGE; + constexpr label nShapePoints = 6; + if (vertOffset.size()) { - vertOffset[celli] = 6; + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = 6; + vertLabels[nVertLabels++] = nShapePoints; } vertLabels[nVertLabels++] = shape[0]; @@ -369,13 +460,15 @@ void Foam::vtk::vtuSizing::populateArrays { // Treat as squeezed hex cellTypes[celli] = vtk::cellType::VTK_HEXAHEDRON; + constexpr label nShapePoints = 8; + if (vertOffset.size()) { - vertOffset[celli] = 8; + vertOffset[celli] = nShapePoints; } if (prefix) { - vertLabels[nVertLabels++] = 8; + vertLabels[nVertLabels++] = nShapePoints; } vertLabels[nVertLabels++] = shape[0]; @@ -427,7 +520,7 @@ void Foam::vtk::vtuSizing::populateArrays { // Quad becomes a pyramid - const label nShapePoints = 5; // pyr (5 vertices) + constexpr label nShapePoints = 5; // pyr (5 vertices) label celLoc, vrtLoc; if (first) @@ -479,7 +572,7 @@ void Foam::vtk::vtuSizing::populateArrays { // Triangle becomes a tetrahedral - const label nShapePoints = 4; // tet (4 vertices) + constexpr label nShapePoints = 4; // tet (4 vertices) label celLoc, vrtLoc; if (first) @@ -604,8 +697,12 @@ void Foam::vtk::vtuSizing::populateArrays // 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 + // - INTERNAL1 connectivity has size prefixed + // + // Cell offsets: + // - XML format expects end-offsets, + // - INTERNAL1 expects begin-offsets + // - INTERNAL2 expects begin/end-offsets switch (output) { @@ -614,17 +711,19 @@ void Foam::vtk::vtuSizing::populateArrays case contentType::XML: { - // No prefix, determine end offsets - // vertOffset[0] already contains its size + // Transform cell sizes (vertOffset) into begin offsets + + // vertOffset[0] already contains its size, leave untouched for (label i = 1; i < vertOffset.size(); ++i) { vertOffset[i] += vertOffset[i-1]; } + // The end face offsets, leaving -1 untouched if (sizing.nFaceLabels()) { - // End face offsets, leaving -1 untouched - LabelType prev = 0; + LabelType prev(0); + for (LabelType& off : faceOffset) { const auto sz = off; @@ -637,21 +736,63 @@ void Foam::vtk::vtuSizing::populateArrays } break; } - case contentType::INTERNAL: + + case contentType::INTERNAL1: + { + // Transform cell sizes (vertOffset) into begin offsets + { + LabelType beg(0); + + for (LabelType& off : vertOffset) + { + const auto sz = off; + off = beg; + beg += 1 + sz; // Additional 1 to skip embedded prefix + } + } + + // The begin face offsets, leaving -1 untouched + if (sizing.nFaceLabels()) + { + LabelType beg(0); + + for (LabelType& off : faceOffset) + { + const auto sz = off; + if (sz > 0) + { + off = beg; + beg += sz; + } + } + } + break; + } + + case contentType::INTERNAL2: { - // Has prefix, determine begin offsets - label beg = 0; - for (LabelType& off : vertOffset) + // 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 { - const auto sz = off; - off = beg; - beg += 1 + sz; + LabelType total(0); + + for (LabelType& off : vertOffset) + { + const auto sz = off; + off = total; + total += sz; + } } - // Begin face offsets, leaving -1 untouched + // The begin face offsets, leaving -1 untouched if (sizing.nFaceLabels()) { - beg = 0; + LabelType beg(0); + for (LabelType& off : faceOffset) { const auto sz = off;