@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;
}