diff --git a/Common/DataModel/Testing/Cxx/TestPolyhedronDecompose.cxx b/Common/DataModel/Testing/Cxx/TestPolyhedronDecompose.cxx index d25132e4598291670d47a1b7250faa01726cc5f2..1e61082d0f649727cdf26b9968743f5ede1fdf77 100644 --- a/Common/DataModel/Testing/Cxx/TestPolyhedronDecompose.cxx +++ b/Common/DataModel/Testing/Cxx/TestPolyhedronDecompose.cxx @@ -5,10 +5,12 @@ #include <vtkActor.h> #include <vtkBitArray.h> #include <vtkCamera.h> +#include <vtkCellArray.h> #include <vtkCellData.h> #include <vtkContourFilter.h> #include <vtkDoubleArray.h> #include <vtkGeometryFilter.h> +#include <vtkIdTypeArray.h> #include <vtkNew.h> #include <vtkPointData.h> #include <vtkPoints.h> @@ -318,10 +320,16 @@ vtkSmartPointer<vtkPolyhedron> MakePolyhedron1() polyhedron->GetPoints()->InsertNextPoint(6.25, -3.75, 6.25); // Faces - vtkIdType faces[31] = { 6, 4, 0, 1, 3, 2, 4, 0, 4, 5, 1, 4, 0, 2, 6, 4, 4, 1, 5, 7, 3, 4, 3, 7, 6, - 2, 4, 4, 6, 7, 5 }; - - polyhedron->SetFaces(faces); + vtkIdType face_offsets[7] = { 0, 4, 8, 12, 16, 20, 24 }; + vtkIdType face_conns[24] = { 0, 1, 3, 2, 0, 4, 5, 1, 0, 2, 6, 4, 1, 5, 7, 3, 3, 7, 6, 2, 4, 6, 7, + 5 }; + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 7, 1); + conns_arr->SetArray(face_conns, 24, 1); + faces->SetData(offsets_arr, conns_arr); + polyhedron->SetCellFaces(faces); polyhedron->Initialize(); return polyhedron; @@ -349,10 +357,16 @@ vtkSmartPointer<vtkPolyhedron> MakePolyhedron2() polyhedron->GetPoints()->InsertNextPoint(6.25, -13.75, 6.25); // Faces - vtkIdType faces[31] = { 6, 4, 10, 11, 9, 8, 4, 9, 13, 12, 8, 4, 12, 14, 10, 8, 4, 11, 15, 13, 9, - 4, 10, 14, 15, 11, 4, 13, 15, 14, 12 }; - - polyhedron->SetFaces(faces); + vtkIdType face_offsets[7] = { 0, 4, 8, 12, 16, 20, 24 }; + vtkIdType face_conns[24] = { 10, 11, 9, 8, 9, 13, 12, 8, 12, 14, 10, 8, 11, 15, 13, 9, 10, 14, 15, + 11, 13, 15, 14, 12 }; + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 7, 1); + conns_arr->SetArray(face_conns, 24, 1); + faces->SetData(offsets_arr, conns_arr); + polyhedron->SetCellFaces(faces); polyhedron->Initialize(); return polyhedron; diff --git a/Common/DataModel/Testing/Cxx/TestPolyhedronTriangulateFaces.cxx b/Common/DataModel/Testing/Cxx/TestPolyhedronTriangulateFaces.cxx index 0ca5273fab7d00d9dc90d36858614cea161394df..a79bf48b2b9e7d27ef791b16f05f32c9e3f0a5b1 100644 --- a/Common/DataModel/Testing/Cxx/TestPolyhedronTriangulateFaces.cxx +++ b/Common/DataModel/Testing/Cxx/TestPolyhedronTriangulateFaces.cxx @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause +#include <vtkCellArray.h> #include <vtkExtractEdges.h> +#include <vtkIdTypeArray.h> #include <vtkNew.h> #include <vtkPolyhedron.h> #include <vtkSmartPointer.h> @@ -38,13 +40,28 @@ vtkSmartPointer<vtkPolyhedron> MakeDodecahedron() aDodecahedron->GetPoints()->InsertNextPoint(-0.375185, -1.1547, -1.58931); aDodecahedron->GetPoints()->InsertNextPoint(0.982247, -0.713644, -1.58931); - vtkIdType faces[73] = { 12, // number of faces - 5, 0, 1, 2, 3, 4, // number of ids on face, ids - 5, 0, 5, 10, 6, 1, 5, 1, 6, 11, 7, 2, 5, 2, 7, 12, 8, 3, 5, 3, 8, 13, 9, 4, 5, 4, 9, 14, 5, 0, - 5, 15, 10, 5, 14, 19, 5, 16, 11, 6, 10, 15, 5, 17, 12, 7, 11, 16, 5, 18, 13, 8, 12, 17, 5, 19, - 14, 9, 13, 18, 5, 19, 18, 17, 16, 15 }; - - aDodecahedron->SetFaces(faces); + vtkIdType face_offsets[13] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 }; + vtkIdType face_conns[60] = { + 0, 1, 2, 3, 4, // ids + 0, 5, 10, 6, 1, // + 1, 6, 11, 7, 2, // + 2, 7, 12, 8, 3, // + 3, 8, 13, 9, 4, // + 4, 9, 14, 5, 0, // + 15, 10, 5, 14, 19, // + 16, 11, 6, 10, 15, // + 17, 12, 7, 11, 16, // + 18, 13, 8, 12, 17, // + 19, 14, 9, 13, 18, // + 19, 18, 17, 16, 15 // + }; + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 13, 1); + conns_arr->SetArray(face_conns, 60, 1); + faces->SetData(offsets_arr, conns_arr); + aDodecahedron->SetCellFaces(faces); aDodecahedron->Initialize(); return aDodecahedron; @@ -72,16 +89,23 @@ vtkSmartPointer<vtkPolyhedron> MakeConcavePolyhedron() aPolyhedron->GetPoints()->InsertNextPoint(0.0, 2.0, 2.0); aPolyhedron->GetPoints()->InsertNextPoint(1.0, 1.0, 2.0); - vtkIdType faces[73] = { 8, 5, 0, 1, 2, 3, 4, // poly - 5, 5, 6, 7, 8, 9, // poly - 4, 0, 4, 9, 5, // quad - 4, 4, 3, 8, 9, // quad - 4, 3, 2, 7, 8, // quad - 4, 5, 6, 1, 0, // quad - 3, 6, 7, 1, // tri - 3, 7, 2, 1 }; // tri - - aPolyhedron->SetFaces(faces); + vtkIdType face_offsets[9] = { 0, 5, 10, 14, 18, 22, 26, 29, 32 }; + vtkIdType face_conns[32] = { 0, 1, 2, 3, 4, // poly + 5, 6, 7, 8, 9, // poly + 0, 4, 9, 5, // quad + 4, 3, 8, 9, // quad + 3, 2, 7, 8, // quad + 5, 6, 1, 0, // quad + 6, 7, 1, // tri + 7, 2, 1 }; // tri + + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 9, 1); + conns_arr->SetArray(face_conns, 32, 1); + faces->SetData(offsets_arr, conns_arr); + aPolyhedron->SetCellFaces(faces); aPolyhedron->Initialize(); return aPolyhedron; @@ -109,15 +133,22 @@ vtkSmartPointer<vtkPolyhedron> MakeConcaveNonPlanarPolyhedron() aPolyhedron->GetPoints()->InsertNextPoint(0.0, 2.0, 2.0); aPolyhedron->GetPoints()->InsertNextPoint(1.0, 1.0, 2.0); - vtkIdType faces[73] = { 7, 5, 0, 1, 2, 3, 4, // planar poly - 5, 5, 6, 7, 8, 9, // planar poly - 6, 0, 4, 3, 8, 9, 5, // non-planar poly - 4, 3, 2, 7, 8, // quad - 4, 5, 6, 1, 0, // quad - 3, 6, 7, 1, // tri - 3, 7, 2, 1 }; // tri - - aPolyhedron->SetFaces(faces); + vtkIdType face_offsets[8] = { 0, 5, 10, 16, 20, 24, 27, 30 }; + vtkIdType face_conns[30] = { 0, 1, 2, 3, 4, // planar poly + 5, 6, 7, 8, 9, // planar poly + 0, 4, 3, 8, 9, 5, // non-planar poly + 3, 2, 7, 8, // quad + 5, 6, 1, 0, // quad + 6, 7, 1, // tri + 7, 2, 1 }; // tri + + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 8, 1); + conns_arr->SetArray(face_conns, 30, 1); + faces->SetData(offsets_arr, conns_arr); + aPolyhedron->SetCellFaces(faces); aPolyhedron->Initialize(); return aPolyhedron; @@ -126,9 +157,9 @@ vtkSmartPointer<vtkPolyhedron> MakeConcaveNonPlanarPolyhedron() //------------------------------------------------------------------------------ bool TestPolyhedron(vtkPolyhedron* poly, int expectedNbOfFaces, int expectedNbOfEdges) { - vtkNew<vtkIdList> newFaces; + vtkNew<vtkCellArray> newFaces; poly->TriangulateFaces(newFaces); - poly->SetFaces(newFaces->GetPointer(0)); + poly->SetCellFaces(newFaces); poly->Initialize(); if (poly->GetNumberOfFaces() != expectedNbOfFaces) diff --git a/Common/DataModel/Testing/Cxx/UnitTestCells.cxx b/Common/DataModel/Testing/Cxx/UnitTestCells.cxx index 1b28209f51d7da44425458318f79e0fd553d17ed..3f4f247d5422301fa0902f786cdc39a21dee4503 100644 --- a/Common/DataModel/Testing/Cxx/UnitTestCells.cxx +++ b/Common/DataModel/Testing/Cxx/UnitTestCells.cxx @@ -44,6 +44,7 @@ #include "vtkCubicLine.h" #include "vtkCellArray.h" +#include "vtkIdTypeArray.h" #include "vtkMath.h" #include "vtkMathUtilities.h" #include "vtkPoints.h" @@ -753,17 +754,23 @@ vtkSmartPointer<vtkPolyhedron> MakeCube() aCube->GetPoints()->SetPoint(6, 1.0, 1.0, 1.0); aCube->GetPoints()->SetPoint(7, -1.0, 1.0, 1.0); - vtkIdType faces[31] = { - 6, // number of faces - 4, 0, 3, 2, 1, // - 4, 0, 4, 7, 3, // - 4, 4, 5, 6, 7, // - 4, 5, 1, 2, 6, // - 4, 0, 1, 5, 4, // - 4, 2, 3, 7, 6 // + vtkIdType face_offsets[7] = { 0, 4, 8, 12, 16, 20, 24 }; + vtkIdType face_conns[24] = { + 0, 3, 2, 1, // + 0, 4, 7, 3, // + 4, 5, 6, 7, // + 5, 1, 2, 6, // + 0, 1, 5, 4, // + 2, 3, 7, 6 // }; - - aCube->SetFaces(faces); + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 7, 1); + conns_arr->SetArray(face_conns, 24, 1); + faces->SetData(offsets_arr, conns_arr); + + aCube->SetCellFaces(faces); aCube->Initialize(); return aCube; @@ -802,23 +809,29 @@ vtkSmartPointer<vtkPolyhedron> MakeDodecahedron() aDodecahedron->GetPoints()->InsertNextPoint(-0.375185, -1.1547, -1.58931); aDodecahedron->GetPoints()->InsertNextPoint(0.982247, -0.713644, -1.58931); - vtkIdType faces[73] = { - 12, // number of faces - 5, 0, 1, 2, 3, 4, // number of ids on face, ids - 5, 0, 5, 10, 6, 1, // - 5, 1, 6, 11, 7, 2, // - 5, 2, 7, 12, 8, 3, // - 5, 3, 8, 13, 9, 4, // - 5, 4, 9, 14, 5, 0, // - 5, 15, 10, 5, 14, 19, // - 5, 16, 11, 6, 10, 15, // - 5, 17, 12, 7, 11, 16, // - 5, 18, 13, 8, 12, 17, // - 5, 19, 14, 9, 13, 18, // - 5, 19, 18, 17, 16, 15 // + vtkIdType face_offsets[13] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 }; + vtkIdType face_conns[60] = { + 0, 1, 2, 3, 4, // ids + 0, 5, 10, 6, 1, // + 1, 6, 11, 7, 2, // + 2, 7, 12, 8, 3, // + 3, 8, 13, 9, 4, // + 4, 9, 14, 5, 0, // + 15, 10, 5, 14, 19, // + 16, 11, 6, 10, 15, // + 17, 12, 7, 11, 16, // + 18, 13, 8, 12, 17, // + 19, 14, 9, 13, 18, // + 19, 18, 17, 16, 15 // }; - - aDodecahedron->SetFaces(faces); + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 13, 1); + conns_arr->SetArray(face_conns, 60, 1); + faces->SetData(offsets_arr, conns_arr); + + aDodecahedron->SetCellFaces(faces); aDodecahedron->Initialize(); return aDodecahedron; diff --git a/Filters/Core/vtkExtractCells.cxx b/Filters/Core/vtkExtractCells.cxx index c1037b6cfc70ed03a01eff8c31dac5d937d84000..f191892af9870e13d84548d9582e993a5a87543f 100644 --- a/Filters/Core/vtkExtractCells.cxx +++ b/Filters/Core/vtkExtractCells.cxx @@ -35,8 +35,8 @@ struct ExtractedCellsT { vtkSmartPointer<vtkCellArray> Connectivity; vtkSmartPointer<vtkUnsignedCharArray> CellTypes; - vtkSmartPointer<vtkIdTypeArray> Faces; - vtkSmartPointer<vtkIdTypeArray> FaceLocations; + vtkSmartPointer<vtkCellArray> PolyFaces; + vtkSmartPointer<vtkCellArray> PolyFaceLocations; }; //============================================================================= @@ -304,65 +304,87 @@ void ExtractPolyhedralFaces( ExtractedCellsT& result, vtkUnstructuredGrid* input, const CellWorkT& work) { const auto numCells = work.GetNumberOfCells(); - auto inFaceLocations = input->GetFaceLocations(); - auto inFaces = input->GetFaces(); + auto inFaceLocations = input->GetPolyhedronFaceLocations(); + auto inFaces = input->GetPolyhedronFaces(); - result.FaceLocations.TakeReference(vtkIdTypeArray::New()); - result.FaceLocations->SetNumberOfTuples(numCells); + vtkNew<vtkIdTypeArray> connectivityPoly; + vtkNew<vtkIdTypeArray> offsetsPoly; + vtkNew<vtkIdTypeArray> connectivityPolyFaces; + vtkNew<vtkIdTypeArray> offsetsPolyFaces; vtkIdType outFacesSize = 0; + vtkIdType outFaceLocSize = 0; + for (vtkIdType cc = 0; cc < numCells; ++cc) { - const auto loc = inFaceLocations->GetValue(work.GetCellId(cc)); - if (loc == -1) + const auto size = inFaceLocations->GetCellSize(work.GetCellId(cc)); + if (size != 0) { - // not a polyhedral cell - result.FaceLocations->SetTypedComponent(cc, 0, -1); + outFaceLocSize += size; } - else + } + offsetsPoly->SetNumberOfValues(numCells + 1); + connectivityPoly->SetNumberOfValues(outFaceLocSize); + offsetsPoly->SetValue(0, 0); + // Prepare polyhedron cells offsets + vtkIdType facePos = 0; + vtkNew<vtkIdList> faceIds; + for (vtkIdType cc = 0; cc < numCells; ++cc) + { + const auto size = inFaceLocations->GetCellSize(work.GetCellId(cc)); + if (size != 0) { - result.FaceLocations->SetTypedComponent(cc, 0, outFacesSize); - vtkIdType* pfaces_start = inFaces->GetPointer(loc); - vtkIdType* pfaces = pfaces_start; - const auto nfaces = (*pfaces++); + vtkIdType nfaces; + const vtkIdType* faces; + inFaceLocations->GetCellAtId(work.GetCellId(cc), nfaces, faces, faceIds); for (vtkIdType face = 0; face < nfaces; ++face) { - const auto npts = (*pfaces++); - pfaces += npts; + outFacesSize += static_cast<vtkIdType>(inFaces->GetCellSize(faces[face])); + // Store local to global faceId for later reuse + connectivityPoly->SetValue(facePos, faces[face]); + facePos++; } - outFacesSize += static_cast<vtkIdType>(std::distance(pfaces_start, pfaces)); } + offsetsPoly->SetValue(cc + 1, facePos); + } + faceIds->Initialize(); + offsetsPolyFaces->SetNumberOfValues(outFaceLocSize + 1); + connectivityPolyFaces->SetNumberOfValues(outFacesSize); + connectivityPolyFaces->FillValue(0); + offsetsPolyFaces->SetValue(0, 0); + // Prepare offsets needed for SMPTools + facePos = 0; + for (vtkIdType face = 0; face < outFaceLocSize; ++face) + { + const auto size = inFaces->GetCellSize(connectivityPoly->GetValue(face)); + facePos += size; + offsetsPolyFaces->SetValue(face + 1, facePos); } - // Now copy polyhedron Faces. - result.Faces.TakeReference(vtkIdTypeArray::New()); - result.Faces->SetNumberOfTuples(outFacesSize); - - vtkSMPTools::For(0, numCells, [&](vtkIdType start, vtkIdType end) { + vtkSMPTools::For(0, outFaceLocSize, [&](vtkIdType start, vtkIdType end) { + vtkNew<vtkIdList> facePts; for (vtkIdType cc = start; cc < end; ++cc) { - const auto inLoc = inFaceLocations->GetValue(work.GetCellId(cc)); - if (inLoc == -1) - { - continue; - } - const auto outLoc = result.FaceLocations->GetValue(cc); - - auto iptr = inFaces->GetPointer(inLoc); - auto optr = result.Faces->GetPointer(outLoc); - const auto nfaces = *iptr++; - *optr++ = nfaces; - for (vtkIdType face = 0; face < nfaces; ++face) - { - const auto npts = (*iptr++); - *optr++ = npts; - std::transform( - iptr, iptr + npts, optr, [&work](vtkIdType id) { return work.GetPointId(id); }); - optr += npts; - iptr += npts; - } + vtkIdType npts; + const vtkIdType* pts; + vtkIdType faceId = connectivityPoly->GetValue(cc); + inFaces->GetCellAtId(faceId, npts, pts, facePts); + const auto loc = offsetsPolyFaces->GetValue(cc); + auto optr = connectivityPolyFaces->GetPointer(loc); + std::transform(pts, pts + npts, optr, [&work](vtkIdType id) { return work.GetPointId(id); }); } }); + // Finalize the mapping to local faces + facePos = 0; + for (vtkIdType face = 0; face < outFaceLocSize; ++face) + { + connectivityPoly->SetValue(face, face); + } + // Prepare return result + result.PolyFaceLocations.TakeReference(vtkCellArray::New()); + result.PolyFaceLocations->SetData(offsetsPoly, connectivityPoly); + result.PolyFaces.TakeReference(vtkCellArray::New()); + result.PolyFaces->SetData(offsetsPolyFaces, connectivityPolyFaces); } //------------------------------------------------------------------------------ @@ -668,12 +690,13 @@ int vtkExtractCells::RequestData(vtkInformation* vtkNotUsed(request), // Handle polyhedral cells auto inputUG = vtkUnstructuredGrid::SafeDownCast(input); - if (inputUG && inputUG->GetFaces() && inputUG->GetFaceLocations() && - inputUG->GetFaceLocations()->GetRange(0)[1] != -1) + if (inputUG && inputUG->GetPolyhedronFaces() && inputUG->GetPolyhedronFaceLocations() && + inputUG->GetPolyhedronFaceLocations()->GetOffsetsArray()->GetRange(0)[1] != 0) { ::ExtractPolyhedralFaces(cells, inputUG, work); } - output->SetCells(cells.CellTypes, cells.Connectivity, cells.FaceLocations, cells.Faces); + output->SetPolyhedralCells( + cells.CellTypes, cells.Connectivity, cells.PolyFaceLocations, cells.PolyFaces); this->UpdateProgress(1.00); return 1; @@ -713,7 +736,7 @@ bool vtkExtractCells::Copy(vtkDataSet* input, vtkUnstructuredGrid* output) const auto numCells = input->GetNumberOfCells(); auto cells = ::ExtractCells(input, AllElementsWork{ 0, numCells }, this->BatchSize); - output->SetCells(cells.CellTypes, cells.Connectivity, nullptr, nullptr); + output->SetPolyhedralCells(cells.CellTypes, cells.Connectivity, nullptr, nullptr); // copy cell/point arrays. output->GetPointData()->ShallowCopy(input->GetPointData()); diff --git a/Filters/Core/vtkPolyDataToUnstructuredGrid.cxx b/Filters/Core/vtkPolyDataToUnstructuredGrid.cxx index 3a7995a6a54a8d6e6aa9b223ccbfaaaba6ebe85d..2325ccfe3b26cc856666470c8b1dce48618596de 100644 --- a/Filters/Core/vtkPolyDataToUnstructuredGrid.cxx +++ b/Filters/Core/vtkPolyDataToUnstructuredGrid.cxx @@ -213,19 +213,19 @@ int vtkPolyDataToUnstructuredGrid::RequestData( if (hasOnlyVerts) { - output->SetCells(cellTypes, input->GetVerts(), nullptr, nullptr); + output->SetPolyhedralCells(cellTypes, input->GetVerts(), nullptr, nullptr); } else if (hasOnlyLines) { - output->SetCells(cellTypes, input->GetLines(), nullptr, nullptr); + output->SetPolyhedralCells(cellTypes, input->GetLines(), nullptr, nullptr); } else if (hasOnlyPolys) { - output->SetCells(cellTypes, input->GetPolys(), nullptr, nullptr); + output->SetPolyhedralCells(cellTypes, input->GetPolys(), nullptr, nullptr); } else if (hasOnlyStrips) { - output->SetCells(cellTypes, input->GetStrips(), nullptr, nullptr); + output->SetPolyhedralCells(cellTypes, input->GetStrips(), nullptr, nullptr); } else { @@ -276,7 +276,7 @@ int vtkPolyDataToUnstructuredGrid::RequestData( vtkNew<vtkCellArray> cellArray; cellArray->SetData(offsets, connectivity); // set cells - output->SetCells(cellTypes, cellArray, nullptr, nullptr); + output->SetPolyhedralCells(cellTypes, cellArray, nullptr, nullptr); } this->UpdateProgress(0.95); diff --git a/Filters/Core/vtkRemoveUnusedPoints.cxx b/Filters/Core/vtkRemoveUnusedPoints.cxx index 674b800813f12dc26b9c26c84c609b080bfe22cc..cf2e1188ba98855088e8802334455171257d33cf 100644 --- a/Filters/Core/vtkRemoveUnusedPoints.cxx +++ b/Filters/Core/vtkRemoveUnusedPoints.cxx @@ -99,8 +99,8 @@ bool CopyConnectivity(vtkUnstructuredGrid* input, vtkUnstructuredGrid* output, auto inCellArray = input->GetCells(); auto inConnectivity = inCellArray->GetConnectivityArray(); auto inOffsets = inCellArray->GetOffsetsArray(); - auto inFaces = input->GetFaces(); - auto inFaceLocations = input->GetFaceLocations(); + auto inFaces = input->GetPolyhedronFaces(); + auto inFaceLocations = input->GetPolyhedronFaceLocations(); vtkSmartPointer<vtkDataArray> outConnectivity; outConnectivity.TakeReference(inConnectivity->NewInstance()); @@ -115,23 +115,30 @@ bool CopyConnectivity(vtkUnstructuredGrid* input, vtkUnstructuredGrid* output, return false; } - vtkSmartPointer<vtkIdTypeArray> outFaces; + vtkSmartPointer<vtkCellArray> outFaces; if (inFaces) { - using SupportedFacesArrays = vtkTypeList::Create<vtkIdTypeArray>; - outFaces.TakeReference(vtkIdTypeArray::New()); - outFaces->SetNumberOfComponents(inFaces->GetNumberOfComponents()); - outFaces->SetNumberOfTuples(inFaces->GetNumberOfTuples()); + auto inFacesConnectivity = inFaces->GetConnectivityArray(); + vtkSmartPointer<vtkDataArray> outFacesConnectivity; + outFacesConnectivity.TakeReference(inFacesConnectivity->NewInstance()); + outFacesConnectivity->SetNumberOfComponents(inFacesConnectivity->GetNumberOfComponents()); + outFacesConnectivity->SetNumberOfTuples(inFacesConnectivity->GetNumberOfTuples()); + + using SupportedFacesArrays = vtkCellArray::StorageArrayList; using DispatchFaces = vtkArrayDispatch::DispatchByArray<SupportedFacesArrays>; - if (!DispatchFaces::Execute(inFaces, worker, outFaces, pointMap, filter)) + + if (!DispatchFaces::Execute( + inFacesConnectivity, worker, outFacesConnectivity, pointMap, filter)) { return false; } + outFaces = vtkSmartPointer<vtkCellArray>::New(); + outFaces->SetData(inFaces->GetOffsetsArray(), outFacesConnectivity); } vtkNew<vtkCellArray> outCellArray; outCellArray->SetData(inOffsets, outConnectivity); - output->SetCells(input->GetCellTypesArray(), outCellArray, inFaceLocations, outFaces); + output->SetPolyhedralCells(input->GetCellTypesArray(), outCellArray, inFaceLocations, outFaces); return true; } } diff --git a/Filters/Core/vtkStaticCleanUnstructuredGrid.cxx b/Filters/Core/vtkStaticCleanUnstructuredGrid.cxx index 6ca160919d9a2d2857a9e970bd88f00ce90bad3f..896560e28e432a11316d6045011f285b08d7302a 100644 --- a/Filters/Core/vtkStaticCleanUnstructuredGrid.cxx +++ b/Filters/Core/vtkStaticCleanUnstructuredGrid.cxx @@ -313,25 +313,9 @@ void UpdateCellArrayConnectivity(vtkCellArray* ca, vtkIdType* ptMap) } // Update the polyhedra face connectivity array. -void UpdatePolyhedraFaces(vtkIdTypeArray* a, vtkIdType* ptMap) +void UpdatePolyhedraFaces(vtkCellArray* a, vtkIdType* ptMap) { - vtkIdType num = a->GetNumberOfTuples(); - vtkIdType* c = a->GetPointer(0); - - for (vtkIdType idx = 0; idx < num;) - { - vtkIdType numFaces = c[idx++]; - vtkIdType npts; - for (vtkIdType faceNum = 0; faceNum < numFaces; ++faceNum) - { - npts = c[idx++]; - for (vtkIdType i = 0; i < npts; ++i) - { - c[idx + i] = ptMap[c[idx + i]]; - } - idx += npts; - } - } + UpdateCellArrayConnectivity(a, ptMap); } } // anonymous namespace @@ -523,15 +507,15 @@ int vtkStaticCleanUnstructuredGrid::RequestData(vtkInformation* vtkNotUsed(reque // If the unstructured grid contains polyhedra, the face connectivity needs // to be updated as well. - vtkIdTypeArray* faceLocations = input->GetFaceLocations(); - vtkIdTypeArray* faces = input->GetFaces(); + vtkCellArray* faceLocations = input->GetPolyhedronFaceLocations(); + vtkCellArray* faces = input->GetPolyhedronFaces(); if (faces != nullptr) { UpdatePolyhedraFaces(faces, pmap); } // Finally, assemble the filter output. - output->SetCells(input->GetCellTypesArray(), outCells, faceLocations, faces); + output->SetPolyhedralCells(input->GetCellTypesArray(), outCells, faceLocations, faces); // Free unneeded memory this->Locator->Initialize(); diff --git a/Filters/General/Testing/Cxx/TestCellValidator.cxx b/Filters/General/Testing/Cxx/TestCellValidator.cxx index 78e2960599840c65d5b2eaffb312c9673852ce17..44bf54c2b7b56aa7c543df858d7089959a3afab7 100644 --- a/Filters/General/Testing/Cxx/TestCellValidator.cxx +++ b/Filters/General/Testing/Cxx/TestCellValidator.cxx @@ -898,17 +898,22 @@ vtkSmartPointer<vtkPolyhedron> MakeCube() aCube->GetPoints()->SetPoint(6, 1.0, 1.0, 1.0); aCube->GetPoints()->SetPoint(7, -1.0, 1.0, 1.0); - vtkIdType faces[31] = { - 6, // number of faces - 4, 0, 3, 2, 1, // - 4, 0, 4, 7, 3, // - 4, 4, 5, 6, 7, // - 4, 5, 1, 2, 6, // - 4, 0, 1, 5, 4, // - 4, 2, 3, 7, 6 // + vtkIdType face_offsets[7] = { 0, 4, 8, 12, 16, 20, 24 }; + vtkIdType face_conns[24] = { + 0, 3, 2, 1, // + 0, 4, 7, 3, // + 4, 5, 6, 7, // + 5, 1, 2, 6, // + 0, 1, 5, 4, // + 2, 3, 7, 6 // }; - - aCube->SetFaces(faces); + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 7, 1); + conns_arr->SetArray(face_conns, 24, 1); + faces->SetData(offsets_arr, conns_arr); + aCube->SetCellFaces(faces); aCube->Initialize(); return aCube; @@ -947,23 +952,28 @@ vtkSmartPointer<vtkPolyhedron> MakeDodecahedron() aDodecahedron->GetPoints()->InsertNextPoint(-0.375185, -1.1547, -1.58931); aDodecahedron->GetPoints()->InsertNextPoint(0.982247, -0.713644, -1.58931); - vtkIdType faces[73] = { - 12, // number of faces - 5, 0, 1, 2, 3, 4, // number of ids on face, ids - 5, 0, 5, 10, 6, 1, // - 5, 1, 6, 11, 7, 2, // - 5, 2, 7, 12, 8, 3, // - 5, 3, 8, 13, 9, 4, // - 5, 4, 9, 14, 5, 0, // - 5, 15, 10, 5, 14, 19, // - 5, 16, 11, 6, 10, 15, // - 5, 17, 12, 7, 11, 16, // - 5, 18, 13, 8, 12, 17, // - 5, 19, 14, 9, 13, 18, // - 5, 19, 18, 17, 16, 15 // + vtkIdType face_offsets[13] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 }; + vtkIdType face_conns[60] = { + 0, 1, 2, 3, 4, // ids + 0, 5, 10, 6, 1, // + 1, 6, 11, 7, 2, // + 2, 7, 12, 8, 3, // + 3, 8, 13, 9, 4, // + 4, 9, 14, 5, 0, // + 15, 10, 5, 14, 19, // + 16, 11, 6, 10, 15, // + 17, 12, 7, 11, 16, // + 18, 13, 8, 12, 17, // + 19, 14, 9, 13, 18, // + 19, 18, 17, 16, 15 // }; - - aDodecahedron->SetFaces(faces); + vtkNew<vtkCellArray> faces; + vtkNew<vtkIdTypeArray> offsets_arr; + vtkNew<vtkIdTypeArray> conns_arr; + offsets_arr->SetArray(face_offsets, 13, 1); + conns_arr->SetArray(face_conns, 60, 1); + faces->SetData(offsets_arr, conns_arr); + aDodecahedron->SetCellFaces(faces); aDodecahedron->Initialize(); return aDodecahedron; diff --git a/Filters/General/vtkMergeCells.cxx b/Filters/General/vtkMergeCells.cxx index 4890f8281502a7efd22def8cc49c19d6c4ff69f8..2b27af258bc6e1f9b8a0b983b99265ce7a59e03c 100644 --- a/Filters/General/vtkMergeCells.cxx +++ b/Filters/General/vtkMergeCells.cxx @@ -346,24 +346,26 @@ vtkIdType vtkMergeCells::AddNewCellsUnstructuredGrid(vtkDataSet* set, vtkIdType* // Connectivity for the merged grid so far vtkCellArray* cellArray = nullptr; - vtkIdType* flocs = nullptr; - vtkIdType* faces = nullptr; + vtkCellArray* flocs = nullptr; + vtkCellArray* faces = nullptr; unsigned char* types = nullptr; vtkIdType numCells = 0; vtkIdType numConnections = 0; + vtkIdType numFaces = 0; vtkIdType numFacesConnections = 0; if (!firstSet) { cellArray = grid->GetCells(); types = grid->GetCellTypesArray()->GetPointer(0); - flocs = grid->GetFaceLocations() ? grid->GetFaceLocations()->GetPointer(0) : nullptr; - faces = grid->GetFaces() ? grid->GetFaces()->GetPointer(0) : nullptr; + flocs = grid->GetPolyhedronFaceLocations() ? grid->GetPolyhedronFaceLocations() : nullptr; + faces = grid->GetPolyhedronFaces() ? grid->GetPolyhedronFaces() : nullptr; numCells = cellArray->GetNumberOfCells(); numConnections = cellArray->GetNumberOfConnectivityIds(); - numFacesConnections = faces ? grid->GetFaces()->GetNumberOfValues() : 0; + numFacesConnections = faces ? grid->GetPolyhedronFaces()->GetNumberOfConnectivityIds() : 0; + numFaces = faces ? grid->GetPolyhedronFaces()->GetNumberOfCells() : 0; } // New output grid: merging of existing and incoming grids @@ -390,28 +392,29 @@ vtkIdType vtkMergeCells::AddNewCellsUnstructuredGrid(vtkDataSet* set, vtkIdType* } // FACES LOCATION ARRAY - vtkNew<vtkIdTypeArray> facesLocationArray; - facesLocationArray->SetNumberOfValues(totalNumCells); + vtkNew<vtkCellArray> facesLocationArray; + facesLocationArray->Allocate(totalNumCells); + facesLocationArray->GetOffsetsArray()->SetNumberOfValues(totalNumCells + 1); if (!firstSet && flocs) { - vtkIdType* fiptr = facesLocationArray->GetPointer(0); // new output dataset - memcpy(fiptr, flocs, numCells * sizeof(vtkIdType)); // existing set + auto copycells = std::min(numCells, totalNumCells); + facesLocationArray->GetConnectivityArray()->DeepCopy(flocs->GetConnectivityArray()); + flocs->GetOffsetsArray()->GetTuples(0, copycells, facesLocationArray->GetOffsetsArray()); } else if (!firstSet) { - facesLocationArray->FillComponent(0, -1); + facesLocationArray->GetOffsetsArray()->FillComponent(0, 0); } bool havePolyhedron = false; // FACES ARRAY - vtkNew<vtkIdTypeArray> facesArray; - facesArray->SetNumberOfValues(numFacesConnections); + vtkNew<vtkCellArray> facesArray; + facesArray->Allocate(numFaces, numFacesConnections); if (!firstSet && faces) { havePolyhedron = true; - vtkIdType* faptr = facesArray->GetPointer(0); // new output dataset - memcpy(faptr, faces, numFacesConnections * sizeof(vtkIdType)); // existing set + facesArray->DeepCopy(faces); } // set up new cell data @@ -455,24 +458,34 @@ vtkIdType vtkMergeCells::AddNewCellsUnstructuredGrid(vtkDataSet* set, vtkIdType* const vtkIdType* ptIds; newGrid->GetFaceStream(oldCellId, nfaces, ptIds); - facesLocationArray->SetValue(finalCellId, facesArray->GetNumberOfValues()); - facesArray->InsertNextValue(nfaces); + auto faceLocOff = facesLocationArray->GetOffsetsArray(); + auto faceLocCon = facesLocationArray->GetConnectivityArray(); + + auto startFace = faceLocCon->GetNumberOfValues(); + faceLocOff->SetTuple1(finalCellId, startFace); + faceLocOff->SetTuple1(finalCellId + 1, startFace + nfaces); + for (vtkIdType loc = startFace; loc < startFace + nfaces; ++loc) + { + faceLocCon->InsertTuple1(loc, loc); + } for (vtkIdType i = 0; i < nfaces; i++) { vtkIdType nfpts = *ptIds++; - facesArray->InsertNextValue(nfpts); + facesArray->InsertNextCell(nfpts); for (vtkIdType j = 0; j < nfpts; j++) { oldPtId = *ptIds++; finalPtId = idMap ? idMap[oldPtId] : this->NumberOfPoints + oldPtId; - facesArray->InsertNextValue(finalPtId); + facesArray->InsertCellPoint(finalPtId); } } } else { - facesLocationArray->SetValue(finalCellId, -1); + // Hazardous... + vtkIdType tmp = facesLocationArray->GetOffsetsArray()->GetTuple1(finalCellId - 1); + facesLocationArray->GetOffsetsArray()->SetTuple1(finalCellId, tmp); } grid->GetCellData()->CopyData( @@ -483,11 +496,11 @@ vtkIdType vtkMergeCells::AddNewCellsUnstructuredGrid(vtkDataSet* set, vtkIdType* if (havePolyhedron) { - grid->SetCells(typeArray, finalCellArray, facesLocationArray, facesArray); + grid->SetPolyhedralCells(typeArray, finalCellArray, facesLocationArray, facesArray); } else { - grid->SetCells(typeArray, finalCellArray, nullptr, nullptr); + grid->SetPolyhedralCells(typeArray, finalCellArray, nullptr, nullptr); } if (duplicateCellIds) diff --git a/Filters/General/vtkTableBasedClipDataSet.cxx b/Filters/General/vtkTableBasedClipDataSet.cxx index 5bfae09bb2305436c51f171eaf18ff0c15e12452..a43a75472484c3d4229cd8ab4ce0444bf74f2aaf 100644 --- a/Filters/General/vtkTableBasedClipDataSet.cxx +++ b/Filters/General/vtkTableBasedClipDataSet.cxx @@ -1363,7 +1363,7 @@ vtkSmartPointer<vtkUnstructuredGrid> vtkTableBasedClipDataSet::ClipTDataSet( auto outputClippedCells = vtkSmartPointer<vtkUnstructuredGrid>::New(); outputClippedCells->SetPoints(outputPoints); outputClippedCells->GetPointData()->ShallowCopy(outputPointData); - outputClippedCells->SetCells(outputCellTypes, outputCellArray, nullptr, nullptr); + outputClippedCells->SetPolyhedralCells(outputCellTypes, outputCellArray, nullptr, nullptr); outputClippedCells->GetCellData()->ShallowCopy(outputCellData); // check if there are unsupported cell types diff --git a/Filters/HyperTree/vtkHyperTreeGridContour.cxx b/Filters/HyperTree/vtkHyperTreeGridContour.cxx index 394f1ee1582c71111ca59fb0797d711a9fbe213e..bd834c133d0b57b0b871a77ccd57d383417bc04e 100644 --- a/Filters/HyperTree/vtkHyperTreeGridContour.cxx +++ b/Filters/HyperTree/vtkHyperTreeGridContour.cxx @@ -56,7 +56,6 @@ const unsigned int* MooreCursors[3] = { // Conversion table of canonical ids from voxel to polyhedron constexpr vtkIdType CANONICAL_FACES[24] = { 2, 3, 1, 0, 1, 5, 4, 0, 4, 6, 2, 0, 3, 7, 5, 1, 2, 6, 7, 3, 5, 7, 6, 4 }; -constexpr std::size_t POLY_FACES_SIZE = 31; constexpr vtkIdType POLY_FACES_NB = 6; constexpr vtkIdType POLY_FACES_POINTS_NB = 4; constexpr vtkIdType POLY_POINTS_NB = 8; @@ -259,7 +258,7 @@ void ReplaceWithIndexedArray(const std::string& contourArrayName, vtkContourValu struct vtkHyperTreeGridContour::vtkInternals { // Temporary data structures related to USE_DECOMPOSED_POLYHEDRA strategy - std::vector<vtkIdType> Faces; + vtkNew<vtkCellArray> Faces; vtkNew<vtkPolyhedron> Polyhedron; vtkNew<vtkGenericCell> Tetra; vtkNew<vtkDoubleArray> TetraScalars; @@ -305,7 +304,7 @@ vtkHyperTreeGridContour::vtkHyperTreeGridContour() // Initialize temporal structures related to USE_DECOMPOSED_POLYHEDRA strategy this->Internals->Polyhedron->GetPointIds()->SetNumberOfIds(::POLY_POINTS_NB); this->Internals->Polyhedron->GetPoints()->SetNumberOfPoints(::POLY_POINTS_NB); - this->Internals->Faces.reserve(::POLY_FACES_SIZE); + this->Internals->Faces->AllocateExact(::POLY_FACES_NB, ::POLY_FACES_POINTS_NB * ::POLY_FACES_NB); } //------------------------------------------------------------------------------ @@ -887,18 +886,18 @@ void vtkHyperTreeGridContour::RecursivelyProcessTree( } // Construct faces from voxel point ids (global ids) - this->Internals->Faces.clear(); - this->Internals->Faces.emplace_back(::POLY_FACES_NB); + this->Internals->Faces->Reset(); for (int faceId = 0, canonicalId = 0; faceId < ::POLY_FACES_NB; faceId++) { - this->Internals->Faces.emplace_back(::POLY_FACES_POINTS_NB); + this->Internals->Faces->InsertNextCell(::POLY_FACES_POINTS_NB); for (int i = 0; i < ::POLY_FACES_POINTS_NB; i++, canonicalId++) { - this->Internals->Faces.emplace_back(cell->GetPointId(::CANONICAL_FACES[canonicalId])); + this->Internals->Faces->InsertCellPoint( + cell->GetPointId(::CANONICAL_FACES[canonicalId])); } } - this->Internals->Polyhedron->SetFaces(this->Internals->Faces.data()); + this->Internals->Polyhedron->SetCellFaces(this->Internals->Faces); this->Internals->Polyhedron->Initialize(); // Decompose the this->Internals->Polyhedron diff --git a/Filters/Parallel/vtkExtractUnstructuredGridPiece.cxx b/Filters/Parallel/vtkExtractUnstructuredGridPiece.cxx index 988b15291a33676d015dc79baa9955365467a070..2eb462ce97b56ecf57d302da9a7e06277ac427b6 100644 --- a/Filters/Parallel/vtkExtractUnstructuredGridPiece.cxx +++ b/Filters/Parallel/vtkExtractUnstructuredGridPiece.cxx @@ -160,6 +160,7 @@ int vtkExtractUnstructuredGridPiece::RequestData(vtkInformation* vtkNotUsed(requ vtkIdType numFaces; vtkIdType numFacePts; double* x; + vtkNew<vtkIdList> faceStreamList; // Pipeline update piece will tell us what to generate. ghostLevel = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()); @@ -263,7 +264,8 @@ int vtkExtractUnstructuredGridPiece::RequestData(vtkInformation* vtkNotUsed(requ } else { // Polyhedron, need to process face stream. - faceStream = input->GetFaces(cellId); + input->GetFaceStream(cellId, faceStreamList); + faceStream = faceStreamList->GetPointer(0); numFaces = *faceStream++; newCellPts->InsertNextId(numFaces); for (vtkIdType face = 0; face < numFaces; ++face) diff --git a/Filters/ParallelDIY2/Testing/Cxx/TestGhostCellsGenerator.cxx b/Filters/ParallelDIY2/Testing/Cxx/TestGhostCellsGenerator.cxx index 2464fe45eb031269f884c585ef80915641dc16a8..246f1e28eec9e8157f1a5cdf907ba53ba0f81579 100644 --- a/Filters/ParallelDIY2/Testing/Cxx/TestGhostCellsGenerator.cxx +++ b/Filters/ParallelDIY2/Testing/Cxx/TestGhostCellsGenerator.cxx @@ -1977,12 +1977,12 @@ vtkSmartPointer<vtkUnstructuredGrid> Convert3DImageToUnstructuredGrid( } const int* extent = input->GetExtent(); - vtkNew<vtkIdTypeArray> faces; - // half cells * number of faces in voxel [6] * (number of points in face + 1) [4 + 1] - faces->SetNumberOfValues((numberOfCells / 2) * (6 * 5 + 1)); + vtkNew<vtkCellArray> faces; + // half cells * number of faces in voxel [6] * (number of points in face) [4] + faces->AllocateExact((numberOfCells / 2) * 6, (numberOfCells / 2) * (6 * 4)); - vtkNew<vtkIdTypeArray> faceLocations; - faceLocations->SetNumberOfValues(numberOfCells); + vtkNew<vtkCellArray> faceLocations; + faceLocations->AllocateExact(numberOfCells, (numberOfCells / 2) * 6); vtkNew<vtkUnsignedCharArray> types; types->SetNumberOfValues(numberOfCells); @@ -2009,72 +2009,70 @@ vtkSmartPointer<vtkUnstructuredGrid> Convert3DImageToUnstructuredGrid( if (producePolyhedrons && cellId % 2) { - vtkIdType id = ((cellId / 2) * (5 * 6 + 1)); - faceLocations->SetValue(cellId, id); + vtkIdType pos = (cellId / 2) * 6; + faceLocations->InsertNextCell(6); // 6 faces. + faceLocations->InsertCellPoint(pos + 0); + faceLocations->InsertCellPoint(pos + 1); + faceLocations->InsertCellPoint(pos + 2); + faceLocations->InsertCellPoint(pos + 3); + faceLocations->InsertCellPoint(pos + 4); + faceLocations->InsertCellPoint(pos + 5); types->SetValue(cellId, VTK_POLYHEDRON); - faces->SetValue(id, 6); // 6 faces. - ++id; - vtkIdType offsetId = connectivityId - 8; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Bottom face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 0)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 1)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 3)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 2)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 0)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 1)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 3)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 2)); - id += 5; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Top face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 4)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 5)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 7)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 6)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 4)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 5)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 7)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 6)); - id += 5; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Front face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 0)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 1)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 5)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 4)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 0)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 1)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 5)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 4)); - id += 5; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Back face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 2)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 3)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 7)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 6)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 2)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 3)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 7)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 6)); - id += 5; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Left face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 0)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 2)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 6)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 4)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 0)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 2)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 6)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 4)); - id += 5; - faces->SetValue(id, 4); // 4 points per face. + faces->InsertNextCell(4); // 4 points per face. // Right face - faces->SetValue(id + 1, connectivity->GetValue(offsetId + 1)); - faces->SetValue(id + 2, connectivity->GetValue(offsetId + 3)); - faces->SetValue(id + 3, connectivity->GetValue(offsetId + 7)); - faces->SetValue(id + 4, connectivity->GetValue(offsetId + 5)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 1)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 3)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 7)); + faces->InsertCellPoint(connectivity->GetValue(offsetId + 5)); } else { - faceLocations->SetValue(cellId, -1); + faceLocations->InsertNextCell(0); types->SetValue(cellId, VTK_VOXEL); } } if (producePolyhedrons) { - output->SetCells(types, cells, faceLocations, faces); + output->SetPolyhedralCells(types, cells, faceLocations, faces); } else { diff --git a/Parallel/DIY/vtkDIYGhostUtilities.cxx b/Parallel/DIY/vtkDIYGhostUtilities.cxx index e095eaec84362d46d0a139f26c14e99db1872d2e..cc8b9f5bcd9a7c5d54991d8b4dba7c612f66f436 100644 --- a/Parallel/DIY/vtkDIYGhostUtilities.cxx +++ b/Parallel/DIY/vtkDIYGhostUtilities.cxx @@ -1926,11 +1926,36 @@ struct ComputePolyDataConnectivitySizeWorker vtkIdType TotalStripsSize = 0; }; +//---------------------------------------------------------------------------- +// Helper for ComputeFacesSizeWorker and UpdateCellBufferSize +namespace +{ +struct GetPolyhedronNPts +{ + // Insert full cell + template <typename CellStateT> + vtkIdType operator()(CellStateT& state, const vtkIdType cellId, const vtkCellArray* faces) + { + vtkIdType npts = 0; + + const vtkIdType beginOffset = state.GetBeginOffset(cellId); + const vtkIdType endOffset = state.GetEndOffset(cellId); + const vtkIdType NumberOfFaces = endOffset - beginOffset; + const auto cellFaces = state.GetConnectivity()->GetPointer(beginOffset); + + for (vtkIdType faceNum = 0; faceNum < NumberOfFaces; ++faceNum) + { + npts += faces->GetCellSize(static_cast<vtkIdType>(cellFaces[faceNum])); + } + return npts; + } +}; +} //============================================================================ struct ComputeFacesSizeWorker { - ComputeFacesSizeWorker(vtkIdTypeArray* faces, vtkIdTypeArray* faceLocations, + ComputeFacesSizeWorker(vtkCellArray* faces, vtkCellArray* faceLocations, vtkUnsignedCharArray* ghostCells) : Faces(faces) , FaceLocations(faceLocations) @@ -1941,20 +1966,17 @@ struct ComputeFacesSizeWorker void operator()(vtkIdType startId, vtkIdType endId) { vtkIdType& size = this->Size.Local(); + vtkIdType& facenum = this->FaceNum.Local(); + for (vtkIdType cellId = startId; cellId < endId; ++cellId) { if (!(this->GhostCells->GetValue(cellId) & ::GHOST_CELL_TO_PEEL_IN_UNSTRUCTURED_DATA)) { - vtkIdType id = this->FaceLocations->GetValue(cellId); - if (id != -1) + vtkIdType id = this->FaceLocations->GetCellSize(cellId); + if (id != 0) { - vtkIdType numberOfFaces = this->Faces->GetValue(id++); - size += numberOfFaces + 1; - for (vtkIdType faceId = 0; faceId < numberOfFaces; - ++faceId, id += this->Faces->GetValue(id) + 1) - { - size += this->Faces->GetValue(id); - } + facenum += this->FaceLocations->GetCellSize(cellId); + size += this->FaceLocations->Visit(GetPolyhedronNPts{}, cellId, this->Faces); } } } @@ -1963,6 +1985,7 @@ struct ComputeFacesSizeWorker void Initialize() { this->Size.Local() = 0; + this->FaceNum.Local() = 0; } void Reduce() @@ -1971,14 +1994,20 @@ struct ComputeFacesSizeWorker { this->TotalSize += size; } + for (const vtkIdType& size : this->FaceNum) + { + this->TotalFaceNum += size; + } } - vtkIdTypeArray* Faces; - vtkIdTypeArray* FaceLocations; + vtkCellArray* Faces; + vtkCellArray* FaceLocations; vtkUnsignedCharArray* GhostCells; vtkSMPThreadLocal<vtkIdType> Size; + vtkSMPThreadLocal<vtkIdType> FaceNum; vtkIdType TotalSize = 0; + vtkIdType TotalFaceNum = 0; }; #define ComputePolyDataConnectivitySizeWorkerMacro(mask) \ @@ -2142,25 +2171,28 @@ void InitializeInformationIdsForUnstructuredData(vtkUnstructuredGrid* input, info.InputConnectivitySize = worker.TotalSize; } - vtkIdTypeArray* faceLocations = input->GetFaceLocations(); - vtkIdTypeArray* faces = input->GetFaces(); + vtkCellArray* faceLocations = input->GetPolyhedronFaceLocations(); + vtkCellArray* faces = input->GetPolyhedronFaces(); - if (faceLocations && faceLocations->GetNumberOfValues() && faces && faces->GetNumberOfValues()) + if (faceLocations && faceLocations->GetNumberOfCells() && faces && faces->GetNumberOfCells()) { ::ComputeFacesSizeWorker worker(faces, faceLocations, ghosts); vtkSMPTools::For(0, numberOfCells, worker); info.InputFacesSize = worker.TotalSize; + info.InputNumberOfFaces = worker.TotalFaceNum; } } else { info.InputConnectivitySize = cells->GetConnectivityArray()->GetNumberOfTuples(); - info.InputFacesSize = input->GetFaces() ? input->GetFaces()->GetNumberOfValues() : 0; + info.InputFacesSize = input->GetPolyhedronFaces() ? input->GetPolyhedronFaces()->GetConnectivityArray()->GetNumberOfTuples() : 0; + info.InputNumberOfFaces = input->GetPolyhedronFaces() ? input->GetPolyhedronFaces()->GetOffsetsArray()->GetNumberOfTuples()-1 : 0; } info.CurrentConnectivitySize = info.InputConnectivitySize; info.CurrentFacesSize = info.InputFacesSize; + info.CurrentMaxFaceId = info.InputNumberOfFaces; } //---------------------------------------------------------------------------- @@ -2525,23 +2557,21 @@ struct FillUnstructuredDataTopologyBufferFunctor<InputArrayT, OutputArrayT, vtkU vtkCellArray* inputCellArray = input->GetCells(); vtkIdType outputId = 0; - vtkIdTypeArray* inputFaces = input->GetFaces(); - vtkIdTypeArray* inputFaceLocations = input->GetFaceLocations(); + vtkCellArray* inputFaces = input->GetPolyhedronFaces(); + vtkCellArray* inputFaceLocations = input->GetPolyhedronFaceLocations(); // faces and faceLocations deal with VTK_POLYHEDRON. If there are VTK_POLYHEDRON cells in the // input, we instantiate those arrays for our buffers. - if (inputFaces && inputFaces->GetNumberOfValues()) + if (inputFaces && inputFaces->GetNumberOfCells()) { - buffer.Faces = vtkSmartPointer<vtkIdTypeArray>::New(); - buffer.Faces->SetNumberOfValues(blockStructure.FacesSize); - buffer.FaceLocations = vtkSmartPointer<vtkIdTypeArray>::New(); - buffer.FaceLocations->SetNumberOfValues(numberOfCellsToSend); - buffer.FaceLocations->FillValue(-1); - + buffer.Faces = vtkSmartPointer<vtkCellArray>::New(); + buffer.Faces->AllocateExact(blockStructure.FacesNum, blockStructure.FacesSize); + buffer.FaceLocations = vtkSmartPointer<vtkCellArray>::New(); + buffer.FaceLocations->AllocateExact(numberOfCellsToSend, blockStructure.FacesNum); } - vtkIdTypeArray* faces = buffer.Faces; - vtkIdTypeArray* faceLocations = buffer.FaceLocations; + vtkCellArray* faces = buffer.Faces; + vtkCellArray* faceLocations = buffer.FaceLocations; vtkIdType currentFacesId = 0; @@ -2555,36 +2585,42 @@ struct FillUnstructuredDataTopologyBufferFunctor<InputArrayT, OutputArrayT, vtkU if (cellType == VTK_POLYHEDRON) { - faceLocations->SetValue(outputId, currentFacesId); - vtkIdType id = inputFaceLocations->GetValue(cellId); - vtkIdType numberOfFaces = inputFaces->GetValue(id++); - faces->SetValue(currentFacesId++, numberOfFaces); + vtkIdType numberOfFaces =0; + vtkIdType const* faceIds; + vtkNew<vtkIdList> faceTmp; + vtkNew<vtkIdList> ptsTmp; + inputFaceLocations->GetCellAtId(cellId, numberOfFaces, faceIds, faceTmp); + faceLocations->InsertNextCell(numberOfFaces); for (vtkIdType faceId = 0; faceId < numberOfFaces; ++faceId) { - vtkIdType numberOfPoints = inputFaces->GetValue(id++); - faces->SetValue(currentFacesId++, numberOfPoints); + vtkIdType numberOfPoints; + vtkIdType const* facePointIds; + inputFaces->GetCellAtId(faceIds[faceId], numberOfPoints, facePointIds, ptsTmp); + faceLocations->InsertCellPoint(currentFacesId++); + faces->InsertNextCell(numberOfPoints); for (vtkIdType facePointId = 0; facePointId < numberOfPoints; ++facePointId) { - vtkIdType pointId = inputFaces->GetValue(id + facePointId); + vtkIdType pointId = facePointIds[facePointId]; auto it = pointIdsToSendWithIndex.find(pointId); // We will find a valid it of the point of id pointId is not on the interface between us // and the current connected block if (it != pointIdsToSendWithIndex.end()) { - faces->SetValue(currentFacesId + facePointId, it->second); + faces->InsertCellPoint(it->second); } else { // We put a negative id here to tell the block who will receive this // that this point is part of the interfacing points: the neighboring block already owns // a copy of this point. - faces->SetValue(currentFacesId + facePointId, -seedPointIdsToSendWithIndex.at(pointId)); + faces->InsertCellPoint(-seedPointIdsToSendWithIndex.at(pointId)); } - } - currentFacesId += numberOfPoints; - id += numberOfPoints; + } } } + else if (faceLocations){ + faceLocations->InsertNextCell(0); + } types->SetValue(outputId++, cellType); } } @@ -2700,20 +2736,17 @@ void UpdateCellBufferSize<vtkUnstructuredGrid>(vtkIdType cellIdToSend, { blockStructure.ConnectivitySize += info.Input->GetCells()->GetCellSize(cellIdToSend); - vtkIdTypeArray* faces = info.Faces; - vtkIdTypeArray* faceLocations = info.FaceLocations; - if (faces && faceLocations && faceLocations->GetValue(cellIdToSend) != -1) // i.e. is polyhedron + vtkCellArray* faces = info.Faces; + vtkCellArray* faceLocations = info.FaceLocations; + if (faces && faceLocations && faceLocations->GetCellSize(cellIdToSend) != 0) // i.e. is polyhedron { vtkIdType& facesSize = blockStructure.FacesSize; - vtkIdType locationId = faceLocations->GetValue(cellIdToSend); - vtkIdType numberOfFaces = faces->GetValue(locationId++); - facesSize += 1 + numberOfFaces; - for (vtkIdType faceId = 0; faceId < numberOfFaces; ++faceId) - { - vtkIdType faceSize = faces->GetValue(locationId); - facesSize += faceSize; - locationId += faceSize + 1; - } + vtkIdType& facesNum = blockStructure.FacesNum; + vtkIdType numberOfFaces = 0; + // + numberOfFaces = faceLocations->GetCellSize(cellIdToSend); + facesNum += numberOfFaces; + facesSize += faceLocations->Visit(GetPolyhedronNPts{}, cellIdToSend, faces); } } @@ -3788,46 +3821,115 @@ void DeepCopyCells(vtkCellArray* inputCells, vtkCellArray* outputCells, } } + //---------------------------------------------------------------------------- -void DeepCopyPolyhedrons(vtkUnstructuredGrid* ug, vtkUnstructuredGrid* clone, - ::UnstructuredGridInformation& info) +template<class InputArrayT, class OutputArrayT> +void DeepCopyPolyhedronImpl(vtkCellArray* inputFaceLocations, vtkCellArray* inputFaces, + vtkCellArray* outputFaceLocations, vtkCellArray* outputFaces, + vtkIdList* cellRedirectionMap, vtkIdList* pointRedirectionMap) { - vtkIdTypeArray* ugFaceLocations = ug->GetFaceLocations(); - vtkIdTypeArray* cloneFaceLocations = clone->GetFaceLocations(); + InputArrayT* inputConnectivity = vtkArrayDownCast<InputArrayT>(inputFaceLocations->GetConnectivityArray()); + InputArrayT* inputOffsets = vtkArrayDownCast<InputArrayT>(inputFaceLocations->GetOffsetsArray()); + InputArrayT* inputFacesConnectivity = vtkArrayDownCast<InputArrayT>(inputFaces->GetConnectivityArray()); + InputArrayT* inputFacesOffsets = vtkArrayDownCast<InputArrayT>(inputFaces->GetOffsetsArray()); - vtkIdList* cellRedirectionMap = info.OutputToInputCellIdRedirectionMap; - vtkIdList* pointRedirectionMap = info.OutputToInputPointIdRedirectionMap; + OutputArrayT* outputConnectivity = vtkArrayDownCast<OutputArrayT>(outputFaceLocations->GetConnectivityArray()); + OutputArrayT* outputOffsets = vtkArrayDownCast<OutputArrayT>(outputFaceLocations->GetOffsetsArray()); + OutputArrayT* outputFacesConnectivity = vtkArrayDownCast<OutputArrayT>(outputFaces->GetConnectivityArray()); + OutputArrayT* outputFacesOffsets = vtkArrayDownCast<OutputArrayT>(outputFaces->GetOffsetsArray()); - ugFaceLocations->GetTuples(cellRedirectionMap, cloneFaceLocations); + auto inputConnectivityRange = vtk::DataArrayValueRange<1>(inputConnectivity); + auto inputOffsetsRange = vtk::DataArrayValueRange<1>(inputOffsets); + auto inputFacesRange = vtk::DataArrayValueRange<1>(inputFacesOffsets); + auto inputFacesConnectivityRange = vtk::DataArrayValueRange<1>(inputFacesConnectivity); - vtkIdType outputFacesId = 0; + auto outputConnectivityRange = vtk::DataArrayValueRange<1>(outputConnectivity); + auto outputOffsetsRange = vtk::DataArrayValueRange<1>(outputOffsets); + auto outputFacesRange = vtk::DataArrayValueRange<1>(outputFacesOffsets); + auto outputFacesConnectivityRange = vtk::DataArrayValueRange<1>(outputFacesConnectivity); - vtkIdTypeArray* ugFaces = ug->GetFaces(); - vtkIdTypeArray* cloneFaces = clone->GetFaces(); - for (vtkIdType outputCellId = 0; outputCellId < clone->GetNumberOfCells(); ++outputCellId) + vtkIdType outputFacesId = 0; + outputOffsetsRange[0] = 0; + outputFacesRange[0] = 0; + for (vtkIdType outputCellId = 0; outputCellId < cellRedirectionMap->GetNumberOfIds(); ++outputCellId) { - if (cloneFaceLocations->GetValue(outputCellId) != -1) - { - vtkIdType inputCellId = cellRedirectionMap->GetId(outputCellId); - vtkIdType inputFacesId = ugFaceLocations->GetValue(inputCellId); - vtkIdType numberOfFaces = ugFaces->GetValue(inputFacesId++); - cloneFaces->SetValue(outputFacesId++, numberOfFaces); - - for (vtkIdType faceId = 0; faceId < numberOfFaces; ++faceId) - { - vtkIdType numberOfPoints = ugFaces->GetValue(inputFacesId++); - cloneFaces->SetValue(outputFacesId++, numberOfPoints); - - for (vtkIdType pointId = 0; pointId < numberOfPoints; ++pointId) + vtkIdType inputCellId = cellRedirectionMap->GetId(outputCellId); + vtkIdType inputOffset = inputOffsetsRange[inputCellId]; + vtkIdType nextInputOffset = inputOffsetsRange[inputCellId + 1]; + vtkIdType cellSize = nextInputOffset - inputOffset; + outputOffsetsRange[outputCellId + 1] = outputOffsetsRange[outputCellId] + cellSize; + vtkIdType outputOffset = outputOffsetsRange[outputCellId]; + // Prepare cloneFaceLocations + for (vtkIdType faceId = 0; faceId < cellSize; ++faceId) + { + outputConnectivityRange[outputOffset + faceId] = outputFacesId++; + } + // copy polyhedron faces + for (vtkIdType faceSrcId = inputOffset, faceDstId = outputConnectivityRange[outputOffset] ; faceSrcId < nextInputOffset; ++faceSrcId, ++faceDstId) + { + vtkIdType faceSrcLoc = inputConnectivityRange[faceSrcId]; + vtkIdType faceSrcOffset = inputFacesRange[faceSrcLoc]; + vtkIdType nextSrcFaceOffset = inputFacesRange[faceSrcLoc+1]; + outputFacesRange[faceDstId+1] = outputFacesRange[faceDstId] + (nextSrcFaceOffset-faceSrcOffset); + for (vtkIdType pointSrcId=faceSrcOffset, pointDestId=outputFacesRange[faceDstId]; pointSrcId < nextSrcFaceOffset; ++pointSrcId, ++pointDestId) { - cloneFaces->SetValue(outputFacesId + pointId, - pointRedirectionMap->GetId(ugFaces->GetValue(inputFacesId + pointId))); + outputFacesConnectivityRange[pointDestId] = pointRedirectionMap->GetId(inputFacesConnectivityRange[pointSrcId]); } - } } } } +//---------------------------------------------------------------------------- +void DeepCopyPolyhedrons(vtkUnstructuredGrid* ug, vtkUnstructuredGrid* clone, + ::UnstructuredGridInformation& info) +{ + + using ArrayType32 = vtkCellArray::ArrayType32; + using ArrayType64 = vtkCellArray::ArrayType64; + + vtkCellArray* ugFaceLocations = ug->GetPolyhedronFaceLocations(); + vtkCellArray* ugFaces = ug->GetPolyhedronFaces(); + vtkCellArray* cloneFaceLocations = clone->GetPolyhedronFaceLocations(); + vtkCellArray* cloneFaces = clone->GetPolyhedronFaces(); + + vtkIdList* cellRedirectionMap = info.OutputToInputCellIdRedirectionMap; + vtkIdList* pointRedirectionMap = info.OutputToInputPointIdRedirectionMap; + + // Protection against mismatch storage + if (ugFaceLocations->IsStorage64Bit() != ugFaces->IsStorage64Bit()) + { + ugFaceLocations->ConvertTo64BitStorage(); + ugFaces->ConvertTo64BitStorage(); + } + if (cloneFaceLocations->IsStorage64Bit() != cloneFaces->IsStorage64Bit()) + { + cloneFaceLocations->ConvertTo64BitStorage(); + cloneFaces->ConvertTo64BitStorage(); + } + + // compute storage mask + int mask = static_cast<int>(ugFaceLocations->IsStorage64Bit()) | (static_cast<int>(cloneFaceLocations->IsStorage64Bit()) << 1); + + switch(mask) + { + case 0: + ::DeepCopyPolyhedronImpl<ArrayType32, ArrayType32>(ugFaceLocations, ugFaces, cloneFaceLocations, cloneFaces, cellRedirectionMap, + pointRedirectionMap); + break; + case 1: + ::DeepCopyPolyhedronImpl<ArrayType64, ArrayType32>(ugFaceLocations, ugFaces, cloneFaceLocations, cloneFaces, cellRedirectionMap, + pointRedirectionMap); + break; + case 2: + ::DeepCopyPolyhedronImpl<ArrayType32, ArrayType64>(ugFaceLocations, ugFaces, cloneFaceLocations, cloneFaces, cellRedirectionMap, + pointRedirectionMap); + break; + case 3: + ::DeepCopyPolyhedronImpl<ArrayType64, ArrayType64>(ugFaceLocations, ugFaces, cloneFaceLocations, cloneFaces, cellRedirectionMap, + pointRedirectionMap); + break; + } +} //---------------------------------------------------------------------------- /** @@ -3842,14 +3944,56 @@ void CloneUnstructuredGrid(vtkUnstructuredGrid* ug, vtkUnstructuredGrid* clone, ::ClonePoints(ug, clone, info); ::CloneCellData(ug, clone, info); + if (!ug->GetPolyhedronFaces() && clone->GetPolyhedronFaces() + && clone->GetPolyhedronFaceLocations()) + { + //initialize empty polyhedron when none are present but they are required for output. + using ArrayType32 = vtkCellArray::ArrayType32; + using ArrayType64 = vtkCellArray::ArrayType64; + + if (clone->GetPolyhedronFaceLocations()->IsStorage64Bit()) + { + auto faceLocRange = vtkArrayDownCast<ArrayType64>(clone->GetPolyhedronFaceLocations()->GetOffsetsArray()); + for (vtkIdType pos=0; pos<ug->GetNumberOfCells()+1; ++pos) + { + faceLocRange->SetValue(pos, 0); + } + } + else + { + auto faceLocRange = vtkArrayDownCast<ArrayType32>(clone->GetPolyhedronFaceLocations()->GetOffsetsArray()); + for (vtkIdType pos=0; pos<ug->GetNumberOfCells()+1; ++pos) + { + faceLocRange->SetValue(pos, 0); + } + } + + if (clone->GetPolyhedronFaces()->IsStorage64Bit()) + { + auto faceLocRange = vtkArrayDownCast<ArrayType64>(clone->GetPolyhedronFaces()->GetOffsetsArray()); + for (vtkIdType pos=0; pos<clone->GetPolyhedronFaces()->GetOffsetsArray()->GetNumberOfTuples(); ++pos) + { + faceLocRange->SetValue(pos, 0); + } + } + else + { + auto faceLocRange = vtkArrayDownCast<ArrayType32>(clone->GetPolyhedronFaces()->GetOffsetsArray()); + for (vtkIdType pos=0; pos<clone->GetPolyhedronFaces()->GetOffsetsArray()->GetNumberOfTuples(); ++pos) + { + faceLocRange->SetValue(pos, 0); + } + } + } + if (vtkIdList* redirectionMap = info.OutputToInputCellIdRedirectionMap) { ::DeepCopyCells(ug->GetCells(), clone->GetCells(), redirectionMap, info.InputToOutputPointIdRedirectionMap); ug->GetCellTypesArray()->GetTuples(redirectionMap, clone->GetCellTypesArray()); - vtkIdTypeArray* ugFaceLocations = ug->GetFaceLocations(); - if (clone->GetFaceLocations() && ugFaceLocations && ugFaceLocations->GetNumberOfValues()) + vtkCellArray* ugFaceLocations = ug->GetPolyhedronFaceLocations(); + if (clone->GetPolyhedronFaceLocations() && ugFaceLocations && ugFaceLocations->GetNumberOfCells()) { ::DeepCopyPolyhedrons(ug, clone, info); } @@ -3861,16 +4005,22 @@ void CloneUnstructuredGrid(vtkUnstructuredGrid* ug, vtkUnstructuredGrid* clone, vtkDataArray* ugConnectivity = ugCellArray->GetConnectivityArray(); vtkDataArray* ugOffsets = ugCellArray->GetOffsetsArray(); - ugConnectivity->GetTuples(0, ugConnectivity->GetNumberOfTuples() - 1, - cloneCellArray->GetConnectivityArray()); + ugConnectivity->GetTuples(0, ugConnectivity->GetNumberOfTuples() - 1, cloneCellArray->GetConnectivityArray()); ugOffsets->GetTuples(0, ugOffsets->GetNumberOfTuples() - 1, cloneCellArray->GetOffsetsArray()); ug->GetCellTypesArray()->GetTuples(0, ug->GetNumberOfCells() - 1, clone->GetCellTypesArray()); - vtkIdTypeArray* ugFaces = ug->GetFaces(); - if (clone->GetFaces() && ugFaces && ugFaces->GetNumberOfValues()) + vtkCellArray* ugFaces = ug->GetPolyhedronFaces(); + + if (clone->GetPolyhedronFaces() && ugFaces && ugFaces->GetNumberOfCells()) { - ug->GetFaceLocations()->GetTuples(0, ug->GetNumberOfCells() - 1, clone->GetFaceLocations()); - ug->GetFaces()->GetTuples(0, ug->GetFaces()->GetNumberOfValues() - 1, clone->GetFaces()); + vtkDataArray* ugFaceConnectivity = ug->GetPolyhedronFaces()->GetConnectivityArray(); + vtkDataArray* ugFaceOffsets = ug->GetPolyhedronFaces()->GetOffsetsArray(); + vtkDataArray* ugPolyConnectivity = ug->GetPolyhedronFaceLocations()->GetConnectivityArray(); + vtkDataArray* ugPolyOffsets = ug->GetPolyhedronFaceLocations()->GetOffsetsArray(); + ugFaceConnectivity->GetTuples(0, ugFaceConnectivity->GetNumberOfTuples() - 1, clone->GetPolyhedronFaces()->GetConnectivityArray()); + ugFaceOffsets->GetTuples(0, ugFaceOffsets->GetNumberOfTuples() - 1, clone->GetPolyhedronFaces()->GetOffsetsArray()); + ugPolyConnectivity->GetTuples(0, ugPolyConnectivity->GetNumberOfTuples() - 1, clone->GetPolyhedronFaceLocations()->GetConnectivityArray()); + ugPolyOffsets->GetTuples(0, ugPolyOffsets->GetNumberOfTuples() - 1, clone->GetPolyhedronFaceLocations()->GetOffsetsArray()); } } } @@ -4095,8 +4245,19 @@ void EnqueueCellsForUnstructuredData<vtkUnstructuredGrid>(const diy::Master::Pro cp.enqueue<vtkDataArray*>(blockId, buffer.Types); cp.enqueue<vtkDataArray*>(blockId, buffer.CellArray->GetOffsetsArray()); cp.enqueue<vtkDataArray*>(blockId, buffer.CellArray->GetConnectivityArray()); - cp.enqueue<vtkDataArray*>(blockId, buffer.Faces); - cp.enqueue<vtkDataArray*>(blockId, buffer.FaceLocations); + if (buffer.Faces && buffer.FaceLocations){ + cp.enqueue<vtkDataArray*>(blockId, buffer.Faces->GetOffsetsArray()); + cp.enqueue<vtkDataArray*>(blockId, buffer.Faces->GetConnectivityArray()); + cp.enqueue<vtkDataArray*>(blockId, buffer.FaceLocations->GetOffsetsArray()); + cp.enqueue<vtkDataArray*>(blockId, buffer.FaceLocations->GetConnectivityArray()); + } + else + { + cp.enqueue<vtkDataArray*>(blockId, vtkSmartPointer<vtkIdTypeArray>(nullptr) ); + cp.enqueue<vtkDataArray*>(blockId, vtkSmartPointer<vtkIdTypeArray>(nullptr)); + cp.enqueue<vtkDataArray*>(blockId, vtkSmartPointer<vtkIdTypeArray>(nullptr)); + cp.enqueue<vtkDataArray*>(blockId, vtkSmartPointer<vtkIdTypeArray>(nullptr)); + } } //---------------------------------------------------------------------------- @@ -4211,25 +4372,56 @@ void DequeueCellsForUnstructuredData<::UnstructuredGridBlockStructure>( vtkDataArray* types = nullptr; vtkDataArray* offsets = nullptr; vtkDataArray* connectivity = nullptr; + vtkDataArray* faces_offsets = nullptr; vtkDataArray* faces = nullptr; + vtkDataArray* faceLocations_offsets = nullptr; vtkDataArray* faceLocations = nullptr; cp.dequeue<vtkDataArray*>(gid, types); cp.dequeue<vtkDataArray*>(gid, offsets); cp.dequeue<vtkDataArray*>(gid, connectivity); + cp.dequeue<vtkDataArray*>(gid, faces_offsets); cp.dequeue<vtkDataArray*>(gid, faces); + cp.dequeue<vtkDataArray*>(gid, faceLocations_offsets); cp.dequeue<vtkDataArray*>(gid, faceLocations); buffer.Types = vtkSmartPointer<vtkUnsignedCharArray>::Take( vtkArrayDownCast<vtkUnsignedCharArray>(types)); - buffer.Faces = vtkSmartPointer<vtkIdTypeArray>::Take( - vtkArrayDownCast<vtkIdTypeArray>(faces)); - buffer.FaceLocations = vtkSmartPointer<vtkIdTypeArray>::Take( - vtkArrayDownCast<vtkIdTypeArray>(faceLocations)); using ArrayType32 = vtkCellArray::ArrayType32; using ArrayType64 = vtkCellArray::ArrayType64; + if (faces && faces_offsets) + { + buffer.Faces = vtkSmartPointer<vtkCellArray>::New(); + if (ArrayType32* offsets32 = vtkArrayDownCast<ArrayType32>(faces_offsets)) + { + buffer.Faces->SetData(offsets32, vtkArrayDownCast<ArrayType32>(faces)); + } + else + { + buffer.Faces->SetData(vtkArrayDownCast<ArrayType64>(faces_offsets), + vtkArrayDownCast<ArrayType64>(faces)); + } + faces_offsets->FastDelete(); + faces->FastDelete(); + } + + if (faceLocations && faceLocations_offsets){ + buffer.FaceLocations = vtkSmartPointer<vtkCellArray>::New(); + if (ArrayType32* offsets32 = vtkArrayDownCast<ArrayType32>(faceLocations_offsets)) + { + buffer.FaceLocations->SetData(offsets32, vtkArrayDownCast<ArrayType32>(faceLocations)); + } + else + { + buffer.FaceLocations->SetData(vtkArrayDownCast<ArrayType64>(faceLocations_offsets), + vtkArrayDownCast<ArrayType64>(faceLocations)); + } + faceLocations_offsets->FastDelete(); + faceLocations->FastDelete(); + } + if (ArrayType32* offsets32 = vtkArrayDownCast<ArrayType32>(offsets)) { buffer.CellArray->SetData(offsets32, vtkArrayDownCast<ArrayType32>(connectivity)); @@ -4433,8 +4625,7 @@ struct CellArrayInserter void operator()(vtkIdType startId, vtkIdType endId) { ArrayT* offsetsSource = vtkArrayDownCast<ArrayT>(this->SourceCells->GetOffsetsArray()); - ArrayT* connectivitySource = vtkArrayDownCast<ArrayT>( - this->SourceCells->GetConnectivityArray()); + ArrayT* connectivitySource = vtkArrayDownCast<ArrayT>(this->SourceCells->GetConnectivityArray()); ArrayT* offsetsDest = vtkArrayDownCast<ArrayT>(this->DestCells->GetOffsetsArray()); ArrayT* connectivityDest = vtkArrayDownCast<ArrayT>(this->DestCells->GetConnectivityArray()); @@ -4549,14 +4740,16 @@ void InsertCells(vtkCellArray* srcCells, vtkCellArray* dstCells, } //============================================================================ +template<class ArrayT> struct PolyhedronsInserter { - PolyhedronsInserter(vtkIdTypeArray* srcFaceLocations, vtkIdTypeArray* srcFaces, - vtkIdTypeArray* dstFaceLocations, vtkIdTypeArray* dstFaces, + PolyhedronsInserter(vtkCellArray* srcFaceLocations, vtkCellArray* srcFaces, + vtkCellArray* dstFaceLocations, vtkCellArray* dstFaces, vtkIdList* matchingReceivedPointIds, const std::map<vtkIdType, vtkIdType>& redirectionMapForDuplicatePointIds, const std::map<vtkIdType, vtkIdType>& pointIdOffsetIntervals, - vtkIdType pointIdOffset, vtkIdType cellIdOffset, vtkIdType facesOffset) + vtkIdType pointIdOffset, vtkIdType cellIdOffset, + vtkIdType facesIdOffset, vtkIdType facesOffset) : SourceFaceLocations(srcFaceLocations) , SourceFaces(srcFaces) , DestFaceLocations(dstFaceLocations) @@ -4566,81 +4759,101 @@ struct PolyhedronsInserter , PointIdOffsetIntervals(pointIdOffsetIntervals) , PointIdOffset(pointIdOffset) , CellIdOffset(cellIdOffset) + , FacesIdOffset(facesIdOffset) , FacesOffset(facesOffset) { + ArrayT* offsetsFacesDest = vtkArrayDownCast<ArrayT>(this->DestFaces->GetOffsetsArray()); + ArrayT* offsetsFacesSource = vtkArrayDownCast<ArrayT>(this->SourceFaces->GetOffsetsArray()); + ArrayT* offsetsFaceLocDest = vtkArrayDownCast<ArrayT>(this->DestFaceLocations->GetOffsetsArray()); + ArrayT* offsetsFaceLocSource = vtkArrayDownCast<ArrayT>(this->SourceFaceLocations->GetOffsetsArray()); + + // Last location of offsets will never be set in the loop, as it has + // numberOfCells + 1 values. + offsetsFaceLocDest->SetValue(this->CellIdOffset + this->SourceFaceLocations->GetNumberOfCells(), + offsetsFaceLocDest->GetValue(this->CellIdOffset) + + offsetsFaceLocSource->GetValue(this->SourceFaceLocations->GetNumberOfCells())); + offsetsFacesDest->SetValue(this->FacesIdOffset + this->SourceFaces->GetNumberOfCells(), + offsetsFacesDest->GetValue(this->FacesIdOffset) + + offsetsFacesSource->GetValue(this->SourceFaces->GetNumberOfCells())); } void operator()(vtkIdType startId, vtkIdType endId) { + ArrayT *srcOffsets = vtkArrayDownCast<ArrayT>(this->SourceFaceLocations->GetOffsetsArray()); + ArrayT *srcConnectivity = vtkArrayDownCast<ArrayT>(this->SourceFaceLocations->GetConnectivityArray()); + ArrayT *srcFacesOffsets = vtkArrayDownCast<ArrayT>(this->SourceFaces->GetOffsetsArray()); + ArrayT *srcFacesConnectivity = vtkArrayDownCast<ArrayT>(this->SourceFaces->GetConnectivityArray()); + // + ArrayT *destOffsets = vtkArrayDownCast<ArrayT>(this->DestFaceLocations->GetOffsetsArray()); + ArrayT *destConnectivity = vtkArrayDownCast<ArrayT>(this->DestFaceLocations->GetConnectivityArray()); + ArrayT *destFacesOffsets = vtkArrayDownCast<ArrayT>(this->DestFaces->GetOffsetsArray()); + ArrayT *destFacesConnectivity = vtkArrayDownCast<ArrayT>(this->DestFaces->GetConnectivityArray()); + for (vtkIdType cellId = startId; cellId < endId; ++cellId) { - // We enter the following if statement if current cell is a VTK_POLYHEDRON - if (this->SourceFaceLocations->GetValue(cellId) != -1) - { - vtkIdType id = this->SourceFaceLocations->GetValue(cellId); - vtkIdType currentFacesOffset = this->FacesOffset + id; - - vtkIdType numberOfFaces = this->SourceFaces->GetValue(id++); + vtkIdType offset = srcOffsets->GetValue(cellId); + vtkIdType nextOffset = srcOffsets->GetValue(cellId + 1); + destOffsets->SetValue(this->CellIdOffset + cellId, this->FacesIdOffset + offset); - - this->DestFaceLocations->SetValue(this->CellIdOffset + cellId, currentFacesOffset); - this->DestFaces->SetValue(currentFacesOffset++, numberOfFaces); - - for (vtkIdType faceId = 0; faceId < numberOfFaces; ++faceId) + // We enter the following if statement if current cell is a VTK_POLYHEDRON + if ((nextOffset-offset) > 0) + { + for (vtkIdType id = offset; id < nextOffset; ++id) { - vtkIdType faceSize = this->SourceFaces->GetValue(id++); - this->DestFaces->SetValue(currentFacesOffset++, faceSize); - - for (vtkIdType facePointId = 0; facePointId < faceSize; ++facePointId) + vtkIdType faceId = srcConnectivity->GetValue(id); + // + vtkIdType faceOffset = srcFacesOffsets->GetValue(faceId); + vtkIdType nextFaceOffset = srcFacesOffsets->GetValue(faceId+1); + // + destConnectivity->SetValue(this->FacesIdOffset+id, this->FacesIdOffset+id); + destFacesOffsets->SetValue(this->FacesIdOffset+id, this->FacesOffset+faceOffset); + // + for (vtkIdType locPt = faceOffset; locPt<nextFaceOffset; ++locPt) { - // The following follows the same logic as for the connectivity array: - // Depending of if we already own a copy of the point, we map the connectivity - // to the point that is already stored. Otherwise, we create a new point. - vtkIdType pointId = this->SourceFaces->GetValue(id + facePointId); - if (pointId >= 0) - { - if (this->RedirectionMapForDuplicatePointIds.empty()) + vtkIdType pointId = srcFacesConnectivity->GetValue(locPt); + if (pointId >= 0) { - this->DestFaces->SetValue(currentFacesOffset + facePointId, - this->PointIdOffset + pointId); - } - else - { - auto it = this->RedirectionMapForDuplicatePointIds.find(pointId); - if (it == this->RedirectionMapForDuplicatePointIds.end()) + if (this->RedirectionMapForDuplicatePointIds.empty()) { - this->DestFaces->SetValue(currentFacesOffset + facePointId, - this->PointIdOffset + pointId - - this->PointIdOffsetIntervals.lower_bound(pointId)->second); + destFacesConnectivity->SetValue(this->FacesOffset + locPt, + this->PointIdOffset + pointId); } else { - this->DestFaces->SetValue(currentFacesOffset + facePointId, it->second); + auto it = this->RedirectionMapForDuplicatePointIds.find(pointId); + if (it == this->RedirectionMapForDuplicatePointIds.end()) + { + destFacesConnectivity->SetValue(this->FacesOffset + locPt, + this->PointIdOffset + pointId - + this->PointIdOffsetIntervals.lower_bound(pointId)->second); + } + else + { + destFacesConnectivity->SetValue(this->FacesOffset + locPt, it->second); + } } } - } - else - { - this->DestFaces->SetValue(currentFacesOffset + facePointId, - this->MatchingReceivedPointIds->GetId(-pointId - 1)); - } + else + { + destFacesConnectivity->SetValue(this->FacesOffset + locPt, + this->MatchingReceivedPointIds->GetId(-pointId - 1)); + } } - id += faceSize; - currentFacesOffset += faceSize; } } } } - vtkIdTypeArray* SourceFaceLocations; - vtkIdTypeArray* SourceFaces; - vtkIdTypeArray* DestFaceLocations; - vtkIdTypeArray* DestFaces; + vtkCellArray* SourceFaceLocations; + vtkCellArray* SourceFaces; + vtkCellArray* DestFaceLocations; + vtkCellArray* DestFaces; vtkIdList* MatchingReceivedPointIds; const std::map<vtkIdType, vtkIdType>& RedirectionMapForDuplicatePointIds; const std::map<vtkIdType, vtkIdType>& PointIdOffsetIntervals; vtkIdType PointIdOffset; vtkIdType CellIdOffset; + vtkIdType FacesIdOffset; vtkIdType FacesOffset; }; @@ -4683,6 +4896,7 @@ void DeepCopyInputAndAllocateGhosts(::UnstructuredGridBlock* block, vtkIdType connectivitySize = info.InputConnectivitySize; vtkIdType facesSize = info.InputFacesSize; + vtkIdType facesNum = info.InputNumberOfFaces; for (auto& pair : block->BlockStructures) { @@ -4692,8 +4906,9 @@ void DeepCopyInputAndAllocateGhosts(::UnstructuredGridBlock* block, numberOfCells += blockStructure.ReceiveBuffer.Types->GetNumberOfValues(); connectivitySize += blockStructure.ReceiveBuffer.CellArray->GetConnectivityArray()->GetNumberOfValues(); - vtkIdTypeArray* faces = blockStructure.ReceiveBuffer.Faces; - facesSize += faces ? faces->GetNumberOfValues() : 0; + vtkCellArray* faces = blockStructure.ReceiveBuffer.Faces; + facesSize += faces ? faces->GetConnectivityArray()->GetNumberOfValues() : 0; + facesNum += faces ? faces->GetOffsetsArray()->GetNumberOfValues() - 1 : 0; } vtkPoints* inputPoints = input->GetPoints(); @@ -4710,16 +4925,19 @@ void DeepCopyInputAndAllocateGhosts(::UnstructuredGridBlock* block, vtkNew<vtkUnsignedCharArray> types; types->SetNumberOfValues(numberOfCells); - vtkSmartPointer<vtkIdTypeArray> outputFaces = nullptr; - vtkSmartPointer<vtkIdTypeArray> outputFaceLocations = nullptr; + vtkSmartPointer<vtkCellArray> outputFaces = nullptr; + vtkSmartPointer<vtkCellArray> outputFaceLocations = nullptr; if (facesSize) { - outputFaces = vtkSmartPointer<vtkIdTypeArray>::New(); - outputFaces->SetNumberOfValues(facesSize); - outputFaceLocations = vtkSmartPointer<vtkIdTypeArray>::New(); - outputFaceLocations->SetNumberOfValues(numberOfCells); - outputFaceLocations->FillValue(-1); + outputFaces = vtkSmartPointer<vtkCellArray>::New(); + outputFaces->AllocateExact(facesNum, facesSize); + outputFaces->GetConnectivityArray()->SetNumberOfTuples(facesSize); + outputFaces->GetOffsetsArray()->SetNumberOfTuples(facesNum+1); + outputFaceLocations = vtkSmartPointer<vtkCellArray>::New(); + outputFaceLocations->AllocateExact(numberOfCells, facesNum); + outputFaceLocations->GetConnectivityArray()->SetNumberOfTuples(facesNum); + outputFaceLocations->GetOffsetsArray()->SetNumberOfTuples(numberOfCells+1); } // We're being careful to account for different storage options in cell arrays @@ -4733,7 +4951,7 @@ void DeepCopyInputAndAllocateGhosts(::UnstructuredGridBlock* block, outputCellArray->GetConnectivityArray()->SetNumberOfTuples(connectivitySize); outputCellArray->GetOffsetsArray()->SetNumberOfTuples(numberOfCells + 1); - output->SetCells(types, outputCellArray, + output->SetPolyhedralCells(types, outputCellArray, outputFaceLocations, outputFaces); ::CloneUnstructuredGrid(input, output, info); @@ -5447,8 +5665,8 @@ void FillReceivedGhosts(::UnstructuredGridBlock* block, int myGid, vtkCellArray* outputCellArray = output->GetCells(); vtkUnsignedCharArray* outputTypes = output->GetCellTypesArray(); - vtkIdTypeArray* outputFaceLocations = output->GetFaceLocations(); - vtkIdTypeArray* outputFaces = output->GetFaces(); + vtkCellArray* outputFaceLocations = output->GetPolyhedronFaceLocations(); + vtkCellArray* outputFaces = output->GetPolyhedronFaces(); auto& buffer = blockStructure.ReceiveBuffer; vtkIdType numberOfAddedCells = buffer.Types->GetNumberOfValues(); @@ -5463,14 +5681,58 @@ void FillReceivedGhosts(::UnstructuredGridBlock* block, int myGid, blockStructure.RedirectionMapForDuplicatePointIds, pointIdOffsetIntervals, info.CurrentMaxPointId, info.CurrentMaxCellId, info.CurrentConnectivitySize); - if (vtkIdTypeArray* faceLocations = buffer.FaceLocations) + if (vtkCellArray* faceLocations = buffer.FaceLocations) { - ::PolyhedronsInserter inserter(faceLocations, buffer.Faces, outputFaceLocations, outputFaces, - blockStructure.RemappedMatchingReceivedPointIdsSortedLikeTarget, - blockStructure.RedirectionMapForDuplicatePointIds, pointIdOffsetIntervals, - info.CurrentMaxPointId, info.CurrentMaxCellId, info.CurrentFacesSize); + using ArrayType32 = vtkCellArray::ArrayType32; + using ArrayType64 = vtkCellArray::ArrayType64; - vtkSMPTools::For(0, faceLocations->GetNumberOfValues(), inserter); + if (!faceLocations->GetNumberOfCells()) + { + return; + } + + if (faceLocations->IsStorage64Bit()) + { + ::PolyhedronsInserter<ArrayType64> inserter(faceLocations, buffer.Faces, outputFaceLocations, outputFaces, + blockStructure.RemappedMatchingReceivedPointIdsSortedLikeTarget, + blockStructure.RedirectionMapForDuplicatePointIds, pointIdOffsetIntervals, + info.CurrentMaxPointId, info.CurrentMaxCellId, info.CurrentMaxFaceId, info.CurrentFacesSize); + vtkSMPTools::For(0, faceLocations->GetNumberOfCells(), inserter); + } + else + { + ::PolyhedronsInserter<ArrayType32> inserter(faceLocations, buffer.Faces, outputFaceLocations, outputFaces, + blockStructure.RemappedMatchingReceivedPointIdsSortedLikeTarget, + blockStructure.RedirectionMapForDuplicatePointIds, pointIdOffsetIntervals, + info.CurrentMaxPointId, info.CurrentMaxCellId, info.CurrentMaxFaceId, info.CurrentFacesSize); + vtkSMPTools::For(0, faceLocations->GetNumberOfCells(), inserter); + } + } + else + { + // Take care of polyhedron when buffer do not have them but they are needed in the end + // Insert empty faces + if (outputFaceLocations) + { + using ArrayType32 = vtkCellArray::ArrayType32; + using ArrayType64 = vtkCellArray::ArrayType64; + if (outputFaceLocations->IsStorage64Bit()) + { + auto faceLocRange = vtkArrayDownCast<ArrayType64>(outputFaceLocations->GetOffsetsArray()); + for (vtkIdType pos=0; pos<numberOfAddedCells; ++pos) + { + faceLocRange->SetValue(info.CurrentMaxCellId+pos+1,faceLocRange->GetValue(info.CurrentMaxCellId+pos)); + } + } + else + { + auto faceLocRange = vtkArrayDownCast<ArrayType32>(outputFaceLocations->GetOffsetsArray()); + for (vtkIdType pos=0; pos<numberOfAddedCells; ++pos) + { + faceLocRange->SetValue(info.CurrentMaxCellId+pos+1,faceLocRange->GetValue(info.CurrentMaxCellId+pos)); + } + } + } } ::FillDuplicateCellGhostArrayForUnstructureData(block->GhostCellArray, @@ -5481,7 +5743,8 @@ void FillReceivedGhosts(::UnstructuredGridBlock* block, int myGid, info.CurrentMaxPointId += numberOfAddedPoints; info.CurrentMaxCellId += numberOfAddedCells; info.CurrentConnectivitySize += buffer.CellArray->GetConnectivityArray()->GetNumberOfTuples(); - info.CurrentFacesSize += buffer.Faces ? buffer.Faces->GetNumberOfValues() : 0; + info.CurrentFacesSize += buffer.Faces ? buffer.Faces->GetConnectivityArray()->GetNumberOfTuples():0; + info.CurrentMaxFaceId += buffer.Faces ? buffer.Faces->GetOffsetsArray()->GetNumberOfTuples()-1:0; } //---------------------------------------------------------------------------- @@ -6200,13 +6463,13 @@ void vtkDIYGhostUtilities::InitializeBlocks(diy::Master& master, BlockType* block = master.block<BlockType>(localId); typename BlockType::InformationType& information = block->Information; - vtkIdTypeArray* faces = input->GetFaces(); - information.Faces = faces && faces->GetNumberOfValues() + vtkCellArray* faces = input->GetPolyhedronFaces(); + information.Faces = faces && faces->GetNumberOfCells() ? faces : nullptr; - vtkIdTypeArray* faceLocations = input->GetFaceLocations(); - information.FaceLocations = faceLocations && faceLocations->GetNumberOfValues() + vtkCellArray* faceLocations = input->GetPolyhedronFaceLocations(); + information.FaceLocations = faceLocations && faceLocations->GetNumberOfCells() ? faceLocations : nullptr; } diff --git a/Parallel/DIY/vtkDIYGhostUtilities.h b/Parallel/DIY/vtkDIYGhostUtilities.h index 3492231605e0d44d53e628f98e5ba69d331c783d..0d692610b1ab2c4f3b0baea90c50e82ecf77bed9 100644 --- a/Parallel/DIY/vtkDIYGhostUtilities.h +++ b/Parallel/DIY/vtkDIYGhostUtilities.h @@ -568,14 +568,20 @@ protected: */ vtkIdType CurrentFacesSize = 0; + /** + * This is a cursor telling the amount of faces information, that has + * already been added to the output. This variable is used at the very end of the pipeline. + */ + vtkIdType CurrentMaxFaceId = 0; + /** * This is a cursor telling how much the output connectivity array is filled. * This is used at the very end of the pipeline. */ vtkIdType CurrentConnectivitySize = 0; - vtkIdTypeArray* Faces = nullptr; - vtkIdTypeArray* FaceLocations = nullptr; + vtkCellArray* Faces = nullptr; + vtkCellArray* FaceLocations = nullptr; vtkUnstructuredGrid* Input; @@ -588,6 +594,11 @@ protected: * Faces array size of the input if the ghost cells are removed. */ vtkIdType InputFacesSize = 0; + + /** + * Number of Faces stored in Faces array of the input if the ghost cells are removed. + */ + vtkIdType InputNumberOfFaces = 0; }; struct UnstructuredGridBlockStructure : public UnstructuredDataBlockStructure @@ -598,8 +609,8 @@ protected: struct TopologyBufferType { vtkSmartPointer<vtkUnsignedCharArray> Types = nullptr; - vtkSmartPointer<vtkIdTypeArray> Faces = nullptr; - vtkSmartPointer<vtkIdTypeArray> FaceLocations = nullptr; + vtkSmartPointer<vtkCellArray> Faces = nullptr; + vtkSmartPointer<vtkCellArray> FaceLocations = nullptr; vtkNew<vtkCellArray> CellArray; }; @@ -611,6 +622,7 @@ protected: * Handle to the faces / connectivity size that we have to send to the neighboring block. */ vtkIdType FacesSize = 0; + vtkIdType FacesNum = 0; vtkIdType ConnectivitySize = 0; ///@} };