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;
446template <
typename TreeT>
452 count_internal::ActiveVoxelCountBBoxOp<TreeT>
op(bbox);
460template <
typename TreeT>
463 count_internal::InactiveVoxelCountOp<TreeT>
op;
470template <
typename TreeT>
473 count_internal::InactiveVoxelCountOp<TreeT>
op;
481template <
typename TreeT>
484 count_internal::ActiveTileCountOp<TreeT>
op;
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.
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition Coord.h:322
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:359
Templated class to compute the minimum and maximum values.
Definition Stats.h:32
Definition NodeManager.h:891
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:1044
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
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:533
Definition PointDataGrid.h:170
constexpr 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:218