mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
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:
parent
f48b4b761e
commit
ca032801a8
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user