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> 46 template<
typename ValueType>
58 template<
typename TreeT>
74 template<
typename TreeT>
87 template<
typename TreeT>
100 template<
typename TreeT>
113 template<
typename TreeT>
126 template<
typename TreeT>
127 std::vector<TileData<typename TreeT::ValueType>>
139 template<
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>
222 using RootChildType =
typename TreeT::RootNodeType::ChildNodeType;
227 std::vector<TileDataT> mRootTiles;
228 std::vector<RootChild> mRootNodes;
234 template<
typename TreeT>
240 template<
typename TreeT>
246 template<
typename TreeT>
254 template<
typename TreeT>
261 template<
typename TreeT>
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);
273 template<
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)) {
298 template<
typename TreeT>
301 for (
auto& node : mRootNodes) {
302 if (!node.bbox.hasOverlap(bbox)) {
304 }
else if (node.bbox.isInside(bbox)) {
313 template<
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)) {
331 template<
typename TreeT>
335 for (
auto& tile : mRootTiles) {
336 if (!tile.bbox.hasOverlap(bbox)) {
338 }
else if (tile.bbox.isInside(bbox)) {
339 return bbox.volume();
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);
360 template<
typename TreeT>
361 std::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) ) {
392 template<
typename TreeT>
393 template<
typename NodeT>
396 typename NodeT::NodeMaskType mask;
397 auto b = node->getNodeBoundingBox();
398 assert( bbox.hasOverlap(b) );
399 if ( bbox.isInside(b) ) {
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));
417 template<
typename TreeT>
418 template<
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) {
438 template<
typename TreeT>
439 template<
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) {
455 template<
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());
471 template<
typename TreeT>
472 template<
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) {
493 template<
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;
511 template<
typename TreeT>
512 template<
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);
558 template<
typename TreeT>
559 template<
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 ) {
585 tmp[i].bbox.intersect(bbox);
588 tiles.insert(tiles.end(), tmp.begin(), tmp.end());
592 template<
typename TreeT>
597 RootChild(
const Coord& ijk = Coord(),
const RootChildType* ptr =
nullptr)
598 : bbox(
CoordBBox::createCube(ijk, RootChildType::DIM)), child(ptr)
605 template<
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>
640 TileData(
const ParentNodeT &parent,
const Coord &ijk,
const ValueType &v)
641 : bbox(
CoordBBox::createCube(ijk, parent.getChildDim()))
652 template<
typename TreeT>
661 template<
typename TreeT>
670 template<
typename TreeT>
679 template<
typename TreeT>
688 template<
typename TreeT>
696 template<
typename TreeT>
697 std::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&) 746 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 753 #endif // OPENVDB_TOOLS_FINDACTIVEVALUES_HAS_BEEN_INCLUDED
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:226
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:150
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1658
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:110
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
Level getLevel()
Return the current logging level.
Definition: logging.h:141
Index32 Index
Definition: Types.h:54
Functions to count tiles, nodes or voxels in a grid.
#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