20#ifndef OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
21#define OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
47template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
49rasterize(
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) {}
248template <
typename FilterT>
253 , mLocalFilter(nullptr) {}
255 : mFilter(other.mFilter)
256 , mLocalFilter(nullptr) {}
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;
295template <
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);
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);
349 std::array<void*, Size> mBuffers;
350 std::array<NodeMaskT*, Size> mMasks;
355template <
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.");
386 if (
auto leaf = mTree->probeLeaf(origin)) {
387 mBuffer = leaf->buffer().data();
388 mMask = &(leaf->getValueMask());
408 TreeType*
const mTree;
415namespace transfer_internal
417template<
typename T,
typename F,
size_t... Is>
418void foreach(T&& t,
const F& func, std::integer_sequence<size_t, Is...>)
420 auto init = { (func(std::get<Is>(t), Is), 0)... };
424template<
typename T,
typename F,
size_t... Is>
425void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
427 int init[
sizeof...(Is)] = {
428 (func(
static_cast<typename std::tuple_element<Is, T>::type*
>
429 (*(buffers + Is)), Is), 0)...
433template<
typename T,
template <
typename>
class R,
typename F,
size_t... Is>
434void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
436 int init[
sizeof...(Is)] = {
437 (func(
static_cast<typename R<typename std::tuple_element<Is, T>::type
>::Type*>
438 (*(buffers + Is)), Is), 0)...
445template <
typename ...TreeTypes>
447 : mTreeArray({ trees... })
451 transfer_internal::foreach(mTreeArray, [](
auto&&
tree,
const size_t) {
452 using TreeT =
typename std::remove_pointer<
typename std::decay<
decltype(
tree)>::type>::type;
453 static_assert(std::is_base_of<TreeBase, TreeT>::value,
454 "One or more template arguments to VolumeTransfer "
455 "are not a valid openvdb::Tree type.");
457 }, std::make_integer_sequence<size_t, Size>());
459 mBuffers.fill(
nullptr);
460 mMasks.fill(
nullptr);
463template <
typename ...TreeTypes>
466 transfer_internal::foreach(mTreeArray,
467 [&](
auto&&
tree,
const size_t i) {
469 if (
auto leaf =
tree->probeLeaf(origin)) {
470 mBuffers[i] =
static_cast<void*
>(leaf->buffer().data());
471 mMasks[i] = &(leaf->getValueMask());
474 mBuffers[i] =
nullptr;
477 }, std::make_integer_sequence<size_t, Size>());
480template <
typename ...TreeTypes>
481template <
typename FunctorT>
484 transfer_internal::foreach<TreeTupleT, TypeResolver>(mBuffers.data(), functor,
485 std::make_integer_sequence<size_t, Size>());
490namespace transfer_internal
496template <
typename TransferT,
500struct RasterizePoints
503 using LeafNodeT =
typename LeafManagerT::LeafNodeType;
508 static const Index DIM = TopologyT::LeafNodeType::DIM;
509 static const Int32 DIM32 =
static_cast<Int32>(DIM);
510 static const Index LOG2DIM = TopologyT::LeafNodeType::LOG2DIM;
511 static constexpr bool UseRasterizePoints =
513 static constexpr bool UseRasterizePoint =
517 const TransferT& transfer,
519 const PointFilterT& filter = PointFilterT(),
520 InterrupterT* interrupter =
nullptr)
521 : mPointAccessor(
tree)
522 , mTransfer(transfer)
523 , mPointBounds(pointBounds)
525 , mInterrupter(interrupter) {}
527 void operator()(LeafNodeT& leaf,
const size_t idx)
const
529 if (this->interrupted())
return;
531 const Coord& origin = leaf.origin();
532 auto& mask = leaf.getValueMask();
537 if (mask.isConstant(state)) {
539 else bounds = leaf.getNodeBoundingBox();
544 leaf.evalActiveBoundingBox(bounds);
548 mTransfer.initialize(origin, idx, bounds);
550 CoordBBox search = bounds;
551 const Vec3i range(mTransfer.range(origin, idx));
552 search.min() -= Coord(range);
553 search.max() += Coord(range);
554 this->transform<>(search);
555 search.intersect(mPointBounds);
558 const Coord min = (search.min() & ~(DIM-1));
559 const Coord& max = search.max();
564 PointFilterT localFilter(mFilter);
568 for (leafOrigin[0] = min[0]; leafOrigin[0] <= max[0]; leafOrigin[0]+=DIM32) {
569 for (leafOrigin[1] = min[1]; leafOrigin[1] <= max[1]; leafOrigin[1]+=DIM32) {
570 for (leafOrigin[2] = min[2]; leafOrigin[2] <= max[2]; leafOrigin[2]+=DIM32) {
573 CoordBBox pbox = CoordBBox::createCube(leafOrigin, DIM32);
574 pbox.intersect(search);
575 if (pbox.empty())
continue;
578 const auto* pointLeaf = mPointAccessor.probeConstLeaf(leafOrigin);
579 if (!pointLeaf)
continue;
580 if (!mTransfer.startPointLeaf(*pointLeaf))
continue;
581 localFilter.reset(*pointLeaf);
583 if (this->interrupted())
return;
591 const auto valiter = pointLeaf->cbeginValueAll();
594 const Coord& pmin(pbox.min());
595 const Coord& pmax(pbox.max());
596 for (Coord ijk = pmin; ijk.x() <= pmax.x(); ++ijk.x()) {
597 const Index i = ((ijk.x() & (DIM-1u)) << 2*LOG2DIM);
598 for (ijk.y() = pmin.y(); ijk.y() <= pmax.y(); ++ijk.y()) {
599 const Index ij = i + ((ijk.y() & (DIM-1u)) << LOG2DIM);
600 for (ijk.z() = pmin.z(); ijk.z() <= pmax.z(); ++ijk.z()) {
603 const Index index = ij + (ijk.z() & (DIM-1u));
604 const Index end = valiter.getItem(index);
605 Index
id = (index == 0) ? 0 : Index(valiter.getItem(index - 1));
606 if (this->interrupted())
return;
608 if constexpr (UseRasterizePoints)
611 mTransfer.rasterizePoints(ijk,
id, end, bounds);
613 else if constexpr (UseRasterizePoint)
615 for (;
id < end; ++id) {
616 if (!localFilter.valid(&
id))
continue;
617 mTransfer.rasterizePoint(ijk,
id, bounds);
621 static_assert(UseRasterizePoints || UseRasterizePoint,
622 "Invalid transfer scheme in openvdb::tools::rasterize. Must correctly Implement rasterizePoints or rasterizePoint.");
628 if (!mTransfer.endPointLeaf(*pointLeaf)) {
630 if (!mTransfer.finalize(origin, idx)) {
631 this->operator()(leaf, idx);
640 if (!mTransfer.finalize(origin, idx)) {
641 this->operator()(leaf, idx);
645 void operator()(
const typename LeafManagerT::LeafRange& range)
const
647 for (
auto leaf = range.begin(); leaf; ++leaf) {
648 (*this)(*leaf, leaf.pos());
654 template <
typename EnableT = TransferT>
655 typename std::enable_if<std::is_base_of<TransformTransfer, EnableT>::value>::type
656 transform(CoordBBox& bounds)
const
658 const TransformTransfer* transform =
659 static_cast<TransformTransfer*
>(&mTransfer);
660 const BBoxd bbox(bounds.min().asVec3d(), bounds.max().asVec3d());
661 bounds = transform->sourceTransform().worldToIndexCellCentered(
662 transform->targetTransform().indexToWorld(bbox));
665 template <
typename EnableT = TransferT>
666 typename std::enable_if<!std::is_base_of<TransformTransfer, EnableT>::value>::type
667 transform(CoordBBox&)
const {}
669 template <
typename EnableT = TransferT>
670 typename std::enable_if<std::is_base_of<InterruptableTransfer, EnableT>::value,
bool>::type
673 return mTransfer.interrupted();
676 template <
typename EnableT = TransferT>
677 constexpr typename std::enable_if<!std::is_base_of<InterruptableTransfer, EnableT>::value,
bool>::type
681 if constexpr (std::is_same<InterrupterT, util::NullInterrupter>::value)
return false;
683 if (util::wasInterrupted(mInterrupter)) {
684 thread::cancelGroupExecution();
692 const PointDataGrid::ConstAccessor mPointAccessor;
693 mutable TransferT mTransfer;
694 const CoordBBox& mPointBounds;
695 const PointFilterT& mFilter;
696 InterrupterT* mInterrupter;
706template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
711 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
712 "Provided points to rasterize is not a derived TreeBase type.");
715 auto& topology = transfer.topology();
716 using TreeT =
typename std::decay<
decltype(topology)>::type;
720 tree.evalLeafBoundingBox(bounds);
723 transfer_internal::RasterizePoints<TransferT, TreeT> raster(
tree, transfer, bounds);
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
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
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
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
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
typename RootNodeType::LeafNodeType LeafNodeType
Definition Tree.h:203
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)
Perform potentially complex rasterization from a user defined transfer scheme. See below comments for...
Definition PointTransfer.h:708
vptr bool cancelGroupExecution()
Definition Threading.h:33
Definition PointDataGrid.h:170
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
Index32 Index
Definition Types.h:34
GridTypes::Transform< internal::ToTreeType > TreeTypes
Definition openvdb.h:127
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types....
math::BBox< Vec3d > BBoxd
Definition Types.h:65
int32_t Int32
Definition Types.h:36
Definition Exceptions.h:13
#define OPENVDB_HAS_INVOKABLE_MEMBER_FUNCTION(T, F,...)
Definition Types.h:220
#define OPENVDB_INIT_INVOKABLE_MEMBER_FUNCTION(F)
Macros to help determine whether or not a class has a particular member function.
Definition Types.h:206
static NonConstTreeType & tree(NonConstTreeType &t)
Definition Grid.h:1072
_TreeType TreeType
Definition Grid.h:1057
bool filter(const Index) const
Definition PointTransfer.h:288
FilteredTransfer(const NullFilter &)
Definition PointTransfer.h:285
void initialize(const Coord &, const size_t, const CoordBBox &)
Definition PointTransfer.h:286
bool startPointLeaf(const PointDataTree::LeafNodeType &)
Definition PointTransfer.h:287
bool filter(const Index id) const
Definition PointTransfer.h:269
bool startPointLeaf(const PointDataTree::LeafNodeType &leaf)
Definition PointTransfer.h:263
FilteredTransfer(const FilterT &filter)
Definition PointTransfer.h:251
void initialize(const Coord &, const size_t, const CoordBBox &)
Definition PointTransfer.h:258
FilteredTransfer(const FilteredTransfer &other)
Definition PointTransfer.h:254
bool interrupted() const
Definition PointTransfer.h:234
InterruptableTransfer(util::NullInterrupter *const interrupt)
Definition PointTransfer.h:232
Definition PointTransfer.h:303
typename T::ValueType Type
Definition PointTransfer.h:303
const NodeMaskT * mask() const
Definition PointTransfer.h:405
typename TreeType::ValueType ValueType
Definition PointTransfer.h:359
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:383
const ValueType * buffer() const
Definition PointTransfer.h:403
const NodeMaskT * mask() const
Definition PointTransfer.h:399
ValueType * buffer()
Definition PointTransfer.h:402
VolumeTransfer(TreeType &tree)
Definition PointTransfer.h:373
NodeMaskT * mask()
Definition PointTransfer.h:398
VolumeTransfer(TreeType *tree)
Definition PointTransfer.h:366
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:376
const ValueType * buffer() const
Definition PointTransfer.h:397
NodeMaskT * mask()
Definition PointTransfer.h:404
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:360
ValueType * buffer()
Definition PointTransfer.h:396
TreeType & topology()
Definition PointTransfer.h:381
TreeT TreeType
Definition PointTransfer.h:358
const NodeMaskT * mask() const
Definition PointTransfer.h:341
VolumeTransfer(TreeTypes *... trees)
Definition PointTransfer.h:446
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:464
const ValueType< Idx > * buffer() const
Definition PointTransfer.h:331
ValueType< Idx > * buffer()
Definition PointTransfer.h:325
typename std::tuple_element< Idx, std::tuple< TreeTypes... > >::type TreeType
Definition PointTransfer.h:301
TreeType< 0 > & topology()
Definition PointTransfer.h:320
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:304
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:311
std::tuple< TreeTypes *... > TreeTupleT
Definition PointTransfer.h:299
NodeMaskT * mask()
Definition PointTransfer.h:337
void foreach(const FunctorT &functor)
Definition PointTransfer.h:482
NodeMaskT * mask(const size_t idx)
Definition PointTransfer.h:338
const NodeMaskT * mask(const size_t idx) const
Definition PointTransfer.h:342
static const size_t Size
Definition PointTransfer.h:298
VolumeTransfer(TreeTypes &... trees)
Definition PointTransfer.h:308
typename TreeType< Idx >::ValueType ValueType
Definition PointTransfer.h:302
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