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>>
 
  128activeTiles(
const TreeT& tree, 
const CoordBBox &bbox);
 
  139template<
typename TreeT>
 
  188    void init(
const TreeT &
tree);
 
  190    template<
typename NodeT>
 
  191    typename NodeT::NodeMaskType getBBoxMask(
const CoordBBox &
bbox, 
const NodeT* node) 
const;
 
  197    void activeTiles(
const typename TreeT::LeafNodeType*, 
const CoordBBox&, std::vector<TileDataT>&)
 const {;}
 
  198    inline Index64 count(
const typename TreeT::LeafNodeType* leaf, 
const CoordBBox &bbox ) 
const;
 
  201    template<
typename NodeT>
 
  202    bool anyActiveValues(
const NodeT* node, 
const CoordBBox &bbox) 
const;
 
  203    template<
typename NodeT>
 
  204    bool anyActiveVoxels(
const NodeT* node, 
const CoordBBox &bbox) 
const;
 
  205    template<
typename NodeT>
 
  206    bool anyActiveTiles(
const NodeT* node, 
const CoordBBox &bbox) 
const;
 
  207    template<
typename NodeT>
 
  208    void activeTiles(
const NodeT* node, 
const CoordBBox &bbox, std::vector<TileDataT> &tiles) 
const;
 
  209    template<
typename NodeT>
 
  213    using RootChildType = 
typename TreeT::RootNodeType::ChildNodeType;
 
  218    std::vector<TileDataT> mRootTiles;
 
  219    std::vector<RootChild> mRootNodes;
 
  225template<
typename TreeT>
 
  231template<
typename TreeT>
 
  237template<
typename TreeT>
 
  245template<
typename TreeT>
 
  246void FindActiveValues<TreeT>::clear()
 
  252template<
typename TreeT>
 
  253void FindActiveValues<TreeT>::init(
const TreeT& 
tree)
 
  255    const auto &root = 
tree.root();
 
  256    for (
auto i = root.cbeginChildOn(); i; ++i) {
 
  257        mRootNodes.emplace_back(i.getCoord(), &*i);
 
  259    for (
auto i = root.cbeginValueOn(); i; ++i) {
 
  260        mRootTiles.emplace_back(root, i.getCoord(), *i);
 
  264template<
typename TreeT>
 
  269        if (mAcc.isValueOn( (bbox.
min() + bbox.
max())>>1 )) 
return true;
 
  271        if (mAcc.tree().isValueOn( (bbox.
min() + bbox.
max())>>1 )) 
return true;
 
  274    for (
auto& tile : mRootTiles) {
 
  275        if (tile.bbox.hasOverlap(bbox)) 
return true;
 
  277    for (
auto& node : mRootNodes) {
 
  278        if (!node.bbox.hasOverlap(bbox)) {
 
  280        } 
else if (node.bbox.isInside(bbox)) {
 
 
  289template<
typename TreeT>
 
  292    for (
auto& node : mRootNodes) {
 
  293        if (!node.bbox.hasOverlap(bbox)) {
 
  295        } 
else if (node.bbox.isInside(bbox)) {
 
 
  304template<
typename TreeT>
 
  307    for (
auto& tile : mRootTiles) {
 
  308        if (tile.bbox.hasOverlap(bbox)) 
return true;
 
  310    for (
auto& node : mRootNodes) {
 
  311        if (!node.bbox.hasOverlap(bbox)) {
 
  313        } 
else if (node.bbox.isInside(bbox)) {
 
 
  322template<
typename TreeT>
 
  326    for (
auto& tile : mRootTiles) {
 
  327        if (!tile.bbox.hasOverlap(bbox)) {
 
  329        } 
else if (tile.bbox.isInside(bbox)) {
 
  331        } 
else if (bbox.
isInside(tile.bbox)) {
 
  332            count += RootChildType::NUM_VOXELS;
 
  334            auto tmp = tile.bbox;
 
  336            count += tmp.volume();
 
  339    for (
auto &node : mRootNodes) {
 
  340        if ( !node.bbox.hasOverlap(bbox) ) {
 
  342        } 
else if ( node.bbox.isInside(bbox) ) {
 
  343            return this->count(node.child, bbox);
 
  345            count += this->count(node.child, bbox);
 
 
  351template<
typename TreeT>
 
  352std::vector<TileData<typename TreeT::ValueType> >
 
  355    std::vector<TileDataT> tiles;
 
  356    for (
auto& tile : mRootTiles) {
 
  357        if (!tile.bbox.hasOverlap(bbox)) {
 
  359        } 
else if (tile.bbox.isInside(bbox)) {
 
  360            tiles.emplace_back(bbox, tile.value, tile.level);
 
  362        } 
else if (bbox.
isInside(tile.bbox)) {
 
  363            tiles.push_back(tile);
 
  365            auto tmp = tile.bbox;
 
  367            tiles.emplace_back(tmp, tile.value, tile.level);
 
  370    for (
auto &node : mRootNodes) {
 
  371        if ( !node.bbox.hasOverlap(bbox) ) {
 
  373        } 
else if ( node.bbox.isInside(bbox) ) {
 
 
 
  383template<
typename TreeT>
 
  384template<
typename NodeT>
 
  385typename NodeT::NodeMaskType FindActiveValues<TreeT>::getBBoxMask(
const CoordBBox &bbox, 
const NodeT* node)
 const 
  387    typename NodeT::NodeMaskType mask;
 
  388    auto b = node->getNodeBoundingBox();
 
  395        b.min() &=  NodeT::DIM-1u;
 
  396        b.min() >>= NodeT::ChildNodeType::TOTAL;
 
  397        b.max() &=  NodeT::DIM-1u;
 
  398        b.max() >>= NodeT::ChildNodeType::TOTAL;
 
  401        for (
const Coord& ijk = *it; it; ++it) {
 
  402            mask.setOn(ijk[2] + (ijk[1] << NodeT::LOG2DIM) + (ijk[0] << 2*NodeT::LOG2DIM));
 
  408template<
typename TreeT>
 
  409template<
typename NodeT>
 
  413    auto mask = this->getBBoxMask(bbox, node);
 
  416    const auto tmp = mask & node->getValueMask();
 
  417    if (!tmp.isOff()) 
return true;
 
  420    mask &= node->getChildMask();
 
  421    const auto* table = node->getTable();
 
  423    for (
auto i = mask.beginOn(); !active && i; ++i) {
 
  429template<
typename TreeT>
 
  430template<
typename NodeT>
 
  434    auto mask = this->getBBoxMask(bbox, node);
 
  437    mask &= node->getChildMask();
 
  438    const auto* table = node->getTable();
 
  440    for (
auto i = mask.beginOn(); !active && i; ++i) {
 
  446template<
typename TreeT>
 
  449    const auto &mask = leaf->getValueMask();
 
  452    if (bbox.isInside(leaf->getNodeBoundingBox())) 
return !mask.isOff();
 
  453    if (mask.isOn()) 
return true;
 
  456    for (
auto i = leaf->cbeginValueOn(); !active && i; ++i) {
 
  457        active = bbox.isInside(i.getCoord());
 
  462template<
typename TreeT>
 
  463template<
typename NodeT>
 
  467    auto mask = this->getBBoxMask(bbox, node);
 
  470    const auto tmp = mask & node->getValueMask();
 
  471    if (!tmp.isOff()) 
return true;
 
  474    if (NodeT::LEVEL>1) {
 
  475        mask &= node->getChildMask();
 
  476        const auto* table = node->getTable();
 
  477        for (
auto i = mask.beginOn(); !active && i; ++i) {
 
  484template<
typename TreeT>
 
  488    auto b = leaf->getNodeBoundingBox();
 
  489    if (b.isInside(bbox)) { 
 
  490        count = leaf->onVoxelCount();
 
  491    } 
else if (leaf->isDense()) {
 
  494    } 
else if (b.hasOverlap(bbox)) {
 
  495        for (
auto i = leaf->cbeginValueOn(); i; ++i) {
 
  496            if (bbox.isInside(i.getCoord())) ++count;
 
  502template<
typename TreeT>
 
  503template<
typename NodeT>
 
  509    auto mask = this->getBBoxMask(bbox, node);
 
  510    const auto childMask = mask & node->getChildMask();
 
  511    mask &= node->getValueMask();
 
  512    const auto* table = node->getTable();
 
  515        using ChildT = 
typename NodeT::ChildNodeType;
 
  516        using RangeT = tbb::blocked_range<typename std::vector<const ChildT*>::iterator>;
 
  517        std::vector<const ChildT*> childNodes(childMask.countOn());
 
  519        for (
auto i = childMask.beginOn(); i; ++i, ++j) childNodes[j] = table[i.pos()].getChild();
 
  520        count += tbb::parallel_reduce( RangeT(childNodes.begin(), childNodes.end()), 0,
 
  521            [&](
const RangeT& r, 
Index64 sum)->Index64 {
 
  522                for ( auto i = r.begin(); i != r.end(); ++i ) sum += this->count(*i, bbox);
 
  529        std::vector<Coord> coords(mask.countOn());
 
  530        using RangeT = tbb::blocked_range<typename std::vector<Coord>::iterator>;
 
  532        for (
auto i = mask.beginOn(); i; ++i, ++j) coords[j] = node->offsetToGlobalCoord(i.pos());
 
  533        count += tbb::parallel_reduce( RangeT(coords.begin(), coords.end()), 0,
 
  534            [&bbox](
const RangeT& r, 
Index64 sum)->Index64 {
 
  535                for ( auto i = r.begin(); i != r.end(); ++i ) {
 
  536                    auto b = CoordBBox::createCube(*i, NodeT::ChildNodeType::DIM);
 
  549template<
typename TreeT>
 
  550template<
typename NodeT>
 
  551void FindActiveValues<TreeT>::activeTiles(
const NodeT* node, 
const CoordBBox &bbox, std::vector<TileDataT> &tiles)
 const 
  554    auto mask = this->getBBoxMask(bbox, node);
 
  555    const auto childMask = mask & node->getChildMask();
 
  556    mask &= node->getValueMask();
 
  558    if (NodeT::LEVEL > 1) {
 
  559        const auto* table = node->getTable();
 
  560        for (
auto i = childMask.beginOn(); i; ++i) this->
activeTiles(table[i.pos()].getChild(), bbox, tiles);
 
  563    const size_t tileCount = mask.countOn();
 
  565        for (
auto iter = mask.beginOn(); iter; ++iter) {
 
  566            tiles.emplace_back(*node, iter.pos());
 
  567            tiles.back().bbox.intersect(bbox);
 
  570        std::vector<TileDataT> tmp( tileCount );
 
  572        for (
auto iter = mask.beginOn(); iter; ++iter) tmp[n++].level = iter.pos();
 
  573        tbb::parallel_for(tbb::blocked_range<size_t>(0, tileCount, 8), [&](
const tbb::blocked_range<size_t>& r) {
 
  574            for ( 
size_t i = r.begin(); i != r.end(); ++i ) {
 
  575                tmp[i] = TileDataT(*node, tmp[i].level);
 
  576                tmp[i].bbox.intersect(bbox);
 
  579        tiles.insert(tiles.end(), tmp.begin(), tmp.end());
 
  583template<
typename TreeT>
 
  596template<
typename ValueType>
 
  616    template <
typename ParentNodeT>
 
  618        : 
bbox(
CoordBBox::createCube(parent.offsetToGlobalCoord(childIdx), parent.getChildDim()))
 
  619        , 
level(parent.getLevel())
 
  625        value = parent.getTable()[childIdx].getValue();
 
 
  630    template <
typename ParentNodeT>
 
  634        , 
level(parent.getLevel())
 
 
 
  643template<
typename TreeT>
 
  648    return op.anyActiveValues(bbox);
 
 
  652template<
typename TreeT>
 
  657    return op.anyActiveVoxels(bbox);
 
 
  661template<
typename TreeT>
 
  666    return op.anyActiveTiles(bbox);
 
 
  670template<
typename TreeT>
 
  675    return op.noActiveValues(bbox);
 
 
  679template<
typename TreeT>
 
  687template<
typename TreeT>
 
  688std::vector<TileData<typename TreeT::ValueType>>
 
  692    return op.activeTiles(bbox);
 
 
  701#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 
  703#ifdef OPENVDB_INSTANTIATE_FINDACTIVEVALUES 
  707#define _FUNCTION(TreeT) \ 
  708    bool anyActiveValues(const TreeT&, const CoordBBox&) 
  712#define _FUNCTION(TreeT) \ 
  713    bool anyActiveVoxels(const TreeT&, const CoordBBox&) 
  717#define _FUNCTION(TreeT) \ 
  718    bool anyActiveTiles(const TreeT&, const CoordBBox&) 
  722#define _FUNCTION(TreeT) \ 
  723    bool noActiveValues(const TreeT&, const CoordBBox&) 
  727#define _FUNCTION(TreeT) \ 
  728    Index64 countActiveValues(const TreeT&, const CoordBBox&) 
  732#define _FUNCTION(TreeT) \ 
  733    std::vector<TileData<TreeT::ValueType>> activeTiles(const TreeT&, const CoordBBox&) 
 
 
 
 
 
 
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Functions to count tiles, nodes or voxels in a grid.
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
const Coord & min() const
Definition Coord.h:324
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition Coord.h:415
const Coord & max() const
Definition Coord.h:325
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition Coord.h:388
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition Coord.h:403
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Definition PointDataGrid.h:170
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
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:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition version.h.in:165