Faster method for GetPoint

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

1 Like