Enable any scalar field in ParticleDensity filters

This is done using the `CastAndCallScalarField` from `FilterField`,
which uses a cast-and-call with a float fallback.
This commit is contained in:
Kenneth Moreland 2023-02-02 14:43:33 -05:00
parent d38efa87f2
commit 0ba818e907
3 changed files with 23 additions and 43 deletions

@ -1,4 +1,4 @@
# Update filters' field map to work on any field type
# Update filters' field map and execute 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
@ -10,7 +10,8 @@ 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.
updated. In some circumstances where it makes sense, a simple float
fallback is used.
* `CleanGrid`
* `CellAverage`
@ -20,3 +21,5 @@ updated.
* `MIRFilter`
* `PointAverage`
* `NDHistogram`
* `ParticleDensityCloudInCell`
* `ParticleDensityNearestGridPoint`

@ -111,28 +111,15 @@ VTKM_CONT vtkm::cont::DataSet ParticleDensityCloudInCell::DoExecute(const cont::
uniform.AddField(vtkm::cont::make_FieldPoint("density", density));
};
// Note: This is the so called Immediately-Invoked Function Expression (IIFE). Here we define
// a lambda expression and immediately call it at the end. This allows us to not declare an
// UnknownArrayHandle first and then assign it in the if-else statement. If I really want to
// show-off, I can even inline the `fieldArray` variable and turn it into a long expression.
auto fieldArray = [&]() -> vtkm::cont::UnknownArrayHandle {
if (this->ComputeNumberDensity)
{
return vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 },
input.GetNumberOfPoints());
}
else
{
return this->GetFieldFromDataSet(input).GetData();
}
}();
fieldArray.CastAndCallForTypes<
vtkm::TypeListFieldScalar,
vtkm::ListAppend<VTKM_DEFAULT_STORAGE_LIST, vtkm::List<vtkm::cont::StorageTagConstant>>>(
resolveType);
// Deposition of the input field to the output field is already mapping. No need to map other
// fields.
if (this->ComputeNumberDensity)
{
resolveType(
vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, input.GetNumberOfPoints()));
}
else
{
this->CastAndCallScalarField(this->GetFieldFromDataSet(input), resolveType);
}
return uniform;
}
} // namespace density_estimate

@ -95,25 +95,15 @@ VTKM_CONT vtkm::cont::DataSet ParticleDensityNearestGridPoint::DoExecute(
uniform.AddField(vtkm::cont::make_FieldCell("density", density));
};
// Note: This is the so called Immediately-Invoked Function Expression (IIFE). Here we define
// a lambda expression and immediately call it at the end. This allows us to not declare an
// UnknownArrayHandle first and then assign it in the if-else statement. If I really want to
// show-off, I can even inline the `fieldArray` variable and turn it into a long expression.
auto fieldArray = [&]() -> vtkm::cont::UnknownArrayHandle {
if (this->ComputeNumberDensity)
{
return vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 },
input.GetNumberOfPoints());
}
else
{
return this->GetFieldFromDataSet(input).GetData();
}
}();
fieldArray.CastAndCallForTypes<
vtkm::TypeListFieldScalar,
vtkm::ListAppend<VTKM_DEFAULT_STORAGE_LIST, vtkm::List<vtkm::cont::StorageTagConstant>>>(
resolveType);
if (this->ComputeNumberDensity)
{
resolveType(
vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, input.GetNumberOfPoints()));
}
else
{
this->CastAndCallScalarField(this->GetFieldFromDataSet(input), resolveType);
}
// Deposition of the input field to the output field is already mapping. No need to map other
// fields.