11 #ifndef OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
12 #define OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
26 template <
typename TreeT>
32 template <
typename TreeT>
37 template <
typename TreeT>
43 template <
typename TreeT>
48 template <
typename TreeT>
53 template <
typename TreeT>
58 template <
typename TreeT>
67 template <
typename TreeT>
74 template <
typename TreeT>
80 template <
typename TreeT>
81 math::MinMax<typename TreeT::ValueType>
minMax(
const TreeT& tree,
bool threaded =
true);
88 namespace count_internal {
91 template<
typename TreeType>
92 struct 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;
126 template<
typename TreeType>
127 struct 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;
208 template<
typename TreeType>
209 struct 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) {
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;
257 template<
typename TreeType>
258 struct 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;
296 template<
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;
341 template<
typename TreeType>
342 struct MinMaxValuesOp
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;
378 bool join(
const MinMaxValuesOp& other)
380 if (!other.seen_value)
return true;
412 template <
typename TreeT>
415 count_internal::ActiveVoxelCountOp<TreeT> op;
422 template <
typename TreeT>
425 if (bbox.empty())
return Index64(0);
428 count_internal::ActiveVoxelCountBBoxOp<TreeT> op(bbox);
435 template <
typename TreeT>
438 count_internal::ActiveVoxelCountOp<TreeT> op;
441 leafManager.
reduce(op, threaded);
446 template <
typename TreeT>
449 if (bbox.empty())
return Index64(0);
452 count_internal::ActiveVoxelCountBBoxOp<TreeT> op(bbox);
455 leafManager.
reduce(op, threaded);
460 template <
typename TreeT>
463 count_internal::InactiveVoxelCountOp<TreeT> op;
470 template <
typename TreeT>
473 count_internal::InactiveVoxelCountOp<TreeT> op;
476 leafManager.
reduce(op, threaded);
481 template <
typename TreeT>
484 count_internal::ActiveTileCountOp<TreeT> op;
487 nodeManager.reduceTopDown(op, threaded);
492 template <
typename TreeT>
495 count_internal::MemUsageOp<TreeT> op(
true);
498 return op.mCount +
sizeof(tree);
501 template <
typename TreeT>
509 count_internal::MemUsageOp<TreeT> op(
false);
512 return op.mCount +
sizeof(tree);
515 template <
typename TreeT>
520 count_internal::MinMaxValuesOp<TreeT> op;
532 #endif // OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
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. Unlike foreach (defined above) this method performs a reduction on all the leaf nodes.
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
#define OPENVDB_USE_VERSION_NAMESPACE
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
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.
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Classes to compute statistics and histograms.
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Templated class to compute the minimum and maximum values.
Library and file format version numbers.
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.