35 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
36 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
41 #include <boost/type_traits/remove_const.hpp>
42 #include <openvdb/Exceptions.h>
43 #include <openvdb/Types.h>
44 #include <openvdb/io/Compression.h>
45 #include <openvdb/math/Math.h>
46 #include <openvdb/math/BBox.h>
47 #include <openvdb/util/NodeMasks.h>
48 #include <openvdb/version.h>
57 template<
typename ChildType>
65 static const Index LEVEL = 1 + ChildType::LEVEL;
69 template<
typename OtherValueType>
94 template<
typename OtherChildType>
96 const ValueType& background,
const ValueType& foreground,
114 template<
typename OtherChildType>
124 Tile(): value(
zeroVal<ValueType>()), active(false) {}
125 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
135 NodeStruct(): child(NULL) {}
136 NodeStruct(ChildType& c): child(&c) {}
137 NodeStruct(
const Tile& t): child(NULL), tile(t) {}
140 bool isChild()
const {
return child != NULL; }
141 bool isTile()
const {
return child == NULL; }
142 bool isTileOff()
const {
return isTile() && !tile.active; }
143 bool isTileOn()
const {
return isTile() && tile.active; }
145 void set(ChildType& c) {
delete child; child = &c; }
146 void set(
const Tile& t) {
delete child; child = NULL; tile = t; }
147 ChildType& steal(
const Tile& t) { ChildType* c = child; child = NULL; tile = t;
return *c; }
150 typedef std::map<Coord, NodeStruct> MapType;
151 typedef typename MapType::iterator MapIter;
152 typedef typename MapType::const_iterator MapCIter;
154 typedef std::set<Coord> CoordSet;
155 typedef typename CoordSet::iterator CoordSetIter;
156 typedef typename CoordSet::const_iterator CoordSetCIter;
158 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
159 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
160 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
161 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
162 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
163 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
164 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
165 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
167 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
168 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
169 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
170 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
171 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
172 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
173 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
174 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
177 static inline bool test(
const MapIter&) {
return true; }
178 static inline bool test(
const MapCIter&) {
return true; }
181 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
182 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
184 struct ValueOffPred {
185 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
186 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
188 struct ValueAllPred {
189 static inline bool test(
const MapIter& i) {
return isTile(i); }
190 static inline bool test(
const MapCIter& i) {
return isTile(i); }
193 static inline bool test(
const MapIter& i) {
return isChild(i); }
194 static inline bool test(
const MapCIter& i) {
return isChild(i); }
196 struct ChildOffPred {
197 static inline bool test(
const MapIter& i) {
return isTile(i); }
198 static inline bool test(
const MapCIter& i) {
return isTile(i); }
201 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
205 typedef _RootNodeT RootNodeT;
206 typedef _MapIterT MapIterT;
210 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
212 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
214 RootNodeT* getParentNode()
const {
return mParentNode; }
216 RootNodeT& parent()
const
218 if (!mParentNode)
OPENVDB_THROW(ValueError,
"iterator references a null parent node");
222 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
223 operator bool()
const {
return this->test(); }
225 void increment() { ++mIter; this->skip(); }
226 bool next() { this->increment();
return this->test(); }
227 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
233 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
236 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
237 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
238 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
239 void setValueOff()
const { mIter->second.tile.active =
false; }
242 Coord getCoord()
const {
return mIter->first; }
244 void getCoord(
Coord& xyz)
const { xyz = this->getCoord(); }
247 BaseIter(): mParentNode(NULL) {}
248 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
250 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
252 RootNodeT* mParentNode;
256 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
257 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
260 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
261 typedef RootNodeT NodeType;
262 typedef NodeType ValueType;
263 typedef ChildNodeT ChildNodeType;
264 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
265 typedef typename boost::remove_const<ValueType>::type NonConstValueType;
266 typedef typename boost::remove_const<ChildNodeType>::type NonConstChildNodeType;
270 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
272 ChildIter& operator++() { BaseT::increment();
return *
this; }
274 ChildNodeT& getValue()
const {
return getChild(mIter); }
275 ChildNodeT&
operator*()
const {
return this->getValue(); }
276 ChildNodeT* operator->()
const {
return &this->getValue(); }
279 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
280 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
283 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
284 typedef RootNodeT NodeType;
285 typedef ValueT ValueType;
286 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
287 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
291 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
293 ValueIter& operator++() { BaseT::increment();
return *
this; }
295 ValueT& getValue()
const {
return getTile(mIter).value; }
296 ValueT&
operator*()
const {
return this->getValue(); }
297 ValueT* operator->()
const {
return &(this->getValue()); }
299 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
302 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
303 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
306 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
307 typedef RootNodeT NodeType;
308 typedef ValueT ValueType;
309 typedef ChildNodeT ChildNodeType;
310 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
311 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
312 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
316 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
318 DenseIter& operator++() { BaseT::increment();
return *
this; }
320 bool isChildNode()
const {
return isChild(mIter); }
322 ChildNodeT* probeChild(NonConstValueType& value)
const
324 if (isChild(mIter))
return &getChild(mIter);
325 value = getTile(mIter).value;
328 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const
330 child = this->probeChild(value);
331 return child != NULL;
333 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
335 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
336 void setChild(ChildNodeT* c)
const { assert(c != NULL); RootNodeT::setChild(mIter, *c); }
337 void setValue(
const ValueT& v)
const
339 if (isTile(mIter)) getTile(mIter).value = v;
343 else stealChild(mIter, Tile(v,
true));
348 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
349 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
350 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
351 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
352 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
353 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
355 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
356 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
357 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
358 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
359 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
360 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
388 void evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const;
396 void setBackground(
const ValueType& value);
403 bool isBackgroundTile(
const Tile&)
const;
406 bool isBackgroundTile(
const MapIter&)
const;
407 bool isBackgroundTile(
const MapCIter&)
const;
411 size_t numBackgroundTiles()
const;
414 size_t eraseBackgroundTiles();
415 void clear() { this->clearTable(); }
418 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
423 bool expand(
const Coord& xyz);
426 static void getNodeLog2Dims(std::vector<Index>& dims);
432 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
433 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
434 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
437 Coord getMinIndex()
const;
439 Coord getMaxIndex()
const;
441 void getIndexRange(
CoordBBox& bbox)
const;
445 template<
typename OtherChildType>
449 template<
typename OtherChildType>
456 Index64 onLeafVoxelCount()
const;
457 Index64 offLeafVoxelCount()
const;
459 bool isValueOn(
const Coord& xyz)
const;
461 bool hasActiveTiles()
const;
463 const ValueType& getValue(
const Coord& xyz)
const;
464 bool probeValue(
const Coord& xyz, ValueType& value)
const;
469 int getValueDepth(
const Coord& xyz)
const;
472 void setActiveState(
const Coord& xyz,
bool on);
475 void setValueOff(
const Coord& xyz);
477 void setValueOff(
const Coord& xyz,
const ValueType& value);
479 void setValueOn(
const Coord& xyz,
const ValueType& value);
480 void setValueOnly(
const Coord& xyz,
const ValueType& value);
481 void setValueOnMin(
const Coord& xyz,
const ValueType& value);
482 void setValueOnMax(
const Coord& xyz,
const ValueType& value);
483 void setValueOnSum(
const Coord& xyz,
const ValueType& value);
491 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
497 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
498 bool readTopology(std::istream&,
bool fromHalf =
false);
500 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
501 void readBuffers(std::istream&,
bool fromHalf =
false);
507 template<
typename AccessorT>
508 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
513 template<
typename AccessorT>
514 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
520 template<
typename AccessorT>
521 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
527 template<
typename AccessorT>
528 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
535 template<
typename AccessorT>
536 void setValueOnSumAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
542 template<
typename AccessorT>
543 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
549 template<
typename AccessorT>
550 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
556 template<
typename AccessorT>
557 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
564 template<
typename AccessorT>
565 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
573 template<
typename PruneOp>
void pruneOp(PruneOp&);
578 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
582 void pruneInactive(
const ValueType&);
586 void pruneInactive();
594 LeafNodeType* touchLeaf(
const Coord& xyz);
598 LeafNodeType* probeLeaf(
const Coord& xyz);
601 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
605 template<
typename AccessorT>
606 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
610 template<
typename AccessorT>
611 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT&);
614 template<
typename AccessorT>
615 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT&)
const;
622 void signedFloodFill();
630 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
640 void voxelizeActiveTiles();
655 template<
typename OtherChildType>
658 template<
typename CombineOp>
661 template<
typename CombineOp>
663 CombineOp& op,
bool prune =
false);
670 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
672 template<
typename VisitorOp>
void visit(VisitorOp&);
673 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
675 template<
typename OtherRootNodeType,
typename VisitorOp>
676 void visit2(OtherRootNodeType& other, VisitorOp&);
677 template<
typename OtherRootNodeType,
typename VisitorOp>
678 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
687 inline void clearTable();
690 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
691 void resetTable(
const MapType&)
const {}
694 Index getChildCount()
const;
695 Index getTileCount()
const;
696 Index getActiveTileCount()
const;
697 Index getInactiveTileCount()
const;
700 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
703 void insertKeys(CoordSet&)
const;
706 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
710 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
711 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
716 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
717 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
722 MapIter findOrAddCoord(
const Coord& xyz);
725 template<
typename OtherChildType>
726 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
728 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
729 static inline void doVisit(RootNodeT&, VisitorOp&);
731 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
732 typename ChildAllIterT,
typename OtherChildAllIterT>
733 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
737 ValueType mBackground;
744 template<
typename ChildT>
746 RootNode<ChildT>::RootNode(): mBackground(
zeroVal<ValueType>())
752 template<
typename ChildT>
760 template<
typename ChildT>
761 template<
typename OtherChildType>
770 enforceSameConfiguration(other);
772 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
775 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
776 mTable[i->first] = OtherRootT::isTile(i)
777 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
778 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
783 template<
typename ChildT>
784 template<
typename OtherChildType>
793 enforceSameConfiguration(other);
795 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
797 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
798 mTable[i->first] = OtherRootT::isTile(i)
799 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
800 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
805 template<
typename ChildT>
809 mBackground = other.mBackground;
814 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
816 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
825 template<
typename ChildT>
833 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
834 ChildT *child = iter->second.child;
836 child->resetBackground(mBackground, background);
838 Tile& tile = getTile(iter);
839 if (tile.active)
continue;
841 tile.value = background;
847 mBackground = background;
851 template<
typename ChildT>
858 template<
typename ChildT>
865 template<
typename ChildT>
873 template<
typename ChildT>
878 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
879 if (this->isBackgroundTile(i)) ++count;
885 template<
typename ChildT>
889 std::set<Coord> keysToErase;
890 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
891 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
893 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
896 return keysToErase.size();
903 template<
typename ChildT>
907 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
908 keys.insert(i->first);
913 template<
typename ChildT>
914 inline typename RootNode<ChildT>::MapIter
915 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
917 const Coord key = coordToKey(xyz);
918 std::pair<MapIter, bool> result = mTable.insert(
919 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
924 template<
typename ChildT>
928 const Coord key = coordToKey(xyz);
929 std::pair<MapIter, bool> result = mTable.insert(
930 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
931 return result.second;
938 template<
typename ChildT>
943 ChildT::getNodeLog2Dims(dims);
947 template<
typename ChildT>
951 return mTable.empty() ?
Coord(0) : mTable.begin()->first;
954 template<
typename ChildT>
958 return mTable.empty() ?
Coord(0) : mTable.rbegin()->first +
Coord(ChildT::DIM - 1);
962 template<
typename ChildT>
966 bbox.
min() = this->getMinIndex();
967 bbox.
max() = this->getMaxIndex();
974 template<
typename ChildT>
975 template<
typename OtherChildType>
980 typedef typename OtherRootT::MapType OtherMapT;
981 typedef typename OtherRootT::MapIter OtherIterT;
982 typedef typename OtherRootT::MapCIter OtherCIterT;
984 if (!hasSameConfiguration(other))
return false;
987 OtherMapT copyOfOtherTable = other.mTable;
990 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
991 if (this->isBackgroundTile(thisIter))
continue;
994 OtherCIterT otherIter = other.findKey(thisIter->first);
995 if (otherIter == other.mTable.end())
return false;
998 if (isChild(thisIter)) {
999 if (OtherRootT::isTile(otherIter))
return false;
1001 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1003 if (OtherRootT::isChild(otherIter))
return false;
1004 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1011 copyOfOtherTable.erase(otherIter->first);
1014 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1021 template<
typename ChildT>
1022 template<
typename OtherChildType>
1026 std::vector<Index> thisDims, otherDims;
1029 return (thisDims == otherDims);
1033 template<
typename ChildT>
1034 template<
typename OtherChildType>
1038 std::vector<Index> thisDims, otherDims;
1041 if (thisDims != otherDims) {
1042 std::ostringstream ostr;
1043 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1044 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1045 ostr <<
" vs. " << otherDims[0];
1046 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1056 template<
typename ChildT>
1061 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1062 if (
const ChildT *child = iter->second.child) {
1063 sum += child->memUsage();
1069 template<
typename ChildT>
1073 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1074 if (
const ChildT *child = iter->second.child) {
1075 child->evalActiveVoxelBoundingBox(bbox);
1076 }
else if (isTileOn(iter)) {
1077 bbox.
expand(iter->first, ChildT::DIM);
1083 template<
typename ChildT>
1087 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1088 delete i->second.child;
1094 template<
typename ChildT>
1096 RootNode<ChildT>::getChildCount()
const {
1098 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1099 if (isChild(i)) ++sum;
1105 template<
typename ChildT>
1107 RootNode<ChildT>::getTileCount()
const
1110 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1111 if (isTile(i)) ++sum;
1117 template<
typename ChildT>
1119 RootNode<ChildT>::getActiveTileCount()
const
1122 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1123 if (isTileOn(i)) ++sum;
1129 template<
typename ChildT>
1131 RootNode<ChildT>::getInactiveTileCount()
const
1134 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1135 if (isTileOff(i)) ++sum;
1141 template<
typename ChildT>
1146 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1147 if (isChild(i)) sum += getChild(i).leafCount();
1153 template<
typename ChildT>
1158 if (ChildT::LEVEL != 0) {
1159 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1160 if (isChild(i)) sum += getChild(i).nonLeafCount();
1167 template<
typename ChildT>
1172 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1174 sum += getChild(i).onVoxelCount();
1175 }
else if (isTileOn(i)) {
1176 sum += ChildT::NUM_VOXELS;
1183 template<
typename ChildT>
1188 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1190 sum += getChild(i).offVoxelCount();
1191 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1192 sum += ChildT::NUM_VOXELS;
1199 template<
typename ChildT>
1204 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1205 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1211 template<
typename ChildT>
1216 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1217 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1226 template<
typename ChildT>
1230 MapCIter iter = this->findCoord(xyz);
1231 if (iter == mTable.end() || isTileOff(iter))
return false;
1232 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1235 template<
typename ChildT>
1239 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1240 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1245 template<
typename ChildT>
1246 template<
typename AccessorT>
1250 MapCIter iter = this->findCoord(xyz);
1251 if (iter == mTable.end() || isTileOff(iter))
return false;
1252 if (isTileOn(iter))
return true;
1253 acc.insert(xyz, &getChild(iter));
1254 return getChild(iter).isValueOnAndCache(xyz, acc);
1258 template<
typename ChildT>
1259 inline const typename ChildT::ValueType&
1262 MapCIter iter = this->findCoord(xyz);
1263 return iter == mTable.end() ? mBackground
1264 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1267 template<
typename ChildT>
1268 template<
typename AccessorT>
1269 inline const typename ChildT::ValueType&
1272 MapCIter iter = this->findCoord(xyz);
1273 if (iter == mTable.end())
return mBackground;
1274 if (isChild(iter)) {
1275 acc.insert(xyz, &getChild(iter));
1276 return getChild(iter).getValueAndCache(xyz, acc);
1278 return getTile(iter).value;
1282 template<
typename ChildT>
1286 MapCIter iter = this->findCoord(xyz);
1287 return iter == mTable.end() ? -1
1288 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1291 template<
typename ChildT>
1292 template<
typename AccessorT>
1296 MapCIter iter = this->findCoord(xyz);
1297 if (iter == mTable.end())
return -1;
1298 if (isTile(iter))
return 0;
1299 acc.insert(xyz, &getChild(iter));
1300 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1304 template<
typename ChildT>
1308 MapIter iter = this->findCoord(xyz);
1309 if (iter != mTable.end() && !isTileOff(iter)) {
1310 if (isTileOn(iter)) {
1311 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1313 getChild(iter).setValueOff(xyz);
1318 template<
typename ChildT>
1322 ChildT* child = NULL;
1323 MapIter iter = this->findCoord(xyz);
1324 if (iter == mTable.end()) {
1326 child =
new ChildT(xyz, mBackground);
1327 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1331 }
else if (isChild(iter)) {
1332 child = &getChild(iter);
1333 }
else if (on != getTile(iter).active) {
1334 child =
new ChildT(xyz, getTile(iter).value, !on);
1335 setChild(iter, *child);
1337 if (child) child->setActiveState(xyz, on);
1340 template<
typename ChildT>
1341 template<
typename AccessorT>
1345 ChildT* child = NULL;
1346 MapIter iter = this->findCoord(xyz);
1347 if (iter == mTable.end()) {
1349 child =
new ChildT(xyz, mBackground);
1350 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1354 }
else if (isChild(iter)) {
1355 child = &getChild(iter);
1356 }
else if (on != getTile(iter).active) {
1357 child =
new ChildT(xyz, getTile(iter).value, !on);
1358 setChild(iter, *child);
1361 acc.insert(xyz, child);
1362 child->setActiveStateAndCache(xyz, on, acc);
1367 template<
typename ChildT>
1371 ChildT* child = NULL;
1372 MapIter iter = this->findCoord(xyz);
1373 if (iter == mTable.end()) {
1375 child =
new ChildT(xyz, mBackground);
1376 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1378 }
else if (isChild(iter)) {
1379 child = &getChild(iter);
1381 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1382 setChild(iter, *child);
1384 if (child) child->setValueOff(xyz, value);
1387 template<
typename ChildT>
1388 template<
typename AccessorT>
1392 ChildT* child = NULL;
1393 MapIter iter = this->findCoord(xyz);
1394 if (iter == mTable.end()) {
1396 child =
new ChildT(xyz, mBackground);
1397 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1399 }
else if (isChild(iter)) {
1400 child = &getChild(iter);
1402 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1403 setChild(iter, *child);
1406 acc.insert(xyz, child);
1407 child->setValueOffAndCache(xyz, value, acc);
1412 template<
typename ChildT>
1416 ChildT* child = NULL;
1417 MapIter iter = this->findCoord(xyz);
1418 if (iter == mTable.end()) {
1419 child =
new ChildT(xyz, mBackground);
1420 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1421 }
else if (isChild(iter)) {
1422 child = &getChild(iter);
1424 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1425 setChild(iter, *child);
1427 if (child) child->setValueOn(xyz, value);
1430 template<
typename ChildT>
1431 template<
typename AccessorT>
1435 ChildT* child = NULL;
1436 MapIter iter = this->findCoord(xyz);
1437 if (iter == mTable.end()) {
1438 child =
new ChildT(xyz, mBackground);
1439 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1440 }
else if (isChild(iter)) {
1441 child = &getChild(iter);
1443 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1444 setChild(iter, *child);
1447 acc.insert(xyz, child);
1448 child->setValueAndCache(xyz, value, acc);
1453 template<
typename ChildT>
1457 ChildT* child = NULL;
1458 MapIter iter = this->findCoord(xyz);
1459 if (iter == mTable.end()) {
1460 child =
new ChildT(xyz, mBackground);
1461 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1462 }
else if (isChild(iter)) {
1463 child = &getChild(iter);
1465 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1466 setChild(iter, *child);
1468 if (child) child->setValueOnly(xyz, value);
1471 template<
typename ChildT>
1472 template<
typename AccessorT>
1476 ChildT* child = NULL;
1477 MapIter iter = this->findCoord(xyz);
1478 if (iter == mTable.end()) {
1479 child =
new ChildT(xyz, mBackground);
1480 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1481 }
else if (isChild(iter)) {
1482 child = &getChild(iter);
1484 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1485 setChild(iter, *child);
1488 acc.insert(xyz, child);
1489 child->setValueOnlyAndCache(xyz, value, acc);
1494 template<
typename ChildT>
1498 ChildT* child = NULL;
1499 MapIter iter = this->findCoord(xyz);
1500 if (iter == mTable.end()) {
1501 child =
new ChildT(xyz, mBackground);
1502 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1503 }
else if (isChild(iter)) {
1504 child = &getChild(iter);
1505 }
else if (isTileOff(iter) || getTile(iter).value > value) {
1506 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1507 setChild(iter, *child);
1509 if (child) child->setValueOnMin(xyz, value);
1513 template<
typename ChildT>
1517 ChildT* child = NULL;
1518 MapIter iter = this->findCoord(xyz);
1519 if (iter == mTable.end()) {
1520 child =
new ChildT(xyz, mBackground);
1521 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1522 }
else if (isChild(iter)) {
1523 child = &getChild(iter);
1524 }
else if (isTileOff(iter) || getTile(iter).value < value) {
1525 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1526 setChild(iter, *child);
1528 if (child) child->setValueOnMax(xyz, value);
1532 template<
typename ChildT>
1536 ChildT* child = NULL;
1537 MapIter iter = this->findCoord(xyz);
1538 if (iter == mTable.end()) {
1539 child =
new ChildT(xyz, mBackground);
1540 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1541 }
else if (isChild(iter)) {
1542 child = &getChild(iter);
1544 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1545 setChild(iter, *child);
1547 if (child) child->setValueOnSum(xyz, addend);
1550 template<
typename ChildT>
1551 template<
typename AccessorT>
1554 const ValueType& addend, AccessorT& acc)
1556 ChildT* child = NULL;
1557 MapIter iter = this->findCoord(xyz);
1558 if (iter == mTable.end()) {
1559 child =
new ChildT(xyz, mBackground);
1560 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1561 }
else if (isChild(iter)) {
1562 child = &getChild(iter);
1564 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1565 setChild(iter, *child);
1568 acc.insert(xyz, child);
1569 child->setValueOnSumAndCache(xyz, addend, acc);
1574 template<
typename ChildT>
1578 MapCIter iter = this->findCoord(xyz);
1579 if (iter == mTable.end()) {
1580 value = mBackground;
1582 }
else if (isChild(iter)) {
1583 return getChild(iter).probeValue(xyz, value);
1585 value = getTile(iter).value;
1586 return isTileOn(iter);
1589 template<
typename ChildT>
1590 template<
typename AccessorT>
1594 MapCIter iter = this->findCoord(xyz);
1595 if (iter == mTable.end()) {
1596 value = mBackground;
1598 }
else if (isChild(iter)) {
1599 acc.insert(xyz, &getChild(iter));
1600 return getChild(iter).probeValueAndCache(xyz, value, acc);
1602 value = getTile(iter).value;
1603 return isTileOn(iter);
1610 template<
typename ChildT>
1614 if (bbox.
empty())
return;
1617 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
1619 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
1621 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
1625 Coord tileMin = coordToKey(xyz);
1626 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
1632 ChildT* child = NULL;
1633 MapIter iter = this->findKey(tileMin);
1634 if (iter == mTable.end()) {
1637 child =
new ChildT(xyz, mBackground);
1638 mTable[tileMin] = NodeStruct(*child);
1639 }
else if (isTile(iter)) {
1642 const Tile& tile = getTile(iter);
1643 child =
new ChildT(xyz, tile.value, tile.active);
1644 mTable[tileMin] = NodeStruct(*child);
1645 }
else if (isChild(iter)) {
1646 child = &getChild(iter);
1657 MapIter iter = this->findOrAddCoord(tileMin);
1658 setTile(iter, Tile(value, active));
1669 template<
typename ChildT>
1674 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(
ValueType));
1677 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(
ValueType));
1681 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
1682 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
1683 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
1685 if (numTiles == 0 && numChildren == 0)
return false;
1688 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1689 if (isChild(i))
continue;
1690 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1691 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(
ValueType));
1692 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
1695 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1696 if (isTile(i))
continue;
1697 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1698 getChild(i).writeTopology(os, toHalf);
1705 template<
typename ChildT>
1717 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
1719 is.read(reinterpret_cast<char*>(&inside),
sizeof(
ValueType));
1724 Coord rangeMin, rangeMax;
1726 is.read(reinterpret_cast<char*>(rangeMax.
asPointer()), 3 *
sizeof(
Int32));
1729 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
1731 for (
int i = 0; i < 3; ++i) {
1732 offset[i] = rangeMin[i] >> ChildT::TOTAL;
1733 rangeMin[i] = offset[i] << ChildT::TOTAL;
1735 tableSize += log2Dim[i];
1736 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
1738 log2Dim[3] = log2Dim[1] + log2Dim[2];
1739 tableSize = 1U << tableSize;
1747 for (
Index i = 0; i < tableSize; ++i) {
1751 origin[0] = (n >> log2Dim[3]) + offset[0];
1752 n &= (1U << log2Dim[3]) - 1;
1753 origin[1] = (n >> log2Dim[2]) + offset[1];
1754 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
1755 origin <<= ChildT::TOTAL;
1757 if (childMask.isOn(i)) {
1759 ChildT* child =
new ChildT(origin, mBackground);
1760 child->readTopology(is);
1761 mTable[origin] = NodeStruct(*child);
1766 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1768 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
1777 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
1780 Index numTiles = 0, numChildren = 0;
1781 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
1782 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
1784 if (numTiles == 0 && numChildren == 0)
return false;
1791 for (
Index n = 0; n < numTiles; ++n) {
1792 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
1793 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1794 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
1795 mTable[
Coord(vec)] = NodeStruct(Tile(value, active));
1799 for (
Index n = 0; n < numChildren; ++n) {
1800 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
1802 ChildT* child =
new ChildT(origin, mBackground);
1803 child->readTopology(is, fromHalf);
1804 mTable[
Coord(vec)] = NodeStruct(*child);
1811 template<
typename ChildT>
1815 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1816 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
1821 template<
typename ChildT>
1825 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1826 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
1834 template<
typename ChildT>
1835 template<
typename PruneOp>
1839 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1840 if (this->isTile(i)|| !op(this->getChild(i)))
continue;
1841 this->setTile(i, Tile(op.value, op.state));
1843 this->eraseBackgroundTiles();
1847 template<
typename ChildT>
1856 template<
typename ChildT>
1865 template<
typename ChildT>
1869 this->pruneInactive(mBackground);
1876 template<
typename ChildT>
1877 inline typename ChildT::LeafNodeType*
1880 ChildT* child = NULL;
1881 MapIter iter = this->findCoord(xyz);
1882 if (iter == mTable.end()) {
1883 child =
new ChildT(xyz, mBackground,
false);
1884 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1885 }
else if (isChild(iter)) {
1886 child = &getChild(iter);
1888 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1889 setChild(iter, *child);
1891 return child->touchLeaf(xyz);
1895 template<
typename ChildT>
1896 template<
typename AccessorT>
1897 inline typename ChildT::LeafNodeType*
1900 ChildT* child = NULL;
1901 MapIter iter = this->findCoord(xyz);
1902 if (iter == mTable.end()) {
1903 child =
new ChildT(xyz, mBackground,
false);
1904 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1905 }
else if (isChild(iter)) {
1906 child = &getChild(iter);
1908 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1909 setChild(iter, *child);
1911 acc.insert(xyz, child);
1912 return child->touchLeafAndCache(xyz, acc);
1919 template<
typename ChildT>
1920 inline typename ChildT::LeafNodeType*
1923 MapIter iter = this->findCoord(xyz);
1924 if (iter == mTable.end() || isTile(iter))
return NULL;
1925 return getChild(iter).probeLeaf(xyz);
1929 template<
typename ChildT>
1930 inline const typename ChildT::LeafNodeType*
1933 MapCIter iter = this->findCoord(xyz);
1934 if (iter == mTable.end() || isTile(iter))
return NULL;
1935 return getChild(iter).probeConstLeaf(xyz);
1939 template<
typename ChildT>
1940 template<
typename AccessorT>
1941 inline typename ChildT::LeafNodeType*
1944 MapIter iter = this->findCoord(xyz);
1945 if (iter == mTable.end() || isTile(iter))
return NULL;
1946 ChildT* child = &getChild(iter);
1947 acc.insert(xyz, child);
1948 return child->probeLeafAndCache(xyz, acc);
1952 template<
typename ChildT>
1953 template<
typename AccessorT>
1954 inline const typename ChildT::LeafNodeType*
1957 MapCIter iter = this->findCoord(xyz);
1958 if (iter == mTable.end() || isTile(iter))
return NULL;
1959 const ChildT* child = &getChild(iter);
1960 acc.insert(xyz, child);
1961 return child->probeConstLeafAndCache(xyz, acc);
1968 template<
typename ChildT>
1972 this->signedFloodFill(mBackground,
negative(mBackground));
1976 template<
typename ChildT>
1980 const ValueType zero = zeroVal<ValueType>();
1982 mBackground = outside;
1986 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1987 if (this->isTile(i))
continue;
1988 getChild(i).signedFloodFill(outside, inside);
1989 nodeKeys.insert(i->first);
1995 const Tile insideTile(inside,
false);
1996 CoordSetCIter b = nodeKeys.begin(), e = nodeKeys.end();
1997 if ( b == e )
return;
1998 for (CoordSetCIter a = b++; b != e; ++a, ++b) {
2000 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(ChildT::DIM))
continue;
2001 MapIter i = mTable.find(*a), j = mTable.find(*b);
2002 const ValueType fill[] = { getChild(i).getLastValue(), getChild(j).getFirstValue() };
2003 if (!(fill[0] < zero) || !(fill[1] < zero))
continue;
2004 for (
Coord c = *a +
Coord(0u,0u,ChildT::DIM); c[2] != (*b)[2]; c[2] += ChildT::DIM) {
2005 mTable[c] = insideTile;
2014 template<
typename ChildT>
2018 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2019 if (this->isTileOff(i))
continue;
2020 ChildT* child = i->second.child;
2022 child =
new ChildT(i->first, this->getTile(i).value,
true);
2023 i->second.child = child;
2025 child->voxelizeActiveTiles();
2033 template<
typename ChildT>
2037 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2038 MapIter j = mTable.find(i->first);
2039 if (other.isChild(i)) {
2040 if (j == mTable.end()) {
2041 mTable[i->first]=NodeStruct(stealChild(i, Tile(other.mBackground,
false)));
2042 }
else if (isTile(j)) {
2043 setChild(j, stealChild(i, Tile(other.mBackground,
false)));
2045 getChild(j).merge(getChild(i),other.mBackground, mBackground);
2048 if (j == mTable.end()) {
2049 mTable[i->first] = i->second;
2061 template<
typename ChildT>
2062 template<
typename OtherChildType>
2067 typedef typename OtherRootT::MapCIter OtherCIterT;
2069 enforceSameConfiguration(other);
2071 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2072 MapIter j = mTable.find(i->first);
2073 if (other.isChild(i)) {
2074 if (j == mTable.end()) {
2075 mTable[i->first] = NodeStruct(
2076 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
2077 }
else if (this->isChild(j)) {
2078 this->getChild(j).topologyUnion(other.getChild(i));
2080 ChildT* child =
new ChildT(
2081 other.getChild(i), this->getTile(j).value,
TopologyCopy());
2082 if (this->isTileOn(j)) child->setValuesOn();
2083 this->setChild(j, *child);
2085 }
else if (other.isTileOn(i)) {
2086 if (j == mTable.end()) {
2087 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
2088 }
else if (this->isChild(j)) {
2089 this->getChild(j).setValuesOn();
2090 }
else if (this->isTileOff(j)) {
2091 this->setTile(j, Tile(this->getTile(j).value,
true));
2101 template<
typename ChildT>
2102 template<
typename CombineOp>
2109 this->insertKeys(keys);
2110 other.insertKeys(keys);
2112 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2113 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
2114 if (isTile(iter) && isTile(otherIter)) {
2117 op(args.
setARef(getTile(iter).value)
2118 .setAIsActive(isTileOn(iter))
2119 .setBRef(getTile(otherIter).value)
2120 .setBIsActive(isTileOn(otherIter)));
2123 }
else if (isChild(iter) && isTile(otherIter)) {
2125 ChildT& child = getChild(iter);
2126 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
2128 }
else if (isTile(iter) && isChild(otherIter)) {
2133 ChildT& child = getChild(otherIter);
2134 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
2137 setChild(iter, stealChild(otherIter, Tile()));
2141 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
2142 child.combine(otherChild, op);
2144 if (prune && isChild(iter)) getChild(iter).prune();
2148 op(args.
setARef(mBackground).setBRef(other.mBackground));
2149 mBackground = args.
result();
2159 template<
typename ChildT>
2160 template<
typename CombineOp>
2163 CombineOp& op,
bool prune)
2168 other0.insertKeys(keys);
2169 other1.insertKeys(keys);
2172 bg0(Tile(other0.mBackground,
false)),
2173 bg1(Tile(other1.mBackground,
false));
2175 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2176 MapIter thisIter = this->findOrAddCoord(*i);
2177 MapCIter iter0 = other0.findKey(*i), iter1 = other1.findKey(*i);
2179 &ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0,
2180 &ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
2181 if (ns0.isTile() && ns1.isTile()) {
2184 op(args.
setARef(ns0.tile.value)
2185 .setAIsActive(ns0.isTileOn())
2186 .setBRef(ns1.tile.value)
2187 .setBIsActive(ns1.isTileOn()));
2190 ChildT& otherChild = ns0.isChild() ? *ns0.child : *ns1.child;
2191 if (!isChild(thisIter)) {
2194 *(
new ChildT(otherChild.getOrigin(), getTile(thisIter).value)));
2196 ChildT& child = getChild(thisIter);
2201 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
2202 }
else if (ns1.isTile()) {
2205 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
2209 child.combine2(*ns0.child, *ns1.child, op);
2212 if (prune && isChild(thisIter)) getChild(thisIter).prune();
2216 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
2217 mBackground = args.
result();
2224 template<
typename ChildT>
2225 template<
typename BBoxOp>
2229 const bool descent = op.template descent<LEVEL>();
2230 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2231 if (this->isTileOff(i))
continue;
2232 if (this->isChild(i) && descent) {
2233 this->getChild(i).visitActiveBBox(op);
2245 template<
typename ChildT>
2246 template<
typename VisitorOp>
2250 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
2254 template<
typename ChildT>
2255 template<
typename VisitorOp>
2259 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
2263 template<
typename ChildT>
2264 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
2268 typename RootNodeT::ValueType val;
2269 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2270 if (op(iter))
continue;
2271 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2281 template<
typename ChildT>
2282 template<
typename OtherRootNodeType,
typename VisitorOp>
2287 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
2291 template<
typename ChildT>
2292 template<
typename OtherRootNodeType,
typename VisitorOp>
2297 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
2301 template<
typename ChildT>
2304 typename OtherRootNodeT,
2306 typename ChildAllIterT,
2307 typename OtherChildAllIterT>
2313 enforceSameConfiguration(other);
2315 typename RootNodeT::ValueType val;
2316 typename OtherRootNodeT::ValueType otherVal;
2321 RootNodeT copyOfSelf(
self.mBackground);
2322 copyOfSelf.mTable =
self.mTable;
2323 OtherRootNodeT copyOfOther(other.mBackground);
2324 copyOfOther.mTable = other.mTable;
2328 self.insertKeys(keys);
2329 other.insertKeys(keys);
2330 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2331 copyOfSelf.findOrAddCoord(*i);
2332 copyOfOther.findOrAddCoord(*i);
2335 ChildAllIterT iter = copyOfSelf.beginChildAll();
2336 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
2338 for ( ; iter && otherIter; ++iter, ++otherIter)
2340 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2342 typename ChildAllIterT::ChildNodeType* child =
2343 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2344 typename OtherChildAllIterT::ChildNodeType* otherChild =
2345 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2347 if (child != NULL && otherChild != NULL) {
2348 child->visit2Node(*otherChild, op);
2349 }
else if (child != NULL) {
2350 child->visit2(otherIter, op);
2351 }
else if (otherChild != NULL) {
2352 otherChild->visit2(iter, op,
true);
2357 copyOfSelf.eraseBackgroundTiles();
2358 copyOfOther.eraseBackgroundTiles();
2362 self.resetTable(copyOfSelf.mTable);
2363 other.resetTable(copyOfOther.mTable);
2370 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED