Faster method for GetPoint

@AllisonVacanti on a related note, I was hoping you could provide some guidance.

I am dispatching on a vtk data array, and at the same time I have a second array of exactly the same type, num tuples, num components (see code below). There is no need for double dispatch because the types are always the same.

I am wondering the best way to cast the second array (from newPts), traverse over it, and assign values to it. Basically I am running down these two arrays and assigning values from the first to the second. I’ve fooled around a little bit, but I suspect that you can provide a more efficient and elegant solution.


// Support dispatch of different types
struct InitializePointsWorker
{
  template <typename DataT>
  void operator()(DataT* pts, vtkIdType numPts, vtkPoints *newPts,
                  int normalize, double length, double center[3])
  {
    vtkSMPTools::For(0,numPts, [&](vtkIdType ptId, vtkIdType endPtId) {

      const auto in = vtk::DataArrayTupleRange<3>(pts, ptId, endPtId);
      double x[3];

      for (const auto tuple : in)
      {
        x[0] = static_cast<double>(tuple[0]);
        x[1] = static_cast<double>(tuple[1]);
        x[2] = static_cast<double>(tuple[2]);

        if ( normalize )
        {
          x[0] = (x[0] - center[0]) / length;
          x[1] = (x[1] - center[1]) / length;
          x[2] = (x[2] - center[2]) / length;
        }

        //Now set the value of the new points


      }//for all points

    }); //end lambda

  }
};

// Initialize points including possibly normalizing them.
vtkPoints *InitializePoints(int normalize, vtkPolyData *input,
                            double &length, double center[3])
{
  vtkPoints *inPts = input->GetPoints();
  vtkIdType numPts = inPts->GetNumberOfPoints();
  vtkPoints *newPts = vtkPoints::New();
  newPts->SetDataType(inPts->GetDataType());
  newPts->SetNumberOfPoints(numPts);

  // May need to grab normalization info
  if ( normalize )
  {
    length = input->GetLength();
    input->GetCenter(center);
  }

  using vtkArrayDispatch::Reals;
  using InitializePointsDispatch = vtkArrayDispatch::DispatchByValueType<Reals>;
  InitializePointsWorker initPtsWorker;
  if ( !InitializePointsDispatch::Execute(inPts->GetData(),initPtsWorker,
                                          numPts,newPts,normalize,length,center) )
  { // Fallback to slowpath for other point types
    initPtsWorker(inPts->GetData(),numPts,newPts,normalize,length,center);
  }

  return newPts;
}
1 Like