//============================================================================ // 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_CellLocatorChooser_h #define vtk_m_cont_CellLocatorChooser_h #include #include #include #include #include #include namespace vtkm { namespace cont { namespace detail { template struct CellLocatorChooserImpl { using type = vtkm::cont::CellLocatorTwoLevel; }; using UniformArray = vtkm::cont::ArrayHandleUniformPointCoordinates; template <> struct CellLocatorChooserImpl, UniformArray> { using type = vtkm::cont::CellLocatorUniformGrid; }; using RectilinearArray = vtkm::cont::ArrayHandleCartesianProduct, vtkm::cont::ArrayHandle, vtkm::cont::ArrayHandle>; template <> struct CellLocatorChooserImpl, RectilinearArray> { using type = vtkm::cont::CellLocatorRectilinearGrid; }; } // namespace detail /// \brief A template to select an appropriate CellLocator based on CellSet type. /// /// Given a concrete type for a `CellSet` subclass and a type of `ArrayHandle` for the /// coordinate system, `CellLocatorChooser` picks an appropriate `CellLocator` for that /// type of grid. It is a convenient class to use when you can resolve your templates /// to discover the type of data set being used for location. /// template using CellLocatorChooser = typename detail::CellLocatorChooserImpl::type; namespace detail { struct CastAndCallCellLocatorChooserFunctor { template void CallFunctorWithLocator(const vtkm::cont::DynamicCellSet& cellSet, const vtkm::cont::CoordinateSystem& coordinateSystem, Functor&& functor, Args&&... args) const { CellLocatorType locator; locator.SetCellSet(cellSet); locator.SetCoordinates(coordinateSystem); functor(locator, std::forward(args)...); } template void operator()(const CellSetType& cellSet, const vtkm::cont::CoordinateSystem& coordinateSystem, Functor&& functor, Args&&... args) const { this->CallFunctorWithLocator( cellSet, coordinateSystem, std::forward(functor), std::forward(args)...); } template void operator()(const vtkm::cont::CellSetStructured<3>& cellSet, const vtkm::cont::CoordinateSystem& coordinateSystem, Functor&& functor, Args&&... args) const { auto coordArray = coordinateSystem.GetData(); if (coordArray.IsType()) { this->CallFunctorWithLocator( cellSet, coordinateSystem, std::forward(functor), std::forward(args)...); } else if (coordArray.IsType()) { this->CallFunctorWithLocator( cellSet, coordinateSystem, std::forward(functor), std::forward(args)...); } else { this->CallFunctorWithLocator( cellSet, coordinateSystem, std::forward(functor), std::forward(args)...); } } }; } // namespace detail /// \brief Calls a functor with the appropriate type of `CellLocator`. /// /// Given a cell set and a coordinate system of unknown types, calls a functor with an appropriate /// CellLocator of the given type. The CellLocator is populated with the provided cell set and /// coordinate system. /// /// Any additional args are passed to the functor. /// template VTKM_CONT void CastAndCallCellLocatorChooser( const vtkm::cont::DynamicCellSetBase& cellSet, const vtkm::cont::CoordinateSystem& coordinateSystem, Functor&& functor, Args&&... args) { vtkm::cont::CastAndCall(cellSet, detail::CastAndCallCellLocatorChooserFunctor{}, coordinateSystem, std::forward(functor), std::forward(args)...); } /// \brief Calls a functor with the appropriate type of `CellLocator`. /// /// Given a `DataSet`, calls a functor with an appropriate CellLocator of the given type. /// The CellLocator is populated with the provided cell set and coordinate system. /// /// Any additional args are passed to the functor. /// template VTKM_CONT void CastAndCallCellLocatorChooser(const vtkm::cont::DataSet& dataSet, Functor&& functor, Args&&... args) { CastAndCallCellLocatorChooser(dataSet.GetCellSet(), dataSet.GetCoordinateSystem(), std::forward(functor), std::forward(args)...); } } } // namespace vtkm::cont #endif //vtk_m_cont_CellLocatorChooser_h