7d769a8f4a
Each type of point coordinates has its own class with the name PointCoordinates*. Currently there is a PointCoordiantesArray that contains an ArrayHandle holding the point coordinates and a PointCoordinatesUniform that takes the standard extent, origin, and spacing for a uniform rectilinear grid and defines point coordiantes for that. Creating new PointCoordinates arrays is pretty easy, and we will almost definitely add more. For example, we should have an elevation version that takes uniform coordinates for a 2D grid and then an elevation in the third dimension. We can probably also use a basic composite point coordinates that can build them from other coordinates. There is also a DynamicPointCoordinates class that polymorphically stores an instance of a PointCoordinates class. It has a CastAndCall method that behaves like DynamicArrayHandle; it can call a functor with an array handle (possible implicit) that holds the point coordinates.
389 lines
14 KiB
C++
389 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.
|
|
//
|
|
// Copyright 2014 Sandia Corporation.
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
// Copyright 2014. Los Alamos National Security
|
|
//
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
// this software.
|
|
//============================================================================
|
|
#ifndef vtk_m_cont_DynamicPointCoordinates_h
|
|
#define vtk_m_cont_DynamicPointCoordinates_h
|
|
|
|
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
#include <vtkm/cont/ErrorControlBadValue.h>
|
|
#include <vtkm/cont/PointCoordinatesArray.h>
|
|
#include <vtkm/cont/PointCoordinatesListTag.h>
|
|
|
|
#include <vtkm/cont/internal/DynamicTransform.h>
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
namespace vtkm {
|
|
namespace cont {
|
|
|
|
namespace internal {
|
|
|
|
/// Behaves like (and is interchangable with) a \c DynamicPointCoordinates. The
|
|
/// difference is that the lists of point coordinates, base types, and
|
|
/// containers to try when calling \c CastAndCall is set to the class template
|
|
/// arguments.
|
|
///
|
|
template<typename PointCoordinatesList,
|
|
typename TypeList,
|
|
typename ContainerList>
|
|
class DynamicPointCoordinatesCast;
|
|
|
|
} // namespace internal
|
|
|
|
/// \brief Holds point coordinates polymorphically.
|
|
///
|
|
/// The \c DynamicPointCoordinates holds a point coordinate field for a mesh.
|
|
/// Like a \c DynamicArrayHandle it contains a \c CastAndCall method that
|
|
/// allows it to interface with templated functions and will automatically be
|
|
/// converted on a worklet invoke.
|
|
///
|
|
/// \c DynamicPointCoordinates differes from \c DynamicArrayHandle in the type
|
|
/// of arrays it will check. Point coordinates are often defined as implicit
|
|
/// (uniform), semi-implicit (structured), unstructured, or some combination
|
|
/// thereof. Methods for defining point coordinates are captured in \c
|
|
/// PointCoordinates classes, and \c DynamicPointCoordinates polymorphically
|
|
/// stores one of these \c PointCoordinates objects.
|
|
///
|
|
/// By default, \c DynamicPointCoordinates will assume that the stored point
|
|
/// coordinates are of a type specified by \c
|
|
/// VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG. This can be overriden by using the
|
|
/// \c ResetPointCoordinatesList method.
|
|
///
|
|
/// Internally, some \c PointCoordinates objects will reference dynamic arrays.
|
|
/// Thus, \c DynamicPointCoordinates also maintains lists of types and
|
|
/// containers that these subarrays might use. These default to \c
|
|
/// VTKM_DEFAULT_TYPE_LIST_TAG and \c VTKM_DEFAULT_CONTAINER_LIST_TAG and can
|
|
/// be changed with the \c ResetTypeList and \c ResetContainerList methods.
|
|
///
|
|
class DynamicPointCoordinates
|
|
{
|
|
public:
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinates() { }
|
|
|
|
/// Special constructor for the common case of using a basic array to store
|
|
/// point coordinates.
|
|
///
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinates(const vtkm::cont::DynamicArrayHandle &array)
|
|
: PointCoordinatesContainer(new vtkm::cont::PointCoordinatesArray(array))
|
|
{ }
|
|
|
|
/// Special constructor for the common case of using a basic array to store
|
|
/// point coordinates.
|
|
///
|
|
template<typename Container>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinates(
|
|
const vtkm::cont::ArrayHandle<vtkm::Vector3,Container> &array)
|
|
: PointCoordinatesContainer(new vtkm::cont::PointCoordinatesArray(array))
|
|
{ }
|
|
|
|
/// Takes a concrete point coordinates class and stores it polymorphically.
|
|
/// Although the template will match any possible type, there is a check
|
|
/// to make sure that the type is a valid point coordinates class. If you get
|
|
/// a compile error in the check, follow the instantiation list to where the
|
|
/// constructor is called.
|
|
///
|
|
template<typename PointCoordinatesType>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinates(const PointCoordinatesType &pointCoordinates)
|
|
: PointCoordinatesContainer(new PointCoordinatesType(pointCoordinates))
|
|
{
|
|
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
|
|
}
|
|
|
|
/// Returns true if these point coordinates are stored in a \c
|
|
/// PointCoordinates class of the given type.
|
|
///
|
|
template<typename PointCoordinatesType>
|
|
VTKM_CONT_EXPORT
|
|
bool IsPointCoordinateType(PointCoordinatesType = PointCoordinatesType()) const
|
|
{
|
|
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
|
|
return (this->TryCastPointCoordinatesType<PointCoordinatesType>() != NULL);
|
|
}
|
|
|
|
/// Returns these point coordinates in a \c PointCoordinates class of the
|
|
/// given type. Throws \c ErrorControlBadValue if the cast does not work. Use
|
|
/// \c IsPointCoordinateType to check if the cast can happen.
|
|
///
|
|
template<typename PointCoordinatesType>
|
|
VTKM_CONT_EXPORT
|
|
const PointCoordinatesType &
|
|
CastToPointCoordinates(PointCoordinatesType = PointCoordinatesType()) const {
|
|
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
|
|
PointCoordinatesType *pointCoordinates =
|
|
this->TryCastPointCoordinatesType<PointCoordinatesType>();
|
|
if (pointCoordinates == NULL)
|
|
{
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
"Bad cast of dynamic point coordinates.");
|
|
}
|
|
return *pointCoordinates;
|
|
}
|
|
|
|
/// Changes the point coordinates objects to try casting to when resolving
|
|
/// dynamic arrays within the point coordinates container, which is specified
|
|
/// with a list tag like those in PointCoordinatesListTag.h. Since C++ does
|
|
/// not allow you to actually change the template arguments, this method
|
|
/// returns a new dynamic array object. This method is particularly useful to
|
|
/// narrow down (or expand) the types when using an array of particular
|
|
/// constraints.
|
|
///
|
|
template<typename NewPointCoordinatesList>
|
|
VTKM_CONT_EXPORT
|
|
internal::DynamicPointCoordinatesCast<
|
|
NewPointCoordinatesList,
|
|
VTKM_DEFAULT_TYPE_LIST_TAG,
|
|
VTKM_DEFAULT_CONTAINER_LIST_TAG>
|
|
ResetPointCoordinatesList(
|
|
NewPointCoordinatesList = NewPointCoordinatesList()) const {
|
|
return internal::DynamicPointCoordinatesCast<
|
|
NewPointCoordinatesList,
|
|
VTKM_DEFAULT_TYPE_LIST_TAG,
|
|
VTKM_DEFAULT_CONTAINER_LIST_TAG>(*this);
|
|
}
|
|
|
|
/// Changes the types to try casting to when resolving dynamic arrays within
|
|
/// the point coordinates container, which is specified with a list tag like
|
|
/// those in TypeListTag.h. Since C++ does not allow you to actually change
|
|
/// the template arguments, this method returns a new dynamic array object.
|
|
/// This method is particularly useful to narrow down (or expand) the types
|
|
/// when using an array of particular constraints.
|
|
///
|
|
template<typename NewTypeList>
|
|
VTKM_CONT_EXPORT
|
|
internal::DynamicPointCoordinatesCast<
|
|
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
|
|
NewTypeList,
|
|
VTKM_DEFAULT_CONTAINER_LIST_TAG>
|
|
ResetTypeList(NewTypeList = NewTypeList()) const {
|
|
return internal::DynamicPointCoordinatesCast<
|
|
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
|
|
NewTypeList,
|
|
VTKM_DEFAULT_CONTAINER_LIST_TAG>(*this);
|
|
}
|
|
|
|
/// Changes the array containers to try casting to when resolving dynamic
|
|
/// arrays within the point coordinates container, which is specified with a
|
|
/// list tag like those in ContainerListTag.h. Since C++ does not allow you
|
|
/// to actually change the template arguments, this method returns a new
|
|
/// dynamic array object. This method is particularly useful to narrow down
|
|
/// (or expand) the types when using an array of particular constraints.
|
|
///
|
|
template<typename NewContainerList>
|
|
VTKM_CONT_EXPORT
|
|
internal::DynamicPointCoordinatesCast<
|
|
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
|
|
VTKM_DEFAULT_TYPE_LIST_TAG,
|
|
NewContainerList>
|
|
ResetContainerList(NewContainerList = NewContainerList()) const {
|
|
return internal::DynamicPointCoordinatesCast<
|
|
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
|
|
VTKM_DEFAULT_TYPE_LIST_TAG,
|
|
NewContainerList>(*this);
|
|
}
|
|
|
|
/// Attempts to cast the held point coordinates to a specific array
|
|
/// representation and then call the given functor with the cast array. This
|
|
/// is generally done in two parts. The first part finds the concrete type of
|
|
/// \c PointCoordinates object by trying all those in \c
|
|
/// VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG.
|
|
///
|
|
/// The second part then asks the concrete \c PointCoordinates object to cast
|
|
/// and call to a concrete array. This second cast might rely on \c
|
|
/// VTKM_DEFAULT_TYPE_LIST_TAG and \c VTKM_DEFAULT_CONTAINER_LIST_TAG.
|
|
///
|
|
template<typename Functor>
|
|
VTKM_CONT_EXPORT
|
|
void CastAndCall(const Functor &f) const
|
|
{
|
|
this->CastAndCall(f,
|
|
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG(),
|
|
VTKM_DEFAULT_TYPE_LIST_TAG(),
|
|
VTKM_DEFAULT_CONTAINER_LIST_TAG());
|
|
}
|
|
|
|
/// A version of \c CastAndCall that tries specified lists of point
|
|
/// coordinates, types, and containers.
|
|
///
|
|
template<typename Functor,
|
|
typename PointCoordinatesList,
|
|
typename TypeList,
|
|
typename ContainerList>
|
|
VTKM_CONT_EXPORT
|
|
void CastAndCall(const Functor &f,
|
|
PointCoordinatesList,
|
|
TypeList,
|
|
ContainerList) const;
|
|
|
|
private:
|
|
boost::shared_ptr<vtkm::cont::internal::PointCoordinatesBase>
|
|
PointCoordinatesContainer;
|
|
|
|
template<typename PointCoordinatesType>
|
|
VTKM_CONT_EXPORT
|
|
PointCoordinatesType *
|
|
TryCastPointCoordinatesType() const {
|
|
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
|
|
return dynamic_cast<PointCoordinatesType *>(
|
|
this->PointCoordinatesContainer.get());
|
|
}
|
|
};
|
|
|
|
namespace detail {
|
|
|
|
template<typename Functor, typename TypeList, typename ContainerList>
|
|
struct DynamicPointCoordinatesTryContainer
|
|
{
|
|
const DynamicPointCoordinates PointCoordinates;
|
|
const Functor &Function;
|
|
bool FoundCast;
|
|
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesTryContainer(
|
|
const DynamicPointCoordinates &pointCoordinates,
|
|
const Functor &f)
|
|
: PointCoordinates(pointCoordinates), Function(f), FoundCast(false)
|
|
{ }
|
|
|
|
template<typename PointCoordinatesType>
|
|
VTKM_CONT_EXPORT
|
|
void operator()(PointCoordinatesType) {
|
|
if (!this->FoundCast &&
|
|
this->PointCoordinates.IsPointCoordinateType(PointCoordinatesType()))
|
|
{
|
|
PointCoordinatesType pointCoordinates =
|
|
this->PointCoordinates.CastToPointCoordinates(PointCoordinatesType());
|
|
pointCoordinates.CastAndCall(this->Function, TypeList(), ContainerList());
|
|
this->FoundCast = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template<typename Functor,
|
|
typename PointCoordinatesList,
|
|
typename TypeList,
|
|
typename ContainerList>
|
|
VTKM_CONT_EXPORT
|
|
void DynamicPointCoordinates::CastAndCall(const Functor &f,
|
|
PointCoordinatesList,
|
|
TypeList,
|
|
ContainerList) const
|
|
{
|
|
typedef detail::DynamicPointCoordinatesTryContainer<
|
|
Functor, TypeList, ContainerList> TryTypeType;
|
|
TryTypeType tryType = TryTypeType(*this, f);
|
|
vtkm::ListForEach(tryType, PointCoordinatesList());
|
|
if (!tryType.FoundCast)
|
|
{
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
"Could not find appropriate cast for point coordinates in CastAndCall.");
|
|
}
|
|
}
|
|
|
|
namespace internal {
|
|
|
|
template<typename PointCoordinatesList,
|
|
typename TypeList,
|
|
typename ContainerList>
|
|
class DynamicPointCoordinatesCast : public vtkm::cont::DynamicPointCoordinates
|
|
{
|
|
public:
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast() : DynamicPointCoordinates() { }
|
|
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast(const vtkm::cont::DynamicPointCoordinates &coords)
|
|
: DynamicPointCoordinates(coords) { }
|
|
|
|
template<typename SrcPointCoordinatesList,
|
|
typename SrcTypeList,
|
|
typename SrcContainerList>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast(
|
|
const DynamicPointCoordinatesCast<SrcPointCoordinatesList,SrcTypeList,SrcContainerList> &coords)
|
|
: DynamicPointCoordinates(coords)
|
|
{ }
|
|
|
|
template<typename NewPointCoordinatesList>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast<NewPointCoordinatesList,TypeList,ContainerList>
|
|
ResetPointCoordinatesList(
|
|
NewPointCoordinatesList = NewPointCoordinatesList()) const {
|
|
return DynamicPointCoordinatesCast<
|
|
NewPointCoordinatesList,TypeList,ContainerList>(*this);
|
|
}
|
|
|
|
template<typename NewTypeList>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast<PointCoordinatesList,NewTypeList,ContainerList>
|
|
ResetTypeList(NewTypeList = NewTypeList()) const {
|
|
return DynamicPointCoordinatesCast<
|
|
PointCoordinatesList,NewTypeList,ContainerList>(*this);
|
|
}
|
|
|
|
template<typename NewContainerList>
|
|
VTKM_CONT_EXPORT
|
|
DynamicPointCoordinatesCast<PointCoordinatesList,TypeList,NewContainerList>
|
|
ResetContainerList(NewContainerList = NewContainerList()) const {
|
|
return DynamicPointCoordinatesCast<
|
|
PointCoordinatesList,TypeList,NewContainerList>(*this);
|
|
}
|
|
|
|
template<typename Functor>
|
|
VTKM_CONT_EXPORT
|
|
void CastAndCall(const Functor &f) const
|
|
{
|
|
this->CastAndCall(f, PointCoordinatesList(), TypeList(), ContainerList());
|
|
}
|
|
|
|
template<typename Functor, typename PCL, typename TL, typename CL>
|
|
VTKM_CONT_EXPORT
|
|
void CastAndCall(const Functor &f, PCL, TL, CL) const
|
|
{
|
|
this->DynamicPointCoordinates::CastAndCall(f, PCL(), TL(), CL());
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct DynamicTransformTraits<vtkm::cont::DynamicPointCoordinates> {
|
|
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
|
|
};
|
|
|
|
template<typename PointCoordinatesList,
|
|
typename TypeList,
|
|
typename ContainerList>
|
|
struct DynamicTransformTraits<
|
|
vtkm::cont::internal::DynamicPointCoordinatesCast<
|
|
PointCoordinatesList,TypeList,ContainerList> >
|
|
{
|
|
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
}
|
|
} // namespace vtkm::cont
|
|
|
|
#endif //vtk_m_cont_DynamicPointCoordinates_h
|