OpenVDB: Count.h Source File

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>
15 #include <openvdb/tree/NodeManager.h>
16
17 namespace openvdb {
18 OPENVDB_USE_VERSION_NAMESPACE
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>
46 struct ActiveVoxelCountOp
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>
81 struct ActiveVoxelCountBBoxOp
82 {
83 using LeafT = typename TreeType::LeafNodeType;
84
85 explicit ActiveVoxelCountBBoxOp(const CoordBBox& bbox)
86 : mBBox(bbox) { }
87 ActiveVoxelCountBBoxOp(const ActiveVoxelCountBBoxOp& other, tbb::split)
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
156 openvdb::Index64 count{0};
157 private:
158 CoordBBox mBBox;
159 }; // struct ActiveVoxelCountBBoxOp
160
162 template<typename TreeType>
163 struct MemUsageOp
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
200 openvdb::Index64 count{0};
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 {
212 count_internal::ActiveVoxelCountOp<TreeT> op;
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
225 count_internal::ActiveVoxelCountBBoxOp<TreeT> op(bbox);
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 {
235 count_internal::MemUsageOp<TreeT> op;
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.h
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
openvdb::v8_1::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
openvdb::v8_1::math::CoordBBox::empty
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
openvdb::v8_1::math::CoordBBox::hasOverlap
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:412
openvdb::v8_1::math::CoordBBox::volume
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:385
openvdb::v8_1::math::CoordBBox::inf
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:319
openvdb::v8_1::math::CoordBBox::isInside
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:400
openvdb::v8_1::math::CoordBBox::intersect
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:444
openvdb::v8_1::math::CoordBBox::createCube
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:313
openvdb::v8_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
openvdb::v8_1::tree::DynamicNodeManager
Definition: NodeManager.h:884
openvdb::v8_1::tree::DynamicNodeManager::reduceTopDown
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
openvdb::v8_1::tools::countActiveVoxels
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
openvdb::v8_1::tools::memUsage
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:233
openvdb::v8_1::Index64
uint64_t Index64
Definition: openvdb/Types.h:49
openvdb
Definition: openvdb/Exceptions.h:13
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp
A DynamicNodeManager operator to count active voxels in a tree that fall within a provided bounding b...
Definition: Count.h:82
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::join
void join(const ActiveVoxelCountBBoxOp &other)
Definition: Count.h:151
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::operator()
bool operator()(const NodeT &node, size_t)
Definition: Count.h:92
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::count
openvdb::Index64 count
Definition: Count.h:156
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::ActiveVoxelCountBBoxOp
ActiveVoxelCountBBoxOp(const CoordBBox &bbox)
Definition: Count.h:85
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::operator()
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:126
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::ActiveVoxelCountBBoxOp
ActiveVoxelCountBBoxOp(const ActiveVoxelCountBBoxOp &other, tbb::split)
Definition: Count.h:87
openvdb::v8_1::tools::count_internal::ActiveVoxelCountBBoxOp::LeafT
typename TreeType::LeafNodeType LeafT
Definition: Count.h:83
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp
A DynamicNodeManager operator to count active voxels in a tree.
Definition: Count.h:47
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::join
void join(const ActiveVoxelCountOp &other)
Definition: Count.h:70
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::ActiveVoxelCountOp
ActiveVoxelCountOp()=default
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::operator()
bool operator()(const NodeT &node, size_t)
Definition: Count.h:55
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::count
openvdb::Index64 count
Definition: Count.h:75
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::operator()
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:64
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::ActiveVoxelCountOp
ActiveVoxelCountOp(const ActiveVoxelCountOp &, tbb::split)
Definition: Count.h:51
openvdb::v8_1::tools::count_internal::ActiveVoxelCountOp::LeafT
typename TreeType::LeafNodeType LeafT
Definition: Count.h:48
openvdb::v8_1::tools::count_internal::MemUsageOp
A DynamicNodeManager operator to sum the number of bytes of memory used.
Definition: Count.h:164
openvdb::v8_1::tools::count_internal::MemUsageOp::MemUsageOp
MemUsageOp(const MemUsageOp &, tbb::split)
Definition: Count.h:169
openvdb::v8_1::tools::count_internal::MemUsageOp::RootT
typename TreeType::RootNodeType RootT
Definition: Count.h:165
openvdb::v8_1::tools::count_internal::MemUsageOp::operator()
bool operator()(const NodeT &node, size_t)
Definition: Count.h:180
openvdb::v8_1::tools::count_internal::MemUsageOp::count
openvdb::Index64 count
Definition: Count.h:200
openvdb::v8_1::tools::count_internal::MemUsageOp::join
void join(const MemUsageOp &other)
Definition: Count.h:195
openvdb::v8_1::tools::count_internal::MemUsageOp::operator()
bool operator()(const RootT &root, size_t)
Definition: Count.h:172
openvdb::v8_1::tools::count_internal::MemUsageOp::MemUsageOp
MemUsageOp()=default
openvdb::v8_1::tools::count_internal::MemUsageOp::operator()
bool operator()(const LeafT &leaf, size_t)
Definition: Count.h:189
openvdb::v8_1::tools::count_internal::MemUsageOp::LeafT
typename TreeType::LeafNodeType LeafT
Definition: Count.h:166
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178