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> 164 template <
typename PointDataTreeOrGridT,
166 typename FilterT = NullFilter,
167 typename InterrupterT = util::NullInterrupter>
169 rasterize(
const PointDataTreeOrGridT& points,
171 const FilterT& filter = NullFilter(),
172 InterrupterT* interrupter =
nullptr);
185 : mSourceTransform(st)
186 , mTargetTransform(tt) {}
188 template <
typename T>
191 const auto result = mSourceTransform.indexToWorld(value);
192 return mTargetTransform.worldToIndex(result);
195 template <
typename T>
198 const auto result = mTargetTransform.indexToWorld(value);
199 return mSourceTransform.worldToIndex(result);
214 template <
typename ...TreeTypes>
217 static const size_t Size =
sizeof...(TreeTypes);
220 template <
size_t Idx>
using TreeType =
typename std::tuple_element<Idx, std::tuple<
TreeTypes...>>::type;
231 : mTreeArray(other.mTreeArray)
235 mBuffers.fill(
nullptr);
236 mMasks.fill(
nullptr);
241 inline void initialize(
const Coord& origin,
const size_t,
const CoordBBox&);
243 template <
size_t Idx>
249 template <
size_t Idx>
255 template <
size_t Idx>
259 template <
size_t Idx>
261 inline const NodeMaskT*
mask(
const size_t idx)
const {
return mMasks[idx]; }
263 template <
typename FunctorT>
264 inline void foreach(
const FunctorT& functor);
268 std::array<void*, Size> mBuffers;
269 std::array<NodeMaskT*, Size> mMasks;
274 template <
typename TreeT>
279 using NodeMaskT =
typename TreeType::LeafNodeType::NodeMaskType;
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.");
302 inline void initialize(
const Coord& origin,
const size_t,
const CoordBBox&)
305 if (
auto leaf = mTree->probeLeaf(origin)) {
306 mBuffer = leaf->buffer().data();
307 mMask = &(leaf->getValueMask());
332 namespace transfer_internal
334 template<
typename T,
typename F,
size_t... Is>
335 void foreach(T&& t,
const F& func, std::integer_sequence<size_t, Is...>)
337 auto init = { (func(std::get<Is>(t), Is), 0)... };
341 template<
typename T,
typename F,
size_t... Is>
342 void foreach(
void** buffers,
const F& func, std::integer_sequence<size_t, Is...>)
344 int init[
sizeof...(Is)] = {
345 (func(
static_cast<typename std::tuple_element<Is, T>::type*
> 346 (*(buffers + Is)), Is), 0)...
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...>)
353 int init[
sizeof...(Is)] = {
354 (func(
static_cast<typename R<typename std::tuple_element<Is, T>::type
>::Type*>
355 (*(buffers + Is)), Is), 0)...
360 template <
typename ...TreeTypes>
362 : mTreeArray({ trees... })
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.");
372 }, std::make_integer_sequence<size_t, Size>());
374 mBuffers.fill(
nullptr);
375 mMasks.fill(
nullptr);
378 template <
typename ...TreeTypes>
382 [&](
auto&& tree,
const size_t i) {
384 if (
auto leaf = tree->probeLeaf(origin)) {
385 mBuffers[i] =
static_cast<void*
>(leaf->buffer().data());
386 mMasks[i] = &(leaf->getValueMask());
389 mBuffers[i] =
nullptr;
392 }, std::make_integer_sequence<size_t, Size>());
395 template <
typename ...TreeTypes>
396 template <
typename FunctorT>
399 transfer_internal::foreach<TreeTupleT, TypeResolver>(mBuffers.data(), functor,
400 std::make_integer_sequence<size_t, Size>());
403 namespace transfer_internal
405 template <
typename TransferT,
414 static const Index DIM = TopologyT::LeafNodeType::DIM;
416 static const Index LOG2DIM = TopologyT::LeafNodeType::LOG2DIM;
419 const TransferT& transfer,
420 const PointFilterT& filter = PointFilterT(),
421 InterrupterT* interrupter =
nullptr)
422 : mPointAccessor(tree)
423 , mTransfer(transfer)
425 , mInterrupter(interrupter) {}
430 thread::cancelGroupExecution();
434 const Coord& origin = leaf.origin();
435 auto&
mask = leaf.getValueMask();
440 if (
mask.isConstant(state)) {
442 else bounds = leaf.getNodeBoundingBox();
447 leaf.evalActiveBoundingBox(bounds);
451 mTransfer.initialize(origin, idx, bounds);
453 CoordBBox search = bounds.expandBy(mTransfer.range(origin, idx));
454 this->transform<>(search);
457 const Coord
min = (search.min() & ~(DIM-1));
458 const Coord&
max = search.max();
459 PointFilterT localFilter(mFilter);
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) {
468 CoordBBox pbox = CoordBBox::createCube(leafOrigin, DIM32);
469 pbox.intersect(search);
470 if (pbox.empty())
continue;
473 const auto* pointLeaf = mPointAccessor.probeConstLeaf(leafOrigin);
474 if (!pointLeaf)
continue;
475 if (!mTransfer.startPointLeaf(*pointLeaf))
continue;
476 localFilter.reset(*pointLeaf);
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);
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()) {
488 const Index index = ij + (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);
499 if (!mTransfer.endPointLeaf(*pointLeaf)) {
501 if (!mTransfer.finalize(origin, idx)) {
502 this->operator()(leaf, idx);
511 if (!mTransfer.finalize(origin, idx)) {
512 this->operator()(leaf, idx);
518 for (
auto leaf = range.
begin(); leaf; ++leaf) {
519 (*this)(*leaf, leaf.pos());
525 template <
typename EnableT = TransferT>
526 typename std::enable_if<std::is_base_of<TransformTransfer, EnableT>::value>::type
527 transform(CoordBBox& bounds)
const 531 const BBoxd bbox(bounds.min().asVec3d(), bounds.max().asVec3d());
536 template <
typename EnableT = TransferT>
537 typename std::enable_if<!std::is_base_of<TransformTransfer, EnableT>::value>::type
538 transform(CoordBBox&)
const {}
542 mutable TransferT mTransfer;
543 const PointFilterT& mFilter;
544 InterrupterT* mInterrupter;
552 template <
typename PointDataTreeOrGridT,
555 typename InterrupterT>
559 const FilterT& filter,
560 InterrupterT* interrupter)
563 static_assert(std::is_base_of<TreeBase, PointTreeT>::value,
564 "Provided points to rasterize is not a derived TreeBase type.");
568 auto&
topology = transfer.topology();
569 using TreeT =
typename std::decay<decltype(topology)>::type;
572 raster(tree, transfer, filter, interrupter);
580 #endif //OPENVEB_POINTS_TRANSFER_HAS_BEEN_INCLUDED
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
Iterator begin() const
Definition: LeafManager.h:156
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
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 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
Definition: PointTransfer.h:409
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
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
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
Definition: LeafManager.h:102
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: PointTransfer.h:222
TreeT TreeType
Definition: PointTransfer.h:277
This class manages a linear array of pointers to a given tree'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
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
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