20 #ifndef OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
21 #define OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
31 #include <type_traits>
47 template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
203 : mSourceTransform(st)
204 , mTargetTransform(tt) {}
206 template <
typename T>
213 template <
typename T>
233 : mInterrupt(interrupt) {}
237 thread::cancelGroupExecution();
248 template <
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;
295 template <
typename ...TreeTypes>
298 static const size_t Size =
sizeof...(TreeTypes);
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;
355 template <
typename TreeT>
360 using NodeMaskT =
typename TreeType::LeafNodeType::NodeMaskType;
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());
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)] = {
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)] = {
436 (*(buffers + Is)), Is), 0)...
441 template <
typename ...TreeTypes>
443 : mTreeArray({ trees... })
450 "One or more template arguments to VolumeTransfer "
451 "are not a valid openvdb::Tree type.");
453 }, std::make_integer_sequence<size_t, Size>());
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());
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,
493 typename InterrupterT = util::NullInterrupter>
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,
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);
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>
654 const BBoxd bbox(bounds.min().asVec3d(), bounds.max().asVec3d());
659 template <
typename EnableT = TransferT>
663 template <
typename EnableT = TransferT>
667 return mTransfer.interrupted();
670 template <
typename EnableT = TransferT>
678 thread::cancelGroupExecution();
686 const PointDataGrid::ConstAccessor mPointAccessor;
687 mutable TransferT mTransfer;
689 const PointFilterT& mFilter;
690 InterrupterT* mInterrupter;
698 template <
typename Po
intDataTreeOrGr
idT,
typename TransferT>
704 "Provided points to rasterize is not a derived TreeBase type.");
707 auto&
topology = transfer.topology();
712 tree.evalLeafBoundingBox(bounds);
724 #endif //OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer)
Perform potentially complex rasterization from a user defined transfer scheme. See below comments for...
VolumeTransfer(const VolumeTransfer &other)
const NodeMaskT * mask(const size_t idx) const
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
VolumeTransfer(const VolumeTransfer &other)
GLdouble GLdouble GLint GLint const GLdouble * points
FilteredTransfer(const FilterT &filter)
bool filter(const Index id) const
bool startPointLeaf(const PointDataTree::LeafNodeType &leaf)
typename T::ValueType Type
typename LeafManagerT::LeafNodeType LeafNodeT
GLsizei const GLfloat * value
const ValueType * buffer() const
void(const Coord &, const Index, const CoordBBox &) RasterizePointSignature
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
void foreach(const FunctorT &functor)
#define OPENVDB_USE_VERSION_NAMESPACE
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
InterruptableTransfer(util::NullInterrupter *const interrupt)
**But if you need a result
A no-op filter that can be used when iterating over all indices.
Base class for interrupters.
NodeMaskT * mask(const size_t idx)
#define OPENVDB_ASSERT(X)
FilteredTransfer(const FilteredTransfer &other)
RasterizePoints(const points::PointDataTree &tree, const TransferT &transfer, const CoordBBox &pointBounds, const PointFilterT &filter=PointFilterT(), InterrupterT *interrupter=nullptr)
GLint GLint GLsizei GLint GLenum GLenum type
bool startPointLeaf(const PointDataTree::LeafNodeType &)
#define OPENVDB_INIT_INVOKABLE_MEMBER_FUNCTION(F)
Macros to help determine whether or not a class has a particular member function. ...
void initialize(const Coord &origin, const size_t, const CoordBBox &)
GT_API const UT_StringHolder topology
const NodeMaskT * mask() const
InterruptableTransfer module, when derived from allows for schemes to callback into a interrupter...
VolumeTransfer(TreeType &tree)
std::tuple< TreeTypes *...> TreeTupleT
void initialize(const Coord &origin, const size_t, const CoordBBox &)
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
HUSD_API const char * raster()
GridTypes::Transform< internal::ToTreeType > TreeTypes
#define OPENVDB_HAS_INVOKABLE_MEMBER_FUNCTION(T, F,...)
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.
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.
GA_API const UT_StringHolder transform
void initialize(const Coord &, const size_t, const CoordBBox &)
FilteredTransfer(const NullFilter &)
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
static NonConstTreeType & tree(NonConstTreeType &t)
const ValueType< Idx > * buffer() const
bool filter(const Index) const
GT_API const UT_StringHolder st
typename RootNodeType::LeafNodeType LeafNodeType
typename std::tuple_element< Idx, std::tuple< TreeTypes...>>::type TreeType
void(const Coord &, const Index, const Index, const CoordBBox &) RasterizePointsSignature
ValueType< Idx > * buffer()
TreeType< 0 > & topology()
void foreach(T &&t, const F &func, std::integer_sequence< size_t, Is...>)
void operator()(LeafNodeT &leaf, const size_t idx) const
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void initialize(const Coord &, const size_t, const CoordBBox &)
VolumeTransfer(TreeType *tree)
void operator()(const typename LeafManagerT::LeafRange &range) const
const ValueType * buffer() const
The VolumeTransfer module provides methods to automatically setup and access destination buffers for ...
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 >>> PointDataTree
Point index tree configured to match the default VDB configurations.
const NodeMaskT * mask() const
typename TreeType< Idx >::ValueType ValueType
VolumeTransfer(TreeTypes &...trees)
bool wasInterrupted(T *i, int percent=-1)
const NodeMaskT * mask() const
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
VolumeTransfer(TreeTypes *...trees)
typename TreeType::ValueType ValueType
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter