20#ifndef OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
21#define OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
28#include <openvdb/thread/Threading.h>
163template <
typename PointDataTreeOrGridT,
165 typename FilterT = NullFilter,
166 typename InterrupterT = util::NullInterrupter>
168rasterize(
const PointDataTreeOrGridT& points,
170 const FilterT& filter = NullFilter(),
171 InterrupterT* interrupter =
nullptr);
184 : mSourceTransform(st)
185 , mTargetTransform(tt) {}
187 template <
typename T>
190 const auto result = mSourceTransform.indexToWorld(
value);
191 return mTargetTransform.worldToIndex(result);
194 template <
typename T>
197 const auto result = mTargetTransform.indexToWorld(
value);
198 return mSourceTransform.worldToIndex(result);
213template <
typename ...TreeTypes>
216 static const size_t Size =
sizeof...(TreeTypes);
219 template <
size_t Idx>
using TreeType =
typename std::tuple_element<Idx, std::tuple<
TreeTypes...>>::type;
230 : mTreeArray(other.mTreeArray)
234 mBuffers.fill(
nullptr);
235 mMasks.fill(
nullptr);
242 template <
size_t Idx>
248 template <
size_t Idx>
254 template <
size_t Idx>
258 template <
size_t Idx>
260 inline const NodeMaskT*
mask(
const size_t idx)
const {
return mMasks[idx]; }
262 template <
typename FunctorT>
263 inline void foreach(
const FunctorT& functor);
266 const TreeTupleT mTreeArray;
267 std::array<void*, Size> mBuffers;
268 std::array<NodeMaskT*, Size> mMasks;
273template <
typename TreeT>
278 using NodeMaskT =
typename TreeType::LeafNodeType::NodeMaskType;
280 static_assert(std::is_base_of<TreeBase, TreeType>::value,
281 "One or more template arguments to VolumeTransfer "
282 "are not a valid openvdb::Tree type.");
304 if (
auto leaf = mTree->probeLeaf(origin)) {
305 mBuffer = leaf->buffer().data();
306 mMask = &(leaf->getValueMask());
326 TreeType*
const mTree;
331namespace transfer_internal
333template<
typename T,
typename F,
size_t... Is>
334void foreach(T&& t,
const F& func, std::integer_sequence<size_t, Is...>)
336 auto init = { (func(std::get<Is>(t), Is), 0)... };
340template<
typename T,
typename F,
size_t... Is>
341void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
343 int init[
sizeof...(Is)] = {
344 (func(
static_cast<typename std::tuple_element<Is, T>::type*
>
345 (*(buffers + Is)), Is), 0)...
349template<
typename T,
template <
typename>
class R,
typename F,
size_t... Is>
350void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
352 int init[
sizeof...(Is)] = {
353 (func(
static_cast<typename R<typename std::tuple_element<Is, T>::type
>::Type*>
354 (*(buffers + Is)), Is), 0)...
359template <
typename ...TreeTypes>
361 : mTreeArray({ trees... })
365 transfer_internal::foreach(mTreeArray, [](
auto&& tree,
const size_t) {
366 using TreeT =
typename std::remove_pointer<
typename std::decay<
decltype(tree)>::type>::type;
367 static_assert(std::is_base_of<TreeBase, TreeT>::value,
368 "One or more template arguments to VolumeTransfer "
369 "are not a valid openvdb::Tree type.");
371 }, std::make_integer_sequence<size_t, Size>());
373 mBuffers.fill(
nullptr);
374 mMasks.fill(
nullptr);
377template <
typename ...TreeTypes>
380 transfer_internal::foreach(mTreeArray,
381 [&](
auto&& tree,
const size_t i) {
383 if (
auto leaf = tree->probeLeaf(origin)) {
384 mBuffers[i] =
static_cast<void*
>(leaf->buffer().data());
385 mMasks[i] = &(leaf->getValueMask());
388 mBuffers[i] =
nullptr;
391 }, std::make_integer_sequence<size_t, Size>());
394template <
typename ...TreeTypes>
395template <
typename FunctorT>
398 transfer_internal::foreach<TreeTupleT, TypeResolver>(mBuffers.data(), functor,
399 std::make_integer_sequence<size_t, Size>());
402namespace transfer_internal
404template <
typename TransferT,
408struct RasterizePoints
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;
418 const TransferT& transfer,
419 const PointFilterT& filter = PointFilterT(),
420 InterrupterT* interrupter =
nullptr)
421 : mPointAccessor(tree)
422 , mTransfer(transfer)
424 , mInterrupter(interrupter) {}
426 void operator()(LeafNodeT& leaf,
const size_t idx)
const
429 thread::cancelGroupExecution();
433 const Coord& origin = leaf.origin();
434 auto& mask = leaf.getValueMask();
439 if (mask.isConstant(state)) {
441 else bounds = leaf.getNodeBoundingBox();
446 leaf.evalActiveBoundingBox(bounds);
447 assert(!bounds.
empty());
450 mTransfer.initialize(origin, idx, bounds);
453 this->transform<>(search);
456 const Coord
min = (search.min() & ~(DIM-1));
457 const Coord&
max = search.max();
458 PointFilterT localFilter(mFilter);
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) {
468 pbox.intersect(search);
469 if (pbox.empty())
continue;
472 const auto* pointLeaf = mPointAccessor.probeConstLeaf(leafOrigin);
473 if (!pointLeaf)
continue;
474 if (!mTransfer.startPointLeaf(*pointLeaf))
continue;
475 localFilter.reset(*pointLeaf);
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);
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()) {
486 assert((ijk & ~(DIM-1u)) == leafOrigin);
487 const Index index = ij + (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);
498 if (!mTransfer.endPointLeaf(*pointLeaf)) {
500 if (!mTransfer.finalize(origin, idx)) {
501 this->operator()(leaf, idx);
510 if (!mTransfer.finalize(origin, idx)) {
511 this->operator()(leaf, idx);
515 void operator()(
const typename LeafManagerT::LeafRange& range)
const
517 for (
auto leaf = range.begin(); leaf; ++leaf) {
518 (*this)(*leaf, leaf.pos());
524 template <
typename EnableT = TransferT>
525 typename std::enable_if<std::is_base_of<TransformTransfer, EnableT>::value>::type
526 transform(CoordBBox& bounds)
const
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));
535 template <
typename EnableT = TransferT>
536 typename std::enable_if<!std::is_base_of<TransformTransfer, EnableT>::value>::type
537 transform(CoordBBox&)
const {}
541 mutable TransferT mTransfer;
542 const PointFilterT& mFilter;
543 InterrupterT* mInterrupter;
551template <
typename PointDataTreeOrGridT,
554 typename InterrupterT>
558 const FilterT& filter,
559 InterrupterT* interrupter)
562 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
563 "Provided points to rasterize is not a derived TreeBase type.");
567 auto& topology = transfer.topology();
568 using TreeT =
typename std::decay<
decltype(topology)>::type;
570 transfer_internal::RasterizePoints<TransferT, TreeT, FilterT, InterrupterT>
571 raster(tree, transfer, filter, interrupter);
572 manager.foreach(raster);
ValueT value
Definition GridBuilder.h:1290
typename tree::ValueAccessor< const _TreeType, true > ConstAccessor
Definition Grid.h:590
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:249
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:356
CoordBBox expandBy(ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition Coord.h:425
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition Coord.h:313
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:51
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:85
LeafType LeafNodeType
Definition LeafManager.h:92
BBox< Coord > CoordBBox
Definition NanoVDB.h:1809
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
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
Index32 Index
Definition Types.h:54
GridTypes::Transform< internal::ToTreeType > TreeTypes
Definition openvdb.h:123
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types....
math::BBox< Vec3d > BBoxd
Definition Types.h:84
int32_t Int32
Definition Types.h:56
Definition Exceptions.h:13
static TreeType & tree(TreeType &t)
Definition Grid.h:1076
_TreeType TreeType
Definition Grid.h:1061
Definition PointTransfer.h:221
typename T::ValueType Type
Definition PointTransfer.h:221
const NodeMaskT * mask() const
Definition PointTransfer.h:323
typename TreeType::ValueType ValueType
Definition PointTransfer.h:277
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:301
const ValueType * buffer() const
Definition PointTransfer.h:321
const NodeMaskT * mask() const
Definition PointTransfer.h:317
ValueType * buffer()
Definition PointTransfer.h:320
VolumeTransfer(TreeType &tree)
Definition PointTransfer.h:291
NodeMaskT * mask()
Definition PointTransfer.h:316
VolumeTransfer(TreeType *tree)
Definition PointTransfer.h:284
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:294
const ValueType * buffer() const
Definition PointTransfer.h:315
NodeMaskT * mask()
Definition PointTransfer.h:322
typename TreeType::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:278
ValueType * buffer()
Definition PointTransfer.h:314
TreeType & topology()
Definition PointTransfer.h:299
TreeT TreeType
Definition PointTransfer.h:276
The VolumeTransfer module provides methods to automatically setup and access destination buffers for ...
Definition PointTransfer.h:215
const NodeMaskT * mask() const
Definition PointTransfer.h:259
typename std::tuple_element< Idx, std::tuple< TreeTypes... > >::type TreeType
Definition PointTransfer.h:219
void initialize(const Coord &origin, const size_t, const CoordBBox &)
Definition PointTransfer.h:378
const ValueType< Idx > * buffer() const
Definition PointTransfer.h:249
ValueType< Idx > * buffer()
Definition PointTransfer.h:243
TreeType< 0 > & topology()
Definition PointTransfer.h:238
typename TreeType< 0 >::LeafNodeType::NodeMaskType NodeMaskT
Definition PointTransfer.h:222
VolumeTransfer(const VolumeTransfer &other)
Definition PointTransfer.h:229
std::tuple< TreeTypes *... > TreeTupleT
Definition PointTransfer.h:217
NodeMaskT * mask()
Definition PointTransfer.h:255
void foreach(const FunctorT &functor)
Definition PointTransfer.h:396
NodeMaskT * mask(const size_t idx)
Definition PointTransfer.h:256
const NodeMaskT * mask(const size_t idx) const
Definition PointTransfer.h:260
VolumeTransfer(TreeTypes &... trees)
Definition PointTransfer.h:226
typename TreeType< Idx >::ValueType ValueType
Definition PointTransfer.h:220
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:212