OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
PointTransfer.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3//
4/// @author Nick Avramoussis
5///
6/// @file PointTransfer.h
7///
8/// @brief Framework methods for rasterizing PointDataGrid data to Trees.
9///
10/// @details Provides a generic inherited interface for deriving transfer
11/// schemes that represent how point data should be rasterized. The provided
12/// components together support the transfer of multiple attributes to
13/// arbitrary and multiple grid types. Target grids must have the same
14/// transform, but this transform can differ from the source PointDataGrid
15/// (multiple instantiations of rasterize() should instead be invoked to
16/// transfer to grids of different transforms). Arbitrary attributes can be
17/// accessed and transfered to arbitrary trees.
18///
19
20#ifndef OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
21#define OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
22
23#include <openvdb/openvdb.h>
24#include <openvdb/Types.h>
25#include <openvdb/Grid.h>
28#include <openvdb/util/Assert.h>
29#include <openvdb/thread/Threading.h>
30
31#include <type_traits>
32#include <tuple>
33
34namespace openvdb {
36namespace OPENVDB_VERSION_NAME {
37namespace points {
38
39/// @par A transfer scheme must be configured to call the provided
40/// rasterize methods. See below for an example or
41/// PointRasterizeSDF.h/PointRasterizeTrilinear.h for implementations.
42/// @code
43/// struct Transfer
44/// {
45/// /// @return Returns the tree topology to loop over. This can be different
46/// /// from the destination tree i.e. This can act as a mask.
47/// inline auto& topology();
48///
49/// /// @brief The maximum lookup range of this transfer scheme in index
50/// /// space of the source points.
51/// /// @details The return value represent how far away from the destination
52/// /// leaf node points should be accessed.
53/// /// @param origin The leaf origin of the topology being accessed
54/// /// @param idx The leaf index of the topology being accessed
55/// inline Int32 range(const Coord& origin, size_t idx) const;
56///
57/// /// @brief The initialize function, called on each leaf which has valid
58/// /// topology to write to.
59/// /// @param origin The leaf origin of the topology being accessed
60/// /// @param idx The leaf index of the topology being accessed
61/// /// @param bounds The active voxel bounds of the leaf
62/// inline void initialize(const Coord& origin, size_t idx, const CoordBBox& bounds);
63///
64/// /// @brief Run each time a point leaf is accessed. Typically this is
65/// /// where attribute handles can be constructed
66/// /// @param leaf The PointDataLeafNode which is being accessed.
67/// /// @return Return true to continue rasterization, false to early exit
68/// /// and skip the current leaf's contribution to the destination volume.
69/// inline bool startPointLeaf(const PointDataTree::LeafNodeType& leaf);
70///
71/// /// @brief The point stamp function. Each point which contributes to
72/// /// the current leaf will call this function exactly once.
73/// /// @param ijk The current voxel containing the point being rasterized.
74/// /// May be outside the destination leaf node depending on the range()
75/// /// @param id The point index being rasterized
76/// /// @param bounds The active bounds of the leaf node.
77/// void rasterizePoint(const Coord& ijk,
78/// const Index id,
79/// const CoordBBox& bounds);
80///
81/// /// @brief Run each time a point leaf is finished with.
82/// /// @param leaf The PointDataLeafNode which was being accessed.
83/// /// @return Return true to continue rasterization, false to early exit
84/// /// and stop rasterization to the destination leaf node.
85/// inline bool endPointLeaf(const PointDataTree::LeafNodeType& leaf);
86///
87/// /// @brief The finalization function for the given destination tree(s).
88/// /// @param origin The leaf origin of the topology being accessed
89/// /// @param idx The leaf index of the topology being accessed
90/// /// @return Return true to stop, false to recursively rasterize
91/// inline bool finalize(const Coord& origin, size_t idx);
92/// };
93/// @endcode
94///
95///
96/// Below is a full example using the native components.
97///
98/// @code
99/// /// @brief Sum point distances into a target float tree
100/// /// Note: Using TransformTransfer to handle different index spaces, and
101/// /// VolumeTransfer for automatic buffer setup
102/// struct MyTransfer :
103/// public TransformTransfer,
104/// public VolumeTransfer<FloatTree>
105/// {
106/// MyTransfer(FloatGrid& dest, const PointDataGrid& source)
107/// : TransformTransfer(source.transform(), dest.transform())
108/// , VolumeTransfer(dest.tree())
109/// , mHandle(nullptr) {}
110///
111/// MyTransfer(const MyTransfer& other)
112/// : TransformTransfer(other)
113/// , VolumeTransfer(other)
114/// , mHandle(nullptr) {}
115///
116/// /// @brief Range in index space of the source points
117/// Int32 range(const Coord&, size_t) const { return Int32(1); }
118///
119/// /// @brief Every time we start a new point leaf, init the position array.
120/// /// Always return true as we don't skip any leaf nodes.
121/// bool startPointLeaf(const PointDataTree::LeafNodeType& leaf)
122/// {
123/// mHandle.reset(new AttributeHandle<Vec3f>(leaf.constAttributeArray("P"));
124/// return true;
125/// }
126///
127/// /// @brief For each point, compute its relative index space position in
128/// /// the destination tree and sum the length of its distance
129/// void rasterizePoint(const Coord& ijk, const Index id, const CoordBBox& bounds)
130/// {
131/// Vec3d P = ijk.asVec3d() + Vec3d(this->mHandle->get(id));
132/// P = this->transformSourceToTarget(P); // TransformTransfer::transformSourceToTarget
133/// // for each active voxel, accumulate distance
134/// const auto* mask = this->mask(); // VolumeTransfer::mask
135/// for (auto& coord : bounds) {
136/// const Index voxel = FloatTree::LeafNodeType::coordToOffset(coord);
137/// if (!mask->isOn(voxel)) continue;
138/// Vec3d dist = coord.asVec3d() - P;
139/// this->buffer()[voxel] += dist.length(); // VolumeTransfer::buffer
140/// }
141/// }
142///
143/// /// @brief Return true for endPointLeaf() to continue, false for finalize() so
144/// /// we don't recurse.
145/// bool endPointLeaf(const PointDataTree::LeafNodeType&) { return true; }
146/// bool finalize(const Coord&, size_t) { return false; }
147///
148/// private:
149/// std::unique_ptr<AttributeHandle<Vec3f>> mHandle;
150/// };
151/// @endcode
152
153
154/// @brief Perform potentially complex rasterization from a user defined
155/// transfer scheme.
156/// @details The method works by looping over a single Tree topology, looking
157/// up point data at a position relative to that topology and passing that
158/// data to a transfer scheme TransferT.
159/// @note Each thread receives a copy of the transfer scheme object.
160/// @param points the point data grid to rasterize
161/// @param transfer the transfer scheme
162/// @param filter optional point filter
163/// @param interrupter optional interrupter
164template <typename PointDataTreeOrGridT,
165 typename TransferT,
166 typename FilterT = NullFilter,
167 typename InterrupterT = util::NullInterrupter>
168inline void
169rasterize(const PointDataTreeOrGridT& points,
170 TransferT& transfer,
171 const FilterT& filter = NullFilter(),
172 InterrupterT* interrupter = nullptr);
173
174
175///////////////////////////////////////////////////
176
177/// @brief The TransformTransfer module should be used if the source transform
178/// of the input points and the target transforms of the destination volumes
179/// differ. The default rasterizer will skip index to world (and vice versa)
180/// transformations unless a transfer scheme derives from a TransformTransfer.
182{
184 const math::Transform& tt)
185 : mSourceTransform(st)
186 , mTargetTransform(tt) {}
187
188 template <typename T>
189 inline auto transformSourceToTarget(const T& value) const
190 {
191 const auto result = mSourceTransform.indexToWorld(value);
192 return mTargetTransform.worldToIndex(result);
193 }
194
195 template <typename T>
196 inline auto transformTargetToSource(const T& value) const
197 {
198 const auto result = mTargetTransform.indexToWorld(value);
199 return mSourceTransform.worldToIndex(result);
200 }
201
202 const math::Transform& sourceTransform() const { return mSourceTransform; }
203 const math::Transform& targetTransform() const { return mTargetTransform; }
204
205private:
206 const math::Transform& mSourceTransform;
207 const math::Transform& mTargetTransform;
208};
209
210/// @brief The VolumeTransfer module provides methods to automatically setup
211/// and access destination buffers for multiple target volumes of arbitrary
212/// types. Deriving from a VolumeTransfer ensures that the available
213/// buffers correlate to the order of the provided tree arguments.
214template <typename ...TreeTypes>
216{
217 static const size_t Size = sizeof...(TreeTypes);
218 using TreeTupleT = std::tuple<TreeTypes*...>;
219
220 template <size_t Idx> using TreeType = typename std::tuple_element<Idx, std::tuple<TreeTypes...>>::type;
221 template <size_t Idx> using ValueType = typename TreeType<Idx>::ValueType;
222 template <typename T> struct TypeResolver { using Type = typename T::ValueType; };
224
226
228 : VolumeTransfer(&trees...) {}
229
231 : mTreeArray(other.mTreeArray)
232 , mBuffers()
233 , mMasks()
234 {
235 mBuffers.fill(nullptr);
236 mMasks.fill(nullptr);
237 }
238
239 inline TreeType<0>& topology() { return *(std::get<0>(mTreeArray)); }
240
241 inline void initialize(const Coord& origin, const size_t, const CoordBBox&);
242
243 template <size_t Idx>
245 {
246 return static_cast<ValueType<Idx>*>(mBuffers[Idx]);
247 }
248
249 template <size_t Idx>
250 inline const ValueType<Idx>* buffer() const
251 {
252 return static_cast<ValueType<Idx>*>(mBuffers[Idx]);
253 }
254
255 template <size_t Idx>
256 inline NodeMaskT* mask() { return mMasks[Idx]; }
257 inline NodeMaskT* mask(const size_t idx) { return mMasks[idx]; }
258
259 template <size_t Idx>
260 inline const NodeMaskT* mask() const { return mMasks[Idx]; }
261 inline const NodeMaskT* mask(const size_t idx) const { return mMasks[idx]; }
262
263 template <typename FunctorT>
264 inline void foreach(const FunctorT& functor);
265
266private:
267 const TreeTupleT mTreeArray;
268 std::array<void*, Size> mBuffers;
269 std::array<NodeMaskT*, Size> mMasks;
270};
271
272/// @brief VolumeTransfer specialization for a single target volume
273/// @todo this specialization should avoid the probe
274template <typename TreeT>
275struct VolumeTransfer<TreeT>
276{
277 using TreeType = TreeT;
278 using ValueType = typename TreeType::ValueType;
279 using NodeMaskT = typename TreeType::LeafNodeType::NodeMaskType;
280
281 static_assert(std::is_base_of<TreeBase, TreeType>::value,
282 "One or more template arguments to VolumeTransfer "
283 "are not a valid openvdb::Tree type.");
284
286 : mTree(tree)
287 , mBuffer(nullptr)
288 , mMask(nullptr) {
290 }
291
294
296 : mTree(other.mTree)
297 , mBuffer(nullptr)
298 , mMask(nullptr) {}
299
300 inline TreeType& topology() { return *mTree; }
301
302 inline void initialize(const Coord& origin, const size_t, const CoordBBox&)
303 {
304 OPENVDB_ASSERT(mTree);
305 if (auto leaf = mTree->probeLeaf(origin)) {
306 mBuffer = leaf->buffer().data();
307 mMask = &(leaf->getValueMask());
308 }
309 else {
310 mBuffer = nullptr;
311 mMask = nullptr;
312 }
313 }
314
315 inline ValueType* buffer() { return mBuffer; }
316 inline const ValueType* buffer() const { return mBuffer; }
317 inline NodeMaskT* mask() { return mMask; }
318 inline const NodeMaskT* mask() const { return mMask; }
319
320 // compatibility with multi tree containers
321 template <size_t> inline ValueType* buffer() { return this->buffer(); }
322 template <size_t> inline const ValueType* buffer() const { return this->buffer(); }
323 template <size_t> inline NodeMaskT* mask() { return this->mask(); }
324 template <size_t> inline const NodeMaskT* mask() const { return this->mask(); }
325
326private:
327 TreeType* const mTree;
328 ValueType* mBuffer;
329 NodeMaskT* mMask;
330};
331
333{
334template<typename T, typename F, size_t... Is>
335void foreach(T&& t, const F& func, std::integer_sequence<size_t, Is...>)
336{
337 auto init = { (func(std::get<Is>(t), Is), 0)... };
338 (void)init;
339}
340
341template<typename T, typename F, size_t... Is>
342void foreach(void** buffers, const F& func, std::integer_sequence<size_t, Is...>)
343{
344 int init[sizeof...(Is)] = {
345 (func(static_cast<typename std::tuple_element<Is, T>::type*>
346 (*(buffers + Is)), Is), 0)...
347 };
348}
349
350template<typename T, template <typename> class R, typename F, size_t... Is>
351void foreach(void** buffers, const F& func, std::integer_sequence<size_t, Is...>)
352{
353 int init[sizeof...(Is)] = {
354 (func(static_cast<typename R<typename std::tuple_element<Is, T>::type>::Type*>
355 (*(buffers + Is)), Is), 0)...
356 };
357}
358}
359
360template <typename ...TreeTypes>
362 : mTreeArray({ trees... })
363 , mBuffers()
364 , mMasks()
365{
366 transfer_internal::foreach(mTreeArray, [](auto&& tree, const size_t) {
367 using TreeT = typename std::remove_pointer<typename std::decay<decltype(tree)>::type>::type;
368 static_assert(std::is_base_of<TreeBase, TreeT>::value,
369 "One or more template arguments to VolumeTransfer "
370 "are not a valid openvdb::Tree type.");
372 }, std::make_integer_sequence<size_t, Size>());
373
374 mBuffers.fill(nullptr);
375 mMasks.fill(nullptr);
376}
377
378template <typename ...TreeTypes>
379inline void VolumeTransfer<TreeTypes...>::initialize(const Coord& origin, const size_t, const CoordBBox&)
380{
382 [&](auto&& tree, const size_t i) {
384 if (auto leaf = tree->probeLeaf(origin)) {
385 mBuffers[i] = static_cast<void*>(leaf->buffer().data());
386 mMasks[i] = &(leaf->getValueMask());
387 }
388 else {
389 mBuffers[i] = nullptr;
390 mMasks[i] = nullptr;
391 }
392 }, std::make_integer_sequence<size_t, Size>());
393}
394
395template <typename ...TreeTypes>
396template <typename FunctorT>
397inline void VolumeTransfer<TreeTypes...>::foreach(const FunctorT& functor)
398{
400 std::make_integer_sequence<size_t, Size>());
401}
402
403namespace transfer_internal
404{
405template <typename TransferT,
406 typename TopologyT,
407 typename PointFilterT = points::NullFilter,
408 typename InterrupterT = util::NullInterrupter>
410{
413
414 static const Index DIM = TopologyT::LeafNodeType::DIM;
415 static const Int32 DIM32 = static_cast<Int32>(DIM);
416 static const Index LOG2DIM = TopologyT::LeafNodeType::LOG2DIM;
417
419 const TransferT& transfer,
420 const PointFilterT& filter = PointFilterT(),
421 InterrupterT* interrupter = nullptr)
422 : mPointAccessor(tree)
423 , mTransfer(transfer)
424 , mFilter(filter)
425 , mInterrupter(interrupter) {}
426
427 void operator()(LeafNodeT& leaf, const size_t idx) const
428 {
429 if (util::wasInterrupted(mInterrupter)) {
430 thread::cancelGroupExecution();
431 return;
432 }
433
434 const Coord& origin = leaf.origin();
435 auto& mask = leaf.getValueMask();
436
437 CoordBBox bounds;
438
439 bool state;
440 if (mask.isConstant(state)) {
441 if (!state) return; // all inactive
442 else bounds = leaf.getNodeBoundingBox();
443 }
444 else {
445 // Use evalActiveBoundingBox over getNodeBoundingBox()
446 // to get a better approximation
447 leaf.evalActiveBoundingBox(bounds);
448 OPENVDB_ASSERT(!bounds.empty());
449 }
450
451 mTransfer.initialize(origin, idx, bounds);
452
453 CoordBBox search = bounds.expandBy(mTransfer.range(origin, idx));
454 this->transform<>(search);
455
456 // start the iteration from a leaf origin
457 const Coord min = (search.min() & ~(DIM-1));
458 const Coord& max = search.max();
459 PointFilterT localFilter(mFilter);
460
461 // loop over overlapping leaf nodes
462 Coord leafOrigin;
463 for (leafOrigin[0] = min[0]; leafOrigin[0] <= max[0]; leafOrigin[0]+=DIM32) {
464 for (leafOrigin[1] = min[1]; leafOrigin[1] <= max[1]; leafOrigin[1]+=DIM32) {
465 for (leafOrigin[2] = min[2]; leafOrigin[2] <= max[2]; leafOrigin[2]+=DIM32) {
466
467 // if no overlap, continue
468 CoordBBox pbox = CoordBBox::createCube(leafOrigin, DIM32);
469 pbox.intersect(search);
470 if (pbox.empty()) continue;
471
472 // if no points, continue
473 const auto* pointLeaf = mPointAccessor.probeConstLeaf(leafOrigin);
474 if (!pointLeaf) continue;
475 if (!mTransfer.startPointLeaf(*pointLeaf)) continue;
476 localFilter.reset(*pointLeaf);
477
478 // loop over point voxels which contribute to this leaf
479 const Coord& pmin(pbox.min());
480 const Coord& pmax(pbox.max());
481 for (Coord ijk = pmin; ijk.x() <= pmax.x(); ++ijk.x()) {
482 const Index i = ((ijk.x() & (DIM-1u)) << 2*LOG2DIM); // unsigned bit shift mult
483 for (ijk.y() = pmin.y(); ijk.y() <= pmax.y(); ++ijk.y()) {
484 const Index ij = i + ((ijk.y() & (DIM-1u)) << LOG2DIM);
485 for (ijk.z() = pmin.z(); ijk.z() <= pmax.z(); ++ijk.z()) {
486 // voxel should be in this points leaf
487 OPENVDB_ASSERT((ijk & ~(DIM-1u)) == leafOrigin);
488 const Index index = ij + /*k*/(ijk.z() & (DIM-1u));
489 const Index end = pointLeaf->getValue(index);
490 Index id = (index == 0) ? 0 : Index(pointLeaf->getValue(index - 1));
491 for (; id < end; ++id) {
492 if (!localFilter.valid(&id)) continue;
493 mTransfer.rasterizePoint(ijk, id, bounds);
494 } //point idx
495 }
496 }
497 } // outer point voxel
498
499 if (!mTransfer.endPointLeaf(*pointLeaf)) {
500 // rescurse if necessary
501 if (!mTransfer.finalize(origin, idx)) {
502 this->operator()(leaf, idx);
503 }
504 return;
505 }
506 }
507 }
508 } // outer leaf node
509
510 // rescurse if necessary
511 if (!mTransfer.finalize(origin, idx)) {
512 this->operator()(leaf, idx);
513 }
514 }
515
516 void operator()(const typename LeafManagerT::LeafRange& range) const
517 {
518 for (auto leaf = range.begin(); leaf; ++leaf) {
519 (*this)(*leaf, leaf.pos());
520 }
521 }
522
523private:
524
525 template <typename EnableT = TransferT>
526 typename std::enable_if<std::is_base_of<TransformTransfer, EnableT>::value>::type
527 transform(CoordBBox& bounds) const
528 {
529 const TransformTransfer* transform =
530 static_cast<TransformTransfer*>(&mTransfer);
531 const BBoxd bbox(bounds.min().asVec3d(), bounds.max().asVec3d());
532 bounds = transform->sourceTransform().worldToIndexCellCentered(
533 transform->targetTransform().indexToWorld(bbox));
534 }
535
536 template <typename EnableT = TransferT>
537 typename std::enable_if<!std::is_base_of<TransformTransfer, EnableT>::value>::type
538 transform(CoordBBox&) const {}
539
540private:
541 const PointDataGrid::ConstAccessor mPointAccessor;
542 mutable TransferT mTransfer;
543 const PointFilterT& mFilter;
544 InterrupterT* mInterrupter;
545};
546
547} // namespace transfer_internal
548
549///////////////////////////////////////////////////
550///////////////////////////////////////////////////
551
552template <typename PointDataTreeOrGridT,
553 typename TransferT,
554 typename FilterT,
555 typename InterrupterT>
556inline void
557rasterize(const PointDataTreeOrGridT& points,
558 TransferT& transfer,
559 const FilterT& filter,
560 InterrupterT* interrupter)
561{
562 using PointTreeT = typename TreeAdapter<PointDataTreeOrGridT>::TreeType;
563 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
564 "Provided points to rasterize is not a derived TreeBase type.");
565
567
568 auto& topology = transfer.topology();
569 using TreeT = typename std::decay<decltype(topology)>::type;
570 tree::LeafManager<TreeT> manager(topology);
572 raster(tree, transfer, filter, interrupter);
573 manager.foreach(raster);
574}
575
576} // namespace points
577} // namespace OPENVDB_VERSION_NAME
578} // namespace openvdb
579
580#endif //OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition Coord.h:316
typename PointDataTree::ConstAccessor ConstAccessor
Definition Grid.h:590
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:359
const Coord & min() const
Definition Coord.h:324
const Coord & max() const
Definition Coord.h:325
CoordBBox expandBy(ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition Coord.h:428
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition Coord.h:447
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Vec3d asVec3d() const
Definition Coord.h:144
Int32 y() const
Definition Coord.h:132
Int32 x() const
Definition Coord.h:131
Int32 z() const
Definition Coord.h:133
Definition Transform.h:40
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Definition Transform.h:111
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition Transform.h:108
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:52
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
LeafType LeafNodeType
Definition LeafManager.h:93
Definition IndexIterator.h:35
Definition PointTransfer.h:333
void foreach(T &&t, const F &func, std::integer_sequence< size_t, Is... >)
Definition PointTransfer.h:335
Definition AttributeArray.h:42
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 > > > PointDataTree
Point index tree configured to match the default VDB configurations.
Definition PointDataGrid.h:190
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer, const FilterT &filter=NullFilter(), InterrupterT *interrupter=nullptr)
Perform potentially complex rasterization from a user defined transfer scheme.
Definition PointTransfer.h:557
Definition PointDataGrid.h:170
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
Index32 Index
Definition Types.h:54
GridTypes::Transform< internal::ToTreeType > TreeTypes
Definition openvdb.h:123
math::BBox< Vec3d > BBoxd
Definition Types.h:84
int32_t Int32
Definition Types.h:56
Definition Exceptions.h:13
static NonConstTreeType & tree(NonConstTreeType &t)
Definition Grid.h:1076
_TreeType TreeType
Definition Grid.h:1061
The TransformTransfer module should be used if the source transform of the input points and the targe...
Definition PointTransfer.h:182
auto transformTargetToSource(const T &value) const
Definition PointTransfer.h:196
const math::Transform & sourceTransform() const
Definition PointTransfer.h:202
const math::Transform & targetTransform() const
Definition PointTransfer.h:203
auto transformSourceToTarget(const T &value) const
Definition PointTransfer.h:189
TransformTransfer(const math::Transform &st, const math::Transform &tt)
Definition PointTransfer.h:183
typename T::ValueType Type
Definition PointTransfer.h:222
const NodeMaskT * mask() const
Definition PointTransfer.h:324
typename TreeType::ValueType ValueType
Definition PointTransfer.h:278
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:302
const ValueType * buffer() const
Definition PointTransfer.h:322
const NodeMaskT * mask() const
Definition PointTransfer.h:318
ValueType * buffer()
Definition PointTransfer.h:321
VolumeTransfer(TreeType &tree)
Definition PointTransfer.h:292
NodeMaskT * mask()
Definition PointTransfer.h:317
VolumeTransfer(TreeType *tree)
Definition PointTransfer.h:285
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:295
const ValueType * buffer() const
Definition PointTransfer.h:316
NodeMaskT * mask()
Definition PointTransfer.h:323
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:279
ValueType * buffer()
Definition PointTransfer.h:315
TreeType & topology()
Definition PointTransfer.h:300
TreeT TreeType
Definition PointTransfer.h:277
const NodeMaskT * mask() const
Definition PointTransfer.h:260
VolumeTransfer(TreeTypes *... trees)
Definition PointTransfer.h:361
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:379
const ValueType< Idx > * buffer() const
Definition PointTransfer.h:250
ValueType< Idx > * buffer()
Definition PointTransfer.h:244
typename std::tuple_element< Idx, std::tuple< TreeTypes... > >::type TreeType
Definition PointTransfer.h:220
TreeType< 0 > & topology()
Definition PointTransfer.h:239
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:223
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:230
std::tuple< TreeTypes *... > TreeTupleT
Definition PointTransfer.h:218
NodeMaskT * mask()
Definition PointTransfer.h:256
void foreach(const FunctorT &functor)
Definition PointTransfer.h:397
NodeMaskT * mask(const size_t idx)
Definition PointTransfer.h:257
const NodeMaskT * mask(const size_t idx) const
Definition PointTransfer.h:261
static const size_t Size
Definition PointTransfer.h:217
VolumeTransfer(TreeTypes &... trees)
Definition PointTransfer.h:227
typename TreeType< Idx >::ValueType ValueType
Definition PointTransfer.h:221
static const Index DIM
Definition PointTransfer.h:414
tree::LeafManager< TopologyT > LeafManagerT
Definition PointTransfer.h:411
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition PointTransfer.h:516
static const Int32 DIM32
Definition PointTransfer.h:415
typename LeafManagerT::LeafNodeType LeafNodeT
Definition PointTransfer.h:412
RasterizePoints(const points::PointDataTree &tree, const TransferT &transfer, const PointFilterT &filter=PointFilterT(), InterrupterT *interrupter=nullptr)
Definition PointTransfer.h:418
static const Index LOG2DIM
Definition PointTransfer.h:416
void operator()(LeafNodeT &leaf, const size_t idx) const
Definition PointTransfer.h:427
Base class for interrupters.
Definition NullInterrupter.h:26
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218