35 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 42 #include <boost/type_traits/remove_const.hpp> 43 #include <boost/type_traits/remove_pointer.hpp> 44 #include <boost/type_traits/is_pointer.hpp> 45 #include <boost/type_traits/is_const.hpp> 46 #include <boost/mpl/contains.hpp> 47 #include <boost/mpl/if.hpp> 48 #include <boost/mpl/vector.hpp> 49 #include <boost/mpl/at.hpp> 50 #include <boost/mpl/push_back.hpp> 51 #include <boost/mpl/size.hpp> 52 #include <tbb/parallel_for.h> 53 #include <openvdb/Exceptions.h> 54 #include <openvdb/Types.h> 55 #include <openvdb/io/Compression.h> 56 #include <openvdb/math/Math.h> 57 #include <openvdb/math/BBox.h> 58 #include <openvdb/util/NodeMasks.h> 59 #include <openvdb/version.h> 68 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
74 template<
typename ChildType>
83 static const Index LEVEL = 1 + ChildType::LEVEL;
87 BOOST_STATIC_ASSERT(boost::mpl::size<NodeChainType>::value == LEVEL + 1);
91 template<
typename OtherValueType>
99 template<
typename OtherNodeType>
109 explicit RootNode(
const ValueType& background);
119 template<
typename OtherChildType>
130 template<
typename OtherChildType>
132 const ValueType& background,
const ValueType& foreground,
TopologyCopy);
144 template<
typename OtherChildType>
156 template<
typename OtherChildType>
163 Tile(): value(zeroVal<ValueType>()), active(
false) {}
164 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
174 NodeStruct(): child(NULL) {}
175 NodeStruct(ChildType& c): child(&c) {}
176 NodeStruct(
const Tile& t): child(NULL), tile(t) {}
179 bool isChild()
const {
return child != NULL; }
180 bool isTile()
const {
return child == NULL; }
181 bool isTileOff()
const {
return isTile() && !tile.active; }
182 bool isTileOn()
const {
return isTile() && tile.active; }
184 void set(ChildType& c) {
delete child; child = &c; }
185 void set(
const Tile& t) {
delete child; child = NULL; tile = t; }
186 ChildType& steal(
const Tile& t) { ChildType* c = child; child = NULL; tile = t;
return *c; }
189 typedef std::map<Coord, NodeStruct> MapType;
190 typedef typename MapType::iterator MapIter;
191 typedef typename MapType::const_iterator MapCIter;
193 typedef std::set<Coord> CoordSet;
194 typedef typename CoordSet::iterator CoordSetIter;
195 typedef typename CoordSet::const_iterator CoordSetCIter;
197 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
198 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
199 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
200 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
201 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
202 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
203 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
204 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
206 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
207 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
208 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
209 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
210 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
211 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
212 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
213 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
216 static inline bool test(
const MapIter&) {
return true; }
217 static inline bool test(
const MapCIter&) {
return true; }
220 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
221 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
223 struct ValueOffPred {
224 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
225 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
227 struct ValueAllPred {
228 static inline bool test(
const MapIter& i) {
return isTile(i); }
229 static inline bool test(
const MapCIter& i) {
return isTile(i); }
232 static inline bool test(
const MapIter& i) {
return isChild(i); }
233 static inline bool test(
const MapCIter& i) {
return isChild(i); }
235 struct ChildOffPred {
236 static inline bool test(
const MapIter& i) {
return isTile(i); }
237 static inline bool test(
const MapCIter& i) {
return isTile(i); }
240 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
244 typedef _RootNodeT RootNodeT;
245 typedef _MapIterT MapIterT;
249 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
251 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
253 RootNodeT* getParentNode()
const {
return mParentNode; }
255 RootNodeT& parent()
const 261 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
262 operator bool()
const {
return this->test(); }
264 void increment() { ++mIter; this->skip(); }
265 bool next() { this->increment();
return this->test(); }
266 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
272 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
275 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
276 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
277 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
278 void setValueOff()
const { mIter->second.tile.active =
false; }
281 Coord getCoord()
const {
return mIter->first; }
283 void getCoord(
Coord& xyz)
const { xyz = this->getCoord(); }
286 BaseIter(): mParentNode(NULL) {}
287 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
289 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
291 RootNodeT* mParentNode;
295 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
296 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
299 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
300 typedef RootNodeT NodeType;
301 typedef NodeType ValueType;
302 typedef ChildNodeT ChildNodeType;
303 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
304 typedef typename boost::remove_const<ValueType>::type NonConstValueType;
305 typedef typename boost::remove_const<ChildNodeType>::type NonConstChildNodeType;
309 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
311 ChildIter& operator++() { BaseT::increment();
return *
this; }
313 ChildNodeT& getValue()
const {
return getChild(mIter); }
314 ChildNodeT&
operator*()
const {
return this->getValue(); }
315 ChildNodeT* operator->()
const {
return &this->getValue(); }
318 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
319 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
322 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
323 typedef RootNodeT NodeType;
324 typedef ValueT ValueType;
325 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
326 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
330 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
332 ValueIter& operator++() { BaseT::increment();
return *
this; }
334 ValueT& getValue()
const {
return getTile(mIter).value; }
335 ValueT&
operator*()
const {
return this->getValue(); }
336 ValueT* operator->()
const {
return &(this->getValue()); }
338 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
340 template<
typename ModifyOp>
341 void modifyValue(
const ModifyOp& op)
const 343 assert(isTile(mIter));
344 op(getTile(mIter).value);
348 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
349 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
352 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
353 typedef RootNodeT NodeType;
354 typedef ValueT ValueType;
355 typedef ChildNodeT ChildNodeType;
356 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
357 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
358 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
362 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
364 DenseIter& operator++() { BaseT::increment();
return *
this; }
366 bool isChildNode()
const {
return isChild(mIter); }
368 ChildNodeT* probeChild(NonConstValueType& value)
const 370 if (isChild(mIter))
return &getChild(mIter);
371 value = getTile(mIter).value;
374 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const 376 child = this->probeChild(value);
377 return child != NULL;
379 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
381 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
382 void setChild(ChildNodeT* c)
const { assert(c != NULL); RootNodeT::setChild(mIter, *c); }
383 void setValue(
const ValueT& v)
const 385 if (isTile(mIter)) getTile(mIter).value = v;
389 else stealChild(mIter, Tile(v,
true));
394 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
395 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
396 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
397 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
398 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
399 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
401 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
402 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
403 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
404 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
405 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
406 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
409 ChildOnCIter
cbeginChildOn()
const {
return ChildOnCIter(*
this, mTable.begin()); }
410 ChildOffCIter
cbeginChildOff()
const {
return ChildOffCIter(*
this, mTable.begin()); }
411 ChildAllCIter
cbeginChildAll()
const {
return ChildAllCIter(*
this, mTable.begin()); }
415 ChildOnIter
beginChildOn() {
return ChildOnIter(*
this, mTable.begin()); }
416 ChildOffIter
beginChildOff() {
return ChildOffIter(*
this, mTable.begin()); }
417 ChildAllIter
beginChildAll() {
return ChildAllIter(*
this, mTable.begin()); }
419 ValueOnCIter
cbeginValueOn()
const {
return ValueOnCIter(*
this, mTable.begin()); }
420 ValueOffCIter
cbeginValueOff()
const {
return ValueOffCIter(*
this, mTable.begin()); }
421 ValueAllCIter
cbeginValueAll()
const {
return ValueAllCIter(*
this, mTable.begin()); }
425 ValueOnIter
beginValueOn() {
return ValueOnIter(*
this, mTable.begin()); }
426 ValueOffIter
beginValueOff() {
return ValueOffIter(*
this, mTable.begin()); }
427 ValueAllIter
beginValueAll() {
return ValueAllIter(*
this, mTable.begin()); }
437 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
454 void setBackground(
const ValueType& value,
bool updateChildNodes);
460 bool isBackgroundTile(
const Tile&)
const;
462 bool isBackgroundTile(
const MapIter&)
const;
464 bool isBackgroundTile(
const MapCIter&)
const;
468 size_t numBackgroundTiles()
const;
471 size_t eraseBackgroundTiles();
475 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
480 bool expand(
const Coord& xyz);
483 static void getNodeLog2Dims(std::vector<Index>& dims);
489 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
490 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
491 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
494 Coord getMinIndex()
const;
496 Coord getMaxIndex()
const;
498 void getIndexRange(
CoordBBox& bbox)
const;
502 template<
typename OtherChildType>
506 template<
typename OtherChildType>
511 template<
typename OtherChildType>
518 Index64 onLeafVoxelCount()
const;
519 Index64 offLeafVoxelCount()
const;
522 bool isValueOn(
const Coord& xyz)
const;
524 bool hasActiveTiles()
const;
526 const ValueType& getValue(
const Coord& xyz)
const;
527 bool probeValue(
const Coord& xyz, ValueType& value)
const;
532 int getValueDepth(
const Coord& xyz)
const;
535 void setActiveState(
const Coord& xyz,
bool on);
537 void setValueOnly(
const Coord& xyz,
const ValueType& value);
539 void setValueOn(
const Coord& xyz,
const ValueType& value);
541 void setValueOff(
const Coord& xyz);
543 void setValueOff(
const Coord& xyz,
const ValueType& value);
547 template<
typename ModifyOp>
548 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
550 template<
typename ModifyOp>
551 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
554 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
565 this->fill(bbox, value, active);
578 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
585 template<
typename DenseT>
592 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
593 bool readTopology(std::istream&,
bool fromHalf =
false);
595 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
596 void readBuffers(std::istream&,
bool fromHalf =
false);
597 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
607 template<
typename AccessorT>
608 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
613 template<
typename AccessorT>
614 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
620 template<
typename AccessorT>
621 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
627 template<
typename AccessorT>
628 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
635 template<
typename ModifyOp,
typename AccessorT>
636 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
642 template<
typename ModifyOp,
typename AccessorT>
643 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
649 template<
typename AccessorT>
650 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
656 template<
typename AccessorT>
657 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
664 template<
typename AccessorT>
665 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
672 template<
typename AccessorT>
673 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
683 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
687 void addLeaf(LeafNodeType* leaf);
691 template<
typename AccessorT>
692 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
702 template<
typename NodeT>
703 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
707 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
712 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
716 template<
typename AccessorT>
717 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
724 LeafNodeType* touchLeaf(
const Coord& xyz);
728 template<
typename AccessorT>
729 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
732 template <
typename NodeT>
735 NodeT* probeNode(
const Coord& xyz);
736 template <
typename NodeT>
737 const NodeT* probeConstNode(
const Coord& xyz)
const;
741 template<
typename NodeT,
typename AccessorT>
744 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
745 template<
typename NodeT,
typename AccessorT>
746 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
750 LeafNodeType* probeLeaf(
const Coord& xyz);
753 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
754 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
758 template<
typename AccessorT>
761 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
762 template<
typename AccessorT>
763 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
764 template<
typename AccessorT>
765 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
774 template<
typename ArrayT>
void getNodes(ArrayT& array);
797 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
801 template<
typename ArrayT>
825 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
826 template<
typename ArrayT>
836 void voxelizeActiveTiles(
bool threaded =
true);
845 template<MergePolicy Policy>
void merge(
RootNode& other);
860 template<
typename OtherChildType>
876 template<
typename OtherChildType>
889 template<
typename OtherChildType>
892 template<
typename CombineOp>
893 void combine(
RootNode& other, CombineOp&,
bool prune =
false);
895 template<
typename CombineOp,
typename OtherRootNode >
896 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
897 CombineOp& op,
bool prune =
false);
904 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
906 template<
typename VisitorOp>
void visit(VisitorOp&);
907 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
909 template<
typename OtherRootNodeType,
typename VisitorOp>
910 void visit2(OtherRootNodeType& other, VisitorOp&);
911 template<
typename OtherRootNodeType,
typename VisitorOp>
912 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
925 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
927 void resetTable(
const MapType&)
const {}
930 Index getChildCount()
const;
931 Index getTileCount()
const;
932 Index getActiveTileCount()
const;
933 Index getInactiveTileCount()
const;
936 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
939 void insertKeys(CoordSet&)
const;
942 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
944 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
947 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
950 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
953 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
955 MapIter findOrAddCoord(
const Coord& xyz);
964 template<
typename OtherChildType>
972 template<
typename OtherChildType>
975 template<
typename CombineOp,
typename OtherRootNode >
976 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
978 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
979 static inline void doVisit(RootNodeT&, VisitorOp&);
981 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
982 typename ChildAllIterT,
typename OtherChildAllIterT>
983 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
987 ValueType mBackground;
1014 template<
typename HeadT,
int HeadLevel>
1017 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
1021 template<
typename HeadT>
1023 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
1031 template<
typename ChildT1,
typename NodeT2>
1035 static const bool value =
false;
1038 template<
typename ChildT1,
typename ChildT2>
1040 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1048 template<
typename ChildT>
1056 template<
typename ChildT>
1064 template<
typename ChildT>
1065 template<
typename OtherChildType>
1068 const ValueType& backgd,
const ValueType& foregd,
TopologyCopy):
1073 enforceSameConfiguration(other);
1075 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1078 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1079 mTable[i->first] = OtherRootT::isTile(i)
1080 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1081 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1086 template<
typename ChildT>
1087 template<
typename OtherChildType>
1095 enforceSameConfiguration(other);
1097 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1099 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1100 mTable[i->first] = OtherRootT::isTile(i)
1101 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1102 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1113 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1120 self.enforceSameConfiguration(other);
1121 self.enforceCompatibleValueTypes(other);
1123 std::ostringstream ostr;
1124 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1125 <<
" to a " <<
typeid(RootT).name();
1131 template<
typename RootT,
typename OtherRootT>
1136 typedef typename RootT::ValueType ValueT;
1137 typedef typename RootT::ChildNodeType ChildT;
1138 typedef typename RootT::NodeStruct NodeStruct;
1139 typedef typename RootT::Tile Tile;
1140 typedef typename OtherRootT::ValueType OtherValueT;
1141 typedef typename OtherRootT::MapCIter OtherMapCIter;
1142 typedef typename OtherRootT::Tile OtherTile;
1146 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1149 self.mBackground = Local::convertValue(other.mBackground);
1154 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1155 if (other.isTile(i)) {
1157 const OtherTile& otherTile = other.getTile(i);
1158 self.mTable[i->first] = NodeStruct(
1159 Tile(Local::convertValue(otherTile.value), otherTile.active));
1162 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1170 template<
typename ChildT>
1174 if (&other !=
this) {
1175 mBackground = other.mBackground;
1180 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1182 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1189 template<
typename ChildT>
1190 template<
typename OtherChildType>
1195 typedef typename OtherRootT::ValueType OtherValueT;
1205 template<
typename ChildT>
1211 if (updateChildNodes) {
1214 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1215 ChildT *child = iter->second.child;
1217 child->resetBackground(mBackground, background);
1219 Tile& tile = getTile(iter);
1220 if (tile.active)
continue;
1232 template<
typename ChildT>
1239 template<
typename ChildT>
1246 template<
typename ChildT>
1254 template<
typename ChildT>
1259 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1266 template<
typename ChildT>
1270 std::set<Coord> keysToErase;
1271 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1274 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1277 return keysToErase.size();
1284 template<
typename ChildT>
1288 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1289 keys.insert(i->first);
1294 template<
typename ChildT>
1295 inline typename RootNode<ChildT>::MapIter
1298 const Coord key = coordToKey(xyz);
1299 std::pair<MapIter, bool> result = mTable.insert(
1300 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1301 return result.first;
1305 template<
typename ChildT>
1309 const Coord key = coordToKey(xyz);
1310 std::pair<MapIter, bool> result = mTable.insert(
1311 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1312 return result.second;
1319 template<
typename ChildT>
1324 ChildT::getNodeLog2Dims(dims);
1328 template<
typename ChildT>
1332 return mTable.empty() ?
Coord(0) : mTable.begin()->first;
1335 template<
typename ChildT>
1339 return mTable.empty() ?
Coord(0) : mTable.rbegin()->first +
Coord(ChildT::DIM - 1);
1343 template<
typename ChildT>
1355 template<
typename ChildT>
1356 template<
typename OtherChildType>
1361 typedef typename OtherRootT::MapType OtherMapT;
1362 typedef typename OtherRootT::MapIter OtherIterT;
1363 typedef typename OtherRootT::MapCIter OtherCIterT;
1368 OtherMapT copyOfOtherTable = other.mTable;
1371 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1375 OtherCIterT otherIter = other.findKey(thisIter->first);
1376 if (otherIter == other.mTable.end())
return false;
1379 if (isChild(thisIter)) {
1380 if (OtherRootT::isTile(otherIter))
return false;
1382 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1384 if (OtherRootT::isChild(otherIter))
return false;
1385 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1392 copyOfOtherTable.erase(otherIter->first);
1395 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1402 template<
typename ChildT>
1403 template<
typename OtherChildType>
1407 std::vector<Index> thisDims, otherDims;
1410 return (thisDims == otherDims);
1414 template<
typename ChildT>
1415 template<
typename OtherChildType>
1419 std::vector<Index> thisDims, otherDims;
1422 if (thisDims != otherDims) {
1423 std::ostringstream ostr;
1424 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1425 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1426 ostr <<
" vs. " << otherDims[0];
1427 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1434 template<
typename ChildT>
1435 template<
typename OtherChildType>
1439 typedef typename OtherChildType::ValueType OtherValueType;
1444 template<
typename ChildT>
1445 template<
typename OtherChildType>
1449 typedef typename OtherChildType::ValueType OtherValueType;
1451 std::ostringstream ostr;
1452 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1453 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1462 template<
typename ChildT>
1467 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1468 if (
const ChildT *child = iter->second.child) {
1469 sum += child->memUsage();
1476 template<
typename ChildT>
1480 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1481 delete i->second.child;
1487 template<
typename ChildT>
1491 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1492 if (
const ChildT *child = iter->second.child) {
1493 child->evalActiveBoundingBox(bbox, visitVoxels);
1494 }
else if (isTileOn(iter)) {
1495 bbox.
expand(iter->first, ChildT::DIM);
1501 template<
typename ChildT>
1505 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1506 if (isChild(i)) ++sum;
1512 template<
typename ChildT>
1517 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1518 if (isTile(i)) ++sum;
1524 template<
typename ChildT>
1529 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1530 if (isTileOn(i)) ++sum;
1536 template<
typename ChildT>
1541 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1542 if (isTileOff(i)) ++sum;
1548 template<
typename ChildT>
1553 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1554 if (isChild(i)) sum += getChild(i).leafCount();
1560 template<
typename ChildT>
1565 if (ChildT::LEVEL != 0) {
1566 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1567 if (isChild(i)) sum += getChild(i).nonLeafCount();
1574 template<
typename ChildT>
1579 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1581 sum += getChild(i).onVoxelCount();
1582 }
else if (isTileOn(i)) {
1583 sum += ChildT::NUM_VOXELS;
1590 template<
typename ChildT>
1595 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1597 sum += getChild(i).offVoxelCount();
1599 sum += ChildT::NUM_VOXELS;
1606 template<
typename ChildT>
1611 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1612 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1618 template<
typename ChildT>
1623 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1624 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1629 template<
typename ChildT>
1634 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1636 sum += getChild(i).onTileCount();
1637 }
else if (isTileOn(i)) {
1647 template<
typename ChildT>
1651 MapCIter iter = this->findCoord(xyz);
1652 if (iter == mTable.end() || isTileOff(iter))
return false;
1653 return isTileOn(iter) ? true : getChild(iter).isValueOn(xyz);
1656 template<
typename ChildT>
1660 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1661 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1666 template<
typename ChildT>
1667 template<
typename AccessorT>
1671 MapCIter iter = this->findCoord(xyz);
1672 if (iter == mTable.end() || isTileOff(iter))
return false;
1673 if (isTileOn(iter))
return true;
1674 acc.insert(xyz, &getChild(iter));
1675 return getChild(iter).isValueOnAndCache(xyz, acc);
1679 template<
typename ChildT>
1680 inline const typename ChildT::ValueType&
1683 MapCIter iter = this->findCoord(xyz);
1684 return iter == mTable.end() ? mBackground
1685 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1688 template<
typename ChildT>
1689 template<
typename AccessorT>
1690 inline const typename ChildT::ValueType&
1693 MapCIter iter = this->findCoord(xyz);
1694 if (iter == mTable.end())
return mBackground;
1695 if (isChild(iter)) {
1696 acc.insert(xyz, &getChild(iter));
1697 return getChild(iter).getValueAndCache(xyz, acc);
1699 return getTile(iter).value;
1703 template<
typename ChildT>
1707 MapCIter iter = this->findCoord(xyz);
1708 return iter == mTable.end() ? -1
1709 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1712 template<
typename ChildT>
1713 template<
typename AccessorT>
1717 MapCIter iter = this->findCoord(xyz);
1718 if (iter == mTable.end())
return -1;
1719 if (isTile(iter))
return 0;
1720 acc.insert(xyz, &getChild(iter));
1721 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1725 template<
typename ChildT>
1729 MapIter iter = this->findCoord(xyz);
1730 if (iter != mTable.end() && !isTileOff(iter)) {
1731 if (isTileOn(iter)) {
1732 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1734 getChild(iter).setValueOff(xyz);
1739 template<
typename ChildT>
1743 ChildT* child = NULL;
1744 MapIter iter = this->findCoord(xyz);
1745 if (iter == mTable.end()) {
1747 child =
new ChildT(xyz, mBackground);
1748 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1752 }
else if (isChild(iter)) {
1753 child = &getChild(iter);
1754 }
else if (on != getTile(iter).active) {
1755 child =
new ChildT(xyz, getTile(iter).value, !on);
1756 setChild(iter, *child);
1758 if (child) child->setActiveState(xyz, on);
1761 template<
typename ChildT>
1762 template<
typename AccessorT>
1766 ChildT* child = NULL;
1767 MapIter iter = this->findCoord(xyz);
1768 if (iter == mTable.end()) {
1770 child =
new ChildT(xyz, mBackground);
1771 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1775 }
else if (isChild(iter)) {
1776 child = &getChild(iter);
1777 }
else if (on != getTile(iter).active) {
1778 child =
new ChildT(xyz, getTile(iter).value, !on);
1779 setChild(iter, *child);
1782 acc.insert(xyz, child);
1783 child->setActiveStateAndCache(xyz, on, acc);
1788 template<
typename ChildT>
1792 ChildT* child = NULL;
1793 MapIter iter = this->findCoord(xyz);
1794 if (iter == mTable.end()) {
1796 child =
new ChildT(xyz, mBackground);
1797 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1799 }
else if (isChild(iter)) {
1800 child = &getChild(iter);
1802 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1803 setChild(iter, *child);
1805 if (child) child->setValueOff(xyz, value);
1808 template<
typename ChildT>
1809 template<
typename AccessorT>
1813 ChildT* child = NULL;
1814 MapIter iter = this->findCoord(xyz);
1815 if (iter == mTable.end()) {
1817 child =
new ChildT(xyz, mBackground);
1818 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1820 }
else if (isChild(iter)) {
1821 child = &getChild(iter);
1823 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1824 setChild(iter, *child);
1827 acc.insert(xyz, child);
1828 child->setValueOffAndCache(xyz, value, acc);
1833 template<
typename ChildT>
1837 ChildT* child = NULL;
1838 MapIter iter = this->findCoord(xyz);
1839 if (iter == mTable.end()) {
1840 child =
new ChildT(xyz, mBackground);
1841 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1842 }
else if (isChild(iter)) {
1843 child = &getChild(iter);
1845 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1846 setChild(iter, *child);
1848 if (child) child->setValueOn(xyz, value);
1851 template<
typename ChildT>
1852 template<
typename AccessorT>
1856 ChildT* child = NULL;
1857 MapIter iter = this->findCoord(xyz);
1858 if (iter == mTable.end()) {
1859 child =
new ChildT(xyz, mBackground);
1860 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1861 }
else if (isChild(iter)) {
1862 child = &getChild(iter);
1864 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1865 setChild(iter, *child);
1868 acc.insert(xyz, child);
1869 child->setValueAndCache(xyz, value, acc);
1874 template<
typename ChildT>
1878 ChildT* child = NULL;
1879 MapIter iter = this->findCoord(xyz);
1880 if (iter == mTable.end()) {
1881 child =
new ChildT(xyz, mBackground);
1882 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1883 }
else if (isChild(iter)) {
1884 child = &getChild(iter);
1886 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1887 setChild(iter, *child);
1889 if (child) child->setValueOnly(xyz, value);
1892 template<
typename ChildT>
1893 template<
typename AccessorT>
1897 ChildT* child = NULL;
1898 MapIter iter = this->findCoord(xyz);
1899 if (iter == mTable.end()) {
1900 child =
new ChildT(xyz, mBackground);
1901 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1902 }
else if (isChild(iter)) {
1903 child = &getChild(iter);
1905 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1906 setChild(iter, *child);
1909 acc.insert(xyz, child);
1910 child->setValueOnlyAndCache(xyz, value, acc);
1915 template<
typename ChildT>
1916 template<
typename ModifyOp>
1920 ChildT* child = NULL;
1921 MapIter iter = this->findCoord(xyz);
1922 if (iter == mTable.end()) {
1923 child =
new ChildT(xyz, mBackground);
1924 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1925 }
else if (isChild(iter)) {
1926 child = &getChild(iter);
1930 bool createChild = isTileOff(iter);
1934 const ValueType& tileVal = getTile(iter).value;
1935 ValueType modifiedVal = tileVal;
1940 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1941 setChild(iter, *child);
1944 if (child) child->modifyValue(xyz, op);
1947 template<
typename ChildT>
1948 template<
typename ModifyOp,
typename AccessorT>
1952 ChildT* child = NULL;
1953 MapIter iter = this->findCoord(xyz);
1954 if (iter == mTable.end()) {
1955 child =
new ChildT(xyz, mBackground);
1956 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1957 }
else if (isChild(iter)) {
1958 child = &getChild(iter);
1962 bool createChild = isTileOff(iter);
1966 const ValueType& tileVal = getTile(iter).value;
1967 ValueType modifiedVal = tileVal;
1972 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1973 setChild(iter, *child);
1977 acc.insert(xyz, child);
1978 child->modifyValueAndCache(xyz, op, acc);
1983 template<
typename ChildT>
1984 template<
typename ModifyOp>
1988 ChildT* child = NULL;
1989 MapIter iter = this->findCoord(xyz);
1990 if (iter == mTable.end()) {
1991 child =
new ChildT(xyz, mBackground);
1992 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1993 }
else if (isChild(iter)) {
1994 child = &getChild(iter);
1996 const Tile& tile = getTile(iter);
1997 bool modifiedState = tile.active;
1998 ValueType modifiedVal = tile.value;
1999 op(modifiedVal, modifiedState);
2003 child =
new ChildT(xyz, tile.value, tile.active);
2004 setChild(iter, *child);
2007 if (child) child->modifyValueAndActiveState(xyz, op);
2010 template<
typename ChildT>
2011 template<
typename ModifyOp,
typename AccessorT>
2014 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2016 ChildT* child = NULL;
2017 MapIter iter = this->findCoord(xyz);
2018 if (iter == mTable.end()) {
2019 child =
new ChildT(xyz, mBackground);
2020 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2021 }
else if (isChild(iter)) {
2022 child = &getChild(iter);
2024 const Tile& tile = getTile(iter);
2025 bool modifiedState = tile.active;
2026 ValueType modifiedVal = tile.value;
2027 op(modifiedVal, modifiedState);
2031 child =
new ChildT(xyz, tile.value, tile.active);
2032 setChild(iter, *child);
2036 acc.insert(xyz, child);
2037 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2042 template<
typename ChildT>
2046 MapCIter iter = this->findCoord(xyz);
2047 if (iter == mTable.end()) {
2048 value = mBackground;
2050 }
else if (isChild(iter)) {
2051 return getChild(iter).probeValue(xyz, value);
2053 value = getTile(iter).value;
2054 return isTileOn(iter);
2057 template<
typename ChildT>
2058 template<
typename AccessorT>
2062 MapCIter iter = this->findCoord(xyz);
2063 if (iter == mTable.end()) {
2064 value = mBackground;
2066 }
else if (isChild(iter)) {
2067 acc.insert(xyz, &getChild(iter));
2068 return getChild(iter).probeValueAndCache(xyz, value, acc);
2070 value = getTile(iter).value;
2071 return isTileOn(iter);
2077 template<
typename ChildT>
2081 if (bbox.
empty())
return;
2084 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
2086 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
2088 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
2092 Coord tileMin = coordToKey(xyz);
2093 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2099 ChildT* child = NULL;
2100 MapIter iter = this->findKey(tileMin);
2101 if (iter == mTable.end()) {
2104 child =
new ChildT(xyz, mBackground);
2105 mTable[tileMin] = NodeStruct(*child);
2106 }
else if (isTile(iter)) {
2109 const Tile& tile = getTile(iter);
2110 child =
new ChildT(xyz, tile.value, tile.active);
2111 mTable[tileMin] = NodeStruct(*child);
2112 }
else if (isChild(iter)) {
2113 child = &getChild(iter);
2118 child->fill(
CoordBBox(xyz, tmp), value, active);
2124 MapIter iter = this->findOrAddCoord(tileMin);
2125 setTile(iter, Tile(value, active));
2132 template<
typename ChildT>
2140 template<
typename ChildT>
2141 template<
typename DenseT>
2145 typedef typename DenseT::ValueType DenseValueType;
2147 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2148 const Coord&
min = dense.bbox().min();
2150 for (
Coord xyz = bbox.
min(); xyz[0] <= bbox.
max()[0]; xyz[0] = nodeBBox.
max()[0] + 1) {
2151 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] = nodeBBox.
max()[1] + 1) {
2152 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] = nodeBBox.
max()[2] + 1) {
2160 MapCIter iter = this->findKey(nodeBBox.
min());
2161 if (iter != mTable.end() && isChild(iter)) {
2162 getChild(iter).copyToDense(sub, dense);
2164 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2166 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2167 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2168 DenseValueType* a1 = a0 + x*xStride;
2169 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2170 DenseValueType* a2 = a1 + y*yStride;
2171 for (
Int32 z=sub.
min()[2], ez=sub.
max()[2]+1; z<ez; ++z, a2 += zStride) {
2172 *a2 = DenseValueType(value);
2185 template<
typename ChildT>
2190 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(ValueType));
2193 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueType));
2197 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
2198 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
2199 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
2201 if (numTiles == 0 && numChildren == 0)
return false;
2204 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2205 if (isChild(i))
continue;
2206 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2207 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(ValueType));
2208 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
2211 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2212 if (isTile(i))
continue;
2213 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2214 getChild(i).writeTopology(os, toHalf);
2221 template<
typename ChildT>
2233 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2235 is.read(reinterpret_cast<char*>(&inside),
sizeof(ValueType));
2240 Coord rangeMin, rangeMax;
2242 is.read(reinterpret_cast<char*>(rangeMax.
asPointer()), 3 *
sizeof(
Int32));
2245 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2247 for (
int i = 0; i < 3; ++i) {
2248 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2249 rangeMin[i] = offset[i] << ChildT::TOTAL;
2251 tableSize += log2Dim[i];
2252 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2254 log2Dim[3] = log2Dim[1] + log2Dim[2];
2255 tableSize = 1U << tableSize;
2263 for (
Index i = 0; i < tableSize; ++i) {
2267 origin[0] = (n >> log2Dim[3]) + offset[0];
2268 n &= (1U << log2Dim[3]) - 1;
2269 origin[1] = (n >> log2Dim[2]) + offset[1];
2270 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2271 origin <<= ChildT::TOTAL;
2273 if (childMask.isOn(i)) {
2275 #ifdef OPENVDB_2_ABI_COMPATIBLE 2276 ChildT* child =
new ChildT(origin, mBackground);
2278 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2280 child->readTopology(is);
2281 mTable[origin] = NodeStruct(*child);
2286 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2288 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2297 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2300 Index numTiles = 0, numChildren = 0;
2301 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2302 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2304 if (numTiles == 0 && numChildren == 0)
return false;
2311 for (
Index n = 0; n < numTiles; ++n) {
2312 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2313 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2314 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2315 mTable[
Coord(vec)] = NodeStruct(Tile(value, active));
2319 for (
Index n = 0; n < numChildren; ++n) {
2320 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2322 #ifdef OPENVDB_2_ABI_COMPATIBLE 2323 ChildT* child =
new ChildT(origin, mBackground);
2325 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2327 child->readTopology(is, fromHalf);
2328 mTable[
Coord(vec)] = NodeStruct(*child);
2335 template<
typename ChildT>
2339 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2340 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2345 template<
typename ChildT>
2349 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2350 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2355 template<
typename ChildT>
2359 const Tile bgTile(mBackground,
false);
2361 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2367 ChildT& child = getChild(i);
2368 child.readBuffers(is, clipBBox, fromHalf);
2372 this->
clip(clipBBox);
2379 template<
typename ChildT>
2383 const Tile bgTile(mBackground,
false);
2387 MapType copyOfTable(mTable);
2388 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2389 const Coord& xyz = i->first;
2393 setTile(this->findCoord(xyz), bgTile);
2395 }
else if (!clipBBox.
isInside(tileBBox)) {
2399 getChild(i).clip(clipBBox, mBackground);
2403 tileBBox.intersect(clipBBox);
2404 const Tile& origTile = getTile(i);
2405 setTile(this->findCoord(xyz), bgTile);
2406 this->
sparseFill(tileBBox, origTile.value, origTile.active);
2419 template<
typename ChildT>
2424 ValueType value = zeroVal<ValueType>();
2425 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2426 if (this->isTile(i))
continue;
2427 this->getChild(i).prune(tolerance);
2428 if (this->getChild(i).isConstant(value, state, tolerance)) {
2429 this->setTile(i, Tile(value, state));
2439 template<
typename ChildT>
2440 template<
typename NodeT>
2444 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2445 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2447 MapIter iter = this->findCoord(xyz);
2448 if (iter == mTable.end() || isTile(iter))
return NULL;
2449 return (boost::is_same<NodeT, ChildT>::value)
2450 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2451 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2459 template<
typename ChildT>
2463 if (leaf == NULL)
return;
2464 ChildT* child = NULL;
2465 const Coord& xyz = leaf->origin();
2466 MapIter iter = this->findCoord(xyz);
2467 if (iter == mTable.end()) {
2468 if (ChildT::LEVEL>0) {
2469 child =
new ChildT(xyz, mBackground,
false);
2471 child =
reinterpret_cast<ChildT*
>(leaf);
2473 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2474 }
else if (isChild(iter)) {
2475 if (ChildT::LEVEL>0) {
2476 child = &getChild(iter);
2478 child =
reinterpret_cast<ChildT*
>(leaf);
2479 setChild(iter, *child);
2482 if (ChildT::LEVEL>0) {
2483 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2485 child =
reinterpret_cast<ChildT*
>(leaf);
2487 setChild(iter, *child);
2489 child->addLeaf(leaf);
2493 template<
typename ChildT>
2494 template<
typename AccessorT>
2498 if (leaf == NULL)
return;
2499 ChildT* child = NULL;
2500 const Coord& xyz = leaf->origin();
2501 MapIter iter = this->findCoord(xyz);
2502 if (iter == mTable.end()) {
2503 if (ChildT::LEVEL>0) {
2504 child =
new ChildT(xyz, mBackground,
false);
2506 child =
reinterpret_cast<ChildT*
>(leaf);
2508 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2509 }
else if (isChild(iter)) {
2510 if (ChildT::LEVEL>0) {
2511 child = &getChild(iter);
2513 child =
reinterpret_cast<ChildT*
>(leaf);
2514 setChild(iter, *child);
2517 if (ChildT::LEVEL>0) {
2518 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2520 child =
reinterpret_cast<ChildT*
>(leaf);
2522 setChild(iter, *child);
2524 acc.insert(xyz, child);
2525 child->addLeafAndCache(leaf, acc);
2528 template<
typename ChildT>
2532 MapIter iter = this->findCoord(xyz);
2533 if (iter == mTable.end()) {
2534 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2536 setTile(iter, Tile(value, state));
2540 template<
typename ChildT>
2543 const ValueType& value,
bool state)
2545 if (LEVEL >= level) {
2546 MapIter iter = this->findCoord(xyz);
2547 if (iter == mTable.end()) {
2548 if (LEVEL > level) {
2549 ChildT* child =
new ChildT(xyz, mBackground,
false);
2550 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2551 child->addTile(level, xyz, value, state);
2553 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2555 }
else if (isChild(iter)) {
2556 if (LEVEL > level) {
2557 getChild(iter).addTile(level, xyz, value, state);
2559 setTile(iter, Tile(value, state));
2562 if (LEVEL > level) {
2563 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2564 setChild(iter, *child);
2565 child->addTile(level, xyz, value, state);
2567 setTile(iter, Tile(value, state));
2574 template<
typename ChildT>
2575 template<
typename AccessorT>
2578 bool state, AccessorT& acc)
2580 if (LEVEL >= level) {
2581 MapIter iter = this->findCoord(xyz);
2582 if (iter == mTable.end()) {
2583 if (LEVEL > level) {
2584 ChildT* child =
new ChildT(xyz, mBackground,
false);
2585 acc.insert(xyz, child);
2586 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2587 child->addTileAndCache(level, xyz, value, state, acc);
2589 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2591 }
else if (isChild(iter)) {
2592 if (LEVEL > level) {
2593 ChildT* child = &getChild(iter);
2594 acc.insert(xyz, child);
2595 child->addTileAndCache(level, xyz, value, state, acc);
2597 setTile(iter, Tile(value, state));
2600 if (LEVEL > level) {
2601 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2602 acc.insert(xyz, child);
2603 setChild(iter, *child);
2604 child->addTileAndCache(level, xyz, value, state, acc);
2606 setTile(iter, Tile(value, state));
2616 template<
typename ChildT>
2617 inline typename ChildT::LeafNodeType*
2620 ChildT* child = NULL;
2621 MapIter iter = this->findCoord(xyz);
2622 if (iter == mTable.end()) {
2623 child =
new ChildT(xyz, mBackground,
false);
2624 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2625 }
else if (isChild(iter)) {
2626 child = &getChild(iter);
2628 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2629 setChild(iter, *child);
2631 return child->touchLeaf(xyz);
2635 template<
typename ChildT>
2636 template<
typename AccessorT>
2637 inline typename ChildT::LeafNodeType*
2640 ChildT* child = NULL;
2641 MapIter iter = this->findCoord(xyz);
2642 if (iter == mTable.end()) {
2643 child =
new ChildT(xyz, mBackground,
false);
2644 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2645 }
else if (isChild(iter)) {
2646 child = &getChild(iter);
2648 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2649 setChild(iter, *child);
2651 acc.insert(xyz, child);
2652 return child->touchLeafAndCache(xyz, acc);
2659 template<
typename ChildT>
2660 template<
typename NodeT>
2664 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2665 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2667 MapIter iter = this->findCoord(xyz);
2668 if (iter == mTable.end() || isTile(iter))
return NULL;
2669 ChildT* child = &getChild(iter);
2670 return (boost::is_same<NodeT, ChildT>::value)
2671 ?
reinterpret_cast<NodeT*
>(child)
2672 : child->template probeNode<NodeT>(xyz);
2677 template<
typename ChildT>
2678 template<
typename NodeT>
2682 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2683 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2685 MapCIter iter = this->findCoord(xyz);
2686 if (iter == mTable.end() || isTile(iter))
return NULL;
2687 const ChildT* child = &getChild(iter);
2688 return (boost::is_same<NodeT, ChildT>::value)
2689 ?
reinterpret_cast<const NodeT*
>(child)
2690 : child->template probeConstNode<NodeT>(xyz);
2695 template<
typename ChildT>
2696 inline typename ChildT::LeafNodeType*
2699 return this->
template probeNode<LeafNodeType>(xyz);
2703 template<
typename ChildT>
2704 inline const typename ChildT::LeafNodeType*
2707 return this->
template probeConstNode<LeafNodeType>(xyz);
2711 template<
typename ChildT>
2712 template<
typename AccessorT>
2713 inline typename ChildT::LeafNodeType*
2716 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2720 template<
typename ChildT>
2721 template<
typename AccessorT>
2722 inline const typename ChildT::LeafNodeType*
2725 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2729 template<
typename ChildT>
2730 template<
typename AccessorT>
2731 inline const typename ChildT::LeafNodeType*
2738 template<
typename ChildT>
2739 template<
typename NodeT,
typename AccessorT>
2743 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2744 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2746 MapIter iter = this->findCoord(xyz);
2747 if (iter == mTable.end() || isTile(iter))
return NULL;
2748 ChildT* child = &getChild(iter);
2749 acc.insert(xyz, child);
2750 return (boost::is_same<NodeT, ChildT>::value)
2751 ?
reinterpret_cast<NodeT*
>(child)
2752 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2757 template<
typename ChildT>
2758 template<
typename NodeT,
typename AccessorT>
2762 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2763 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2765 MapCIter iter = this->findCoord(xyz);
2766 if (iter == mTable.end() || isTile(iter))
return NULL;
2767 const ChildT* child = &getChild(iter);
2768 acc.insert(xyz, child);
2769 return (boost::is_same<NodeT, ChildT>::value)
2770 ?
reinterpret_cast<const NodeT*
>(child)
2771 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2778 template<
typename ChildT>
2779 template<
typename ArrayT>
2783 typedef typename ArrayT::value_type NodePtr;
2785 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2786 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2787 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2789 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2790 const ChildT, ChildT>::type ArrayChildT;
2792 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2793 if (ChildT* child = iter->second.child) {
2795 if (boost::is_same<NodePtr, ArrayChildT*>::value) {
2796 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2798 child->getNodes(array);
2805 template<
typename ChildT>
2806 template<
typename ArrayT>
2810 typedef typename ArrayT::value_type NodePtr;
2812 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2814 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2815 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2818 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2819 if (
const ChildNodeType *child = iter->second.child) {
2821 if (boost::is_same<NodePtr, const ChildT*>::value) {
2822 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2824 child->getNodes(array);
2833 template<
typename ChildT>
2834 template<
typename ArrayT>
2838 typedef typename ArrayT::value_type NodePtr;
2840 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2841 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2842 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2844 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2845 const ChildT, ChildT>::type ArrayChildT;
2847 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2848 if (ChildT* child = iter->second.child) {
2850 if (boost::is_same<NodePtr, ArrayChildT*>::value) {
2851 array.push_back(reinterpret_cast<NodePtr>(&stealChild(iter, Tile(value, state))));
2853 child->stealNodes(array, value, state);
2864 template<
typename ChildT>
2873 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2874 if (this->isTileOff(i))
continue;
2875 ChildT* child = i->second.child;
2877 child =
new ChildT(i->first, this->getTile(i).value,
true);
2878 i->second.child = child;
2880 child->voxelizeActiveTiles(threaded);
2888 template<
typename ChildT>
2889 template<MergePolicy Policy>
2899 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2900 MapIter j = mTable.find(i->first);
2901 if (other.isChild(i)) {
2902 if (j == mTable.end()) {
2903 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2904 child.resetBackground(other.mBackground, mBackground);
2905 mTable[i->first] = NodeStruct(child);
2906 }
else if (isTile(j)) {
2908 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2909 child.resetBackground(other.mBackground, mBackground);
2913 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
2914 other.mBackground, mBackground);
2916 }
else if (other.isTileOn(i)) {
2917 if (j == mTable.end()) {
2918 mTable[i->first] = i->second;
2919 }
else if (!isTileOn(j)) {
2921 setTile(j, Tile(other.getTile(i).value,
true));
2928 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2929 MapIter j = mTable.find(i->first);
2930 if (other.isChild(i)) {
2931 if (j == mTable.end()) {
2932 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2933 child.resetBackground(other.mBackground, mBackground);
2934 mTable[i->first] = NodeStruct(child);
2935 }
else if (isTile(j)) {
2936 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2937 child.resetBackground(other.mBackground, mBackground);
2940 getChild(j).template merge<MERGE_NODES>(
2941 getChild(i), other.mBackground, mBackground);
2948 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2949 MapIter j = mTable.find(i->first);
2950 if (other.isChild(i)) {
2951 if (j == mTable.end()) {
2953 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2954 child.resetBackground(other.mBackground, mBackground);
2955 mTable[i->first] = NodeStruct(child);
2956 }
else if (isTile(j)) {
2958 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2959 child.resetBackground(other.mBackground, mBackground);
2960 const Tile tile = getTile(j);
2964 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2965 tile.value, tile.active);
2969 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
2970 other.mBackground, mBackground);
2972 }
else if (other.isTileOn(i)) {
2973 if (j == mTable.end()) {
2975 mTable[i->first] = i->second;
2976 }
else if (isTileOff(j)) {
2978 setTile(j, Tile(other.getTile(i).value,
true));
2979 }
else if (isChild(j)) {
2981 const Tile& tile = getTile(i);
2982 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2983 tile.value, tile.active);
3000 template<
typename ChildT>
3001 template<
typename OtherChildType>
3006 typedef typename OtherRootT::MapCIter OtherCIterT;
3008 enforceSameConfiguration(other);
3010 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3011 MapIter j = mTable.find(i->first);
3012 if (other.isChild(i)) {
3013 if (j == mTable.end()) {
3014 mTable[i->first] = NodeStruct(
3015 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
3016 }
else if (this->isChild(j)) {
3017 this->getChild(j).topologyUnion(other.getChild(i));
3019 ChildT* child =
new ChildT(
3020 other.getChild(i), this->getTile(j).value,
TopologyCopy());
3021 if (this->isTileOn(j)) child->setValuesOn();
3022 this->setChild(j, *child);
3024 }
else if (other.isTileOn(i)) {
3025 if (j == mTable.end()) {
3026 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
3027 }
else if (this->isChild(j)) {
3028 this->getChild(j).setValuesOn();
3029 }
else if (this->isTileOff(j)) {
3030 this->setTile(j, Tile(this->getTile(j).value,
true));
3036 template<
typename ChildT>
3037 template<
typename OtherChildType>
3042 typedef typename OtherRootT::MapCIter OtherCIterT;
3044 enforceSameConfiguration(other);
3046 std::set<Coord> tmp;
3047 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3048 OtherCIterT j = other.mTable.find(i->first);
3049 if (this->isChild(i)) {
3050 if (j == other.mTable.end() || other.isTileOff(j)) {
3051 tmp.insert(i->first);
3052 }
else if (other.isChild(j)) {
3053 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3055 }
else if (this->isTileOn(i)) {
3056 if (j == other.mTable.end() || other.isTileOff(j)) {
3057 this->setTile(i, Tile(this->getTile(i).value,
false));
3058 }
else if (other.isChild(j)) {
3060 new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
3061 this->setChild(i, *child);
3065 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3066 MapIter it = this->findCoord(*i);
3067 setTile(it, Tile());
3072 template<
typename ChildT>
3073 template<
typename OtherChildType>
3078 typedef typename OtherRootT::MapCIter OtherCIterT;
3080 enforceSameConfiguration(other);
3082 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3083 MapIter j = mTable.find(i->first);
3084 if (other.isChild(i)) {
3085 if (j == mTable.end() || this->isTileOff(j)) {
3087 }
else if (this->isChild(j)) {
3088 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3089 }
else if (this->isTileOn(j)) {
3091 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
3092 child->topologyDifference(other.getChild(i), mBackground);
3093 this->setChild(j, *child);
3095 }
else if (other.isTileOn(i)) {
3096 if (j == mTable.end() || this->isTileOff(j)) {
3098 }
else if (this->isChild(j)) {
3101 }
else if (this->isTileOn(j)) {
3102 this->setTile(j, Tile(this->getTile(j).value,
false));
3111 template<
typename ChildT>
3112 template<
typename CombineOp>
3119 this->insertKeys(keys);
3120 other.insertKeys(keys);
3122 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3123 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3124 if (isTile(iter) && isTile(otherIter)) {
3127 op(args.
setARef(getTile(iter).value)
3128 .setAIsActive(isTileOn(iter))
3129 .setBRef(getTile(otherIter).value)
3130 .setBIsActive(isTileOn(otherIter)));
3133 }
else if (isChild(iter) && isTile(otherIter)) {
3135 ChildT& child = getChild(iter);
3136 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3138 }
else if (isTile(iter) && isChild(otherIter)) {
3143 ChildT& child = getChild(otherIter);
3144 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3147 setChild(iter, stealChild(otherIter, Tile()));
3151 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3152 child.combine(otherChild, op);
3154 if (prune && isChild(iter)) getChild(iter).prune();
3158 op(args.
setARef(mBackground).setBRef(other.mBackground));
3159 mBackground = args.
result();
3171 template<
typename CombineOp,
typename RootT,
typename OtherRootT,
bool Compatible = false>
3174 static inline void combine2(RootT&
self,
const RootT&,
const OtherRootT& other1,
3179 self.enforceSameConfiguration(other1);
3180 self.enforceCompatibleValueTypes(other1);
3182 std::ostringstream ostr;
3183 ostr <<
"cannot combine a " <<
typeid(OtherRootT).name()
3184 <<
" into a " <<
typeid(RootT).name();
3190 template<
typename CombineOp,
typename RootT,
typename OtherRootT>
3193 static inline void combine2(RootT&
self,
const RootT& other0,
const OtherRootT& other1,
3194 CombineOp& op,
bool prune)
3196 self.doCombine2(other0, other1, op, prune);
3201 template<
typename ChildT>
3202 template<
typename CombineOp,
typename OtherRootNode>
3205 CombineOp& op,
bool prune)
3207 typedef typename OtherRootNode::ValueType OtherValueType;
3211 *
this, other0, other1, op, prune);
3215 template<
typename ChildT>
3216 template<
typename CombineOp,
typename OtherRootNode>
3219 CombineOp& op,
bool prune)
3221 enforceSameConfiguration(other1);
3223 typedef typename OtherRootNode::ValueType OtherValueT;
3224 typedef typename OtherRootNode::Tile OtherTileT;
3225 typedef typename OtherRootNode::NodeStruct OtherNodeStructT;
3226 typedef typename OtherRootNode::MapCIter OtherMapCIterT;
3231 other0.insertKeys(keys);
3232 other1.insertKeys(keys);
3234 const NodeStruct bg0(Tile(other0.mBackground,
false));
3235 const OtherNodeStructT bg1(OtherTileT(other1.mBackground,
false));
3237 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3238 MapIter thisIter = this->findOrAddCoord(*i);
3239 MapCIter iter0 = other0.findKey(*i);
3240 OtherMapCIterT iter1 = other1.findKey(*i);
3241 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3242 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3243 if (ns0.isTile() && ns1.isTile()) {
3246 op(args.
setARef(ns0.tile.value)
3247 .setAIsActive(ns0.isTileOn())
3248 .setBRef(ns1.tile.value)
3249 .setBIsActive(ns1.isTileOn()));
3252 if (!isChild(thisIter)) {
3254 const Coord& childOrigin =
3255 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3256 setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
3258 ChildT& child = getChild(thisIter);
3263 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3264 }
else if (ns1.isTile()) {
3267 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3271 child.combine2(*ns0.child, *ns1.child, op);
3274 if (prune && isChild(thisIter)) getChild(thisIter).prune();
3278 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
3279 mBackground = args.
result();
3286 template<
typename ChildT>
3287 template<
typename BBoxOp>
3291 const bool descent = op.template descent<LEVEL>();
3292 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3293 if (this->isTileOff(i))
continue;
3294 if (this->isChild(i) && descent) {
3295 this->getChild(i).visitActiveBBox(op);
3307 template<
typename ChildT>
3308 template<
typename VisitorOp>
3312 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
3316 template<
typename ChildT>
3317 template<
typename VisitorOp>
3321 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
3325 template<
typename ChildT>
3326 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
3330 typename RootNodeT::ValueType val;
3331 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
3332 if (op(iter))
continue;
3333 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3343 template<
typename ChildT>
3344 template<
typename OtherRootNodeType,
typename VisitorOp>
3349 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
3353 template<
typename ChildT>
3354 template<
typename OtherRootNodeType,
typename VisitorOp>
3359 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
3363 template<
typename ChildT>
3366 typename OtherRootNodeT,
3368 typename ChildAllIterT,
3369 typename OtherChildAllIterT>
3373 enforceSameConfiguration(other);
3375 typename RootNodeT::ValueType val;
3376 typename OtherRootNodeT::ValueType otherVal;
3381 RootNodeT copyOfSelf(
self.mBackground);
3382 copyOfSelf.mTable =
self.mTable;
3383 OtherRootNodeT copyOfOther(other.mBackground);
3384 copyOfOther.mTable = other.mTable;
3388 self.insertKeys(keys);
3389 other.insertKeys(keys);
3390 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3391 copyOfSelf.findOrAddCoord(*i);
3392 copyOfOther.findOrAddCoord(*i);
3395 ChildAllIterT iter = copyOfSelf.beginChildAll();
3396 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3398 for ( ; iter && otherIter; ++iter, ++otherIter)
3400 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3402 typename ChildAllIterT::ChildNodeType* child =
3403 (skipBranch & 1U) ? NULL : iter.probeChild(val);
3404 typename OtherChildAllIterT::ChildNodeType* otherChild =
3405 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
3407 if (child != NULL && otherChild != NULL) {
3408 child->visit2Node(*otherChild, op);
3409 }
else if (child != NULL) {
3410 child->visit2(otherIter, op);
3411 }
else if (otherChild != NULL) {
3412 otherChild->visit2(iter, op,
true);
3417 copyOfSelf.eraseBackgroundTiles();
3418 copyOfOther.eraseBackgroundTiles();
3422 self.resetTable(copyOfSelf.mTable);
3423 other.resetTable(copyOfOther.mTable);
3430 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3346
const NodeT * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2680
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:68
RootNode< typename ChildType::template ValueConverter< OtherValueType >::Type > Type
Definition: RootNode.h:93
bool resultIsActive() const
Definition: Types.h:376
Index32 nonLeafCount() const
Definition: RootNode.h:1562
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:403
Definition: NodeMasks.h:1068
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1895
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2381
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1620
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: RootNode.h:1918
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:191
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:421
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:420
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1268
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: RootNode.h:2461
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
Coord & setX(Int32 x)
Definition: Coord.h:101
bool isOn(Index32 i) const
Definition: NodeMasks.h:1334
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2337
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: RootNode.h:1705
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1321
RootNode(const RootNode &other)
Definition: RootNode.h:111
boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:1023
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:70
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1256
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1854
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:151
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2347
NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:86
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:397
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Index64 onVoxelCount() const
Definition: RootNode.h:1576
Index64 onTileCount() const
Definition: RootNode.h:1631
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:404
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: RootNode.h:2134
Index getHeight() const
Definition: RootNode.h:490
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:365
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1234
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2223
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: RootNode.h:1835
ChildAllIter beginChildAll()
Definition: RootNode.h:417
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2781
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of all voxels, both active and inactive, that intersect a given bou...
Definition: RootNode.h:2143
BOOST_STATIC_ASSERT(boost::mpl::size< NodeChainType >::value==LEVEL+1)
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:1016
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:658
Index32 leafCount() const
Definition: RootNode.h:1550
ChildType::ValueType ValueType
Definition: RootNode.h:80
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: RootNode.h:2421
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1172
bool hasActiveTiles() const
Definition: RootNode.h:1658
Int32 x() const
Definition: Coord.h:146
ChildOffCIter beginChildOff() const
Definition: RootNode.h:413
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Expand the specified bbox so it includes the active tiles of this root node as well as all the active...
Definition: RootNode.h:1489
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1116
void topologyDifference(const RootNode< OtherChildType > &other)
Difference this tree's set of active values with the active values of the other tree, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this tree and inactive in the other tree.
Definition: RootNode.h:3075
Index getDepth() const
Definition: RootNode.h:491
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:92
ChildOnIter beginChildOn()
Definition: RootNode.h:415
ChildType::BuildType BuildType
Definition: RootNode.h:81
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:440
ChildOffIter beginChildOff()
Definition: RootNode.h:416
void addTile(const Coord &xyz, const ValueType &value, bool state)
Add a tile containing voxel (x, y, z) at the root level, deleting the existing branch if necessary...
Definition: RootNode.h:2530
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3204
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2866
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:396
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:330
Coord & setY(Int32 y)
Definition: Coord.h:102
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:224
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:370
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:394
Index32 Index
Definition: Types.h:58
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:398
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: RootNode.h:2705
Index64 offVoxelCount() const
Definition: RootNode.h:1592
int32_t Int32
Definition: Types.h:60
ValueAllIter beginValueAll()
Definition: RootNode.h:427
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
uint64_t Index64
Definition: Types.h:57
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:399
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: RootNode.h:827
ValueAllCIter beginValueAll() const
Definition: RootNode.h:424
#define OPENVDB_VERSION_NAME
Definition: version.h:43
ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:79
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: RootNode.h:2836
ValueOffCIter beginValueOff() const
Definition: RootNode.h:423
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
NodeT * probeNodeAndCache(const Coord &xyz, AccessorT &acc)
Same as probeNode() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:2741
Coord & setZ(Int32 z)
Definition: Coord.h:103
bool hasSameTopology(const RootNode< OtherChildType > &other) const
Return true if the given tree has the same node and active value topology as this tree (but possibly ...
Definition: RootNode.h:1358
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool state)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
Definition: RootNode.h:2442
~RootNode()
Definition: RootNode.h:159
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:401
OPENVDB_API void setGridBackgroundValuePtr(std::ios_base &, const void *background)
Specify (a pointer to) the background value of the grid currently being read from or written to the g...
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() but, if necessary, update the given accessor with pointers to the nodes along the p...
Definition: RootNode.h:2496
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:100
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1405
Definition: version.h:100
const AValueType & result() const
Get the output value.
Definition: Types.h:357
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1950
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:405
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3174
void load(std::istream &is)
Definition: NodeMasks.h:1375
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1986
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1727
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3114
void translate(const Coord &t)
Translate this bounding box by .
Definition: Coord.h:440
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:111
ValueOnCIter beginValueOn() const
Definition: RootNode.h:422
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: RootNode.h:2079
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2662
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:475
void clear()
Definition: RootNode.h:1478
ValueOnIter beginValueOn()
Definition: RootNode.h:425
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:183
Definition: Exceptions.h:39
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1134
uint32_t Index32
Definition: Types.h:56
Definition: RootNode.h:69
ChildOnCIter beginChildOn() const
Definition: RootNode.h:412
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: RootNode.h:2697
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:409
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3193
ChildAllCIter beginChildAll() const
Definition: RootNode.h:414
boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:1017
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1764
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:487
void topologyIntersection(const RootNode< OtherChildType > &other)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
Definition: RootNode.h:3039
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: RootNode.h:1876
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:395
RootNode(const RootNode< OtherChildType > &other)
Construct a new tree that reproduces the topology and active states of a tree of a different ValueTyp...
Definition: RootNode.h:120
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1669
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1811
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1050
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:402
Int32 z() const
Definition: Coord.h:148
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1345
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:3289
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1681
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: RootNode.h:2618
Definition: Exceptions.h:87
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1330
void topologyUnion(const RootNode< OtherChildType > &other)
Union this tree's set of active values with the active values of the other tree, whose ValueType may ...
Definition: RootNode.h:3003
const Coord & min() const
Definition: Coord.h:332
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:457
static Index getLevel()
Definition: RootNode.h:482
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1715
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:450
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:395
const Coord & max() const
Definition: Coord.h:333
Definition: RootNode.h:71
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:259
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1464
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:411
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1649
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:406
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2060
void read(std::istream &is)
Definition: Coord.h:235
Int32 y() const
Definition: Coord.h:147
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: RootNode.h:1741
Definition: Exceptions.h:88
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:458
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2044
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2187
ChildType ChildNodeType
Definition: RootNode.h:78
Index getWidth() const
Definition: RootNode.h:489
void sparseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: RootNode.h:563
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1437
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1307
void visit(VisitorOp &)
Definition: RootNode.h:3310
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:410
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
ValueOffIter beginValueOff()
Definition: RootNode.h:426
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:383
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void setBackground(const ValueType &value, bool updateChildNodes)
Change inactive tiles or voxels with a value equal to +/- the old background to the specified value (...
Definition: RootNode.h:1207
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:401
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2891
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2013
bool empty() const
Definition: Coord.h:350
const Int32 * asPointer() const
Definition: Coord.h:157
const NodeT * probeConstNodeAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeNode() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:2760
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:312
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1337
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1608
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:419
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:75
static Index getChildDim()
Definition: RootNode.h:484
void addTileAndCache(Index level, const Coord &xyz, const ValueType &, bool state, AccessorT &)
Same as addTile() but, if necessary, update the given accessor with pointers to the nodes along the p...
Definition: RootNode.h:2577
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:324
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94