diff --git a/vtkm/cont/CellLocatorChooser.h b/vtkm/cont/CellLocatorChooser.h index 587c2a37d..91759b800 100644 --- a/vtkm/cont/CellLocatorChooser.h +++ b/vtkm/cont/CellLocatorChooser.h @@ -10,10 +10,12 @@ #ifndef vtk_m_cont_CellLocatorChooser_h #define vtk_m_cont_CellLocatorChooser_h +#include #include #include #include #include +#include namespace vtkm { @@ -29,19 +31,21 @@ struct CellLocatorChooserImpl using type = vtkm::cont::CellLocatorTwoLevel; }; +using UniformArray = vtkm::cont::ArrayHandleUniformPointCoordinates; + template <> -struct CellLocatorChooserImpl, - vtkm::cont::ArrayHandleUniformPointCoordinates> +struct CellLocatorChooserImpl, UniformArray> { using type = vtkm::cont::CellLocatorUniformGrid; }; -template <> -struct CellLocatorChooserImpl< - vtkm::cont::CellSetStructured<3>, +using RectilinearArray = vtkm::cont::ArrayHandleCartesianProduct, vtkm::cont::ArrayHandle, - vtkm::cont::ArrayHandle>> + vtkm::cont::ArrayHandle>; + +template <> +struct CellLocatorChooserImpl, RectilinearArray> { using type = vtkm::cont::CellLocatorRectilinearGrid; }; @@ -59,6 +63,101 @@ 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 diff --git a/vtkm/cont/CellLocatorGeneral.cxx b/vtkm/cont/CellLocatorGeneral.cxx index 244568f8f..272094f1c 100644 --- a/vtkm/cont/CellLocatorGeneral.cxx +++ b/vtkm/cont/CellLocatorGeneral.cxx @@ -83,6 +83,7 @@ CellLocatorGeneral::ExecObjType CellLocatorGeneral::PrepareForExecution( vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { + this->Update(); return this->LocatorImpl.CastAndCall(PrepareFunctor{}, device, token); } diff --git a/vtkm/cont/CellLocatorRectilinearGrid.cxx b/vtkm/cont/CellLocatorRectilinearGrid.cxx index 8cca452bd..d86964cdf 100644 --- a/vtkm/cont/CellLocatorRectilinearGrid.cxx +++ b/vtkm/cont/CellLocatorRectilinearGrid.cxx @@ -54,6 +54,8 @@ vtkm::exec::CellLocatorRectilinearGrid CellLocatorRectilinearGrid::PrepareForExe vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { + this->Update(); + using ExecObjType = vtkm::exec::CellLocatorRectilinearGrid; if (this->Is3D) diff --git a/vtkm/cont/CellLocatorTwoLevel.cxx b/vtkm/cont/CellLocatorTwoLevel.cxx index e4c62afdc..e1294628f 100644 --- a/vtkm/cont/CellLocatorTwoLevel.cxx +++ b/vtkm/cont/CellLocatorTwoLevel.cxx @@ -482,6 +482,7 @@ CellLocatorTwoLevel::ExecObjType CellLocatorTwoLevel::PrepareForExecution( vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { + this->Update(); ExecObjType execObject; this->GetCellSet().CastAndCall(MakeExecObject{}, device, token, *this, execObject); return execObject; diff --git a/vtkm/cont/CellLocatorUniformGrid.cxx b/vtkm/cont/CellLocatorUniformGrid.cxx index ea9c9742f..c2c11bce1 100644 --- a/vtkm/cont/CellLocatorUniformGrid.cxx +++ b/vtkm/cont/CellLocatorUniformGrid.cxx @@ -72,6 +72,7 @@ vtkm::exec::CellLocatorUniformGrid CellLocatorUniformGrid::PrepareForExecution( vtkm::cont::DeviceAdapterId vtkmNotUsed(device), vtkm::cont::Token& vtkmNotUsed(token)) const { + this->Update(); return vtkm::exec::CellLocatorUniformGrid( this->CellDims, this->Origin, this->InvSpacing, this->MaxPoint); } diff --git a/vtkm/cont/internal/CellLocatorBase.h b/vtkm/cont/internal/CellLocatorBase.h index 702b941a3..c2a0386ac 100644 --- a/vtkm/cont/internal/CellLocatorBase.h +++ b/vtkm/cont/internal/CellLocatorBase.h @@ -138,7 +138,7 @@ class VTKM_ALWAYS_EXPORT CellLocatorBase : public vtkm::cont::ExecutionObjectBas { vtkm::cont::DynamicCellSet CellSet; vtkm::cont::CoordinateSystem Coords; - bool Modified = true; + mutable bool Modified = true; public: #ifndef VTKM_NO_DEPRECATED_VIRTUAL @@ -167,11 +167,11 @@ public: this->SetModified(); } - void Update() + void Update() const { if (this->Modified) { - static_cast(this)->Build(); + static_cast(const_cast(this))->Build(); this->Modified = false; } } diff --git a/vtkm/worklet/Probe.h b/vtkm/worklet/Probe.h index fc54fe248..0fc63d86f 100644 --- a/vtkm/worklet/Probe.h +++ b/vtkm/worklet/Probe.h @@ -12,13 +12,12 @@ #include #include -#include +#include +#include #include #include #include -#include -#include #include #include @@ -53,6 +52,16 @@ public: }; private: + struct RunSelectLocator + { + template + void operator()(const LocatorType& locator, Probe& worklet, const PointsType& points) const + { + worklet.Invoke( + FindCellWorklet{}, points, locator, worklet.CellIds, worklet.ParametricCoordinates); + } + }; + template void RunImpl(const CellSetType& cells, const vtkm::cont::CoordinateSystem& coords, @@ -60,14 +69,7 @@ private: { this->InputCellSet = vtkm::cont::DynamicCellSet(cells); - vtkm::cont::CellLocatorGeneral locator; - locator.SetCellSet(this->InputCellSet); - locator.SetCoordinates(coords); - locator.Update(); - - vtkm::worklet::DispatcherMapField dispatcher; - // CellLocatorGeneral is non-copyable. Pass it via a pointer. - dispatcher.Invoke(points, &locator, this->CellIds, this->ParametricCoordinates); + vtkm::cont::CastAndCallCellLocatorChooser(cells, coords, RunSelectLocator{}, *this, points); } //============================================================================ @@ -151,8 +153,8 @@ private: this->CellIds); this->ParametricCoordinates.Allocate(points.GetNumberOfValues()); - vtkm::worklet::DispatcherMapTopology dispatcher; - dispatcher.Invoke(cells, coords, points, this->CellIds, this->ParametricCoordinates); + this->Invoke( + ProbeUniformPoints{}, cells, coords, points, this->CellIds, this->ParametricCoordinates); } //============================================================================ @@ -298,8 +300,7 @@ public: vtkm::cont::ArrayHandle GetHiddenPointsField() const { vtkm::cont::ArrayHandle field; - vtkm::worklet::DispatcherMapField dispatcher; - dispatcher.Invoke(this->CellIds, field); + this->Invoke(HiddenPointsWorklet{}, this->CellIds, field); return field; } @@ -331,8 +332,7 @@ public: vtkm::cont::ArrayHandle GetHiddenCellsField(CellSetType cellset) const { vtkm::cont::ArrayHandle field; - vtkm::worklet::DispatcherMapTopology dispatcher; - dispatcher.Invoke(cellset, this->CellIds, field); + this->Invoke(HiddenCellsWorklet{}, cellset, this->CellIds, field); return field; } @@ -343,6 +343,8 @@ private: vtkm::cont::ArrayHandle CellIds; vtkm::cont::ArrayHandle ParametricCoordinates; vtkm::cont::DynamicCellSet InputCellSet; + + vtkm::cont::Invoker Invoke; }; } } // vtkm::worklet