Add ability to extract components in UnknownArrayHandle

This allows you to handle just about every type of array with about 10
basic types. It allows you to ignore both the size of `Vec`s and the
actual storage of the data.
This commit is contained in:
Kenneth Moreland 2020-12-15 17:22:03 -07:00
parent 0f24f82dad
commit 67507185ce
8 changed files with 416 additions and 112 deletions

@ -83,6 +83,17 @@ VTKM_CONT bool UnknownArrayHandle::IsStorageTypeImpl(std::type_index type) const
return this->Container->StorageType == type;
}
VTKM_CONT bool UnknownArrayHandle::IsBaseComponentTypeImpl(std::type_index type) const
{
if (!this->Container)
{
return false;
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Container->BaseComponentType == type;
}
namespace detail
{

@ -12,12 +12,15 @@
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayExtractComponent.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleMultiplexer.h>
#include <vtkm/cont/ArrayHandleStride.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/internal/ArrayPortalFromExtractedComponents.h>
#include <memory>
#include <typeindex>
@ -70,6 +73,36 @@ static vtkm::IdComponent UnknownAHNumberOfComponents()
return UnknownAHNumberOfComponentsImpl<T>::Value;
}
template <typename T, typename StaticSize = typename vtkm::VecTraits<T>::IsSizeStatic>
struct UnknownAHNumberOfComponentsFlatImpl;
template <typename T>
struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeStatic>
{
static constexpr vtkm::IdComponent Value = vtkm::VecFlat<T>::NUM_COMPONENTS;
};
template <typename T>
struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeVariable>
{
static constexpr vtkm::IdComponent Value = 0;
};
template <typename T>
static vtkm::IdComponent UnknownAHNumberOfComponentsFlat()
{
return UnknownAHNumberOfComponentsFlatImpl<T>::Value;
}
template <typename T, typename S>
static std::vector<vtkm::cont::internal::Buffer>
UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
auto componentArray = vtkm::cont::ArrayExtractComponent(*arrayHandle, componentIndex, allowCopy);
vtkm::cont::internal::Buffer* buffers = componentArray.GetBuffers();
return std::vector<vtkm::cont::internal::Buffer>(buffers, buffers + 2);
}
template <typename T, typename S>
static void UnknownAHReleaseResources(void* mem)
{
@ -108,6 +141,7 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
std::type_index ValueType;
std::type_index StorageType;
std::type_index BaseComponentType;
using DeleteType = void(void*);
DeleteType* DeleteFunction;
@ -120,6 +154,12 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
using NumberOfComponentsType = vtkm::IdComponent();
NumberOfComponentsType* NumberOfComponents;
NumberOfComponentsType* NumberOfComponentsFlat;
using ExtractComponentType = std::vector<vtkm::cont::internal::Buffer>(void*,
vtkm::IdComponent,
vtkm::CopyFlag);
ExtractComponentType* ExtractComponent;
using ReleaseResourcesType = void(void*);
ReleaseResourcesType* ReleaseResources;
@ -173,10 +213,13 @@ private:
: ArrayHandlePointer(new vtkm::cont::ArrayHandle<T, S>(array))
, ValueType(typeid(T))
, StorageType(typeid(S))
, BaseComponentType(typeid(typename vtkm::VecTraits<T>::BaseComponentType))
, DeleteFunction(detail::UnknownAHDelete<T, S>)
, NewInstance(detail::UnknownADNewInstance<T, S>)
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T>)
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T>)
, ExtractComponent(detail::UnknownAHExtractComponent<T, S>)
, ReleaseResources(detail::UnknownAHReleaseResources<T, S>)
, ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution<T, S>)
, PrintSummary(detail::UnknownAHPrintSummary<T, S>)
@ -233,6 +276,7 @@ class VTKM_CONT_EXPORT UnknownArrayHandle
VTKM_CONT bool IsValueTypeImpl(std::type_index type) const;
VTKM_CONT bool IsStorageTypeImpl(std::type_index type) const;
VTKM_CONT bool IsBaseComponentTypeImpl(std::type_index type) const;
public:
VTKM_CONT UnknownArrayHandle() = default;
@ -278,6 +322,23 @@ public:
return this->IsStorageTypeImpl(typeid(StorageType));
}
/// \brief Returns true if this array's `ValueType` has the provided base component type.
///
/// The base component type is the recursive component type of any `Vec`-like object. So
/// if the array's `ValueType` is `vtkm::Vec<vtkm::Float32, 3>`, then the base component
/// type will be `vtkm::Float32`. Likewise, if the `ValueType` is
/// `vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 2>`, then the base component type is still
/// `vtkm::Float32`.
///
/// If the `ValueType` is not `Vec`-like type, then the base component type is the same.
/// So a `ValueType` of `vtkm::Float32` has a base component type of `vtkm::Float32`.
///
template <typename BaseComponentType>
VTKM_CONT bool IsBaseComponentType() const
{
return this->IsBaseComponentTypeImpl(typeid(BaseComponentType));
}
/// Returns true if this array matches the ArrayHandleType template argument.
///
template <typename ArrayHandleType>
@ -322,7 +383,8 @@ public:
/// If the array holds `Vec`-like objects that have the number of components that can vary
/// at runtime, this method will return 0 (because there is no consistent answer).
///
VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const
VTKM_CONT VTKM_DEPRECATED(1.6, "Use GetNumberOfComponentsFlat.") vtkm::IdComponent
GetNumberOfComponents() const
{
if (this->Container)
{
@ -334,6 +396,31 @@ public:
}
}
/// \brief Returns the total number of components for each value in the array.
///
/// If the array holds `vtkm::Vec` objects, this will return the total number of components
/// in each value assuming the object is flattened out to one level of `Vec` objects.
/// If the array holds a basic C type (such as `float`), this will return 1.
/// If the array holds a simple `Vec` (such as `vtkm::Vec3f`), this will return the number
/// of components (in this case 3).
/// If the array holds a hierarchy of `Vec`s (such as `vtkm::Vec<vtkm::Vec3f, 2>`), this will
/// return the total number of vecs (in this case 6).
/// If the array holds `Vec`-like objects that have the number of components that can vary
/// at runtime, this method will return 0 (because there is no consistent answer).
///
VTKM_CONT
vtkm::IdComponent GetNumberOfComponentsFlat() const
{
if (this->Container)
{
return this->Container->NumberOfComponentsFlat();
}
else
{
return 0;
}
}
/// \brief Determine if the contained array can be passed to the given array type.
///
/// This method will return true if calling `AsArrayHandle` of the given type will
@ -396,6 +483,97 @@ public:
VTKM_DEPRECATED_SUPPRESS_END
#endif
/// \brief Extract a component of the array.
///
/// This method returns an array that holds the data for a given flat component of the data.
/// The `BaseComponentType` has to be specified and must match the contained array (i.e.
/// the result of `IsBaseComponentType` must succeed for the given type).
///
/// This method treats each value in the array as a flat `Vec` even if it is a `Vec` of
/// `Vec`s. For example, if the array actually holds values of type `Vec<Vec<T, 3>, 2>`,
/// it is treated as if it holds a `Vec<T, 6>`. See `vtkm::VecFlat` for details on how
/// vectors are flattened.
///
/// The point of using `ExtractComponent` over `AsArrayHandle` is that it drastically reduces
/// the amount of types you have to try. Most of the type the base component type is one of
/// the basic C types (i.e. `int`, `long`, `float`, etc.). You do not need to know what shape
/// the containing `Vec` is in, nor do you need to know the actual storage of the array.
///
/// Note that the type of the array returned is `ArrayHandleStride`. Using this type of
/// array handle has a slight overhead over basic arrays like `ArrayHandleBasic` and
/// `ArrayHandleSOA`.
///
/// When extracting a component of an array, a shallow pointer to the data is returned
/// whenever possible. However, in some circumstances it is impossible to conform the
/// array. In these cases, the data are by default copied. If copying the data would
/// cause problems (for example, you are writing into the array), you can select the
/// optional `allowCopy` flag to `vtkm::CopyFlag::Off`. In this case, an exception
/// will be thrown if the result cannot be represented by a shallow copy.
///
template <typename BaseComponentType>
VTKM_CONT vtkm::cont::ArrayHandleStride<BaseComponentType> ExtractComponent(
vtkm::IdComponent componentIndex,
vtkm::CopyFlag allowCopy = vtkm::CopyFlag::On) const
{
using ComponentArrayType = vtkm::cont::ArrayHandleStride<BaseComponentType>;
if (!this->IsBaseComponentType<BaseComponentType>())
{
VTKM_LOG_CAST_FAIL(*this, ComponentArrayType);
throwFailedDynamicCast(vtkm::cont::TypeToString(*this),
"component array of " + vtkm::cont::TypeToString<BaseComponentType>());
}
auto buffers = this->Container->ExtractComponent(
this->Container->ArrayHandlePointer, componentIndex, allowCopy);
return ComponentArrayType(buffers);
}
///@{
/// \brief Convenience portal to access all components (in control environment).
///
/// This method returns a portal that allows you to access all the values in the contained
/// portal by knowing only the type of the base component. The `BaseComponentType` has to
/// be specified and must match the contained array (i.e.the result of `IsBaseComponentType`
/// must succeed for the given type).
///
/// Note that the returned portal is not thread safe, but you may safely create multiple portals
/// for multiple threads.
///
template <typename BaseComponentType>
VTKM_CONT vtkm::cont::internal::ArrayPortalFromExtractedComponents<
typename vtkm::cont::ArrayHandleStride<BaseComponentType>::ReadPortalType>
ReadPortalForBaseComponentType() const
{
vtkm::IdComponent numComponents = this->GetNumberOfComponentsFlat();
vtkm::cont::internal::ArrayPortalFromExtractedComponents<
typename vtkm::cont::ArrayHandleStride<BaseComponentType>::ReadPortalType>
portal(numComponents);
for (vtkm::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
{
auto array = this->ExtractComponent<BaseComponentType>(cIndex, vtkm::CopyFlag::On);
portal.AddArray(array, array.ReadPortal());
}
return portal;
}
template <typename BaseComponentType>
VTKM_CONT vtkm::cont::internal::ArrayPortalFromExtractedComponents<
typename vtkm::cont::ArrayHandleStride<BaseComponentType>::WritePortalType>
WritePortalForBaseComponentType() const
{
vtkm::IdComponent numComponents = this->GetNumberOfComponentsFlat();
vtkm::cont::internal::ArrayPortalFromExtractedComponents<
typename vtkm::cont::ArrayHandleStride<BaseComponentType>::WritePortalType>
portal(numComponents);
for (vtkm::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
{
auto array = this->ExtractComponent<BaseComponentType>(cIndex, vtkm::CopyFlag::Off);
portal.AddArray(array, array.WritePortal());
}
return portal;
}
///@}
/// \brief Call a functor using the underlying array type.
///
/// `CastAndCall` attempts to cast the held array to a specific value type,

@ -0,0 +1,96 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_internal_ArrayPortalFromExtractedComponents_h
#define vtk_m_cont_internal_ArrayPortalFromExtractedComponents_h
#include <vtkm/cont/ArrayHandleStride.h>
#include <vtkm/internal/ArrayPortalHelpers.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
#include <vector>
namespace vtkm
{
namespace cont
{
class UnknownArrayHandle;
namespace internal
{
/// `ArrayPortalFromExtractedComponents` is a convenience class that allows you to treat
/// a group of arrays that were extracted from the components of an array and treat them
/// like a portal to the array itself. It is used internally by `UnknownArrayHandle` to
/// get read and write portals to the array
///
/// Note that this portal only works on the control environment.
///
template <typename PortalType>
class ArrayPortalFromExtractedComponents
{
private:
using T = typename PortalType::ValueType;
std::vector<vtkm::cont::ArrayHandleStride<T>> Arrays;
std::vector<PortalType> Portals;
mutable std::vector<T> Values;
friend UnknownArrayHandle;
void AddArray(const vtkm::cont::ArrayHandleStride<T>& array, const PortalType& portal)
{
this->Arrays.push_back(array);
this->Portals.push_back(portal);
}
public:
using ValueType = vtkm::VecCConst<T>;
ArrayPortalFromExtractedComponents(vtkm::IdComponent expectedArrays = 0)
{
this->Arrays.reserve(static_cast<std::size_t>(expectedArrays));
this->Portals.reserve(static_cast<std::size_t>(expectedArrays));
}
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Portals[0].GetNumberOfValues(); }
VTKM_CONT ValueType Get(vtkm::Id index) const
{
// Note: this is not thread-safe
this->Values.clear();
for (auto&& portal : this->Portals)
{
this->Values.push_back(portal.Get(index));
}
return ValueType(this->Values.data(), static_cast<vtkm::IdComponent>(this->Values.size()));
}
template <typename VecType,
typename Writable = vtkm::internal::PortalSupportsSets<PortalType>,
typename = typename std::enable_if<Writable::value>::type>
VTKM_CONT void Set(vtkm::Id index, const VecType& value) const
{
using Traits = vtkm::VecTraits<VecType>;
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::GetNumberOfComponents(value); ++cIndex)
{
this->Portals[static_cast<std::size_t>(cIndex)].Set(index,
Traits::GetComponent(value, index));
}
}
};
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_internal_ArrayPortalFromExtractedComponents_h

@ -10,6 +10,7 @@
set(headers
ArrayHandleExecutionManager.h
ArrayPortalFromExtractedComponents.h
ArrayPortalFromIterators.h
ArrayTransfer.h
AtomicInterfaceControl.h

@ -55,6 +55,8 @@ namespace vtkm
template <>
struct VecTraits<UnusualType> : VecTraits<UnusualType::T>
{
using ComponentType = UnusualType;
using BaseComponentType = UnusualType;
};
} // namespace vtkm
@ -100,7 +102,7 @@ void BasicUnknownArrayChecks(const vtkm::cont::UnknownArrayHandle& array,
{
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
"Dynamic array reports unexpected size.");
VTKM_TEST_ASSERT(array.GetNumberOfComponents() == numComponents,
VTKM_TEST_ASSERT(array.GetNumberOfComponentsFlat() == numComponents,
"Dynamic array reports unexpected number of components.");
}
@ -426,6 +428,47 @@ void TryAsArrayHandle()
TryAsArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE));
}
template <typename ArrayHandleType>
void TryExtractComponent()
{
using ValueType = typename ArrayHandleType::ValueType;
using FlatVec = vtkm::VecFlat<ValueType>;
using ComponentType = typename FlatVec::ComponentType;
ArrayHandleType originalArray;
originalArray.Allocate(ARRAY_SIZE);
SetPortal(originalArray.WritePortal());
vtkm::cont::UnknownArrayHandle unknownArray(originalArray);
VTKM_TEST_ASSERT(unknownArray.GetNumberOfComponentsFlat() == FlatVec::NUM_COMPONENTS);
auto componentPortal = unknownArray.ReadPortalForBaseComponentType<ComponentType>();
auto originalPortal = originalArray.ReadPortal();
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
FlatVec originalData = originalPortal.Get(valueIndex);
auto componentData = componentPortal.Get(valueIndex);
VTKM_TEST_ASSERT(test_equal(originalData, componentData));
}
}
void TryExtractComponent()
{
std::cout << " Scalar array." << std::endl;
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::FloatDefault>>();
std::cout << " Basic Vec." << std::endl;
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Id3>>();
std::cout << " Vec of Vecs." << std::endl;
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Vec2f, 3>>>();
std::cout << " Vec of Vecs of Vecs." << std::endl;
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Vec<vtkm::Id4, 3>, 2>>>();
}
void TrySetCastArray()
{
vtkm::cont::ArrayHandle<vtkm::Id> knownArray = CreateArray(vtkm::Id{});
@ -473,6 +516,9 @@ void TestUnknownArrayHandle()
std::cout << "Try AsArrayHandle" << std::endl;
TryAsArrayHandle();
std::cout << "Try ExtractComponent" << std::endl;
TryExtractComponent();
std::cout << "Try setting ArrayHandleCast" << std::endl;
TrySetCastArray();

@ -71,6 +71,8 @@ namespace vtkm
template <>
struct VecTraits<UnusualType> : VecTraits<UnusualType::T>
{
using ComponentType = UnusualType;
using BaseComponentType = UnusualType;
};
} // namespace vtkm
@ -145,9 +147,9 @@ void BasicArrayVariantChecks(const vtkm::cont::VariantArrayHandleBase<TypeList>&
{
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
"Dynamic array reports unexpected size.");
std::cout << "array.GetNumberOfComponents() = " << array.GetNumberOfComponents() << ", "
std::cout << "array.GetNumberOfComponents() = " << array.GetNumberOfComponentsFlat() << ", "
<< "numComponents = " << numComponents << "\n";
VTKM_TEST_ASSERT(array.GetNumberOfComponents() == numComponents,
VTKM_TEST_ASSERT(array.GetNumberOfComponentsFlat() == numComponents,
"Dynamic array reports unexpected number of components.");
}

@ -35,112 +35,95 @@
namespace
{
struct CallForBaseTypeFunctor
{
template <typename T, typename Functor, typename... Args>
void operator()(T t,
bool& success,
Functor functor,
const vtkm::cont::UnknownArrayHandle& array,
Args&&... args)
{
if (!array.IsBaseComponentType<T>())
{
return;
}
success = true;
functor(t, array, std::forward<Args>(args)...);
}
};
template <typename Functor, typename... Args>
void CallForBaseType(Functor&& functor, const vtkm::cont::UnknownArrayHandle& array, Args&&... args)
{
bool success = true;
vtkm::ListForEach(CallForBaseTypeFunctor{},
vtkm::TypeListScalarAll{},
success,
std::forward<Functor>(functor),
array,
std::forward<Args>(args)...);
if (!success)
{
std::ostringstream out;
out << "Unrecognized base type in array to be written out.\nArray: ";
array.PrintSummary(out);
throw vtkm::cont::ErrorBadValue(out.str());
}
}
template <typename T>
using ArrayHandleRectilinearCoordinates =
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T>,
vtkm::cont::ArrayHandle<T>,
vtkm::cont::ArrayHandle<T>>;
struct OutputPointsFunctor
struct OutputArrayDataFunctor
{
private:
std::ostream& out;
template <typename PortalType>
VTKM_CONT void Output(const PortalType& portal) const
template <typename T>
VTKM_CONT void operator()(T, const vtkm::cont::UnknownArrayHandle& array, std::ostream& out) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
auto portal = array.ReadPortalForBaseComponentType<T>();
vtkm::Id numValues = portal.GetNumberOfValues();
for (vtkm::Id valueIndex = 0; valueIndex < numValues; ++valueIndex)
{
const int VTKDims = 3; // VTK files always require 3 dims for points
using ValueType = typename PortalType::ValueType;
using VecType = typename vtkm::VecTraits<ValueType>;
const ValueType& value = portal.Get(index);
vtkm::IdComponent numComponents = VecType::GetNumberOfComponents(value);
for (vtkm::IdComponent c = 0; c < numComponents && c < VTKDims; c++)
auto value = portal.Get(valueIndex);
for (vtkm::IdComponent cIndex = 0; cIndex < value.GetNumberOfComponents(); ++cIndex)
{
out << (c == 0 ? "" : " ") << VecType::GetComponent(value, c);
out << ((cIndex == 0) ? "" : " ") << value[cIndex];
}
for (vtkm::IdComponent c = numComponents; c < VTKDims; c++)
{
out << " 0";
}
out << '\n';
out << "\n";
}
}
public:
VTKM_CONT
OutputPointsFunctor(std::ostream& o)
: out(o)
{
}
template <typename T, typename Storage>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, Storage>& array) const
{
this->Output(array.ReadPortal());
}
};
struct OutputFieldFunctor
void OutputArrayData(const vtkm::cont::UnknownArrayHandle& array, std::ostream& out)
{
private:
std::ostream& out;
CallForBaseType(OutputArrayDataFunctor{}, array, out);
}
template <typename PortalType>
VTKM_CONT void Output(const PortalType& portal) const
struct GetFieldTypeNameFunctor
{
template <typename Type>
void operator()(Type, const vtkm::cont::UnknownArrayHandle& array, std::string& name) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
if (array.IsBaseComponentType<Type>())
{
using ValueType = typename PortalType::ValueType;
using VecType = typename vtkm::VecTraits<ValueType>;
const ValueType& value = portal.Get(index);
vtkm::IdComponent numComponents = VecType::GetNumberOfComponents(value);
for (vtkm::IdComponent c = 0; c < numComponents; c++)
{
out << (c == 0 ? "" : " ") << VecType::GetComponent(value, c);
}
out << '\n';
name = vtkm::io::internal::DataTypeName<Type>::Name();
}
}
public:
VTKM_CONT
OutputFieldFunctor(std::ostream& o)
: out(o)
{
}
template <typename T, typename Storage>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, Storage>& array) const
{
this->Output(array.ReadPortal());
}
};
class GetDataTypeName
std::string GetFieldTypeName(const vtkm::cont::UnknownArrayHandle& array)
{
public:
GetDataTypeName(std::string& name)
: Name(&name)
{
}
template <typename ArrayHandleType>
void operator()(const ArrayHandleType&) const
{
using DataType = typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType;
*this->Name = vtkm::io::internal::DataTypeName<DataType>::Name();
}
private:
std::string* Name;
};
std::string name;
CallForBaseType(GetFieldTypeNameFunctor{}, array, name);
return name;
}
template <vtkm::IdComponent DIM>
void WriteDimensions(std::ostream& out, const vtkm::cont::CellSetStructured<DIM>& cellSet)
@ -160,13 +143,12 @@ void WritePoints(std::ostream& out, const vtkm::cont::DataSet& dataSet)
int cindex = 0;
auto cdata = dataSet.GetCoordinateSystem(cindex).GetData();
std::string typeName;
vtkm::cont::CastAndCall(cdata, GetDataTypeName(typeName));
std::string typeName = GetFieldTypeName(cdata);
vtkm::Id npoints = cdata.GetNumberOfValues();
out << "POINTS " << npoints << " " << typeName << " " << '\n';
cdata.CastAndCall(OutputPointsFunctor{ out });
OutputArrayData(cdata, out);
}
template <class CellSetType>
@ -215,11 +197,7 @@ void WritePointFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
}
vtkm::Id npoints = field.GetNumberOfValues();
int ncomps = field.GetData().GetNumberOfComponents();
if (ncomps > 4)
{
continue;
}
int ncomps = field.GetData().GetNumberOfComponentsFlat();
if (!wrote_header)
{
@ -227,9 +205,7 @@ void WritePointFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
wrote_header = true;
}
std::string typeName;
vtkm::cont::CastAndCall(field.GetData().ResetTypes(vtkm::TypeListAll{}),
GetDataTypeName(typeName));
std::string typeName = GetFieldTypeName(field.GetData());
std::string name = field.GetName();
for (auto& c : name)
{
@ -241,8 +217,7 @@ void WritePointFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
out << "SCALARS " << name << " " << typeName << " " << ncomps << '\n';
out << "LOOKUP_TABLE default" << '\n';
vtkm::cont::CastAndCall(field.GetData().ResetTypes(vtkm::TypeListAll{}),
OutputFieldFunctor(out));
OutputArrayData(field.GetData(), out);
}
}
@ -259,9 +234,7 @@ void WriteCellFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
vtkm::Id ncells = field.GetNumberOfValues();
int ncomps = field.GetData().GetNumberOfComponents();
if (ncomps > 4)
continue;
int ncomps = field.GetData().GetNumberOfComponentsFlat();
if (!wrote_header)
{
@ -269,9 +242,7 @@ void WriteCellFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
wrote_header = true;
}
std::string typeName;
vtkm::cont::CastAndCall(field.GetData().ResetTypes(vtkm::TypeListAll{}),
GetDataTypeName(typeName));
std::string typeName = GetFieldTypeName(field.GetData());
std::string name = field.GetName();
for (auto& c : name)
@ -285,8 +256,7 @@ void WriteCellFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
out << "SCALARS " << name << " " << typeName << " " << ncomps << '\n';
out << "LOOKUP_TABLE default" << '\n';
vtkm::cont::CastAndCall(field.GetData().ResetTypes(vtkm::TypeListAll{}),
OutputFieldFunctor(out));
OutputArrayData(field.GetData(), out);
}
}
@ -330,15 +300,15 @@ void WriteDataSetAsRectilinearGrid(std::ostream& out,
dimArray = points.GetFirstArray();
out << "X_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
OutputFieldFunctor{ out }(dimArray);
OutputArrayData(dimArray, out);
dimArray = points.GetSecondArray();
out << "Y_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
OutputFieldFunctor{ out }(dimArray);
OutputArrayData(dimArray, out);
dimArray = points.GetThirdArray();
out << "Z_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
OutputFieldFunctor{ out }(dimArray);
OutputArrayData(dimArray, out);
}
template <vtkm::IdComponent DIM>

@ -82,7 +82,7 @@ Actor::Actor(const vtkm::cont::DynamicCellSet& cells,
void Actor::Init(const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::cont::Field& scalarField)
{
VTKM_ASSERT(scalarField.GetData().GetNumberOfComponents() == 1);
VTKM_ASSERT(scalarField.GetData().GetNumberOfComponentsFlat() == 1);
scalarField.GetRange(&this->Internals->ScalarRange);
this->Internals->SpatialBounds = coordinates.GetBounds();