Update probe filter to interpolate any field type

Previously, the probe filter only worked on certain `Vec` sizes and
converted many types to floating point.

This change uses the extract component feature to pull data from any
array at its natural component type.

The bad part of this change is that it has to call the worklet
separately for each component in the field. That adds overhead and
probably lowers the cache efficiency. It was implemented this way
because the cell interpolation function does not work with the
recombined vecs returned from extract array.
This commit is contained in:
Kenneth Moreland 2023-02-03 12:55:57 -05:00
parent 863cede529
commit eddf6df384
3 changed files with 37 additions and 19 deletions

@ -19,7 +19,8 @@ fallback is used.
* `ClipWithImplicitFunction` * `ClipWithImplicitFunction`
* `Contour` * `Contour`
* `MIRFilter` * `MIRFilter`
* `PointAverage`
* `NDHistogram` * `NDHistogram`
* `ParticleDensityCloudInCell` * `ParticleDensityCloudInCell`
* `ParticleDensityNearestGridPoint` * `ParticleDensityNearestGridPoint`
* `PointAverage`
* `Probe`

@ -30,15 +30,34 @@ bool DoMapField(vtkm::cont::DataSet& result,
{ {
if (field.IsPointField()) if (field.IsPointField())
{ {
auto resolve = [&](const auto& concrete) { vtkm::cont::UnknownArrayHandle inArray = field.GetData();
using T = typename std::decay_t<decltype(concrete)>::ValueType; vtkm::cont::UnknownArrayHandle outArray = inArray.NewInstanceBasic();
vtkm::cont::ArrayHandle<T> outputArray = worklet.ProcessPointField(
concrete, vtkm::cont::internal::CastInvalidValue<T>(invalidValue)); bool called = false;
result.AddPointField(field.GetName(), outputArray); auto tryType = [&](auto t) {
using T = std::decay_t<decltype(t)>;
if (!called && inArray.IsBaseComponentType<T>())
{
called = true;
vtkm::IdComponent numComponents = inArray.GetNumberOfComponentsFlat();
VTKM_ASSERT(numComponents == outArray.GetNumberOfComponentsFlat());
for (vtkm::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
{
worklet.ProcessPointField(inArray.ExtractComponent<T>(cIndex),
outArray.ExtractComponent<T>(cIndex, vtkm::CopyFlag::Off),
vtkm::cont::internal::CastInvalidValue<T>(invalidValue));
}
}
}; };
field.GetData() vtkm::ListForEach(tryType, vtkm::TypeListScalarAll{});
.CastAndCallForTypesWithFloatFallback<vtkm::TypeListField, VTKM_DEFAULT_STORAGE_LIST>( if (!called)
resolve); {
VTKM_LOG_CAST_FAIL(worklet, vtkm::TypeListScalarAll);
return false;
}
result.AddPointField(field.GetName(), outArray);
return true; return true;
} }
else if (field.IsCellField()) else if (field.IsCellField())

@ -217,24 +217,22 @@ public:
}; };
/// Intepolate the input point field data at the points of the geometry /// Intepolate the input point field data at the points of the geometry
template <typename T, template <typename InArrayType,
typename Storage, typename OutArrayType,
typename ComponentType,
typename InputCellSetTypeList = VTKM_DEFAULT_CELL_SET_LIST> typename InputCellSetTypeList = VTKM_DEFAULT_CELL_SET_LIST>
vtkm::cont::ArrayHandle<T> ProcessPointField( void ProcessPointField(const InArrayType& field,
const vtkm::cont::ArrayHandle<T, Storage>& field, const OutArrayType& result,
const T& invalidValue, ComponentType invalidValue,
InputCellSetTypeList icsTypes = InputCellSetTypeList()) const InputCellSetTypeList icsTypes = InputCellSetTypeList()) const
{ {
vtkm::cont::ArrayHandle<T> result;
vtkm::cont::Invoker invoke; vtkm::cont::Invoker invoke;
invoke(InterpolatePointField<T>(invalidValue), invoke(InterpolatePointField<ComponentType>(invalidValue),
this->CellIds, this->CellIds,
this->ParametricCoordinates, this->ParametricCoordinates,
this->InputCellSet.ResetCellSetList(icsTypes), this->InputCellSet.ResetCellSetList(icsTypes),
field, field,
result); result);
return result;
} }
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIds() const { return this->CellIds; } vtkm::cont::ArrayHandle<vtkm::Id> GetCellIds() const { return this->CellIds; }