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>
68 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
74 template<
typename ChildType>
82 static const Index LEVEL = 1 + ChildType::LEVEL;
86 BOOST_STATIC_ASSERT(boost::mpl::size<NodeChainType>::value == LEVEL + 1);
90 template<
typename OtherValueType>
98 template<
typename OtherNodeType>
108 explicit RootNode(
const ValueType& background);
118 template<
typename OtherChildType>
129 template<
typename OtherChildType>
131 const ValueType& background,
const ValueType& foreground,
TopologyCopy);
143 template<
typename OtherChildType>
155 template<
typename OtherChildType>
162 Tile(): value(
zeroVal<ValueType>()), active(false) {}
163 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
173 NodeStruct(): child(NULL) {}
174 NodeStruct(ChildType& c): child(&c) {}
175 NodeStruct(
const Tile& t): child(NULL), tile(t) {}
178 bool isChild()
const {
return child != NULL; }
179 bool isTile()
const {
return child == NULL; }
180 bool isTileOff()
const {
return isTile() && !tile.active; }
181 bool isTileOn()
const {
return isTile() && tile.active; }
183 void set(ChildType& c) {
delete child; child = &c; }
184 void set(
const Tile& t) {
delete child; child = NULL; tile = t; }
185 ChildType& steal(
const Tile& t) { ChildType* c = child; child = NULL; tile = t;
return *c; }
188 typedef std::map<Coord, NodeStruct> MapType;
189 typedef typename MapType::iterator MapIter;
190 typedef typename MapType::const_iterator MapCIter;
192 typedef std::set<Coord> CoordSet;
193 typedef typename CoordSet::iterator CoordSetIter;
194 typedef typename CoordSet::const_iterator CoordSetCIter;
196 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
197 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
198 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
199 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
200 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
201 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
202 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
203 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
205 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
206 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
207 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
208 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
209 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
210 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
211 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
212 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
215 static inline bool test(
const MapIter&) {
return true; }
216 static inline bool test(
const MapCIter&) {
return true; }
219 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
220 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
222 struct ValueOffPred {
223 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
224 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
226 struct ValueAllPred {
227 static inline bool test(
const MapIter& i) {
return isTile(i); }
228 static inline bool test(
const MapCIter& i) {
return isTile(i); }
231 static inline bool test(
const MapIter& i) {
return isChild(i); }
232 static inline bool test(
const MapCIter& i) {
return isChild(i); }
234 struct ChildOffPred {
235 static inline bool test(
const MapIter& i) {
return isTile(i); }
236 static inline bool test(
const MapCIter& i) {
return isTile(i); }
239 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
243 typedef _RootNodeT RootNodeT;
244 typedef _MapIterT MapIterT;
248 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
250 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
252 RootNodeT* getParentNode()
const {
return mParentNode; }
254 RootNodeT& parent()
const
256 if (!mParentNode)
OPENVDB_THROW(ValueError,
"iterator references a null parent node");
260 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
261 operator bool()
const {
return this->test(); }
263 void increment() { ++mIter; this->skip(); }
264 bool next() { this->increment();
return this->test(); }
265 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
271 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
274 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
275 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
276 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
277 void setValueOff()
const { mIter->second.tile.active =
false; }
280 Coord getCoord()
const {
return mIter->first; }
282 void getCoord(Coord& xyz)
const { xyz = this->getCoord(); }
285 BaseIter(): mParentNode(NULL) {}
286 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
288 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
290 RootNodeT* mParentNode;
294 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
295 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
298 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
299 typedef RootNodeT NodeType;
300 typedef NodeType ValueType;
301 typedef ChildNodeT ChildNodeType;
302 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
303 typedef typename boost::remove_const<ValueType>::type NonConstValueType;
304 typedef typename boost::remove_const<ChildNodeType>::type NonConstChildNodeType;
308 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
310 ChildIter& operator++() { BaseT::increment();
return *
this; }
312 ChildNodeT& getValue()
const {
return getChild(mIter); }
313 ChildNodeT&
operator*()
const {
return this->getValue(); }
314 ChildNodeT* operator->()
const {
return &this->getValue(); }
317 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
318 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
321 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
322 typedef RootNodeT NodeType;
323 typedef ValueT ValueType;
324 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
325 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
329 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
331 ValueIter& operator++() { BaseT::increment();
return *
this; }
333 ValueT& getValue()
const {
return getTile(mIter).value; }
334 ValueT&
operator*()
const {
return this->getValue(); }
335 ValueT* operator->()
const {
return &(this->getValue()); }
337 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
339 template<
typename ModifyOp>
340 void modifyValue(
const ModifyOp& op)
const
342 assert(isTile(mIter));
343 op(getTile(mIter).value);
347 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
348 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
351 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
352 typedef RootNodeT NodeType;
353 typedef ValueT ValueType;
354 typedef ChildNodeT ChildNodeType;
355 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
356 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
357 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
361 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
363 DenseIter& operator++() { BaseT::increment();
return *
this; }
365 bool isChildNode()
const {
return isChild(mIter); }
367 ChildNodeT* probeChild(NonConstValueType& value)
const
369 if (isChild(mIter))
return &getChild(mIter);
370 value = getTile(mIter).value;
373 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const
375 child = this->probeChild(value);
376 return child != NULL;
378 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
380 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
381 void setChild(ChildNodeT* c)
const { assert(c != NULL); RootNodeT::setChild(mIter, *c); }
382 void setValue(
const ValueT& v)
const
384 if (isTile(mIter)) getTile(mIter).value = v;
388 else stealChild(mIter, Tile(v,
true));
393 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
394 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
395 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
396 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
397 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
398 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
400 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
401 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
402 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
403 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
404 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
405 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
408 ChildOnCIter
cbeginChildOn()
const {
return ChildOnCIter(*
this, mTable.begin()); }
409 ChildOffCIter
cbeginChildOff()
const {
return ChildOffCIter(*
this, mTable.begin()); }
410 ChildAllCIter
cbeginChildAll()
const {
return ChildAllCIter(*
this, mTable.begin()); }
414 ChildOnIter
beginChildOn() {
return ChildOnIter(*
this, mTable.begin()); }
415 ChildOffIter
beginChildOff() {
return ChildOffIter(*
this, mTable.begin()); }
416 ChildAllIter
beginChildAll() {
return ChildAllIter(*
this, mTable.begin()); }
418 ValueOnCIter
cbeginValueOn()
const {
return ValueOnCIter(*
this, mTable.begin()); }
419 ValueOffCIter
cbeginValueOff()
const {
return ValueOffCIter(*
this, mTable.begin()); }
420 ValueAllCIter
cbeginValueAll()
const {
return ValueAllCIter(*
this, mTable.begin()); }
424 ValueOnIter
beginValueOn() {
return ValueOnIter(*
this, mTable.begin()); }
425 ValueOffIter
beginValueOff() {
return ValueOffIter(*
this, mTable.begin()); }
426 ValueAllIter
beginValueAll() {
return ValueAllIter(*
this, mTable.begin()); }
436 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
453 void setBackground(
const ValueType& value,
bool updateChildNodes);
459 bool isBackgroundTile(
const Tile&)
const;
461 bool isBackgroundTile(
const MapIter&)
const;
463 bool isBackgroundTile(
const MapCIter&)
const;
467 size_t numBackgroundTiles()
const;
470 size_t eraseBackgroundTiles();
471 void clear() { this->clearTable(); }
474 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
479 bool expand(
const Coord& xyz);
482 static void getNodeLog2Dims(std::vector<Index>& dims);
488 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
489 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
490 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
493 Coord getMinIndex()
const;
495 Coord getMaxIndex()
const;
497 void getIndexRange(CoordBBox& bbox)
const;
501 template<
typename OtherChildType>
505 template<
typename OtherChildType>
510 template<
typename OtherChildType>
517 Index64 onLeafVoxelCount()
const;
518 Index64 offLeafVoxelCount()
const;
521 bool isValueOn(
const Coord& xyz)
const;
523 bool hasActiveTiles()
const;
525 const ValueType& getValue(
const Coord& xyz)
const;
526 bool probeValue(
const Coord& xyz, ValueType& value)
const;
531 int getValueDepth(
const Coord& xyz)
const;
534 void setActiveState(
const Coord& xyz,
bool on);
536 void setValueOnly(
const Coord& xyz,
const ValueType& value);
538 void setValueOn(
const Coord& xyz,
const ValueType& value);
540 void setValueOff(
const Coord& xyz);
542 void setValueOff(
const Coord& xyz,
const ValueType& value);
546 template<
typename ModifyOp>
547 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
549 template<
typename ModifyOp>
550 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
558 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
565 template<
typename DenseT>
566 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
572 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
573 bool readTopology(std::istream&,
bool fromHalf =
false);
575 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
576 void readBuffers(std::istream&,
bool fromHalf =
false);
577 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
587 template<
typename AccessorT>
588 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
593 template<
typename AccessorT>
594 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
600 template<
typename AccessorT>
601 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
607 template<
typename AccessorT>
608 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
615 template<
typename ModifyOp,
typename AccessorT>
616 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
622 template<
typename ModifyOp,
typename AccessorT>
623 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
629 template<
typename AccessorT>
630 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
636 template<
typename AccessorT>
637 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
644 template<
typename AccessorT>
645 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
652 template<
typename AccessorT>
653 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
656 void clip(
const CoordBBox&);
663 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
667 void addLeaf(LeafNodeType* leaf);
671 template<
typename AccessorT>
672 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
682 template<
typename NodeT>
683 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
687 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
692 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
696 template<
typename AccessorT>
697 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
704 LeafNodeType* touchLeaf(
const Coord& xyz);
708 template<
typename AccessorT>
709 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
712 template <
typename NodeT>
715 NodeT* probeNode(
const Coord& xyz);
716 template <
typename NodeT>
717 const NodeT* probeConstNode(
const Coord& xyz)
const;
721 template<
typename NodeT,
typename AccessorT>
724 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
725 template<
typename NodeT,
typename AccessorT>
726 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
730 LeafNodeType* probeLeaf(
const Coord& xyz);
733 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
734 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
738 template<
typename AccessorT>
741 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
742 template<
typename AccessorT>
743 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
744 template<
typename AccessorT>
745 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
754 template<
typename ArrayT>
void getNodes(ArrayT& array);
777 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
781 template<
typename ArrayT>
805 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
806 template<
typename ArrayT>
811 void voxelizeActiveTiles();
820 template<MergePolicy Policy>
void merge(
RootNode& other);
835 template<
typename OtherChildType>
851 template<
typename OtherChildType>
864 template<
typename OtherChildType>
867 template<
typename CombineOp>
868 void combine(
RootNode& other, CombineOp&,
bool prune =
false);
870 template<
typename CombineOp,
typename OtherRootNode >
871 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
872 CombineOp& op,
bool prune =
false);
879 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
881 template<
typename VisitorOp>
void visit(VisitorOp&);
882 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
884 template<
typename OtherRootNodeType,
typename VisitorOp>
885 void visit2(OtherRootNodeType& other, VisitorOp&);
886 template<
typename OtherRootNodeType,
typename VisitorOp>
887 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
899 inline void clearTable();
901 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
903 void resetTable(
const MapType&)
const {}
906 Index getChildCount()
const;
907 Index getTileCount()
const;
908 Index getActiveTileCount()
const;
909 Index getInactiveTileCount()
const;
912 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
915 void insertKeys(CoordSet&)
const;
918 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
920 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
923 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
926 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
929 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
931 MapIter findOrAddCoord(
const Coord& xyz);
940 template<
typename OtherChildType>
941 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
948 template<
typename OtherChildType>
949 static void enforceCompatibleValueTypes(
const RootNode<OtherChildType>& other);
951 template<
typename CombineOp,
typename OtherRootNode >
952 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
954 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
955 static inline void doVisit(RootNodeT&, VisitorOp&);
957 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
958 typename ChildAllIterT,
typename OtherChildAllIterT>
959 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
963 ValueType mBackground;
990 template<
typename HeadT,
int HeadLevel>
993 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
997 template<
typename HeadT>
999 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
1007 template<
typename ChildT1,
typename NodeT2>
1011 static const bool value =
false;
1014 template<
typename ChildT1,
typename ChildT2>
1016 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1024 template<
typename ChildT>
1032 template<
typename ChildT>
1040 template<
typename ChildT>
1041 template<
typename OtherChildType>
1044 const ValueType& backgd,
const ValueType& foregd,
TopologyCopy):
1049 enforceSameConfiguration(other);
1051 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1054 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1055 mTable[i->first] = OtherRootT::isTile(i)
1056 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1057 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1062 template<
typename ChildT>
1063 template<
typename OtherChildType>
1071 enforceSameConfiguration(other);
1073 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1075 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1076 mTable[i->first] = OtherRootT::isTile(i)
1077 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1078 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1089 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1096 self.enforceSameConfiguration(other);
1097 self.enforceCompatibleValueTypes(other);
1099 std::ostringstream ostr;
1100 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1101 <<
" to a " <<
typeid(RootT).name();
1107 template<
typename RootT,
typename OtherRootT>
1112 typedef typename RootT::ValueType ValueT;
1113 typedef typename RootT::ChildNodeType ChildT;
1114 typedef typename RootT::NodeStruct NodeStruct;
1115 typedef typename RootT::Tile Tile;
1116 typedef typename OtherRootT::ValueType OtherValueT;
1117 typedef typename OtherRootT::MapCIter OtherMapCIter;
1118 typedef typename OtherRootT::Tile OtherTile;
1122 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1125 self.mBackground = Local::convertValue(other.mBackground);
1130 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1131 if (other.isTile(i)) {
1133 const OtherTile& otherTile = other.getTile(i);
1134 self.mTable[i->first] = NodeStruct(
1135 Tile(Local::convertValue(otherTile.value), otherTile.active));
1138 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1146 template<
typename ChildT>
1147 inline RootNode<ChildT>&
1150 if (&other !=
this) {
1151 mBackground = other.mBackground;
1156 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1158 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1165 template<
typename ChildT>
1166 template<
typename OtherChildType>
1171 typedef typename OtherRootT::ValueType OtherValueT;
1181 template<
typename ChildT>
1187 if (updateChildNodes) {
1190 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1191 ChildT *child = iter->second.child;
1193 child->resetBackground(mBackground, background);
1195 Tile& tile = getTile(iter);
1196 if (tile.active)
continue;
1198 tile.value = background;
1205 mBackground = background;
1208 template<
typename ChildT>
1215 template<
typename ChildT>
1222 template<
typename ChildT>
1230 template<
typename ChildT>
1235 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1236 if (this->isBackgroundTile(i)) ++count;
1242 template<
typename ChildT>
1246 std::set<Coord> keysToErase;
1247 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1248 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
1250 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1253 return keysToErase.size();
1260 template<
typename ChildT>
1264 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1265 keys.insert(i->first);
1270 template<
typename ChildT>
1271 inline typename RootNode<ChildT>::MapIter
1272 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
1274 const Coord key = coordToKey(xyz);
1275 std::pair<MapIter, bool> result = mTable.insert(
1276 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1277 return result.first;
1281 template<
typename ChildT>
1285 const Coord key = coordToKey(xyz);
1286 std::pair<MapIter, bool> result = mTable.insert(
1287 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1288 return result.second;
1295 template<
typename ChildT>
1300 ChildT::getNodeLog2Dims(dims);
1304 template<
typename ChildT>
1308 return mTable.empty() ? Coord(0) : mTable.begin()->first;
1311 template<
typename ChildT>
1315 return mTable.empty() ? Coord(0) : mTable.rbegin()->first + Coord(ChildT::DIM - 1);
1319 template<
typename ChildT>
1323 bbox.min() = this->getMinIndex();
1324 bbox.max() = this->getMaxIndex();
1331 template<
typename ChildT>
1332 template<
typename OtherChildType>
1337 typedef typename OtherRootT::MapType OtherMapT;
1338 typedef typename OtherRootT::MapIter OtherIterT;
1339 typedef typename OtherRootT::MapCIter OtherCIterT;
1341 if (!hasSameConfiguration(other))
return false;
1344 OtherMapT copyOfOtherTable = other.mTable;
1347 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1348 if (this->isBackgroundTile(thisIter))
continue;
1351 OtherCIterT otherIter = other.findKey(thisIter->first);
1352 if (otherIter == other.mTable.end())
return false;
1355 if (isChild(thisIter)) {
1356 if (OtherRootT::isTile(otherIter))
return false;
1358 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1360 if (OtherRootT::isChild(otherIter))
return false;
1361 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1368 copyOfOtherTable.erase(otherIter->first);
1371 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1378 template<
typename ChildT>
1379 template<
typename OtherChildType>
1383 std::vector<Index> thisDims, otherDims;
1386 return (thisDims == otherDims);
1390 template<
typename ChildT>
1391 template<
typename OtherChildType>
1395 std::vector<Index> thisDims, otherDims;
1398 if (thisDims != otherDims) {
1399 std::ostringstream ostr;
1400 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1401 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1402 ostr <<
" vs. " << otherDims[0];
1403 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1410 template<
typename ChildT>
1411 template<
typename OtherChildType>
1415 typedef typename OtherChildType::ValueType OtherValueType;
1420 template<
typename ChildT>
1421 template<
typename OtherChildType>
1425 typedef typename OtherChildType::ValueType OtherValueType;
1427 std::ostringstream ostr;
1428 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1429 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1438 template<
typename ChildT>
1443 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1444 if (
const ChildT *child = iter->second.child) {
1445 sum += child->memUsage();
1452 template<
typename ChildT>
1456 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1457 delete i->second.child;
1463 template<
typename ChildT>
1467 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1468 if (
const ChildT *child = iter->second.child) {
1469 child->evalActiveBoundingBox(bbox, visitVoxels);
1470 }
else if (isTileOn(iter)) {
1471 bbox.expand(iter->first, ChildT::DIM);
1477 template<
typename ChildT>
1481 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1482 if (isChild(i)) ++sum;
1488 template<
typename ChildT>
1490 RootNode<ChildT>::getTileCount()
const
1493 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1494 if (isTile(i)) ++sum;
1500 template<
typename ChildT>
1502 RootNode<ChildT>::getActiveTileCount()
const
1505 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1506 if (isTileOn(i)) ++sum;
1512 template<
typename ChildT>
1514 RootNode<ChildT>::getInactiveTileCount()
const
1517 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1518 if (isTileOff(i)) ++sum;
1524 template<
typename ChildT>
1529 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1530 if (isChild(i)) sum += getChild(i).leafCount();
1536 template<
typename ChildT>
1541 if (ChildT::LEVEL != 0) {
1542 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1543 if (isChild(i)) sum += getChild(i).nonLeafCount();
1550 template<
typename ChildT>
1555 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1557 sum += getChild(i).onVoxelCount();
1558 }
else if (isTileOn(i)) {
1559 sum += ChildT::NUM_VOXELS;
1566 template<
typename ChildT>
1571 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1573 sum += getChild(i).offVoxelCount();
1574 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1575 sum += ChildT::NUM_VOXELS;
1582 template<
typename ChildT>
1587 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1588 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1594 template<
typename ChildT>
1599 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1600 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1605 template<
typename ChildT>
1610 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1612 sum += getChild(i).onTileCount();
1613 }
else if (isTileOn(i)) {
1623 template<
typename ChildT>
1627 MapCIter iter = this->findCoord(xyz);
1628 if (iter == mTable.end() || isTileOff(iter))
return false;
1629 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1632 template<
typename ChildT>
1636 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1637 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1642 template<
typename ChildT>
1643 template<
typename AccessorT>
1647 MapCIter iter = this->findCoord(xyz);
1648 if (iter == mTable.end() || isTileOff(iter))
return false;
1649 if (isTileOn(iter))
return true;
1650 acc.insert(xyz, &getChild(iter));
1651 return getChild(iter).isValueOnAndCache(xyz, acc);
1655 template<
typename ChildT>
1656 inline const typename ChildT::ValueType&
1659 MapCIter iter = this->findCoord(xyz);
1660 return iter == mTable.end() ? mBackground
1661 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1664 template<
typename ChildT>
1665 template<
typename AccessorT>
1666 inline const typename ChildT::ValueType&
1669 MapCIter iter = this->findCoord(xyz);
1670 if (iter == mTable.end())
return mBackground;
1671 if (isChild(iter)) {
1672 acc.insert(xyz, &getChild(iter));
1673 return getChild(iter).getValueAndCache(xyz, acc);
1675 return getTile(iter).value;
1679 template<
typename ChildT>
1683 MapCIter iter = this->findCoord(xyz);
1684 return iter == mTable.end() ? -1
1685 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1688 template<
typename ChildT>
1689 template<
typename AccessorT>
1693 MapCIter iter = this->findCoord(xyz);
1694 if (iter == mTable.end())
return -1;
1695 if (isTile(iter))
return 0;
1696 acc.insert(xyz, &getChild(iter));
1697 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1701 template<
typename ChildT>
1705 MapIter iter = this->findCoord(xyz);
1706 if (iter != mTable.end() && !isTileOff(iter)) {
1707 if (isTileOn(iter)) {
1708 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1710 getChild(iter).setValueOff(xyz);
1715 template<
typename ChildT>
1719 ChildT* child = NULL;
1720 MapIter iter = this->findCoord(xyz);
1721 if (iter == mTable.end()) {
1723 child =
new ChildT(xyz, mBackground);
1724 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1728 }
else if (isChild(iter)) {
1729 child = &getChild(iter);
1730 }
else if (on != getTile(iter).active) {
1731 child =
new ChildT(xyz, getTile(iter).value, !on);
1732 setChild(iter, *child);
1734 if (child) child->setActiveState(xyz, on);
1737 template<
typename ChildT>
1738 template<
typename AccessorT>
1742 ChildT* child = NULL;
1743 MapIter iter = this->findCoord(xyz);
1744 if (iter == mTable.end()) {
1746 child =
new ChildT(xyz, mBackground);
1747 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1751 }
else if (isChild(iter)) {
1752 child = &getChild(iter);
1753 }
else if (on != getTile(iter).active) {
1754 child =
new ChildT(xyz, getTile(iter).value, !on);
1755 setChild(iter, *child);
1758 acc.insert(xyz, child);
1759 child->setActiveStateAndCache(xyz, on, acc);
1764 template<
typename ChildT>
1768 ChildT* child = NULL;
1769 MapIter iter = this->findCoord(xyz);
1770 if (iter == mTable.end()) {
1772 child =
new ChildT(xyz, mBackground);
1773 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1775 }
else if (isChild(iter)) {
1776 child = &getChild(iter);
1778 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1779 setChild(iter, *child);
1781 if (child) child->setValueOff(xyz, value);
1784 template<
typename ChildT>
1785 template<
typename AccessorT>
1789 ChildT* child = NULL;
1790 MapIter iter = this->findCoord(xyz);
1791 if (iter == mTable.end()) {
1793 child =
new ChildT(xyz, mBackground);
1794 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1796 }
else if (isChild(iter)) {
1797 child = &getChild(iter);
1799 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1800 setChild(iter, *child);
1803 acc.insert(xyz, child);
1804 child->setValueOffAndCache(xyz, value, acc);
1809 template<
typename ChildT>
1813 ChildT* child = NULL;
1814 MapIter iter = this->findCoord(xyz);
1815 if (iter == mTable.end()) {
1816 child =
new ChildT(xyz, mBackground);
1817 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1818 }
else if (isChild(iter)) {
1819 child = &getChild(iter);
1821 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1822 setChild(iter, *child);
1824 if (child) child->setValueOn(xyz, value);
1827 template<
typename ChildT>
1828 template<
typename AccessorT>
1832 ChildT* child = NULL;
1833 MapIter iter = this->findCoord(xyz);
1834 if (iter == mTable.end()) {
1835 child =
new ChildT(xyz, mBackground);
1836 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1837 }
else if (isChild(iter)) {
1838 child = &getChild(iter);
1840 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1841 setChild(iter, *child);
1844 acc.insert(xyz, child);
1845 child->setValueAndCache(xyz, value, acc);
1850 template<
typename ChildT>
1854 ChildT* child = NULL;
1855 MapIter iter = this->findCoord(xyz);
1856 if (iter == mTable.end()) {
1857 child =
new ChildT(xyz, mBackground);
1858 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1859 }
else if (isChild(iter)) {
1860 child = &getChild(iter);
1862 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1863 setChild(iter, *child);
1865 if (child) child->setValueOnly(xyz, value);
1868 template<
typename ChildT>
1869 template<
typename AccessorT>
1873 ChildT* child = NULL;
1874 MapIter iter = this->findCoord(xyz);
1875 if (iter == mTable.end()) {
1876 child =
new ChildT(xyz, mBackground);
1877 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1878 }
else if (isChild(iter)) {
1879 child = &getChild(iter);
1881 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1882 setChild(iter, *child);
1885 acc.insert(xyz, child);
1886 child->setValueOnlyAndCache(xyz, value, acc);
1891 template<
typename ChildT>
1892 template<
typename ModifyOp>
1896 ChildT* child = NULL;
1897 MapIter iter = this->findCoord(xyz);
1898 if (iter == mTable.end()) {
1899 child =
new ChildT(xyz, mBackground);
1900 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1901 }
else if (isChild(iter)) {
1902 child = &getChild(iter);
1906 bool createChild = isTileOff(iter);
1910 const ValueType& tileVal = getTile(iter).value;
1911 ValueType modifiedVal = tileVal;
1916 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1917 setChild(iter, *child);
1920 if (child) child->modifyValue(xyz, op);
1923 template<
typename ChildT>
1924 template<
typename ModifyOp,
typename AccessorT>
1928 ChildT* child = NULL;
1929 MapIter iter = this->findCoord(xyz);
1930 if (iter == mTable.end()) {
1931 child =
new ChildT(xyz, mBackground);
1932 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1933 }
else if (isChild(iter)) {
1934 child = &getChild(iter);
1938 bool createChild = isTileOff(iter);
1942 const ValueType& tileVal = getTile(iter).value;
1943 ValueType modifiedVal = tileVal;
1948 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1949 setChild(iter, *child);
1953 acc.insert(xyz, child);
1954 child->modifyValueAndCache(xyz, op, acc);
1959 template<
typename ChildT>
1960 template<
typename ModifyOp>
1964 ChildT* child = NULL;
1965 MapIter iter = this->findCoord(xyz);
1966 if (iter == mTable.end()) {
1967 child =
new ChildT(xyz, mBackground);
1968 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1969 }
else if (isChild(iter)) {
1970 child = &getChild(iter);
1972 const Tile& tile = getTile(iter);
1973 bool modifiedState = tile.active;
1974 ValueType modifiedVal = tile.value;
1975 op(modifiedVal, modifiedState);
1979 child =
new ChildT(xyz, tile.value, tile.active);
1980 setChild(iter, *child);
1983 if (child) child->modifyValueAndActiveState(xyz, op);
1986 template<
typename ChildT>
1987 template<
typename ModifyOp,
typename AccessorT>
1990 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1992 ChildT* child = NULL;
1993 MapIter iter = this->findCoord(xyz);
1994 if (iter == mTable.end()) {
1995 child =
new ChildT(xyz, mBackground);
1996 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1997 }
else if (isChild(iter)) {
1998 child = &getChild(iter);
2000 const Tile& tile = getTile(iter);
2001 bool modifiedState = tile.active;
2002 ValueType modifiedVal = tile.value;
2003 op(modifiedVal, modifiedState);
2007 child =
new ChildT(xyz, tile.value, tile.active);
2008 setChild(iter, *child);
2012 acc.insert(xyz, child);
2013 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2018 template<
typename ChildT>
2022 MapCIter iter = this->findCoord(xyz);
2023 if (iter == mTable.end()) {
2024 value = mBackground;
2026 }
else if (isChild(iter)) {
2027 return getChild(iter).probeValue(xyz, value);
2029 value = getTile(iter).value;
2030 return isTileOn(iter);
2033 template<
typename ChildT>
2034 template<
typename AccessorT>
2038 MapCIter iter = this->findCoord(xyz);
2039 if (iter == mTable.end()) {
2040 value = mBackground;
2042 }
else if (isChild(iter)) {
2043 acc.insert(xyz, &getChild(iter));
2044 return getChild(iter).probeValueAndCache(xyz, value, acc);
2046 value = getTile(iter).value;
2047 return isTileOn(iter);
2054 template<
typename ChildT>
2058 if (bbox.empty())
return;
2061 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2063 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2065 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2069 Coord tileMin = coordToKey(xyz);
2070 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2072 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
2076 ChildT* child = NULL;
2077 MapIter iter = this->findKey(tileMin);
2078 if (iter == mTable.end()) {
2081 child =
new ChildT(xyz, mBackground);
2082 mTable[tileMin] = NodeStruct(*child);
2083 }
else if (isTile(iter)) {
2086 const Tile& tile = getTile(iter);
2087 child =
new ChildT(xyz, tile.value, tile.active);
2088 mTable[tileMin] = NodeStruct(*child);
2089 }
else if (isChild(iter)) {
2090 child = &getChild(iter);
2101 MapIter iter = this->findOrAddCoord(tileMin);
2102 setTile(iter, Tile(value, active));
2109 template<
typename ChildT>
2110 template<
typename DenseT>
2114 typedef typename DenseT::ValueType DenseValueType;
2116 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2117 const Coord&
min = dense.bbox().min();
2119 for (Coord xyz = bbox.min(); xyz[0] <= bbox.max()[0]; xyz[0] = nodeBBox.max()[0] + 1) {
2120 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] = nodeBBox.max()[1] + 1) {
2121 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] = nodeBBox.max()[2] + 1) {
2124 nodeBBox = CoordBBox::createCube(coordToKey(xyz), ChildT::DIM);
2129 MapCIter iter = this->findKey(nodeBBox.min());
2130 if (iter != mTable.end() && isChild(iter)) {
2131 getChild(iter).copyToDense(sub, dense);
2133 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2134 sub.translate(-min);
2135 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2136 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2137 DenseValueType* a1 = a0 + x*xStride;
2138 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2139 DenseValueType* a2 = a1 + y*yStride;
2140 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
2141 *a2 = DenseValueType(value);
2154 template<
typename ChildT>
2159 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(ValueType));
2162 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueType));
2166 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
2167 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
2168 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
2170 if (numTiles == 0 && numChildren == 0)
return false;
2173 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2174 if (isChild(i))
continue;
2175 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2176 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(ValueType));
2177 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
2180 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2181 if (isTile(i))
continue;
2182 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2183 getChild(i).writeTopology(os, toHalf);
2190 template<
typename ChildT>
2202 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2204 is.read(reinterpret_cast<char*>(&inside),
sizeof(ValueType));
2209 Coord rangeMin, rangeMax;
2210 is.read(reinterpret_cast<char*>(rangeMin.asPointer()), 3 *
sizeof(
Int32));
2211 is.read(reinterpret_cast<char*>(rangeMax.asPointer()), 3 *
sizeof(
Int32));
2214 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2216 for (
int i = 0; i < 3; ++i) {
2217 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2218 rangeMin[i] = offset[i] << ChildT::TOTAL;
2220 tableSize += log2Dim[i];
2221 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2223 log2Dim[3] = log2Dim[1] + log2Dim[2];
2224 tableSize = 1U << tableSize;
2232 for (
Index i = 0; i < tableSize; ++i) {
2236 origin[0] = (n >> log2Dim[3]) + offset[0];
2237 n &= (1U << log2Dim[3]) - 1;
2238 origin[1] = (n >> log2Dim[2]) + offset[1];
2239 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2240 origin <<= ChildT::TOTAL;
2242 if (childMask.isOn(i)) {
2244 #ifdef OPENVDB_2_ABI_COMPATIBLE
2245 ChildT* child =
new ChildT(origin, mBackground);
2247 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2249 child->readTopology(is);
2250 mTable[origin] = NodeStruct(*child);
2255 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2257 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2266 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2269 Index numTiles = 0, numChildren = 0;
2270 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2271 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2273 if (numTiles == 0 && numChildren == 0)
return false;
2280 for (
Index n = 0; n < numTiles; ++n) {
2281 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2282 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2283 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2284 mTable[Coord(vec)] = NodeStruct(Tile(value, active));
2288 for (
Index n = 0; n < numChildren; ++n) {
2289 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2291 #ifdef OPENVDB_2_ABI_COMPATIBLE
2292 ChildT* child =
new ChildT(origin, mBackground);
2294 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2296 child->readTopology(is, fromHalf);
2297 mTable[Coord(vec)] = NodeStruct(*child);
2304 template<
typename ChildT>
2308 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2309 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2314 template<
typename ChildT>
2318 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2319 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2324 template<
typename ChildT>
2328 const Tile bgTile(mBackground,
false);
2330 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2336 ChildT& child = getChild(i);
2337 child.readBuffers(is, clipBBox, fromHalf);
2341 this->
clip(clipBBox);
2348 template<
typename ChildT>
2352 const Tile bgTile(mBackground,
false);
2356 MapType copyOfTable(mTable);
2357 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2358 const Coord& xyz = i->first;
2359 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
2360 if (!clipBBox.hasOverlap(tileBBox)) {
2362 setTile(this->findCoord(xyz), bgTile);
2364 }
else if (!clipBBox.isInside(tileBBox)) {
2368 getChild(i).clip(clipBBox, mBackground);
2372 tileBBox.intersect(clipBBox);
2373 const Tile& origTile = getTile(i);
2374 setTile(this->findCoord(xyz), bgTile);
2375 this->fill(tileBBox, origTile.value, origTile.active);
2388 template<
typename ChildT>
2393 ValueType value = zeroVal<ValueType>();
2394 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2395 if (this->isTile(i))
continue;
2396 this->getChild(i).prune(tolerance);
2397 if (this->getChild(i).isConstant(value, state, tolerance)) {
2398 this->setTile(i, Tile(value, state));
2401 this->eraseBackgroundTiles();
2408 template<
typename ChildT>
2409 template<
typename NodeT>
2413 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2414 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2416 MapIter iter = this->findCoord(xyz);
2417 if (iter == mTable.end() || isTile(iter))
return NULL;
2418 return (boost::is_same<NodeT, ChildT>::value)
2419 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2420 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2428 template<
typename ChildT>
2432 if (leaf == NULL)
return;
2433 ChildT* child = NULL;
2434 const Coord& xyz = leaf->origin();
2435 MapIter iter = this->findCoord(xyz);
2436 if (iter == mTable.end()) {
2437 if (ChildT::LEVEL>0) {
2438 child =
new ChildT(xyz, mBackground,
false);
2440 child =
reinterpret_cast<ChildT*
>(leaf);
2442 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2443 }
else if (isChild(iter)) {
2444 if (ChildT::LEVEL>0) {
2445 child = &getChild(iter);
2447 child =
reinterpret_cast<ChildT*
>(leaf);
2448 setChild(iter, *child);
2451 if (ChildT::LEVEL>0) {
2452 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2454 child =
reinterpret_cast<ChildT*
>(leaf);
2456 setChild(iter, *child);
2458 child->addLeaf(leaf);
2462 template<
typename ChildT>
2463 template<
typename AccessorT>
2467 if (leaf == NULL)
return;
2468 ChildT* child = NULL;
2469 const Coord& xyz = leaf->origin();
2470 MapIter iter = this->findCoord(xyz);
2471 if (iter == mTable.end()) {
2472 if (ChildT::LEVEL>0) {
2473 child =
new ChildT(xyz, mBackground,
false);
2475 child =
reinterpret_cast<ChildT*
>(leaf);
2477 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2478 }
else if (isChild(iter)) {
2479 if (ChildT::LEVEL>0) {
2480 child = &getChild(iter);
2482 child =
reinterpret_cast<ChildT*
>(leaf);
2483 setChild(iter, *child);
2486 if (ChildT::LEVEL>0) {
2487 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2489 child =
reinterpret_cast<ChildT*
>(leaf);
2491 setChild(iter, *child);
2493 acc.insert(xyz, child);
2494 child->addLeafAndCache(leaf, acc);
2497 template<
typename ChildT>
2501 MapIter iter = this->findCoord(xyz);
2502 if (iter == mTable.end()) {
2503 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2505 setTile(iter, Tile(value, state));
2509 template<
typename ChildT>
2512 const ValueType& value,
bool state)
2514 if (LEVEL >= level) {
2515 MapIter iter = this->findCoord(xyz);
2516 if (iter == mTable.end()) {
2517 if (LEVEL > level) {
2518 ChildT* child =
new ChildT(xyz, mBackground,
false);
2519 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2520 child->addTile(level, xyz, value, state);
2522 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2524 }
else if (isChild(iter)) {
2525 if (LEVEL > level) {
2526 getChild(iter).addTile(level, xyz, value, state);
2528 setTile(iter, Tile(value, state));
2531 if (LEVEL > level) {
2532 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2533 setChild(iter, *child);
2534 child->addTile(level, xyz, value, state);
2536 setTile(iter, Tile(value, state));
2543 template<
typename ChildT>
2544 template<
typename AccessorT>
2547 bool state, AccessorT& acc)
2549 if (LEVEL >= level) {
2550 MapIter iter = this->findCoord(xyz);
2551 if (iter == mTable.end()) {
2552 if (LEVEL > level) {
2553 ChildT* child =
new ChildT(xyz, mBackground,
false);
2554 acc.insert(xyz, child);
2555 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2556 child->addTileAndCache(level, xyz, value, state, acc);
2558 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2560 }
else if (isChild(iter)) {
2561 if (LEVEL > level) {
2562 ChildT* child = &getChild(iter);
2563 acc.insert(xyz, child);
2564 child->addTileAndCache(level, xyz, value, state, acc);
2566 setTile(iter, Tile(value, state));
2569 if (LEVEL > level) {
2570 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2571 acc.insert(xyz, child);
2572 setChild(iter, *child);
2573 child->addTileAndCache(level, xyz, value, state, acc);
2575 setTile(iter, Tile(value, state));
2585 template<
typename ChildT>
2586 inline typename ChildT::LeafNodeType*
2589 ChildT* child = NULL;
2590 MapIter iter = this->findCoord(xyz);
2591 if (iter == mTable.end()) {
2592 child =
new ChildT(xyz, mBackground,
false);
2593 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2594 }
else if (isChild(iter)) {
2595 child = &getChild(iter);
2597 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2598 setChild(iter, *child);
2600 return child->touchLeaf(xyz);
2604 template<
typename ChildT>
2605 template<
typename AccessorT>
2606 inline typename ChildT::LeafNodeType*
2609 ChildT* child = NULL;
2610 MapIter iter = this->findCoord(xyz);
2611 if (iter == mTable.end()) {
2612 child =
new ChildT(xyz, mBackground,
false);
2613 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2614 }
else if (isChild(iter)) {
2615 child = &getChild(iter);
2617 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2618 setChild(iter, *child);
2620 acc.insert(xyz, child);
2621 return child->touchLeafAndCache(xyz, acc);
2628 template<
typename ChildT>
2629 template<
typename NodeT>
2633 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2634 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2636 MapIter iter = this->findCoord(xyz);
2637 if (iter == mTable.end() || isTile(iter))
return NULL;
2638 ChildT* child = &getChild(iter);
2639 return (boost::is_same<NodeT, ChildT>::value)
2640 ?
reinterpret_cast<NodeT*
>(child)
2641 : child->template probeNode<NodeT>(xyz);
2646 template<
typename ChildT>
2647 template<
typename NodeT>
2651 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2652 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2654 MapCIter iter = this->findCoord(xyz);
2655 if (iter == mTable.end() || isTile(iter))
return NULL;
2656 const ChildT* child = &getChild(iter);
2657 return (boost::is_same<NodeT, ChildT>::value)
2658 ?
reinterpret_cast<const NodeT*
>(child)
2659 : child->template probeConstNode<NodeT>(xyz);
2664 template<
typename ChildT>
2665 inline typename ChildT::LeafNodeType*
2668 return this->
template probeNode<LeafNodeType>(xyz);
2672 template<
typename ChildT>
2673 inline const typename ChildT::LeafNodeType*
2676 return this->
template probeConstNode<LeafNodeType>(xyz);
2680 template<
typename ChildT>
2681 template<
typename AccessorT>
2682 inline typename ChildT::LeafNodeType*
2685 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2689 template<
typename ChildT>
2690 template<
typename AccessorT>
2691 inline const typename ChildT::LeafNodeType*
2694 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2698 template<
typename ChildT>
2699 template<
typename AccessorT>
2700 inline const typename ChildT::LeafNodeType*
2703 return this->probeConstLeafAndCache(xyz, acc);
2707 template<
typename ChildT>
2708 template<
typename NodeT,
typename AccessorT>
2712 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2713 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2715 MapIter iter = this->findCoord(xyz);
2716 if (iter == mTable.end() || isTile(iter))
return NULL;
2717 ChildT* child = &getChild(iter);
2718 acc.insert(xyz, child);
2719 return (boost::is_same<NodeT, ChildT>::value)
2720 ?
reinterpret_cast<NodeT*
>(child)
2721 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2726 template<
typename ChildT>
2727 template<
typename NodeT,
typename AccessorT>
2731 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2732 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2734 MapCIter iter = this->findCoord(xyz);
2735 if (iter == mTable.end() || isTile(iter))
return NULL;
2736 const ChildT* child = &getChild(iter);
2737 acc.insert(xyz, child);
2738 return (boost::is_same<NodeT, ChildT>::value)
2739 ?
reinterpret_cast<const NodeT*
>(child)
2740 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2747 template<
typename ChildT>
2748 template<
typename ArrayT>
2752 typedef typename ArrayT::value_type NodePtr;
2753 BOOST_STATIC_ASSERT(boost::is_pointer<NodePtr>::value);
2754 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2755 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2756 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2757 BOOST_STATIC_ASSERT(result::value);
2758 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2759 const ChildT, ChildT>::type ArrayChildT;
2761 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2762 if (ChildT* child = iter->second.child) {
2764 if (boost::is_same<NodePtr, ArrayChildT*>::value) {
2765 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2767 child->getNodes(array);
2774 template<
typename ChildT>
2775 template<
typename ArrayT>
2779 typedef typename ArrayT::value_type NodePtr;
2780 BOOST_STATIC_ASSERT(boost::is_pointer<NodePtr>::value);
2781 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2782 BOOST_STATIC_ASSERT(boost::is_const<NodeType>::value);
2783 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2784 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2785 BOOST_STATIC_ASSERT(result::value);
2787 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2788 if (
const ChildNodeType *child = iter->second.child) {
2790 if (boost::is_same<NodePtr, const ChildT*>::value) {
2791 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2793 child->getNodes(array);
2802 template<
typename ChildT>
2803 template<
typename ArrayT>
2807 typedef typename ArrayT::value_type NodePtr;
2808 BOOST_STATIC_ASSERT(boost::is_pointer<NodePtr>::value);
2809 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2810 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2811 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2812 BOOST_STATIC_ASSERT(result::value);
2813 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2814 const ChildT, ChildT>::type ArrayChildT;
2816 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2817 if (ChildT* child = iter->second.child) {
2819 if (boost::is_same<NodePtr, ArrayChildT*>::value) {
2820 array.push_back(reinterpret_cast<NodePtr>(&stealChild(iter, Tile(value, state))));
2822 child->stealNodes(array, value, state);
2833 template<
typename ChildT>
2837 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2838 if (this->isTileOff(i))
continue;
2839 ChildT* child = i->second.child;
2841 child =
new ChildT(i->first, this->getTile(i).value,
true);
2842 i->second.child = child;
2844 child->voxelizeActiveTiles();
2852 template<
typename ChildT>
2853 template<MergePolicy Policy>
2863 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2864 MapIter j = mTable.find(i->first);
2865 if (other.isChild(i)) {
2866 if (j == mTable.end()) {
2867 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2868 child.resetBackground(other.mBackground, mBackground);
2869 mTable[i->first] = NodeStruct(child);
2870 }
else if (isTile(j)) {
2872 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2873 child.resetBackground(other.mBackground, mBackground);
2877 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
2878 other.mBackground, mBackground);
2880 }
else if (other.isTileOn(i)) {
2881 if (j == mTable.end()) {
2882 mTable[i->first] = i->second;
2883 }
else if (!isTileOn(j)) {
2885 setTile(j, Tile(other.getTile(i).value,
true));
2892 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2893 MapIter j = mTable.find(i->first);
2894 if (other.isChild(i)) {
2895 if (j == mTable.end()) {
2896 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2897 child.resetBackground(other.mBackground, mBackground);
2898 mTable[i->first] = NodeStruct(child);
2899 }
else if (isTile(j)) {
2900 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2901 child.resetBackground(other.mBackground, mBackground);
2904 getChild(j).template merge<MERGE_NODES>(
2905 getChild(i), other.mBackground, mBackground);
2912 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2913 MapIter j = mTable.find(i->first);
2914 if (other.isChild(i)) {
2915 if (j == mTable.end()) {
2917 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2918 child.resetBackground(other.mBackground, mBackground);
2919 mTable[i->first] = NodeStruct(child);
2920 }
else if (isTile(j)) {
2922 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2923 child.resetBackground(other.mBackground, mBackground);
2924 const Tile tile = getTile(j);
2928 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2929 tile.value, tile.active);
2933 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
2934 other.mBackground, mBackground);
2936 }
else if (other.isTileOn(i)) {
2937 if (j == mTable.end()) {
2939 mTable[i->first] = i->second;
2940 }
else if (isTileOff(j)) {
2942 setTile(j, Tile(other.getTile(i).value,
true));
2943 }
else if (isChild(j)) {
2945 const Tile& tile = getTile(i);
2946 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2947 tile.value, tile.active);
2964 template<
typename ChildT>
2965 template<
typename OtherChildType>
2970 typedef typename OtherRootT::MapCIter OtherCIterT;
2972 enforceSameConfiguration(other);
2974 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2975 MapIter j = mTable.find(i->first);
2976 if (other.isChild(i)) {
2977 if (j == mTable.end()) {
2978 mTable[i->first] = NodeStruct(
2979 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
2980 }
else if (this->isChild(j)) {
2981 this->getChild(j).topologyUnion(other.getChild(i));
2983 ChildT* child =
new ChildT(
2984 other.getChild(i), this->getTile(j).value,
TopologyCopy());
2985 if (this->isTileOn(j)) child->setValuesOn();
2986 this->setChild(j, *child);
2988 }
else if (other.isTileOn(i)) {
2989 if (j == mTable.end()) {
2990 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
2991 }
else if (this->isChild(j)) {
2992 this->getChild(j).setValuesOn();
2993 }
else if (this->isTileOff(j)) {
2994 this->setTile(j, Tile(this->getTile(j).value,
true));
3000 template<
typename ChildT>
3001 template<
typename OtherChildType>
3006 typedef typename OtherRootT::MapCIter OtherCIterT;
3008 enforceSameConfiguration(other);
3010 std::set<Coord> tmp;
3011 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3012 OtherCIterT j = other.mTable.find(i->first);
3013 if (this->isChild(i)) {
3014 if (j == other.mTable.end() || other.isTileOff(j)) {
3015 tmp.insert(i->first);
3016 }
else if (other.isChild(j)) {
3017 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3019 }
else if (this->isTileOn(i)) {
3020 if (j == other.mTable.end() || other.isTileOff(j)) {
3021 this->setTile(i, Tile(this->getTile(i).value,
false));
3022 }
else if (other.isChild(j)) {
3024 new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
3025 this->setChild(i, *child);
3029 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3030 MapIter it = this->findCoord(*i);
3031 setTile(it, Tile());
3036 template<
typename ChildT>
3037 template<
typename OtherChildType>
3042 typedef typename OtherRootT::MapCIter OtherCIterT;
3044 enforceSameConfiguration(other);
3046 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3047 MapIter j = mTable.find(i->first);
3048 if (other.isChild(i)) {
3049 if (j == mTable.end() || this->isTileOff(j)) {
3051 }
else if (this->isChild(j)) {
3052 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3053 }
else if (this->isTileOn(j)) {
3055 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
3056 child->topologyDifference(other.getChild(i), mBackground);
3057 this->setChild(j, *child);
3059 }
else if (other.isTileOn(i)) {
3060 if (j == mTable.end() || this->isTileOff(j)) {
3062 }
else if (this->isChild(j)) {
3065 }
else if (this->isTileOn(j)) {
3066 this->setTile(j, Tile(this->getTile(j).value,
false));
3075 template<
typename ChildT>
3076 template<
typename CombineOp>
3083 this->insertKeys(keys);
3084 other.insertKeys(keys);
3086 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3087 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3088 if (isTile(iter) && isTile(otherIter)) {
3091 op(args.
setARef(getTile(iter).value)
3092 .setAIsActive(isTileOn(iter))
3093 .setBRef(getTile(otherIter).value)
3094 .setBIsActive(isTileOn(otherIter)));
3097 }
else if (isChild(iter) && isTile(otherIter)) {
3099 ChildT& child = getChild(iter);
3100 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3102 }
else if (isTile(iter) && isChild(otherIter)) {
3107 ChildT& child = getChild(otherIter);
3108 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3111 setChild(iter, stealChild(otherIter, Tile()));
3115 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3116 child.combine(otherChild, op);
3118 if (prune && isChild(iter)) getChild(iter).prune();
3122 op(args.
setARef(mBackground).setBRef(other.mBackground));
3123 mBackground = args.
result();
3135 template<
typename CombineOp,
typename RootT,
typename OtherRootT,
bool Compatible = false>
3138 static inline void combine2(RootT&
self,
const RootT&,
const OtherRootT& other1,
3143 self.enforceSameConfiguration(other1);
3144 self.enforceCompatibleValueTypes(other1);
3146 std::ostringstream ostr;
3147 ostr <<
"cannot combine a " <<
typeid(OtherRootT).name()
3148 <<
" into a " <<
typeid(RootT).name();
3154 template<
typename CombineOp,
typename RootT,
typename OtherRootT>
3157 static inline void combine2(RootT&
self,
const RootT& other0,
const OtherRootT& other1,
3158 CombineOp& op,
bool prune)
3160 self.doCombine2(other0, other1, op, prune);
3165 template<
typename ChildT>
3166 template<
typename CombineOp,
typename OtherRootNode>
3169 CombineOp& op,
bool prune)
3171 typedef typename OtherRootNode::ValueType OtherValueType;
3175 *
this, other0, other1, op, prune);
3179 template<
typename ChildT>
3180 template<
typename CombineOp,
typename OtherRootNode>
3183 CombineOp& op,
bool prune)
3185 enforceSameConfiguration(other1);
3187 typedef typename OtherRootNode::ValueType OtherValueT;
3188 typedef typename OtherRootNode::Tile OtherTileT;
3189 typedef typename OtherRootNode::NodeStruct OtherNodeStructT;
3190 typedef typename OtherRootNode::MapCIter OtherMapCIterT;
3195 other0.insertKeys(keys);
3196 other1.insertKeys(keys);
3198 const NodeStruct bg0(Tile(other0.mBackground,
false));
3199 const OtherNodeStructT bg1(OtherTileT(other1.mBackground,
false));
3201 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3202 MapIter thisIter = this->findOrAddCoord(*i);
3203 MapCIter iter0 = other0.findKey(*i);
3204 OtherMapCIterT iter1 = other1.findKey(*i);
3205 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3206 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3207 if (ns0.isTile() && ns1.isTile()) {
3210 op(args.
setARef(ns0.tile.value)
3211 .setAIsActive(ns0.isTileOn())
3212 .setBRef(ns1.tile.value)
3213 .setBIsActive(ns1.isTileOn()));
3216 if (!isChild(thisIter)) {
3218 const Coord& childOrigin =
3219 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3220 setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
3222 ChildT& child = getChild(thisIter);
3227 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3228 }
else if (ns1.isTile()) {
3231 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3235 child.combine2(*ns0.child, *ns1.child, op);
3238 if (prune && isChild(thisIter)) getChild(thisIter).prune();
3242 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
3243 mBackground = args.
result();
3250 template<
typename ChildT>
3251 template<
typename BBoxOp>
3255 const bool descent = op.template descent<LEVEL>();
3256 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3257 if (this->isTileOff(i))
continue;
3258 if (this->isChild(i) && descent) {
3259 this->getChild(i).visitActiveBBox(op);
3262 op.operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
3264 op.template operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
3271 template<
typename ChildT>
3272 template<
typename VisitorOp>
3276 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
3280 template<
typename ChildT>
3281 template<
typename VisitorOp>
3285 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
3289 template<
typename ChildT>
3290 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
3294 typename RootNodeT::ValueType val;
3295 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
3296 if (op(iter))
continue;
3297 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3307 template<
typename ChildT>
3308 template<
typename OtherRootNodeType,
typename VisitorOp>
3312 doVisit2<
RootNode, OtherRootNodeType, VisitorOp, ChildAllIter,
3313 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
3317 template<
typename ChildT>
3318 template<
typename OtherRootNodeType,
typename VisitorOp>
3322 doVisit2<
const RootNode, OtherRootNodeType, VisitorOp, ChildAllCIter,
3323 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
3327 template<
typename ChildT>
3330 typename OtherRootNodeT,
3332 typename ChildAllIterT,
3333 typename OtherChildAllIterT>
3337 enforceSameConfiguration(other);
3339 typename RootNodeT::ValueType val;
3340 typename OtherRootNodeT::ValueType otherVal;
3345 RootNodeT copyOfSelf(
self.mBackground);
3346 copyOfSelf.mTable =
self.mTable;
3347 OtherRootNodeT copyOfOther(other.mBackground);
3348 copyOfOther.mTable = other.mTable;
3352 self.insertKeys(keys);
3353 other.insertKeys(keys);
3354 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3355 copyOfSelf.findOrAddCoord(*i);
3356 copyOfOther.findOrAddCoord(*i);
3359 ChildAllIterT iter = copyOfSelf.beginChildAll();
3360 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3362 for ( ; iter && otherIter; ++iter, ++otherIter)
3364 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3366 typename ChildAllIterT::ChildNodeType* child =
3367 (skipBranch & 1U) ? NULL : iter.probeChild(val);
3368 typename OtherChildAllIterT::ChildNodeType* otherChild =
3369 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
3371 if (child != NULL && otherChild != NULL) {
3372 child->visit2Node(*otherChild, op);
3373 }
else if (child != NULL) {
3374 child->visit2(otherIter, op);
3375 }
else if (otherChild != NULL) {
3376 otherChild->visit2(iter, op,
true);
3381 copyOfSelf.eraseBackgroundTiles();
3382 copyOfOther.eraseBackgroundTiles();
3386 self.resetTable(copyOfSelf.mTable);
3387 other.resetTable(copyOfOther.mTable);
3394 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
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...
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:2430
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
Definition: NodeMasks.h:1042
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1871
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1657
Index32 Index
Definition: Types.h:58
ChildOffCIter beginChildOff() const
Definition: RootNode.h:412
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:1334
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1625
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
void load(std::istream &is)
Definition: NodeMasks.h:1349
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1110
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3310
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2350
Index getDepth() const
Definition: RootNode.h:490
Index getHeight() const
Definition: RootNode.h:489
RootNode(const RootNode &other)
Definition: RootNode.h:110
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:151
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1244
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:418
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:420
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:450
Definition: RootNode.h:70
boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:999
ChildAllIter beginChildAll()
Definition: RootNode.h:416
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...
ValueOffCIter beginValueOff() const
Definition: RootNode.h:422
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2750
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1232
NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:85
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:403
bool resultIsActive() const
Definition: Types.h:353
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2316
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1297
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:396
uint32_t Index32
Definition: Types.h:56
Definition: version.h:100
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1830
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:458
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:1811
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:419
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2835
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:2499
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2192
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
ChildAllCIter beginChildAll() const
Definition: RootNode.h:413
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:2390
NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:992
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1148
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:2112
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:2674
Definition: RootNode.h:69
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:439
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:395
bool isOn(Index32 i) const
Definition: NodeMasks.h:1308
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1691
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:393
boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:993
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:3039
ChildOnIter beginChildOn()
Definition: RootNode.h:414
ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:79
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:511
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:1681
Index getWidth() const
Definition: RootNode.h:488
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2020
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1210
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:397
Definition: RootNode.h:75
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:408
ChildOffIter beginChildOff()
Definition: RootNode.h:415
ChildOnCIter beginChildOn() const
Definition: RootNode.h:411
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3168
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:2710
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:2411
~RootNode()
Definition: RootNode.h:158
#define OPENVDB_VERSION_NAME
Definition: version.h:43
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1381
Index32 leafCount() const
Definition: RootNode.h:1526
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:398
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:807
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given box to a constant value, if necessary subdividing tiles that intersect ...
Definition: RootNode.h:2056
ValueOnIter beginValueOn()
Definition: RootNode.h:424
SameConfiguration::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:99
ValueAllIter beginValueAll()
Definition: RootNode.h:426
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3157
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:2465
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1703
Index64 offVoxelCount() const
Definition: RootNode.h:1568
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3078
Definition: RootNode.h:71
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:342
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:404
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:474
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:2805
Index64 onVoxelCount() const
Definition: RootNode.h:1552
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1306
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1962
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:456
Definition: Exceptions.h:39
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3138
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1740
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:3003
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1926
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:1465
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:2666
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1787
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:409
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1026
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:401
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:2631
void clear()
Definition: RootNode.h:471
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:1852
ValueAllCIter beginValueAll() const
Definition: RootNode.h:423
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:2587
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:119
NodeChain::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:68
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:2649
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:410
Index64 onTileCount() const
Definition: RootNode.h:1607
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:486
const AValueType & result() const
Get the output value.
Definition: Types.h:334
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:394
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1584
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:1717
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1596
bool hasActiveTiles() const
Definition: RootNode.h:1634
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:304
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2306
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1283
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:2967
int32_t Int32
Definition: Types.h:60
ValueOffIter beginValueOff()
Definition: RootNode.h:425
uint64_t Index64
Definition: Types.h:57
static Index getLevel()
Definition: RootNode.h:481
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2036
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1645
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:400
ChildType ChildNodeType
Definition: RootNode.h:78
CanConvertType::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:180
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:405
RootNode< typename ChildType::template ValueConverter< OtherValueType >::Type > Type
Definition: RootNode.h:92
ValueOnCIter beginValueOn() const
Definition: RootNode.h:421
Index32 nonLeafCount() const
Definition: RootNode.h:1538
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void visit(VisitorOp &)
Definition: RootNode.h:3274
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1321
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1092
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:2729
static Index getChildDim()
Definition: RootNode.h:483
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:1183
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1413
Definition: Exceptions.h:87
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:2546
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1440
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1313
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:3253
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:402
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2156
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:1894
ValueConverter::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:91
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2855
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1989