Merge topic 'contour-interp-any-field'

719d347fd Update contour filter's field map to work on any field type

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Sujin Philip <sujin.philip@kitware.com>
Merge-request: !2973
This commit is contained in:
Kenneth Moreland 2023-02-02 17:07:59 +00:00 committed by Kitware Robot
commit 3a02a45729
5 changed files with 43 additions and 24 deletions

@ -1,11 +0,0 @@
# Update clip filter's field map to work on any field type
The previous implementation of the map field in the clip filters
(`ClipWithField` and `ClipWithImplicitFunction`) checked for common field
types and interpolated those. If the field value type did not match, it
would either convert the field to floats (which is at odds with what VTK
does) or fail outright if the `Vec` length is not supported.
The map field function for clip has been changed to support all possible
types. It does this by using the extract component functionality to get
data from any type of array.

@ -0,0 +1,17 @@
# Update filters' field map to work on any field type
Several filters implemented their map field by checking for common field
types and interpolated those. Although there was a float fallback to catch
odd component types, there were still a couple of issues. First, it meant
that several types got converted to `vtkm::FloatDefault`, which is often at
odds with how VTK handles it. Second, it does not handle all `Vec` lengths,
so it is still possible to drop fields.
The map field functions for these filters have been changed to support all
possible types. This is done by using the extract component functionality
to get data from any type of array. The following filters have been
updated.
* `ClipWithField`
* `ClipWithImplicitFunction`
* `Contour`

@ -45,13 +45,16 @@ VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
{
if (field.IsPointField())
{
vtkm::cont::UnknownArrayHandle inputArray = field.GetData();
vtkm::cont::UnknownArrayHandle outputArray = inputArray.NewInstanceBasic();
auto functor = [&](const auto& concrete) {
auto fieldArray = worklet.ProcessPointField(concrete);
result.AddPointField(field.GetName(), fieldArray);
using ComponentType = typename std::decay_t<decltype(concrete)>::ValueType::ComponentType;
auto fieldArray = outputArray.ExtractArrayFromComponents<ComponentType>();
worklet.ProcessPointField(concrete, fieldArray);
};
field.GetData()
.CastAndCallForTypesWithFloatFallback<vtkm::TypeListField, VTKM_DEFAULT_STORAGE_LIST>(
functor);
inputArray.CastAndCallWithExtractedArray(functor);
result.AddPointField(field.GetName(), outputArray);
return true;
}
else if (field.IsCellField())

@ -150,21 +150,17 @@ public:
}
//----------------------------------------------------------------------------
template <typename ValueType, typename StorageType>
vtkm::cont::ArrayHandle<ValueType> ProcessPointField(
const vtkm::cont::ArrayHandle<ValueType, StorageType>& input) const
template <typename InArrayType, typename OutArrayType>
void ProcessPointField(const InArrayType& input, const OutArrayType& output) const
{
using vtkm::worklet::contour::MapPointField;
vtkm::worklet::DispatcherMapField<MapPointField> applyFieldDispatcher;
vtkm::cont::ArrayHandle<ValueType> output;
applyFieldDispatcher.Invoke(this->SharedState.InterpolationEdgeIds,
this->SharedState.InterpolationWeights,
input,
output);
return output;
}
//----------------------------------------------------------------------------

@ -42,8 +42,22 @@ public:
OutFieldType& result) const
{
//fetch the low / high values from inPortal
result = static_cast<OutFieldType>(
vtkm::Lerp(inPortal.Get(low_high[0]), inPortal.Get(low_high[1]), weight));
OutFieldType lowValue = inPortal.Get(low_high[0]);
OutFieldType highValue = inPortal.Get(low_high[1]);
// Interpolate per-vected because some vec-like objects do not allow intermediate variables
using VTraits = vtkm::VecTraits<OutFieldType>;
VTKM_ASSERT(VTraits::GetNumberOfComponents(lowValue) == VTraits::GetNumberOfComponents(result));
VTKM_ASSERT(VTraits::GetNumberOfComponents(highValue) ==
VTraits::GetNumberOfComponents(result));
for (vtkm::IdComponent cIndex = 0; cIndex < VTraits::GetNumberOfComponents(result); ++cIndex)
{
VTraits::SetComponent(result,
cIndex,
vtkm::Lerp(VTraits::GetComponent(lowValue, cIndex),
VTraits::GetComponent(highValue, cIndex),
weight));
}
}
};
}