OpenVDB  8.1.0
Count.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
10 
11 #ifndef OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
12 #define OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
13 
14 #include <openvdb/version.h>
16 
17 namespace openvdb {
19 namespace OPENVDB_VERSION_NAME {
20 namespace tools {
21 
22 
24 template <typename TreeT>
25 Index64 countActiveVoxels(const TreeT& tree, bool threaded = true);
26 
27 
30 template <typename TreeT>
31 Index64 countActiveVoxels(const TreeT& tree, const CoordBBox& bbox, bool threaded = true);
32 
33 
35 template <typename TreeT>
36 Index64 memUsage(const TreeT& tree, bool threaded = true);
37 
38 
40 
41 
42 namespace count_internal {
43 
45 template<typename TreeType>
47 {
48  using LeafT = typename TreeType::LeafNodeType;
49 
50  ActiveVoxelCountOp() = default;
51  ActiveVoxelCountOp(const ActiveVoxelCountOp&, tbb::split) { }
52 
53  // accumulate all voxels in active tile children
54  template<typename NodeT>
55  bool operator()(const NodeT& node, size_t)
56  {
57  for (auto iter = node.cbeginValueOn(); iter; ++iter) {
58  count += NodeT::ChildNodeType::NUM_VOXELS;
59  }
60  return true;
61  }
62 
63  // accumulate all active voxels in the leaf
64  bool operator()(const LeafT& leaf, size_t)
65  {
66  count += leaf.onVoxelCount();
67  return false;
68  }
69 
70  void join(const ActiveVoxelCountOp& other)
71  {
72  count += other.count;
73  }
74 
75  openvdb::Index64 count{0};
76 }; // struct ActiveVoxelCountOp
77 
80 template<typename TreeType>
82 {
83  using LeafT = typename TreeType::LeafNodeType;
84 
85  explicit ActiveVoxelCountBBoxOp(const CoordBBox& bbox)
86  : mBBox(bbox) { }
88  : mBBox(other.mBBox) { }
89 
90  // accumulate all voxels in active tile children bounded by the bbox
91  template<typename NodeT>
92  bool operator()(const NodeT& node, size_t)
93  {
94  if (!mBBox.hasOverlap(node.getNodeBoundingBox())) return false;
95 
96  // count any overlapping regions in active tiles
97  for (auto iter = node.cbeginValueOn(); iter; ++iter) {
98  CoordBBox bbox(CoordBBox::createCube(iter.getCoord(), NodeT::ChildNodeType::DIM));
99 
100  if (!bbox.hasOverlap(mBBox)) {
101  // box is completely outside the active tile
102  continue;
103  } else if (bbox.isInside(mBBox)) {
104  // bbox is completely inside the active tile
105  count += mBBox.volume();
106  } else if (mBBox.isInside(bbox)) {
107  // active tile is completely inside bbox
108  count += bbox.volume();
109  } else {
110  // partial overlap between tile and bbox
111  bbox.intersect(mBBox);
112  count += bbox.volume();
113  }
114  }
115 
116  // return true if any child nodes overlap with the bounding box
117  for (auto iter = node.cbeginChildOn(); iter; ++iter) {
118  if (mBBox.hasOverlap(iter->getNodeBoundingBox())) return true;
119  }
120 
121  // otherwise return false to prevent recursion along this branch
122  return false;
123  }
124 
125  // accumulate all active voxels in the leaf bounded by the bbox
126  inline bool operator()(const LeafT& leaf, size_t)
127  {
128  // note: the true/false return value does nothing
129 
130  CoordBBox bbox = leaf.getNodeBoundingBox();
131 
132  if (mBBox.isInside(bbox)) {
133  // leaf node is completely inside bbox
134  count += leaf.onVoxelCount();
135  } else if (!bbox.hasOverlap(mBBox)) {
136  // bbox is completely outside the leaf node
137  return false;
138  } else if (leaf.isDense()) {
139  // partial overlap between dense leaf node and bbox
140  bbox.intersect(mBBox);
141  count += bbox.volume();
142  } else {
143  // partial overlap between sparse leaf node and bbox
144  for (auto i = leaf.cbeginValueOn(); i; ++i) {
145  if (mBBox.isInside(i.getCoord())) ++count;
146  }
147  }
148  return false;
149  }
150 
151  void join(const ActiveVoxelCountBBoxOp& other)
152  {
153  count += other.count;
154  }
155 
157 private:
158  CoordBBox mBBox;
159 }; // struct ActiveVoxelCountBBoxOp
160 
162 template<typename TreeType>
164 {
165  using RootT = typename TreeType::RootNodeType;
166  using LeafT = typename TreeType::LeafNodeType;
167 
168  MemUsageOp() = default;
169  MemUsageOp(const MemUsageOp&, tbb::split) { }
170 
171  // accumulate size of the root node in bytes
172  bool operator()(const RootT& root, size_t)
173  {
174  count += sizeof(root);
175  return true;
176  }
177 
178  // accumulate size of all child nodes in bytes
179  template<typename NodeT>
180  bool operator()(const NodeT& node, size_t)
181  {
182  count += NodeT::NUM_VALUES * sizeof(typename NodeT::UnionType) +
183  node.getChildMask().memUsage() + node.getValueMask().memUsage() +
184  sizeof(Coord);
185  return true;
186  }
187 
188  // accumulate size of leaf node in bytes
189  bool operator()(const LeafT& leaf, size_t)
190  {
191  count += leaf.memUsage();
192  return false;
193  }
194 
195  void join(const MemUsageOp& other)
196  {
197  count += other.count;
198  }
199 
201 }; // struct MemUsageOp
202 
203 } // namespace count_internal
204 
205 
207 
208 
209 template <typename TreeT>
210 Index64 countActiveVoxels(const TreeT& tree, bool threaded)
211 {
213  tree::DynamicNodeManager<const TreeT> nodeManager(tree);
214  nodeManager.reduceTopDown(op, threaded);
215  return op.count;
216 }
217 
218 
219 template <typename TreeT>
220 Index64 countActiveVoxels(const TreeT& tree, const CoordBBox& bbox, bool threaded)
221 {
222  if (bbox.empty()) return Index64(0);
223  else if (bbox == CoordBBox::inf()) return countActiveVoxels(tree, threaded);
224 
226  tree::DynamicNodeManager<const TreeT> nodeManager(tree);
227  nodeManager.reduceTopDown(op, threaded);
228  return op.count;
229 }
230 
231 
232 template <typename TreeT>
233 Index64 memUsage(const TreeT& tree, bool threaded)
234 {
236  tree::DynamicNodeManager<const TreeT> nodeManager(tree);
237  nodeManager.reduceTopDown(op, threaded);
238  return op.count + sizeof(tree);
239 }
240 
241 
242 } // namespace tools
243 } // namespace OPENVDB_VERSION_NAME
244 } // namespace openvdb
245 
246 #endif // OPENVDB_TOOLS_COUNT_HAS_BEEN_INCLUDED
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
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
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:412
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:385
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:319
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:400
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:444
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:313
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
Definition: NodeManager.h:884
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition: NodeManager.h:1032
Index64 countActiveVoxels(const TreeT &tree, const CoordBBox &bbox, bool threaded=true)
Return the total number of active voxels in the tree that intersects a bounding box.
Definition: Count.h:220
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:233
uint64_t Index64
Definition: openvdb/Types.h:49
Definition: openvdb/Exceptions.h:13
A DynamicNodeManager operator to count active voxels in a tree that fall within a provided bounding b...
Definition: Count.h:82
void join(const ActiveVoxelCountBBoxOp &other)
Definition: Count.h:151
bool operator()(const NodeT &node, size_t)
Definition: Count.h:92
openvdb::Index64 count
Definition: Count.h:156
ActiveVoxelCountBBoxOp(const CoordBBox &bbox)
Definition: Count.h:85
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:126
ActiveVoxelCountBBoxOp(const ActiveVoxelCountBBoxOp &other, tbb::split)
Definition: Count.h:87
typename TreeType::LeafNodeType LeafT
Definition: Count.h:83
A DynamicNodeManager operator to count active voxels in a tree.
Definition: Count.h:47
void join(const ActiveVoxelCountOp &other)
Definition: Count.h:70
bool operator()(const NodeT &node, size_t)
Definition: Count.h:55
openvdb::Index64 count
Definition: Count.h:75
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:64
ActiveVoxelCountOp(const ActiveVoxelCountOp &, tbb::split)
Definition: Count.h:51
typename TreeType::LeafNodeType LeafT
Definition: Count.h:48
A DynamicNodeManager operator to sum the number of bytes of memory used.
Definition: Count.h:164
MemUsageOp(const MemUsageOp &, tbb::split)
Definition: Count.h:169
typename TreeType::RootNodeType RootT
Definition: Count.h:165
bool operator()(const NodeT &node, size_t)
Definition: Count.h:180
openvdb::Index64 count
Definition: Count.h:200
void join(const MemUsageOp &other)
Definition: Count.h:195
bool operator()(const RootT &root, size_t)
Definition: Count.h:172
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:189
typename TreeType::LeafNodeType LeafT
Definition: Count.h:166
#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:178