mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
9b992dcdde
Getting the number of components (or the number of flattened components) from an `ArrayHandle` is usually trivial. However, if the `ArrayHandle` is special in that the number of components is specified at runtime, then it becomes much more difficult to determine. Getting the number of components is most important when extracting component arrays (or reconstructions using component arrays) with `UnknownArrayHandle`. Previously, `UnknownArrayHandle` used a hack to get the number of components, which mostly worked but broke down when wrapping a runtime array inside another array such as `ArrayHandleView`. To prevent this issue, the ability to get the number of components has been added to `ArrayHandle` proper. All `Storage` objects for `ArrayHandle`s now need a method named `GetNumberOfComponentsFlat`. The implementation of this method is usually trivial. The `ArrayHandle` template now also provides a `GetNumberOfComponentsFlat` method that gets this information from the `Storage`. This provides an easy access point for the `UnknownArrayHandle` to pull this information.
493 lines
14 KiB
C++
493 lines
14 KiB
C++
//============================================================================
|
|
// 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_ArrayHandleXGCCoordinates_h
|
|
#define vtk_m_cont_ArrayHandleXGCCoordinates_h
|
|
|
|
#include <vtkm/Math.h>
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
#include <vtkm/cont/ErrorBadType.h>
|
|
|
|
#include <vtkm/internal/IndicesExtrude.h>
|
|
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace internal
|
|
{
|
|
|
|
template <typename PortalType>
|
|
struct VTKM_ALWAYS_EXPORT ArrayPortalXGCCoordinates
|
|
{
|
|
using ValueType = vtkm::Vec<typename PortalType::ValueType, 3>;
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
ArrayPortalXGCCoordinates()
|
|
: Portal()
|
|
, NumberOfPointsPerPlane(0)
|
|
, NumberOfPlanes(0)
|
|
, NumberOfPlanesOwned(0)
|
|
, PlaneStartId(0)
|
|
, UseCylindrical(false){};
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
ArrayPortalXGCCoordinates(const PortalType& p,
|
|
vtkm::Id numOfPlanes,
|
|
vtkm::Id numOfPlanesOwned,
|
|
vtkm::Id planeStartId,
|
|
bool cylindrical = false)
|
|
: Portal(p)
|
|
, NumberOfPlanes(numOfPlanes)
|
|
, NumberOfPlanesOwned(numOfPlanesOwned)
|
|
, PlaneStartId(planeStartId)
|
|
, UseCylindrical(cylindrical)
|
|
{
|
|
this->NumberOfPointsPerPlane = this->Portal.GetNumberOfValues() / 2;
|
|
}
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
vtkm::Id GetNumberOfValues() const
|
|
{
|
|
return (this->NumberOfPointsPerPlane * static_cast<vtkm::Id>(NumberOfPlanesOwned));
|
|
}
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
ValueType Get(vtkm::Id index) const
|
|
{
|
|
const vtkm::Id realIdx = ((index * 2) % this->Portal.GetNumberOfValues()) / 2;
|
|
const vtkm::Id whichPlane = (index * 2) / this->Portal.GetNumberOfValues() + this->PlaneStartId;
|
|
return this->Get(vtkm::Id2(realIdx, whichPlane));
|
|
}
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
ValueType Get(vtkm::Id2 index) const
|
|
{
|
|
using CompType = typename ValueType::ComponentType;
|
|
|
|
const vtkm::Id realIdx = (index[0] * 2);
|
|
const vtkm::Id whichPlane = index[1];
|
|
const auto phi = static_cast<CompType>(whichPlane * (vtkm::TwoPi() / this->NumberOfPlanes));
|
|
|
|
auto r = this->Portal.Get(realIdx);
|
|
auto z = this->Portal.Get(realIdx + 1);
|
|
if (this->UseCylindrical)
|
|
{
|
|
return ValueType(r, phi, z);
|
|
}
|
|
else
|
|
{
|
|
return ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z);
|
|
}
|
|
}
|
|
|
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
|
VTKM_EXEC_CONT
|
|
vtkm::Vec<ValueType, 6> GetWedge(const exec::IndicesExtrude& index) const
|
|
{
|
|
using CompType = typename ValueType::ComponentType;
|
|
|
|
vtkm::Vec<ValueType, 6> result;
|
|
for (int j = 0; j < 2; ++j)
|
|
{
|
|
const auto phi =
|
|
static_cast<CompType>(index.Planes[j] * (vtkm::TwoPi() / this->NumberOfPlanes));
|
|
for (int i = 0; i < 3; ++i)
|
|
{
|
|
const vtkm::Id realIdx = index.PointIds[j][i] * 2;
|
|
auto r = this->Portal.Get(realIdx);
|
|
auto z = this->Portal.Get(realIdx + 1);
|
|
result[3 * j + i] = this->UseCylindrical
|
|
? ValueType(r, phi, z)
|
|
: ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private:
|
|
PortalType Portal;
|
|
vtkm::Id NumberOfPointsPerPlane;
|
|
vtkm::Id NumberOfPlanes;
|
|
vtkm::Id NumberOfPlanesOwned;
|
|
vtkm::Id PlaneStartId;
|
|
bool UseCylindrical;
|
|
};
|
|
|
|
}
|
|
} // namespace vtkm::internal
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
struct VTKM_ALWAYS_EXPORT StorageTagXGCCoordinates
|
|
{
|
|
};
|
|
|
|
namespace internal
|
|
{
|
|
|
|
struct XGCCoordinatesMetaData
|
|
{
|
|
vtkm::Id NumberOfPlanes = 0;
|
|
vtkm::Id NumberOfPlanesOwned = 0;
|
|
vtkm::Id PlaneStartId = -1;
|
|
bool UseCylindrical = false;
|
|
|
|
XGCCoordinatesMetaData() = default;
|
|
|
|
XGCCoordinatesMetaData(vtkm::Id numberOfPlanes,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
vtkm::Id planeStartId,
|
|
bool useCylindrical)
|
|
: NumberOfPlanes(numberOfPlanes)
|
|
, NumberOfPlanesOwned(numberOfPlanesOwned)
|
|
, PlaneStartId(planeStartId)
|
|
, UseCylindrical(useCylindrical)
|
|
{
|
|
}
|
|
};
|
|
|
|
namespace detail
|
|
{
|
|
|
|
template <typename T>
|
|
class XGCCoordinatesStorageImpl
|
|
{
|
|
using SourceStorage = Storage<T, StorageTagBasic>; // only allow input AH to use StorageTagBasic
|
|
using MetaData = XGCCoordinatesMetaData;
|
|
|
|
static MetaData& GetMetaData(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return buffers[0].GetMetaData<MetaData>();
|
|
}
|
|
|
|
// Used to skip the metadata buffer and return only actual data buffers
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
|
|
}
|
|
|
|
public:
|
|
using ReadPortalType =
|
|
vtkm::internal::ArrayPortalXGCCoordinates<typename SourceStorage::ReadPortalType>;
|
|
|
|
VTKM_CONT static vtkm::IdComponent GetNumberOfComponentsFlat(
|
|
const std::vector<vtkm::cont::internal::Buffer>&)
|
|
{
|
|
return 3;
|
|
}
|
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfValues(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return GetNumberOfValuesPerPlane(buffers) * GetNumberOfPlanesOwned(buffers);
|
|
}
|
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers)) / 2;
|
|
}
|
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfPlanes(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return GetMetaData(buffers).NumberOfPlanes;
|
|
}
|
|
|
|
VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return GetMetaData(buffers).NumberOfPlanesOwned;
|
|
}
|
|
|
|
VTKM_CONT static vtkm::Id GetPlaneStartId(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return GetMetaData(buffers).PlaneStartId;
|
|
}
|
|
|
|
VTKM_CONT static bool GetUseCylindrical(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return GetMetaData(buffers).UseCylindrical;
|
|
}
|
|
|
|
VTKM_CONT static ReadPortalType CreateReadPortal(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers,
|
|
vtkm::cont::DeviceAdapterId device,
|
|
vtkm::cont::Token& token)
|
|
{
|
|
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
|
|
GetNumberOfPlanes(buffers),
|
|
GetNumberOfPlanesOwned(buffers),
|
|
GetPlaneStartId(buffers),
|
|
GetUseCylindrical(buffers));
|
|
}
|
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
|
|
const vtkm::cont::ArrayHandle<T>& array,
|
|
vtkm::Id numberOfPlanes,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
vtkm::Id planeStartId,
|
|
bool useCylindrical)
|
|
{
|
|
return vtkm::cont::internal::CreateBuffers(
|
|
MetaData(numberOfPlanes, numberOfPlanesOwned, planeStartId, useCylindrical), array);
|
|
}
|
|
|
|
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
|
|
{
|
|
return CreateBuffers(vtkm::cont::ArrayHandle<T>{}, 0, 0, 0, false);
|
|
}
|
|
|
|
VTKM_CONT static vtkm::cont::ArrayHandle<T> GetArrayHandle(
|
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
|
{
|
|
return vtkm::cont::ArrayHandle<T>(SourceBuffers(buffers));
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template <>
|
|
class Storage<vtkm::Vec3f_32, vtkm::cont::StorageTagXGCCoordinates>
|
|
: public detail::XGCCoordinatesStorageImpl<vtkm::Float32>
|
|
{
|
|
public:
|
|
VTKM_STORAGE_NO_RESIZE;
|
|
VTKM_STORAGE_NO_WRITE_PORTAL;
|
|
};
|
|
|
|
template <>
|
|
class Storage<vtkm::Vec3f_64, vtkm::cont::StorageTagXGCCoordinates>
|
|
: public detail::XGCCoordinatesStorageImpl<vtkm::Float64>
|
|
{
|
|
public:
|
|
VTKM_STORAGE_NO_RESIZE;
|
|
VTKM_STORAGE_NO_WRITE_PORTAL;
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
template <typename T>
|
|
class VTKM_ALWAYS_EXPORT ArrayHandleXGCCoordinates
|
|
: public vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>
|
|
{
|
|
using AHandleType = vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>>;
|
|
using OriginalType = vtkm::cont::ArrayHandle<T>;
|
|
|
|
public:
|
|
VTKM_ARRAY_HANDLE_SUBCLASS(
|
|
ArrayHandleXGCCoordinates,
|
|
(ArrayHandleXGCCoordinates<T>),
|
|
(vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>));
|
|
|
|
VTKM_CONT
|
|
ArrayHandleXGCCoordinates(const OriginalType& array,
|
|
vtkm::Id numberOfPlanes,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
vtkm::Id planeStartId,
|
|
bool cylindrical)
|
|
: Superclass(StorageType::CreateBuffers(array,
|
|
numberOfPlanes,
|
|
numberOfPlanesOwned,
|
|
planeStartId,
|
|
cylindrical))
|
|
{
|
|
}
|
|
|
|
~ArrayHandleXGCCoordinates() {}
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfPlanes() const
|
|
{
|
|
return StorageType::GetNumberOfPlanes(this->GetBuffers());
|
|
}
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfPlanesOwned() const
|
|
{
|
|
return StorageType::GetNumberOfPlanesOwned(this->GetBuffers());
|
|
}
|
|
|
|
VTKM_CONT vtkm::Id GetPlaneStartId() const
|
|
{
|
|
return StorageType::GetPlaneStartId(this->GetBuffers());
|
|
}
|
|
|
|
VTKM_CONT bool GetUseCylindrical() const
|
|
{
|
|
return StorageType::GetUseCylindrical(this->GetBuffers());
|
|
}
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfPointsPerPlane() const
|
|
{
|
|
return StorageType::GetNumberOfValuesPerPlane(this->GetBuffers());
|
|
}
|
|
|
|
VTKM_CONT OriginalType GetArray() const
|
|
{
|
|
return StorageType::GetArrayHandle(this->GetBuffers());
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
vtkm::cont::ArrayHandleXGCCoordinates<T> make_ArrayHandleXGCCoordinates(
|
|
const vtkm::cont::ArrayHandle<T>& arrHandle,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
bool cylindrical,
|
|
vtkm::Id numberOfPlanes = -1,
|
|
vtkm::Id planeStartId = 0)
|
|
{
|
|
if (numberOfPlanes == -1)
|
|
{
|
|
numberOfPlanes = numberOfPlanesOwned;
|
|
}
|
|
return ArrayHandleXGCCoordinates<T>(
|
|
arrHandle, numberOfPlanes, numberOfPlanesOwned, planeStartId, cylindrical);
|
|
}
|
|
|
|
template <typename T>
|
|
vtkm::cont::ArrayHandleXGCCoordinates<T> make_ArrayHandleXGCCoordinates(
|
|
const T* array,
|
|
vtkm::Id length,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
bool cylindrical,
|
|
vtkm::Id numberOfPlanes = -1,
|
|
vtkm::Id planeStartId = 0,
|
|
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
|
|
{
|
|
if (numberOfPlanes == -1)
|
|
{
|
|
numberOfPlanes = numberOfPlanesOwned;
|
|
}
|
|
return ArrayHandleXGCCoordinates<T>(vtkm::cont::make_ArrayHandle(array, length, copy),
|
|
numberOfPlanes,
|
|
numberOfPlanesOwned,
|
|
planeStartId,
|
|
cylindrical);
|
|
}
|
|
|
|
// if all planes belong to a single partition, then numberOfPlanes and planeStartId not needed
|
|
template <typename T>
|
|
vtkm::cont::ArrayHandleXGCCoordinates<T> make_ArrayHandleXGCCoordinates(
|
|
const std::vector<T>& array,
|
|
vtkm::Id numberOfPlanesOwned,
|
|
bool cylindrical,
|
|
vtkm::Id numberOfPlanes = -1,
|
|
vtkm::Id planeStartId = 0,
|
|
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
|
|
{
|
|
if (!array.empty())
|
|
{
|
|
if (numberOfPlanes == -1)
|
|
{
|
|
numberOfPlanes = numberOfPlanesOwned;
|
|
}
|
|
return make_ArrayHandleXGCCoordinates<T>(&array.front(),
|
|
static_cast<vtkm::Id>(array.size()),
|
|
numberOfPlanesOwned,
|
|
cylindrical,
|
|
numberOfPlanes,
|
|
planeStartId,
|
|
copy);
|
|
}
|
|
else
|
|
{
|
|
// Vector empty. Just return an empty array handle.
|
|
return ArrayHandleXGCCoordinates<T>();
|
|
}
|
|
}
|
|
|
|
}
|
|
} // end namespace vtkm::cont
|
|
|
|
//=============================================================================
|
|
// Specializations of serialization related classes
|
|
/// @cond SERIALIZATION
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
|
|
template <typename T>
|
|
struct SerializableTypeString<vtkm::cont::ArrayHandleXGCCoordinates<T>>
|
|
{
|
|
static VTKM_CONT const std::string& Get()
|
|
{
|
|
static std::string name = "AH_XGCCoordinates<" + SerializableTypeString<T>::Get() + ">";
|
|
return name;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct SerializableTypeString<
|
|
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>>
|
|
: SerializableTypeString<vtkm::cont::ArrayHandleXGCCoordinates<T>>
|
|
{
|
|
};
|
|
}
|
|
} // vtkm::cont
|
|
|
|
namespace mangled_diy_namespace
|
|
{
|
|
|
|
template <typename T>
|
|
struct Serialization<vtkm::cont::ArrayHandleXGCCoordinates<T>>
|
|
{
|
|
private:
|
|
using Type = vtkm::cont::ArrayHandleXGCCoordinates<T>;
|
|
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
|
|
|
public:
|
|
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
|
{
|
|
Type ah = obj;
|
|
vtkmdiy::save(bb, ah.GetNumberOfPlanes());
|
|
vtkmdiy::save(bb, ah.GetNumberOfPlanesOwned());
|
|
vtkmdiy::save(bb, ah.GetPlaneStartId());
|
|
vtkmdiy::save(bb, ah.GetUseCylindrical());
|
|
vtkmdiy::save(bb, ah.GetArray());
|
|
}
|
|
|
|
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& ah)
|
|
{
|
|
vtkm::Id numberOfPlanes;
|
|
vtkm::Id numberOfPlanesOwned;
|
|
vtkm::Id planeStartId;
|
|
bool isCylindrical;
|
|
vtkm::cont::ArrayHandle<T> array;
|
|
|
|
vtkmdiy::load(bb, numberOfPlanes);
|
|
vtkmdiy::load(bb, numberOfPlanesOwned);
|
|
vtkmdiy::load(bb, planeStartId);
|
|
vtkmdiy::load(bb, isCylindrical);
|
|
vtkmdiy::load(bb, array);
|
|
|
|
ah = vtkm::cont::make_ArrayHandleXGCCoordinates(
|
|
array, numberOfPlanes, numberOfPlanesOwned, planeStartId, isCylindrical);
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct Serialization<vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>>
|
|
: Serialization<vtkm::cont::ArrayHandleXGCCoordinates<T>>
|
|
{
|
|
};
|
|
} // diy
|
|
/// @endcond SERIALIZATION
|
|
#endif
|