Faster method for GetPoint

Hi Will,

In these cases, it’s important to be careful with the distinction between arrays of the same type and arrays of the same value type.

In this snippet, newPts will always construct a default layout AOS array with the same valuetype as inPts – but if inPts contains a user-provided SOA array, then these arrays will not have the same type (only the same valuetype) and a double dispatch is needed.

To handle this case (same valuetype, possibly different memory layout), the vtkArrayDispatch::Dispatch2BySameValueType<vtkArrayDispatch::Reals> dispatcher should be used. When VTK is built with SOA support, it will generate fast-paths for:

Path# inPts newPts
1 AOS,float AOS,float
2 AOS,float SOA,float
3 SOA,float AOS,float
4 SOA,float SOA,float
5 AOS,double AOS,double
6 AOS,double SOA,double
7 SOA,double AOS,double
8 SOA,double SOA,double

When SOA support is off, only paths 1 and 5 will be generated (which turns into a single dispatch plus a downcast).

For an example, this pattern is currently used in vtkPointCloudFilter to accomplish a similar goal.

OTOH, if both arrays are known to have exactly the same valuetype and memory layout, you can just dispatch one of them, pass the other as a vtkDataArray*, and then cast it inside the functor once the full type information is available:

struct Worker
{
  template <typename ArrayType>
  void operator()(ArrayType *array1, vtkDataArray *dataArray2)
  {
    ArrayType *array2 = vtkArrayDownCast<ArrayType>(dataArray2);
    // do work with array1 / array2
  }
};


void doDispatch(vtkDataArray *dataArray1, vtkDataArray *dataArray2)
{
  using Dispatcher = vtkArrayDispatch::DispatchByValueType<vtkArrayDispatch::Reals>;

  // This is safe if and only if both arrays are known to have 
  // exactly the same type.
  if (!Dispatcher::Execute(dataArray1, Worker{}, dataArray2))
  { // Fallback in case valuetype is not `Real`.
    Worker{}(dataArray1, dataArray2);
  }
}
2 Likes