At the top there is the foo
function. Is this a fallback? You don’t use it in the code below.
foo
and bar
do the same thing: foo
is using the convenience API, while bar
is the optimized version of foo
.
In my case I’m iterating over the points of single polygons. How to handle this?
VTK has some examples of doing random access work using these APIs. It sounds like you’ll want something similar to what the vtkCellDataToPointData
filter does.
vtkCellDataToPointData
This algorithm uses a large functor to implement most of the algorithm: https://gitlab.kitware.com/vtk/vtk/-/blob/master/Filters/Core/vtkCellDataToPointData.cxx#L48-135
It is dispatched once, passing in two arrays, the Spread
functor, and several algorithm parameters. Both arrays will have their valuetypes and memory layouts resolved by the dispatch: https://gitlab.kitware.com/vtk/vtk/-/blob/master/Filters/Core/vtkCellDataToPointData.cxx#L488-495
Inside the functor, the destination array is initialized to 0 and tuple ranges for the input and output arrays are created:
// Both arrays will have the same value type:
using T = vtk::GetAPIType<SrcArrayT>;
// zero initialization
std::fill_n(vtk::DataArrayValueRange(dstarray).begin(), npoints * ncomps, T(0));
const auto srcTuples = vtk::DataArrayTupleRange(srcarray);
auto dstTuples = vtk::DataArrayTupleRange(dstarray);
Next, the cells are walked through, scattering each cell’s data into the point array.
for (vtkIdType cid = 0; cid < ncells; ++cid)
{
vtkCell* cell = src->GetCell(cid);
if (cell->GetCellDimension() >= highestCellDimension)
{
const auto srcTuple = srcTuples[cid];
vtkIdList* pids = cell->GetPointIds();
for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
{
const vtkIdType ptId = pids->GetId(i);
auto dstTuple = dstTuples[ptId];
// accumulate cell data to point data <==> point_data += cell_data
std::transform(srcTuple.cbegin(), srcTuple.cend(), dstTuple.cbegin(), dstTuple.begin(),
std::plus<T>());
}
}
}
Note that this is not the most efficient way to traverse cells these days – see the vtkCellArray docs for more info.
After that, the point data is cleaned up, but that’s not relevant to just doing random access into an array using cell information.
You’ll want do something similar with your point array that encapsulates all of the random lookup operations into a single functor execution. It may take some refactoring of the algorithm to accomplish this. But once in the functor, create a range object and do something like pointTupleRange[cellPtIdx]
to do random access using the cell indices.
InsertTuples
For a simpler example of basic random access, vtkDataArray::InsertTuples
does a mixed gather and scatter operation to shuffle tuples between two arrays:
Functor: https://gitlab.kitware.com/vtk/vtk/-/blob/master/Common/Core/vtkDataArray.cxx#L303-329
Invocation: https://gitlab.kitware.com/vtk/vtk/-/blob/master/Common/Core/vtkDataArray.cxx#L619-623