OpenVDB: Tree.h Source File

OpenVDB 4.0.2

Tree.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
34
35 #ifndef OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
37
38 #include <openvdb/Types.h>
39 #include <openvdb/Metadata.h>
40 #include <openvdb/math/Math.h>
41 #include <openvdb/math/BBox.h>
42 #include <openvdb/util/Formats.h>
43 #include <openvdb/util/logging.h>
44 #include <openvdb/Platform.h>
45 #include "RootNode.h"
46 #include "InternalNode.h"
47 #include "LeafNode.h"
48 #include "TreeIterator.h"
49 #include "ValueAccessor.h"
50 #include <tbb/atomic.h>
51 #include <tbb/concurrent_hash_map.h>
52 #include <cstdint>
53 #include <iostream>
54 #include <sstream>
55 #include <vector>
56
57
58 namespace openvdb {
59 OPENVDB_USE_VERSION_NAMESPACE
60 namespace OPENVDB_VERSION_NAME {
61 namespace tree {
62
64 class OPENVDB_API TreeBase
65 {
66 public:
67 using Ptr = SharedPtr<TreeBase>;
68 using ConstPtr = SharedPtr<const TreeBase>;
69
70 TreeBase() = default;
71 TreeBase(const TreeBase&) = default;
72 TreeBase& operator=(const TreeBase&) = delete; // disallow assignment
73 virtual ~TreeBase() = default;
74
76 virtual const Name& type() const = 0;
77
79 virtual Name valueType() const = 0;
80
82 virtual TreeBase::Ptr copy() const = 0;
83
84 //
85 // Tree methods
86 //
89 virtual Metadata::Ptr getBackgroundValue() const { return Metadata::Ptr(); }
90
98 virtual bool evalLeafBoundingBox(CoordBBox& bbox) const = 0;
99
103 virtual bool evalLeafDim(Coord& dim) const = 0;
104
112 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const = 0;
113
117 virtual bool evalActiveVoxelDim(Coord& dim) const = 0;
118
119 virtual void getIndexRange(CoordBBox& bbox) const = 0;
120
121 #ifndef OPENVDB_2_ABI_COMPATIBLE
122 virtual void clipUnallocatedNodes() = 0;
128 #ifndef OPENVDB_3_ABI_COMPATIBLE
129 virtual Index32 unallocatedLeafCount() const = 0;
131 #endif
132 #endif
133
134
135 //
136 // Statistics
137 //
141 virtual Index treeDepth() const = 0;
143 virtual Index32 leafCount() const = 0;
145 virtual Index32 nonLeafCount() const = 0;
147 virtual Index64 activeLeafVoxelCount() const = 0;
149 virtual Index64 inactiveLeafVoxelCount() const = 0;
151 virtual Index64 activeVoxelCount() const = 0;
153 virtual Index64 inactiveVoxelCount() const = 0;
154 #ifndef OPENVDB_2_ABI_COMPATIBLE
155 virtual Index64 activeTileCount() const = 0;
157 #endif
158
160 virtual Index64 memUsage() const { return 0; }
161
162
163 //
164 // I/O methods
165 //
169 virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
173 virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
174
176 virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false) = 0;
177 #ifndef OPENVDB_2_ABI_COMPATIBLE
178 virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) = 0;
185 virtual void readNonresidentBuffers() const = 0;
186 #endif
187 virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const = 0;
189
197 virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
198 };
199
200
202
203
204 template<typename _RootNodeType>
205 class Tree: public TreeBase
206 {
207 public:
208 using Ptr = SharedPtr<Tree>;
209 using ConstPtr = SharedPtr<const Tree>;
210
211 using RootNodeType = _RootNodeType;
212 using ValueType = typename RootNodeType::ValueType;
213 using BuildType = typename RootNodeType::BuildType;
214 using LeafNodeType = typename RootNodeType::LeafNodeType;
215
216 static const Index DEPTH = RootNodeType::LEVEL + 1;
217
224 template<typename OtherValueType>
225 struct ValueConverter {
226 using Type = Tree<typename RootNodeType::template ValueConverter<OtherValueType>::Type>;
227 };
228
229
230 Tree() {}
231
232 Tree& operator=(const Tree&) = delete; // disallow assignment
233
235 Tree(const Tree& other): TreeBase(other), mRoot(other.mRoot)
236 {
237 }
238
245 template<typename OtherRootType>
246 explicit Tree(const Tree<OtherRootType>& other): TreeBase(other), mRoot(other.root())
247 {
248 }
249
260 template<typename OtherTreeType>
261 Tree(const OtherTreeType& other,
262 const ValueType& inactiveValue,
263 const ValueType& activeValue,
264 TopologyCopy):
265 TreeBase(other),
266 mRoot(other.root(), inactiveValue, activeValue, TopologyCopy())
267 {
268 }
269
281 template<typename OtherTreeType>
282 Tree(const OtherTreeType& other, const ValueType& background, TopologyCopy):
283 TreeBase(other),
284 mRoot(other.root(), background, TopologyCopy())
285 {
286 }
287
289 Tree(const ValueType& background): mRoot(background) {}
290
291 ~Tree() override { this->clear(); releaseAllAccessors(); }
292
294 TreeBase::Ptr copy() const override { return TreeBase::Ptr(new Tree(*this)); }
295
297 Name valueType() const override { return typeNameAsString<ValueType>(); }
298
300 static const Name& treeType();
302 const Name& type() const override { return this->treeType(); }
303
304 bool operator==(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
305 bool operator!=(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
306
308 RootNodeType& root() { return mRoot; }
310 const RootNodeType& root() const { return mRoot; }
312
313
314 //
315 // Tree methods
316 //
319 template<typename OtherRootNodeType>
320 bool hasSameTopology(const Tree<OtherRootNodeType>& other) const;
321
322 bool evalLeafBoundingBox(CoordBBox& bbox) const override;
323 bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const override;
324 bool evalActiveVoxelDim(Coord& dim) const override;
325 bool evalLeafDim(Coord& dim) const override;
326
330 static void getNodeLog2Dims(std::vector<Index>& dims);
331
332
333 //
334 // I/O methods
335 //
339 void readTopology(std::istream&, bool saveFloatAsHalf = false) override;
343 void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const override;
345 void readBuffers(std::istream&, bool saveFloatAsHalf = false) override;
346 #ifndef OPENVDB_2_ABI_COMPATIBLE
347 void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) override;
354 void readNonresidentBuffers() const override;
355 #endif
356 void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const override;
358
359 void print(std::ostream& os = std::cout, int verboseLevel = 1) const override;
360
361
362 //
363 // Statistics
364 //
368 Index treeDepth() const override { return DEPTH; }
370 Index32 leafCount() const override { return mRoot.leafCount(); }
372 Index32 nonLeafCount() const override { return mRoot.nonLeafCount(); }
374 Index64 activeLeafVoxelCount() const override { return mRoot.onLeafVoxelCount(); }
376 Index64 inactiveLeafVoxelCount() const override { return mRoot.offLeafVoxelCount(); }
378 Index64 activeVoxelCount() const override { return mRoot.onVoxelCount(); }
380 Index64 inactiveVoxelCount() const override;
382 Index64 activeTileCount() const override { return mRoot.onTileCount(); }
383
385 void evalMinMax(ValueType &min, ValueType &max) const;
386
387 Index64 memUsage() const override { return sizeof(*this) + mRoot.memUsage(); }
388
389
390 //
391 // Voxel access methods (using signed indexing)
392 //
394 const ValueType& getValue(const Coord& xyz) const;
397 template<typename AccessT> const ValueType& getValue(const Coord& xyz, AccessT&) const;
398
402 int getValueDepth(const Coord& xyz) const;
403
405 void setActiveState(const Coord& xyz, bool on);
407 void setValueOnly(const Coord& xyz, const ValueType& value);
409 void setValueOn(const Coord& xyz);
411 void setValueOn(const Coord& xyz, const ValueType& value);
413 void setValue(const Coord& xyz, const ValueType& value);
416 template<typename AccessT> void setValue(const Coord& xyz, const ValueType& value, AccessT&);
418 void setValueOff(const Coord& xyz);
420 void setValueOff(const Coord& xyz, const ValueType& value);
421
440 template<typename ModifyOp>
441 void modifyValue(const Coord& xyz, const ModifyOp& op);
442
462 template<typename ModifyOp>
463 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
464
467 bool probeValue(const Coord& xyz, ValueType& value) const;
468
470 bool isValueOn(const Coord& xyz) const { return mRoot.isValueOn(xyz); }
472 bool isValueOff(const Coord& xyz) const { return !this->isValueOn(xyz); }
474 bool hasActiveTiles() const { return mRoot.hasActiveTiles(); }
475
477 void clip(const CoordBBox&);
478
479 #ifndef OPENVDB_2_ABI_COMPATIBLE
480 void clipUnallocatedNodes() override;
486 #ifndef OPENVDB_3_ABI_COMPATIBLE
487 Index32 unallocatedLeafCount() const override;
489 #endif
490 #endif
491
493 void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
502 void fill(const CoordBBox& bbox, const ValueType& value, bool active = true)
503 {
504 this->sparseFill(bbox, value, active);
505 }
507
515 void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
516
525 void voxelizeActiveTiles(bool threaded = true);
526
531 void prune(const ValueType& tolerance = zeroVal<ValueType>())
532 {
533 this->clearAllAccessors();
534 mRoot.prune(tolerance);
535 }
536
538 void addLeaf(LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
544 OPENVDB_DEPRECATED void addLeaf(LeafNodeType& leaf) { mRoot.addLeaf(&leaf); }
546
551 void addTile(Index level, const Coord& xyz, const ValueType& value, bool active);
552
557 template<typename NodeT>
558 NodeT* stealNode(const Coord& xyz, const ValueType& value, bool active);
559
565 LeafNodeType* touchLeaf(const Coord& xyz);
566
568 template<typename NodeType> NodeType* probeNode(const Coord& xyz);
571 template<typename NodeType> const NodeType* probeConstNode(const Coord& xyz) const;
572 template<typename NodeType> const NodeType* probeNode(const Coord& xyz) const;
574
576 LeafNodeType* probeLeaf(const Coord& xyz);
579 const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
580 const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
582
584 template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
607 template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
609
633 template<typename ArrayT>
634 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
635 template<typename ArrayT>
636 void stealNodes(ArrayT& array, const ValueType& value, bool state)
637 {
638 this->clearAllAccessors();
639 mRoot.stealNodes(array, value, state);
640 }
641
642 //
643 // Aux methods
644 //
647 bool empty() const { return mRoot.empty(); }
648
650 void clear();
651
653 void clearAllAccessors();
654
656 void attachAccessor(ValueAccessorBase<Tree, true>&) const;
659 void attachAccessor(ValueAccessorBase<const Tree, true>&) const;
661
663 void attachAccessor(ValueAccessorBase<Tree, false>&) const {}
665 void attachAccessor(ValueAccessorBase<const Tree, false>&) const {}
667
669 void releaseAccessor(ValueAccessorBase<Tree, true>&) const;
671 void releaseAccessor(ValueAccessorBase<const Tree, true>&) const;
673
675 void releaseAccessor(ValueAccessorBase<Tree, false>&) const {}
677 void releaseAccessor(ValueAccessorBase<const Tree, false>&) const {}
679
682 Metadata::Ptr getBackgroundValue() const override;
683
689 const ValueType& background() const { return mRoot.background(); }
690
692 void getIndexRange(CoordBBox& bbox) const override { mRoot.getIndexRange(bbox); }
693
701 void merge(Tree& other, MergePolicy = MERGE_ACTIVE_STATES);
702
716 template<typename OtherRootNodeType>
717 void topologyUnion(const Tree<OtherRootNodeType>& other);
718
732 template<typename OtherRootNodeType>
733 void topologyIntersection(const Tree<OtherRootNodeType>& other);
734
745 template<typename OtherRootNodeType>
746 void topologyDifference(const Tree<OtherRootNodeType>& other);
747
792 template<typename CombineOp>
793 void combine(Tree& other, CombineOp& op, bool prune = false);
794 #ifndef _MSC_VER
795 template<typename CombineOp>
796 void combine(Tree& other, const CombineOp& op, bool prune = false);
797 #endif
798
837 template<typename ExtendedCombineOp>
838 void combineExtended(Tree& other, ExtendedCombineOp& op, bool prune = false);
839 #ifndef _MSC_VER
840 template<typename ExtendedCombineOp>
841 void combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune = false);
842 #endif
843
872 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
873 void combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune = false);
874 #ifndef _MSC_VER
875 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
876 void combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune = false);
877 #endif
878
952 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
953 void combine2Extended(const Tree& a, const OtherTreeType& b, ExtendedCombineOp& op,
954 bool prune = false);
955 #ifndef _MSC_VER
956 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
957 void combine2Extended(const Tree& a, const OtherTreeType& b, const ExtendedCombineOp&,
958 bool prune = false);
959 #endif
960
1001 template<typename BBoxOp> void visitActiveBBox(BBoxOp& op) const { mRoot.visitActiveBBox(op); }
1002
1056 template<typename VisitorOp> void visit(VisitorOp& op);
1057 template<typename VisitorOp> void visit(const VisitorOp& op);
1058
1063 template<typename VisitorOp> void visit(VisitorOp& op) const;
1064 template<typename VisitorOp> void visit(const VisitorOp& op) const;
1065
1113 template<typename OtherTreeType, typename VisitorOp>
1114 void visit2(OtherTreeType& other, VisitorOp& op);
1115 template<typename OtherTreeType, typename VisitorOp>
1116 void visit2(OtherTreeType& other, const VisitorOp& op);
1117
1128 template<typename OtherTreeType, typename VisitorOp>
1129 void visit2(OtherTreeType& other, VisitorOp& op) const;
1130 template<typename OtherTreeType, typename VisitorOp>
1131 void visit2(OtherTreeType& other, const VisitorOp& op) const;
1132
1133
1134 //
1135 // Iteration
1136 //
1138 typename RootNodeType::ChildOnCIter beginRootChildren() const { return mRoot.cbeginChildOn(); }
1140 typename RootNodeType::ChildOnCIter cbeginRootChildren() const { return mRoot.cbeginChildOn(); }
1141 typename RootNodeType::ChildOnIter beginRootChildren() { return mRoot.beginChildOn(); }
1143
1145 typename RootNodeType::ChildOffCIter beginRootTiles() const { return mRoot.cbeginChildOff(); }
1147 typename RootNodeType::ChildOffCIter cbeginRootTiles() const { return mRoot.cbeginChildOff(); }
1148 typename RootNodeType::ChildOffIter beginRootTiles() { return mRoot.beginChildOff(); }
1150
1152 typename RootNodeType::ChildAllCIter beginRootDense() const { return mRoot.cbeginChildAll(); }
1154 typename RootNodeType::ChildAllCIter cbeginRootDense() const { return mRoot.cbeginChildAll(); }
1155 typename RootNodeType::ChildAllIter beginRootDense() { return mRoot.beginChildAll(); }
1157
1158
1160 using NodeIter = NodeIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
1162 using NodeCIter = NodeIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
1164
1166 using LeafIter = LeafIteratorBase<Tree, typename RootNodeType::ChildOnIter>;
1168 using LeafCIter = LeafIteratorBase<const Tree, typename RootNodeType::ChildOnCIter>;
1170
1172 NodeIter beginNode() { return NodeIter(*this); }
1174 NodeCIter beginNode() const { return NodeCIter(*this); }
1175 NodeCIter cbeginNode() const { return NodeCIter(*this); }
1177
1179 LeafIter beginLeaf() { return LeafIter(*this); }
1181 LeafCIter beginLeaf() const { return LeafCIter(*this); }
1182 LeafCIter cbeginLeaf() const { return LeafCIter(*this); }
1184
1185 using ValueAllIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueAllIter>;
1186 using ValueAllCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueAllCIter>;
1187 using ValueOnIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOnIter>;
1188 using ValueOnCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOnCIter>;
1189 using ValueOffIter = TreeValueIteratorBase<Tree, typename RootNodeType::ValueOffIter>;
1190 using ValueOffCIter = TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOffCIter>;
1191
1193 ValueAllIter beginValueAll() { return ValueAllIter(*this); }
1195 ValueAllCIter beginValueAll() const { return ValueAllCIter(*this); }
1196 ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this); }
1198
1199 ValueOnIter beginValueOn() { return ValueOnIter(*this); }
1201 ValueOnCIter beginValueOn() const { return ValueOnCIter(*this); }
1202 ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this); }
1204
1205 ValueOffIter beginValueOff() { return ValueOffIter(*this); }
1207 ValueOffCIter beginValueOff() const { return ValueOffCIter(*this); }
1208 ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this); }
1210
1213 template<typename IterT> IterT begin();
1216 template<typename CIterT> CIterT cbegin() const;
1217
1218
1219 protected:
1220 using AccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<Tree, true>*, bool>;
1221 using ConstAccessorRegistry = tbb::concurrent_hash_map<ValueAccessorBase<const Tree, true>*, bool>;
1222
1225 void releaseAllAccessors();
1226
1227 // TBB body object used to deallocates nodes in parallel.
1228 template<typename NodeType>
1229 struct DeallocateNodes {
1230 DeallocateNodes(std::vector<NodeType*>& nodes)
1231 : mNodes(nodes.empty() ? nullptr : &nodes.front()) { }
1232 void operator()(const tbb::blocked_range<size_t>& range) const {
1233 for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
1234 delete mNodes[n]; mNodes[n] = nullptr;
1235 }
1236 }
1237 NodeType ** const mNodes;
1238 };
1239
1240 //
1241 // Data members
1242 //
1243 RootNodeType mRoot; // root node of the tree
1244 mutable AccessorRegistry mAccessorRegistry;
1245 mutable ConstAccessorRegistry mConstAccessorRegistry;
1246
1247 static tbb::atomic<const Name*> sTreeTypeName;
1248 }; // end of Tree class
1249
1250 template<typename _RootNodeType>
1251 tbb::atomic<const Name*> Tree<_RootNodeType>::sTreeTypeName;
1252
1253
1258 template<typename T, Index N1=4, Index N2=3>
1259 struct Tree3 {
1260 using Type = Tree<RootNode<InternalNode<LeafNode<T, N2>, N1>>>;
1261 };
1262
1263
1268 template<typename T, Index N1=5, Index N2=4, Index N3=3>
1269 struct Tree4 {
1270 using Type = Tree<RootNode<InternalNode<InternalNode<LeafNode<T, N3>, N2>, N1>>>;
1271 };
1272
1277 template<typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1278 struct Tree5 {
1279 using Type =
1280 Tree<RootNode<InternalNode<InternalNode<InternalNode<LeafNode<T, N4>, N3>, N2>, N1>>>;
1281 };
1282
1283
1285
1286
1287 inline void
1288 TreeBase::readTopology(std::istream& is, bool /*saveFloatAsHalf*/)
1289 {
1290 int32_t bufferCount;
1291 is.read(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1292 if (bufferCount != 1) OPENVDB_LOG_WARN("multi-buffer trees are no longer supported");
1293 }
1294
1295
1296 inline void
1297 TreeBase::writeTopology(std::ostream& os, bool /*saveFloatAsHalf*/) const
1298 {
1299 int32_t bufferCount = 1;
1300 os.write(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1301 }
1302
1303
1304 inline void
1305 TreeBase::print(std::ostream& os, int /*verboseLevel*/) const
1306 {
1307 os << " Tree Type: " << type()
1308 << " Active Voxel Count: " << activeVoxelCount() << std::endl
1309 #ifndef OPENVDB_2_ABI_COMPATIBLE
1310 << " Active tile Count: " << activeTileCount() << std::endl
1311 #endif
1312 << " Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1313 << " Leaf Node Count: " << leafCount() << std::endl
1314 << " Non-leaf Node Count: " << nonLeafCount() << std::endl;
1315 }
1316
1317
1319
1320
1321 //
1322 // Type traits for tree iterators
1323 //
1324
1327 template<typename TreeT, typename IterT> struct TreeIterTraits;
1328
1329 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1330 static typename TreeT::RootNodeType::ChildOnIter begin(TreeT& tree) {
1331 return tree.beginRootChildren();
1332 }
1333 };
1334
1335 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1336 static typename TreeT::RootNodeType::ChildOnCIter begin(const TreeT& tree) {
1337 return tree.cbeginRootChildren();
1338 }
1339 };
1340
1341 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1342 static typename TreeT::RootNodeType::ChildOffIter begin(TreeT& tree) {
1343 return tree.beginRootTiles();
1344 }
1345 };
1346
1347 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1348 static typename TreeT::RootNodeType::ChildOffCIter begin(const TreeT& tree) {
1349 return tree.cbeginRootTiles();
1350 }
1351 };
1352
1353 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1354 static typename TreeT::RootNodeType::ChildAllIter begin(TreeT& tree) {
1355 return tree.beginRootDense();
1356 }
1357 };
1358
1359 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1360 static typename TreeT::RootNodeType::ChildAllCIter begin(const TreeT& tree) {
1361 return tree.cbeginRootDense();
1362 }
1363 };
1364
1365 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeIter> {
1366 static typename TreeT::NodeIter begin(TreeT& tree) { return tree.beginNode(); }
1367 };
1368
1369 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeCIter> {
1370 static typename TreeT::NodeCIter begin(const TreeT& tree) { return tree.cbeginNode(); }
1371 };
1372
1373 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafIter> {
1374 static typename TreeT::LeafIter begin(TreeT& tree) { return tree.beginLeaf(); }
1375 };
1376
1377 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafCIter> {
1378 static typename TreeT::LeafCIter begin(const TreeT& tree) { return tree.cbeginLeaf(); }
1379 };
1380
1381 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnIter> {
1382 static typename TreeT::ValueOnIter begin(TreeT& tree) { return tree.beginValueOn(); }
1383 };
1384
1385 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1386 static typename TreeT::ValueOnCIter begin(const TreeT& tree) { return tree.cbeginValueOn(); }
1387 };
1388
1389 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1390 static typename TreeT::ValueOffIter begin(TreeT& tree) { return tree.beginValueOff(); }
1391 };
1392
1393 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1394 static typename TreeT::ValueOffCIter begin(const TreeT& tree) { return tree.cbeginValueOff(); }
1395 };
1396
1397 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1398 static typename TreeT::ValueAllIter begin(TreeT& tree) { return tree.beginValueAll(); }
1399 };
1400
1401 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1402 static typename TreeT::ValueAllCIter begin(const TreeT& tree) { return tree.cbeginValueAll(); }
1403 };
1404
1405
1406 template<typename RootNodeType>
1407 template<typename IterT>
1408 inline IterT
1409 Tree<RootNodeType>::begin()
1410 {
1411 return TreeIterTraits<Tree, IterT>::begin(*this);
1412 }
1413
1414
1415 template<typename RootNodeType>
1416 template<typename IterT>
1417 inline IterT
1418 Tree<RootNodeType>::cbegin() const
1419 {
1420 return TreeIterTraits<Tree, IterT>::begin(*this);
1421 }
1422
1423
1425
1426
1427 template<typename RootNodeType>
1428 void
1429 Tree<RootNodeType>::readTopology(std::istream& is, bool saveFloatAsHalf)
1430 {
1431 this->clearAllAccessors();
1432 TreeBase::readTopology(is, saveFloatAsHalf);
1433 mRoot.readTopology(is, saveFloatAsHalf);
1434 }
1435
1436
1437 template<typename RootNodeType>
1438 void
1439 Tree<RootNodeType>::writeTopology(std::ostream& os, bool saveFloatAsHalf) const
1440 {
1441 TreeBase::writeTopology(os, saveFloatAsHalf);
1442 mRoot.writeTopology(os, saveFloatAsHalf);
1443 }
1444
1445
1446 template<typename RootNodeType>
1447 inline void
1448 Tree<RootNodeType>::readBuffers(std::istream &is, bool saveFloatAsHalf)
1449 {
1450 this->clearAllAccessors();
1451 mRoot.readBuffers(is, saveFloatAsHalf);
1452 }
1453
1454
1455 #ifndef OPENVDB_2_ABI_COMPATIBLE
1456
1457 template<typename RootNodeType>
1458 inline void
1459 Tree<RootNodeType>::readBuffers(std::istream &is, const CoordBBox& bbox, bool saveFloatAsHalf)
1460 {
1461 this->clearAllAccessors();
1462 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1463 }
1464
1465
1466 template<typename RootNodeType>
1467 inline void
1468 Tree<RootNodeType>::readNonresidentBuffers() const
1469 {
1470 for (LeafCIter it = this->cbeginLeaf(); it; ++it) {
1471 // Retrieving the value of a leaf voxel forces loading of the leaf node's voxel buffer.
1472 it->getValue(Index(0));
1473 }
1474 }
1475
1476 #endif // !OPENVDB_2_ABI_COMPATIBLE
1477
1478
1479 template<typename RootNodeType>
1480 inline void
1481 Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
1482 {
1483 mRoot.writeBuffers(os, saveFloatAsHalf);
1484 }
1485
1486
1487 template<typename RootNodeType>
1488 inline void
1489 Tree<RootNodeType>::clear()
1490 {
1491 std::vector<LeafNodeType*> leafnodes;
1492 this->stealNodes(leafnodes);
1493
1494 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1495 DeallocateNodes<LeafNodeType>(leafnodes));
1496
1497 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1498 this->stealNodes(internalNodes);
1499
1500 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1501 DeallocateNodes<typename RootNodeType::ChildNodeType>(internalNodes));
1502
1503 mRoot.clear();
1504
1505 this->clearAllAccessors();
1506 }
1507
1508
1510
1511
1512 template<typename RootNodeType>
1513 inline void
1514 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<Tree, true>& accessor) const
1515 {
1516 typename AccessorRegistry::accessor a;
1517 mAccessorRegistry.insert(a, &accessor);
1518 }
1519
1520
1521 template<typename RootNodeType>
1522 inline void
1523 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1524 {
1525 typename ConstAccessorRegistry::accessor a;
1526 mConstAccessorRegistry.insert(a, &accessor);
1527 }
1528
1529
1530 template<typename RootNodeType>
1531 inline void
1532 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<Tree, true>& accessor) const
1533 {
1534 mAccessorRegistry.erase(&accessor);
1535 }
1536
1537
1538 template<typename RootNodeType>
1539 inline void
1540 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1541 {
1542 mConstAccessorRegistry.erase(&accessor);
1543 }
1544
1545
1546 template<typename RootNodeType>
1547 inline void
1548 Tree<RootNodeType>::clearAllAccessors()
1549 {
1550 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1551 it != mAccessorRegistry.end(); ++it)
1552 {
1553 if (it->first) it->first->clear();
1554 }
1555
1556 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1557 it != mConstAccessorRegistry.end(); ++it)
1558 {
1559 if (it->first) it->first->clear();
1560 }
1561 }
1562
1563
1564 template<typename RootNodeType>
1565 inline void
1566 Tree<RootNodeType>::releaseAllAccessors()
1567 {
1568 mAccessorRegistry.erase(nullptr);
1569 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1570 it != mAccessorRegistry.end(); ++it)
1571 {
1572 it->first->release();
1573 }
1574 mAccessorRegistry.clear();
1575
1576 mAccessorRegistry.erase(nullptr);
1577 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1578 it != mConstAccessorRegistry.end(); ++it)
1579 {
1580 it->first->release();
1581 }
1582 mConstAccessorRegistry.clear();
1583 }
1584
1585
1587
1588
1589 template<typename RootNodeType>
1590 inline const typename RootNodeType::ValueType&
1591 Tree<RootNodeType>::getValue(const Coord& xyz) const
1592 {
1593 return mRoot.getValue(xyz);
1594 }
1595
1596
1597 template<typename RootNodeType>
1598 template<typename AccessT>
1599 inline const typename RootNodeType::ValueType&
1600 Tree<RootNodeType>::getValue(const Coord& xyz, AccessT& accessor) const
1601 {
1602 return accessor.getValue(xyz);
1603 }
1604
1605
1606 template<typename RootNodeType>
1607 inline int
1608 Tree<RootNodeType>::getValueDepth(const Coord& xyz) const
1609 {
1610 return mRoot.getValueDepth(xyz);
1611 }
1612
1613
1614 template<typename RootNodeType>
1615 inline void
1616 Tree<RootNodeType>::setValueOff(const Coord& xyz)
1617 {
1618 mRoot.setValueOff(xyz);
1619 }
1620
1621
1622 template<typename RootNodeType>
1623 inline void
1624 Tree<RootNodeType>::setValueOff(const Coord& xyz, const ValueType& value)
1625 {
1626 mRoot.setValueOff(xyz, value);
1627 }
1628
1629
1630 template<typename RootNodeType>
1631 inline void
1632 Tree<RootNodeType>::setActiveState(const Coord& xyz, bool on)
1633 {
1634 mRoot.setActiveState(xyz, on);
1635 }
1636
1637
1638 template<typename RootNodeType>
1639 inline void
1640 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value)
1641 {
1642 mRoot.setValueOn(xyz, value);
1643 }
1644
1645 template<typename RootNodeType>
1646 inline void
1647 Tree<RootNodeType>::setValueOnly(const Coord& xyz, const ValueType& value)
1648 {
1649 mRoot.setValueOnly(xyz, value);
1650 }
1651
1652 template<typename RootNodeType>
1653 template<typename AccessT>
1654 inline void
1655 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value, AccessT& accessor)
1656 {
1657 accessor.setValue(xyz, value);
1658 }
1659
1660
1661 template<typename RootNodeType>
1662 inline void
1663 Tree<RootNodeType>::setValueOn(const Coord& xyz)
1664 {
1665 mRoot.setActiveState(xyz, true);
1666 }
1667
1668
1669 template<typename RootNodeType>
1670 inline void
1671 Tree<RootNodeType>::setValueOn(const Coord& xyz, const ValueType& value)
1672 {
1673 mRoot.setValueOn(xyz, value);
1674 }
1675
1676
1677 template<typename RootNodeType>
1678 template<typename ModifyOp>
1679 inline void
1680 Tree<RootNodeType>::modifyValue(const Coord& xyz, const ModifyOp& op)
1681 {
1682 mRoot.modifyValue(xyz, op);
1683 }
1684
1685
1686 template<typename RootNodeType>
1687 template<typename ModifyOp>
1688 inline void
1689 Tree<RootNodeType>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1690 {
1691 mRoot.modifyValueAndActiveState(xyz, op);
1692 }
1693
1694
1695 template<typename RootNodeType>
1696 inline bool
1697 Tree<RootNodeType>::probeValue(const Coord& xyz, ValueType& value) const
1698 {
1699 return mRoot.probeValue(xyz, value);
1700 }
1701
1702
1704
1705
1706 template<typename RootNodeType>
1707 inline void
1708 Tree<RootNodeType>::addTile(Index level, const Coord& xyz,
1709 const ValueType& value, bool active)
1710 {
1711 mRoot.addTile(level, xyz, value, active);
1712 }
1713
1714
1715 template<typename RootNodeType>
1716 template<typename NodeT>
1717 inline NodeT*
1718 Tree<RootNodeType>::stealNode(const Coord& xyz, const ValueType& value, bool active)
1719 {
1720 this->clearAllAccessors();
1721 return mRoot.template stealNode<NodeT>(xyz, value, active);
1722 }
1723
1724
1725 template<typename RootNodeType>
1726 inline typename RootNodeType::LeafNodeType*
1727 Tree<RootNodeType>::touchLeaf(const Coord& xyz)
1728 {
1729 return mRoot.touchLeaf(xyz);
1730 }
1731
1732
1733 template<typename RootNodeType>
1734 inline typename RootNodeType::LeafNodeType*
1735 Tree<RootNodeType>::probeLeaf(const Coord& xyz)
1736 {
1737 return mRoot.probeLeaf(xyz);
1738 }
1739
1740
1741 template<typename RootNodeType>
1742 inline const typename RootNodeType::LeafNodeType*
1743 Tree<RootNodeType>::probeConstLeaf(const Coord& xyz) const
1744 {
1745 return mRoot.probeConstLeaf(xyz);
1746 }
1747
1748
1749 template<typename RootNodeType>
1750 template<typename NodeType>
1751 inline NodeType*
1752 Tree<RootNodeType>::probeNode(const Coord& xyz)
1753 {
1754 return mRoot.template probeNode<NodeType>(xyz);
1755 }
1756
1757
1758 template<typename RootNodeType>
1759 template<typename NodeType>
1760 inline const NodeType*
1761 Tree<RootNodeType>::probeNode(const Coord& xyz) const
1762 {
1763 return this->template probeConstNode<NodeType>(xyz);
1764 }
1765
1766
1767 template<typename RootNodeType>
1768 template<typename NodeType>
1769 inline const NodeType*
1770 Tree<RootNodeType>::probeConstNode(const Coord& xyz) const
1771 {
1772 return mRoot.template probeConstNode<NodeType>(xyz);
1773 }
1774
1775
1777
1778
1779 template<typename RootNodeType>
1780 inline void
1781 Tree<RootNodeType>::clip(const CoordBBox& bbox)
1782 {
1783 this->clearAllAccessors();
1784 return mRoot.clip(bbox);
1785 }
1786
1787
1788 #ifndef OPENVDB_2_ABI_COMPATIBLE
1789 template<typename RootNodeType>
1790 inline void
1791 Tree<RootNodeType>::clipUnallocatedNodes()
1792 {
1793 this->clearAllAccessors();
1794 for (LeafIter it = this->beginLeaf(); it; ) {
1795 const LeafNodeType* leaf = it.getLeaf();
1796 ++it; // advance the iterator before deleting the leaf node
1797 if (!leaf->isAllocated()) {
1798 this->addTile(/*level=*/0, leaf->origin(), this->background(), /*active=*/false);
1799 }
1800 }
1801 }
1802
1803 #ifndef OPENVDB_3_ABI_COMPATIBLE
1804 template<typename RootNodeType>
1805 inline Index32
1806 Tree<RootNodeType>::unallocatedLeafCount() const
1807 {
1808 Index32 sum = 0;
1809 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
1810 return sum;
1811 }
1812 #endif
1813 #endif
1814
1815
1816 template<typename RootNodeType>
1817 inline void
1818 Tree<RootNodeType>::sparseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1819 {
1820 this->clearAllAccessors();
1821 return mRoot.sparseFill(bbox, value, active);
1822 }
1823
1824
1825 template<typename RootNodeType>
1826 inline void
1827 Tree<RootNodeType>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1828 {
1829 this->clearAllAccessors();
1830 return mRoot.denseFill(bbox, value, active);
1831 }
1832
1833
1834 template<typename RootNodeType>
1835 inline void
1836 Tree<RootNodeType>::voxelizeActiveTiles(bool threaded)
1837 {
1838 this->clearAllAccessors();
1839 mRoot.voxelizeActiveTiles(threaded);
1840 }
1841
1842
1843 template<typename RootNodeType>
1844 Metadata::Ptr
1845 Tree<RootNodeType>::getBackgroundValue() const
1846 {
1847 Metadata::Ptr result;
1848 if (Metadata::isRegisteredType(valueType())) {
1849 using MetadataT = TypedMetadata<ValueType>;
1850 result = Metadata::createMetadata(valueType());
1851 if (result->typeName() == MetadataT::staticTypeName()) {
1852 MetadataT* m = static_cast<MetadataT*>(result.get());
1853 m->value() = mRoot.background();
1854 }
1855 }
1856 return result;
1857 }
1858
1859
1861
1862
1863 template<typename RootNodeType>
1864 inline void
1865 Tree<RootNodeType>::merge(Tree& other, MergePolicy policy)
1866 {
1867 this->clearAllAccessors();
1868 other.clearAllAccessors();
1869 switch (policy) {
1870 case MERGE_ACTIVE_STATES:
1871 mRoot.template merge<MERGE_ACTIVE_STATES>(other.mRoot); break;
1872 case MERGE_NODES:
1873 mRoot.template merge<MERGE_NODES>(other.mRoot); break;
1874 case MERGE_ACTIVE_STATES_AND_NODES:
1875 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.mRoot); break;
1876 }
1877 }
1878
1879
1880 template<typename RootNodeType>
1881 template<typename OtherRootNodeType>
1882 inline void
1883 Tree<RootNodeType>::topologyUnion(const Tree<OtherRootNodeType>& other)
1884 {
1885 this->clearAllAccessors();
1886 mRoot.topologyUnion(other.root());
1887 }
1888
1889 template<typename RootNodeType>
1890 template<typename OtherRootNodeType>
1891 inline void
1892 Tree<RootNodeType>::topologyIntersection(const Tree<OtherRootNodeType>& other)
1893 {
1894 this->clearAllAccessors();
1895 mRoot.topologyIntersection(other.root());
1896 }
1897
1898 template<typename RootNodeType>
1899 template<typename OtherRootNodeType>
1900 inline void
1901 Tree<RootNodeType>::topologyDifference(const Tree<OtherRootNodeType>& other)
1902 {
1903 this->clearAllAccessors();
1904 mRoot.topologyDifference(other.root());
1905 }
1906
1908
1909
1912 template<typename AValueT, typename CombineOp, typename BValueT = AValueT>
1913 struct CombineOpAdapter
1914 {
1915 CombineOpAdapter(CombineOp& _op): op(_op) {}
1916
1917 void operator()(CombineArgs<AValueT, BValueT>& args) const {
1918 op(args.a(), args.b(), args.result());
1919 }
1920
1921 CombineOp& op;
1922 };
1923
1924
1925 template<typename RootNodeType>
1926 template<typename CombineOp>
1927 inline void
1928 Tree<RootNodeType>::combine(Tree& other, CombineOp& op, bool prune)
1929 {
1930 CombineOpAdapter<ValueType, CombineOp> extendedOp(op);
1931 this->combineExtended(other, extendedOp, prune);
1932 }
1933
1934
1937 #ifndef _MSC_VER
1938 template<typename RootNodeType>
1939 template<typename CombineOp>
1940 inline void
1941 Tree<RootNodeType>::combine(Tree& other, const CombineOp& op, bool prune)
1942 {
1943 CombineOpAdapter<ValueType, const CombineOp> extendedOp(op);
1944 this->combineExtended(other, extendedOp, prune);
1945 }
1946 #endif
1947
1948
1949 template<typename RootNodeType>
1950 template<typename ExtendedCombineOp>
1951 inline void
1952 Tree<RootNodeType>::combineExtended(Tree& other, ExtendedCombineOp& op, bool prune)
1953 {
1954 this->clearAllAccessors();
1955 mRoot.combine(other.root(), op, prune);
1956 }
1957
1958
1961 #ifndef _MSC_VER
1962 template<typename RootNodeType>
1963 template<typename ExtendedCombineOp>
1964 inline void
1965 Tree<RootNodeType>::combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune)
1966 {
1967 this->clearAllAccessors();
1968 mRoot.template combine<const ExtendedCombineOp>(other.mRoot, op, prune);
1969 }
1970 #endif
1971
1972
1973 template<typename RootNodeType>
1974 template<typename CombineOp, typename OtherTreeType>
1975 inline void
1976 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune)
1977 {
1978 CombineOpAdapter<ValueType, CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1979 this->combine2Extended(a, b, extendedOp, prune);
1980 }
1981
1982
1985 #ifndef _MSC_VER
1986 template<typename RootNodeType>
1987 template<typename CombineOp, typename OtherTreeType>
1988 inline void
1989 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune)
1990 {
1991 CombineOpAdapter<ValueType, const CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1992 this->combine2Extended(a, b, extendedOp, prune);
1993 }
1994 #endif
1995
1996
1997 template<typename RootNodeType>
1998 template<typename ExtendedCombineOp, typename OtherTreeType>
1999 inline void
2000 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
2001 ExtendedCombineOp& op, bool prune)
2002 {
2003 this->clearAllAccessors();
2004 mRoot.combine2(a.root(), b.root(), op, prune);
2005 }
2006
2007
2011 #ifndef _MSC_VER
2012 template<typename RootNodeType>
2013 template<typename ExtendedCombineOp, typename OtherTreeType>
2014 inline void
2015 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
2016 const ExtendedCombineOp& op, bool prune)
2017 {
2018 this->clearAllAccessors();
2019 mRoot.template combine2<const ExtendedCombineOp>(a.root(), b.root(), op, prune);
2020 }
2021 #endif
2022
2023
2025
2026
2027 template<typename RootNodeType>
2028 template<typename VisitorOp>
2029 inline void
2030 Tree<RootNodeType>::visit(VisitorOp& op)
2031 {
2032 this->clearAllAccessors();
2033 mRoot.template visit<VisitorOp>(op);
2034 }
2035
2036
2037 template<typename RootNodeType>
2038 template<typename VisitorOp>
2039 inline void
2040 Tree<RootNodeType>::visit(VisitorOp& op) const
2041 {
2042 mRoot.template visit<VisitorOp>(op);
2043 }
2044
2045
2048 template<typename RootNodeType>
2049 template<typename VisitorOp>
2050 inline void
2051 Tree<RootNodeType>::visit(const VisitorOp& op)
2052 {
2053 this->clearAllAccessors();
2054 mRoot.template visit<const VisitorOp>(op);
2055 }
2056
2057
2060 template<typename RootNodeType>
2061 template<typename VisitorOp>
2062 inline void
2063 Tree<RootNodeType>::visit(const VisitorOp& op) const
2064 {
2065 mRoot.template visit<const VisitorOp>(op);
2066 }
2067
2068
2070
2071
2072 template<typename RootNodeType>
2073 template<typename OtherTreeType, typename VisitorOp>
2074 inline void
2075 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op)
2076 {
2077 this->clearAllAccessors();
2078 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2079 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2080 }
2081
2082
2083 template<typename RootNodeType>
2084 template<typename OtherTreeType, typename VisitorOp>
2085 inline void
2086 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op) const
2087 {
2088 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2089 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2090 }
2091
2092
2095 template<typename RootNodeType>
2096 template<typename OtherTreeType, typename VisitorOp>
2097 inline void
2098 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op)
2099 {
2100 this->clearAllAccessors();
2101 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2102 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2103 }
2104
2105
2108 template<typename RootNodeType>
2109 template<typename OtherTreeType, typename VisitorOp>
2110 inline void
2111 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op) const
2112 {
2113 using OtherRootNodeType = typename OtherTreeType::RootNodeType;
2114 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2115 }
2116
2117
2119
2120
2121 template<typename RootNodeType>
2122 inline const Name&
2123 Tree<RootNodeType>::treeType()
2124 {
2125 if (sTreeTypeName == nullptr) {
2126 std::vector<Index> dims;
2127 Tree::getNodeLog2Dims(dims);
2128 std::ostringstream ostr;
2129 ostr << "Tree_" << typeNameAsString<BuildType>();
2130 for (size_t i = 1, N = dims.size(); i < N; ++i) { // start from 1 to skip the RootNode
2131 ostr << "_" << dims[i];
2132 }
2133 Name* s = new Name(ostr.str());
2134 if (sTreeTypeName.compare_and_swap(s, nullptr) != nullptr) delete s;
2135 }
2136 return *sTreeTypeName;
2137 }
2138
2139
2140 template<typename RootNodeType>
2141 template<typename OtherRootNodeType>
2142 inline bool
2143 Tree<RootNodeType>::hasSameTopology(const Tree<OtherRootNodeType>& other) const
2144 {
2145 return mRoot.hasSameTopology(other.root());
2146 }
2147
2148
2149 template<typename RootNodeType>
2150 Index64
2151 Tree<RootNodeType>::inactiveVoxelCount() const
2152 {
2153 Coord dim(0, 0, 0);
2154 this->evalActiveVoxelDim(dim);
2155 const Index64
2156 totalVoxels = dim.x() * dim.y() * dim.z(),
2157 activeVoxels = this->activeVoxelCount();
2158 assert(totalVoxels >= activeVoxels);
2159 return totalVoxels - activeVoxels;
2160 }
2161
2162
2163 template<typename RootNodeType>
2164 inline bool
2165 Tree<RootNodeType>::evalLeafBoundingBox(CoordBBox& bbox) const
2166 {
2167 bbox.reset(); // default invalid bbox
2168
2169 if (this->empty()) return false; // empty
2170
2171 mRoot.evalActiveBoundingBox(bbox, false);
2172
2173 return true;// not empty
2174 }
2175
2176 template<typename RootNodeType>
2177 inline bool
2178 Tree<RootNodeType>::evalActiveVoxelBoundingBox(CoordBBox& bbox) const
2179 {
2180 bbox.reset(); // default invalid bbox
2181
2182 if (this->empty()) return false; // empty
2183
2184 mRoot.evalActiveBoundingBox(bbox, true);
2185
2186 return true;// not empty
2187 }
2188
2189
2190 template<typename RootNodeType>
2191 inline bool
2192 Tree<RootNodeType>::evalActiveVoxelDim(Coord& dim) const
2193 {
2194 CoordBBox bbox;
2195 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2196 dim = bbox.extents();
2197 return notEmpty;
2198 }
2199
2200
2201 template<typename RootNodeType>
2202 inline bool
2203 Tree<RootNodeType>::evalLeafDim(Coord& dim) const
2204 {
2205 CoordBBox bbox;
2206 bool notEmpty = this->evalLeafBoundingBox(bbox);
2207 dim = bbox.extents();
2208 return notEmpty;
2209 }
2210
2211
2212 template<typename RootNodeType>
2213 inline void
2214 Tree<RootNodeType>::evalMinMax(ValueType& minVal, ValueType& maxVal) const
2215 {
2216 minVal = maxVal = zeroVal<ValueType>();
2217 if (ValueOnCIter iter = this->cbeginValueOn()) {
2218 minVal = maxVal = *iter;
2219 for (++iter; iter; ++iter) {
2220 const ValueType& val = *iter;
2221 if (val < minVal) minVal = val;
2222 if (val > maxVal) maxVal = val;
2223 }
2224 }
2225 }
2226
2227
2228 template<typename RootNodeType>
2229 inline void
2230 Tree<RootNodeType>::getNodeLog2Dims(std::vector<Index>& dims)
2231 {
2232 dims.clear();
2233 RootNodeType::getNodeLog2Dims(dims);
2234 }
2235
2236
2237 template<typename RootNodeType>
2238 inline void
2239 Tree<RootNodeType>::print(std::ostream& os, int verboseLevel) const
2240 {
2241 if (verboseLevel <= 0) return;
2242
2244 struct OnExit {
2245 std::ostream& os;
2246 std::streamsize savedPrecision;
2247 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2248 ~OnExit() { os.precision(savedPrecision); }
2249 };
2250 OnExit restorePrecision(os);
2251
2252 std::vector<Index> dims;
2253 Tree::getNodeLog2Dims(dims);
2254
2255 os << "Information about Tree:\n"
2256 << " Type: " << this->type() << "\n";
2257
2258 os << " Configuration:\n";
2259
2260 if (verboseLevel <= 1) {
2261 // Print node types and sizes.
2262 os << " Root(" << mRoot.getTableSize() << ")";
2263 if (dims.size() > 1) {
2264 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2265 os << ", Internal(" << (1 << dims[i]) << "^3)";
2266 }
2267 os << ", Leaf(" << (1 << *dims.rbegin()) << "^3)\n";
2268 }
2269 os << " Background value: " << mRoot.background() << "\n";
2270 return;
2271 }
2272
2273 // The following is tree information that is expensive to extract.
2274
2275 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2276 if (verboseLevel > 3) {
2277 // This forces loading of all non-resident nodes.
2278 this->evalMinMax(minVal, maxVal);
2279 }
2280
2281 std::vector<Index64> nodeCount(dims.size());
2282 for (NodeCIter it = cbeginNode(); it; ++it) ++(nodeCount[it.getDepth()]);
2283
2284 Index64 totalNodeCount = 0;
2285 for (size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2286
2287 // Print node types, counts and sizes.
2288 os << " Root(1 x " << mRoot.getTableSize() << ")";
2289 if (dims.size() > 1) {
2290 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2291 os << ", Internal(" << util::formattedInt(nodeCount[i]);
2292 os << " x " << (1 << dims[i]) << "^3)";
2293 }
2294 os << ", Leaf(" << util::formattedInt(*nodeCount.rbegin());
2295 os << " x " << (1 << *dims.rbegin()) << "^3)\n";
2296 }
2297 os << " Background value: " << mRoot.background() << "\n";
2298
2299 // Statistics of topology and values
2300
2301 if (verboseLevel > 3) {
2302 os << " Min value: " << minVal << "\n";
2303 os << " Max value: " << maxVal << "\n";
2304 }
2305
2306 const Index64
2307 leafCount = *nodeCount.rbegin(),
2308 numActiveVoxels = this->activeVoxelCount(),
2309 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2310 numActiveTiles = this->activeTileCount();
2311
2312 os << " Number of active voxels: " << util::formattedInt(numActiveVoxels) << "\n";
2313 os << " Number of active tiles: " << util::formattedInt(numActiveTiles) << "\n";
2314
2315 Coord dim(0, 0, 0);
2316 Index64 totalVoxels = 0;
2317 if (numActiveVoxels) { // nonempty
2318 CoordBBox bbox;
2319 this->evalActiveVoxelBoundingBox(bbox);
2320 dim = bbox.extents();
2321 totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2322
2323 os << " Bounding box of active voxels: " << bbox << "\n";
2324 os << " Dimensions of active voxels: "
2325 << dim[0] << " x " << dim[1] << " x " << dim[2] << "\n";
2326
2327 const double activeRatio = (100.0 * double(numActiveVoxels)) / double(totalVoxels);
2328 os << " Percentage of active voxels: " << std::setprecision(3) << activeRatio << "%\n";
2329
2330 if (leafCount > 0) {
2331 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2332 / (double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2333 os << " Average leaf node fill ratio: " << fillRatio << "%\n";
2334 }
2335
2336 #ifndef OPENVDB_2_ABI_COMPATIBLE
2337 if (verboseLevel > 2) {
2338 Index64 sum = 0;// count the number of unallocated leaf nodes
2339 for (auto it = this->cbeginLeaf(); it; ++it) if (!it->isAllocated()) ++sum;
2340 os << " Number of unallocated nodes: "
2341 << util::formattedInt(sum) << " ("
2342 << (100.0 * double(sum) / double(totalNodeCount)) << "%)\n";
2343 }
2344 #endif
2345 } else {
2346 os << " Tree is empty!\n";
2347 }
2348 os << std::flush;
2349
2350 if (verboseLevel == 2) return;
2351
2352 // Memory footprint in bytes
2353 const Index64
2354 actualMem = this->memUsage(),
2355 denseMem = sizeof(ValueType) * totalVoxels,
2356 voxelsMem = sizeof(ValueType) * numActiveLeafVoxels;
2358
2359 os << "Memory footprint:\n";
2360 util::printBytes(os, actualMem, " Actual: ");
2361 util::printBytes(os, voxelsMem, " Active leaf voxels: ");
2362
2363 if (numActiveVoxels) {
2364 util::printBytes(os, denseMem, " Dense equivalent: ");
2365 os << " Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2366 << "% of an equivalent dense volume\n";
2367 os << " Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2368 << "% of actual footprint\n";
2369 }
2370 }
2371
2372 } // namespace tree
2373 } // namespace OPENVDB_VERSION_NAME
2374 } // namespace openvdb
2375
2376 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
2377
2378 // Copyright (c) 2012-2017 DreamWorks Animation LLC
2379 // All rights reserved. This software is distributed under the
2380 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v4_0_2::tree::CombineOpAdapter::operator()
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1917
openvdb::v4_0_2::tree::Tree::releaseAccessor
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:677
openvdb::v4_0_2::tree::Tree::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Get the value of the voxel at the given coordinates.
Definition: Tree.h:1697
openvdb::v4_0_2::tree::Tree::leafCount
Index32 leafCount() const override
Return the number of leaf nodes.
Definition: Tree.h:370
openvdb::v4_0_2::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:1259
openvdb::v4_0_2::tree::Tree
Definition: Tree.h:205
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
openvdb::v4_0_2::tree::TreeBase::ConstPtr
SharedPtr< const TreeBase > ConstPtr
Definition: Tree.h:68
openvdb::v4_0_2::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:634
openvdb::v4_0_2::tree::Tree::beginLeaf
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1181
openvdb::v4_0_2::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:375
openvdb::v4_0_2::tree::Tree::cbeginValueOff
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1208
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::LeafIter >::begin
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1374
openvdb::v4_0_2::tree::Tree::mAccessorRegistry
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1244
Types.h
openvdb::v4_0_2::tree::Tree::ValueType
typename RootNodeType::ValueType ValueType
Definition: Tree.h:212
OPENVDB_DEPRECATED
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
openvdb::v4_0_2::tree::Tree::memUsage
Index64 memUsage() const override
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:387
Formats.h
Utility routines to output nicely-formatted numeric values.
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffIter >::begin
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1342
openvdb::v4_0_2::tree::TreeBase::print
virtual void print(std::ostream &os=std::cout, int verboseLevel=1) const
Print statistics, memory usage and other information about this tree.
Definition: Tree.h:1305
openvdb::v4_0_2::tree::Tree::stealNodes
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:636
openvdb::v4_0_2::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: Types.h:130
openvdb::v4_0_2::tree::Tree::sTreeTypeName
static tbb::atomic< const Name * > sTreeTypeName
Definition: Tree.h:1247
openvdb::v4_0_2::MERGE_NODES
Definition: Types.h:317
openvdb::v4_0_2::math::Coord::z
Int32 z() const
Definition: Coord.h:156
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v4_0_2::tree::Tree::addLeaf
OPENVDB_DEPRECATED 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:544
openvdb::v4_0_2::tree::Tree::valueType
Name valueType() const override
Return the name of the type of a voxel&#39;s value (e.g., "float" or "vec3d")
Definition: Tree.h:297
openvdb::v4_0_2::tree::Tree::Tree
Tree()
Definition: Tree.h:230
openvdb::v4_0_2::NotImplementedError
Definition: Exceptions.h:88
Metadata.h
openvdb::v4_0_2::tree::Tree::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: Tree.h:1616
openvdb::v4_0_2::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:531
openvdb::v4_0_2::tree::CombineOpAdapter
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1913
openvdb::v4_0_2::util::formattedInt
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnCIter >::begin
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1336
openvdb::v4_0_2::tree::NodeIteratorBase
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:977
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllCIter >::begin
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1402
openvdb::v4_0_2::tree::Tree::activeLeafVoxelCount
Index64 activeLeafVoxelCount() const override
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:374
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
openvdb::v4_0_2::math::Coord::y
Int32 y() const
Definition: Coord.h:155
openvdb::v4_0_2::Index32
uint32_t Index32
Definition: Types.h:55
openvdb::v4_0_2::tree::ValueAccessorBase
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:121
openvdb::v4_0_2::tree::Tree::root
RootNodeType & root()
Return this tree&#39;s root node.
Definition: Tree.h:309
openvdb::v4_0_2::tree::Tree::cbeginValueOn
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1202
openvdb::v4_0_2::tree::Tree::cbeginRootTiles
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1147
i
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
openvdb::v4_0_2::tree::Tree::isValueOn
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:470
openvdb::v4_0_2::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:1708
openvdb::v4_0_2::tree::Tree::activeTileCount
Index64 activeTileCount() const override
Return the total number of active tiles.
Definition: Tree.h:382
openvdb::v4_0_2::tree::Tree::cbeginRootDense
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1154
openvdb::v4_0_2::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:261
openvdb::v4_0_2::tree::Tree::Tree
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:289
openvdb::v4_0_2::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:2143
openvdb::v4_0_2::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:1640
BBox.h
openvdb::v4_0_2::Index
Index32 Index
Definition: Types.h:57
openvdb::v4_0_2::tree::Tree::probeLeaf
const LeafNodeType * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: Tree.h:580
openvdb::v4_0_2::tree::Tree::beginRootTiles
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1148
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::NodeCIter >::begin
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1370
logging.h
openvdb::v4_0_2::tree::Tree::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don&#39;t change its active state.
Definition: Tree.h:1647
openvdb::v4_0_2::tree::Tree::getIndexRange
void getIndexRange(CoordBBox &bbox) const override
Min and max are both inclusive.
Definition: Tree.h:692
openvdb::v4_0_2::tree::Tree::cbeginRootChildren
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:1140
openvdb::v4_0_2::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:1001
openvdb::v4_0_2::tree::Tree::getNodes
void getNodes(ArrayT &array) const
Adds all nodes of a certain type to a container with the following API:
Definition: Tree.h:607
openvdb::v4_0_2::tree::Tree::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: Tree.h:1689
openvdb::v4_0_2::tree::Tree::root
const RootNodeType & root() const
Return this tree&#39;s root node.
Definition: Tree.h:310
openvdb::v4_0_2::tree::Tree::attachAccessor
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:665
openvdb::v4_0_2::tree::Tree::setActiveState
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don&#39;t change its value.
Definition: Tree.h:1632
openvdb::v4_0_2::tree::Tree::DeallocateNodes::DeallocateNodes
DeallocateNodes(std::vector< NodeType *> &nodes)
Definition: Tree.h:1230
openvdb::v4_0_2::MERGE_ACTIVE_STATES
Definition: Types.h:316
openvdb::v4_0_2::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
openvdb::v4_0_2::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:261
openvdb::v4_0_2::CombineArgs::b
const BValueType & b() const
Get the B input value.
Definition: Types.h:413
openvdb::v4_0_2::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
openvdb::v4_0_2::CombineArgs::result
const AValueType & result() const
Get the output value.
Definition: Types.h:416
openvdb::v4_0_2::Index64
uint64_t Index64
Definition: Types.h:56
openvdb::v4_0_2::tree::Tree::operator!=
bool operator!=(const Tree &) const
Definition: Tree.h:305
openvdb::v4_0_2::tree::TreeBase::memUsage
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:160
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::NodeIter >::begin
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1366
openvdb::v4_0_2::tree::Tree::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1591
openvdb::v4_0_2::tree::Tree::background
const ValueType & background() const
Return this tree&#39;s background value.
Definition: Tree.h:689
openvdb::v4_0_2::Name
std::string Name
Definition: Name.h:44
TreeIterator.h
InternalNode.h
Internal table nodes for OpenVDB trees.
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffIter >::begin
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1390
openvdb::v4_0_2::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:361
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnCIter >::begin
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1386
openvdb::v4_0_2::tree::Tree5
Tree5<T, N1, N2, N3, N4>::Type is the type of a five-level tree (Root, Internal, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2, N3 and N4, respectively.
Definition: Tree.h:1278
openvdb::v4_0_2::tree::Tree::isValueOff
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:472
openvdb::v4_0_2::math::CoordBBox::extents
Coord extents() const
Definition: Coord.h:383
openvdb::v4_0_2::TreeBase
tree::TreeBase TreeBase
Definition: Grid.h:53
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllCIter >::begin
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1360
openvdb::v4_0_2::tree::Tree::cbeginNode
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1175
openvdb::v4_0_2::TypedMetadata
Templated metadata class to hold specific types.
Definition: Metadata.h:138
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllIter >::begin
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1354
openvdb::v4_0_2::tree::TreeBase::getBackgroundValue
virtual Metadata::Ptr getBackgroundValue() const
Return this tree&#39;s background value wrapped as metadata.
Definition: Tree.h:89
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form &#39;someVar << "some text" << ...&#39;.
Definition: logging.h:279
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::LeafCIter >::begin
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1378
openvdb::v4_0_2::Metadata::isRegisteredType
static bool isRegisteredType(const Name &typeName)
Return true if the given type is known by the metadata type registry.
openvdb::v4_0_2::tree::Tree::mConstAccessorRegistry
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1245
openvdb::v4_0_2::tree::Tree::ConstAccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1221
openvdb::v4_0_2::tree::Tree::beginRootDense
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1155
openvdb::v4_0_2::CombineArgs::a
const AValueType & a() const
Get the A input value.
Definition: Types.h:411
openvdb
Definition: Exceptions.h:39
openvdb::v4_0_2::tree::Tree::beginNode
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1174
openvdb::v4_0_2::tree::Tree::BuildType
typename RootNodeType::BuildType BuildType
Definition: Tree.h:213
openvdb::v4_0_2::tree::Tree::cbeginLeaf
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1182
openvdb::v4_0_2::tree::LeafIteratorBase
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1228
openvdb::v4_0_2::tree::Tree::clear
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1489
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffCIter >::begin
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1394
openvdb::v4_0_2::CombineArgs
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:371
openvdb::v4_0_2::tree::TreeValueIteratorBase
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:658
openvdb::v4_0_2::tree::TreeIterTraits
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1327
openvdb::v4_0_2::tree::Tree::inactiveLeafVoxelCount
Index64 inactiveLeafVoxelCount() const override
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:376
openvdb::v4_0_2::tree::Tree::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:214
openvdb::v4_0_2::tree::Tree::clearAllAccessors
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1548
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnIter >::begin
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1330
LeafNode.h
openvdb::v4_0_2::util::printBytes
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\, bool exact=false, int width=8, int precision=3)
openvdb::v4_0_2::tree::Tree::Tree
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:235
openvdb::v4_0_2::tree::Tree::probeConstLeaf
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: Tree.h:1743
openvdb::v4_0_2::MERGE_ACTIVE_STATES_AND_NODES
Definition: Types.h:318
openvdb::v4_0_2::tree::Tree::writeBuffers
void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const override
Write out all data buffers for this tree.
Definition: Tree.h:1481
openvdb::v4_0_2::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:225
openvdb::v4_0_2::tree::Tree::DeallocateNodes::operator()
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1232
ValueAccessor.h
openvdb::v4_0_2::tree::Tree::AccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1220
openvdb::v4_0_2::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, create one that preserves the values and active states of all voxels.
Definition: Tree.h:1727
openvdb::v4_0_2::tree::Tree::Tree
Tree(const OtherTreeType &other, const ValueType &background, TopologyCopy)
Topology copy constructor from a tree of a different type.
Definition: Tree.h:282
openvdb::v4_0_2::tree::CombineOpAdapter::op
CombineOp & op
Definition: Tree.h:1921
openvdb::v4_0_2::tree::Tree::operator==
bool operator==(const Tree &) const
Definition: Tree.h:304
openvdb::v4_0_2::math::Coord::x
Int32 x() const
Definition: Coord.h:154
openvdb::v4_0_2::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:1680
openvdb::v4_0_2::tree::Tree::DeallocateNodes
Definition: Tree.h:1229
openvdb::v4_0_2::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:1608
openvdb::v4_0_2::Metadata::createMetadata
static Metadata::Ptr createMetadata(const Name &typeName)
Create new metadata of the given type.
openvdb::v4_0_2::MergePolicy
MergePolicy
Definition: Types.h:315
RootNode.h
The root node of an OpenVDB tree.
openvdb::v4_0_2::tree::Tree::beginRootChildren
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
Definition: Tree.h:1141
openvdb::v4_0_2::tree::Tree::mRoot
RootNodeType mRoot
Definition: Tree.h:1243
openvdb::v4_0_2::tree::Tree::activeVoxelCount
Index64 activeVoxelCount() const override
Return the total number of active voxels.
Definition: Tree.h:378
openvdb::v4_0_2::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
openvdb::v4_0_2::tree::Tree::~Tree
~Tree() override
Definition: Tree.h:291
openvdb::v4_0_2::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
openvdb::v4_0_2::tree::Tree4
Tree4<T, N1, N2, N3>::Type is the type of a four-level tree (Root, Internal, Internal, Leaf) with value type T and internal and leaf node log dimensions N1, N2 and N3, respectively.
Definition: Tree.h:1269
openvdb::v4_0_2::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:647
openvdb::v4_0_2::tree::Tree::DeallocateNodes::mNodes
NodeType **const mNodes
Definition: Tree.h:1237
openvdb::v4_0_2::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, return nullptr.
Definition: Tree.h:1735
openvdb::v4_0_2::tree::Tree::copy
TreeBase::Ptr copy() const override
Return a pointer to a deep copy of this tree.
Definition: Tree.h:294
openvdb::v4_0_2::tree::Tree::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: Tree.h:1663
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllIter >::begin
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1398
openvdb::v4_0_2::tree::Tree::fill
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: Tree.h:502
openvdb::v4_0_2::tree::Tree::treeDepth
Index treeDepth() const override
Return the depth of this tree.
Definition: Tree.h:368
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnIter >::begin
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1382
openvdb::v4_0_2::tree::Tree::beginValueAll
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1195
openvdb::v4_0_2::tree::Tree::nonLeafCount
Index32 nonLeafCount() const override
Return the number of non-leaf nodes.
Definition: Tree.h:372
openvdb::v4_0_2::tree::Tree::beginValueOff
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1207
openvdb::v4_0_2::tree::TreeBase
Base class for typed trees.
Definition: Tree.h:64
openvdb::v4_0_2::math::CoordBBox::reset
void reset()
Definition: Coord.h:340
openvdb::v4_0_2::tree::TreeBase::Ptr
SharedPtr< TreeBase > Ptr
Definition: Tree.h:67
openvdb::v4_0_2::tree::Tree::type
const Name & type() const override
Return the name of this type of tree.
Definition: Tree.h:302
openvdb::v4_0_2::tree::Tree::RootNodeType
_RootNodeType RootNodeType
Definition: Tree.h:211
openvdb::v4_0_2::tree::TreeBase::writeTopology
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1297
openvdb::v4_0_2::tree::TreeBase::readTopology
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1288
openvdb::v4_0_2::tree::Tree::cbeginValueAll
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1196
openvdb::v4_0_2::tree::Tree::Tree
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:246
openvdb::v4_0_2::tree::Tree::beginValueOn
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1201
openvdb::v4_0_2::Metadata::Ptr
SharedPtr< Metadata > Ptr
Definition: Metadata.h:51
openvdb::v4_0_2::tree::CombineOpAdapter::CombineOpAdapter
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1915
Platform.h
openvdb::v4_0_2::tree::Tree::hasActiveTiles
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:474
openvdb::v4_0_2::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffCIter >::begin
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1348