22#ifndef OPENVDB_TOOLS_FINDACTIVEVALUES_HAS_BEEN_INCLUDED
23#define OPENVDB_TOOLS_FINDACTIVEVALUES_HAS_BEEN_INCLUDED
26#include <openvdb/version.h>
33#include <tbb/blocked_range.h>
34#include <tbb/parallel_for.h>
35#include <tbb/parallel_reduce.h>
46template<
typename ValueType>
58template<
typename TreeT>
74template<
typename TreeT>
87template<
typename TreeT>
100template<
typename TreeT>
113template<
typename TreeT>
126template<
typename TreeT>
127std::vector<TileData<typename TreeT::ValueType>>
139template<
typename TreeT>
153 void update(
const TreeT& tree);
197 void init(
const TreeT &tree);
199 template<
typename NodeT>
200 typename NodeT::NodeMaskType getBBoxMask(
const CoordBBox &bbox,
const NodeT* node)
const;
206 void activeTiles(
const typename TreeT::LeafNodeType*,
const CoordBBox&, std::vector<TileDataT>&)
const {;}
207 inline Index64 count(
const typename TreeT::LeafNodeType* leaf,
const CoordBBox &bbox )
const;
210 template<
typename NodeT>
212 template<
typename NodeT>
214 template<
typename NodeT>
216 template<
typename NodeT>
217 void activeTiles(
const NodeT* node,
const CoordBBox &bbox, std::vector<TileDataT> &tiles)
const;
218 template<
typename NodeT>
221 using AccT = tree::ValueAccessor<
const TreeT,
false>;
222 using RootChildType =
typename TreeT::RootNodeType::ChildNodeType;
227 std::vector<TileDataT> mRootTiles;
228 std::vector<RootChild> mRootNodes;
234template<
typename TreeT>
240template<
typename TreeT>
246template<
typename TreeT>
254template<
typename TreeT>
261template<
typename TreeT>
262void FindActiveValues<TreeT>::init(
const TreeT& tree)
264 const auto &root = tree.root();
265 for (
auto i = root.cbeginChildOn(); i; ++i) {
266 mRootNodes.emplace_back(i.getCoord(), &*i);
268 for (
auto i = root.cbeginValueOn(); i; ++i) {
269 mRootTiles.emplace_back(root, i.getCoord(), *i);
273template<
typename TreeT>
278 if (mAcc.isValueOn( (bbox.
min() + bbox.
max())>>1 ))
return true;
280 if (mAcc.tree().isValueOn( (bbox.
min() + bbox.
max())>>1 ))
return true;
283 for (
auto& tile : mRootTiles) {
284 if (tile.bbox.hasOverlap(bbox))
return true;
286 for (
auto& node : mRootNodes) {
287 if (!node.bbox.hasOverlap(bbox)) {
289 }
else if (node.bbox.isInside(bbox)) {
298template<
typename TreeT>
301 for (
auto& node : mRootNodes) {
302 if (!node.bbox.hasOverlap(bbox)) {
304 }
else if (node.bbox.isInside(bbox)) {
313template<
typename TreeT>
316 for (
auto& tile : mRootTiles) {
317 if (tile.bbox.hasOverlap(bbox))
return true;
319 for (
auto& node : mRootNodes) {
320 if (!node.bbox.hasOverlap(bbox)) {
322 }
else if (node.bbox.isInside(bbox)) {
331template<
typename TreeT>
335 for (
auto& tile : mRootTiles) {
336 if (!tile.bbox.hasOverlap(bbox)) {
338 }
else if (tile.bbox.isInside(bbox)) {
340 }
else if (bbox.
isInside(tile.bbox)) {
341 count += RootChildType::NUM_VOXELS;
343 auto tmp = tile.bbox;
345 count += tmp.volume();
348 for (
auto &node : mRootNodes) {
349 if ( !node.bbox.hasOverlap(bbox) ) {
351 }
else if ( node.bbox.isInside(bbox) ) {
352 return this->count(node.child, bbox);
354 count += this->count(node.child, bbox);
360template<
typename TreeT>
361std::vector<TileData<typename TreeT::ValueType> >
364 std::vector<TileDataT> tiles;
365 for (
auto& tile : mRootTiles) {
366 if (!tile.bbox.hasOverlap(bbox)) {
368 }
else if (tile.bbox.isInside(bbox)) {
369 tiles.emplace_back(bbox, tile.value, tile.level);
371 }
else if (bbox.
isInside(tile.bbox)) {
372 tiles.push_back(tile);
374 auto tmp = tile.bbox;
376 tiles.emplace_back(tmp, tile.value, tile.level);
379 for (
auto &node : mRootNodes) {
380 if ( !node.bbox.hasOverlap(bbox) ) {
382 }
else if ( node.bbox.isInside(bbox) ) {
392template<
typename TreeT>
393template<
typename NodeT>
396 typename NodeT::NodeMaskType mask;
397 auto b = node->getNodeBoundingBox();
404 b.min() &= NodeT::DIM-1u;
405 b.min() >>= NodeT::ChildNodeType::TOTAL;
406 b.max() &= NodeT::DIM-1u;
407 b.max() >>= NodeT::ChildNodeType::TOTAL;
408 assert( b.hasVolume() );
410 for (
const Coord& ijk = *it; it; ++it) {
411 mask.setOn(ijk[2] + (ijk[1] << NodeT::LOG2DIM) + (ijk[0] << 2*NodeT::LOG2DIM));
417template<
typename TreeT>
418template<
typename NodeT>
422 auto mask = this->getBBoxMask(bbox, node);
425 const auto tmp = mask & node->getValueMask();
426 if (!tmp.isOff())
return true;
429 mask &= node->getChildMask();
430 const auto* table = node->getTable();
432 for (
auto i = mask.beginOn(); !active && i; ++i) {
438template<
typename TreeT>
439template<
typename NodeT>
443 auto mask = this->getBBoxMask(bbox, node);
446 mask &= node->getChildMask();
447 const auto* table = node->getTable();
449 for (
auto i = mask.beginOn(); !active && i; ++i) {
455template<
typename TreeT>
458 const auto &mask = leaf->getValueMask();
461 if (bbox.isInside(leaf->getNodeBoundingBox()))
return !mask.isOff();
462 if (mask.isOn())
return true;
465 for (
auto i = leaf->cbeginValueOn(); !active && i; ++i) {
466 active = bbox.isInside(i.getCoord());
471template<
typename TreeT>
472template<
typename NodeT>
476 auto mask = this->getBBoxMask(bbox, node);
479 const auto tmp = mask & node->getValueMask();
480 if (!tmp.isOff())
return true;
483 if (NodeT::LEVEL>1) {
484 mask &= node->getChildMask();
485 const auto* table = node->getTable();
486 for (
auto i = mask.beginOn(); !active && i; ++i) {
493template<
typename TreeT>
497 auto b = leaf->getNodeBoundingBox();
498 if (b.isInside(bbox)) {
499 count = leaf->onVoxelCount();
500 }
else if (leaf->isDense()) {
503 }
else if (b.hasOverlap(bbox)) {
504 for (
auto i = leaf->cbeginValueOn(); i; ++i) {
505 if (bbox.isInside(i.getCoord())) ++count;
511template<
typename TreeT>
512template<
typename NodeT>
518 auto mask = this->getBBoxMask(bbox, node);
519 const auto childMask = mask & node->getChildMask();
520 mask &= node->getValueMask();
521 const auto* table = node->getTable();
524 using ChildT =
typename NodeT::ChildNodeType;
525 using RangeT = tbb::blocked_range<typename std::vector<const ChildT*>::iterator>;
526 std::vector<const ChildT*> childNodes(childMask.countOn());
528 for (
auto i = childMask.beginOn(); i; ++i, ++j) childNodes[j] = table[i.pos()].getChild();
529 count += tbb::parallel_reduce( RangeT(childNodes.begin(), childNodes.end()), 0,
530 [&](
const RangeT& r,
Index64 sum)->Index64 {
531 for ( auto i = r.begin(); i != r.end(); ++i ) sum += this->count(*i, bbox);
538 std::vector<Coord> coords(mask.countOn());
539 using RangeT = tbb::blocked_range<typename std::vector<Coord>::iterator>;
541 for (
auto i = mask.beginOn(); i; ++i, ++j) coords[j] = node->offsetToGlobalCoord(i.pos());
542 count += tbb::parallel_reduce( RangeT(coords.begin(), coords.end()), 0,
543 [&bbox](
const RangeT& r,
Index64 sum)->Index64 {
544 for ( auto i = r.begin(); i != r.end(); ++i ) {
545 auto b = CoordBBox::createCube(*i, NodeT::ChildNodeType::DIM);
558template<
typename TreeT>
559template<
typename NodeT>
563 auto mask = this->getBBoxMask(bbox, node);
564 const auto childMask = mask & node->getChildMask();
565 mask &= node->getValueMask();
567 if (NodeT::LEVEL > 1) {
568 const auto* table = node->getTable();
569 for (
auto i = childMask.beginOn(); i; ++i) this->
activeTiles(table[i.pos()].getChild(), bbox, tiles);
572 const size_t tileCount = mask.countOn();
574 for (
auto iter = mask.beginOn(); iter; ++iter) {
575 tiles.emplace_back(*node, iter.pos());
576 tiles.back().bbox.intersect(bbox);
579 std::vector<TileDataT> tmp( tileCount );
581 for (
auto iter = mask.beginOn(); iter; ++iter) tmp[n++].level = iter.pos();
582 tbb::parallel_for(tbb::blocked_range<size_t>(0, tileCount, 8), [&](
const tbb::blocked_range<size_t>& r) {
583 for (
size_t i = r.begin(); i != r.end(); ++i ) {
584 tmp[i] = TileDataT(*node, tmp[i].level);
585 tmp[i].bbox.intersect(bbox);
588 tiles.insert(tiles.end(), tmp.begin(), tmp.end());
592template<
typename TreeT>
598 : bbox(
CoordBBox::createCube(ijk, RootChildType::DIM)),
child(ptr)
605template<
typename ValueType>
618 : bbox(b),
value(v), level(l), state(active) {}
625 template <
typename ParentNodeT>
627 : bbox(
CoordBBox::createCube(parent.offsetToGlobalCoord(childIdx), parent.getChildDim()))
631 assert(childIdx < ParentNodeT::NUM_VALUES);
632 assert(parent.isChildMaskOff(childIdx));
633 assert(parent.isValueMaskOn(childIdx));
634 value = parent.getTable()[childIdx].getValue();
639 template <
typename ParentNodeT>
641 : bbox(
CoordBBox::createCube(ijk, parent.getChildDim()))
652template<
typename TreeT>
661template<
typename TreeT>
670template<
typename TreeT>
679template<
typename TreeT>
688template<
typename TreeT>
696template<
typename TreeT>
697std::vector<TileData<typename TreeT::ValueType>>
710#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
712#ifdef OPENVDB_INSTANTIATE_FINDACTIVEVALUES
716#define _FUNCTION(TreeT) \
717 bool anyActiveValues(const TreeT&, const CoordBBox&)
721#define _FUNCTION(TreeT) \
722 bool anyActiveVoxels(const TreeT&, const CoordBBox&)
726#define _FUNCTION(TreeT) \
727 bool anyActiveTiles(const TreeT&, const CoordBBox&)
731#define _FUNCTION(TreeT) \
732 bool noActiveValues(const TreeT&, const CoordBBox&)
736#define _FUNCTION(TreeT) \
737 Index64 countActiveValues(const TreeT&, const CoordBBox&)
741#define _FUNCTION(TreeT) \
742 std::vector<TileData<TreeT::ValueType>> activeTiles(const TreeT&, const CoordBBox&)
Functions to count tiles, nodes or voxels in a grid.
ValueT value
Definition: GridBuilder.h:1287
ChildT * child
Definition: GridBuilder.h:1286
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
const Coord & min() const
Definition: Coord.h:320
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:411
const Coord & max() const
Definition: Coord.h:321
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:384
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:399
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1658
Level getLevel()
Return the current logging level.
Definition: logging.h:141
Index32 Index
Definition: Types.h:54
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:150