Allow ArrayExtractComponent to work with Vec-like value types

Before, `ArrayExtractComponent` only worked with `Vec` types. Anything
that was not specifically a `Vec` was assumed to be a basic component
even if it had `VecTraits`. This was changed to extract components out
of anything that has `VecTraits`. The assumption is that all components
of the Vec-like object are packed tightly in the object.

This allows `ArrayExtractComponent` to work with objects like
`vtkm::Range` and `vtkm::Bounds` and extract their parts as expected.
This commit is contained in:
Kenneth Moreland 2022-01-25 10:36:03 -07:00
parent f48b4b761e
commit ca032801a8
2 changed files with 66 additions and 10 deletions

@ -93,23 +93,52 @@ template <>
struct ArrayExtractComponentImpl<vtkm::cont::StorageTagStride>
{
template <typename T>
vtkm::cont::ArrayHandleStride<T> operator()(
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> operator()(
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>& src,
vtkm::IdComponent componentIndex,
vtkm::CopyFlag vtkmNotUsed(allowCopy)) const
vtkm::CopyFlag allowCopy) const
{
VTKM_ASSERT(componentIndex == 0);
return src;
return this->DoExtract(
src, componentIndex, allowCopy, typename vtkm::VecTraits<T>::HasMultipleComponents{});
}
template <typename T, vtkm::IdComponent N>
auto operator()(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, vtkm::cont::StorageTagStride>& src,
vtkm::IdComponent componentIndex,
vtkm::CopyFlag allowCopy) const
-> decltype((*this)(vtkm::cont::ArrayHandleStride<T>{}, componentIndex, allowCopy))
private:
template <typename T>
auto DoExtract(const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagStride>& src,
vtkm::IdComponent componentIndex,
vtkm::CopyFlag vtkmNotUsed(allowCopy),
vtkm::VecTraitsTagSingleComponent) const
{
VTKM_ASSERT(componentIndex == 0);
using VTraits = vtkm::VecTraits<T>;
using TBase = typename VTraits::BaseComponentType;
VTKM_STATIC_ASSERT(VTraits::NUM_COMPONENTS == 1);
vtkm::cont::ArrayHandleStride<T> array(src);
// Note, we are initializing the result in this strange way for cases where type
// T has a single component but does not equal its own BaseComponentType. A vtkm::Vec
// of size 1 fits into this category.
return vtkm::cont::ArrayHandleStride<TBase>(array.GetBuffers()[1],
array.GetNumberOfValues(),
array.GetStride(),
array.GetOffset(),
array.GetModulo(),
array.GetDivisor());
}
template <typename VecType>
auto DoExtract(const vtkm::cont::ArrayHandle<VecType, vtkm::cont::StorageTagStride>& src,
vtkm::IdComponent componentIndex,
vtkm::CopyFlag allowCopy,
vtkm::VecTraitsTagMultipleComponents) const
{
using VTraits = vtkm::VecTraits<VecType>;
using T = typename VTraits::ComponentType;
constexpr vtkm::IdComponent N = VTraits::NUM_COMPONENTS;
constexpr vtkm::IdComponent subStride = vtkm::internal::TotalNumComponents<T>::value;
vtkm::cont::ArrayHandleStride<vtkm::Vec<T, N>> array(src);
vtkm::cont::ArrayHandleStride<VecType> array(src);
vtkm::cont::ArrayHandleStride<T> tmpIn(array.GetBuffers()[1],
array.GetNumberOfValues(),
array.GetStride() * N,

@ -13,6 +13,9 @@
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/Bounds.h>
#include <vtkm/Range.h>
#include <vtkm/cont/testing/Testing.h>
namespace
@ -145,11 +148,35 @@ void TryCopy()
}
}
void TryRange()
{
std::cout << "Trying vtkm::Range" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Range> values =
vtkm::cont::make_ArrayHandle<vtkm::Range>({ { 0.0, 1.0 }, { 1.0, 2.0 }, { 2.0, 4.0 } });
vtkm::Range range = vtkm::cont::ArrayGetValue(1, values);
VTKM_TEST_ASSERT(range == vtkm::Range{ 1.0, 2.0 });
}
void TryBounds()
{
std::cout << "Trying vtkm::Bounds" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Bounds> values =
vtkm::cont::make_ArrayHandle<vtkm::Bounds>({ { { 0.0, 1.0 }, { 0.0, 1.0 }, { 0.0, 1.0 } },
{ { 1.0, 2.0 }, { 1.0, 2.0 }, { 1.0, 2.0 } },
{ { 2.0, 4.0 }, { 2.0, 4.0 }, { 2.0, 4.0 } } });
vtkm::Bounds bounds = vtkm::cont::ArrayGetValue(1, values);
VTKM_TEST_ASSERT(bounds == vtkm::Bounds{ { 1.0, 2.0 }, { 1.0, 2.0 }, { 1.0, 2.0 } });
}
void Test()
{
TryCopy<vtkm::Id>();
TryCopy<vtkm::IdComponent>();
TryCopy<vtkm::Float32>();
TryRange();
TryBounds();
}
} // anonymous namespace