diff --git a/docs/users-guide/acknowledgements.rst b/docs/users-guide/acknowledgements.rst index 7a054dfaf8a03d1166b3db99218ddf01376b83f5..eabbc2175c809a91826af6365eb7fa0a3b16ef63 100644 --- a/docs/users-guide/acknowledgements.rst +++ b/docs/users-guide/acknowledgements.rst @@ -38,9 +38,7 @@ contributions to this text: .. Dave Pugmire filters: Streamlines, point transform, coordinate system transforms, add ghost cells, remove ghost cells. -**Abhishek Yenpure** and **Li-Ta Lo** for their documentation of locator structures.. - -.. (Chapter~\ref{chap:Locators}). +**Abhishek Yenpure** and **Li-Ta Lo** for their documentation of locator structures in :chapref:`locators:Locators`. .. Abhishek Yenpure: General cell locators and BoundingIntervalHierarchy .. Li-Ta Lo: General point locators and uniform grid point locator, particle density diff --git a/docs/users-guide/examples/CMakeLists.txt b/docs/users-guide/examples/CMakeLists.txt index 507a5ce0c537c1f7d5f30ca799e841fd15e7ea20..f915df88682f59c6514eb415bc3fddda052e9ead 100644 --- a/docs/users-guide/examples/CMakeLists.txt +++ b/docs/users-guide/examples/CMakeLists.txt @@ -49,6 +49,7 @@ set(examples_device GuideExampleFields.cxx GuideExampleFilterDataSetWithField.cxx GuideExampleGenerateMeshConstantShape.cxx + GuideExamplePointLocator.cxx GuideExampleSimpleAlgorithm.cxx GuideExampleSimpleHistogram.cxx GuideExampleSumOfAngles.cxx diff --git a/docs/users-guide/examples/GuideExampleCellLocator.cxx b/docs/users-guide/examples/GuideExampleCellLocator.cxx index aa40a2cd9f97429c99864962a9927884f146c6c5..3b5216876fae7b7031f15d0daec2bb3381379af2 100644 --- a/docs/users-guide/examples/GuideExampleCellLocator.cxx +++ b/docs/users-guide/examples/GuideExampleCellLocator.cxx @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -105,12 +106,14 @@ struct DemoQueryCells //// RESUME-EXAMPLE //// //// BEGIN-EXAMPLE ConstructCellLocator + //// BEGIN-EXAMPLE CellLocatorGeneral //// vtkm::cont::CellLocatorGeneral cellLocator; cellLocator.SetCellSet(inDataSet.GetCellSet()); cellLocator.SetCoordinates(inDataSet.GetCoordinateSystem()); cellLocator.Update(); //// + //// END-EXAMPLE CellLocatorGeneral //// END-EXAMPLE ConstructCellLocator //// @@ -130,7 +133,7 @@ struct DemoQueryCells } }; -void TestCellLocator() +void TestCellLocator1() { using ValueType = vtkm::Vec3f; using ArrayType = vtkm::cont::ArrayHandle; @@ -162,9 +165,81 @@ void TestCellLocator() VTKM_TEST_ASSERT(test_equal_portals(expected.ReadPortal(), interpolated.ReadPortal())); } +//// +//// BEGIN-EXAMPLE CellLocatorChooser +//// +template +void QueryCells(const CellSetType& cellSet, + const CoordsType& coords, + const QueryPointsType& queryPoints, + const FieldType& inField, + const FieldType& interpolatedField) +{ + VTKM_IS_CELL_SET(CellSetType); + VTKM_IS_ARRAY_HANDLE(CoordsType); + VTKM_IS_ARRAY_HANDLE(QueryPointsType); + VTKM_IS_ARRAY_HANDLE(FieldType); + + vtkm::cont::CellLocatorChooser cellLocator; + cellLocator.SetCellSet(cellSet); + cellLocator.SetCoordinates(coords); + cellLocator.Update(); + + vtkm::cont::Invoker invoke; + invoke( + QueryCellsWorklet{}, queryPoints, cellLocator, cellSet, inField, interpolatedField); +} +//// +//// END-EXAMPLE CellLocatorChooser +//// + +void TestCellLocator2() +{ + using ValueType = vtkm::Vec3f; + using ArrayType = vtkm::cont::ArrayHandle; + + vtkm::cont::DataSet data = vtkm::cont::DataSetBuilderUniform::Create(DimensionSizes); + + ArrayType inField; + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleUniformPointCoordinates( + DimensionSizes, ValueType(0.0f), ValueType(2.0f)), + inField); + + ArrayType queryPoints; + + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleUniformPointCoordinates( + DimensionSizes - vtkm::Id3(1), ValueType(0.5f)), + queryPoints); + + ArrayType interpolated; + + QueryCells(data.GetCellSet().AsCellSet>(), + data.GetCoordinateSystem() + .GetData() + .AsArrayHandle(), + queryPoints, + inField, + interpolated); + + vtkm::cont::ArrayHandleUniformPointCoordinates expected( + DimensionSizes - vtkm::Id3(1), ValueType(1.0f), ValueType(2.0f)); + + std::cout << "Expected: "; + vtkm::cont::printSummary_ArrayHandle(expected, std::cout); + + std::cout << "Interpolated: "; + vtkm::cont::printSummary_ArrayHandle(interpolated, std::cout); + + VTKM_TEST_ASSERT(test_equal_portals(expected.ReadPortal(), interpolated.ReadPortal())); +} + void Run() { - TestCellLocator(); + TestCellLocator1(); + TestCellLocator2(); } } // anonymous namespace diff --git a/docs/users-guide/examples/GuideExamplePointLocator.cxx b/docs/users-guide/examples/GuideExamplePointLocator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f7e731740975098f23caf7e9d91e891b461b67ec --- /dev/null +++ b/docs/users-guide/examples/GuideExamplePointLocator.cxx @@ -0,0 +1,156 @@ +//============================================================================= +// +// 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. +// +//============================================================================= + +#include + +#include +#include +#include + +#include + +#include + +namespace +{ + +constexpr vtkm::Id DimensionSize = 50; +const vtkm::Id3 DimensionSizes = vtkm::Id3(DimensionSize); + +//// +//// BEGIN-EXAMPLE UsePointLocator +//// +/// Worklet that generates for each input coordinate a unit vector that points +/// to the closest point in a locator. +struct PointToClosestWorklet : public vtkm::worklet::WorkletMapField +{ + using ControlSignature = void(FieldIn, ExecObject, WholeArrayIn, FieldOut); + using ExecutionSignature = void(_1, _2, _3, _4); + + template + VTKM_EXEC void operator()(const Point& queryPoint, + const PointLocatorExecObject& pointLocator, + const CoordinateSystemPortal& coordinateSystem, + OutType& out) const + { + // Use the point locator to find the point in the locator closest to the point + // given. + vtkm::Id pointId; + vtkm::FloatDefault distanceSquared; + pointLocator.FindNearestNeighbor(queryPoint, pointId, distanceSquared); + + // Use this information to find the nearest point and create a unit vector + // pointing to it. + if (pointId >= 0) + { + // Get nearest point coordinate. + auto point = coordinateSystem.Get(pointId); + + // Get the vector pointing to this point + out = point - queryPoint; + + // Convert to unit vector (if possible) + if (distanceSquared > vtkm::Epsilon()) + { + out = vtkm::RSqrt(distanceSquared) * out; + } + } + else + { + this->RaiseError("Locator could not find closest point."); + } + } +}; + +// +// Later in the associated Filter class... +// + +//// PAUSE-EXAMPLE +struct DemoQueryPoints +{ + vtkm::cont::Invoker Invoke; + + vtkm::cont::ArrayHandle QueryPoints; + + VTKM_CONT vtkm::cont::ArrayHandle Run( + const vtkm::cont::DataSet& inDataSet) + { + // Note: when more point locators are created, we might want to switch the + // example to a different (perhaps more general) one. + //// RESUME-EXAMPLE + //// + //// BEGIN-EXAMPLE ConstructPointLocator + //// + vtkm::cont::PointLocatorSparseGrid pointLocator; + pointLocator.SetCoordinates(inDataSet.GetCoordinateSystem()); + pointLocator.Update(); + //// + //// END-EXAMPLE ConstructPointLocator + //// + + vtkm::cont::ArrayHandle pointDirections; + + this->Invoke(PointToClosestWorklet{}, + this->QueryPoints, + &pointLocator, + pointLocator.GetCoordinates(), + pointDirections); + //// + //// END-EXAMPLE UsePointLocator + //// + + return pointDirections; + } +}; + +void TestPointLocator() +{ + using ValueType = vtkm::Vec3f; + using ArrayType = vtkm::cont::ArrayHandle; + + vtkm::cont::DataSet data = vtkm::cont::DataSetBuilderUniform::Create(DimensionSizes); + + DemoQueryPoints demo; + + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleUniformPointCoordinates( + DimensionSizes - vtkm::Id3(1), ValueType(0.75f)), + demo.QueryPoints); + + ArrayType pointers = demo.Run(data); + + auto expected = vtkm::cont::make_ArrayHandleConstant( + vtkm::Vec3f(0.57735f), demo.QueryPoints.GetNumberOfValues()); + + std::cout << "Expected: "; + vtkm::cont::printSummary_ArrayHandle(expected, std::cout); + + std::cout << "Calculated: "; + vtkm::cont::printSummary_ArrayHandle(pointers, std::cout); + + VTKM_TEST_ASSERT(test_equal_portals(expected.ReadPortal(), pointers.ReadPortal())); +} + +void Run() +{ + TestPointLocator(); +} + +} // anonymous namespace + +int GuideExamplePointLocator(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(Run, argc, argv); +} diff --git a/docs/users-guide/locators.rst b/docs/users-guide/locators.rst new file mode 100644 index 0000000000000000000000000000000000000000..9e2a47425db74e2a88377ecd28bbbaca92526ed5 --- /dev/null +++ b/docs/users-guide/locators.rst @@ -0,0 +1,231 @@ +============================== +Locators +============================== + +Locators are a special type of structure that allows you to take a point coordinate in space and then find a topological element that contains or is near that coordinate. +|VTKm| comes with multiple types of locators, which are categorized by the type of topological element that they find. +For example, a *cell locator* takes a coordinate in world space and finds the cell in a :class:`vtkm::cont::DataSet` that contains that cell. +Likewise, a *point locator* takes a coordinate in world space and finds a point from a :class:`vtkm::cont::CoordinateSystem` nearby. + +Different locators differ in their interface slightly, but they all follow the same basic operation. +First, they are constructed and provided with one or more elements of a :class:`vtkm::cont::DataSet`. +Then they are built with a call to an :func:`vtkm::cont::CellLocatorBase::Update` method. +The locator can then be passed to a worklet as an ``ExecObject``, which will cause the worklet to get a special execution version of the locator that can do the queries. + +.. didyouknow:: + Other visualization libraries, like |VTKm|'s big sister toolkit VTK, provide similar locator structures that allow iterative building by adding one element at a time. + |VTKm| explicitly disallows this use case. + Although iteratively adding elements to a locator is undoubtedly useful, such an operation will inevitably bottleneck a highly threaded algorithm in critical sections. + This makes iterative additions to locators too costly to support in |VTKm|. + + +------------------------------ +Cell Locators +------------------------------ + +.. index:: + double: locator; cell + +Cell Locators in |VTKm| provide a means of building spatial search structures that can later be used to find a cell containing a certain point. +This could be useful in scenarios where the application demands the cell to which a point belongs to to achieve a certain functionality. +For example, while tracing a particle's path through a vector field, after every step we lookup which cell the particle has entered to interpolate the velocity at the new location to take the next step. + +Using cell locators is a two step process. +The first step is to build the search structure. +This is done by instantiating one of the ``CellLocator`` classes, providing a cell set and coordinate system (usually from a :class:`vtkm::cont::DataSet`), and then updating the structure. +Once the cell locator is built, it can be used in the execution environment within a filter or worklet. + +Building a Cell Locator +============================== + +All cell locators in |VTKm| share the same basic interface for the required features of cell locators. +This generic interface provides methods to set the cell set (with :func:`vtkm::cont::CellLocatorBase::SetCellSet` and :func:`vtkm::cont::CellLocatorBase::GetCellSet`) and to set the coordinate system (with :func:`vtkm::cont::CellLocatorBase::SetCoordinates` and :func:`vtkm::cont::CellLocatorBase::GetCoordinates`). +Once the cell set and coordinates are provided, you may call :func:`vtkm::cont::CellLocatorBase::Update` to construct the search structures. +Although :func:`vtkm::cont::CellLocatorBase::Update` is called from the control environment, the search structure will be built on parallel devices. + +.. load-example:: ConstructCellLocator + :file: GuideExampleCellLocator.cxx + :caption: Constructing a ``CellLocator``. + +|VTKm| provides multiple implementations of cell locators. +All cell locator classes derive the abstract :class:`vtkm::cont::CellLocatorBase` class. + +.. doxygenclass:: vtkm::cont::CellLocatorBase + :members: + +The choice of which cell locator to use depends on the structure of the cells and the regularity of the distribution. + +Cell Locators for Structured Cell Sets +---------------------------------------- + +If your :class:`vtkm::cont::DataSet` has a cell set of type :class:`vtkm::cont::CellSetStructured`, this can give a locator information about the regular nature of the cells to more quickly identify cells. +The mechanism to find the cells then becomes dependent on the type of coordinates in the cell set. + +.. index:: + double: uniform grid; locator + +If the :class:`vtkm::cont::DataSet` contains a :class:`vtkm::cont::ArrayHandleUniformPointCoordinates` as the coordinate system, this is known as a uniform grid. +The cells are aligned with the world axes and have uniform spacing between them. +In this case, the :class:`vtkm::cont::CellLocatorUniformGrid` is highly optimized to find cells. + +.. doxygenclass:: vtkm::cont::CellLocatorUniformGrid + :members: + +.. index:: + double: rectilinear grid; locator + +In a related case, if the :class:`vtkm::cont::DataSet` with structured cells contains a :class:`vtkm::cont::ArrayHandleCartesianProduct` as the coordinate system, this is known as a rectilinear grid. +The cells are aligned with the world axes, but the spacing can vary between them. +In this case, the :class:`vtkm::cont::CellLocatorRectilinearGrid` is best to find cells. + +.. doxygenclass:: vtkm::cont::CellLocatorRectilinearGrid + :members: + +For a :class:`vtkm::cont::DataSet` containing any other type of cell set or coordinate types, one of the locators for irregular cell sets described below must be used. + +Cell Locators for Irregular Cell Sets +---------------------------------------- + +|VTKm| contains several locating strategies cells in irregular patterns in space. +These are typically used for cell sets with explicit connectivity or general positioning of points. +Although they will technically work on any type of data, they may be less efficient than those designed for a specific structure of data. + +A good performing locator across many distributions of cells is :class:`vtkm::cont::CellLocatorTwoLevel`. +This search structure uses a single level of indirection to adapt to an uneven distribution of cells. +This tends to lead to a good balance between the number of ids to trace while finding cells, the number of cells that need to be checked, and the space to store the structure. + +.. doxygenclass:: vtkm::cont::CellLocatorTwoLevel + :members: + +If you happen to know that the cells are evenly distributed across the bounds of the space, then the indirect reference of :class:`vtkm::cont::CellLocatorTwoLevel` is unnecessary. +Each bin in the grid will have approximately the same number of cells, and thus a single level can be used to remove some indirection in the lookup. +This is implemented with :class:`vtkm::cont::CellLocatorUniformBins`. + +.. doxygenclass:: vtkm::cont::CellLocatorUniformBins + :members: + +In contrast, a very irregular data set may have multiple orders of magnitude difference in the size of its cells. +If the cell distribution is very irregular, the :class:`vtkm::cont::CellLocatorTwoLevel` can be left with bins containing a large number of cells in a regions with very small cells. +In these cases, :class:`vtkm::cont::CellLocatorBoundingIntervalHierarchy` can be used to capture the diversity in cell distribution. +:class:`vtkm::cont::CellLocatorBoundingIntervalHierarchy` builds a search structure by recursively dividing the space of cells. +This creates a deeper structure than :class:`vtkm::cont::CellLocatorTwoLevel`, so it can take longer to find a containing bin when searching for a cell. +However, the deeper structure means that each bin is guaranteed to contain a small number of cells. + +.. doxygenclass:: vtkm::cont::CellLocatorBoundingIntervalHierarchy + :members: + +Cell Locators for Unknown Cell Sets +---------------------------------------- + +The previously described cell locators require you to know the type of cell set and coordinate system array to build a cell locator. +Often, this information is not available. +In these cases, |VTKm| provides a couple of classes to choose an appropriate locator. + +If you are developing function that is templated on the type of cell set and coordinate system, you can use the :type:`vtkm::cont::CellLocatorChooser` templated type to automatically choose a locator of an appropriate type. + +.. doxygentypedef:: vtkm::cont::CellLocatorChooser + +.. load-example:: CellLocatorChooser + :file: GuideExampleCellLocator.cxx + :caption: Using :type:`vtkm::cont::CellLocatorChooser` to determine the cell locator type. + +There are times when the type of cell locator cannot be easily determined at compile times. +In this case, the :class:`vtkm::cont::CellLocatorGeneral` can be used. +This locator will accept any type of cell set and coordinate system. +It will then choose at runtime the most appropriate cell locating structure to use. + +.. doxygenclass:: vtkm::cont::CellLocatorGeneral + :members: + +.. load-example:: CellLocatorGeneral + :file: GuideExampleCellLocator.cxx + :caption: Using :class:`vtkm::cont::CellLocatorGeneral`. + +Using Cell Locators in a Worklet +======================================== + +The :class:`vtkm::cont::CellLocatorBase` interface implements :class:`vtkm::cont::ExecutionObjectBase`. +This means that any ``CellLocator`` can be used in worklets as an ``ExecObject`` argument (as defined in the ``ControlSignature``). +See :chapref:`execution-objects:Execution Objects` for information on ``ExecObject`` arguments to worklets. + +When a ``CellLocator`` class is passed as an ``ExecObject`` argument to a worklet :class:`vtkm::cont::Invoke`, the worklet receives a different object defined in the ``vtkm::exec`` namespace. +This ``CellLocator`` object provides a ``FindCell()`` method that identifies a containing cell given a point location in space. + +.. commonerrors:: + Note that the ``CellLocator`` classes in the respective ``vtkm::cont`` and ``vtkm::exec`` namespaces are different objects with different interfaces despite the similar names. + +Below is the documentation for :class:`vtkm::exec::CellLocatorUniformGrid`, which corresponds to the execution query struct provided by :class:`vtkm::cont::CellLocatorUniformGrid`. +That said, this interface is shared among all the execution query structs provided by all locator types. + +.. doxygenclass:: vtkm::exec::CellLocatorUniformGrid + :members: + +The following example defines a simple worklet to get the value of a point field interpolated to a group of query point coordinates provided. + +.. load-example:: UseCellLocator + :file: GuideExampleCellLocator.cxx + :caption: Using a ``CellLocator`` in a worklet. + + +------------------------------ +Point Locators +------------------------------ + +.. index:: + double: locator; point + +Point Locators in |VTKm| provide a means of building spatial search structures that can later be used to find the nearest neighbor a certain point. +This could be useful in scenarios where the closest pairs of points are needed. +For example, during halo finding of particles in cosmology simulations, pairs of nearest neighbors within certain linking length are used to form clusters of particles. + +Using point locators is a two step process. +The first step is to build the search structure. +This is done by instantiating one of the ``PointLocator`` classes, providing a coordinate system (usually from a :class:`vtkm::cont::DataSet`) representing the location of points that can later be found through queries, and then updating the structure. +Once the point locator is built, it can be used in the execution environment within a filter or worklet. + +Building a Point Locator +============================== + +All point locators in |VTKm| share the same basic interface for the required features of point locators. +This generic interface provides methods to set the coordinate system (with :func:`vtkm::cont::PointLocatorBase::SetCoordinates` and :func:`vtkm::cont::PointLocatorBase::GetCoordinates`) of training points. +Once the coordinates are provided, you may call :func:`vtkm::cont::PointLocatorBase::Update` to construct the search structures. +Although :func:`vtkm::cont::PointLocatorBase::Update` is called from the control environment, the search structure will be built on parallel devices + +.. load-example:: ConstructPointLocator + :file: GuideExamplePointLocator.cxx + :caption: Constructing a ``PointLocator``. + +Point locators in |VTKm| derive the abstract :class:`vtkm::cont::PointLocatorBase` class. + +.. doxygenclass:: vtkm::cont::PointLocatorBase + :members: + +|VTKm| implements a point locator named :class:`vtkm::cont::PointLocatorSparseGrid`. + +.. doxygenclass:: vtkm::cont::PointLocatorSparseGrid + :members: + +Using Point Locators in a Worklet +======================================== + +The :class:`vtkm::cont::PointLocator::Base` interface implements :class:`vtkm::cont::ExecutionObjectBase`. +This means that any ``PointLocator`` can be used in worklets as an ``ExecObject`` argument (as defined in the ``ControlSignature``). +See :chapref:`execution-objects:Execution Objects` for information on ``ExecObject`` arguments to worklets. + +When a ``PointLocator`` class is passed as an ``ExecObject`` argument to a worklet :class:`vtkm::cont::Invoke`, the worklet receives a different object defined in the ``vtkm::exec`` namespace. +This ``PointLocator`` object provides a ``FindNearestNeighbor`` method that identifies the nearest neighbor point given a point location in space. + +.. commonerrors:: + Note that the ``PointLocator`` classes in the respective ``vtkm::cont`` and ``vtkm::exec`` namespaces are different objects with different interfaces despite the similar names. + +Below is the documentation for :class:`vtkm::exec::PointLocatorSparseGrid`, which corresponds to the execution query struct provided by :class:`vtkm::cont::PointLocatorSparseGrid`. +That said, this interface is shared among all the execution query structs provided by all locator types. + +.. doxygenclass:: vtkm::exec::PointLocatorSparseGrid + :members: + +The following example defines a simple worklet that finds points nearest to query locations. + +.. load-example:: UsePointLocator + :file: GuideExamplePointLocator.cxx + :caption: Using a ``PointLocator`` in a worklet. diff --git a/docs/users-guide/part-advanced.rst b/docs/users-guide/part-advanced.rst index 7615895aff5f8cf7761141727e76387efc3f211a..af1c8f62914cd34fd86d1a70cfc85d188262241b 100644 --- a/docs/users-guide/part-advanced.rst +++ b/docs/users-guide/part-advanced.rst @@ -16,3 +16,4 @@ Advanced Development fancy-array-handles.rst globals.rst execution-objects.rst + locators.rst diff --git a/vtkm/cont/CellLocatorBase.h b/vtkm/cont/CellLocatorBase.h index bb85fcfccdabde85dd4b7ab5ab6b140a1cb7a308..fd531563fb66dc2450883b9a5f7315549eb78cca 100644 --- a/vtkm/cont/CellLocatorBase.h +++ b/vtkm/cont/CellLocatorBase.h @@ -12,7 +12,6 @@ #include -#include #include #include #include @@ -23,11 +22,11 @@ namespace vtkm namespace cont { -/// \brief Base class for all `CellLocator` classes. +/// @brief Base class for all `CellLocator` classes. /// -/// `CellLocatorBase` uses the curiously recurring template pattern (CRTP). Subclasses -/// must provide their own type for the template parameter. Subclasses must implement -/// `Build()` and `PrepareForExecution()` methods. +/// `CellLocatorBase` subclasses must implement the pure virtual `Build()` method. +/// They also must provide a `PrepareForExecution()` method to satisfy the +/// `ExecutionObjectBase` superclass. /// /// If a derived class changes its state in a way that invalidates its internal search /// structure, it should call the protected `SetModified()` method. This will alert the @@ -62,6 +61,11 @@ public: this->Coords = coords; this->SetModified(); } + /// @copydoc GetCoordinates + VTKM_CONT void SetCoordinates(const vtkm::cont::UnknownArrayHandle& coords) + { + this->SetCoordinates({ "coords", coords }); + } /// @brief Build the search structure used to look up cells. /// diff --git a/vtkm/cont/CellLocatorBoundingIntervalHierarchy.h b/vtkm/cont/CellLocatorBoundingIntervalHierarchy.h index 7598c2567b798bc656019e2e5cbc7823e77977ef..7a31e15ff65617447d4e133b93e7e7be06900d7f 100644 --- a/vtkm/cont/CellLocatorBoundingIntervalHierarchy.h +++ b/vtkm/cont/CellLocatorBoundingIntervalHierarchy.h @@ -27,6 +27,17 @@ namespace vtkm namespace cont { +/// @brief A cell locator that performs a recursive division of space. +/// +/// `CellLocatorBoundingIntervalHierarchy` creates a search structure by recursively +/// dividing the space in which data lives. +/// It starts by choosing an axis to split and then defines a number of splitting planes +/// (set with `SetNumberOfSplittingPlanes()`). +/// These splitting planes divide the physical region into partitions, and the cells are +/// divided among these partitions. +/// The algorithm then recurses into each region and repeats the process until the regions +/// are divided to the point where the contain no more than a maximum number of cells +/// (specified with `SetMaxLeafSize()`). class VTKM_CONT_EXPORT CellLocatorBoundingIntervalHierarchy : public vtkm::cont::CellLocatorBase { public: @@ -38,6 +49,8 @@ public: using ExecObjType = vtkm::ListApply; using LastCell = typename ExecObjType::LastCell; + /// Construct a `CellLocatorBoundingIntervalHierarchy` while optionally specifying the + /// number of splitting planes and number of cells in each leaf. VTKM_CONT CellLocatorBoundingIntervalHierarchy(vtkm::IdComponent numPlanes = 4, vtkm::IdComponent maxLeafSize = 5) @@ -48,25 +61,36 @@ public: { } - VTKM_CONT - void SetNumberOfSplittingPlanes(vtkm::IdComponent numPlanes) + /// @brief Specify the number of splitting planes to use each time a region is divided. + /// + /// Larger numbers of splitting planes result in a shallower tree (which is good because + /// it means fewer memory lookups to find a cell), but too many splitting planes could lead + /// to poorly shaped regions that inefficiently partition cells. + /// + /// The default value is 4. + VTKM_CONT void SetNumberOfSplittingPlanes(vtkm::IdComponent numPlanes) { this->NumPlanes = numPlanes; this->SetModified(); } - - VTKM_CONT - vtkm::IdComponent GetNumberOfSplittingPlanes() { return this->NumPlanes; } - - VTKM_CONT - void SetMaxLeafSize(vtkm::IdComponent maxLeafSize) + /// @copydoc SetNumberOfSplittingPlanes + VTKM_CONT vtkm::IdComponent GetNumberOfSplittingPlanes() { return this->NumPlanes; } + + /// @brief Specify the number of cells in each leaf. + /// + /// Larger numbers for the maximum leaf size result in a shallower tree (which is good + /// because it means fewer memory lookups to find a cell), but it also means there will + /// be more cells to check in each leaf (which is bad as checking a cell is slower + /// than decending a tree level). + /// + /// The default value is 5. + VTKM_CONT void SetMaxLeafSize(vtkm::IdComponent maxLeafSize) { this->MaxLeafSize = maxLeafSize; this->SetModified(); } - - VTKM_CONT - vtkm::Id GetMaxLeafSize() { return this->MaxLeafSize; } + /// @copydoc SetMaxLeafSize + VTKM_CONT vtkm::Id GetMaxLeafSize() { return this->MaxLeafSize; } VTKM_CONT ExecObjType PrepareForExecution(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const; diff --git a/vtkm/cont/CellLocatorRectilinearGrid.h b/vtkm/cont/CellLocatorRectilinearGrid.h index a0d925e212717f6b2e1dfe2c88b4a1a9d15344f8..a9988ffa2e89e40ef88fb22031418402a60fdb7f 100644 --- a/vtkm/cont/CellLocatorRectilinearGrid.h +++ b/vtkm/cont/CellLocatorRectilinearGrid.h @@ -19,6 +19,12 @@ namespace vtkm namespace cont { +/// @brief A cell locator optimized for finding cells in a rectilinear grid. +/// +/// This locator is optimized for structured data that has nonuniform axis-aligned spacing. +/// For this cell locator to work, it has to be given a cell set of type +/// `vtkm::cont::CellSetStructured` and a coordinate system using a +/// `vtkm::cont::ArrayHandleCartesianProduct` for its data. class VTKM_CONT_EXPORT CellLocatorRectilinearGrid : public vtkm::cont::CellLocatorBase { using Structured2DType = vtkm::cont::CellSetStructured<2>; diff --git a/vtkm/cont/CellLocatorTwoLevel.h b/vtkm/cont/CellLocatorTwoLevel.h index a756a1ef15d858622ba4fdd3843dd118e4b43ee2..8c0aea5402be0e8b5a41300a2b4c6fec31d62ffe 100644 --- a/vtkm/cont/CellLocatorTwoLevel.h +++ b/vtkm/cont/CellLocatorTwoLevel.h @@ -37,8 +37,9 @@ namespace cont /// /// The algorithm used in `CellLocatorTwoLevel` is described in the following publication: /// -/// Javor Kalojanov, Markus Billeter, and Philipp Slusallek. "Two-Level Grids for Ray Tracing -/// on GPUs." _Computer Graphics Forum_, 2011, pages 307-314. DOI 10.1111/j.1467-8659.2011.01862.x +/// Javor Kalojanov, Markus Billeter, and Philipp Slusallek. +/// "Two-Level Grids for Ray Tracing on GPUs." +/// _Computer Graphics Forum_, 2011, pages 307-314. DOI 10.1111/j.1467-8659.2011.01862.x /// class VTKM_CONT_EXPORT CellLocatorTwoLevel : public vtkm::cont::CellLocatorBase { @@ -63,24 +64,31 @@ public: { } - /// Get/Set the desired approximate number of cells per level 1 bin + /// @brief Specify the desired approximate number of cells per level 1 bin. /// + /// The default value is 32. void SetDensityL1(vtkm::FloatDefault val) { this->DensityL1 = val; this->SetModified(); } + /// @copydoc SetDensityL1 vtkm::FloatDefault GetDensityL1() const { return this->DensityL1; } - /// Get/Set the desired approximate number of cells per level 1 bin + /// @brief Specify the desired approximate number of cells per level 2 bin. /// + /// This value should be relatively small as it is close to the average number + /// of cells that must be checked for each find. + /// The default value is 2. void SetDensityL2(vtkm::FloatDefault val) { this->DensityL2 = val; this->SetModified(); } + /// @copydoc SetDensityL2 vtkm::FloatDefault GetDensityL2() const { return this->DensityL2; } + /// Print a summary of the state of this locator. void PrintSummary(std::ostream& out) const; ExecObjType PrepareForExecution(vtkm::cont::DeviceAdapterId device, diff --git a/vtkm/cont/CellLocatorUniformBins.h b/vtkm/cont/CellLocatorUniformBins.h index 1f365065efbcfd2b4b6479e678e7830cdaaa88f4..3c23676e9c5a83cbda680dfcd4d7647bd93044ff 100644 --- a/vtkm/cont/CellLocatorUniformBins.h +++ b/vtkm/cont/CellLocatorUniformBins.h @@ -34,7 +34,6 @@ namespace cont /// a uniformly dense triangle grid. In some cases the `CellLocatorUniformBins` /// produces a more efficient search structure, especially for GPUs where memory /// access patterns are critical to performance. - class VTKM_CONT_EXPORT CellLocatorUniformBins : public vtkm::cont::CellLocatorBase { template @@ -52,10 +51,19 @@ public: using ExecObjType = vtkm::ListApply; using LastCell = typename ExecObjType::LastCell; - CellLocatorUniformBins() {} - void SetDims(const vtkm::Id3& dims) { this->UniformDims = dims; } - vtkm::Id3 GetDims() const { return this->UniformDims; } + CellLocatorUniformBins() = default; + + /// @brief Specify the dimensions of the grid used to establish bins. + /// + /// This locator will establish a grid over the bounds of the input data + /// that contains the number of bins specified by these dimensions in each + /// direction. Larger dimensions will reduce the number of cells in each bin, + /// but will require more memory. `SetDims()` must be called before `Update()`. + VTKM_CONT void SetDims(const vtkm::Id3& dims) { this->UniformDims = dims; } + /// @copydoc SetDims + VTKM_CONT vtkm::Id3 GetDims() const { return this->UniformDims; } + /// Print a summary of the state of this locator. void PrintSummary(std::ostream& out) const; public: diff --git a/vtkm/cont/CellLocatorUniformGrid.h b/vtkm/cont/CellLocatorUniformGrid.h index d620a08748770508ef7abf1fb4330f39ffca561c..00e6b34a4946060525f4aa569b8f6bab33403670 100644 --- a/vtkm/cont/CellLocatorUniformGrid.h +++ b/vtkm/cont/CellLocatorUniformGrid.h @@ -19,6 +19,14 @@ namespace vtkm namespace cont { +/// @brief A cell locator optimized for finding cells in a uniform grid. +/// +/// This locator is optimized for structured data that has uniform axis-aligned spacing. +/// For this cell locator to work, it has to be given a cell set of type +/// `vtkm::cont::CellSetStructured` and a coordinate system using a +/// `vtkm::cont::ArrayHandleUniformPointCoordinates` for its coordinate system. +/// If the data set matches this structure, then this locator will be faster than +/// any others. class VTKM_CONT_EXPORT CellLocatorUniformGrid : public vtkm::cont::CellLocatorBase { public: diff --git a/vtkm/cont/PointLocatorSparseGrid.h b/vtkm/cont/PointLocatorSparseGrid.h index 00d626728f36ccf1670e0b02862549f783efabe9..917d55582ec46b75f08abbb39c080f7202bd6170 100644 --- a/vtkm/cont/PointLocatorSparseGrid.h +++ b/vtkm/cont/PointLocatorSparseGrid.h @@ -37,6 +37,10 @@ class VTKM_CONT_EXPORT PointLocatorSparseGrid : public vtkm::cont::PointLocatorB public: using RangeType = vtkm::Vec; + /// @brief Specify the bounds of the space to search for points. + /// + /// If the spatial range is not set, it will be automatically defined to be + /// the space containing the points. void SetRange(const RangeType& range) { if (this->Range != range) @@ -45,7 +49,7 @@ public: this->SetModified(); } } - + /// @copydoc SetRange const RangeType& GetRange() const { return this->Range; } void SetComputeRangeFromCoordinates() @@ -57,6 +61,14 @@ public: } } + /// @brief Specify the number of bins used in the sparse grid to be searched. + /// + /// Larger dimensions result in smaller bins, which in turn means fewer points are + /// in each bin. This means comparing against fewer points. This is good when searching + /// for coincident points. However, when searching for nearest points a distance away, + /// larger dimensions require searching for more bins. + /// + /// The default number of bins is 32x32x32. void SetNumberOfBins(const vtkm::Id3& bins) { if (this->Dims != bins) @@ -65,7 +77,7 @@ public: this->SetModified(); } } - + /// @copydoc SetNumberOfBins const vtkm::Id3& GetNumberOfBins() const { return this->Dims; } VTKM_CONT diff --git a/vtkm/exec/CellLocatorBoundingIntervalHierarchy.h b/vtkm/exec/CellLocatorBoundingIntervalHierarchy.h index d60a52c3d6859e7e7cd2d33a796bd2db956befcd..74622d5191b6497a2c85c66d057184ee722162f9 100644 --- a/vtkm/exec/CellLocatorBoundingIntervalHierarchy.h +++ b/vtkm/exec/CellLocatorBoundingIntervalHierarchy.h @@ -60,6 +60,15 @@ struct CellLocatorBoundingIntervalHierarchyNode } }; // struct CellLocatorBoundingIntervalHierarchyNode +/// @brief Structure for locating cells. +/// +/// Use the `FindCell()` method to identify which cell contains a point in space. +/// The `FindCell()` method optionally takes a `LastCell` object, which is a +/// structure nested in this class. The `LastCell` object can help speed locating +/// cells for successive finds at nearby points. +/// +/// This class is provided by `vtkm::cont::CellLocatorBoundingIntervalHierarchy` +/// when passed to a worklet. template class VTKM_ALWAYS_EXPORT CellLocatorBoundingIntervalHierarchy { @@ -83,26 +92,27 @@ public: { } + /// @copydoc vtkm::exec::CellLocatorUniformGrid::LastCell struct LastCell { vtkm::Id CellId = -1; vtkm::Id NodeIdx = -1; }; - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric) const { LastCell lastCell; return this->FindCellImpl(point, cellId, parametric, lastCell); } - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric, - LastCell& lastCell) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric, + LastCell& lastCell) const { cellId = -1; diff --git a/vtkm/exec/CellLocatorRectilinearGrid.h b/vtkm/exec/CellLocatorRectilinearGrid.h index 5129fc2eb1fc106447065896ab46409f4dbde729..9cae23ff64530a08682c0c99ae80451ed0205417 100644 --- a/vtkm/exec/CellLocatorRectilinearGrid.h +++ b/vtkm/exec/CellLocatorRectilinearGrid.h @@ -28,6 +28,15 @@ namespace vtkm namespace exec { +/// @brief Structure for locating cells. +/// +/// Use the `FindCell()` method to identify which cell contains a point in space. +/// The `FindCell()` method optionally takes a `LastCell` object, which is a +/// structure nested in this class. The `LastCell` object can help speed locating +/// cells for successive finds at nearby points. +/// +/// This class is provided by `vtkm::cont::CellLocatorRectilinearGrid` +/// when passed to a worklet. class VTKM_ALWAYS_EXPORT CellLocatorRectilinearGrid { private: @@ -43,6 +52,7 @@ private: VTKM_CONT static vtkm::Id3 ToId3(vtkm::Id&& src) { return vtkm::Id3(src, 1, 1); } public: + /// @copydoc vtkm::exec::CellLocatorUniformGrid::LastCell struct LastCell { }; @@ -92,19 +102,19 @@ public: return inside; } - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric, - LastCell& vtkmNotUsed(lastCell)) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric, + LastCell& vtkmNotUsed(lastCell)) const { return this->FindCell(point, cellId, parametric); } - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric) const { if (!this->IsInside(point)) { diff --git a/vtkm/exec/CellLocatorTwoLevel.h b/vtkm/exec/CellLocatorTwoLevel.h index 5d0caea8a61b9a7d653817850676dd7a0da73c56..2e22aabc675428a3d48500368a1bc8dd54fc3395 100644 --- a/vtkm/exec/CellLocatorTwoLevel.h +++ b/vtkm/exec/CellLocatorTwoLevel.h @@ -88,6 +88,16 @@ namespace exec { //-------------------------------------------------------------------- + +/// @brief Structure for locating cells. +/// +/// Use the `FindCell()` method to identify which cell contains a point in space. +/// The `FindCell()` method optionally takes a `LastCell` object, which is a +/// structure nested in this class. The `LastCell` object can help speed locating +/// cells for successive finds at nearby points. +/// +/// This class is provided by `vtkm::cont::CellLocatorTwoLevel` +/// when passed to a worklet. template class VTKM_ALWAYS_EXPORT CellLocatorTwoLevel { @@ -153,12 +163,14 @@ public: { } + /// @copydoc vtkm::exec::CellLocatorUniformGrid::LastCell struct LastCell { vtkm::Id CellId = -1; vtkm::Id LeafIdx = -1; }; + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell VTKM_EXEC vtkm::ErrorCode FindCell(const FloatVec3& point, vtkm::Id& cellId, FloatVec3& parametric) const { @@ -166,6 +178,7 @@ public: return this->FindCellImpl(point, cellId, parametric, lastCell); } + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell VTKM_EXEC vtkm::ErrorCode FindCell(const FloatVec3& point, vtkm::Id& cellId, diff --git a/vtkm/exec/CellLocatorUniformBins.h b/vtkm/exec/CellLocatorUniformBins.h index cd71f661c175e5bab49f16e46162c152472ddc73..b81879bded9019405aeb3e40c930eb0db7b2f6a1 100644 --- a/vtkm/exec/CellLocatorUniformBins.h +++ b/vtkm/exec/CellLocatorUniformBins.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -26,6 +27,16 @@ namespace exec { //-------------------------------------------------------------------- + +/// @brief Structure for locating cells. +/// +/// Use the `FindCell()` method to identify which cell contains a point in space. +/// The `FindCell()` method optionally takes a `LastCell` object, which is a +/// structure nested in this class. The `LastCell` object can help speed locating +/// cells for successive finds at nearby points. +/// +/// This class is provided by `vtkm::cont::CellLocatorBoundingIntervalHierarchy` +/// when passed to a worklet. template class VTKM_ALWAYS_EXPORT CellLocatorUniformBins { @@ -68,26 +79,27 @@ public: { } + /// @copydoc vtkm::exec::CellLocatorUniformGrid::LastCell struct LastCell { vtkm::Id CellId = -1; vtkm::Id BinIdx = -1; }; - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric) const { LastCell lastCell; return this->FindCellImpl(point, cellId, parametric, lastCell); } - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric, - LastCell& lastCell) const + /// @copydoc vtkm::exec::CellLocatorUniformGrid::FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric, + LastCell& lastCell) const { vtkm::Id binIdx = this->FindBinIdx(point); diff --git a/vtkm/exec/CellLocatorUniformGrid.h b/vtkm/exec/CellLocatorUniformGrid.h index 63293ae272af59853d5c2594437fe3245487f997..2816d1743b0119c0afddda339fb8433fbb04a5c0 100644 --- a/vtkm/exec/CellLocatorUniformGrid.h +++ b/vtkm/exec/CellLocatorUniformGrid.h @@ -27,6 +27,15 @@ namespace vtkm namespace exec { +/// @brief Structure for locating cells. +/// +/// Use the `FindCell()` method to identify which cell contains a point in space. +/// The `FindCell()` method optionally takes a `LastCell` object, which is a +/// structure nested in this class. The `LastCell` object can help speed locating +/// cells for successive finds at nearby points. +/// +/// This class is provided by `vtkm::cont::CellLocatorUniformGrid` when passed +/// to a worklet. class VTKM_ALWAYS_EXPORT CellLocatorUniformGrid { public: @@ -55,23 +64,45 @@ public: return inside; } + /// @brief Structure capturing the location of a cell in the search structure. + /// + /// An object of this type is passed to and from the `FindCell()` method. + /// If `FindCell()` is called successively with points near each other, the + /// information in this object can reduce the time to find the cell. struct LastCell { }; - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric, - LastCell& vtkmNotUsed(lastCell)) const + /// @brief Locate the cell containing the provided point. + /// + /// Given the point coordinate `point`, this method determines which cell + /// contains that point. The identification of the cell is returned in + /// the `cellId` reference parameter. The method also determines the + /// cell's parametric coordinates to the point and returns that in the + /// `parametric` reference parameter. This result can be used in functions + /// like `vtkm::exec::CellInterpolate()`. + /// + /// `FindCell()` takes an optional `LastCell` parameter. This parameter + /// captures the location of the found cell and can be passed to the next + /// call of `FindCell()`. If the subsequent `FindCell()` call is for a + /// point that is in or near the same cell, the operation may go faster. + /// + /// This method will return `vtkm::ErrorCode::Success` if a cell is found. + /// If a cell is not found, `vtkm::ErrorCode::CellNotFound` is returned + /// and `cellId` is set to `-1`. + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric, + LastCell& lastCell) const { + (void)lastCell; return this->FindCell(point, cellId, parametric); } - VTKM_EXEC - vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, - vtkm::Id& cellId, - vtkm::Vec3f& parametric) const + /// @copydoc FindCell + VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f& point, + vtkm::Id& cellId, + vtkm::Vec3f& parametric) const { if (!this->IsInside(point)) { diff --git a/vtkm/exec/PointLocatorSparseGrid.h b/vtkm/exec/PointLocatorSparseGrid.h index 1ad0b3a7320d3f74b5b035964d11353fe92d64e3..e5372f16d7b51b79e6c514a57701a1b36e1e3a3c 100644 --- a/vtkm/exec/PointLocatorSparseGrid.h +++ b/vtkm/exec/PointLocatorSparseGrid.h @@ -19,6 +19,12 @@ namespace vtkm namespace exec { +/// @brief Structure for locating point. +/// +/// Use the `FindNearestNeighbor()` method to identify which cell contains a point in space. +/// +/// This class is provided by `vtkm::cont::PointLocatorSparseGrid` when passed +/// to a worklet. class VTKM_ALWAYS_EXPORT PointLocatorSparseGrid { public: @@ -44,11 +50,11 @@ public: { } - /// \brief Nearest neighbor search using a Uniform Grid + /// @brief Nearest neighbor search using a Uniform Grid /// - /// Parallel search of nearesat neighbor for each point in the \c queryPoints in the set of - /// \c coords. Returns neareast neighbot in \c nearestNeighborIds and distances to nearest - /// neighbor in \c distances. + /// Parallel search of nearesat neighbor for each point in the `queryPoints` in the set of + /// `coords`. Returns neareast neighbot in `nearestNeighborIds` and distances to nearest + /// neighbor in `distances`. /// /// \param queryPoint Point coordinates to query for nearest neighbor. /// \param nearestNeighborId Neareast neighbor in the training dataset for each points in