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