OpenVDB: Tree.h Source File

OpenVDB 7.0.0

Tree.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
5
6 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
7 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
8
9 #include <openvdb/Types.h>
10 #include <openvdb/Metadata.h>
11 #include <openvdb/math/Math.h>
12 #include <openvdb/math/BBox.h>
13 #include <openvdb/util/Formats.h>
14 #include <openvdb/util/logging.h>
15 #include <openvdb/Platform.h>
16 #include "RootNode.h"
17 #include "InternalNode.h"
18 #include "LeafNode.h"
19 #include "TreeIterator.h"
20 #include "ValueAccessor.h"
21 #include <tbb/concurrent_hash_map.h>
22 #include <cstdint>
23 #include <iostream>
24 #include <mutex>
25 #include <sstream>
26 #include <vector>
27
28
29 namespace openvdb {
30 OPENVDB_USE_VERSION_NAMESPACE
31 namespace OPENVDB_VERSION_NAME {
32 namespace tree {
33
35 class OPENVDB_API TreeBase
36 {
37 public:
38 using Ptr = SharedPtr<TreeBase>;
39 using ConstPtr = SharedPtr<const TreeBase>;
40
41 TreeBase() = default;
42 TreeBase(const TreeBase&) = default;
43 TreeBase& operator=(const TreeBase&) = delete; // disallow assignment
44 virtual ~TreeBase() = default;
45
47 virtual const Name& type() const = 0;
48
50 virtual Name valueType() const = 0;
51
53 virtual TreeBase::Ptr copy() const = 0;
54
55 //
56 // Tree methods
57 //
60 virtual Metadata::Ptr getBackgroundValue() const { return Metadata::Ptr(); }
61
69 virtual bool evalLeafBoundingBox(CoordBBox& bbox) const = 0;
70
74 virtual bool evalLeafDim(Coord& dim) const = 0;
75
83 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const = 0;
84
88 virtual bool evalActiveVoxelDim(Coord& dim) const = 0;
89
90 virtual void getIndexRange(CoordBBox& bbox) const = 0;
91
97 virtual void clipUnallocatedNodes() = 0;
98 #if OPENVDB_ABI_VERSION_NUMBER >= 4
99 virtual Index32 unallocatedLeafCount() const = 0;
101 #endif
102
103
104 //
105 // Statistics
106 //
110 virtual Index treeDepth() const = 0;
112 virtual Index32 leafCount() const = 0;
113 #if OPENVDB_ABI_VERSION_NUMBER >= 7
114 virtual std::vector<Index32> nodeCount() const = 0;
118 #endif
119 virtual Index32 nonLeafCount() const = 0;
122 virtual Index64 activeLeafVoxelCount() const = 0;
124 virtual Index64 inactiveLeafVoxelCount() const = 0;
126 virtual Index64 activeVoxelCount() const = 0;
128 virtual Index64 inactiveVoxelCount() const = 0;
130 virtual Index64 activeTileCount() const = 0;
131
133 virtual Index64 memUsage() const { return 0; }
134
135
136 //
137 // I/O methods
138 //
142 virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
146 virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
147
149 virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false) = 0;
151 virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) = 0;
157 virtual void readNonresidentBuffers() const = 0;
159 virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const = 0;
160
168 virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
169 };
170
171
173
174
175 template<typename _RootNodeType>
176 class Tree: public TreeBase
177 {
178 public:
179 using Ptr = SharedPtr<Tree>;
180 using ConstPtr = SharedPtr<const Tree>;
181
182 using RootNodeType = _RootNodeType;
183 using ValueType = typename RootNodeType::ValueType;
184 using BuildType = typename RootNodeType::BuildType;
185 using LeafNodeType = typename RootNodeType::LeafNodeType;
186
187 static const Index DEPTH = RootNodeType::LEVEL + 1;
188
195 template<typename OtherValueType>
196 struct ValueConverter {
197 using Type = Tree<typename RootNodeType::template ValueConverter<OtherValueType>::Type>;
198 };
199
200
201 Tree() {}
202
203 Tree& operator=(const Tree&) = delete; // disallow assignment
204
206 Tree(const Tree& other): TreeBase(other), mRoot(other.mRoot)
207 {
208 }
209
216 template<typename OtherRootType>
217 explicit Tree(const Tree<OtherRootType>& other): TreeBase(other), mRoot(other.root())
218 {
219 }
220
231 template<typename OtherTreeType>
232 Tree(const OtherTreeType& other,
233 const ValueType& inactiveValue,
234 const ValueType& activeValue,
235 TopologyCopy):
236 TreeBase(other),
237 mRoot(other.root(), inactiveValue, activeValue, TopologyCopy())
238 {
239 }
240
252 template<typename OtherTreeType>
253 Tree(const OtherTreeType& other, const ValueType& background, TopologyCopy):
254 TreeBase(other),
255 mRoot(other.root(), background, TopologyCopy())
256 {
257 }
258
260 Tree(const ValueType& background): mRoot(background) {}
261
262 ~Tree() override { this->clear(); releaseAllAccessors(); }
263
265 TreeBase::Ptr copy() const override { return TreeBase::Ptr(new Tree(*this)); }
266
268 Name valueType() const override { return typeNameAsString<ValueType>(); }
269
271 static const Name& treeType();
273 const Name& type() const override { return this->treeType(); }
274
275 bool operator==(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
276 bool operator!=(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
277
279 RootNodeType& root() { return mRoot; }
281 const RootNodeType& root() const { return mRoot; }
283
284
285 //
286 // Tree methods
287 //
290 template<typename OtherRootNodeType>
291 bool hasSameTopology(const Tree<OtherRootNodeType>& other) const;
292
293 bool evalLeafBoundingBox(CoordBBox& bbox) const override;
294 bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const override;
295 bool evalActiveVoxelDim(Coord& dim) const override;
296 bool evalLeafDim(Coord& dim) const override;
297
301 static void getNodeLog2Dims(std::vector<Index>& dims);
302
303
304 //
305 // I/O methods
306 //
310 void readTopology(std::istream&, bool saveFloatAsHalf = false) override;
314 void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const override;
316 void readBuffers(std::istream&, bool saveFloatAsHalf = false) override;
318 void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) override;
324 void readNonresidentBuffers() const override;
326 void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const override;
327
328 void print(std::ostream& os = std::cout, int verboseLevel = 1) const override;
329
330
331 //
332 // Statistics
333 //
337 Index treeDepth() const override { return DEPTH; }
339 Index32 leafCount() const override { return mRoot.leafCount(); }
340 #if OPENVDB_ABI_VERSION_NUMBER >= 7
341 std::vector<Index32> nodeCount() const override
345 {
346 std::vector<Index32> vec(DEPTH, 0);
347 mRoot.nodeCount( vec );
348 return vec;// Named Return Value Optimization
349 }
350 #endif
351 Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); }
354 Index64 activeLeafVoxelCount() const override { return mRoot.onLeafVoxelCount(); }
356 Index64 inactiveLeafVoxelCount() const override { return mRoot.offLeafVoxelCount(); }
358 Index64 activeVoxelCount() const override { return mRoot.onVoxelCount(); }
360 Index64 inactiveVoxelCount() const override;
362 Index64 activeTileCount() const override { return mRoot.onTileCount(); }
363
365 void evalMinMax(ValueType &min, ValueType &max) const;
366
367 Index64 memUsage() const override { return sizeof(*this) + mRoot.memUsage(); }
368
369
370 //
371 // Voxel access methods (using signed indexing)
372 //
374 const ValueType& getValue(const Coord& xyz) const;
377 template<typename AccessT> const ValueType& getValue(const Coord& xyz, AccessT&) const;
378
382 int getValueDepth(const Coord& xyz) const;
383
385 void setActiveState(const Coord& xyz, bool on);
387 void setValueOnly(const Coord& xyz, const ValueType& value);
389 void setValueOn(const Coord& xyz);
391 void setValueOn(const Coord& xyz, const ValueType& value);
393 void setValue(const Coord& xyz, const ValueType& value);
396 template<typename AccessT> void setValue(const Coord& xyz, const ValueType& value, AccessT&);
398 void setValueOff(const Coord& xyz);
400 void setValueOff(const Coord& xyz, const ValueType& value);
401
420 template<typename ModifyOp>
421 void modifyValue(const Coord& xyz, const ModifyOp& op);
422
442 template<typename ModifyOp>
443 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
444
447 bool probeValue(const Coord& xyz, ValueType& value) const;
448
450 bool isValueOn(const Coord& xyz) const { return mRoot.isValueOn(xyz); }
452 bool isValueOff(const Coord& xyz) const { return !this->isValueOn(xyz); }
454 bool hasActiveTiles() const { return mRoot.hasActiveTiles(); }
455
457 void clip(const CoordBBox&);
463 void clipUnallocatedNodes() override;
464
465 #if OPENVDB_ABI_VERSION_NUMBER >= 4
466 Index32 unallocatedLeafCount() const override;
468 #endif
469
471 void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
480 void fill(const CoordBBox& bbox, const ValueType& value, bool active = true)
481 {
482 this->sparseFill(bbox, value, active);
483 }
485
493 void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
494
503 void voxelizeActiveTiles(bool threaded = true);
504
509 void prune(const ValueType& tolerance = zeroVal<ValueType>())
510 {
511 this->clearAllAccessors();
512 mRoot.prune(tolerance);
513 }
514
520 void addLeaf(LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
521
526 void addTile(Index level, const Coord& xyz, const ValueType& value, bool active);
527
532 template<typename NodeT>
533 NodeT* stealNode(const Coord& xyz, const ValueType& value, bool active);
534
540 LeafNodeType* touchLeaf(const Coord& xyz);
541
543 template<typename NodeType> NodeType* probeNode(const Coord& xyz);
546 template<typename NodeType> const NodeType* probeConstNode(const Coord& xyz) const;
547 template<typename NodeType> const NodeType* probeNode(const Coord& xyz) const;
549
551 LeafNodeType* probeLeaf(const Coord& xyz);
554 const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
555 const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
557
559 template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
582 template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
584
608 template<typename ArrayT>
609 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
610 template<typename ArrayT>
611 void stealNodes(ArrayT& array, const ValueType& value, bool state)
612 {
613 this->clearAllAccessors();
614 mRoot.stealNodes(array, value, state);
615 }
616
617 //
618 // Aux methods
619 //
622 bool empty() const { return mRoot.empty(); }
623
625 void clear();
626
628 void clearAllAccessors();
629
631 void attachAccessor(ValueAccessorBase<Tree, true>&) const;
634 void attachAccessor(ValueAccessorBase<const Tree, true>&) const;
636
638 void attachAccessor(ValueAccessorBase<Tree, false>&) const {}
640 void attachAccessor(ValueAccessorBase<const Tree, false>&) const {}
642
644 void releaseAccessor(ValueAccessorBase<Tree, true>&) const;
646 void releaseAccessor(ValueAccessorBase<const Tree, true>&) const;
648
650 void releaseAccessor(ValueAccessorBase<Tree, false>&) const {}
652 void releaseAccessor(ValueAccessorBase<const Tree, false>&) const {}
654
657 Metadata::Ptr getBackgroundValue() const override;
658
664 const ValueType& background() const { return mRoot.background(); }
665
667 void getIndexRange(CoordBBox& bbox) const override { mRoot.getIndexRange(bbox); }
668
676 void merge(Tree& other, MergePolicy = MERGE_ACTIVE_STATES);
677
691 template<typename OtherRootNodeType>
692 void topologyUnion(const Tree<OtherRootNodeType>& other);
693
707 template<typename OtherRootNodeType>
708 void topologyIntersection(const Tree<OtherRootNodeType>& other);
709
720 template<typename OtherRootNodeType>
721 void topologyDifference(const Tree<OtherRootNodeType>& other);
722
767 template<typename CombineOp>
768 void combine(Tree& other, CombineOp& op, bool prune = false);
769 #ifndef _MSC_VER
770 template<typename CombineOp>
771 void combine(Tree& other, const CombineOp& op, bool prune = false);
772 #endif
773
812 template<typename ExtendedCombineOp>
813 void combineExtended(Tree& other, ExtendedCombineOp& op, bool prune = false);
814 #ifndef _MSC_VER
815 template<typename ExtendedCombineOp>
816 void combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune = false);
817 #endif
818
847 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
848 void combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune = false);
849 #ifndef _MSC_VER
850 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
851 void combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune = false);
852 #endif
853
927 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
928 void combine2Extended(const Tree& a, const OtherTreeType& b, ExtendedCombineOp& op,
929 bool prune = false);
930 #ifndef _MSC_VER
931 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
932 void combine2Extended(const Tree& a, const OtherTreeType& b, const ExtendedCombineOp&,
933 bool prune = false);
934 #endif
935
976 template<typename BBoxOp> void visitActiveBBox(BBoxOp& op) const { mRoot.visitActiveBBox(op); }
977
1031 template<typename VisitorOp> void visit(VisitorOp& op);
1032 template<typename VisitorOp> void visit(const VisitorOp& op);
1033
1038 template<typename VisitorOp> void visit(VisitorOp& op) const;
1039 template<typename VisitorOp> void visit(const VisitorOp& op) const;
1040
1088 template<typename OtherTreeType, typename VisitorOp>
1089 void visit2(OtherTreeType& other, VisitorOp& op);
1090 template<typename OtherTreeType, typename VisitorOp>
1091 void visit2(OtherTreeType& other, const VisitorOp& op);
1092
1103 template<typename OtherTreeType, typename VisitorOp>
1104 void visit2(OtherTreeType& other, VisitorOp& op) const;
1105 template<typename OtherTreeType, typename VisitorOp>
1106 void visit2(OtherTreeType& other, const VisitorOp& op) const;
1107
1108
1109 //
1110 // Iteration
1111 //
1113 typename RootNodeType::ChildOnCIter beginRootChildren() const { return mRoot.cbeginChildOn(); }
1115 typename RootNodeType::ChildOnCIter cbeginRootChildren() const { return mRoot.cbeginChildOn(); }
1116 typename RootNodeType::ChildOnIter beginRootChildren() { return mRoot.beginChildOn(); }
1118
1120 typename RootNodeType::ChildOffCIter beginRootTiles() const { return mRoot.cbeginChildOff(); }
1122 typename RootNodeType::ChildOffCIter cbeginRootTiles() const { return mRoot.cbeginChildOff(); }
1123 typename RootNodeType::ChildOffIter beginRootTiles() { return mRoot.beginChildOff(); }
1125
1127 typename RootNodeType::ChildAllCIter beginRootDense() const { return mRoot.cbeginChildAll(); }
1129 typename RootNodeType::ChildAllCIter cbeginRootDense() const { return mRoot.cbeginChildAll(); }
1130 typename RootNodeType::ChildAllIter beginRootDense() { return mRoot.beginChildAll(); }
1132
1133
1135 using NodeIter = NodeIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
1137 using NodeCIter = NodeIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
1139
1141 using LeafIter = LeafIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
1143 using LeafCIter = LeafIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
1145
1147 NodeIter beginNode() { return NodeIter(*this); }
1149 NodeCIter beginNode() const { return NodeCIter(*this); }
1150 NodeCIter cbeginNode() const { return NodeCIter(*this); }
1152
1154 LeafIter beginLeaf() { return LeafIter(*this); }
1156 LeafCIter beginLeaf() const { return LeafCIter(*this); }
1157 LeafCIter cbeginLeaf() const { return LeafCIter(*this); }
1159
1160 using ValueAllIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueAllIter>;
1161 using ValueAllCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueAllCIter>;
1162 using ValueOnIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOnIter>;
1163 using ValueOnCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOnCIter>;
1164 using ValueOffIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOffIter>;
1165 using ValueOffCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOffCIter>;
1166
1168 ValueAllIter beginValueAll() { return ValueAllIter(*this); }
1170 ValueAllCIter beginValueAll() const { return ValueAllCIter(*this); }
1171 ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this); }
1173
1174 ValueOnIter beginValueOn() { return ValueOnIter(*this); }
1176 ValueOnCIter beginValueOn() const { return ValueOnCIter(*this); }
1177 ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this); }
1179
1180 ValueOffIter beginValueOff() { return ValueOffIter(*this); }
1182 ValueOffCIter beginValueOff() const { return ValueOffCIter(*this); }
1183 ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this); }
1185
1188 template<typename IterT> IterT begin();
1191 template<typename CIterT> CIterT cbegin() const;
1192
1193
1194 protected:
1195 using AccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<Tree, true>*, bool>;
1196 using ConstAccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<const Tree, true>*, bool>;
1197
1200 void releaseAllAccessors();
1201
1202 // TBB body object used to deallocates nodes in parallel.
1203 template<typename NodeType>
1204 struct DeallocateNodes {
1205 DeallocateNodes(std::vector<NodeType*>& nodes)
1206 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1207 void operator()(const tbb::blocked_range<size_t>& range) const {
1208 for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
1209 delete mNodes[n]; mNodes[n] = nullptr;
1210 }
1211 }
1212 NodeType ** const mNodes;
1213 };
1214
1215 //
1216 // Data members
1217 //
1218 RootNodeType mRoot; // root node of the tree
1219 mutable AccessorRegistry mAccessorRegistry;
1220 mutable ConstAccessorRegistry mConstAccessorRegistry;
1221
1222 static std::unique_ptr<const Name> sTreeTypeName;
1223 }; // end of Tree class
1224
1225 template<typename _RootNodeType>
1226 std::unique_ptr<const Name> Tree<_RootNodeType>::sTreeTypeName;
1227
1228
1233 template<typename T, Index N1=4, Index N2=3>
1234 struct Tree3 {
1235 using Type = Tree<RootNode<InternalNode<LeafNode<T, N2>, N1>>>;
1236 };
1237
1238
1243 template<typename T, Index N1=5, Index N2=4, Index N3=3>
1244 struct Tree4 {
1245 using Type = Tree<RootNode<InternalNode<InternalNode<LeafNode<T, N3>, N2>, N1>>>;
1246 };
1247
1252 template<typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1253 struct Tree5 {
1254 using Type =
1255 Tree<RootNode<InternalNode<InternalNode<InternalNode<LeafNode<T, N4>, N3>, N2>, N1>>>;
1256 };
1257
1258
1260
1261
1262 inline void
1263 TreeBase::readTopology(std::istream& is, bool /*saveFloatAsHalf*/)
1264 {
1265 int32_t bufferCount;
1266 is.read(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1267 if (bufferCount != 1) OPENVDB_LOG_WARN("multi-buffer trees are no longer supported");
1268 }
1269
1270
1271 inline void
1272 TreeBase::writeTopology(std::ostream& os, bool /*saveFloatAsHalf*/) const
1273 {
1274 int32_t bufferCount = 1;
1275 os.write(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1276 }
1277
1278
1279 inline void
1280 TreeBase::print(std::ostream& os, int /*verboseLevel*/) const
1281 {
1282 os << " Tree Type: " << type()
1283 << " Active Voxel Count: " << activeVoxelCount() << std::endl
1284 << " Active tile Count: " << activeTileCount() << std::endl
1285 << " Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1286 << " Leaf Node Count: " << leafCount() << std::endl
1287 << " Non-leaf Node Count: " << nonLeafCount() << std::endl;
1288 }
1289
1290
1292
1293
1294 //
1295 // Type traits for tree iterators
1296 //
1297
1300 template<typename TreeT, typename IterT> struct TreeIterTraits;
1301
1302 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1303 static typename TreeT::RootNodeType::ChildOnIter begin(TreeT& tree) {
1304 return tree.beginRootChildren();
1305 }
1306 };
1307
1308 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1309 static typename TreeT::RootNodeType::ChildOnCIter begin(const TreeT& tree) {
1310 return tree.cbeginRootChildren();
1311 }
1312 };
1313
1314 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1315 static typename TreeT::RootNodeType::ChildOffIter begin(TreeT& tree) {
1316 return tree.beginRootTiles();
1317 }
1318 };
1319
1320 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1321 static typename TreeT::RootNodeType::ChildOffCIter begin(const TreeT& tree) {
1322 return tree.cbeginRootTiles();
1323 }
1324 };
1325
1326 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1327 static typename TreeT::RootNodeType::ChildAllIter begin(TreeT& tree) {
1328 return tree.beginRootDense();
1329 }
1330 };
1331
1332 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1333 static typename TreeT::RootNodeType::ChildAllCIter begin(const TreeT& tree) {
1334 return tree.cbeginRootDense();
1335 }
1336 };
1337
1338 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeIter> {
1339 static typename TreeT::NodeIter begin(TreeT& tree) { return tree.beginNode(); }
1340 };
1341
1342 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeCIter> {
1343 static typename TreeT::NodeCIter begin(const TreeT& tree) { return tree.cbeginNode(); }
1344 };
1345
1346 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafIter> {
1347 static typename TreeT::LeafIter begin(TreeT& tree) { return tree.beginLeaf(); }
1348 };
1349
1350 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafCIter> {
1351 static typename TreeT::LeafCIter begin(const TreeT& tree) { return tree.cbeginLeaf(); }
1352 };
1353
1354 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnIter> {
1355 static typename TreeT::ValueOnIter begin(TreeT& tree) { return tree.beginValueOn(); }
1356 };
1357
1358 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1359 static typename TreeT::ValueOnCIter begin(const TreeT& tree) { return tree.cbeginValueOn(); }
1360 };
1361
1362 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1363 static typename TreeT::ValueOffIter begin(TreeT& tree) { return tree.beginValueOff(); }
1364 };
1365
1366 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1367 static typename TreeT::ValueOffCIter begin(const TreeT& tree) { return tree.cbeginValueOff(); }
1368 };
1369
1370 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1371 static typename TreeT::ValueAllIter begin(TreeT& tree) { return tree.beginValueAll(); }
1372 };
1373
1374 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1375 static typename TreeT::ValueAllCIter begin(const TreeT& tree) { return tree.cbeginValueAll(); }
1376 };
1377
1378
1379 template<typename RootNodeType>
1380 template<typename IterT>
1381 inline IterT
1382 Tree<RootNodeType>::begin()
1383 {
1384 return TreeIterTraits<Tree, IterT>::begin(*this);
1385 }
1386
1387
1388 template<typename RootNodeType>
1389 template<typename IterT>
1390 inline IterT
1391 Tree<RootNodeType>::cbegin() const
1392 {
1393 return TreeIterTraits<Tree, IterT>::begin(*this);
1394 }
1395
1396
1398
1399
1400 template<typename RootNodeType>
1401 void
1402 Tree<RootNodeType>::readTopology(std::istream& is, bool saveFloatAsHalf)
1403 {
1404 this->clearAllAccessors();
1405 TreeBase::readTopology(is, saveFloatAsHalf);
1406 mRoot.readTopology(is, saveFloatAsHalf);
1407 }
1408
1409
1410 template<typename RootNodeType>
1411 void
1412 Tree<RootNodeType>::writeTopology(std::ostream& os, bool saveFloatAsHalf) const
1413 {
1414 TreeBase::writeTopology(os, saveFloatAsHalf);
1415 mRoot.writeTopology(os, saveFloatAsHalf);
1416 }
1417
1418
1419 template<typename RootNodeType>
1420 inline void
1421 Tree<RootNodeType>::readBuffers(std::istream &is, bool saveFloatAsHalf)
1422 {
1423 this->clearAllAccessors();
1424 mRoot.readBuffers(is, saveFloatAsHalf);
1425 }
1426
1427
1428 template<typename RootNodeType>
1429 inline void
1430 Tree<RootNodeType>::readBuffers(std::istream &is, const CoordBBox& bbox, bool saveFloatAsHalf)
1431 {
1432 this->clearAllAccessors();
1433 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1434 }
1435
1436
1437 template<typename RootNodeType>
1438 inline void
1439 Tree<RootNodeType>::readNonresidentBuffers() const
1440 {
1441 for (LeafCIter it = this->cbeginLeaf(); it; ++it) {
1442 // Retrieving the value of a leaf voxel forces loading of the leaf node's voxel buffer.
1443 it->getValue(Index(0));
1444 }
1445 }
1446
1447
1448 template<typename RootNodeType>
1449 inline void
1450 Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
1451 {
1452 mRoot.writeBuffers(os, saveFloatAsHalf);
1453 }
1454
1455
1456 template<typename RootNodeType>
1457 inline void
1458 Tree<RootNodeType>::clear()
1459 {
1460 std::vector<LeafNodeType*> leafnodes;
1461 this->stealNodes(leafnodes);
1462
1463 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1464 DeallocateNodes<LeafNodeType>(leafnodes));
1465
1466 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1467 this->stealNodes(internalNodes);
1468
1469 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1470 DeallocateNodes<typename RootNodeType::ChildNodeType>(internalNodes));
1471
1472 mRoot.clear();
1473
1474 this->clearAllAccessors();
1475 }
1476
1477
1479
1480
1481 template<typename RootNodeType>
1482 inline void
1483 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<Tree, true>& accessor) const
1484 {
1485 typename AccessorRegistry::accessor a;
1486 mAccessorRegistry.insert(a, &accessor);
1487 }
1488
1489
1490 template<typename RootNodeType>
1491 inline void
1492 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1493 {
1494 typename ConstAccessorRegistry::accessor a;
1495 mConstAccessorRegistry.insert(a, &accessor);
1496 }
1497
1498
1499 template<typename RootNodeType>
1500 inline void
1501 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<Tree, true>& accessor) const
1502 {
1503 mAccessorRegistry.erase(&accessor);
1504 }
1505
1506
1507 template<typename RootNodeType>
1508 inline void
1509 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1510 {
1511 mConstAccessorRegistry.erase(&accessor);
1512 }
1513
1514
1515 template<typename RootNodeType>
1516 inline void
1517 Tree<RootNodeType>::clearAllAccessors()
1518 {
1519 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1520 it != mAccessorRegistry.end(); ++it)
1521 {
1522 if (it->first) it->first->clear();
1523 }
1524
1525 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1526 it != mConstAccessorRegistry.end(); ++it)
1527 {
1528 if (it->first) it->first->clear();
1529 }
1530 }
1531
1532
1533 template<typename RootNodeType>
1534 inline void
1535 Tree<RootNodeType>::releaseAllAccessors()
1536 {
1537 mAccessorRegistry.erase(nullptr);
1538 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1539 it != mAccessorRegistry.end(); ++it)
1540 {
1541 it->first->release();
1542 }
1543 mAccessorRegistry.clear();
1544
1545 mAccessorRegistry.erase(nullptr);
1546 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1547 it != mConstAccessorRegistry.end(); ++it)
1548 {
1549 it->first->release();
1550 }
1551 mConstAccessorRegistry.clear();
1552 }
1553
1554
1556
1557
1558 template<typename RootNodeType>
1559 inline const typename RootNodeType::ValueType&
1560 Tree<RootNodeType>::getValue(const Coord& xyz) const
1561 {
1562 return mRoot.getValue(xyz);
1563 }
1564
1565
1566 template<typename RootNodeType>
1567 template<typename AccessT>
1568 inline const typename RootNodeType::ValueType&
1569 Tree<RootNodeType>::getValue(const Coord& xyz, AccessT& accessor) const
1570 {
1571 return accessor.getValue(xyz);
1572 }
1573
1574
1575 template<typename RootNodeType>
1576 inline int
1577 Tree<RootNodeType>::getValueDepth(const Coord& xyz) const
1578 {
1579 return mRoot.getValueDepth(xyz);
1580 }
1581
1582
1583 template<typename RootNodeType>
1584 inline void
1585 Tree<RootNodeType>::setValueOff(const Coord& xyz)
1586 {
1587 mRoot.setValueOff(xyz);
1588 }
1589
1590
1591 template<typename RootNodeType>
1592 inline void
1593 Tree<RootNodeType>::setValueOff(const Coord& xyz, const ValueType& value)
1594 {
1595 mRoot.setValueOff(xyz, value);
1596 }
1597
1598
1599 template<typename RootNodeType>
1600 inline void
1601 Tree<RootNodeType>::setActiveState(const Coord& xyz, bool on)
1602 {
1603 mRoot.setActiveState(xyz, on);
1604 }
1605
1606
1607 template<typename RootNodeType>
1608 inline void
1609 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value)
1610 {
1611 mRoot.setValueOn(xyz, value);
1612 }
1613
1614 template<typename RootNodeType>
1615 inline void
1616 Tree<RootNodeType>::setValueOnly(const Coord& xyz, const ValueType& value)
1617 {
1618 mRoot.setValueOnly(xyz, value);
1619 }
1620
1621 template<typename RootNodeType>
1622 template<typename AccessT>
1623 inline void
1624 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value, AccessT& accessor)
1625 {
1626 accessor.setValue(xyz, value);
1627 }
1628
1629
1630 template<typename RootNodeType>
1631 inline void
1632 Tree<RootNodeType>::setValueOn(const Coord& xyz)
1633 {
1634 mRoot.setActiveState(xyz, true);
1635 }
1636
1637
1638 template<typename RootNodeType>
1639 inline void
1640 Tree<RootNodeType>::setValueOn(const Coord& xyz, const ValueType& value)
1641 {
1642 mRoot.setValueOn(xyz, value);
1643 }
1644
1645
1646 template<typename RootNodeType>
1647 template<typename ModifyOp>
1648 inline void
1649 Tree<RootNodeType>::modifyValue(const Coord& xyz, const ModifyOp& op)
1650 {
1651 mRoot.modifyValue(xyz, op);
1652 }
1653
1654
1655 template<typename RootNodeType>
1656 template<typename ModifyOp>
1657 inline void
1658 Tree<RootNodeType>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1659 {
1660 mRoot.modifyValueAndActiveState(xyz, op);
1661 }
1662
1663
1664 template<typename RootNodeType>
1665 inline bool
1666 Tree<RootNodeType>::probeValue(const Coord& xyz, ValueType& value) const
1667 {
1668 return mRoot.probeValue(xyz, value);
1669 }
1670
1671
1673
1674
1675 template<typename RootNodeType>
1676 inline void
1677 Tree<RootNodeType>::addTile(Index level, const Coord& xyz,
1678 const ValueType& value, bool active)
1679 {
1680 mRoot.addTile(level, xyz, value, active);
1681 }
1682
1683
1684 template<typename RootNodeType>
1685 template<typename NodeT>
1686 inline NodeT*
1687 Tree<RootNodeType>::stealNode(const Coord& xyz, const ValueType& value, bool active)
1688 {
1689 this->clearAllAccessors();
1690 return mRoot.template stealNode<NodeT>(xyz, value, active);
1691 }
1692
1693
1694 template<typename RootNodeType>
1695 inline typename RootNodeType::LeafNodeType*
1696 Tree<RootNodeType>::touchLeaf(const Coord& xyz)
1697 {
1698 return mRoot.touchLeaf(xyz);
1699 }
1700
1701
1702 template<typename RootNodeType>
1703 inline typename RootNodeType::LeafNodeType*
1704 Tree<RootNodeType>::probeLeaf(const Coord& xyz)
1705 {
1706 return mRoot.probeLeaf(xyz);
1707 }
1708
1709
1710 template<typename RootNodeType>
1711 inline const typename RootNodeType::LeafNodeType*
1712 Tree<RootNodeType>::probeConstLeaf(const Coord& xyz) const
1713 {
1714 return mRoot.probeConstLeaf(xyz);
1715 }
1716
1717
1718 template<typename RootNodeType>
1719 template<typename NodeType>
1720 inline NodeType*
1721 Tree<RootNodeType>::probeNode(const Coord& xyz)
1722 {
1723 return mRoot.template probeNode<NodeType>(xyz);
1724 }
1725
1726
1727 template<typename RootNodeType>
1728 template<typename NodeType>
1729 inline const NodeType*
1730 Tree<RootNodeType>::probeNode(const Coord& xyz) const
1731 {
1732 return this->template probeConstNode<NodeType>(xyz);
1733 }
1734
1735
1736 template<typename RootNodeType>
1737 template<typename NodeType>
1738 inline const NodeType*
1739 Tree<RootNodeType>::probeConstNode(const Coord& xyz) const
1740 {
1741 return mRoot.template probeConstNode<NodeType>(xyz);
1742 }
1743
1744
1746
1747
1748 template<typename RootNodeType>
1749 inline void
1750 Tree<RootNodeType>::clip(const CoordBBox& bbox)
1751 {
1752 this->clearAllAccessors();
1753 return mRoot.clip(bbox);
1754 }
1755
1756
1757 template<typename RootNodeType>
1758 inline void
1759 Tree<RootNodeType>::clipUnallocatedNodes()
1760 {
1761 this->clearAllAccessors();
1762 for (LeafIter it = this->beginLeaf(); it; ) {
1763 const LeafNodeType* leaf = it.getLeaf();
1764 ++it; // advance the iterator before deleting the leaf node
1765 if (!leaf->isAllocated()) {
1766 this->addTile(/*level=*/0, leaf->origin(), this->background(), /*active=*/false);
1767 }
1768 }
1769 }
1770
1771 #if OPENVDB_ABI_VERSION_NUMBER >= 4
1772 template<typename RootNodeType>
1773 inline Index32
1774 Tree<RootNodeType>::unallocatedLeafCount() const
1775 {
1776 Index32 sum = 0;
1777 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
1778 return sum;
1779 }
1780 #endif
1781
1782
1783 template<typename RootNodeType>
1784 inline void
1785 Tree<RootNodeType>::sparseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1786 {
1787 this->clearAllAccessors();
1788 return mRoot.sparseFill(bbox, value, active);
1789 }
1790
1791
1792 template<typename RootNodeType>
1793 inline void
1794 Tree<RootNodeType>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1795 {
1796 this->clearAllAccessors();
1797 return mRoot.denseFill(bbox, value, active);
1798 }
1799
1800
1801 template<typename RootNodeType>
1802 inline void
1803 Tree<RootNodeType>::voxelizeActiveTiles(bool threaded)
1804 {
1805 this->clearAllAccessors();
1806 mRoot.voxelizeActiveTiles(threaded);
1807 }
1808
1809
1810 template<typename RootNodeType>
1811 Metadata::Ptr
1812 Tree<RootNodeType>::getBackgroundValue() const
1813 {
1814 Metadata::Ptr result;
1815 if (Metadata::isRegisteredType(valueType())) {
1816 using MetadataT = TypedMetadata<ValueType>;
1817 result = Metadata::createMetadata(valueType());
1818 if (result->typeName() == MetadataT::staticTypeName()) {
1819 MetadataT* m = static_cast<MetadataT*>(result.get());
1820 m->value() = mRoot.background();
1821 }
1822 }
1823 return result;
1824 }
1825
1826
1828
1829
1830 template<typename RootNodeType>
1831 inline void
1832 Tree<RootNodeType>::merge(Tree& other, MergePolicy policy)
1833 {
1834 this->clearAllAccessors();
1835 other.clearAllAccessors();
1836 switch (policy) {
1837 case MERGE_ACTIVE_STATES:
1838 mRoot.template merge<MERGE_ACTIVE_STATES>(other.mRoot); break;
1839 case MERGE_NODES:
1840 mRoot.template merge<MERGE_NODES>(other.mRoot); break;
1841 case MERGE_ACTIVE_STATES_AND_NODES:
1842 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.mRoot); break;
1843 }
1844 }
1845
1846
1847 template<typename RootNodeType>
1848 template<typename OtherRootNodeType>
1849 inline void
1850 Tree<RootNodeType>::topologyUnion(const Tree<OtherRootNodeType>& other)
1851 {
1852 this->clearAllAccessors();
1853 mRoot.topologyUnion(other.root());
1854 }
1855
1856 template<typename RootNodeType>
1857 template<typename OtherRootNodeType>
1858 inline void
1859 Tree<RootNodeType>::topologyIntersection(const Tree<OtherRootNodeType>& other)
1860 {
1861 this->clearAllAccessors();
1862 mRoot.topologyIntersection(other.root());
1863 }
1864
1865 template<typename RootNodeType>
1866 template<typename OtherRootNodeType>
1867 inline void
1868 Tree<RootNodeType>::topologyDifference(const Tree<OtherRootNodeType>& other)
1869 {
1870 this->clearAllAccessors();
1871 mRoot.topologyDifference(other.root());
1872 }
1873
1875
1876
1879 template<typename AValueT, typename CombineOp, typename BValueT = AValueT>
1880 struct CombineOpAdapter
1881 {
1882 CombineOpAdapter(CombineOp& _op): op(_op) {}
1883
1884 void operator()(CombineArgs<AValueT, BValueT>& args) const {
1885 op(args.a(), args.b(), args.result());
1886 }
1887
1888 CombineOp& op;
1889 };
1890
1891
1892 template<typename RootNodeType>
1893 template<typename CombineOp>
1894 inline void
1895 Tree<RootNodeType>::combine(Tree& other, CombineOp& op, bool prune)
1896 {
1897 CombineOpAdapter<ValueType, CombineOp> extendedOp(op);
1898 this->combineExtended(other, extendedOp, prune);
1899 }
1900
1901
1904 #ifndef _MSC_VER
1905 template<typename RootNodeType>
1906 template<typename CombineOp>
1907 inline void
1908 Tree<RootNodeType>::combine(Tree& other, const CombineOp& op, bool prune)
1909 {
1910 CombineOpAdapter<ValueType, const CombineOp> extendedOp(op);
1911 this->combineExtended(other, extendedOp, prune);
1912 }
1913 #endif
1914
1915
1916 template<typename RootNodeType>
1917 template<typename ExtendedCombineOp>
1918 inline void
1919 Tree<RootNodeType>::combineExtended(Tree& other, ExtendedCombineOp& op, bool prune)
1920 {
1921 this->clearAllAccessors();
1922 mRoot.combine(other.root(), op, prune);
1923 }
1924
1925
1928 #ifndef _MSC_VER
1929 template<typename RootNodeType>
1930 template<typename ExtendedCombineOp>
1931 inline void
1932 Tree<RootNodeType>::combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune)
1933 {
1934 this->clearAllAccessors();
1935 mRoot.template combine<const ExtendedCombineOp>(other.mRoot, op, prune);
1936 }
1937 #endif
1938
1939
1940 template<typename RootNodeType>
1941 template<typename CombineOp, typename OtherTreeType>
1942 inline void
1943 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune)
1944 {
1945 CombineOpAdapter<ValueType, CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1946 this->combine2Extended(a, b, extendedOp, prune);
1947 }
1948
1949
1952 #ifndef _MSC_VER
1953 template<typename RootNodeType>
1954 template<typename CombineOp, typename OtherTreeType>
1955 inline void
1956 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune)
1957 {
1958 CombineOpAdapter<ValueType, const CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1959 this->combine2Extended(a, b, extendedOp, prune);
1960 }
1961 #endif
1962
1963
1964 template<typename RootNodeType>
1965 template<typename ExtendedCombineOp, typename OtherTreeType>
1966 inline void
1967 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1968 ExtendedCombineOp& op, bool prune)
1969 {
1970 this->clearAllAccessors();
1971 mRoot.combine2(a.root(), b.root(), op, prune);
1972 }
1973
1974
1978 #ifndef _MSC_VER
1979 template<typename RootNodeType>
1980 template<typename ExtendedCombineOp, typename OtherTreeType>
1981 inline void
1982 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1983 const ExtendedCombineOp& op, bool prune)
1984 {
1985 this->clearAllAccessors();
1986 mRoot.template combine2<const ExtendedCombineOp>(a.root(), b.root(), op, prune);
1987 }
1988 #endif
1989
1990
1992
1993
1994 template<typename RootNodeType>
1995 template<typename VisitorOp>
1996 inline void
1997 Tree<RootNodeType>::visit(VisitorOp& op)
1998 {
1999 this->clearAllAccessors();
2000 mRoot.template visit<VisitorOp>(op);
2001 }
2002
2003
2004 template<typename RootNodeType>
2005 template<typename VisitorOp>
2006 inline void
2007 Tree<RootNodeType>::visit(VisitorOp& op) const
2008 {
2009 mRoot.template visit<VisitorOp>(op);
2010 }
2011
2012
2015 template<typename RootNodeType>
2016 template<typename VisitorOp>
2017 inline void
2018 Tree<RootNodeType>::visit(const VisitorOp& op)
2019 {
2020 this->clearAllAccessors();
2021 mRoot.template visit<const VisitorOp>(op);
2022 }
2023
2024
2027 template<typename RootNodeType>
2028 template<typename VisitorOp>
2029 inline void
2030 Tree<RootNodeType>::visit(const VisitorOp& op) const
2031 {
2032 mRoot.template visit<const VisitorOp>(op);
2033 }
2034
2035
2037
2038
2039 template<typename RootNodeType>
2040 template<typename OtherTreeType, typename VisitorOp>
2041 inline void
2042 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op)
2043 {
2044 this->clearAllAccessors();
2045 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2046 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2047 }
2048
2049
2050 template<typename RootNodeType>
2051 template<typename OtherTreeType, typename VisitorOp>
2052 inline void
2053 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op) const
2054 {
2055 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2056 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2057 }
2058
2059
2062 template<typename RootNodeType>
2063 template<typename OtherTreeType, typename VisitorOp>
2064 inline void
2065 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op)
2066 {
2067 this->clearAllAccessors();
2068 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2069 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2070 }
2071
2072
2075 template<typename RootNodeType>
2076 template<typename OtherTreeType, typename VisitorOp>
2077 inline void
2078 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op) const
2079 {
2080 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2081 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2082 }
2083
2084
2086
2087
2088 template<typename RootNodeType>
2089 inline const Name&
2090 Tree<RootNodeType>::treeType()
2091 {
2092 static std::once_flag once;
2093 std::call_once(once, []()
2094 {
2095 std::vector<Index> dims;
2096 Tree::getNodeLog2Dims(dims);
2097 std::ostringstream ostr;
2098 ostr << "Tree_" << typeNameAsString<BuildType>();
2099 for (size_t i = 1, N = dims.size(); i < N; ++i) { // start from 1 to skip the RootNode
2100 ostr << "_" << dims[i];
2101 }
2102 sTreeTypeName.reset(new Name(ostr.str()));
2103 });
2104 return *sTreeTypeName;
2105 }
2106
2107
2108 template<typename RootNodeType>
2109 template<typename OtherRootNodeType>
2110 inline bool
2111 Tree<RootNodeType>::hasSameTopology(const Tree<OtherRootNodeType>& other) const
2112 {
2113 return mRoot.hasSameTopology(other.root());
2114 }
2115
2116
2117 template<typename RootNodeType>
2118 Index64
2119 Tree<RootNodeType>::inactiveVoxelCount() const
2120 {
2121 Coord dim(0, 0, 0);
2122 this->evalActiveVoxelDim(dim);
2123 const Index64
2124 totalVoxels = dim.x() * dim.y() * dim.z(),
2125 activeVoxels = this->activeVoxelCount();
2126 assert(totalVoxels >= activeVoxels);
2127 return totalVoxels - activeVoxels;
2128 }
2129
2130
2131 template<typename RootNodeType>
2132 inline bool
2133 Tree<RootNodeType>::evalLeafBoundingBox(CoordBBox& bbox) const
2134 {
2135 bbox.reset(); // default invalid bbox
2136
2137 if (this->empty()) return false; // empty
2138
2139 mRoot.evalActiveBoundingBox(bbox, false);
2140
2141 return true;// not empty
2142 }
2143
2144 template<typename RootNodeType>
2145 inline bool
2146 Tree<RootNodeType>::evalActiveVoxelBoundingBox(CoordBBox& bbox) const
2147 {
2148 bbox.reset(); // default invalid bbox
2149
2150 if (this->empty()) return false; // empty
2151
2152 mRoot.evalActiveBoundingBox(bbox, true);
2153
2154 return true;// not empty
2155 }
2156
2157
2158 template<typename RootNodeType>
2159 inline bool
2160 Tree<RootNodeType>::evalActiveVoxelDim(Coord& dim) const
2161 {
2162 CoordBBox bbox;
2163 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2164 dim = bbox.extents();
2165 return notEmpty;
2166 }
2167
2168
2169 template<typename RootNodeType>
2170 inline bool
2171 Tree<RootNodeType>::evalLeafDim(Coord& dim) const
2172 {
2173 CoordBBox bbox;
2174 bool notEmpty = this->evalLeafBoundingBox(bbox);
2175 dim = bbox.extents();
2176 return notEmpty;
2177 }
2178
2179
2180 template<typename RootNodeType>
2181 inline void
2182 Tree<RootNodeType>::evalMinMax(ValueType& minVal, ValueType& maxVal) const
2183 {
2185 minVal = maxVal = zeroVal<ValueType>();
2186 if (ValueOnCIter iter = this->cbeginValueOn()) {
2187 minVal = maxVal = *iter;
2188 for (++iter; iter; ++iter) {
2189 const ValueType& val = *iter;
2190 if (val < minVal) minVal = val;
2191 if (val > maxVal) maxVal = val;
2192 }
2193 }
2194 }
2195
2196
2197 template<typename RootNodeType>
2198 inline void
2199 Tree<RootNodeType>::getNodeLog2Dims(std::vector<Index>& dims)
2200 {
2201 dims.clear();
2202 RootNodeType::getNodeLog2Dims(dims);
2203 }
2204
2205
2206 template<typename RootNodeType>
2207 inline void
2208 Tree<RootNodeType>::print(std::ostream& os, int verboseLevel) const
2209 {
2210 if (verboseLevel <= 0) return;
2211
2213 struct OnExit {
2214 std::ostream& os;
2215 std::streamsize savedPrecision;
2216 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2217 ~OnExit() { os.precision(savedPrecision); }
2218 };
2219 OnExit restorePrecision(os);
2220
2221 std::vector<Index> dims;
2222 Tree::getNodeLog2Dims(dims);// leaf is the last element
2223
2224 os << "Information about Tree:\n"
2225 << " Type: " << this->type() << "\n";
2226
2227 os << " Configuration:\n";
2228
2229 if (verboseLevel <= 1) {
2230 // Print node types and sizes.
2231 os << " Root(" << mRoot.getTableSize() << ")";
2232 if (dims.size() > 1) {
2233 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2234 os << ", Internal(" << (1 << dims[i]) << "^3)";
2235 }
2236 os << ", Leaf(" << (1 << dims.back()) << "^3)\n";
2237 }
2238 os << " Background value: " << mRoot.background() << "\n";
2239 return;
2240 }
2241
2242 // The following is tree information that is expensive to extract.
2243
2244 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2245 if (verboseLevel > 3) {
2246 // This forces loading of all non-resident nodes.
2247 this->evalMinMax(minVal, maxVal);
2248 }
2249
2250 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2251 const auto nodeCount = this->nodeCount();//fast
2252 const Index32 leafCount = nodeCount.front();// leaf is the first element
2253 #else
2254 std::vector<Index64> nodeCount(dims.size());
2255 for (NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);//slow
2256 const Index64 leafCount = *nodeCount.rbegin();// leaf is the last element
2257 #endif
2258 assert(dims.size() == nodeCount.size());
2259
2260 Index64 totalNodeCount = 0;
2261 for (size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2262
2263 // Print node types, counts and sizes.
2264 os << " Root(1 x " << mRoot.getTableSize() << ")";
2265 if (dims.size() >= 2) {
2266 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2267 #if OPENVDB_ABI_VERSION_NUMBER >= 7
2268 os << ", Internal(" << util::formattedInt(nodeCount[N - i]);
2269 #else
2270 os << ", Internal(" << util::formattedInt(nodeCount[i]);
2271 #endif
2272 os << " x " << (1 << dims[i]) << "^3)";
2273 }
2274 os << ", Leaf(" << util::formattedInt(leafCount);
2275 os << " x " << (1 << dims.back()) << "^3)\n";
2276 }
2277 os << " Background value: " << mRoot.background() << "\n";
2278
2279 // Statistics of topology and values
2280
2281 if (verboseLevel > 3) {
2282 os << " Min value: " << minVal << "\n";
2283 os << " Max value: " << maxVal << "\n";
2284 }
2285
2286 const Index64
2287 numActiveVoxels = this->activeVoxelCount(),
2288 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2289 numActiveTiles = this->activeTileCount();
2290
2291 os << " Number of active voxels: " << util::formattedInt(numActiveVoxels) << "\n";
2292 os << " Number of active tiles: " << util::formattedInt(numActiveTiles) << "\n";
2293
2294 Coord dim(0, 0, 0);
2295 Index64 totalVoxels = 0;
2296 if (numActiveVoxels) { // nonempty
2297 CoordBBox bbox;
2298 this->evalActiveVoxelBoundingBox(bbox);
2299 dim = bbox.extents();
2300 totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2301
2302 os << " Bounding box of active voxels: " << bbox << "\n";
2303 os << " Dimensions of active voxels: "
2304 << dim[0] << " x " << dim[1] << " x " << dim[2] << "\n";
2305
2306 const double activeRatio = (100.0 * double(numActiveVoxels)) / double(totalVoxels);
2307 os << " Percentage of active voxels: " << std::setprecision(3) << activeRatio << "%\n";
2308
2309 if (leafCount > 0) {
2310 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2311 / (double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2312 os << " Average leaf node fill ratio: " << fillRatio << "%\n";
2313 }
2314
2315 if (verboseLevel > 2) {
2316 Index64 sum = 0;// count the number of unallocated leaf nodes
2317 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
2318 os << " Number of unallocated nodes: "
2319 << util::formattedInt(sum) << " ("
2320 << (100.0 * double(sum) / double(totalNodeCount)) << "%)\n";
2321 }
2322 } else {
2323 os << " Tree is empty!\n";
2324 }
2325 os << std::flush;
2326
2327 if (verboseLevel == 2) return;
2328
2329 // Memory footprint in bytes
2330 const Index64
2331 actualMem = this->memUsage(),
2332 denseMem = sizeof(ValueType) * totalVoxels,
2333 voxelsMem = sizeof(ValueType) * numActiveLeafVoxels;
2335
2336 os << "Memory footprint:\n";
2337 util::printBytes(os, actualMem, " Actual: ");
2338 util::printBytes(os, voxelsMem, " Active leaf voxels: ");
2339
2340 if (numActiveVoxels) {
2341 util::printBytes(os, denseMem, " Dense equivalent: ");
2342 os << " Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2343 << "% of an equivalent dense volume\n";
2344 os << " Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2345 << "% of actual footprint\n";
2346 }
2347 }
2348
2349 } // namespace tree
2350 } // namespace OPENVDB_VERSION_NAME
2351 } // namespace openvdb
2352
2353 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
openvdb::v7_0::tree::Tree::getNodes
void getNodes(ArrayT &array) const
Definition: Tree.h:582
openvdb::v7_0::tree::Tree::cbeginNode
NodeCIter cbeginNode() const
Definition: Tree.h:1150
openvdb::v7_0::tree::Tree::leafCount
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:339
openvdb::v7_0::tree::Tree::writeBuffers
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1450
RootNode.h
The root node of an OpenVDB tree.
openvdb::v7_0::tree::Tree::beginValueOn
ValueOnCIter beginValueOn() const
Definition: Tree.h:1176
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnIter >::begin
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1303
openvdb::v7_0::MERGE_NODES
@ MERGE_NODES
Definition: Types.h:507
Metadata.h
openvdb::v7_0::util::printBytes
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\n", bool exact=false, int width=8, int precision=3)
openvdb::v7_0::tree::Tree::DeallocateNodes::DeallocateNodes
DeallocateNodes(std::vector< NodeType * > &nodes)
Definition: Tree.h:1205
openvdb::v7_0::tree::Tree::~Tree
~Tree() override
Definition: Tree.h:262
openvdb::v7_0::tree::Tree::addTile
void addTile(Index level, const Coord &xyz, const ValueType &value, bool active)
Add a tile containing voxel (x, y, z) at the specified tree level, creating a new branch if necessary...
Definition: Tree.h:1677
openvdb::v7_0::tree::Tree::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1560
Types.h
openvdb::v7_0::TreeBase
tree::TreeBase TreeBase
Definition: Grid.h:26
openvdb::v7_0::tree::Tree::Tree
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:260
openvdb::v7_0::tree::Tree::getValueDepth
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: Tree.h:1577
openvdb::v7_0::tree::Tree::valueType
Name valueType() const override
Return the name of the type of a voxel's value (e.g., "float" or "vec3d")
Definition: Tree.h:268
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllCIter >::begin
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1333
openvdb::v7_0::tree::Tree::probeLeaf
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1704
openvdb::v7_0::tree::TreeIterTraits
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1300
openvdb::v7_0::tree::CombineOpAdapter::CombineOpAdapter
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1882
openvdb::v7_0::tree::Tree::Tree
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:206
openvdb::v7_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnCIter >::begin
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1309
openvdb::v7_0::tree::Tree::mConstAccessorRegistry
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1220
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::NodeIter >::begin
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1339
openvdb::v7_0::tree::Tree::memUsage
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:367
openvdb::v7_0::tree::Tree::beginRootTiles
RootNodeType::ChildOffIter beginRootTiles()
Definition: Tree.h:1123
openvdb::v7_0::math::Coord::y
Int32 y() const
Definition: Coord.h:132
openvdb::v7_0::tree::Tree5
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal,...
Definition: Tree.h:1253
openvdb::v7_0::NotImplementedError
Definition: Exceptions.h:61
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllIter >::begin
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1327
openvdb::v7_0::Metadata::Ptr
SharedPtr< Metadata > Ptr
Definition: Metadata.h:26
openvdb::v7_0::tree::Tree::attachAccessor
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:640
openvdb::v7_0::MergePolicy
MergePolicy
Definition: Types.h:505
openvdb::v7_0::util::formattedInt
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:118
openvdb::v7_0::tree::Tree::beginRootChildren
RootNodeType::ChildOnIter beginRootChildren()
Definition: Tree.h:1116
openvdb::v7_0::math::Coord::x
Int32 x() const
Definition: Coord.h:131
openvdb::v7_0::tree::Tree::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: Tree.h:1585
openvdb::v7_0::tree::Tree::fill
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: Tree.h:480
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::NodeCIter >::begin
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1343
openvdb::v7_0::tree::ValueAccessorBase
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:95
openvdb::v7_0::tree::Tree::cbeginValueOn
ValueOnCIter cbeginValueOn() const
Definition: Tree.h:1177
Platform.h
openvdb::v7_0::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: Types.h:91
openvdb::v7_0::math::CoordBBox::reset
void reset()
Definition: Coord.h:327
openvdb::v7_0::tree::Tree::DeallocateNodes::mNodes
NodeType **const mNodes
Definition: Tree.h:1212
openvdb::v7_0::CombineArgs::a
const AValueType & a() const
Get the A input value.
Definition: Types.h:607
openvdb::v7_0::tree::Tree::beginValueAll
ValueAllCIter beginValueAll() const
Definition: Tree.h:1170
ValueAccessor.h
openvdb::v7_0::tree::Tree::operator==
bool operator==(const Tree &) const
Definition: Tree.h:275
openvdb::v7_0::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
Formats.h
Utility routines to output nicely-formatted numeric values.
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllCIter >::begin
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1375
openvdb::v7_0::tree::Tree::probeLeaf
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition: Tree.h:555
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:230
openvdb::v7_0::tree::Tree::isValueOn
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:450
openvdb::v7_0::tree::Tree::copy
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:265
openvdb::v7_0::tree::Tree::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:185
openvdb::v7_0::tree::CombineOpAdapter
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1880
openvdb::v7_0::tree::Tree::root
const RootNodeType & root() const
Definition: Tree.h:281
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::LeafIter >::begin
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1347
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffCIter >::begin
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1321
openvdb::v7_0::tree::Tree::type
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:273
openvdb::v7_0::tree::Tree::beginValueOff
ValueOffCIter beginValueOff() const
Definition: Tree.h:1182
openvdb::v7_0::tree::Tree::activeVoxelCount
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:358
openvdb::v7_0::tree::Tree::cbeginRootChildren
RootNodeType::ChildOnCIter cbeginRootChildren() const
Definition: Tree.h:1115
openvdb::v7_0::tree::Tree::getIndexRange
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:667
openvdb::v7_0::tree::TreeBase::memUsage
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:133
openvdb::v7_0::tree::LeafIteratorBase
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1191
openvdb::v7_0::tree::Tree::addLeaf
void addLeaf(LeafNodeType *leaf)
Add the given leaf node to this tree, creating a new branch if necessary. If a leaf node with the sam...
Definition: Tree.h:520
openvdb::v7_0::tree::Tree::activeTileCount
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:362
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnIter >::begin
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1355
openvdb::v7_0::tree::Tree::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1666
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffIter >::begin
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1363
openvdb::v7_0::tree::Tree::hasActiveTiles
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:454
openvdb::v7_0::tree::TreeBase::getBackgroundValue
virtual Metadata::Ptr getBackgroundValue() const
Return this tree's background value wrapped as metadata.
Definition: Tree.h:60
InternalNode.h
Internal table nodes for OpenVDB trees.
openvdb::v7_0::TypedMetadata
Templated metadata class to hold specific types.
Definition: Metadata.h:144
openvdb::v7_0::tree::Tree::touchLeaf
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: Tree.h:1696
openvdb::v7_0::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:106
openvdb::v7_0::tree::Tree::treeDepth
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:337
openvdb::v7_0::tree::Tree::releaseAccessor
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Definition: Tree.h:652
openvdb::v7_0::tree::Tree::beginNode
NodeCIter beginNode() const
Definition: Tree.h:1149
openvdb::v7_0::tree::Tree::probeConstLeaf
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: Tree.h:1712
openvdb::v7_0::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:681
openvdb::v7_0::tree::Tree::cbeginRootDense
RootNodeType::ChildAllCIter cbeginRootDense() const
Definition: Tree.h:1129
openvdb::v7_0::CombineArgs::b
const BValueType & b() const
Get the B input value.
Definition: Types.h:609
openvdb::v7_0::tree::Tree::cbeginValueOff
ValueOffCIter cbeginValueOff() const
Definition: Tree.h:1183
openvdb::v7_0::tree::Tree::sTreeTypeName
static std::unique_ptr< const Name > sTreeTypeName
Definition: Tree.h:1222
openvdb::v7_0::tree::CombineOpAdapter::op
CombineOp & op
Definition: Tree.h:1888
openvdb::v7_0::tree::Tree::cbeginRootTiles
RootNodeType::ChildOffCIter cbeginRootTiles() const
Definition: Tree.h:1122
openvdb::v7_0::tree::Tree::background
const ValueType & background() const
Return this tree's background value.
Definition: Tree.h:664
openvdb::v7_0::tree::NodeIteratorBase
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:940
openvdb::v7_0::tree::Tree::stealNodes
void stealNodes(ArrayT &array)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:
Definition: Tree.h:609
openvdb::v7_0::tree::Tree::ConstAccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1196
openvdb::v7_0::math::Coord::z
Int32 z() const
Definition: Coord.h:133
openvdb::v7_0::CombineArgs
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:567
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::tree::Tree3
Tree3<T, N1, N2>::Type is the type of a three-level tree (Root, Internal, Leaf) with value type T and...
Definition: Tree.h:1234
openvdb::v7_0::tree::TreeBase::ConstPtr
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:39
openvdb::v7_0::tree::Tree::inactiveLeafVoxelCount
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:356
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::LeafCIter >::begin
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1351
openvdb::v7_0::tree::Tree::Tree
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:217
openvdb::v7_0::tree::Tree::modifyValue
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active.
Definition: Tree.h:1649
openvdb::v7_0::tree::TreeValueIteratorBase
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:621
openvdb::v7_0::tree::Tree::Tree
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:253
openvdb::v7_0::tree::Tree::DeallocateNodes::operator()
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1207
openvdb::v7_0::tools::prune
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition: Prune.h:334
openvdb::v7_0::tree::Tree::cbeginLeaf
LeafCIter cbeginLeaf() const
Definition: Tree.h:1157
openvdb::v7_0::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:102
openvdb::v7_0::tree::Tree::empty
bool empty() const
Return true if this tree contains no nodes other than the root node and no tiles other than backgroun...
Definition: Tree.h:622
openvdb::v7_0::tree::Tree::stealNodes
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:611
openvdb::v7_0::tree::Tree::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: Tree.h:1632
openvdb::v7_0::tools::clip
GridType::Ptr clip(const GridType &grid, const BBoxd &bbox, bool keepInterior=true)
Clip the given grid against a world-space bounding box and return a new grid containing the result.
Definition: Clip.h:348
openvdb::v7_0::tree::Tree::operator!=
bool operator!=(const Tree &) const
Definition: Tree.h:276
openvdb::v7_0::tree::Tree::root
RootNodeType & root()
Return this tree's root node.
Definition: Tree.h:280
openvdb::v7_0::Index
Index32 Index
Definition: Types.h:31
logging.h
openvdb::v7_0::tree::Tree::isValueOff
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:452
openvdb::v7_0::Name
std::string Name
Definition: Name.h:17
openvdb::v7_0::tree::CombineOpAdapter::operator()
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1884
openvdb::v7_0::tree::Tree::beginLeaf
LeafCIter beginLeaf() const
Definition: Tree.h:1156
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:108
openvdb::v7_0::MERGE_ACTIVE_STATES_AND_NODES
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: Types.h:508
openvdb::v7_0::math::CoordBBox::extents
Coord extents() const
Definition: Coord.h:382
openvdb::v7_0::tree::Tree::visitActiveBBox
void visitActiveBBox(BBoxOp &op) const
Use sparse traversal to call the given functor with bounding box information for all active tiles and...
Definition: Tree.h:976
openvdb::v7_0::tree::Tree::AccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1195
openvdb::v7_0::tree::Tree::ValueType
typename RootNodeType::ValueType ValueType
Definition: Tree.h:183
openvdb::v7_0::CombineArgs::result
const AValueType & result() const
Get the output value.
Definition: Types.h:612
openvdb::v7_0::Index32
uint32_t Index32
Definition: Types.h:29
BBox.h
openvdb::v7_0::tree::Tree::RootNodeType
_RootNodeType RootNodeType
Definition: Tree.h:182
openvdb::v7_0::tree::Tree::mAccessorRegistry
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1219
openvdb::v7_0::tree::Tree::hasSameTopology
bool hasSameTopology(const Tree< OtherRootNodeType > &other) const
Return true if the given tree has the same node and active value topology as this tree,...
Definition: Tree.h:2111
openvdb::v7_0::tree::Tree::clear
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1458
openvdb::v7_0::tree::Tree::beginRootDense
RootNodeType::ChildAllIter beginRootDense()
Definition: Tree.h:1130
openvdb::v7_0::tree::TreeBase::Ptr
SharedPtr< TreeBase > Ptr
Definition: Tree.h:38
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffCIter >::begin
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1367
openvdb::v7_0::tree::Tree4
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal,...
Definition: Tree.h:1244
openvdb::v7_0::tree::Tree::activeLeafVoxelCount
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:354
openvdb
Definition: Exceptions.h:13
openvdb::v7_0::tree::Tree::Tree
Tree(const OtherTreeType &other, const ValueType &inactiveValue, const ValueType &activeValue, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:232
LeafNode.h
openvdb::v7_0::tree::Tree::ValueConverter
ValueConverter<T>::Type is the type of a tree having the same hierarchy as this tree but a different ...
Definition: Tree.h:196
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffIter >::begin
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1315
openvdb::v7_0::tree::Tree::mRoot
RootNodeType mRoot
Definition: Tree.h:1218
openvdb::v7_0::Index64
uint64_t Index64
Definition: Types.h:30
openvdb::v7_0::tree::Tree::Tree
Tree()
Definition: Tree.h:201
openvdb::v7_0::tree::Tree::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1658
openvdb::v7_0::tree::Tree::BuildType
typename RootNodeType::BuildType BuildType
Definition: Tree.h:184
openvdb::v7_0::tree::Tree::prune
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: Tree.h:509
openvdb::v7_0::MERGE_ACTIVE_STATES
@ MERGE_ACTIVE_STATES
Definition: Types.h:506
openvdb::v7_0::tree::Tree::DeallocateNodes
Definition: Tree.h:1204
openvdb::v7_0::tree::Tree::setValue
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active.
Definition: Tree.h:1609
openvdb::v7_0::tree::Tree::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: Tree.h:1616
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllIter >::begin
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1371
openvdb::v7_0::tree::Tree::setActiveState
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: Tree.h:1601
TreeIterator.h
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
openvdb::v7_0::tree::Tree::clearAllAccessors
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1517
openvdb::v7_0::tree::Tree
Definition: Tree.h:176
openvdb::v7_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnCIter >::begin
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1359
openvdb::v7_0::tree::Tree::cbeginValueAll
ValueAllCIter cbeginValueAll() const
Definition: Tree.h:1171
openvdb::v7_0::tree::TreeBase
Base class for typed trees.
Definition: Tree.h:35
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253