diff --git a/docs/changelog/interp-any-field.md b/docs/changelog/interp-any-field.md index 04cddc994..2b1d77e0b 100644 --- a/docs/changelog/interp-any-field.md +++ b/docs/changelog/interp-any-field.md @@ -19,3 +19,4 @@ updated. * `Contour` * `MIRFilter` * `PointAverage` + * `NDHistogram` diff --git a/vtkm/filter/density_estimate/worklet/NDimsHistogram.h b/vtkm/filter/density_estimate/worklet/NDimsHistogram.h index ee22664e6..9d82347c9 100644 --- a/vtkm/filter/density_estimate/worklet/NDimsHistogram.h +++ b/vtkm/filter/density_estimate/worklet/NDimsHistogram.h @@ -41,29 +41,6 @@ public: vtkm::cont::ArrayCopy(constant0Array, Bin1DIndex); } - // Add a field and the bin number for this field - // Return: rangeOfRange is min max value of this array - // binDelta is delta of a bin - template - void AddField(const HandleType& fieldArray, - vtkm::Id numberOfBins, - vtkm::Range& rangeOfValues, - vtkm::Float64& binDelta) - { - NumberOfBins.push_back(numberOfBins); - - if (fieldArray.GetNumberOfValues() != NumDataPoints) - { - throw vtkm::cont::ErrorBadValue("Array lengths does not match"); - } - else - { - vtkm::cont::CastAndCall( - fieldArray.ResetTypes(vtkm::TypeListScalarAll{}, VTKM_DEFAULT_STORAGE_LIST{}), - vtkm::worklet::histogram::ComputeBins(Bin1DIndex, numberOfBins, rangeOfValues, binDelta)); - } - } - // Add a field and the bin number for this field along with specific range of the data // Return: binDelta is delta of a bin template @@ -71,7 +48,7 @@ public: vtkm::Id numberOfBins, vtkm::Range& rangeOfValues, vtkm::Float64& binDelta, - bool rangeProvided) + bool rangeProvided = false) { NumberOfBins.push_back(numberOfBins); @@ -81,9 +58,35 @@ public: } else { - CastAndCall(fieldArray.ResetTypes(vtkm::TypeListScalarAll()), - vtkm::worklet::histogram::ComputeBins( - Bin1DIndex, numberOfBins, rangeOfValues, binDelta, rangeProvided)); + auto computeBins = [&](auto resolvedField) { + // CastAndCallWithExtractedArray should give us an ArrayHandleRecombineVec + using T = typename std::decay_t::ValueType::ComponentType; + vtkm::cont::ArrayHandleRecombineVec recombineField{ resolvedField }; + if (recombineField.GetNumberOfComponents() != 1) + { + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "NDHistogram expects scalar fields, but was given field with " + << recombineField.GetNumberOfComponents() + << " components. Extracting first component."); + } + vtkm::cont::ArrayHandleStride field = + vtkm::cont::ArrayExtractComponent(recombineField, 0); + if (!rangeProvided) + { + const vtkm::Vec initValue(vtkm::cont::ArrayGetValue(0, field)); + vtkm::Vec minMax = + vtkm::cont::Algorithm::Reduce(field, initValue, vtkm::MinAndMax()); + rangeOfValues.Min = static_cast(minMax[0]); + rangeOfValues.Max = static_cast(minMax[1]); + } + binDelta = vtkm::worklet::histogram::compute_delta( + rangeOfValues.Min, rangeOfValues.Max, numberOfBins); + + vtkm::worklet::histogram::SetHistogramBin binWorklet( + numberOfBins, rangeOfValues.Min, binDelta); + vtkm::cont::Invoker{}(binWorklet, field, this->Bin1DIndex, this->Bin1DIndex); + }; + fieldArray.CastAndCallWithExtractedArray(computeBins); } } diff --git a/vtkm/filter/density_estimate/worklet/histogram/ComputeNDHistogram.h b/vtkm/filter/density_estimate/worklet/histogram/ComputeNDHistogram.h index a56ae51ed..228038cf5 100644 --- a/vtkm/filter/density_estimate/worklet/histogram/ComputeNDHistogram.h +++ b/vtkm/filter/density_estimate/worklet/histogram/ComputeNDHistogram.h @@ -78,63 +78,6 @@ public: } }; -class ComputeBins -{ -public: - VTKM_CONT - ComputeBins(vtkm::cont::ArrayHandle& _bin1DIdx, - vtkm::Id& _numOfBins, - vtkm::Range& _minMax, - vtkm::Float64& _binDelta) - : Bin1DIdx(_bin1DIdx) - , NumOfBins(_numOfBins) - , MinMax(_minMax) - , BinDelta(_binDelta) - , RangeProvided(false) - { - } - - VTKM_CONT - ComputeBins(vtkm::cont::ArrayHandle& _bin1DIdx, - vtkm::Id& _numOfBins, - vtkm::Range& _minMax, - vtkm::Float64& _binDelta, - bool _rangeProvided) - : Bin1DIdx(_bin1DIdx) - , NumOfBins(_numOfBins) - , MinMax(_minMax) - , BinDelta(_binDelta) - , RangeProvided(_rangeProvided) - { - } - - template - VTKM_CONT void operator()(const vtkm::cont::ArrayHandle& field) const - { - if (!RangeProvided) - { - const vtkm::Vec initValue(vtkm::cont::ArrayGetValue(0, field)); - vtkm::Vec minMax = - vtkm::cont::Algorithm::Reduce(field, initValue, vtkm::MinAndMax()); - MinMax.Min = static_cast(minMax[0]); - MinMax.Max = static_cast(minMax[1]); - } - BinDelta = compute_delta(MinMax.Min, MinMax.Max, NumOfBins); - - SetHistogramBin binWorklet(NumOfBins, MinMax.Min, BinDelta); - vtkm::worklet::DispatcherMapField> - setHistogramBinDispatcher(binWorklet); - setHistogramBinDispatcher.Invoke(field, Bin1DIdx, Bin1DIdx); - } - -private: - vtkm::cont::ArrayHandle& Bin1DIdx; - vtkm::Id& NumOfBins; - vtkm::Range& MinMax; - vtkm::Float64& BinDelta; - bool RangeProvided; -}; - // Convert N-dims bin index into 1D index class ConvertHistBinToND : public vtkm::worklet::WorkletMapField {