OpenVDB  12.0.0
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>
26 #include <openvdb/math/Transform.h>
28 #include <openvdb/util/Assert.h>
29 #include <openvdb/thread/Threading.h>
30 
31 #include <type_traits>
32 #include <tuple>
33 
34 namespace openvdb {
36 namespace OPENVDB_VERSION_NAME {
37 namespace 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
164 template <typename PointDataTreeOrGridT,
165  typename TransferT,
166  typename FilterT = NullFilter,
167  typename InterrupterT = util::NullInterrupter>
168 inline void
169 rasterize(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 
205 private:
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.
214 template <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 
225  VolumeTransfer(TreeTypes*... trees);
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 
266 private:
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
274 template <typename TreeT>
275 struct 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) {
289  OPENVDB_ASSERT(tree);
290  }
291 
293  : VolumeTransfer(&tree) {}
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 
326 private:
327  TreeType* const mTree;
328  ValueType* mBuffer;
329  NodeMaskT* mMask;
330 };
331 
332 namespace transfer_internal
333 {
334 template<typename T, typename F, size_t... Is>
335 void 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 
341 template<typename T, typename F, size_t... Is>
342 void 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 
350 template<typename T, template <typename> class R, typename F, size_t... Is>
351 void 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 
360 template <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.");
371  OPENVDB_ASSERT(tree);
372  }, std::make_integer_sequence<size_t, Size>());
373 
374  mBuffers.fill(nullptr);
375  mMasks.fill(nullptr);
376 }
377 
378 template <typename ...TreeTypes>
379 inline void VolumeTransfer<TreeTypes...>::initialize(const Coord& origin, const size_t, const CoordBBox&)
380 {
381  transfer_internal::foreach(mTreeArray,
382  [&](auto&& tree, const size_t i) {
383  OPENVDB_ASSERT(tree);
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 
395 template <typename ...TreeTypes>
396 template <typename FunctorT>
397 inline void VolumeTransfer<TreeTypes...>::foreach(const FunctorT& functor)
398 {
399  transfer_internal::foreach<TreeTupleT, TypeResolver>(mBuffers.data(), functor,
400  std::make_integer_sequence<size_t, Size>());
401 }
402 
403 namespace transfer_internal
404 {
405 template <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 
523 private:
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 
540 private:
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 
552 template <typename PointDataTreeOrGridT,
553  typename TransferT,
554  typename FilterT,
555  typename InterrupterT>
556 inline void
557 rasterize(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 
566  const auto& tree = TreeAdapter<PointDataTreeOrGridT>::tree(points);
567 
568  auto& topology = transfer.topology();
569  using TreeT = typename std::decay<decltype(topology)>::type;
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
Definition: Tree.h:194
VolumeTransfer(TreeTypes &...trees)
Definition: PointTransfer.h:227
VolumeTransfer(const VolumeTransfer &other)
Definition: PointTransfer.h:230
NodeMaskT * mask()
Definition: PointTransfer.h:256
typename TreeType< Idx >::ValueType ValueType
Definition: PointTransfer.h:221
const ValueType * buffer() const
Definition: PointTransfer.h:316
const math::Transform & sourceTransform() const
Definition: PointTransfer.h:202
Iterator begin() const
Definition: LeafManager.h:156
auto transformTargetToSource(const T &value) const
Definition: PointTransfer.h:196
NodeMaskT * mask(const size_t idx)
Definition: PointTransfer.h:257
GridTypes::Transform< internal::ToTreeType > TreeTypes
Definition: openvdb.h:123
VolumeTransfer(TreeType &tree)
Definition: PointTransfer.h:292
void operator()(LeafNodeT &leaf, const size_t idx) const
Definition: PointTransfer.h:427
NodeMaskT * mask()
Definition: PointTransfer.h:323
const ValueType * buffer() const
Definition: PointTransfer.h:322
typename T::ValueType Type
Definition: PointTransfer.h:222
RasterizePoints(const points::PointDataTree &tree, const TransferT &transfer, const PointFilterT &filter=PointFilterT(), InterrupterT *interrupter=nullptr)
Definition: PointTransfer.h:418
const NodeMaskT * mask() const
Definition: PointTransfer.h:318
int32_t Int32
Definition: Types.h:56
Index32 Index
Definition: Types.h:54
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:110
Base class for interrupters.
Definition: NullInterrupter.h:25
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
std::tuple< TreeTypes *... > TreeTupleT
Definition: PointTransfer.h:218
typename std::tuple_element< Idx, std::tuple< TreeTypes... >>::type TreeType
Definition: PointTransfer.h:220
_TreeType TreeType
Definition: Grid.h:1061
static NonConstTreeType & tree(NonConstTreeType &t)
Definition: Grid.h:1076
const math::Transform & targetTransform() const
Definition: PointTransfer.h:203
const ValueType< Idx > * buffer() const
Definition: PointTransfer.h:250
const NodeMaskT * mask() const
Definition: PointTransfer.h:324
typename TreeType::ValueType ValueType
Definition: PointTransfer.h:278
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition: PointTransfer.h:379
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointTransfer.h:516
NodeMaskT * mask()
Definition: PointTransfer.h:317
void foreach(T &&t, const F &func, std::integer_sequence< size_t, Is... >)
Definition: PointTransfer.h:335
Vec3d indexToWorld(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:108
Definition: Exceptions.h:13
const NodeMaskT * mask(const size_t idx) const
Definition: PointTransfer.h:261
VolumeTransfer(TreeType *tree)
Definition: PointTransfer.h:285
LeafType LeafNodeType
Definition: LeafManager.h:93
TreeType< 0 > & topology()
Definition: PointTransfer.h:239
The VolumeTransfer module provides methods to automatically setup and access destination buffers for ...
Definition: PointTransfer.h:215
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
Definition: PointTransfer.h:223
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:111
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
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
Definition: PointTransfer.h:279
TreeType & topology()
Definition: PointTransfer.h:300
ValueType * buffer()
Definition: PointTransfer.h:321
const NodeMaskT * mask() const
Definition: PointTransfer.h:260
auto transformSourceToTarget(const T &value) const
Definition: PointTransfer.h:189
TransformTransfer(const math::Transform &st, const math::Transform &tt)
Definition: PointTransfer.h:183
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition: PointTransfer.h:302
void foreach(const FunctorT &functor)
Definition: PointTransfer.h:397
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:484
Definition: Transform.h:39
TreeT TreeType
Definition: PointTransfer.h:277
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
ValueType * buffer()
Definition: PointTransfer.h:315
typename _TreeType::ConstAccessor ConstAccessor
Definition: Grid.h:590
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:106
VolumeTransfer(const VolumeTransfer &other)
Definition: PointTransfer.h:295
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
typename LeafManagerT::LeafNodeType LeafNodeT
Definition: PointTransfer.h:412
The TransformTransfer module should be used if the source transform of the input points and the targe...
Definition: PointTransfer.h:181
ValueType< Idx > * buffer()
Definition: PointTransfer.h:244
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:51