Support arbitrary field types in CellAverage

Previously, the CellAverage worklet only operated on scalar fields.
However, there is no reason why you cannot average vectors. This change
allows passing input fields with arbitrary value types in the field
array.

We will use this functionality in the commit to test running filters on
coordinate systems (which, of course, are Vec 3 objects).
This commit is contained in:
Kenneth Moreland 2016-10-22 19:58:48 -04:00
parent fe277ca895
commit f820f0c76d

@ -23,6 +23,8 @@
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace worklet {
@ -31,9 +33,9 @@ class CellAverage :
public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(FieldInPoint<Scalar> inPoints,
typedef void ControlSignature(FieldInPoint<> inPoints,
CellSetIn cellset,
FieldOutCell<Scalar> outCells);
FieldOutCell<> outCells);
typedef void ExecutionSignature(_1, PointCount, _3);
typedef _2 InputDomain;
@ -42,6 +44,31 @@ public:
void operator()(const PointValueVecType &pointValues,
const vtkm::IdComponent &numPoints,
OutType &average) const
{
using PointValueType = typename PointValueVecType::ComponentType;
using PointVecSize =
std::integral_constant<
vtkm::IdComponent,
vtkm::VecTraits<PointValueType>::NUM_COMPONENTS>;
using OutVecSize =
std::integral_constant<
vtkm::IdComponent,
vtkm::VecTraits<OutType>::NUM_COMPONENTS>;
this->DoAverage(pointValues,
numPoints,
average,
PointVecSize(),
OutVecSize());
}
private:
template<typename PointValueVecType, typename OutType>
void DoAverage(const PointValueVecType &pointValues,
const vtkm::IdComponent &numPoints,
OutType &average,
std::integral_constant<vtkm::IdComponent,1>,
std::integral_constant<vtkm::IdComponent,1>) const
{
OutType sum = static_cast<OutType>(pointValues[0]);
for (vtkm::IdComponent pointIndex = 1; pointIndex < numPoints; ++pointIndex)
@ -52,6 +79,37 @@ public:
average = sum / static_cast<OutType>(numPoints);
}
template<typename PointValueVecType,
typename OutType,
vtkm::IdComponent VecSize>
void DoAverage(const PointValueVecType &pointValues,
const vtkm::IdComponent &numPoints,
OutType &average,
std::integral_constant<vtkm::IdComponent,VecSize>,
std::integral_constant<vtkm::IdComponent,VecSize>) const
{
OutType sum = OutType(pointValues[0]);
for (vtkm::IdComponent pointIndex = 1; pointIndex < numPoints; ++pointIndex)
{
sum = sum + OutType(pointValues[pointIndex]);
}
average = sum / OutType(numPoints);
}
template<typename PointValueVecType,
typename OutType,
vtkm::IdComponent InVecSize,
vtkm::IdComponent OutVecSize>
void DoAverage(const PointValueVecType &vtkmNotUsed(pointValues),
const vtkm::IdComponent &vtkmNotUsed(numPoints),
OutType &vtkmNotUsed(average),
std::integral_constant<vtkm::IdComponent,InVecSize>,
std::integral_constant<vtkm::IdComponent,OutVecSize>) const
{
this->RaiseError(
"CellAverage called with mismatched Vec sizes for CellAverage.");
}
};
}