11#ifndef OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
12#define OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
14#include <openvdb/version.h>
26template <
typename TreeT>
32template <
typename TreeT>
37template <
typename TreeT>
43template <
typename TreeT>
48template <
typename TreeT>
53template <
typename TreeT>
58template <
typename TreeT>
67template <
typename TreeT>
74template <
typename TreeT>
80template <
typename TreeT>
81math::MinMax<typename TreeT::ValueType>
minMax(
const TreeT& tree,
bool threaded =
true);
88namespace count_internal {
91template<
typename TreeType>
92struct ActiveVoxelCountOp
94 using LeafT =
typename TreeType::LeafNodeType;
96 ActiveVoxelCountOp() =
default;
97 ActiveVoxelCountOp(
const ActiveVoxelCountOp&, tbb::split) { }
100 template<
typename NodeT>
101 bool operator()(
const NodeT& node,
size_t)
103 for (
auto iter = node.cbeginValueOn(); iter; ++iter) {
104 count += NodeT::ChildNodeType::NUM_VOXELS;
110 bool operator()(
const LeafT& leaf,
size_t)
112 count += leaf.onVoxelCount();
116 void join(
const ActiveVoxelCountOp& other)
118 count += other.count;
126template<
typename TreeType>
127struct ActiveVoxelCountBBoxOp
129 using LeafT =
typename TreeType::LeafNodeType;
131 explicit ActiveVoxelCountBBoxOp(
const CoordBBox& bbox)
133 ActiveVoxelCountBBoxOp(
const ActiveVoxelCountBBoxOp& other, tbb::split)
134 : mBBox(other.mBBox) { }
137 template<
typename NodeT>
138 bool operator()(
const NodeT& node,
size_t)
140 if (!mBBox.hasOverlap(node.getNodeBoundingBox()))
return false;
143 for (
auto iter = node.cbeginValueOn(); iter; ++iter) {
144 CoordBBox bbox(CoordBBox::createCube(iter.getCoord(), NodeT::ChildNodeType::DIM));
146 if (!bbox.hasOverlap(mBBox)) {
149 }
else if (bbox.isInside(mBBox)) {
151 count += mBBox.volume();
152 }
else if (mBBox.isInside(bbox)) {
154 count += bbox.volume();
157 bbox.intersect(mBBox);
158 count += bbox.volume();
163 for (
auto iter = node.cbeginChildOn(); iter; ++iter) {
164 if (mBBox.hasOverlap(iter->getNodeBoundingBox()))
return true;
172 inline bool operator()(
const LeafT& leaf,
size_t)
176 CoordBBox bbox = leaf.getNodeBoundingBox();
178 if (mBBox.isInside(bbox)) {
180 count += leaf.onVoxelCount();
181 }
else if (!bbox.hasOverlap(mBBox)) {
184 }
else if (leaf.isDense()) {
186 bbox.intersect(mBBox);
187 count += bbox.volume();
190 for (
auto i = leaf.cbeginValueOn(); i; ++i) {
191 if (mBBox.isInside(i.getCoord())) ++count;
197 void join(
const ActiveVoxelCountBBoxOp& other)
199 count += other.count;
208template<
typename TreeType>
209struct InactiveVoxelCountOp
211 using RootT =
typename TreeType::RootNodeType;
212 using LeafT =
typename TreeType::LeafNodeType;
214 InactiveVoxelCountOp() =
default;
215 InactiveVoxelCountOp(
const InactiveVoxelCountOp&, tbb::split) { }
218 bool operator()(
const RootT& root,
size_t)
220 for (
auto iter = root.cbeginValueOff(); iter; ++iter) {
222 if (!math::isApproxEqual(*iter, root.background())) {
223 count += RootT::ChildNodeType::NUM_VOXELS;
230 template<
typename NodeT>
231 bool operator()(
const NodeT& node,
size_t)
233 for (
auto iter = node.cbeginValueOff(); iter; ++iter) {
234 if (node.isChildMaskOff(iter.pos())) {
235 count += NodeT::ChildNodeType::NUM_VOXELS;
242 bool operator()(
const LeafT& leaf,
size_t)
244 count += leaf.offVoxelCount();
248 void join(
const InactiveVoxelCountOp& other)
250 count += other.count;
257template<
typename TreeType>
258struct ActiveTileCountOp
260 using RootT =
typename TreeType::RootNodeType;
261 using LeafT =
typename TreeType::LeafNodeType;
263 ActiveTileCountOp() =
default;
264 ActiveTileCountOp(
const ActiveTileCountOp&, tbb::split) { }
267 bool operator()(
const RootT& root,
size_t)
269 for (
auto iter = root.cbeginValueOn(); iter; ++iter) count++;
274 template<
typename NodeT>
275 bool operator()(
const NodeT& node,
size_t)
277 count += node.getValueMask().countOn();
282 bool operator()(
const LeafT&,
size_t)
287 void join(
const ActiveTileCountOp& other)
289 count += other.count;
296template<
typename TreeType>
299 using RootT =
typename TreeType::RootNodeType;
300 using LeafT =
typename TreeType::LeafNodeType;
302 MemUsageOp(
const bool inCoreOnly) : mInCoreOnly(inCoreOnly) {}
303 MemUsageOp(
const MemUsageOp& other) : mCount(0), mInCoreOnly(other.mInCoreOnly) {}
304 MemUsageOp(
const MemUsageOp& other, tbb::split) : MemUsageOp(other) {}
307 bool operator()(
const RootT& root,
size_t)
309 mCount +=
sizeof(root);
314 template<
typename NodeT>
315 bool operator()(
const NodeT& node,
size_t)
317 mCount += NodeT::NUM_VALUES *
sizeof(
typename NodeT::UnionType) +
318 node.getChildMask().memUsage() + node.getValueMask().memUsage() +
324 bool operator()(
const LeafT& leaf,
size_t)
326 if (mInCoreOnly) mCount += leaf.memUsage();
327 else mCount += leaf.memUsageIfLoaded();
331 void join(
const MemUsageOp& other)
333 mCount += other.mCount;
337 const bool mInCoreOnly;
341template<
typename TreeType>
344 using ValueT =
typename TreeType::ValueType;
346 explicit MinMaxValuesOp()
349 , seen_value(false) {}
351 MinMaxValuesOp(
const MinMaxValuesOp&, tbb::split)
352 : MinMaxValuesOp() {}
354 template <
typename NodeType>
355 bool operator()(NodeType& node,
size_t)
357 if (
auto iter = node.cbeginValueOn()) {
364 for (; iter; ++iter) {
365 const ValueT val = *iter;
367 if (math::cwiseLessThan(val, min))
370 if (math::cwiseGreaterThan(val, max))
378 bool join(
const MinMaxValuesOp& other)
380 if (!other.seen_value)
return true;
387 if (math::cwiseLessThan(other.min, min))
389 if (math::cwiseGreaterThan(other.max, max))
412template <
typename TreeT>
415 count_internal::ActiveVoxelCountOp<TreeT> op;
422template <
typename TreeT>
428 count_internal::ActiveVoxelCountBBoxOp<TreeT> op(bbox);
435template <
typename TreeT>
438 count_internal::ActiveVoxelCountOp<TreeT> op;
441 leafManager.
reduce(op, threaded);
446template <
typename TreeT>
452 count_internal::ActiveVoxelCountBBoxOp<TreeT> op(bbox);
455 leafManager.
reduce(op, threaded);
460template <
typename TreeT>
463 count_internal::InactiveVoxelCountOp<TreeT> op;
470template <
typename TreeT>
473 count_internal::InactiveVoxelCountOp<TreeT> op;
476 leafManager.
reduce(op, threaded);
481template <
typename TreeT>
484 count_internal::ActiveTileCountOp<TreeT> op;
487 nodeManager.reduceTopDown(op, threaded);
492template <
typename TreeT>
495 count_internal::MemUsageOp<TreeT> op(
true);
498 return op.mCount +
sizeof(tree);
501template <
typename TreeT>
509 count_internal::MemUsageOp<TreeT> op(
false);
512 return op.mCount +
sizeof(tree);
515template <
typename TreeT>
518 using ValueT =
typename TreeT::ValueType;
520 count_internal::MinMaxValuesOp<TreeT> op;
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
Classes to compute statistics and histograms.
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
Templated class to compute the minimum and maximum values.
Definition: Stats.h:31
Definition: NodeManager.h:890
void reduceTopDown(NodeOp &op, bool threaded=true, size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition: NodeManager.h:1043
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
void reduce(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:532
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1809
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:70
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
#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