20 #ifndef OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED 21 #define OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED 29 #include <openvdb/thread/Threading.h> 31 #include <type_traits> 47 template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
49 rasterize(
const PointDataTreeOrGridT& points, TransferT& transfer);
203 : mSourceTransform(st)
204 , mTargetTransform(tt) {}
206 template <
typename T>
209 const auto result = mSourceTransform.indexToWorld(value);
210 return mTargetTransform.worldToIndex(result);
213 template <
typename T>
216 const auto result = mTargetTransform.indexToWorld(value);
217 return mSourceTransform.worldToIndex(result);
233 : mInterrupt(interrupt) {}
237 thread::cancelGroupExecution();
248 template <
typename FilterT>
253 , mLocalFilter(nullptr) {}
255 : mFilter(other.mFilter)
256 , mLocalFilter(nullptr) {}
258 inline void initialize(
const Coord&,
const size_t,
const CoordBBox&)
260 mLocalFilter = std::make_unique<FilterT>(mFilter);
265 mLocalFilter->reset(leaf);
271 return mLocalFilter->valid(&
id);
275 const FilterT& mFilter;
278 std::unique_ptr<FilterT> mLocalFilter;
286 inline void initialize(
const Coord&,
const size_t,
const CoordBBox&) {}
295 template <
typename ...TreeTypes>
298 static const size_t Size =
sizeof...(TreeTypes);
301 template <
size_t Idx>
using TreeType =
typename std::tuple_element<Idx, std::tuple<
TreeTypes...>>::type;
312 : mTreeArray(other.mTreeArray)
316 mBuffers.fill(
nullptr);
317 mMasks.fill(
nullptr);
322 inline void initialize(
const Coord& origin,
const size_t,
const CoordBBox&);
324 template <
size_t Idx>
330 template <
size_t Idx>
336 template <
size_t Idx>
340 template <
size_t Idx>
342 inline const NodeMaskT*
mask(
const size_t idx)
const {
return mMasks[idx]; }
344 template <
typename FunctorT>
345 inline void foreach(
const FunctorT& functor);
348 const TreeTupleT mTreeArray;
349 std::array<void*, Size> mBuffers;
350 std::array<NodeMaskT*, Size> mMasks;
355 template <
typename TreeT>
360 using NodeMaskT =
typename TreeType::LeafNodeType::NodeMaskType;
362 static_assert(std::is_base_of<TreeBase, TreeType>::value,
363 "One or more template arguments to VolumeTransfer " 364 "are not a valid openvdb::Tree type.");
383 inline void initialize(
const Coord& origin,
const size_t,
const CoordBBox&)
386 if (
auto leaf = mTree->probeLeaf(origin)) {
387 mBuffer = leaf->buffer().data();
388 mMask = &(leaf->getValueMask());
413 namespace transfer_internal
415 template<
typename T,
typename F,
size_t... Is>
416 void foreach(T&& t,
const F& func, std::integer_sequence<size_t, Is...>)
418 auto init = { (func(std::get<Is>(t), Is), 0)... };
422 template<
typename T,
typename F,
size_t... Is>
423 void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
425 int init[
sizeof...(Is)] = {
426 (func(
static_cast<typename std::tuple_element<Is, T>::type*
> 427 (*(buffers + Is)), Is), 0)...
431 template<
typename T,
template <
typename>
class R,
typename F,
size_t... Is>
432 void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
434 int init[
sizeof...(Is)] = {
435 (func(
static_cast<typename R<typename std::tuple_element<Is, T>::type
>::Type*>
436 (*(buffers + Is)), Is), 0)...
441 template <
typename ...TreeTypes>
443 : mTreeArray({ trees... })
448 using TreeT =
typename std::remove_pointer<typename std::decay<decltype(tree)>::type>::type;
449 static_assert(std::is_base_of<TreeBase, TreeT>::value,
450 "One or more template arguments to VolumeTransfer " 451 "are not a valid openvdb::Tree type.");
453 }, std::make_integer_sequence<size_t, Size>());
455 mBuffers.fill(
nullptr);
456 mMasks.fill(
nullptr);
459 template <
typename ...TreeTypes>
463 [&](
auto&& tree,
const size_t i) {
465 if (
auto leaf = tree->probeLeaf(origin)) {
466 mBuffers[i] =
static_cast<void*
>(leaf->buffer().data());
467 mMasks[i] = &(leaf->getValueMask());
470 mBuffers[i] =
nullptr;
473 }, std::make_integer_sequence<size_t, Size>());
476 template <
typename ...TreeTypes>
477 template <
typename FunctorT>
480 transfer_internal::foreach<TreeTupleT, TypeResolver>(mBuffers.data(), functor,
481 std::make_integer_sequence<size_t, Size>());
484 namespace transfer_internal
490 template <
typename TransferT,
502 static const Index DIM = TopologyT::LeafNodeType::DIM;
504 static const Index LOG2DIM = TopologyT::LeafNodeType::LOG2DIM;
505 static constexpr
bool UseRasterizePoints =
507 static constexpr
bool UseRasterizePoint =
511 const TransferT& transfer,
512 const CoordBBox& pointBounds,
513 const PointFilterT& filter = PointFilterT(),
514 InterrupterT* interrupter =
nullptr)
515 : mPointAccessor(tree)
516 , mTransfer(transfer)
517 , mPointBounds(pointBounds)
519 , mInterrupter(interrupter) {}
523 if (this->interrupted())
return;
525 const Coord& origin = leaf.origin();
526 auto&
mask = leaf.getValueMask();
531 if (
mask.isConstant(state)) {
533 else bounds = leaf.getNodeBoundingBox();
538 leaf.evalActiveBoundingBox(bounds);
542 mTransfer.initialize(origin, idx, bounds);
544 CoordBBox search = bounds;
545 const Vec3i range(mTransfer.range(origin, idx));
546 search.min() -= Coord(range);
547 search.max() += Coord(range);
548 this->transform<>(search);
549 search.intersect(mPointBounds);
552 const Coord
min = (search.min() & ~(DIM-1));
553 const Coord&
max = search.max();
558 PointFilterT localFilter(mFilter);
562 for (leafOrigin[0] = min[0]; leafOrigin[0] <= max[0]; leafOrigin[0]+=DIM32) {
563 for (leafOrigin[1] = min[1]; leafOrigin[1] <= max[1]; leafOrigin[1]+=DIM32) {
564 for (leafOrigin[2] = min[2]; leafOrigin[2] <= max[2]; leafOrigin[2]+=DIM32) {
567 CoordBBox pbox = CoordBBox::createCube(leafOrigin, DIM32);
568 pbox.intersect(search);
569 if (pbox.empty())
continue;
572 const auto* pointLeaf = mPointAccessor.probeConstLeaf(leafOrigin);
573 if (!pointLeaf)
continue;
574 if (!mTransfer.startPointLeaf(*pointLeaf))
continue;
575 localFilter.reset(*pointLeaf);
577 if (this->interrupted())
return;
585 const auto valiter = pointLeaf->cbeginValueAll();
588 const Coord& pmin(pbox.min());
589 const Coord& pmax(pbox.max());
590 for (Coord ijk = pmin; ijk.x() <= pmax.x(); ++ijk.x()) {
591 const Index i = ((ijk.x() & (DIM-1u)) << 2*LOG2DIM);
592 for (ijk.y() = pmin.y(); ijk.y() <= pmax.y(); ++ijk.y()) {
593 const Index ij = i + ((ijk.y() & (DIM-1u)) << LOG2DIM);
594 for (ijk.z() = pmin.z(); ijk.z() <= pmax.z(); ++ijk.z()) {
597 const Index index = ij + (ijk.z() & (DIM-1u));
598 const Index end = valiter.getItem(index);
599 Index id = (index == 0) ? 0 :
Index(valiter.getItem(index - 1));
600 if (this->interrupted())
return;
602 if constexpr (UseRasterizePoints)
605 mTransfer.rasterizePoints(ijk,
id, end, bounds);
607 else if constexpr (UseRasterizePoint)
609 for (;
id < end; ++id) {
610 if (!localFilter.valid(&
id))
continue;
611 mTransfer.rasterizePoint(ijk,
id, bounds);
615 static_assert(UseRasterizePoints || UseRasterizePoint,
616 "Invalid transfer scheme in openvdb::tools::rasterize. Must correctly Implement rasterizePoints or rasterizePoint.");
622 if (!mTransfer.endPointLeaf(*pointLeaf)) {
624 if (!mTransfer.finalize(origin, idx)) {
625 this->operator()(leaf, idx);
634 if (!mTransfer.finalize(origin, idx)) {
635 this->operator()(leaf, idx);
641 for (
auto leaf = range.
begin(); leaf; ++leaf) {
642 (*this)(*leaf, leaf.pos());
648 template <
typename EnableT = TransferT>
649 typename std::enable_if<std::is_base_of<TransformTransfer, EnableT>::value>::type
650 transform(CoordBBox& bounds)
const 654 const BBoxd bbox(bounds.min().asVec3d(), bounds.max().asVec3d());
659 template <
typename EnableT = TransferT>
660 typename std::enable_if<!std::is_base_of<TransformTransfer, EnableT>::value>::type
661 transform(CoordBBox&)
const {}
663 template <
typename EnableT = TransferT>
664 typename std::enable_if<std::is_base_of<InterruptableTransfer, EnableT>::value,
bool>::type
667 return mTransfer.interrupted();
670 template <
typename EnableT = TransferT>
671 constexpr
typename std::enable_if<!std::is_base_of<InterruptableTransfer, EnableT>::value,
bool>::type
675 if constexpr (std::is_same<InterrupterT, util::NullInterrupter>::value)
return false;
678 thread::cancelGroupExecution();
687 mutable TransferT mTransfer;
688 const CoordBBox& mPointBounds;
689 const PointFilterT& mFilter;
690 InterrupterT* mInterrupter;
698 template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
700 rasterize(
const PointDataTreeOrGridT& points, TransferT& transfer)
703 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
704 "Provided points to rasterize is not a derived TreeBase type.");
707 auto&
topology = transfer.topology();
708 using TreeT =
typename std::decay<decltype(topology)>::type;
712 tree.evalLeafBoundingBox(bounds);
729 template <
typename PointDataTreeOrGridT,
734 "interrupter. Implement this on your transfer scheme (see PointTransfer.h for an example).")
738 const FilterT& filter,
739 InterrupterT* interrupter =
nullptr)
742 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
743 "Provided points to rasterize is not a derived TreeBase type.");
747 auto&
topology = transfer.topology();
748 using TreeT =
typename std::decay<decltype(topology)>::type;
752 tree.evalLeafBoundingBox(bounds);
756 raster(tree, transfer, bounds, filter, interrupter);
764 #endif //OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer, const FilterT &filter, InterrupterT *interrupter=nullptr)
Perform potentially complex rasterization from a user defined transfer scheme.
Definition: PointTransfer.h:736
FilteredTransfer module, when derived from allows for schemes to apply point filtering. Note that this module handles the thread safe intialization and storage of the filter, but derived schemes must call FilteredTransfer::filter() per point id and handle the result.
Definition: PointTransfer.h:249
const NodeMaskT * mask() const
Definition: PointTransfer.h:399
The VolumeTransfer module provides methods to automatically setup and access destination buffers for ...
Definition: PointTransfer.h:296
int32_t Int32
Definition: Types.h:56
Iterator begin() const
Definition: LeafManager.h:156
Definition: LeafManager.h:102
const NodeMaskT * mask(const size_t idx) const
Definition: PointTransfer.h:342
typename std::tuple_element< Idx, std::tuple< TreeTypes... >>::type TreeType
Definition: PointTransfer.h:301
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
void foreach(const FunctorT &functor)
Definition: PointTransfer.h:478
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
Definition: PointTransfer.h:360
VolumeTransfer(TreeType &tree)
Definition: PointTransfer.h:373
typename TreeType< Idx >::ValueType ValueType
Definition: PointTransfer.h:302
ValueType * buffer()
Definition: PointTransfer.h:402
const ValueType< Idx > * buffer() const
Definition: PointTransfer.h:331
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:203
bool startPointLeaf(const PointDataTree::LeafNodeType &)
Definition: PointTransfer.h:287
void foreach(T &&t, const F &func, std::integer_sequence< size_t, Is... >)
Definition: PointTransfer.h:416
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointTransfer.h:639
FilteredTransfer(const FilterT &filter)
Definition: PointTransfer.h:251
VolumeTransfer(TreeType *tree)
Definition: PointTransfer.h:366
bool interrupted() const
Definition: PointTransfer.h:234
const ValueType * buffer() const
Definition: PointTransfer.h:397
typename LeafManagerT::LeafNodeType LeafNodeT
Definition: PointTransfer.h:497
Index32 Index
Definition: Types.h:54
Definition: PointTransfer.h:303
NodeMaskT * mask()
Definition: PointTransfer.h:398
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition: PointTransfer.h:460
ValueType * buffer()
Definition: PointTransfer.h:396
TreeT TreeType
Definition: PointTransfer.h:358
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:51
Vec3< int32_t > Vec3i
Definition: Vec3.h:662
Base class for interrupters.
Definition: NullInterrupter.h:25
typename TreeType::ValueType ValueType
Definition: PointTransfer.h:359
GridTypes::Transform< internal::ToTreeType > TreeTypes
Definition: openvdb.h:123
const NodeMaskT * mask() const
Definition: PointTransfer.h:405
InterruptableTransfer(util::NullInterrupter *const interrupt)
Definition: PointTransfer.h:232
void(const Coord &, const Index, const CoordBBox &) RasterizePointSignature
Definition: PointTransfer.h:499
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
VolumeTransfer(const VolumeTransfer &other)
Definition: PointTransfer.h:376
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
const ValueType * buffer() const
Definition: PointTransfer.h:403
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer)
Perform potentially complex rasterization from a user defined transfer scheme. See below comments for...
Definition: PointTransfer.h:700
void initialize(const Coord &, const size_t, const CoordBBox &)
Definition: PointTransfer.h:258
#define OPENVDB_INIT_INVOKABLE_MEMBER_FUNCTION(F)
Macros to help determine whether or not a class has a particular member function. ...
Definition: Types.h:225
bool startPointLeaf(const PointDataTree::LeafNodeType &leaf)
Definition: PointTransfer.h:263
Definition: Exceptions.h:13
RasterizePoints(const points::PointDataTree &tree, const TransferT &transfer, const CoordBBox &pointBounds, const PointFilterT &filter=PointFilterT(), InterrupterT *interrupter=nullptr)
Definition: PointTransfer.h:510
Definition: PointTransfer.h:494
void(const Coord &, const Index, const Index, const CoordBBox &) RasterizePointsSignature
Definition: PointTransfer.h:500
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition: PointTransfer.h:383
LeafType LeafNodeType
Definition: LeafManager.h:93
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
Definition: PointTransfer.h:304
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
VolumeTransfer(const VolumeTransfer &other)
Definition: PointTransfer.h:311
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
FilteredTransfer(const NullFilter &)
Definition: PointTransfer.h:285
NodeMaskT * mask(const size_t idx)
Definition: PointTransfer.h:338
NodeMaskT * mask()
Definition: PointTransfer.h:337
typename T::ValueType Type
Definition: PointTransfer.h:303
static NonConstTreeType & tree(NonConstTreeType &t)
Definition: Grid.h:1076
bool filter(const Index) const
Definition: PointTransfer.h:288
InterruptableTransfer module, when derived from allows for schemes to callback into a interrupter...
Definition: PointTransfer.h:230
ValueType< Idx > * buffer()
Definition: PointTransfer.h:325
typename _TreeType::ConstAccessor ConstAccessor
Definition: Grid.h:590
VolumeTransfer(TreeTypes &...trees)
Definition: PointTransfer.h:308
void operator()(LeafNodeT &leaf, const size_t idx) const
Definition: PointTransfer.h:521
TreeType< 0 > & topology()
Definition: PointTransfer.h:320
TreeType & topology()
Definition: PointTransfer.h:381
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
FilteredTransfer(const FilteredTransfer &other)
Definition: PointTransfer.h:254
bool filter(const Index id) const
Definition: PointTransfer.h:269
#define OPENVDB_HAS_INVOKABLE_MEMBER_FUNCTION(T, F,...)
Definition: Types.h:239
const NodeMaskT * mask() const
Definition: PointTransfer.h:341
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
void initialize(const Coord &, const size_t, const CoordBBox &)
Definition: PointTransfer.h:286
_TreeType TreeType
Definition: Grid.h:1061
NodeMaskT * mask()
Definition: PointTransfer.h:404