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/math/Math.h>
45 #include <openvdb/math/BBox.h>
46 #include <openvdb/util/NodeMasks.h>
47 #include <openvdb/version.h>
56 template<
typename ChildType>
64 static const Index LEVEL = 1 + ChildType::LEVEL;
68 template<
typename OtherValueType>
93 template<
typename OtherChildType>
95 const ValueType& background,
const ValueType& foreground,
113 template<
typename OtherChildType>
123 Tile(): value(
zeroVal<ValueType>()), active(false) {}
124 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
134 NodeStruct(): child(NULL) {}
135 NodeStruct(ChildType& c): child(&c) {}
136 NodeStruct(
const Tile& t): child(NULL), tile(t) {}
139 bool isChild()
const {
return child != NULL; }
140 bool isTile()
const {
return child == NULL; }
141 bool isTileOff()
const {
return isTile() && !tile.active; }
142 bool isTileOn()
const {
return isTile() && tile.active; }
144 void set(ChildType& c) {
delete child; child = &c; }
145 void set(
const Tile& t) {
delete child; child = NULL; tile = t; }
146 ChildType& steal(
const Tile& t) { ChildType* c = child; child = NULL; tile = t;
return *c; }
149 typedef std::map<Coord, NodeStruct> MapType;
150 typedef typename MapType::iterator MapIter;
151 typedef typename MapType::const_iterator MapCIter;
153 typedef std::set<Coord> CoordSet;
154 typedef typename CoordSet::iterator CoordSetIter;
155 typedef typename CoordSet::const_iterator CoordSetCIter;
157 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
158 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
159 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
160 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
161 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
162 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
163 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
164 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
166 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
167 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
168 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
169 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
170 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
171 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
172 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
173 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
176 static inline bool test(
const MapIter&) {
return true; }
177 static inline bool test(
const MapCIter&) {
return true; }
180 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
181 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
183 struct ValueOffPred {
184 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
185 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
187 struct ValueAllPred {
188 static inline bool test(
const MapIter& i) {
return isTile(i); }
189 static inline bool test(
const MapCIter& i) {
return isTile(i); }
192 static inline bool test(
const MapIter& i) {
return isChild(i); }
193 static inline bool test(
const MapCIter& i) {
return isChild(i); }
195 struct ChildOffPred {
196 static inline bool test(
const MapIter& i) {
return isTile(i); }
197 static inline bool test(
const MapCIter& i) {
return isTile(i); }
200 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
204 typedef _RootNodeT RootNodeT;
205 typedef _MapIterT MapIterT;
209 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
211 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
213 RootNodeT* getParentNode()
const {
return mParentNode; }
215 RootNodeT& parent()
const
217 if (!mParentNode)
OPENVDB_THROW(ValueError,
"iterator references a null parent node");
221 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
222 operator bool()
const {
return this->test(); }
224 void increment() { ++mIter; this->skip(); }
225 bool next() { this->increment();
return this->test(); }
226 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
232 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
235 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
236 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
237 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
238 void setValueOff()
const { mIter->second.tile.active =
false; }
241 Coord getCoord()
const {
return mIter->first; }
243 void getCoord(
Coord& xyz)
const { xyz = this->getCoord(); }
246 BaseIter(): mParentNode(NULL) {}
247 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
249 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
251 RootNodeT* mParentNode;
255 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
256 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
259 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
260 typedef RootNodeT NodeType;
261 typedef NodeType ValueType;
262 typedef ChildNodeT ChildNodeType;
263 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
264 typedef typename boost::remove_const<ValueType>::type NonConstValueType;
265 typedef typename boost::remove_const<ChildNodeType>::type NonConstChildNodeType;
269 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
271 ChildIter& operator++() { BaseT::increment();
return *
this; }
273 ChildNodeT& getValue()
const {
return getChild(mIter); }
274 ChildNodeT&
operator*()
const {
return this->getValue(); }
275 ChildNodeT* operator->()
const {
return &this->getValue(); }
278 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
279 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
282 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
283 typedef RootNodeT NodeType;
284 typedef ValueT ValueType;
285 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
286 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
290 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
292 ValueIter& operator++() { BaseT::increment();
return *
this; }
294 ValueT& getValue()
const {
return getTile(mIter).value; }
295 ValueT&
operator*()
const {
return this->getValue(); }
296 ValueT* operator->()
const {
return &(this->getValue()); }
298 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
301 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
302 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
305 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
306 typedef RootNodeT NodeType;
307 typedef ValueT ValueType;
308 typedef ChildNodeT ChildNodeType;
309 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
310 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
311 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
315 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
317 DenseIter& operator++() { BaseT::increment();
return *
this; }
319 bool isChildNode()
const {
return isChild(mIter); }
321 ChildNodeT* probeChild(NonConstValueType& value)
const
323 if (isChild(mIter))
return &getChild(mIter);
324 value = getTile(mIter).value;
327 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const
329 child = this->probeChild(value);
330 return child != NULL;
332 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
334 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
335 void setChild(ChildNodeT* c)
const { assert(c != NULL); RootNodeT::setChild(mIter, *c); }
336 void setValue(
const ValueT& v)
const
338 if (isTile(mIter)) getTile(mIter).value = v;
342 else stealChild(mIter, Tile(v,
true));
347 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
348 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
349 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
350 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
351 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
352 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
354 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
355 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
356 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
357 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
358 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
359 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
387 void evalActiveVoxelBoundingBox(
CoordBBox& bbox)
const;
392 void setBackground(
const ValueType& value);
396 bool isBackgroundTile(
const Tile&)
const;
399 bool isBackgroundTile(
const MapIter&)
const;
400 bool isBackgroundTile(
const MapCIter&)
const;
404 size_t numBackgroundTiles()
const;
407 size_t eraseBackgroundTiles();
408 void clear() { this->clearTable(); }
411 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
416 bool expand(
const Coord& xyz);
419 static void getNodeLog2Dims(std::vector<Index>& dims);
425 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
426 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
427 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
430 Coord getMinIndex()
const;
432 Coord getMaxIndex()
const;
434 void getIndexRange(
CoordBBox& bbox)
const;
438 template<
typename OtherChildType>
442 template<
typename OtherChildType>
449 Index64 onLeafVoxelCount()
const;
450 Index64 offLeafVoxelCount()
const;
452 bool isValueOn(
const Coord& xyz)
const;
454 bool hasActiveTiles()
const;
456 const ValueType& getValue(
const Coord& xyz)
const;
457 bool probeValue(
const Coord& xyz, ValueType& value)
const;
462 int getValueDepth(
const Coord& xyz)
const;
465 void setActiveState(
const Coord& xyz,
bool on);
468 void setValueOff(
const Coord& xyz);
470 void setValueOff(
const Coord& xyz,
const ValueType& value);
472 void setValueOn(
const Coord& xyz,
const ValueType& value);
473 void setValueOnly(
const Coord& xyz,
const ValueType& value);
474 void setValueOnMin(
const Coord& xyz,
const ValueType& value);
475 void setValueOnMax(
const Coord& xyz,
const ValueType& value);
476 void setValueOnSum(
const Coord& xyz,
const ValueType& value);
484 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
490 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
491 bool readTopology(std::istream&,
bool fromHalf =
false);
493 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
494 void readBuffers(std::istream&,
bool fromHalf =
false);
496 template<
typename AccessorT>
499 template<
typename ProbeType,
typename AccessorT>
502 template<
bool State,
bool Level,
typename AccessorT>
509 template<
typename AccessorT>
510 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
515 template<
typename AccessorT>
516 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
522 template<
typename AccessorT>
523 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
529 template<
typename AccessorT>
530 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
537 template<
typename AccessorT>
538 void setValueOnSumAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
544 template<
typename AccessorT>
545 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
551 template<
typename AccessorT>
552 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
558 template<
typename AccessorT>
559 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
566 template<
typename AccessorT>
567 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
572 template<
typename AccessorT>
581 template<
typename PruneOp>
void pruneOp(PruneOp&);
586 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
590 void pruneInactive(
const ValueType&);
594 void pruneInactive();
602 LeafNodeType* touchLeaf(
const Coord& xyz);
606 LeafNodeType* probeLeaf(
const Coord& xyz);
609 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
613 template<
typename AccessorT>
614 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
618 template<
typename AccessorT>
619 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT&);
622 template<
typename AccessorT>
623 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT&)
const;
627 bool signedFloodFill();
637 void voxelizeActiveTiles();
647 template<
typename OtherChildType>
650 template<
typename CombineOp>
653 template<
typename CombineOp>
655 CombineOp& op,
bool prune =
false);
662 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
664 template<
typename VisitorOp>
void visit(VisitorOp&);
665 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
667 template<
typename OtherRootNodeType,
typename VisitorOp>
668 void visit2(OtherRootNodeType& other, VisitorOp&);
669 template<
typename OtherRootNodeType,
typename VisitorOp>
670 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
679 inline void clearTable();
682 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
683 void resetTable(
const MapType&)
const {}
686 Index getChildCount()
const;
687 Index getTileCount()
const;
688 Index getActiveTileCount()
const;
689 Index getInactiveTileCount()
const;
692 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
695 void insertKeys(CoordSet&)
const;
698 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
702 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
703 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
708 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
709 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
714 MapIter findOrAddCoord(
const Coord& xyz);
717 template<
typename OtherChildType>
718 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
720 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
721 static inline void doVisit(RootNodeT&, VisitorOp&);
723 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
724 typename ChildAllIterT,
typename OtherChildAllIterT>
725 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
729 ValueType mBackground;
736 template<
typename ChildT>
744 template<
typename ChildT>
752 template<
typename ChildT>
753 template<
typename OtherChildType>
762 enforceSameConfiguration(other);
764 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
767 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
768 mTable[i->first] = OtherRootT::isTile(i)
769 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
770 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
775 template<
typename ChildT>
776 template<
typename OtherChildType>
785 enforceSameConfiguration(other);
787 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
789 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
790 mTable[i->first] = OtherRootT::isTile(i)
791 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
792 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
797 template<
typename ChildT>
801 mBackground = other.mBackground;
806 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
808 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
817 template<
typename ChildT>
825 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
826 ChildT *child = iter->second.child;
828 child->resetBackground(mBackground, background);
831 getTile(iter).value = background;
833 getTile(iter).value =
negative(background);
837 mBackground = background;
841 template<
typename ChildT>
848 template<
typename ChildT>
855 template<
typename ChildT>
863 template<
typename ChildT>
868 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
869 if (this->isBackgroundTile(i)) ++count;
875 template<
typename ChildT>
879 std::set<Coord> keysToErase;
880 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
881 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
883 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
886 return keysToErase.size();
893 template<
typename ChildT>
897 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
898 keys.insert(i->first);
903 template<
typename ChildT>
904 inline typename RootNode<ChildT>::MapIter
905 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
907 const Coord key = coordToKey(xyz);
908 std::pair<MapIter, bool> result = mTable.insert(
909 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
914 template<
typename ChildT>
918 const Coord key = coordToKey(xyz);
919 std::pair<MapIter, bool> result = mTable.insert(
920 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
921 return result.second;
928 template<
typename ChildT>
933 ChildT::getNodeLog2Dims(dims);
937 template<
typename ChildT>
941 return mTable.empty() ?
Coord(0) : mTable.begin()->first;
944 template<
typename ChildT>
948 return mTable.empty() ?
Coord(0) : mTable.rbegin()->first +
Coord(ChildT::DIM - 1);
952 template<
typename ChildT>
956 bbox.
min() = this->getMinIndex();
957 bbox.
max() = this->getMaxIndex();
964 template<
typename ChildT>
965 template<
typename OtherChildType>
970 typedef typename OtherRootT::MapType OtherMapT;
971 typedef typename OtherRootT::MapIter OtherIterT;
972 typedef typename OtherRootT::MapCIter OtherCIterT;
974 if (!hasSameConfiguration(other))
return false;
977 OtherMapT copyOfOtherTable = other.mTable;
980 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
981 if (this->isBackgroundTile(thisIter))
continue;
984 OtherCIterT otherIter = other.findKey(thisIter->first);
985 if (otherIter == other.mTable.end())
return false;
988 if (isChild(thisIter)) {
989 if (OtherRootT::isTile(otherIter))
return false;
991 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
993 if (OtherRootT::isChild(otherIter))
return false;
994 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1001 copyOfOtherTable.erase(otherIter->first);
1004 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1011 template<
typename ChildT>
1012 template<
typename OtherChildType>
1016 std::vector<Index> thisDims, otherDims;
1019 return (thisDims == otherDims);
1023 template<
typename ChildT>
1024 template<
typename OtherChildType>
1028 std::vector<Index> thisDims, otherDims;
1031 if (thisDims != otherDims) {
1032 std::ostringstream ostr;
1033 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1034 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1035 ostr <<
" vs. " << otherDims[0];
1036 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1046 template<
typename ChildT>
1051 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1052 if (
const ChildT *child = iter->second.child) {
1053 sum += child->memUsage();
1059 template<
typename ChildT>
1063 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1064 if (
const ChildT *child = iter->second.child) {
1065 child->evalActiveVoxelBoundingBox(bbox);
1066 }
else if (isTileOn(iter)) {
1067 bbox.
expand(iter->first, ChildT::DIM);
1073 template<
typename ChildT>
1077 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1078 delete i->second.child;
1084 template<
typename ChildT>
1086 RootNode<ChildT>::getChildCount()
const {
1088 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1089 if (isChild(i)) ++sum;
1095 template<
typename ChildT>
1097 RootNode<ChildT>::getTileCount()
const
1100 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1101 if (isTile(i)) ++sum;
1107 template<
typename ChildT>
1109 RootNode<ChildT>::getActiveTileCount()
const
1112 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1113 if (isTileOn(i)) ++sum;
1119 template<
typename ChildT>
1121 RootNode<ChildT>::getInactiveTileCount()
const
1124 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1125 if (isTileOff(i)) ++sum;
1131 template<
typename ChildT>
1136 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1137 if (isChild(i)) sum += getChild(i).leafCount();
1143 template<
typename ChildT>
1148 if (ChildT::LEVEL != 0) {
1149 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1150 if (isChild(i)) sum += getChild(i).nonLeafCount();
1157 template<
typename ChildT>
1162 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1164 sum += getChild(i).onVoxelCount();
1165 }
else if (isTileOn(i)) {
1166 sum += ChildT::NUM_VOXELS;
1173 template<
typename ChildT>
1178 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1180 sum += getChild(i).offVoxelCount();
1181 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1182 sum += ChildT::NUM_VOXELS;
1189 template<
typename ChildT>
1194 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1195 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1201 template<
typename ChildT>
1206 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1207 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1216 template<
typename ChildT>
1220 MapCIter iter = this->findCoord(xyz);
1221 if (iter == mTable.end() || isTileOff(iter))
return false;
1222 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1225 template<
typename ChildT>
1229 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1230 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1235 template<
typename ChildT>
1236 template<
typename AccessorT>
1240 MapCIter iter = this->findCoord(xyz);
1241 if (iter == mTable.end() || isTileOff(iter))
return false;
1242 if (isTileOn(iter))
return true;
1243 acc.insert(xyz, &getChild(iter));
1244 return getChild(iter).isValueOnAndCache(xyz, acc);
1248 template<
typename ChildT>
1249 inline const typename ChildT::ValueType&
1252 MapCIter iter = this->findCoord(xyz);
1253 return iter == mTable.end() ? mBackground
1254 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1257 template<
typename ChildT>
1258 template<
typename AccessorT>
1259 inline const typename ChildT::ValueType&
1262 MapCIter iter = this->findCoord(xyz);
1263 if (iter == mTable.end())
return mBackground;
1264 if (isChild(iter)) {
1265 acc.insert(xyz, &getChild(iter));
1266 return getChild(iter).getValueAndCache(xyz, acc);
1268 return getTile(iter).value;
1272 template<
typename ChildT>
1276 MapCIter iter = this->findCoord(xyz);
1277 return iter == mTable.end() ? -1
1278 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1281 template<
typename ChildT>
1282 template<
typename AccessorT>
1286 MapCIter iter = this->findCoord(xyz);
1287 if (iter == mTable.end())
return -1;
1288 if (isTile(iter))
return 0;
1289 acc.insert(xyz, &getChild(iter));
1290 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1294 template<
typename ChildT>
1298 MapIter iter = this->findCoord(xyz);
1299 if (iter != mTable.end() && !isTileOff(iter)) {
1300 if (isTileOn(iter)) {
1301 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1303 getChild(iter).setValueOff(xyz);
1308 template<
typename ChildT>
1312 ChildT* child = NULL;
1313 MapIter iter = this->findCoord(xyz);
1314 if (iter == mTable.end()) {
1316 child =
new ChildT(xyz, mBackground);
1317 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1321 }
else if (isChild(iter)) {
1322 child = &getChild(iter);
1323 }
else if (on != getTile(iter).active) {
1324 child =
new ChildT(xyz, getTile(iter).value, !on);
1325 setChild(iter, *child);
1327 if (child) child->setActiveState(xyz, on);
1330 template<
typename ChildT>
1331 template<
typename AccessorT>
1335 ChildT* child = NULL;
1336 MapIter iter = this->findCoord(xyz);
1337 if (iter == mTable.end()) {
1339 child =
new ChildT(xyz, mBackground);
1340 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1344 }
else if (isChild(iter)) {
1345 child = &getChild(iter);
1346 }
else if (on != getTile(iter).active) {
1347 child =
new ChildT(xyz, getTile(iter).value, !on);
1348 setChild(iter, *child);
1351 acc.insert(xyz, child);
1352 child->setActiveStateAndCache(xyz, on, acc);
1357 template<
typename ChildT>
1361 ChildT* child = NULL;
1362 MapIter iter = this->findCoord(xyz);
1363 if (iter == mTable.end()) {
1365 child =
new ChildT(xyz, mBackground);
1366 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1368 }
else if (isChild(iter)) {
1369 child = &getChild(iter);
1371 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1372 setChild(iter, *child);
1374 if (child) child->setValueOff(xyz, value);
1377 template<
typename ChildT>
1378 template<
typename AccessorT>
1382 ChildT* child = NULL;
1383 MapIter iter = this->findCoord(xyz);
1384 if (iter == mTable.end()) {
1386 child =
new ChildT(xyz, mBackground);
1387 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1389 }
else if (isChild(iter)) {
1390 child = &getChild(iter);
1392 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1393 setChild(iter, *child);
1396 acc.insert(xyz, child);
1397 child->setValueOffAndCache(xyz, value, acc);
1402 template<
typename ChildT>
1406 ChildT* child = NULL;
1407 MapIter iter = this->findCoord(xyz);
1408 if (iter == mTable.end()) {
1409 child =
new ChildT(xyz, mBackground);
1410 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1411 }
else if (isChild(iter)) {
1412 child = &getChild(iter);
1414 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1415 setChild(iter, *child);
1417 if (child) child->setValueOn(xyz, value);
1420 template<
typename ChildT>
1421 template<
typename AccessorT>
1425 ChildT* child = NULL;
1426 MapIter iter = this->findCoord(xyz);
1427 if (iter == mTable.end()) {
1428 child =
new ChildT(xyz, mBackground);
1429 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1430 }
else if (isChild(iter)) {
1431 child = &getChild(iter);
1433 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1434 setChild(iter, *child);
1437 acc.insert(xyz, child);
1438 child->setValueAndCache(xyz, value, acc);
1443 template<
typename ChildT>
1447 ChildT* child = NULL;
1448 MapIter iter = this->findCoord(xyz);
1449 if (iter == mTable.end()) {
1450 child =
new ChildT(xyz, mBackground);
1451 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1452 }
else if (isChild(iter)) {
1453 child = &getChild(iter);
1455 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1456 setChild(iter, *child);
1458 if (child) child->setValueOnly(xyz, value);
1461 template<
typename ChildT>
1462 template<
typename AccessorT>
1466 ChildT* child = NULL;
1467 MapIter iter = this->findCoord(xyz);
1468 if (iter == mTable.end()) {
1469 child =
new ChildT(xyz, mBackground);
1470 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1471 }
else if (isChild(iter)) {
1472 child = &getChild(iter);
1474 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1475 setChild(iter, *child);
1478 acc.insert(xyz, child);
1479 child->setValueOnlyAndCache(xyz, value, acc);
1484 template<
typename ChildT>
1488 ChildT* child = NULL;
1489 MapIter iter = this->findCoord(xyz);
1490 if (iter == mTable.end()) {
1491 child =
new ChildT(xyz, mBackground);
1492 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1493 }
else if (isChild(iter)) {
1494 child = &getChild(iter);
1495 }
else if (isTileOff(iter) || getTile(iter).value > value) {
1496 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1497 setChild(iter, *child);
1499 if (child) child->setValueOnMin(xyz, value);
1503 template<
typename ChildT>
1507 ChildT* child = NULL;
1508 MapIter iter = this->findCoord(xyz);
1509 if (iter == mTable.end()) {
1510 child =
new ChildT(xyz, mBackground);
1511 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1512 }
else if (isChild(iter)) {
1513 child = &getChild(iter);
1514 }
else if (isTileOff(iter) || getTile(iter).value < value) {
1515 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1516 setChild(iter, *child);
1518 if (child) child->setValueOnMax(xyz, value);
1522 template<
typename ChildT>
1526 ChildT* child = NULL;
1527 MapIter iter = this->findCoord(xyz);
1528 if (iter == mTable.end()) {
1529 child =
new ChildT(xyz, mBackground);
1530 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1531 }
else if (isChild(iter)) {
1532 child = &getChild(iter);
1534 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1535 setChild(iter, *child);
1537 if (child) child->setValueOnSum(xyz, addend);
1540 template<
typename ChildT>
1541 template<
typename AccessorT>
1544 const ValueType& addend, AccessorT& acc)
1546 ChildT* child = NULL;
1547 MapIter iter = this->findCoord(xyz);
1548 if (iter == mTable.end()) {
1549 child =
new ChildT(xyz, mBackground);
1550 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1551 }
else if (isChild(iter)) {
1552 child = &getChild(iter);
1554 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1555 setChild(iter, *child);
1558 acc.insert(xyz, child);
1559 child->setValueOnSumAndCache(xyz, addend, acc);
1564 template<
typename ChildT>
1568 MapCIter iter = this->findCoord(xyz);
1569 if (iter == mTable.end()) {
1570 value = mBackground;
1572 }
else if (isChild(iter)) {
1573 return getChild(iter).probeValue(xyz, value);
1575 value = getTile(iter).value;
1576 return isTileOn(iter);
1579 template<
typename ChildT>
1580 template<
typename AccessorT>
1584 MapCIter iter = this->findCoord(xyz);
1585 if (iter == mTable.end()) {
1586 value = mBackground;
1588 }
else if (isChild(iter)) {
1589 acc.insert(xyz, &getChild(iter));
1590 return getChild(iter).probeValueAndCache(xyz, value, acc);
1592 value = getTile(iter).value;
1593 return isTileOn(iter);
1597 template<
typename ChildT>
1598 template<
typename AccessorT>
1599 inline const typename ChildT::ValueType&
1602 MapCIter iter = this->findCoord(xyz);
1603 if (iter == mTable.end()) {
1607 }
else if (isChild(iter)) {
1608 acc.insert(xyz, &getChild(iter));
1609 return getChild(iter).getValue(xyz, state, level, acc);
1611 state = isTileOn(iter);
1613 return getTile(iter).value;
1617 template<
typename ChildT>
1618 template<
typename ProbeT,
typename AccessorT>
1619 inline const typename ChildT::ValueType&
1622 MapCIter iter = this->findCoord(xyz);
1623 if (iter == mTable.end()) {
1627 }
else if (isChild(iter)) {
1628 acc.insert(xyz, &getChild(iter));
1629 return getChild(iter).probe(xyz, p, acc);
1631 p.setState(isTileOn(iter));
1633 return getTile(iter).value;
1636 template<
typename ChildT>
1637 template<
bool State,
bool Level,
typename AccessorT>
1638 inline const typename ChildT::ValueType&
1641 MapCIter iter = this->findCoord(xyz);
1642 if (iter == mTable.end()) {
1643 if (State) state =
false;
1644 if (Level) level = -1;
1646 }
else if (isChild(iter)) {
1647 acc.insert(xyz, &getChild(iter));
1648 return getChild(iter).template probe<State,Level,AccessorT>(xyz, state, level, acc);
1650 if (State) state = isTileOn(iter);
1651 if (Level) level = LEVEL;
1652 return getTile(iter).value;
1656 template<
typename ChildT>
1657 template<
typename AccessorT>
1661 MapCIter iter = this->findCoord(xyz);
1662 if (iter != mTable.end() && isChild(iter)) {
1663 acc.insert(xyz, &getChild(iter));
1664 return getChild(iter).updateCache(xyz, acc);
1672 template<
typename ChildT>
1676 if (bbox.
empty())
return;
1679 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
1681 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
1683 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
1687 Coord tileMin = coordToKey(xyz);
1688 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
1694 ChildT* child = NULL;
1695 MapIter iter = this->findKey(tileMin);
1696 if (iter == mTable.end()) {
1699 child =
new ChildT(xyz, mBackground);
1700 mTable[tileMin] = NodeStruct(*child);
1701 }
else if (isTile(iter)) {
1704 const Tile& tile = getTile(iter);
1705 child =
new ChildT(xyz, tile.value, tile.active);
1706 mTable[tileMin] = NodeStruct(*child);
1707 }
else if (isChild(iter)) {
1708 child = &getChild(iter);
1719 MapIter iter = this->findOrAddCoord(tileMin);
1720 setTile(iter, Tile(value, active));
1731 template<
typename ChildT>
1735 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(
ValueType));
1738 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
1739 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
1740 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
1742 if (numTiles == 0 && numChildren == 0)
return false;
1745 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1746 if (isChild(i))
continue;
1747 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1748 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(
ValueType));
1749 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
1752 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1753 if (isTile(i))
continue;
1754 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1755 getChild(i).writeTopology(os, toHalf);
1762 template<
typename ChildT>
1774 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
1776 is.read(reinterpret_cast<char*>(&inside),
sizeof(
ValueType));
1781 Coord rangeMin, rangeMax;
1783 is.read(reinterpret_cast<char*>(rangeMax.
asPointer()), 3 *
sizeof(
Int32));
1786 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
1788 for (
int i = 0; i < 3; ++i) {
1789 offset[i] = rangeMin[i] >> ChildT::TOTAL;
1790 rangeMin[i] = offset[i] << ChildT::TOTAL;
1792 tableSize += log2Dim[i];
1793 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
1795 log2Dim[3] = log2Dim[1] + log2Dim[2];
1796 tableSize = 1U << tableSize;
1804 for (
Index i = 0; i < tableSize; ++i) {
1808 origin[0] = (n >> log2Dim[3]) + offset[0];
1809 n &= (1U << log2Dim[3]) - 1;
1810 origin[1] = (n >> log2Dim[2]) + offset[1];
1811 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
1812 origin <<= ChildT::TOTAL;
1814 if (childMask.isOn(i)) {
1816 ChildT* child =
new ChildT(origin, mBackground);
1817 child->readTopology(is);
1818 mTable[origin] = NodeStruct(*child);
1823 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1825 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
1834 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
1837 Index numTiles = 0, numChildren = 0;
1838 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
1839 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
1841 if (numTiles == 0 && numChildren == 0)
return false;
1848 for (
Index n = 0; n < numTiles; ++n) {
1849 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
1850 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
1851 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
1852 mTable[
Coord(vec)] = NodeStruct(Tile(value, active));
1856 for (
Index n = 0; n < numChildren; ++n) {
1857 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
1859 ChildT* child =
new ChildT(origin, mBackground);
1860 child->readTopology(is, fromHalf);
1861 mTable[
Coord(vec)] = NodeStruct(*child);
1868 template<
typename ChildT>
1872 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1873 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
1878 template<
typename ChildT>
1882 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1883 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
1891 template<
typename ChildT>
1892 template<
typename PruneOp>
1896 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1897 if (this->isTile(i)|| !op(this->getChild(i)))
continue;
1898 this->setTile(i, Tile(op.value, op.state));
1900 this->eraseBackgroundTiles();
1904 template<
typename ChildT>
1913 template<
typename ChildT>
1922 template<
typename ChildT>
1926 this->pruneInactive(mBackground);
1930 template<
typename ChildT>
1931 inline typename ChildT::LeafNodeType*
1934 ChildT* child = NULL;
1935 MapIter iter = this->findCoord(xyz);
1936 if (iter == mTable.end()) {
1937 child =
new ChildT(xyz, mBackground,
false);
1938 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1939 }
else if (isChild(iter)) {
1940 child = &getChild(iter);
1942 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1943 setChild(iter, *child);
1945 return child->touchLeaf(xyz);
1948 template<
typename ChildT>
1949 template<
typename AccessorT>
1950 inline typename ChildT::LeafNodeType*
1953 ChildT* child = NULL;
1954 MapIter iter = this->findCoord(xyz);
1955 if (iter == mTable.end()) {
1956 child =
new ChildT(xyz, mBackground,
false);
1957 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1958 }
else if (isChild(iter)) {
1959 child = &getChild(iter);
1961 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1962 setChild(iter, *child);
1964 acc.insert(xyz, child);
1965 return child->touchLeafAndCache(xyz, acc);
1969 template<
typename ChildT>
1970 inline typename ChildT::LeafNodeType*
1973 MapIter iter = this->findCoord(xyz);
1974 if (iter == mTable.end() || isTile(iter))
return NULL;
1975 return getChild(iter).probeLeaf(xyz);
1978 template<
typename ChildT>
1979 inline const typename ChildT::LeafNodeType*
1982 MapCIter iter = this->findCoord(xyz);
1983 if (iter == mTable.end() || isTile(iter))
return NULL;
1984 return getChild(iter).probeConstLeaf(xyz);
1987 template<
typename ChildT>
1988 template<
typename AccessorT>
1989 inline typename ChildT::LeafNodeType*
1992 MapIter iter = this->findCoord(xyz);
1993 if (iter == mTable.end() || isTile(iter))
return NULL;
1994 ChildT* child = &getChild(iter);
1995 acc.insert(xyz, child);
1996 return child->probeLeafAndCache(xyz, acc);
1999 template<
typename ChildT>
2000 template<
typename AccessorT>
2001 inline const typename ChildT::LeafNodeType*
2004 MapCIter iter = this->findCoord(xyz);
2005 if (iter == mTable.end() || isTile(iter))
return NULL;
2006 const ChildT* child = &getChild(iter);
2007 acc.insert(xyz, child);
2008 return child->probeConstLeafAndCache(xyz, acc);
2015 template<
typename ChildT>
2019 const ValueType zero = zeroVal<ValueType>();
2021 if (!(mBackground > zero))
return false;
2025 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2026 if (this->isTile(i))
continue;
2027 getChild(i).signedFloodFill(mBackground);
2028 nodeKeys.insert(i->first);
2034 const Tile inside(
negative(mBackground),
false);
2035 CoordSetCIter b = nodeKeys.begin(), e = nodeKeys.end();
2036 if ( b == e )
return false;
2037 for (CoordSetCIter a = b++; b != e; ++a, ++b) {
2039 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(ChildT::DIM))
continue;
2040 MapIter i = mTable.find(*a), j = mTable.find(*b);
2041 const ValueType fill[] = { getChild(i).getLastValue(), getChild(j).getFirstValue() };
2042 if (!(fill[0] < zero) || !(fill[1] < zero))
continue;
2043 for (
Coord c = *a +
Coord(0u,0u,ChildT::DIM); c[2] != (*b)[2]; c[2] += ChildT::DIM) {
2054 template<
typename ChildT>
2058 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2059 if (this->isTileOff(i))
continue;
2060 ChildT* child = i->second.child;
2062 child =
new ChildT(i->first, this->getTile(i).value,
true);
2063 i->second.child = child;
2065 child->voxelizeActiveTiles();
2073 template<
typename ChildT>
2077 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2078 MapIter j = mTable.find(i->first);
2079 if (other.isChild(i)) {
2080 if (j == mTable.end()) {
2081 mTable[i->first]=NodeStruct(stealChild(i, Tile(other.mBackground,
false)));
2082 }
else if (isTile(j)) {
2083 setChild(j, stealChild(i, Tile(other.mBackground,
false)));
2085 getChild(j).merge(getChild(i),other.mBackground, mBackground);
2088 if (j == mTable.end()) {
2089 mTable[i->first] = i->second;
2097 template<
typename ChildT>
2098 template<
typename OtherChildType>
2103 typedef typename OtherRootT::MapCIter OtherCIterT;
2105 enforceSameConfiguration(other);
2107 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2108 MapIter j = mTable.find(i->first);
2109 if (other.isChild(i)) {
2110 if (j == mTable.end()) {
2111 mTable[i->first] = NodeStruct(
2112 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
2113 }
else if (this->isChild(j)) {
2114 this->getChild(j).topologyUnion(other.getChild(i));
2115 }
else if (this->isTileOff(j)) {
2117 *(
new ChildT(other.getChild(i), this->getTile(j).value,
TopologyCopy())));
2119 }
else if (other.isTileOn(i)) {
2120 if (j == mTable.end()) {
2121 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
2122 }
else if (this->isChild(j)) {
2123 this->getChild(j).setValuesOn();
2124 }
else if (this->isTileOff(j)) {
2125 this->setTile(j, Tile(this->getTile(j).value,
true));
2135 template<
typename ChildT>
2136 template<
typename CombineOp>
2143 this->insertKeys(keys);
2144 other.insertKeys(keys);
2146 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2147 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
2148 if (isTile(iter) && isTile(otherIter)) {
2151 op(args.
setARef(getTile(iter).value)
2152 .setAIsActive(isTileOn(iter))
2153 .setBRef(getTile(otherIter).value)
2154 .setBIsActive(isTileOn(otherIter)));
2157 }
else if (isChild(iter) && isTile(otherIter)) {
2159 ChildT& child = getChild(iter);
2160 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
2162 }
else if (isTile(iter) && isChild(otherIter)) {
2167 ChildT& child = getChild(otherIter);
2168 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
2171 setChild(iter, stealChild(otherIter, Tile()));
2175 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
2176 child.combine(otherChild, op);
2178 if (prune && isChild(iter)) getChild(iter).prune();
2182 op(args.
setARef(mBackground).setBRef(other.mBackground));
2183 mBackground = args.
result();
2193 template<
typename ChildT>
2194 template<
typename CombineOp>
2197 CombineOp& op,
bool prune)
2202 other0.insertKeys(keys);
2203 other1.insertKeys(keys);
2206 bg0(Tile(other0.mBackground,
false)),
2207 bg1(Tile(other1.mBackground,
false));
2209 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2210 MapIter thisIter = this->findOrAddCoord(*i);
2211 MapCIter iter0 = other0.findKey(*i), iter1 = other1.findKey(*i);
2213 &ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0,
2214 &ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
2215 if (ns0.isTile() && ns1.isTile()) {
2218 op(args.
setARef(ns0.tile.value)
2219 .setAIsActive(ns0.isTileOn())
2220 .setBRef(ns1.tile.value)
2221 .setBIsActive(ns1.isTileOn()));
2224 ChildT& otherChild = ns0.isChild() ? *ns0.child : *ns1.child;
2225 if (!isChild(thisIter)) {
2228 *(
new ChildT(otherChild.getOrigin(), getTile(thisIter).value)));
2230 ChildT& child = getChild(thisIter);
2235 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
2236 }
else if (ns1.isTile()) {
2239 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
2243 child.combine2(*ns0.child, *ns1.child, op);
2246 if (prune && isChild(thisIter)) getChild(thisIter).prune();
2250 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
2251 mBackground = args.
result();
2258 template<
typename ChildT>
2259 template<
typename BBoxOp>
2263 const bool descent = op.template descent<LEVEL>();
2264 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2265 if (this->isTileOff(i))
continue;
2266 if (this->isChild(i) && descent) {
2267 this->getChild(i).visitActiveBBox(op);
2279 template<
typename ChildT>
2280 template<
typename VisitorOp>
2284 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
2288 template<
typename ChildT>
2289 template<
typename VisitorOp>
2293 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
2297 template<
typename ChildT>
2298 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
2302 typename RootNodeT::ValueType val;
2303 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2304 if (op(iter))
continue;
2305 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2315 template<
typename ChildT>
2316 template<
typename OtherRootNodeType,
typename VisitorOp>
2321 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
2325 template<
typename ChildT>
2326 template<
typename OtherRootNodeType,
typename VisitorOp>
2331 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
2335 template<
typename ChildT>
2338 typename OtherRootNodeT,
2340 typename ChildAllIterT,
2341 typename OtherChildAllIterT>
2347 enforceSameConfiguration(other);
2349 typename RootNodeT::ValueType val;
2350 typename OtherRootNodeT::ValueType otherVal;
2355 RootNodeT copyOfSelf(
self.mBackground);
2356 copyOfSelf.mTable =
self.mTable;
2357 OtherRootNodeT copyOfOther(other.mBackground);
2358 copyOfOther.mTable = other.mTable;
2362 self.insertKeys(keys);
2363 other.insertKeys(keys);
2364 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2365 copyOfSelf.findOrAddCoord(*i);
2366 copyOfOther.findOrAddCoord(*i);
2369 ChildAllIterT iter = copyOfSelf.beginChildAll();
2370 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
2372 for ( ; iter && otherIter; ++iter, ++otherIter)
2374 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2376 typename ChildAllIterT::ChildNodeType* child =
2377 (skipBranch & 1U) ? NULL : iter.probeChild(val);
2378 typename OtherChildAllIterT::ChildNodeType* otherChild =
2379 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
2381 if (child != NULL && otherChild != NULL) {
2382 child->visit2Node(*otherChild, op);
2383 }
else if (child != NULL) {
2384 child->visit2(otherIter, op);
2385 }
else if (otherChild != NULL) {
2386 otherChild->visit2(iter, op,
true);
2391 copyOfSelf.eraseBackgroundTiles();
2392 copyOfOther.eraseBackgroundTiles();
2396 self.resetTable(copyOfSelf.mTable);
2397 other.resetTable(copyOfOther.mTable);
2404 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED