OpenVDB  12.0.0
Classes | Namespaces | Typedefs
ValueAccessor.h File Reference

ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing caches to Tree branches. When traversing a grid in a spatially coherent pattern (e.g., iterating over neighboring voxels), the same branches and nodes of the underlying tree can be hit. If you do this using the Tree/RootNode methods directly, traversal will occur at O(log(n)) (or O(n) depending on the hash map implementation) for every access. However, using a ValueAccessor allows for the Accessor to cache previously visited Nodes, providing possible subsequent access speeds of O(1) if the next access is close to a previously cached Node. Accessors are lightweight and can be configured to cache any number of arbitrary Tree levels. More...

#include <openvdb/version.h>
#include <openvdb/Types.h>
#include <openvdb/util/Assert.h>
#include <tbb/spin_mutex.h>
#include <limits>
#include <type_traits>
#include <mutex>

Go to the source code of this file.

Classes

class  ValueAccessorImpl< _TreeType, IsSafe, MutexT, IntegerSequence >
 The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compatible OpenVDB Tree Node. More...
 
class  ValueAccessorBase< TreeType, IsSafe >
 This base class for ValueAccessors manages registration of an accessor with a tree so that the tree can automatically clear the accessor whenever one of its nodes is deleted. More...
 
struct  ValueAccessorLock< MutexT >
 A small class that contains a Mutex which is derived from by the internal Value Accessor Implementation. This allows for the empty base class optimization to be performed in the case where a Mutex/Lock is not in use. From C++20 we can instead switch to [[no_unique_address]]. More...
 
struct  ValueAccessorLock< void >
 Specialization for the case where no Mutex is in use. See above. More...
 
struct  ValueAccessorLeafBuffer< TreeTypeT, IntegerSequence, Enable >
 A small class that contains a cached pointer to a LeafNode data buffer which is derived from by the internal Value Accessor Implementation. This allows for the empty base class optimization to be performed in the case where a LeafNode does not store a contiguous index-able buffer. From C++20 we can instead switch to [[no_unique_address]]. More...
 
struct  ValueAccessorLeafBuffer< TreeTypeT, IntegerSequence, typename std::enable_if< !value_accessor_internal::EnableLeafBuffer< TreeTypeT, IntegerSequence >::value >::type >
 Specialization for the case where a Leaf Buffer cannot be cached. More...
 
class  ValueAccessorImpl< _TreeType, IsSafe, MutexT, IntegerSequence >
 The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compatible OpenVDB Tree Node. More...
 

Namespaces

 openvdb
 
 openvdb::v12_0
 
 openvdb::v12_0::tree
 

Typedefs

template<typename TreeType , bool IsSafe = true, size_t CacheLevels = std::max(Index(1),TreeType::DEPTH)-1, typename MutexType = void>
using ValueAccessor = ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels >>
 Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes a single Index specifying the number of nodes to cache. This is expanded into an index sequence (required for backward compatibility). More...
 
template<typename TreeType , bool IsSafe>
using ValueAccessor0 = ValueAccessorImpl< TreeType, IsSafe, void, openvdb::index_sequence<>>
 Helper alias for a ValueAccessor which doesn't cache any Internal or Leaf nodes. More...
 
template<typename TreeType , bool IsSafe, size_t L0 = 0>
using ValueAccessor1 = ValueAccessorImpl< TreeType, IsSafe, void, openvdb::index_sequence< L0 >>
 Helper alias for a ValueAccessor which caches a single node level. By default, the node level is 0, which corresponds to the lowest node level, typically LeafNodes. More...
 
template<typename TreeType , bool IsSafe, size_t L0 = 0, size_t L1 = 1>
using ValueAccessor2 = ValueAccessorImpl< TreeType, IsSafe, void, openvdb::index_sequence< L0, L1 >>
 Helper alias for a ValueAccessor which caches two node levels. By default the two lowest node levels are selected (0, 1) which typically correspond to an InternalNode and its child LeafNodes. This instantiation will only be valid for TreeTypes which have at least two levels of nodes (excluding the Root node). More...
 
template<typename TreeType , bool IsSafe, size_t L0 = 0, size_t L1 = 1, size_t L2 = 2>
using ValueAccessor3 = ValueAccessorImpl< TreeType, IsSafe, void, openvdb::index_sequence< L0, L1, L2 >>
 Helper alias for a ValueAccessor which caches three node levels. By default the three lowest node levels are selected (0, 1, 2) which typically correspond to two InternalNodes followed by the bottom LeafNodes. This instantiation will only be valid for TreeTypes which have at least three levels of nodes (excluding the Root node). More...
 
template<typename TreeType , bool IsSafe = true, size_t CacheLevels = std::max(Index(1),TreeType::DEPTH)-1>
using ValueAccessorRW = ValueAccessorImpl< TreeType, IsSafe, tbb::spin_mutex, openvdb::make_index_sequence< CacheLevels >>
 Helper alias for a ValueAccesor which spin locks every API call. More...
 

Detailed Description

ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing caches to Tree branches. When traversing a grid in a spatially coherent pattern (e.g., iterating over neighboring voxels), the same branches and nodes of the underlying tree can be hit. If you do this using the Tree/RootNode methods directly, traversal will occur at O(log(n)) (or O(n) depending on the hash map implementation) for every access. However, using a ValueAccessor allows for the Accessor to cache previously visited Nodes, providing possible subsequent access speeds of O(1) if the next access is close to a previously cached Node. Accessors are lightweight and can be configured to cache any number of arbitrary Tree levels.

The ValueAccessor interfaces matches that of compatible OpenVDB Tree nodes. You can request an Accessor from a Grid (with Grid::getAccessor()) or construct one directly from a Tree. You can use, for example, the accessor's getValue() and setValue() methods in place of those on OpenVDB Nodes/Trees.

Example:
FloatGrid grid;
FloatGrid::Accessor acc = grid.getAccessor();
// First access is slow:
acc.setValue(Coord(0, 0, 0), 100);
// Subsequent nearby accesses are fast, since the accessor now holds pointers
// to nodes that contain (0, 0, 0) along the path from the root of the grid's
// tree to the leaf:
acc.setValue(Coord(0, 0, 1), 100);
acc.getValue(Coord(0, 2, 0), 100);
// Slow, because the accessor must be repopulated:
acc.getValue(Coord(-1, -1, -1));
// Fast:
acc.getValue(Coord(-1, -1, -2));
acc.setValue(Coord(-1, -2, 0), -100);