OpenVDB: Tree.h Source File

OpenVDB 3.2.0

Tree.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 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 <iostream>
39 #include <sstream>
40 #include <vector>
41 #include <boost/shared_ptr.hpp>
42 #include <boost/cstdint.hpp>
43 #include <tbb/atomic.h>
44 #include <tbb/concurrent_hash_map.h>
45 #include <openvdb/Types.h>
46 #include <openvdb/metadata/Metadata.h>
47 #include <openvdb/math/Math.h>
48 #include <openvdb/math/BBox.h>
49 #include <openvdb/util/Formats.h>
50 #include <openvdb/util/logging.h>
51 #include <openvdb/Platform.h>
52 #include "RootNode.h"
53 #include "InternalNode.h"
54 #include "LeafNode.h"
55 #include "TreeIterator.h"
56 #include "ValueAccessor.h"
57
58
59 namespace openvdb {
60 OPENVDB_USE_VERSION_NAMESPACE
61 namespace OPENVDB_VERSION_NAME {
62 namespace tree {
63
65 class OPENVDB_API TreeBase
66 {
67 public:
68 typedef boost::shared_ptr<TreeBase> Ptr;
69 typedef boost::shared_ptr<const TreeBase> ConstPtr;
70
71 TreeBase() {}
72 virtual ~TreeBase() {}
73
75 virtual const Name& type() const = 0;
76
78 virtual Name valueType() const = 0;
79
81 virtual TreeBase::Ptr copy() const = 0;
82
83 //
84 // Tree methods
85 //
88 virtual Metadata::Ptr getBackgroundValue() const { return Metadata::Ptr(); }
89
97 virtual bool evalLeafBoundingBox(CoordBBox& bbox) const = 0;
98
102 virtual bool evalLeafDim(Coord& dim) const = 0;
103
111 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const = 0;
112
116 virtual bool evalActiveVoxelDim(Coord& dim) const = 0;
117
118 virtual void getIndexRange(CoordBBox& bbox) const = 0;
119
120 #ifndef OPENVDB_2_ABI_COMPATIBLE
121 virtual void clipUnallocatedNodes() = 0;
127 #endif
128
129
130 //
131 // Statistics
132 //
136 virtual Index treeDepth() const = 0;
138 virtual Index32 leafCount() const = 0;
140 virtual Index32 nonLeafCount() const = 0;
142 virtual Index64 activeLeafVoxelCount() const = 0;
144 virtual Index64 inactiveLeafVoxelCount() const = 0;
146 virtual Index64 activeVoxelCount() const = 0;
148 virtual Index64 inactiveVoxelCount() const = 0;
149 #ifndef OPENVDB_2_ABI_COMPATIBLE
150 virtual Index64 activeTileCount() const = 0;
152 #endif
153
155 virtual Index64 memUsage() const { return 0; }
156
157
158 //
159 // I/O methods
160 //
164 virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
168 virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
169
171 virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false) = 0;
172 #ifndef OPENVDB_2_ABI_COMPATIBLE
173 virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false) = 0;
180 virtual void readNonresidentBuffers() const = 0;
181 #endif
182 virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const = 0;
184
192 virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
193
194 private:
195 // Disallow copying of instances of this class.
196 //TreeBase(const TreeBase& other);
197 TreeBase& operator=(const TreeBase& other);
198 };
199
200
202
203
204 template<typename _RootNodeType>
205 class Tree: public TreeBase
206 {
207 public:
208 typedef boost::shared_ptr<Tree> Ptr;
209 typedef boost::shared_ptr<const Tree> ConstPtr;
210
211 typedef _RootNodeType RootNodeType;
212 typedef typename RootNodeType::ValueType ValueType;
213 typedef typename RootNodeType::BuildType BuildType;
214 typedef typename RootNodeType::LeafNodeType LeafNodeType;
215
216 static const Index DEPTH = RootNodeType::LEVEL + 1;
217
224 template<typename OtherValueType>
225 struct ValueConverter {
226 typedef Tree<typename RootNodeType::template ValueConverter<OtherValueType>::Type> Type;
227 };
228
229
230 Tree() {}
231
233 Tree(const Tree& other): TreeBase(other), mRoot(other.mRoot)
234 {
235 }
236
243 template<typename OtherRootType>
244 explicit Tree(const Tree<OtherRootType>& other): TreeBase(other), mRoot(other.root())
245 {
246 }
247
258 template<typename OtherTreeType>
259 Tree(const OtherTreeType& other,
260 const ValueType& inactiveValue,
261 const ValueType& activeValue,
262 TopologyCopy):
263 TreeBase(other),
264 mRoot(other.root(), inactiveValue, activeValue, TopologyCopy())
265 {
266 }
267
279 template<typename OtherTreeType>
280 Tree(const OtherTreeType& other, const ValueType& background, TopologyCopy):
281 TreeBase(other),
282 mRoot(other.root(), background, TopologyCopy())
283 {
284 }
285
287 Tree(const ValueType& background): mRoot(background) {}
288
289 virtual ~Tree() { this->clear(); releaseAllAccessors(); }
290
292 virtual TreeBase::Ptr copy() const { return TreeBase::Ptr(new Tree(*this)); }
293
295 virtual Name valueType() const { return typeNameAsString<ValueType>(); }
296
298 static const Name& treeType();
300 virtual const Name& type() const { return this->treeType(); }
301
302 bool operator==(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
303 bool operator!=(const Tree&) const { OPENVDB_THROW(NotImplementedError, ""); }
304
306 RootNodeType& root() { return mRoot; }
308 const RootNodeType& root() const { return mRoot; }
310
311
312 //
313 // Tree methods
314 //
317 template<typename OtherRootNodeType>
318 bool hasSameTopology(const Tree<OtherRootNodeType>& other) const;
319
320 virtual bool evalLeafBoundingBox(CoordBBox& bbox) const;
321 virtual bool evalActiveVoxelBoundingBox(CoordBBox& bbox) const;
322 virtual bool evalActiveVoxelDim(Coord& dim) const;
323 virtual bool evalLeafDim(Coord& dim) const;
324
328 static void getNodeLog2Dims(std::vector<Index>& dims);
329
330
331 //
332 // I/O methods
333 //
337 virtual void readTopology(std::istream&, bool saveFloatAsHalf = false);
341 virtual void writeTopology(std::ostream&, bool saveFloatAsHalf = false) const;
343 virtual void readBuffers(std::istream&, bool saveFloatAsHalf = false);
344 #ifndef OPENVDB_2_ABI_COMPATIBLE
345 virtual void readBuffers(std::istream&, const CoordBBox&, bool saveFloatAsHalf = false);
352 virtual void readNonresidentBuffers() const;
353 #endif
354 virtual void writeBuffers(std::ostream&, bool saveFloatAsHalf = false) const;
356
357 virtual void print(std::ostream& os = std::cout, int verboseLevel = 1) const;
358
359
360 //
361 // Statistics
362 //
366 virtual Index treeDepth() const { return DEPTH; }
368 virtual Index32 leafCount() const { return mRoot.leafCount(); }
370 virtual Index32 nonLeafCount() const { return mRoot.nonLeafCount(); }
372 virtual Index64 activeLeafVoxelCount() const { return mRoot.onLeafVoxelCount(); }
374 virtual Index64 inactiveLeafVoxelCount() const { return mRoot.offLeafVoxelCount(); }
376 virtual Index64 activeVoxelCount() const { return mRoot.onVoxelCount(); }
378 virtual Index64 inactiveVoxelCount() const;
380 Index64 activeTileCount() const { return mRoot.onTileCount(); }
381
383 void evalMinMax(ValueType &min, ValueType &max) const;
384
385 virtual Index64 memUsage() const { return sizeof(*this) + mRoot.memUsage(); }
386
387
388 //
389 // Voxel access methods (using signed indexing)
390 //
392 const ValueType& getValue(const Coord& xyz) const;
395 template<typename AccessT> const ValueType& getValue(const Coord& xyz, AccessT&) const;
396
400 int getValueDepth(const Coord& xyz) const;
401
403 void setActiveState(const Coord& xyz, bool on);
405 void setValueOnly(const Coord& xyz, const ValueType& value);
407 void setValueOn(const Coord& xyz);
409 void setValueOn(const Coord& xyz, const ValueType& value);
411 void setValue(const Coord& xyz, const ValueType& value);
414 template<typename AccessT> void setValue(const Coord& xyz, const ValueType& value, AccessT&);
416 void setValueOff(const Coord& xyz);
418 void setValueOff(const Coord& xyz, const ValueType& value);
419
438 template<typename ModifyOp>
439 void modifyValue(const Coord& xyz, const ModifyOp& op);
440
460 template<typename ModifyOp>
461 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
462
465 bool probeValue(const Coord& xyz, ValueType& value) const;
466
468 bool isValueOn(const Coord& xyz) const { return mRoot.isValueOn(xyz); }
470 bool isValueOff(const Coord& xyz) const { return !this->isValueOn(xyz); }
472 bool hasActiveTiles() const { return mRoot.hasActiveTiles(); }
473
475 void clip(const CoordBBox&);
476
477 #ifndef OPENVDB_2_ABI_COMPATIBLE
478 virtual void clipUnallocatedNodes();
484 #endif
485
487 void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
496 void fill(const CoordBBox& bbox, const ValueType& value, bool active = true)
497 {
498 this->sparseFill(bbox, value, active);
499 }
501
511 void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
512
517 void prune(const ValueType& tolerance = zeroVal<ValueType>())
518 {
519 this->clearAllAccessors();
520 mRoot.prune(tolerance);
521 }
522
524 void addLeaf(LeafNodeType* leaf) { assert(leaf); mRoot.addLeaf(leaf); }
530 OPENVDB_DEPRECATED void addLeaf(LeafNodeType& leaf) { mRoot.addLeaf(&leaf); }
532
537 void addTile(Index level, const Coord& xyz, const ValueType& value, bool active);
538
543 template<typename NodeT>
544 NodeT* stealNode(const Coord& xyz, const ValueType& value, bool active);
545
551 LeafNodeType* touchLeaf(const Coord& xyz);
552
554 template<typename NodeType> NodeType* probeNode(const Coord& xyz);
557 template<typename NodeType> const NodeType* probeConstNode(const Coord& xyz) const;
558 template<typename NodeType> const NodeType* probeNode(const Coord& xyz) const;
560
562 LeafNodeType* probeLeaf(const Coord& xyz);
565 const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
566 const LeafNodeType* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
568
570 template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
593 template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
595
619 template<typename ArrayT>
620 void stealNodes(ArrayT& array) { this->clearAllAccessors(); mRoot.stealNodes(array); }
621 template<typename ArrayT>
622 void stealNodes(ArrayT& array, const ValueType& value, bool state)
623 {
624 this->clearAllAccessors();
625 mRoot.stealNodes(array, value, state);
626 }
627
628 //
629 // Aux methods
630 //
633 bool empty() const { return mRoot.empty(); }
634
636 void clear();
637
639 void clearAllAccessors();
640
642 void attachAccessor(ValueAccessorBase<Tree, true>&) const;
645 void attachAccessor(ValueAccessorBase<const Tree, true>&) const;
647
649 void attachAccessor(ValueAccessorBase<Tree, false>&) const {}
651 void attachAccessor(ValueAccessorBase<const Tree, false>&) const {}
653
655 void releaseAccessor(ValueAccessorBase<Tree, true>&) const;
657 void releaseAccessor(ValueAccessorBase<const Tree, true>&) const;
659
661 void releaseAccessor(ValueAccessorBase<Tree, false>&) const {}
663 void releaseAccessor(ValueAccessorBase<const Tree, false>&) const {}
665
668 virtual Metadata::Ptr getBackgroundValue() const;
669
675 const ValueType& background() const { return mRoot.background(); }
676
678 virtual void getIndexRange(CoordBBox& bbox) const { mRoot.getIndexRange(bbox); }
679
686 void voxelizeActiveTiles(bool threaded = true);
687
695 void merge(Tree& other, MergePolicy = MERGE_ACTIVE_STATES);
696
710 template<typename OtherRootNodeType>
711 void topologyUnion(const Tree<OtherRootNodeType>& other);
712
726 template<typename OtherRootNodeType>
727 void topologyIntersection(const Tree<OtherRootNodeType>& other);
728
739 template<typename OtherRootNodeType>
740 void topologyDifference(const Tree<OtherRootNodeType>& other);
741
786 template<typename CombineOp>
787 void combine(Tree& other, CombineOp& op, bool prune = false);
788 #ifndef _MSC_VER
789 template<typename CombineOp>
790 void combine(Tree& other, const CombineOp& op, bool prune = false);
791 #endif
792
831 template<typename ExtendedCombineOp>
832 void combineExtended(Tree& other, ExtendedCombineOp& op, bool prune = false);
833 #ifndef _MSC_VER
834 template<typename ExtendedCombineOp>
835 void combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune = false);
836 #endif
837
866 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
867 void combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune = false);
868 #ifndef _MSC_VER
869 template<typename CombineOp, typename OtherTreeType /*= Tree*/>
870 void combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune = false);
871 #endif
872
946 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
947 void combine2Extended(const Tree& a, const OtherTreeType& b, ExtendedCombineOp& op,
948 bool prune = false);
949 #ifndef _MSC_VER
950 template<typename ExtendedCombineOp, typename OtherTreeType /*= Tree*/>
951 void combine2Extended(const Tree& a, const OtherTreeType& b, const ExtendedCombineOp&,
952 bool prune = false);
953 #endif
954
995 template<typename BBoxOp> void visitActiveBBox(BBoxOp& op) const { mRoot.visitActiveBBox(op); }
996
1050 template<typename VisitorOp> void visit(VisitorOp& op);
1051 template<typename VisitorOp> void visit(const VisitorOp& op);
1052
1057 template<typename VisitorOp> void visit(VisitorOp& op) const;
1058 template<typename VisitorOp> void visit(const VisitorOp& op) const;
1059
1107 template<typename OtherTreeType, typename VisitorOp>
1108 void visit2(OtherTreeType& other, VisitorOp& op);
1109 template<typename OtherTreeType, typename VisitorOp>
1110 void visit2(OtherTreeType& other, const VisitorOp& op);
1111
1122 template<typename OtherTreeType, typename VisitorOp>
1123 void visit2(OtherTreeType& other, VisitorOp& op) const;
1124 template<typename OtherTreeType, typename VisitorOp>
1125 void visit2(OtherTreeType& other, const VisitorOp& op) const;
1126
1127
1128 //
1129 // Iteration
1130 //
1132 typename RootNodeType::ChildOnCIter beginRootChildren() const { return mRoot.cbeginChildOn(); }
1134 typename RootNodeType::ChildOnCIter cbeginRootChildren() const { return mRoot.cbeginChildOn(); }
1135 typename RootNodeType::ChildOnIter beginRootChildren() { return mRoot.beginChildOn(); }
1137
1139 typename RootNodeType::ChildOffCIter beginRootTiles() const { return mRoot.cbeginChildOff(); }
1141 typename RootNodeType::ChildOffCIter cbeginRootTiles() const { return mRoot.cbeginChildOff(); }
1142 typename RootNodeType::ChildOffIter beginRootTiles() { return mRoot.beginChildOff(); }
1144
1146 typename RootNodeType::ChildAllCIter beginRootDense() const { return mRoot.cbeginChildAll(); }
1148 typename RootNodeType::ChildAllCIter cbeginRootDense() const { return mRoot.cbeginChildAll(); }
1149 typename RootNodeType::ChildAllIter beginRootDense() { return mRoot.beginChildAll(); }
1151
1152
1154 typedef NodeIteratorBase<Tree, typename RootNodeType::ChildOnIter> NodeIter;
1156 typedef NodeIteratorBase<const Tree, typename RootNodeType::ChildOnCIter> NodeCIter;
1158
1160 typedef LeafIteratorBase<Tree, typename RootNodeType::ChildOnIter> LeafIter;
1162 typedef LeafIteratorBase<const Tree, typename RootNodeType::ChildOnCIter> LeafCIter;
1164
1166 NodeIter beginNode() { return NodeIter(*this); }
1168 NodeCIter beginNode() const { return NodeCIter(*this); }
1169 NodeCIter cbeginNode() const { return NodeCIter(*this); }
1171
1173 LeafIter beginLeaf() { return LeafIter(*this); }
1175 LeafCIter beginLeaf() const { return LeafCIter(*this); }
1176 LeafCIter cbeginLeaf() const { return LeafCIter(*this); }
1178
1179 typedef TreeValueIteratorBase<Tree, typename RootNodeType::ValueAllIter> ValueAllIter;
1180 typedef TreeValueIteratorBase<const Tree, typename RootNodeType::ValueAllCIter> ValueAllCIter;
1181 typedef TreeValueIteratorBase<Tree, typename RootNodeType::ValueOnIter> ValueOnIter;
1182 typedef TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOnCIter> ValueOnCIter;
1183 typedef TreeValueIteratorBase<Tree, typename RootNodeType::ValueOffIter> ValueOffIter;
1184 typedef TreeValueIteratorBase<const Tree, typename RootNodeType::ValueOffCIter> ValueOffCIter;
1185
1187 ValueAllIter beginValueAll() { return ValueAllIter(*this); }
1189 ValueAllCIter beginValueAll() const { return ValueAllCIter(*this); }
1190 ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this); }
1192
1193 ValueOnIter beginValueOn() { return ValueOnIter(*this); }
1195 ValueOnCIter beginValueOn() const { return ValueOnCIter(*this); }
1196 ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this); }
1198
1199 ValueOffIter beginValueOff() { return ValueOffIter(*this); }
1201 ValueOffCIter beginValueOff() const { return ValueOffCIter(*this); }
1202 ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this); }
1204
1207 template<typename IterT> IterT begin();
1210 template<typename CIterT> CIterT cbegin() const;
1211
1212
1213 protected:
1214 typedef tbb::concurrent_hash_map<ValueAccessorBase<Tree, true>*, bool> AccessorRegistry;
1215 typedef tbb::concurrent_hash_map<ValueAccessorBase<const Tree, true>*, bool> ConstAccessorRegistry;
1216
1217 // Disallow assignment of instances of this class.
1218 Tree& operator=(const Tree&);
1219
1222 void releaseAllAccessors();
1223
1224 // TBB body object used to deallocates nodes in parallel.
1225 template<typename NodeType>
1226 struct DeallocateNodes {
1227 DeallocateNodes(std::vector<NodeType*>& nodes)
1228 : mNodes(nodes.empty() ? NULL : &nodes.front()) { }
1229 void operator()(const tbb::blocked_range<size_t>& range) const {
1230 for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
1231 delete mNodes[n]; mNodes[n] = NULL;
1232 }
1233 }
1234 NodeType ** const mNodes;
1235 };
1236
1237 //
1238 // Data members
1239 //
1240 RootNodeType mRoot; // root node of the tree
1241 mutable AccessorRegistry mAccessorRegistry;
1242 mutable ConstAccessorRegistry mConstAccessorRegistry;
1243
1244 static tbb::atomic<const Name*> sTreeTypeName;
1245 }; // end of Tree class
1246
1247 template<typename _RootNodeType>
1248 tbb::atomic<const Name*> Tree<_RootNodeType>::sTreeTypeName;
1249
1250
1255 template<typename T, Index N1=4, Index N2=3>
1256 struct Tree3 {
1257 typedef Tree<RootNode<InternalNode<LeafNode<T, N2>, N1> > > Type;
1258 };
1259
1260
1265 template<typename T, Index N1=5, Index N2=4, Index N3=3>
1266 struct Tree4 {
1267 typedef Tree<RootNode<InternalNode<InternalNode<LeafNode<T, N3>, N2>, N1> > > Type;
1268 };
1269
1274 template<typename T, Index N1=6, Index N2=5, Index N3=4, Index N4=3>
1275 struct Tree5 {
1276 typedef Tree<RootNode<InternalNode<InternalNode<InternalNode<LeafNode<T, N4>, N3>, N2>, N1> > >
1277 Type;
1278 };
1279
1280
1282
1283
1284 inline void
1285 TreeBase::readTopology(std::istream& is, bool /*saveFloatAsHalf*/)
1286 {
1287 int32_t bufferCount;
1288 is.read(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1289 if (bufferCount != 1) OPENVDB_LOG_WARN("multi-buffer trees are no longer supported");
1290 }
1291
1292
1293 inline void
1294 TreeBase::writeTopology(std::ostream& os, bool /*saveFloatAsHalf*/) const
1295 {
1296 int32_t bufferCount = 1;
1297 os.write(reinterpret_cast<char*>(&bufferCount), sizeof(int32_t));
1298 }
1299
1300
1301 inline void
1302 TreeBase::print(std::ostream& os, int /*verboseLevel*/) const
1303 {
1304 os << " Tree Type: " << type()
1305 << " Active Voxel Count: " << activeVoxelCount() << std::endl
1306 #ifndef OPENVDB_2_ABI_COMPATIBLE
1307 << " Active tile Count: " << activeTileCount() << std::endl
1308 #endif
1309 << " Inactive Voxel Count: " << inactiveVoxelCount() << std::endl
1310 << " Leaf Node Count: " << leafCount() << std::endl
1311 << " Non-leaf Node Count: " << nonLeafCount() << std::endl;
1312 }
1313
1314
1316
1317
1318 //
1319 // Type traits for tree iterators
1320 //
1321
1324 template<typename TreeT, typename IterT> struct TreeIterTraits;
1325
1326 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnIter> {
1327 static typename TreeT::RootNodeType::ChildOnIter begin(TreeT& tree) {
1328 return tree.beginRootChildren();
1329 }
1330 };
1331
1332 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOnCIter> {
1333 static typename TreeT::RootNodeType::ChildOnCIter begin(const TreeT& tree) {
1334 return tree.cbeginRootChildren();
1335 }
1336 };
1337
1338 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffIter> {
1339 static typename TreeT::RootNodeType::ChildOffIter begin(TreeT& tree) {
1340 return tree.beginRootTiles();
1341 }
1342 };
1343
1344 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildOffCIter> {
1345 static typename TreeT::RootNodeType::ChildOffCIter begin(const TreeT& tree) {
1346 return tree.cbeginRootTiles();
1347 }
1348 };
1349
1350 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllIter> {
1351 static typename TreeT::RootNodeType::ChildAllIter begin(TreeT& tree) {
1352 return tree.beginRootDense();
1353 }
1354 };
1355
1356 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::RootNodeType::ChildAllCIter> {
1357 static typename TreeT::RootNodeType::ChildAllCIter begin(const TreeT& tree) {
1358 return tree.cbeginRootDense();
1359 }
1360 };
1361
1362 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeIter> {
1363 static typename TreeT::NodeIter begin(TreeT& tree) { return tree.beginNode(); }
1364 };
1365
1366 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::NodeCIter> {
1367 static typename TreeT::NodeCIter begin(const TreeT& tree) { return tree.cbeginNode(); }
1368 };
1369
1370 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafIter> {
1371 static typename TreeT::LeafIter begin(TreeT& tree) { return tree.beginLeaf(); }
1372 };
1373
1374 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::LeafCIter> {
1375 static typename TreeT::LeafCIter begin(const TreeT& tree) { return tree.cbeginLeaf(); }
1376 };
1377
1378 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnIter> {
1379 static typename TreeT::ValueOnIter begin(TreeT& tree) { return tree.beginValueOn(); }
1380 };
1381
1382 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOnCIter> {
1383 static typename TreeT::ValueOnCIter begin(const TreeT& tree) { return tree.cbeginValueOn(); }
1384 };
1385
1386 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffIter> {
1387 static typename TreeT::ValueOffIter begin(TreeT& tree) { return tree.beginValueOff(); }
1388 };
1389
1390 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueOffCIter> {
1391 static typename TreeT::ValueOffCIter begin(const TreeT& tree) { return tree.cbeginValueOff(); }
1392 };
1393
1394 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllIter> {
1395 static typename TreeT::ValueAllIter begin(TreeT& tree) { return tree.beginValueAll(); }
1396 };
1397
1398 template<typename TreeT> struct TreeIterTraits<TreeT, typename TreeT::ValueAllCIter> {
1399 static typename TreeT::ValueAllCIter begin(const TreeT& tree) { return tree.cbeginValueAll(); }
1400 };
1401
1402
1403 template<typename RootNodeType>
1404 template<typename IterT>
1405 inline IterT
1406 Tree<RootNodeType>::begin()
1407 {
1408 return TreeIterTraits<Tree, IterT>::begin(*this);
1409 }
1410
1411
1412 template<typename RootNodeType>
1413 template<typename IterT>
1414 inline IterT
1415 Tree<RootNodeType>::cbegin() const
1416 {
1417 return TreeIterTraits<Tree, IterT>::begin(*this);
1418 }
1419
1420
1422
1423
1424 template<typename RootNodeType>
1425 void
1426 Tree<RootNodeType>::readTopology(std::istream& is, bool saveFloatAsHalf)
1427 {
1428 this->clearAllAccessors();
1429 TreeBase::readTopology(is, saveFloatAsHalf);
1430 mRoot.readTopology(is, saveFloatAsHalf);
1431 }
1432
1433
1434 template<typename RootNodeType>
1435 void
1436 Tree<RootNodeType>::writeTopology(std::ostream& os, bool saveFloatAsHalf) const
1437 {
1438 TreeBase::writeTopology(os, saveFloatAsHalf);
1439 mRoot.writeTopology(os, saveFloatAsHalf);
1440 }
1441
1442
1443 template<typename RootNodeType>
1444 inline void
1445 Tree<RootNodeType>::readBuffers(std::istream &is, bool saveFloatAsHalf)
1446 {
1447 this->clearAllAccessors();
1448 mRoot.readBuffers(is, saveFloatAsHalf);
1449 }
1450
1451
1452 #ifndef OPENVDB_2_ABI_COMPATIBLE
1453
1454 template<typename RootNodeType>
1455 inline void
1456 Tree<RootNodeType>::readBuffers(std::istream &is, const CoordBBox& bbox, bool saveFloatAsHalf)
1457 {
1458 this->clearAllAccessors();
1459 mRoot.readBuffers(is, bbox, saveFloatAsHalf);
1460 }
1461
1462
1463 template<typename RootNodeType>
1464 inline void
1465 Tree<RootNodeType>::readNonresidentBuffers() const
1466 {
1467 for (LeafCIter it = this->cbeginLeaf(); it; ++it) {
1468 // Retrieving the value of a leaf voxel forces loading of the leaf node's voxel buffer.
1469 it->getValue(Index(0));
1470 }
1471 }
1472
1473 #endif // !OPENVDB_2_ABI_COMPATIBLE
1474
1475
1476 template<typename RootNodeType>
1477 inline void
1478 Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
1479 {
1480 mRoot.writeBuffers(os, saveFloatAsHalf);
1481 }
1482
1483
1484 template<typename RootNodeType>
1485 inline void
1486 Tree<RootNodeType>::clear()
1487 {
1488 std::vector<LeafNodeType*> leafnodes;
1489 this->stealNodes(leafnodes);
1490
1491 tbb::parallel_for(tbb::blocked_range<size_t>(0, leafnodes.size()),
1492 DeallocateNodes<LeafNodeType>(leafnodes));
1493
1494 std::vector<typename RootNodeType::ChildNodeType*> internalNodes;
1495 this->stealNodes(internalNodes);
1496
1497 tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
1498 DeallocateNodes<typename RootNodeType::ChildNodeType>(internalNodes));
1499
1500 mRoot.clear();
1501
1502 this->clearAllAccessors();
1503 }
1504
1505
1507
1508
1509 template<typename RootNodeType>
1510 inline void
1511 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<Tree, true>& accessor) const
1512 {
1513 typename AccessorRegistry::accessor a;
1514 mAccessorRegistry.insert(a, &accessor);
1515 }
1516
1517
1518 template<typename RootNodeType>
1519 inline void
1520 Tree<RootNodeType>::attachAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1521 {
1522 typename ConstAccessorRegistry::accessor a;
1523 mConstAccessorRegistry.insert(a, &accessor);
1524 }
1525
1526
1527 template<typename RootNodeType>
1528 inline void
1529 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<Tree, true>& accessor) const
1530 {
1531 mAccessorRegistry.erase(&accessor);
1532 }
1533
1534
1535 template<typename RootNodeType>
1536 inline void
1537 Tree<RootNodeType>::releaseAccessor(ValueAccessorBase<const Tree, true>& accessor) const
1538 {
1539 mConstAccessorRegistry.erase(&accessor);
1540 }
1541
1542
1543 template<typename RootNodeType>
1544 inline void
1545 Tree<RootNodeType>::clearAllAccessors()
1546 {
1547 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1548 it != mAccessorRegistry.end(); ++it)
1549 {
1550 if (it->first) it->first->clear();
1551 }
1552
1553 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1554 it != mConstAccessorRegistry.end(); ++it)
1555 {
1556 if (it->first) it->first->clear();
1557 }
1558 }
1559
1560
1561 template<typename RootNodeType>
1562 inline void
1563 Tree<RootNodeType>::releaseAllAccessors()
1564 {
1565 mAccessorRegistry.erase(NULL);
1566 for (typename AccessorRegistry::iterator it = mAccessorRegistry.begin();
1567 it != mAccessorRegistry.end(); ++it)
1568 {
1569 it->first->release();
1570 }
1571 mAccessorRegistry.clear();
1572
1573 mAccessorRegistry.erase(NULL);
1574 for (typename ConstAccessorRegistry::iterator it = mConstAccessorRegistry.begin();
1575 it != mConstAccessorRegistry.end(); ++it)
1576 {
1577 it->first->release();
1578 }
1579 mConstAccessorRegistry.clear();
1580 }
1581
1582
1584
1585
1586 template<typename RootNodeType>
1587 inline const typename RootNodeType::ValueType&
1588 Tree<RootNodeType>::getValue(const Coord& xyz) const
1589 {
1590 return mRoot.getValue(xyz);
1591 }
1592
1593
1594 template<typename RootNodeType>
1595 template<typename AccessT>
1596 inline const typename RootNodeType::ValueType&
1597 Tree<RootNodeType>::getValue(const Coord& xyz, AccessT& accessor) const
1598 {
1599 return accessor.getValue(xyz);
1600 }
1601
1602
1603 template<typename RootNodeType>
1604 inline int
1605 Tree<RootNodeType>::getValueDepth(const Coord& xyz) const
1606 {
1607 return mRoot.getValueDepth(xyz);
1608 }
1609
1610
1611 template<typename RootNodeType>
1612 inline void
1613 Tree<RootNodeType>::setValueOff(const Coord& xyz)
1614 {
1615 mRoot.setValueOff(xyz);
1616 }
1617
1618
1619 template<typename RootNodeType>
1620 inline void
1621 Tree<RootNodeType>::setValueOff(const Coord& xyz, const ValueType& value)
1622 {
1623 mRoot.setValueOff(xyz, value);
1624 }
1625
1626
1627 template<typename RootNodeType>
1628 inline void
1629 Tree<RootNodeType>::setActiveState(const Coord& xyz, bool on)
1630 {
1631 mRoot.setActiveState(xyz, on);
1632 }
1633
1634
1635 template<typename RootNodeType>
1636 inline void
1637 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value)
1638 {
1639 mRoot.setValueOn(xyz, value);
1640 }
1641
1642 template<typename RootNodeType>
1643 inline void
1644 Tree<RootNodeType>::setValueOnly(const Coord& xyz, const ValueType& value)
1645 {
1646 mRoot.setValueOnly(xyz, value);
1647 }
1648
1649 template<typename RootNodeType>
1650 template<typename AccessT>
1651 inline void
1652 Tree<RootNodeType>::setValue(const Coord& xyz, const ValueType& value, AccessT& accessor)
1653 {
1654 accessor.setValue(xyz, value);
1655 }
1656
1657
1658 template<typename RootNodeType>
1659 inline void
1660 Tree<RootNodeType>::setValueOn(const Coord& xyz)
1661 {
1662 mRoot.setActiveState(xyz, true);
1663 }
1664
1665
1666 template<typename RootNodeType>
1667 inline void
1668 Tree<RootNodeType>::setValueOn(const Coord& xyz, const ValueType& value)
1669 {
1670 mRoot.setValueOn(xyz, value);
1671 }
1672
1673
1674 template<typename RootNodeType>
1675 template<typename ModifyOp>
1676 inline void
1677 Tree<RootNodeType>::modifyValue(const Coord& xyz, const ModifyOp& op)
1678 {
1679 mRoot.modifyValue(xyz, op);
1680 }
1681
1682
1683 template<typename RootNodeType>
1684 template<typename ModifyOp>
1685 inline void
1686 Tree<RootNodeType>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1687 {
1688 mRoot.modifyValueAndActiveState(xyz, op);
1689 }
1690
1691
1692 template<typename RootNodeType>
1693 inline bool
1694 Tree<RootNodeType>::probeValue(const Coord& xyz, ValueType& value) const
1695 {
1696 return mRoot.probeValue(xyz, value);
1697 }
1698
1699
1701
1702
1703 template<typename RootNodeType>
1704 inline void
1705 Tree<RootNodeType>::addTile(Index level, const Coord& xyz,
1706 const ValueType& value, bool active)
1707 {
1708 mRoot.addTile(level, xyz, value, active);
1709 }
1710
1711
1712 template<typename RootNodeType>
1713 template<typename NodeT>
1714 inline NodeT*
1715 Tree<RootNodeType>::stealNode(const Coord& xyz, const ValueType& value, bool active)
1716 {
1717 this->clearAllAccessors();
1718 return mRoot.template stealNode<NodeT>(xyz, value, active);
1719 }
1720
1721
1722 template<typename RootNodeType>
1723 inline typename RootNodeType::LeafNodeType*
1724 Tree<RootNodeType>::touchLeaf(const Coord& xyz)
1725 {
1726 return mRoot.touchLeaf(xyz);
1727 }
1728
1729
1730 template<typename RootNodeType>
1731 inline typename RootNodeType::LeafNodeType*
1732 Tree<RootNodeType>::probeLeaf(const Coord& xyz)
1733 {
1734 return mRoot.probeLeaf(xyz);
1735 }
1736
1737
1738 template<typename RootNodeType>
1739 inline const typename RootNodeType::LeafNodeType*
1740 Tree<RootNodeType>::probeConstLeaf(const Coord& xyz) const
1741 {
1742 return mRoot.probeConstLeaf(xyz);
1743 }
1744
1745
1746 template<typename RootNodeType>
1747 template<typename NodeType>
1748 inline NodeType*
1749 Tree<RootNodeType>::probeNode(const Coord& xyz)
1750 {
1751 return mRoot.template probeNode<NodeType>(xyz);
1752 }
1753
1754
1755 template<typename RootNodeType>
1756 template<typename NodeType>
1757 inline const NodeType*
1758 Tree<RootNodeType>::probeNode(const Coord& xyz) const
1759 {
1760 return this->template probeConstNode<NodeType>(xyz);
1761 }
1762
1763
1764 template<typename RootNodeType>
1765 template<typename NodeType>
1766 inline const NodeType*
1767 Tree<RootNodeType>::probeConstNode(const Coord& xyz) const
1768 {
1769 return mRoot.template probeConstNode<NodeType>(xyz);
1770 }
1771
1772
1774
1775
1776 template<typename RootNodeType>
1777 inline void
1778 Tree<RootNodeType>::clip(const CoordBBox& bbox)
1779 {
1780 this->clearAllAccessors();
1781 return mRoot.clip(bbox);
1782 }
1783
1784
1785 #ifndef OPENVDB_2_ABI_COMPATIBLE
1786 template<typename RootNodeType>
1787 inline void
1788 Tree<RootNodeType>::clipUnallocatedNodes()
1789 {
1790 this->clearAllAccessors();
1791 for (LeafIter it = this->beginLeaf(); it; ) {
1792 const LeafNodeType* leaf = it.getLeaf();
1793 ++it; // advance the iterator before deleting the leaf node
1794 if (!leaf->isAllocated()) {
1795 this->addTile(/*level=*/0, leaf->origin(), this->background(), /*active=*/false);
1796 }
1797 }
1798 }
1799 #endif
1800
1801
1802 template<typename RootNodeType>
1803 inline void
1804 Tree<RootNodeType>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1805 {
1806 this->clearAllAccessors();
1807 return mRoot.denseFill(bbox, value, active);
1808 }
1809
1810 template<typename RootNodeType>
1811 inline void
1812 Tree<RootNodeType>::sparseFill(const CoordBBox& bbox, const ValueType& value, bool active)
1813 {
1814 this->clearAllAccessors();
1815 return mRoot.sparseFill(bbox, value, active);
1816 }
1817
1818
1819 template<typename RootNodeType>
1820 Metadata::Ptr
1821 Tree<RootNodeType>::getBackgroundValue() const
1822 {
1823 Metadata::Ptr result;
1824 if (Metadata::isRegisteredType(valueType())) {
1825 typedef TypedMetadata<ValueType> MetadataT;
1826 result = Metadata::createMetadata(valueType());
1827 if (result->typeName() == MetadataT::staticTypeName()) {
1828 MetadataT* m = static_cast<MetadataT*>(result.get());
1829 m->value() = mRoot.background();
1830 }
1831 }
1832 return result;
1833 }
1834
1835
1837
1838
1839 template<typename RootNodeType>
1840 inline void
1841 Tree<RootNodeType>::voxelizeActiveTiles(bool threaded)
1842 {
1843 this->clearAllAccessors();
1844 mRoot.voxelizeActiveTiles(threaded);
1845 }
1846
1847
1848 template<typename RootNodeType>
1849 inline void
1850 Tree<RootNodeType>::merge(Tree& other, MergePolicy policy)
1851 {
1852 this->clearAllAccessors();
1853 other.clearAllAccessors();
1854 switch (policy) {
1855 case MERGE_ACTIVE_STATES:
1856 mRoot.template merge<MERGE_ACTIVE_STATES>(other.mRoot); break;
1857 case MERGE_NODES:
1858 mRoot.template merge<MERGE_NODES>(other.mRoot); break;
1859 case MERGE_ACTIVE_STATES_AND_NODES:
1860 mRoot.template merge<MERGE_ACTIVE_STATES_AND_NODES>(other.mRoot); break;
1861 }
1862 }
1863
1864
1865 template<typename RootNodeType>
1866 template<typename OtherRootNodeType>
1867 inline void
1868 Tree<RootNodeType>::topologyUnion(const Tree<OtherRootNodeType>& other)
1869 {
1870 this->clearAllAccessors();
1871 mRoot.topologyUnion(other.root());
1872 }
1873
1874 template<typename RootNodeType>
1875 template<typename OtherRootNodeType>
1876 inline void
1877 Tree<RootNodeType>::topologyIntersection(const Tree<OtherRootNodeType>& other)
1878 {
1879 this->clearAllAccessors();
1880 mRoot.topologyIntersection(other.root());
1881 }
1882
1883 template<typename RootNodeType>
1884 template<typename OtherRootNodeType>
1885 inline void
1886 Tree<RootNodeType>::topologyDifference(const Tree<OtherRootNodeType>& other)
1887 {
1888 this->clearAllAccessors();
1889 mRoot.topologyDifference(other.root());
1890 }
1891
1893
1894
1897 template<typename AValueT, typename CombineOp, typename BValueT = AValueT>
1898 struct CombineOpAdapter
1899 {
1900 CombineOpAdapter(CombineOp& _op): op(_op) {}
1901
1902 void operator()(CombineArgs<AValueT, BValueT>& args) const {
1903 op(args.a(), args.b(), args.result());
1904 }
1905
1906 CombineOp& op;
1907 };
1908
1909
1910 template<typename RootNodeType>
1911 template<typename CombineOp>
1912 inline void
1913 Tree<RootNodeType>::combine(Tree& other, CombineOp& op, bool prune)
1914 {
1915 CombineOpAdapter<ValueType, CombineOp> extendedOp(op);
1916 this->combineExtended(other, extendedOp, prune);
1917 }
1918
1919
1922 #ifndef _MSC_VER
1923 template<typename RootNodeType>
1924 template<typename CombineOp>
1925 inline void
1926 Tree<RootNodeType>::combine(Tree& other, const CombineOp& op, bool prune)
1927 {
1928 CombineOpAdapter<ValueType, const CombineOp> extendedOp(op);
1929 this->combineExtended(other, extendedOp, prune);
1930 }
1931 #endif
1932
1933
1934 template<typename RootNodeType>
1935 template<typename ExtendedCombineOp>
1936 inline void
1937 Tree<RootNodeType>::combineExtended(Tree& other, ExtendedCombineOp& op, bool prune)
1938 {
1939 this->clearAllAccessors();
1940 mRoot.combine(other.root(), op, prune);
1941 }
1942
1943
1946 #ifndef _MSC_VER
1947 template<typename RootNodeType>
1948 template<typename ExtendedCombineOp>
1949 inline void
1950 Tree<RootNodeType>::combineExtended(Tree& other, const ExtendedCombineOp& op, bool prune)
1951 {
1952 this->clearAllAccessors();
1953 mRoot.template combine<const ExtendedCombineOp>(other.mRoot, op, prune);
1954 }
1955 #endif
1956
1957
1958 template<typename RootNodeType>
1959 template<typename CombineOp, typename OtherTreeType>
1960 inline void
1961 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, CombineOp& op, bool prune)
1962 {
1963 CombineOpAdapter<ValueType, CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1964 this->combine2Extended(a, b, extendedOp, prune);
1965 }
1966
1967
1970 #ifndef _MSC_VER
1971 template<typename RootNodeType>
1972 template<typename CombineOp, typename OtherTreeType>
1973 inline void
1974 Tree<RootNodeType>::combine2(const Tree& a, const OtherTreeType& b, const CombineOp& op, bool prune)
1975 {
1976 CombineOpAdapter<ValueType, const CombineOp, typename OtherTreeType::ValueType> extendedOp(op);
1977 this->combine2Extended(a, b, extendedOp, prune);
1978 }
1979 #endif
1980
1981
1982 template<typename RootNodeType>
1983 template<typename ExtendedCombineOp, typename OtherTreeType>
1984 inline void
1985 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
1986 ExtendedCombineOp& op, bool prune)
1987 {
1988 this->clearAllAccessors();
1989 mRoot.combine2(a.root(), b.root(), op, prune);
1990 }
1991
1992
1996 #ifndef _MSC_VER
1997 template<typename RootNodeType>
1998 template<typename ExtendedCombineOp, typename OtherTreeType>
1999 inline void
2000 Tree<RootNodeType>::combine2Extended(const Tree& a, const OtherTreeType& b,
2001 const ExtendedCombineOp& op, bool prune)
2002 {
2003 this->clearAllAccessors();
2004 mRoot.template combine2<const ExtendedCombineOp>(a.root(), b.root(), op, prune);
2005 }
2006 #endif
2007
2008
2010
2011
2012 template<typename RootNodeType>
2013 template<typename VisitorOp>
2014 inline void
2015 Tree<RootNodeType>::visit(VisitorOp& op)
2016 {
2017 this->clearAllAccessors();
2018 mRoot.template visit<VisitorOp>(op);
2019 }
2020
2021
2022 template<typename RootNodeType>
2023 template<typename VisitorOp>
2024 inline void
2025 Tree<RootNodeType>::visit(VisitorOp& op) const
2026 {
2027 mRoot.template visit<VisitorOp>(op);
2028 }
2029
2030
2033 template<typename RootNodeType>
2034 template<typename VisitorOp>
2035 inline void
2036 Tree<RootNodeType>::visit(const VisitorOp& op)
2037 {
2038 this->clearAllAccessors();
2039 mRoot.template visit<const VisitorOp>(op);
2040 }
2041
2042
2045 template<typename RootNodeType>
2046 template<typename VisitorOp>
2047 inline void
2048 Tree<RootNodeType>::visit(const VisitorOp& op) const
2049 {
2050 mRoot.template visit<const VisitorOp>(op);
2051 }
2052
2053
2055
2056
2057 template<typename RootNodeType>
2058 template<typename OtherTreeType, typename VisitorOp>
2059 inline void
2060 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op)
2061 {
2062 this->clearAllAccessors();
2063 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2064 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2065 }
2066
2067
2068 template<typename RootNodeType>
2069 template<typename OtherTreeType, typename VisitorOp>
2070 inline void
2071 Tree<RootNodeType>::visit2(OtherTreeType& other, VisitorOp& op) const
2072 {
2073 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2074 mRoot.template visit2<OtherRootNodeType, VisitorOp>(other.root(), op);
2075 }
2076
2077
2080 template<typename RootNodeType>
2081 template<typename OtherTreeType, typename VisitorOp>
2082 inline void
2083 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op)
2084 {
2085 this->clearAllAccessors();
2086 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2087 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2088 }
2089
2090
2093 template<typename RootNodeType>
2094 template<typename OtherTreeType, typename VisitorOp>
2095 inline void
2096 Tree<RootNodeType>::visit2(OtherTreeType& other, const VisitorOp& op) const
2097 {
2098 typedef typename OtherTreeType::RootNodeType OtherRootNodeType;
2099 mRoot.template visit2<OtherRootNodeType, const VisitorOp>(other.root(), op);
2100 }
2101
2102
2104
2105
2106 template<typename RootNodeType>
2107 inline const Name&
2108 Tree<RootNodeType>::treeType()
2109 {
2110 if (sTreeTypeName == NULL) {
2111 std::vector<Index> dims;
2112 Tree::getNodeLog2Dims(dims);
2113 std::ostringstream ostr;
2114 ostr << "Tree_" << typeNameAsString<BuildType>();
2115 for (size_t i = 1, N = dims.size(); i < N; ++i) { // start from 1 to skip the RootNode
2116 ostr << "_" << dims[i];
2117 }
2118 Name* s = new Name(ostr.str());
2119 if (sTreeTypeName.compare_and_swap(s, NULL) != NULL) delete s;
2120 }
2121 return *sTreeTypeName;
2122 }
2123
2124
2125 template<typename RootNodeType>
2126 template<typename OtherRootNodeType>
2127 inline bool
2128 Tree<RootNodeType>::hasSameTopology(const Tree<OtherRootNodeType>& other) const
2129 {
2130 return mRoot.hasSameTopology(other.root());
2131 }
2132
2133
2134 template<typename RootNodeType>
2135 Index64
2136 Tree<RootNodeType>::inactiveVoxelCount() const
2137 {
2138 Coord dim(0, 0, 0);
2139 this->evalActiveVoxelDim(dim);
2140 const Index64
2141 totalVoxels = dim.x() * dim.y() * dim.z(),
2142 activeVoxels = this->activeVoxelCount();
2143 assert(totalVoxels >= activeVoxels);
2144 return totalVoxels - activeVoxels;
2145 }
2146
2147
2148 template<typename RootNodeType>
2149 inline bool
2150 Tree<RootNodeType>::evalLeafBoundingBox(CoordBBox& bbox) const
2151 {
2152 bbox.reset(); // default invalid bbox
2153
2154 if (this->empty()) return false; // empty
2155
2156 mRoot.evalActiveBoundingBox(bbox, false);
2157
2158 return true;// not empty
2159 }
2160
2161 template<typename RootNodeType>
2162 inline bool
2163 Tree<RootNodeType>::evalActiveVoxelBoundingBox(CoordBBox& bbox) const
2164 {
2165 bbox.reset(); // default invalid bbox
2166
2167 if (this->empty()) return false; // empty
2168
2169 mRoot.evalActiveBoundingBox(bbox, true);
2170
2171 return true;// not empty
2172 }
2173
2174
2175 template<typename RootNodeType>
2176 inline bool
2177 Tree<RootNodeType>::evalActiveVoxelDim(Coord& dim) const
2178 {
2179 CoordBBox bbox;
2180 bool notEmpty = this->evalActiveVoxelBoundingBox(bbox);
2181 dim = bbox.extents();
2182 return notEmpty;
2183 }
2184
2185
2186 template<typename RootNodeType>
2187 inline bool
2188 Tree<RootNodeType>::evalLeafDim(Coord& dim) const
2189 {
2190 CoordBBox bbox;
2191 bool notEmpty = this->evalLeafBoundingBox(bbox);
2192 dim = bbox.extents();
2193 return notEmpty;
2194 }
2195
2196
2197 template<typename RootNodeType>
2198 inline void
2199 Tree<RootNodeType>::evalMinMax(ValueType& minVal, ValueType& maxVal) const
2200 {
2201 minVal = maxVal = zeroVal<ValueType>();
2202 if (ValueOnCIter iter = this->cbeginValueOn()) {
2203 minVal = maxVal = *iter;
2204 for (++iter; iter; ++iter) {
2205 const ValueType& val = *iter;
2206 if (val < minVal) minVal = val;
2207 if (val > maxVal) maxVal = val;
2208 }
2209 }
2210 }
2211
2212
2213 template<typename RootNodeType>
2214 inline void
2215 Tree<RootNodeType>::getNodeLog2Dims(std::vector<Index>& dims)
2216 {
2217 dims.clear();
2218 RootNodeType::getNodeLog2Dims(dims);
2219 }
2220
2221
2222 template<typename RootNodeType>
2223 inline void
2224 Tree<RootNodeType>::print(std::ostream& os, int verboseLevel) const
2225 {
2226 if (verboseLevel <= 0) return;
2227
2229 struct OnExit {
2230 std::ostream& os;
2231 std::streamsize savedPrecision;
2232 OnExit(std::ostream& _os): os(_os), savedPrecision(os.precision()) {}
2233 ~OnExit() { os.precision(savedPrecision); }
2234 };
2235 OnExit restorePrecision(os);
2236
2237 std::vector<Index> dims;
2238 Tree::getNodeLog2Dims(dims);
2239
2240 os << "Information about Tree:\n"
2241 << " Type: " << this->type() << "\n";
2242
2243 os << " Configuration:\n";
2244
2245 if (verboseLevel <= 1) {
2246 // Print node types and sizes.
2247 os << " Root(" << mRoot.getTableSize() << ")";
2248 if (dims.size() > 1) {
2249 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2250 os << ", Internal(" << (1 << dims[i]) << "^3)";
2251 }
2252 os << ", Leaf(" << (1 << *dims.rbegin()) << "^3)\n";
2253 }
2254 os << " Background value: " << mRoot.background() << "\n";
2255 return;
2256 }
2257
2258 // The following is tree information that is expensive to extract.
2259
2260 ValueType minVal = zeroVal<ValueType>(), maxVal = zeroVal<ValueType>();
2261 if (verboseLevel > 3) {
2262 // This forces loading of all non-resident nodes.
2263 this->evalMinMax(minVal, maxVal);
2264 }
2265
2266 std::vector<Index64> nodeCount(dims.size());
2267 #ifndef OPENVDB_2_ABI_COMPATIBLE
2268 Index64 unallocatedLeafCount = 0;
2269 #endif
2270 for (NodeCIter it = cbeginNode(); it; ++it) {
2271 ++(nodeCount[it.getDepth()]);
2272
2273 #ifndef OPENVDB_2_ABI_COMPATIBLE
2274 if (it.getLevel() == 0) {
2275 const LeafNodeType* leaf = NULL;
2276 it.getNode(leaf);
2277 if (leaf && !leaf->isAllocated()) ++unallocatedLeafCount;
2278 }
2279 #endif
2280 }
2281 Index64 totalNodeCount = 0;
2282 for (size_t i = 0; i < nodeCount.size(); ++i) totalNodeCount += nodeCount[i];
2283
2284 // Print node types, counts and sizes.
2285 os << " Root(1 x " << mRoot.getTableSize() << ")";
2286 if (dims.size() > 1) {
2287 for (size_t i = 1, N = dims.size() - 1; i < N; ++i) {
2288 os << ", Internal(" << util::formattedInt(nodeCount[i]);
2289 os << " x " << (1 << dims[i]) << "^3)";
2290 }
2291 os << ", Leaf(" << util::formattedInt(*nodeCount.rbegin());
2292 os << " x " << (1 << *dims.rbegin()) << "^3)\n";
2293 }
2294 os << " Background value: " << mRoot.background() << "\n";
2295
2296 // Statistics of topology and values
2297
2298 if (verboseLevel > 3) {
2299 os << " Min value: " << minVal << "\n";
2300 os << " Max value: " << maxVal << "\n";
2301 }
2302
2303 const uint64_t
2304 leafCount = *nodeCount.rbegin(),
2305 numActiveVoxels = this->activeVoxelCount(),
2306 numActiveLeafVoxels = this->activeLeafVoxelCount(),
2307 numActiveTiles = this->activeTileCount();
2308
2309 os << " Number of active voxels: " << util::formattedInt(numActiveVoxels) << "\n";
2310 os << " Number of active tiles: " << util::formattedInt(numActiveTiles) << "\n";
2311
2312 Coord dim(0, 0, 0);
2313 uint64_t totalVoxels = 0;
2314 if (numActiveVoxels) { // nonempty
2315 CoordBBox bbox;
2316 this->evalActiveVoxelBoundingBox(bbox);
2317 dim = bbox.extents();
2318 totalVoxels = dim.x() * uint64_t(dim.y()) * dim.z();
2319
2320 os << " Bounding box of active voxels: " << bbox << "\n";
2321 os << " Dimensions of active voxels: "
2322 << dim[0] << " x " << dim[1] << " x " << dim[2] << "\n";
2323
2324 const double activeRatio = (100.0 * double(numActiveVoxels)) / double(totalVoxels);
2325 os << " Percentage of active voxels: " << std::setprecision(3) << activeRatio << "%\n";
2326
2327 if (leafCount > 0) {
2328 const double fillRatio = (100.0 * double(numActiveLeafVoxels))
2329 / (double(leafCount) * double(LeafNodeType::NUM_VOXELS));
2330 os << " Average leaf node fill ratio: " << fillRatio << "%\n";
2331 }
2332
2333 #ifndef OPENVDB_2_ABI_COMPATIBLE
2334 if (verboseLevel > 2) {
2335 os << " Number of unallocated nodes: "
2336 << util::formattedInt(unallocatedLeafCount) << " ("
2337 << (100.0 * double(unallocatedLeafCount) / double(totalNodeCount)) << "%)\n";
2338 }
2339 #endif
2340 } else {
2341 os << " Tree is empty!\n";
2342 }
2343 os << std::flush;
2344
2345 if (verboseLevel == 2) return;
2346
2347 // Memory footprint in bytes
2348 const uint64_t
2349 actualMem = this->memUsage(),
2350 denseMem = sizeof(ValueType) * totalVoxels,
2351 voxelsMem = sizeof(ValueType) * numActiveLeafVoxels;
2353
2354 os << "Memory footprint:\n";
2355 util::printBytes(os, actualMem, " Actual: ");
2356 util::printBytes(os, voxelsMem, " Active leaf voxels: ");
2357
2358 if (numActiveVoxels) {
2359 util::printBytes(os, denseMem, " Dense equivalent: ");
2360 os << " Actual footprint is " << (100.0 * double(actualMem) / double(denseMem))
2361 << "% of an equivalent dense volume\n";
2362 os << " Leaf voxel footprint is " << (100.0 * double(voxelsMem) / double(actualMem))
2363 << "% of actual footprint\n";
2364 }
2365 }
2366
2367 } // namespace tree
2368 } // namespace OPENVDB_VERSION_NAME
2369 } // namespace openvdb
2370
2371 #endif // OPENVDB_TREE_TREE_HAS_BEEN_INCLUDED
2372
2373 // Copyright (c) 2012-2016 DreamWorks Animation LLC
2374 // All rights reserved. This software is distributed under the
2375 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v3_2_0::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:1275
openvdb::v3_2_0::tree::TreeBase
Base class for typed trees.
Definition: Tree.h:65
openvdb::v3_2_0::tree::Tree::operator==
bool operator==(const Tree &) const
Definition: Tree.h:302
openvdb::v3_2_0::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:1613
openvdb::v3_2_0::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:1644
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:195
openvdb::v3_2_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:1677
openvdb::v3_2_0::TypedMetadata
Templated metadata class to hold specific types.
Definition: metadata/Metadata.h:139
openvdb::v3_2_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:1605
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllIter >::begin
static TreeT::RootNodeType::ChildAllIter begin(TreeT &tree)
Definition: Tree.h:1351
openvdb::v3_2_0::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:593
openvdb::v3_2_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:1686
openvdb::v3_2_0::tree::Tree::cbeginValueAll
ValueAllCIter cbeginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1190
Types.h
OPENVDB_DEPRECATED
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
openvdb::v3_2_0::tree::Tree::DeallocateNodes::DeallocateNodes
DeallocateNodes(std::vector< NodeType *> &nodes)
Definition: Tree.h:1227
openvdb::v3_2_0::tree::Tree::ValueType
RootNodeType::ValueType ValueType
Definition: Tree.h:212
Formats.h
Utility routines to output nicely-formatted numeric values.
openvdb::v3_2_0::tree::Tree::mRoot
RootNodeType mRoot
Definition: Tree.h:1240
openvdb::v3_2_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:259
openvdb::v3_2_0::tree::Tree::root
RootNodeType & root()
Return this tree&#39;s root node.
Definition: Tree.h:307
openvdb::v3_2_0::tree::Tree3::Type
Tree< RootNode< InternalNode< LeafNode< T, N2 >, N1 > > > Type
Definition: Tree.h:1257
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v3_2_0::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:1302
openvdb::v3_2_0::tree::Tree::activeVoxelCount
virtual Index64 activeVoxelCount() const
Return the total number of active voxels.
Definition: Tree.h:376
openvdb::v3_2_0::tree::TreeBase::ConstPtr
boost::shared_ptr< const TreeBase > ConstPtr
Definition: Tree.h:69
openvdb::v3_2_0::tree::Tree5::Type
Tree< RootNode< InternalNode< InternalNode< InternalNode< LeafNode< T, N4 >, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1277
openvdb::v3_2_0::TopologyCopy
Definition: Types.h:442
Metadata.h
openvdb::v3_2_0::math::CoordBBox::reset
void reset()
Definition: Coord.h:338
openvdb::v3_2_0::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:1660
openvdb::v3_2_0::tree::Tree::cbeginRootDense
RootNodeType::ChildAllCIter cbeginRootDense() const
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1148
openvdb::v3_2_0::tree::Tree::isValueOff
bool isValueOff(const Coord &xyz) const
Return true if the value at the given coordinates is inactive.
Definition: Tree.h:470
openvdb::v3_2_0::tree::Tree::beginValueAll
ValueAllCIter beginValueAll() const
Return an iterator over all values (tile and voxel) across all nodes.
Definition: Tree.h:1189
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffIter >::begin
static TreeT::RootNodeType::ChildOffIter begin(TreeT &tree)
Definition: Tree.h:1339
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
openvdb::v3_2_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:225
openvdb::v3_2_0::MERGE_ACTIVE_STATES
Definition: Types.h:265
openvdb::v3_2_0::tree::Tree::ValueAllCIter
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueAllCIter > ValueAllCIter
Definition: Tree.h:1180
openvdb::v3_2_0::Name
std::string Name
Definition: Name.h:44
openvdb::v3_2_0::tree::Tree::DeallocateNodes::operator()
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: Tree.h:1229
openvdb::v3_2_0::tree::Tree::beginValueOff
ValueOffCIter beginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1201
openvdb::v3_2_0::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 NULL.
Definition: Tree.h:566
openvdb::v3_2_0::tree::Tree::inactiveLeafVoxelCount
virtual Index64 inactiveLeafVoxelCount() const
Return the number of inactive voxels stored in leaf nodes.
Definition: Tree.h:374
openvdb::v3_2_0::tree::Tree::beginRootTiles
RootNodeType::ChildOffIter beginRootTiles()
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1142
openvdb::v3_2_0::tree::NodeIteratorBase
Base class for tree-traversal iterators over all nodes.
Definition: TreeIterator.h:977
openvdb::v3_2_0::tree::Tree::nonLeafCount
virtual Index32 nonLeafCount() const
Return the number of non-leaf nodes.
Definition: Tree.h:370
openvdb::v3_2_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:995
openvdb::v3_2_0::tree::Tree::mConstAccessorRegistry
ConstAccessorRegistry mConstAccessorRegistry
Definition: Tree.h:1242
openvdb::v3_2_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:517
openvdb::v3_2_0::tree::Tree::NodeCIter
NodeIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > NodeCIter
Iterator over all nodes in this tree.
Definition: Tree.h:1156
openvdb::v3_2_0::tree::Tree::ValueConverter::Type
Tree< typename RootNodeType::template ValueConverter< OtherValueType >::Type > Type
Definition: Tree.h:226
openvdb::v3_2_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
openvdb::v3_2_0::tree::TreeBase::Ptr
boost::shared_ptr< TreeBase > Ptr
Definition: Tree.h:68
openvdb::v3_2_0::tree::Tree::root
const RootNodeType & root() const
Return this tree&#39;s root node.
Definition: Tree.h:308
openvdb::v3_2_0::tree::TreeBase::memUsage
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:155
openvdb::v3_2_0::util::formattedInt
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
openvdb::v3_2_0::tree::CombineOpAdapter::CombineOpAdapter
CombineOpAdapter(CombineOp &_op)
Definition: Tree.h:1900
openvdb::v3_2_0::tools::composite::max
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
BBox.h
openvdb::v3_2_0::tree::TreeValueIteratorBase
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:658
openvdb::v3_2_0::tree::Tree::cbeginRootTiles
RootNodeType::ChildOffCIter cbeginRootTiles() const
Return an iterator over non-child entries of the root node&#39;s table.
Definition: Tree.h:1141
openvdb::v3_2_0::tree::Tree::type
virtual const Name & type() const
Return the name of this type of tree.
Definition: Tree.h:300
openvdb::v3_2_0::math::Coord::x
Int32 x() const
Definition: Coord.h:146
openvdb::v3_2_0::tree::TreeIterTraits
TreeIterTraits provides, for all tree iterators, a begin(tree) function that returns an iterator over...
Definition: Tree.h:1324
logging.h
openvdb::v3_2_0::tree::Tree::cbeginValueOff
ValueOffCIter cbeginValueOff() const
Return an iterator over inactive values (tile and voxel) across all nodes.
Definition: Tree.h:1202
openvdb::v3_2_0::tree::Tree::ValueOnIter
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOnIter > ValueOnIter
Definition: Tree.h:1181
openvdb::v3_2_0::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:1266
openvdb::v3_2_0::Metadata::isRegisteredType
static bool isRegisteredType(const Name &typeName)
Return true if the given type is known by the metadata type registry.
openvdb::v3_2_0::tree::Tree::Tree
Tree(const Tree &other)
Deep copy constructor.
Definition: Tree.h:233
openvdb::v3_2_0::tree::Tree::DeallocateNodes::mNodes
NodeType **const mNodes
Definition: Tree.h:1234
openvdb::v3_2_0::CombineArgs::a
const AValueType & a() const
Get the A input value.
Definition: Types.h:352
openvdb::v3_2_0::Metadata::Ptr
boost::shared_ptr< Metadata > Ptr
Definition: metadata/Metadata.h:52
openvdb::v3_2_0::tree::Tree::ValueOnCIter
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOnCIter > ValueOnCIter
Definition: Tree.h:1182
openvdb::v3_2_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:1637
openvdb::v3_2_0::Index
Index32 Index
Definition: Types.h:58
openvdb::v3_2_0::tree::Tree::DeallocateNodes
Definition: Tree.h:1226
openvdb::v3_2_0::tree::Tree::ValueOffIter
TreeValueIteratorBase< Tree, typename RootNodeType::ValueOffIter > ValueOffIter
Definition: Tree.h:1183
openvdb::v3_2_0::tree::Tree::RootNodeType
_RootNodeType RootNodeType
Definition: Tree.h:211
openvdb::v3_2_0::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:530
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::NodeCIter >::begin
static TreeT::NodeCIter begin(const TreeT &tree)
Definition: Tree.h:1367
openvdb::v3_2_0::tree::Tree::Tree
Tree()
Definition: Tree.h:230
openvdb::v3_2_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:280
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllIter >::begin
static TreeT::ValueAllIter begin(TreeT &tree)
Definition: Tree.h:1395
openvdb::v3_2_0::tree::Tree::activeTileCount
Index64 activeTileCount() const
Return the total number of active tiles.
Definition: Tree.h:380
openvdb::v3_2_0::tree::Tree::cbeginRootChildren
RootNodeType::ChildOnCIter cbeginRootChildren() const
Return an iterator over children of the root node.
Definition: Tree.h:1134
openvdb::v3_2_0::Index64
uint64_t Index64
Definition: Types.h:57
TreeIterator.h
InternalNode.h
Internal table nodes for OpenVDB trees.
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnCIter >::begin
static TreeT::RootNodeType::ChildOnCIter begin(const TreeT &tree)
Definition: Tree.h:1333
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v3_2_0::tools::clip
OPENVDB_STATIC_SPECIALIZATION GridType::Ptr clip(const GridType &grid, const BBoxd &)
Clip the given grid against a world-space bounding box and return a new grid containing the result...
Definition: Clip.h:356
openvdb::v3_2_0::tree::Tree::beginNode
NodeCIter beginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1168
openvdb::v3_2_0::tree::Tree::attachAccessor
void attachAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:651
openvdb::v3_2_0::tree::Tree::cbeginLeaf
LeafCIter cbeginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1176
openvdb::v3_2_0::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:1629
openvdb::v3_2_0::tree::Tree::AccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< Tree, true > *, bool > AccessorRegistry
Definition: Tree.h:1214
openvdb::v3_2_0::tree::Tree::clear
void clear()
Remove all tiles from this tree and all nodes other than the root node.
Definition: Tree.h:1486
openvdb::v3_2_0::CombineArgs::b
const BValueType & b() const
Get the B input value.
Definition: Types.h:354
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::NodeIter >::begin
static TreeT::NodeIter begin(TreeT &tree)
Definition: Tree.h:1363
openvdb::v3_2_0::tree::Tree::cbeginValueOn
ValueOnCIter cbeginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1196
openvdb::v3_2_0::CombineArgs::result
const AValueType & result() const
Get the output value.
Definition: Types.h:357
openvdb::v3_2_0::tree::Tree::ValueAllIter
TreeValueIteratorBase< Tree, typename RootNodeType::ValueAllIter > ValueAllIter
Definition: Tree.h:1179
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form &#39;someVar << "some text" << ...&#39;.
Definition: logging.h:39
openvdb::v3_2_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:633
openvdb::v3_2_0::tree::Tree::background
const ValueType & background() const
Return this tree&#39;s background value.
Definition: Tree.h:675
openvdb::v3_2_0::math::CoordBBox::extents
Coord extents() const
Definition: Coord.h:365
openvdb::v3_2_0::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::v3_2_0::tree::Tree::clearAllAccessors
void clearAllAccessors()
Clear all registered accessors.
Definition: Tree.h:1545
openvdb::v3_2_0::tree::Tree::~Tree
virtual ~Tree()
Definition: Tree.h:289
openvdb::v3_2_0::tree::Tree::isValueOn
bool isValueOn(const Coord &xyz) const
Return true if the value at the given coordinates is active.
Definition: Tree.h:468
openvdb::v3_2_0::MergePolicy
MergePolicy
Definition: Types.h:264
openvdb::v3_2_0::tree::Tree::copy
virtual TreeBase::Ptr copy() const
Return a pointer to a deep copy of this tree.
Definition: Tree.h:292
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOnIter >::begin
static TreeT::RootNodeType::ChildOnIter begin(TreeT &tree)
Definition: Tree.h:1327
openvdb
Definition: Exceptions.h:39
openvdb::v3_2_0::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 NULL.
Definition: Tree.h:1740
openvdb::v3_2_0::tree::Tree::Tree
Tree(const ValueType &background)
Empty tree constructor.
Definition: Tree.h:287
openvdb::v3_2_0::tree::Tree::Ptr
boost::shared_ptr< Tree > Ptr
Definition: Tree.h:208
openvdb::v3_2_0::Index32
uint32_t Index32
Definition: Types.h:56
openvdb::v3_2_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:1256
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueAllCIter >::begin
static TreeT::ValueAllCIter begin(const TreeT &tree)
Definition: Tree.h:1399
openvdb::v3_2_0::tree::CombineOpAdapter::op
CombineOp & op
Definition: Tree.h:1906
openvdb::v3_2_0::tree::LeafIteratorBase
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1228
openvdb::v3_2_0::tree::Tree::ValueOffCIter
TreeValueIteratorBase< const Tree, typename RootNodeType::ValueOffCIter > ValueOffCIter
Definition: Tree.h:1184
openvdb::v3_2_0::tree::Tree::valueType
virtual Name valueType() const
Return the name of the type of a voxel&#39;s value (e.g., "float" or "vec3d")
Definition: Tree.h:295
openvdb::v3_2_0::math::Coord::z
Int32 z() const
Definition: Coord.h:148
LeafNode.h
openvdb::v3_2_0::tree::Tree::BuildType
RootNodeType::BuildType BuildType
Definition: Tree.h:213
openvdb::v3_2_0::tree::CombineOpAdapter
Helper class to adapt a three-argument (a, b, result) CombineOp functor into a single-argument functo...
Definition: Tree.h:1898
openvdb::v3_2_0::tree::Tree::beginRootChildren
RootNodeType::ChildOnIter beginRootChildren()
Return an iterator over children of the root node.
Definition: Tree.h:1135
openvdb::v3_2_0::tree::Tree::leafCount
virtual Index32 leafCount() const
Return the number of leaf nodes.
Definition: Tree.h:368
openvdb::v3_2_0::tree::Tree::hasActiveTiles
bool hasActiveTiles() const
Return true if this tree has any active tiles.
Definition: Tree.h:472
openvdb::v3_2_0::tree::Tree::operator!=
bool operator!=(const Tree &) const
Definition: Tree.h:303
ValueAccessor.h
openvdb::v3_2_0::tree::Tree::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: Tree.h:1588
openvdb::v3_2_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:1694
openvdb::v3_2_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, return NULL.
Definition: Tree.h:1732
openvdb::v3_2_0::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:259
openvdb::v3_2_0::MERGE_ACTIVE_STATES_AND_NODES
Definition: Types.h:267
openvdb::v3_2_0::NotImplementedError
Definition: Exceptions.h:84
RootNode.h
The root node of an OpenVDB tree.
openvdb::v3_2_0::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:496
openvdb::v3_2_0::tree::Tree::cbeginNode
NodeCIter cbeginNode() const
Return an iterator over all nodes in this tree.
Definition: Tree.h:1169
openvdb::v3_2_0::tree::Tree::treeDepth
virtual Index treeDepth() const
Return the depth of this tree.
Definition: Tree.h:366
openvdb::v3_2_0::math::Coord::y
Int32 y() const
Definition: Coord.h:147
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnCIter >::begin
static TreeT::ValueOnCIter begin(const TreeT &tree)
Definition: Tree.h:1383
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::LeafCIter >::begin
static TreeT::LeafCIter begin(const TreeT &tree)
Definition: Tree.h:1375
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::LeafIter >::begin
static TreeT::LeafIter begin(TreeT &tree)
Definition: Tree.h:1371
openvdb::v3_2_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:374
openvdb::v3_2_0::tree::Tree::sTreeTypeName
static tbb::atomic< const Name * > sTreeTypeName
Definition: Tree.h:1244
openvdb::v3_2_0::tree::TreeBase::writeTopology
virtual void writeTopology(std::ostream &, bool saveFloatAsHalf=false) const
Write the tree topology to a stream.
Definition: Tree.h:1294
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOnIter >::begin
static TreeT::ValueOnIter begin(TreeT &tree)
Definition: Tree.h:1379
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffCIter >::begin
static TreeT::ValueOffCIter begin(const TreeT &tree)
Definition: Tree.h:1391
openvdb::v3_2_0::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::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildOffCIter >::begin
static TreeT::RootNodeType::ChildOffCIter begin(const TreeT &tree)
Definition: Tree.h:1345
openvdb::v3_2_0::tree::Tree::beginRootDense
RootNodeType::ChildAllIter beginRootDense()
Return an iterator over all entries of the root node&#39;s table.
Definition: Tree.h:1149
openvdb::v3_2_0::tree::Tree::getIndexRange
virtual void getIndexRange(CoordBBox &bbox) const
Min and max are both inclusive.
Definition: Tree.h:678
openvdb::v3_2_0::tree::Tree::Tree
Tree(const Tree< OtherRootType > &other)
Value conversion deep copy constructor.
Definition: Tree.h:244
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v3_2_0::tree::Tree::writeBuffers
virtual void writeBuffers(std::ostream &, bool saveFloatAsHalf=false) const
Write out all data buffers for this tree.
Definition: Tree.h:1478
openvdb::v3_2_0::tree::Tree::activeLeafVoxelCount
virtual Index64 activeLeafVoxelCount() const
Return the number of active voxels stored in leaf nodes.
Definition: Tree.h:372
openvdb::v3_2_0::tree::Tree::LeafNodeType
RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:214
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::ValueOffIter >::begin
static TreeT::ValueOffIter begin(TreeT &tree)
Definition: Tree.h:1387
openvdb::v3_2_0::tree::Tree::beginValueOn
ValueOnCIter beginValueOn() const
Return an iterator over active values (tile and voxel) across all nodes.
Definition: Tree.h:1195
openvdb::v3_2_0::tree::Tree
Definition: Tree.h:205
openvdb::v3_2_0::tree::TreeBase::getBackgroundValue
virtual Metadata::Ptr getBackgroundValue() const
Return this tree&#39;s background value wrapped as metadata.
Definition: Tree.h:88
openvdb::v3_2_0::tree::Tree::ConstAccessorRegistry
tbb::concurrent_hash_map< ValueAccessorBase< const Tree, true > *, bool > ConstAccessorRegistry
Definition: Tree.h:1215
openvdb::v3_2_0::tree::CombineOpAdapter::operator()
void operator()(CombineArgs< AValueT, BValueT > &args) const
Definition: Tree.h:1902
openvdb::v3_2_0::tree::Tree::releaseAccessor
void releaseAccessor(ValueAccessorBase< const Tree, false > &) const
Dummy implementations.
Definition: Tree.h:663
openvdb::v3_2_0::tree::Tree::memUsage
virtual Index64 memUsage() const
Return the total amount of memory in bytes occupied by this tree.
Definition: Tree.h:385
openvdb::v3_2_0::tree::Tree::LeafCIter
LeafIteratorBase< const Tree, typename RootNodeType::ChildOnCIter > LeafCIter
Iterator over all leaf nodes in this tree.
Definition: Tree.h:1162
openvdb::v3_2_0::MERGE_NODES
Definition: Types.h:266
openvdb::v3_2_0::tree::Tree4::Type
Tree< RootNode< InternalNode< InternalNode< LeafNode< T, N3 >, N2 >, N1 > > > Type
Definition: Tree.h:1267
openvdb::v3_2_0::CombineArgs
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:312
openvdb::v3_2_0::tree::Tree::beginLeaf
LeafCIter beginLeaf() const
Return an iterator over all leaf nodes in this tree.
Definition: Tree.h:1175
openvdb::v3_2_0::tree::TreeBase::~TreeBase
virtual ~TreeBase()
Definition: Tree.h:72
openvdb::v3_2_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:620
openvdb::v3_2_0::tree::TreeBase::TreeBase
TreeBase()
Definition: Tree.h:71
openvdb::v3_2_0::tree::Tree::mAccessorRegistry
AccessorRegistry mAccessorRegistry
Definition: Tree.h:1241
openvdb::v3_2_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:1705
openvdb::v3_2_0::tree::TreeBase::readTopology
virtual void readTopology(std::istream &, bool saveFloatAsHalf=false)
Read the tree topology from a stream.
Definition: Tree.h:1285
openvdb::v3_2_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:2128
Platform.h
openvdb::v3_2_0::Metadata::createMetadata
static Metadata::Ptr createMetadata(const Name &typeName)
Create new metadata of the given type.
openvdb::v3_2_0::tree::TreeIterTraits< TreeT, typename TreeT::RootNodeType::ChildAllCIter >::begin
static TreeT::RootNodeType::ChildAllCIter begin(const TreeT &tree)
Definition: Tree.h:1357
openvdb::v3_2_0::tree::Tree::stealNodes
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Definition: Tree.h:622
openvdb::v3_2_0::tree::Tree::ConstPtr
boost::shared_ptr< const Tree > ConstPtr
Definition: Tree.h:209
openvdb::v3_2_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, create one that preserves the values and active states of all voxels.
Definition: Tree.h:1724
openvdb::v3_2_0::tools::composite::min
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128