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 <boost/mpl/vector.hpp>
43 #include <boost/mpl/at.hpp>
44 #include <boost/mpl/push_back.hpp>
45 #include <boost/mpl/size.hpp>
46 #include <openvdb/Exceptions.h>
47 #include <openvdb/Types.h>
48 #include <openvdb/io/Compression.h>
49 #include <openvdb/math/Math.h>
50 #include <openvdb/math/BBox.h>
51 #include <openvdb/util/NodeMasks.h>
52 #include <openvdb/version.h>
61 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
63 template<
typename ChildType>
71 static const Index LEVEL = 1 + ChildType::LEVEL;
75 BOOST_STATIC_ASSERT(boost::mpl::size<NodeChainType>::value == LEVEL + 1);
79 template<
typename OtherValueType>
100 template<
typename OtherChildType>
102 const ValueType& background,
const ValueType& foreground,
114 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; }
300 template<
typename ModifyOp>
301 void modifyValue(
const ModifyOp& op)
const
303 assert(isTile(mIter));
304 op(getTile(mIter).value);
308 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
309 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
312 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
313 typedef RootNodeT NodeType;
314 typedef ValueT ValueType;
315 typedef ChildNodeT ChildNodeType;
316 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
317 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
318 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
322 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
324 DenseIter& operator++() { BaseT::increment();
return *
this; }
326 bool isChildNode()
const {
return isChild(mIter); }
328 ChildNodeT* probeChild(NonConstValueType& value)
const
330 if (isChild(mIter))
return &getChild(mIter);
331 value = getTile(mIter).value;
334 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const
336 child = this->probeChild(value);
337 return child != NULL;
339 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
341 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
342 void setChild(ChildNodeT* c)
const { assert(c != NULL); RootNodeT::setChild(mIter, *c); }
343 void setValue(
const ValueT& v)
const
345 if (isTile(mIter)) getTile(mIter).value = v;
349 else stealChild(mIter, Tile(v,
true));
354 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
355 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
356 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
357 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
358 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
359 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
361 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
362 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
363 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
364 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
365 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
366 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
397 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
410 void setBackground(
const ValueType& value,
bool updateChildNodes =
true);
416 bool isBackgroundTile(
const Tile&)
const;
418 bool isBackgroundTile(
const MapIter&)
const;
420 bool isBackgroundTile(
const MapCIter&)
const;
424 size_t numBackgroundTiles()
const;
427 size_t eraseBackgroundTiles();
428 void clear() { this->clearTable(); }
431 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
436 bool expand(
const Coord& xyz);
439 static void getNodeLog2Dims(std::vector<Index>& dims);
445 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
446 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
447 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
450 Coord getMinIndex()
const;
452 Coord getMaxIndex()
const;
454 void getIndexRange(CoordBBox& bbox)
const;
458 template<
typename OtherChildType>
462 template<
typename OtherChildType>
469 Index64 onLeafVoxelCount()
const;
470 Index64 offLeafVoxelCount()
const;
473 bool isValueOn(
const Coord& xyz)
const;
475 bool hasActiveTiles()
const;
477 const ValueType& getValue(
const Coord& xyz)
const;
478 bool probeValue(
const Coord& xyz, ValueType& value)
const;
483 int getValueDepth(
const Coord& xyz)
const;
486 void setActiveState(
const Coord& xyz,
bool on);
488 void setValueOnly(
const Coord& xyz,
const ValueType& value);
490 void setValueOn(
const Coord& xyz,
const ValueType& value);
492 void setValueOff(
const Coord& xyz);
494 void setValueOff(
const Coord& xyz,
const ValueType& value);
498 template<
typename ModifyOp>
499 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
501 template<
typename ModifyOp>
502 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
510 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
517 template<
typename DenseT>
518 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
524 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
525 bool readTopology(std::istream&,
bool fromHalf =
false);
527 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
528 void readBuffers(std::istream&,
bool fromHalf =
false);
538 template<
typename AccessorT>
539 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
544 template<
typename AccessorT>
545 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
551 template<
typename AccessorT>
552 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
558 template<
typename AccessorT>
559 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
566 template<
typename ModifyOp,
typename AccessorT>
567 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
573 template<
typename ModifyOp,
typename AccessorT>
574 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
580 template<
typename AccessorT>
581 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
587 template<
typename AccessorT>
588 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
595 template<
typename AccessorT>
596 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
603 template<
typename AccessorT>
604 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
612 template<
typename PruneOp>
void pruneOp(PruneOp&);
617 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
621 void pruneInactive(
const ValueType&);
625 void pruneInactive();
630 void pruneTiles(
const ValueType& tolerance);
634 void addLeaf(LeafNodeType* leaf);
638 template<
typename AccessorT>
639 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
649 template<
typename NodeT>
650 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
655 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
659 template<
typename AccessorT>
660 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
667 LeafNodeType* touchLeaf(
const Coord& xyz);
671 template<
typename AccessorT>
672 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
675 template <
typename NodeT>
678 NodeT* probeNode(
const Coord& xyz);
679 template <
typename NodeT>
680 const NodeT* probeConstNode(
const Coord& xyz)
const;
684 template<
typename NodeT,
typename AccessorT>
687 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
688 template<
typename NodeT,
typename AccessorT>
689 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
693 LeafNodeType* probeLeaf(
const Coord& xyz);
696 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
697 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
701 template<
typename AccessorT>
704 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
705 template<
typename AccessorT>
706 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
707 template<
typename AccessorT>
708 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
719 void signedFloodFill();
726 void signedFloodFill(
const ValueType& outside,
const ValueType& inside);
729 void voxelizeActiveTiles();
738 template<MergePolicy Policy>
void merge(
RootNode& other);
753 template<
typename OtherChildType>
769 template<
typename OtherChildType>
782 template<
typename OtherChildType>
785 template<
typename CombineOp>
788 template<
typename CombineOp>
790 CombineOp& op,
bool prune =
false);
797 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
799 template<
typename VisitorOp>
void visit(VisitorOp&);
800 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
802 template<
typename OtherRootNodeType,
typename VisitorOp>
803 void visit2(OtherRootNodeType& other, VisitorOp&);
804 template<
typename OtherRootNodeType,
typename VisitorOp>
805 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
814 inline void clearTable();
816 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
818 void resetTable(
const MapType&)
const {}
821 Index getChildCount()
const;
822 Index getTileCount()
const;
823 Index getActiveTileCount()
const;
824 Index getInactiveTileCount()
const;
827 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
830 void insertKeys(CoordSet&)
const;
833 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
835 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
838 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
841 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
844 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
846 MapIter findOrAddCoord(
const Coord& xyz);
852 template<
typename OtherChildType>
853 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
855 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
856 static inline void doVisit(RootNodeT&, VisitorOp&);
858 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
859 typename ChildAllIterT,
typename OtherChildAllIterT>
860 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
864 ValueType mBackground;
891 template<
typename HeadT,
int HeadLevel>
894 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
898 template<
typename HeadT>
900 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
907 template<
typename ChildT>
915 template<
typename ChildT>
923 template<
typename ChildT>
924 template<
typename OtherChildType>
933 enforceSameConfiguration(other);
935 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
938 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
939 mTable[i->first] = OtherRootT::isTile(i)
940 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
941 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
946 template<
typename ChildT>
947 template<
typename OtherChildType>
956 enforceSameConfiguration(other);
958 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
960 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
961 mTable[i->first] = OtherRootT::isTile(i)
962 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
963 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
968 template<
typename ChildT>
972 mBackground = other.mBackground;
977 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
979 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
988 template<
typename ChildT>
994 if (updateChildNodes) {
997 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
998 ChildT *child = iter->second.child;
1000 child->resetBackground(mBackground, background);
1002 Tile& tile = getTile(iter);
1003 if (tile.active)
continue;
1005 tile.value = background;
1012 mBackground = background;
1016 template<
typename ChildT>
1023 template<
typename ChildT>
1030 template<
typename ChildT>
1038 template<
typename ChildT>
1043 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1044 if (this->isBackgroundTile(i)) ++count;
1050 template<
typename ChildT>
1054 std::set<Coord> keysToErase;
1055 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1056 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
1058 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1061 return keysToErase.size();
1068 template<
typename ChildT>
1072 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1073 keys.insert(i->first);
1078 template<
typename ChildT>
1079 inline typename RootNode<ChildT>::MapIter
1080 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
1082 const Coord key = coordToKey(xyz);
1083 std::pair<MapIter, bool> result = mTable.insert(
1084 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1085 return result.first;
1089 template<
typename ChildT>
1093 const Coord key = coordToKey(xyz);
1094 std::pair<MapIter, bool> result = mTable.insert(
1095 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1096 return result.second;
1103 template<
typename ChildT>
1108 ChildT::getNodeLog2Dims(dims);
1112 template<
typename ChildT>
1116 return mTable.empty() ? Coord(0) : mTable.begin()->first;
1119 template<
typename ChildT>
1123 return mTable.empty() ? Coord(0) : mTable.rbegin()->first + Coord(ChildT::DIM - 1);
1127 template<
typename ChildT>
1131 bbox.min() = this->getMinIndex();
1132 bbox.max() = this->getMaxIndex();
1139 template<
typename ChildT>
1140 template<
typename OtherChildType>
1145 typedef typename OtherRootT::MapType OtherMapT;
1146 typedef typename OtherRootT::MapIter OtherIterT;
1147 typedef typename OtherRootT::MapCIter OtherCIterT;
1149 if (!hasSameConfiguration(other))
return false;
1152 OtherMapT copyOfOtherTable = other.mTable;
1155 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1156 if (this->isBackgroundTile(thisIter))
continue;
1159 OtherCIterT otherIter = other.findKey(thisIter->first);
1160 if (otherIter == other.mTable.end())
return false;
1163 if (isChild(thisIter)) {
1164 if (OtherRootT::isTile(otherIter))
return false;
1166 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1168 if (OtherRootT::isChild(otherIter))
return false;
1169 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1176 copyOfOtherTable.erase(otherIter->first);
1179 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1186 template<
typename ChildT>
1187 template<
typename OtherChildType>
1191 std::vector<Index> thisDims, otherDims;
1194 return (thisDims == otherDims);
1198 template<
typename ChildT>
1199 template<
typename OtherChildType>
1203 std::vector<Index> thisDims, otherDims;
1206 if (thisDims != otherDims) {
1207 std::ostringstream ostr;
1208 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1209 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1210 ostr <<
" vs. " << otherDims[0];
1211 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1221 template<
typename ChildT>
1226 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1227 if (
const ChildT *child = iter->second.child) {
1228 sum += child->memUsage();
1234 template<
typename ChildT>
1238 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1239 if (
const ChildT *child = iter->second.child) {
1240 child->evalActiveVoxelBoundingBox(bbox);
1241 }
else if (isTileOn(iter)) {
1242 bbox.expand(iter->first, ChildT::DIM);
1247 template<
typename ChildT>
1251 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1252 if (
const ChildT *child = iter->second.child) {
1253 child->evalActiveBoundingBox(bbox, visitVoxels);
1254 }
else if (isTileOn(iter)) {
1255 bbox.expand(iter->first, ChildT::DIM);
1260 template<
typename ChildT>
1264 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1265 delete i->second.child;
1271 template<
typename ChildT>
1273 RootNode<ChildT>::getChildCount()
const {
1275 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1276 if (isChild(i)) ++sum;
1282 template<
typename ChildT>
1284 RootNode<ChildT>::getTileCount()
const
1287 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1288 if (isTile(i)) ++sum;
1294 template<
typename ChildT>
1296 RootNode<ChildT>::getActiveTileCount()
const
1299 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1300 if (isTileOn(i)) ++sum;
1306 template<
typename ChildT>
1308 RootNode<ChildT>::getInactiveTileCount()
const
1311 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1312 if (isTileOff(i)) ++sum;
1318 template<
typename ChildT>
1323 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1324 if (isChild(i)) sum += getChild(i).leafCount();
1330 template<
typename ChildT>
1335 if (ChildT::LEVEL != 0) {
1336 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1337 if (isChild(i)) sum += getChild(i).nonLeafCount();
1344 template<
typename ChildT>
1349 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1351 sum += getChild(i).onVoxelCount();
1352 }
else if (isTileOn(i)) {
1353 sum += ChildT::NUM_VOXELS;
1360 template<
typename ChildT>
1365 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1367 sum += getChild(i).offVoxelCount();
1368 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1369 sum += ChildT::NUM_VOXELS;
1376 template<
typename ChildT>
1381 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1382 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1388 template<
typename ChildT>
1393 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1394 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1399 template<
typename ChildT>
1404 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1406 sum += getChild(i).onTileCount();
1407 }
else if (isTileOn(i)) {
1417 template<
typename ChildT>
1421 MapCIter iter = this->findCoord(xyz);
1422 if (iter == mTable.end() || isTileOff(iter))
return false;
1423 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1426 template<
typename ChildT>
1430 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1431 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1436 template<
typename ChildT>
1437 template<
typename AccessorT>
1441 MapCIter iter = this->findCoord(xyz);
1442 if (iter == mTable.end() || isTileOff(iter))
return false;
1443 if (isTileOn(iter))
return true;
1444 acc.insert(xyz, &getChild(iter));
1445 return getChild(iter).isValueOnAndCache(xyz, acc);
1449 template<
typename ChildT>
1450 inline const typename ChildT::ValueType&
1453 MapCIter iter = this->findCoord(xyz);
1454 return iter == mTable.end() ? mBackground
1455 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1458 template<
typename ChildT>
1459 template<
typename AccessorT>
1460 inline const typename ChildT::ValueType&
1463 MapCIter iter = this->findCoord(xyz);
1464 if (iter == mTable.end())
return mBackground;
1465 if (isChild(iter)) {
1466 acc.insert(xyz, &getChild(iter));
1467 return getChild(iter).getValueAndCache(xyz, acc);
1469 return getTile(iter).value;
1473 template<
typename ChildT>
1477 MapCIter iter = this->findCoord(xyz);
1478 return iter == mTable.end() ? -1
1479 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1482 template<
typename ChildT>
1483 template<
typename AccessorT>
1487 MapCIter iter = this->findCoord(xyz);
1488 if (iter == mTable.end())
return -1;
1489 if (isTile(iter))
return 0;
1490 acc.insert(xyz, &getChild(iter));
1491 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1495 template<
typename ChildT>
1499 MapIter iter = this->findCoord(xyz);
1500 if (iter != mTable.end() && !isTileOff(iter)) {
1501 if (isTileOn(iter)) {
1502 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1504 getChild(iter).setValueOff(xyz);
1509 template<
typename ChildT>
1513 ChildT* child = NULL;
1514 MapIter iter = this->findCoord(xyz);
1515 if (iter == mTable.end()) {
1517 child =
new ChildT(xyz, mBackground);
1518 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1522 }
else if (isChild(iter)) {
1523 child = &getChild(iter);
1524 }
else if (on != getTile(iter).active) {
1525 child =
new ChildT(xyz, getTile(iter).value, !on);
1526 setChild(iter, *child);
1528 if (child) child->setActiveState(xyz, on);
1531 template<
typename ChildT>
1532 template<
typename AccessorT>
1536 ChildT* child = NULL;
1537 MapIter iter = this->findCoord(xyz);
1538 if (iter == mTable.end()) {
1540 child =
new ChildT(xyz, mBackground);
1541 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1545 }
else if (isChild(iter)) {
1546 child = &getChild(iter);
1547 }
else if (on != getTile(iter).active) {
1548 child =
new ChildT(xyz, getTile(iter).value, !on);
1549 setChild(iter, *child);
1552 acc.insert(xyz, child);
1553 child->setActiveStateAndCache(xyz, on, acc);
1558 template<
typename ChildT>
1562 ChildT* child = NULL;
1563 MapIter iter = this->findCoord(xyz);
1564 if (iter == mTable.end()) {
1566 child =
new ChildT(xyz, mBackground);
1567 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1569 }
else if (isChild(iter)) {
1570 child = &getChild(iter);
1572 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1573 setChild(iter, *child);
1575 if (child) child->setValueOff(xyz, value);
1578 template<
typename ChildT>
1579 template<
typename AccessorT>
1583 ChildT* child = NULL;
1584 MapIter iter = this->findCoord(xyz);
1585 if (iter == mTable.end()) {
1587 child =
new ChildT(xyz, mBackground);
1588 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1590 }
else if (isChild(iter)) {
1591 child = &getChild(iter);
1593 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1594 setChild(iter, *child);
1597 acc.insert(xyz, child);
1598 child->setValueOffAndCache(xyz, value, acc);
1603 template<
typename ChildT>
1607 ChildT* child = NULL;
1608 MapIter iter = this->findCoord(xyz);
1609 if (iter == mTable.end()) {
1610 child =
new ChildT(xyz, mBackground);
1611 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1612 }
else if (isChild(iter)) {
1613 child = &getChild(iter);
1615 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1616 setChild(iter, *child);
1618 if (child) child->setValueOn(xyz, value);
1621 template<
typename ChildT>
1622 template<
typename AccessorT>
1626 ChildT* child = NULL;
1627 MapIter iter = this->findCoord(xyz);
1628 if (iter == mTable.end()) {
1629 child =
new ChildT(xyz, mBackground);
1630 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1631 }
else if (isChild(iter)) {
1632 child = &getChild(iter);
1634 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1635 setChild(iter, *child);
1638 acc.insert(xyz, child);
1639 child->setValueAndCache(xyz, value, acc);
1644 template<
typename ChildT>
1648 ChildT* child = NULL;
1649 MapIter iter = this->findCoord(xyz);
1650 if (iter == mTable.end()) {
1651 child =
new ChildT(xyz, mBackground);
1652 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1653 }
else if (isChild(iter)) {
1654 child = &getChild(iter);
1656 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1657 setChild(iter, *child);
1659 if (child) child->setValueOnly(xyz, value);
1662 template<
typename ChildT>
1663 template<
typename AccessorT>
1667 ChildT* child = NULL;
1668 MapIter iter = this->findCoord(xyz);
1669 if (iter == mTable.end()) {
1670 child =
new ChildT(xyz, mBackground);
1671 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1672 }
else if (isChild(iter)) {
1673 child = &getChild(iter);
1675 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1676 setChild(iter, *child);
1679 acc.insert(xyz, child);
1680 child->setValueOnlyAndCache(xyz, value, acc);
1685 template<
typename ChildT>
1686 template<
typename ModifyOp>
1690 ChildT* child = NULL;
1691 MapIter iter = this->findCoord(xyz);
1692 if (iter == mTable.end()) {
1693 child =
new ChildT(xyz, mBackground);
1694 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1695 }
else if (isChild(iter)) {
1696 child = &getChild(iter);
1700 bool createChild = isTileOff(iter);
1704 const ValueType& tileVal = getTile(iter).value;
1710 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1711 setChild(iter, *child);
1714 if (child) child->modifyValue(xyz, op);
1717 template<
typename ChildT>
1718 template<
typename ModifyOp,
typename AccessorT>
1722 ChildT* child = NULL;
1723 MapIter iter = this->findCoord(xyz);
1724 if (iter == mTable.end()) {
1725 child =
new ChildT(xyz, mBackground);
1726 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1727 }
else if (isChild(iter)) {
1728 child = &getChild(iter);
1732 bool createChild = isTileOff(iter);
1736 const ValueType& tileVal = getTile(iter).value;
1742 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1743 setChild(iter, *child);
1747 acc.insert(xyz, child);
1748 child->modifyValueAndCache(xyz, op, acc);
1753 template<
typename ChildT>
1754 template<
typename ModifyOp>
1758 ChildT* child = NULL;
1759 MapIter iter = this->findCoord(xyz);
1760 if (iter == mTable.end()) {
1761 child =
new ChildT(xyz, mBackground);
1762 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1763 }
else if (isChild(iter)) {
1764 child = &getChild(iter);
1766 const Tile& tile = getTile(iter);
1767 bool modifiedState = tile.active;
1769 op(modifiedVal, modifiedState);
1773 child =
new ChildT(xyz, tile.value, tile.active);
1774 setChild(iter, *child);
1777 if (child) child->modifyValueAndActiveState(xyz, op);
1780 template<
typename ChildT>
1781 template<
typename ModifyOp,
typename AccessorT>
1784 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1786 ChildT* child = NULL;
1787 MapIter iter = this->findCoord(xyz);
1788 if (iter == mTable.end()) {
1789 child =
new ChildT(xyz, mBackground);
1790 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1791 }
else if (isChild(iter)) {
1792 child = &getChild(iter);
1794 const Tile& tile = getTile(iter);
1795 bool modifiedState = tile.active;
1797 op(modifiedVal, modifiedState);
1801 child =
new ChildT(xyz, tile.value, tile.active);
1802 setChild(iter, *child);
1806 acc.insert(xyz, child);
1807 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1812 template<
typename ChildT>
1816 MapCIter iter = this->findCoord(xyz);
1817 if (iter == mTable.end()) {
1818 value = mBackground;
1820 }
else if (isChild(iter)) {
1821 return getChild(iter).probeValue(xyz, value);
1823 value = getTile(iter).value;
1824 return isTileOn(iter);
1827 template<
typename ChildT>
1828 template<
typename AccessorT>
1832 MapCIter iter = this->findCoord(xyz);
1833 if (iter == mTable.end()) {
1834 value = mBackground;
1836 }
else if (isChild(iter)) {
1837 acc.insert(xyz, &getChild(iter));
1838 return getChild(iter).probeValueAndCache(xyz, value, acc);
1840 value = getTile(iter).value;
1841 return isTileOn(iter);
1848 template<
typename ChildT>
1852 if (bbox.empty())
return;
1855 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
1857 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
1859 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
1863 Coord tileMin = coordToKey(xyz);
1864 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
1866 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
1870 ChildT* child = NULL;
1871 MapIter iter = this->findKey(tileMin);
1872 if (iter == mTable.end()) {
1875 child =
new ChildT(xyz, mBackground);
1876 mTable[tileMin] = NodeStruct(*child);
1877 }
else if (isTile(iter)) {
1880 const Tile& tile = getTile(iter);
1881 child =
new ChildT(xyz, tile.value, tile.active);
1882 mTable[tileMin] = NodeStruct(*child);
1883 }
else if (isChild(iter)) {
1884 child = &getChild(iter);
1895 MapIter iter = this->findOrAddCoord(tileMin);
1896 setTile(iter, Tile(value, active));
1903 template<
typename ChildT>
1904 template<
typename DenseT>
1908 typedef typename DenseT::ValueType DenseValueType;
1910 const size_t xStride = dense.xStride(), yStride = dense.yStride();
1911 const Coord&
min = dense.bbox().min();
1913 for (Coord xyz = bbox.min(); xyz[0] <= bbox.max()[0]; xyz[0] = nodeBBox.max()[0] + 1) {
1914 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] = nodeBBox.max()[1] + 1) {
1915 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] = nodeBBox.max()[2] + 1) {
1918 nodeBBox = CoordBBox::createCube(coordToKey(xyz), ChildT::DIM);
1923 MapCIter iter = this->findKey(nodeBBox.min());
1924 if (iter != mTable.end() && isChild(iter)) {
1925 getChild(iter).copyToDense(sub, dense);
1927 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
1928 sub.translate(-min);
1929 DenseValueType* a0 = dense.data() + sub.min()[2];
1930 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
1931 DenseValueType* a1 = a0 + x*xStride;
1932 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
1933 DenseValueType* a2 = a1 + y*yStride;
1934 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z) {
1935 *a2++ = DenseValueType(value);
1948 template<
typename ChildT>
1953 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(
ValueType));
1956 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(
ValueType));
1960 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
1961 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
1962 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
1964 if (numTiles == 0 && numChildren == 0)
return false;
1967 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1968 if (isChild(i))
continue;
1969 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1970 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(
ValueType));
1971 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
1974 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1975 if (isTile(i))
continue;
1976 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
1977 getChild(i).writeTopology(os, toHalf);
1984 template<
typename ChildT>
1996 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
1998 is.read(reinterpret_cast<char*>(&inside),
sizeof(
ValueType));
2003 Coord rangeMin, rangeMax;
2004 is.read(reinterpret_cast<char*>(rangeMin.asPointer()), 3 *
sizeof(
Int32));
2005 is.read(reinterpret_cast<char*>(rangeMax.asPointer()), 3 *
sizeof(
Int32));
2008 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2010 for (
int i = 0; i < 3; ++i) {
2011 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2012 rangeMin[i] = offset[i] << ChildT::TOTAL;
2014 tableSize += log2Dim[i];
2015 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2017 log2Dim[3] = log2Dim[1] + log2Dim[2];
2018 tableSize = 1U << tableSize;
2026 for (
Index i = 0; i < tableSize; ++i) {
2030 origin[0] = (n >> log2Dim[3]) + offset[0];
2031 n &= (1U << log2Dim[3]) - 1;
2032 origin[1] = (n >> log2Dim[2]) + offset[1];
2033 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2034 origin <<= ChildT::TOTAL;
2036 if (childMask.isOn(i)) {
2038 ChildT* child =
new ChildT(origin, mBackground);
2039 child->readTopology(is);
2040 mTable[origin] = NodeStruct(*child);
2045 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2047 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2056 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
2059 Index numTiles = 0, numChildren = 0;
2060 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2061 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2063 if (numTiles == 0 && numChildren == 0)
return false;
2070 for (
Index n = 0; n < numTiles; ++n) {
2071 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2072 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2073 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2074 mTable[Coord(vec)] = NodeStruct(Tile(value, active));
2078 for (
Index n = 0; n < numChildren; ++n) {
2079 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2081 ChildT* child =
new ChildT(origin, mBackground);
2082 child->readTopology(is, fromHalf);
2083 mTable[Coord(vec)] = NodeStruct(*child);
2090 template<
typename ChildT>
2094 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2095 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2100 template<
typename ChildT>
2104 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2105 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2113 template<
typename ChildT>
2114 template<
typename PruneOp>
2118 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2119 if (this->isTile(i)|| !op(this->getChild(i)))
continue;
2120 this->setTile(i, Tile(op.value, op.state));
2122 this->eraseBackgroundTiles();
2126 template<
typename ChildT>
2135 template<
typename ChildT>
2144 template<
typename ChildT>
2148 this->pruneInactive(mBackground);
2152 template<
typename ChildT>
2164 template<
typename ChildT>
2165 template<
typename NodeT>
2169 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2170 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2172 MapIter iter = this->findCoord(xyz);
2173 if (iter == mTable.end() || isTile(iter))
return NULL;
2174 return (boost::is_same<NodeT, ChildT>::value)
2175 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2176 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2184 template<
typename ChildT>
2188 if (leaf == NULL)
return;
2189 ChildT* child = NULL;
2190 const Coord& xyz = leaf->origin();
2191 MapIter iter = this->findCoord(xyz);
2192 if (iter == mTable.end()) {
2193 if (ChildT::LEVEL>0) {
2194 child =
new ChildT(xyz, mBackground,
false);
2196 child =
reinterpret_cast<ChildT*
>(leaf);
2198 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2199 }
else if (isChild(iter)) {
2200 if (ChildT::LEVEL>0) {
2201 child = &getChild(iter);
2203 child =
reinterpret_cast<ChildT*
>(leaf);
2204 setChild(iter, *child);
2207 if (ChildT::LEVEL>0) {
2208 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2210 child =
reinterpret_cast<ChildT*
>(leaf);
2212 setChild(iter, *child);
2214 child->addLeaf(leaf);
2218 template<
typename ChildT>
2219 template<
typename AccessorT>
2223 if (leaf == NULL)
return;
2224 ChildT* child = NULL;
2225 const Coord& xyz = leaf->origin();
2226 MapIter iter = this->findCoord(xyz);
2227 if (iter == mTable.end()) {
2228 if (ChildT::LEVEL>0) {
2229 child =
new ChildT(xyz, mBackground,
false);
2231 child =
reinterpret_cast<ChildT*
>(leaf);
2233 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2234 }
else if (isChild(iter)) {
2235 if (ChildT::LEVEL>0) {
2236 child = &getChild(iter);
2238 child =
reinterpret_cast<ChildT*
>(leaf);
2239 setChild(iter, *child);
2242 if (ChildT::LEVEL>0) {
2243 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2245 child =
reinterpret_cast<ChildT*
>(leaf);
2247 setChild(iter, *child);
2249 acc.insert(xyz, child);
2250 child->addLeafAndCache(leaf, acc);
2254 template<
typename ChildT>
2259 if (LEVEL >= level) {
2260 MapIter iter = this->findCoord(xyz);
2261 if (iter == mTable.end()) {
2262 if (LEVEL > level) {
2263 ChildT* child =
new ChildT(xyz, mBackground,
false);
2264 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2265 child->addTile(level, xyz, value, state);
2267 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2269 }
else if (isChild(iter)) {
2270 if (LEVEL > level) {
2271 getChild(iter).addTile(level, xyz, value, state);
2273 setTile(iter, Tile(value, state));
2276 if (LEVEL > level) {
2277 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2278 setChild(iter, *child);
2279 child->addTile(level, xyz, value, state);
2281 setTile(iter, Tile(value, state));
2288 template<
typename ChildT>
2289 template<
typename AccessorT>
2292 bool state, AccessorT& acc)
2294 if (LEVEL >= level) {
2295 MapIter iter = this->findCoord(xyz);
2296 if (iter == mTable.end()) {
2297 if (LEVEL > level) {
2298 ChildT* child =
new ChildT(xyz, mBackground,
false);
2299 acc.insert(xyz, child);
2300 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2301 child->addTileAndCache(level, xyz, value, state, acc);
2303 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2305 }
else if (isChild(iter)) {
2306 if (LEVEL > level) {
2307 ChildT* child = &getChild(iter);
2308 acc.insert(xyz, child);
2309 child->addTileAndCache(level, xyz, value, state, acc);
2311 setTile(iter, Tile(value, state));
2314 if (LEVEL > level) {
2315 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2316 acc.insert(xyz, child);
2317 setChild(iter, *child);
2318 child->addTileAndCache(level, xyz, value, state, acc);
2320 setTile(iter, Tile(value, state));
2330 template<
typename ChildT>
2331 inline typename ChildT::LeafNodeType*
2334 ChildT* child = NULL;
2335 MapIter iter = this->findCoord(xyz);
2336 if (iter == mTable.end()) {
2337 child =
new ChildT(xyz, mBackground,
false);
2338 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2339 }
else if (isChild(iter)) {
2340 child = &getChild(iter);
2342 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2343 setChild(iter, *child);
2345 return child->touchLeaf(xyz);
2349 template<
typename ChildT>
2350 template<
typename AccessorT>
2351 inline typename ChildT::LeafNodeType*
2354 ChildT* child = NULL;
2355 MapIter iter = this->findCoord(xyz);
2356 if (iter == mTable.end()) {
2357 child =
new ChildT(xyz, mBackground,
false);
2358 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2359 }
else if (isChild(iter)) {
2360 child = &getChild(iter);
2362 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2363 setChild(iter, *child);
2365 acc.insert(xyz, child);
2366 return child->touchLeafAndCache(xyz, acc);
2373 template<
typename ChildT>
2374 template<
typename NodeT>
2378 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2379 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2381 MapIter iter = this->findCoord(xyz);
2382 if (iter == mTable.end() || isTile(iter))
return NULL;
2383 ChildT* child = &getChild(iter);
2384 return (boost::is_same<NodeT, ChildT>::value)
2385 ?
reinterpret_cast<NodeT*
>(child)
2386 : child->template probeNode<NodeT>(xyz);
2391 template<
typename ChildT>
2392 template<
typename NodeT>
2396 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2397 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2399 MapCIter iter = this->findCoord(xyz);
2400 if (iter == mTable.end() || isTile(iter))
return NULL;
2401 const ChildT* child = &getChild(iter);
2402 return (boost::is_same<NodeT, ChildT>::value)
2403 ?
reinterpret_cast<const NodeT*
>(child)
2404 : child->template probeConstNode<NodeT>(xyz);
2409 template<
typename ChildT>
2410 inline typename ChildT::LeafNodeType*
2413 return this->
template probeNode<LeafNodeType>(xyz);
2417 template<
typename ChildT>
2418 inline const typename ChildT::LeafNodeType*
2421 return this->
template probeConstNode<LeafNodeType>(xyz);
2425 template<
typename ChildT>
2426 template<
typename AccessorT>
2427 inline typename ChildT::LeafNodeType*
2430 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2434 template<
typename ChildT>
2435 template<
typename AccessorT>
2436 inline const typename ChildT::LeafNodeType*
2439 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2443 template<
typename ChildT>
2444 template<
typename AccessorT>
2445 inline const typename ChildT::LeafNodeType*
2448 return this->probeConstLeafAndCache(xyz, acc);
2452 template<
typename ChildT>
2453 template<
typename NodeT,
typename AccessorT>
2457 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2458 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2460 MapIter iter = this->findCoord(xyz);
2461 if (iter == mTable.end() || isTile(iter))
return NULL;
2462 ChildT* child = &getChild(iter);
2463 acc.insert(xyz, child);
2464 return (boost::is_same<NodeT, ChildT>::value)
2465 ?
reinterpret_cast<NodeT*
>(child)
2466 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2471 template<
typename ChildT>
2472 template<
typename NodeT,
typename AccessorT>
2476 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2477 NodeT::LEVEL > ChildT::LEVEL)
return NULL;
2479 MapCIter iter = this->findCoord(xyz);
2480 if (iter == mTable.end() || isTile(iter))
return NULL;
2481 const ChildT* child = &getChild(iter);
2482 acc.insert(xyz, child);
2483 return (boost::is_same<NodeT, ChildT>::value)
2484 ?
reinterpret_cast<const NodeT*
>(child)
2485 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2493 template<
typename ChildT>
2501 template<
typename ChildT>
2505 const ValueType zero = zeroVal<ValueType>();
2507 mBackground = outside;
2511 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2512 if (this->isTile(i))
continue;
2513 getChild(i).signedFloodFill(outside, inside);
2514 nodeKeys.insert(i->first);
2520 const Tile insideTile(inside,
false);
2521 CoordSetCIter b = nodeKeys.begin(), e = nodeKeys.end();
2522 if ( b == e )
return;
2523 for (CoordSetCIter a = b++; b != e; ++a, ++b) {
2525 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(ChildT::DIM))
continue;
2526 MapIter i = mTable.find(*a), j = mTable.find(*b);
2527 const ValueType fill[] = { getChild(i).getLastValue(), getChild(j).getFirstValue() };
2528 if (!(fill[0] < zero) || !(fill[1] < zero))
continue;
2529 for (Coord c = *a + Coord(0u,0u,ChildT::DIM); c[2] != (*b)[2]; c[2] += ChildT::DIM) {
2530 mTable[c] = insideTile;
2539 template<
typename ChildT>
2543 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2544 if (this->isTileOff(i))
continue;
2545 ChildT* child = i->second.child;
2547 child =
new ChildT(i->first, this->getTile(i).value,
true);
2548 i->second.child = child;
2550 child->voxelizeActiveTiles();
2558 template<
typename ChildT>
2559 template<MergePolicy Policy>
2569 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2570 MapIter j = mTable.find(i->first);
2571 if (other.isChild(i)) {
2572 if (j == mTable.end()) {
2573 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2574 child.resetBackground(other.mBackground, mBackground);
2575 mTable[i->first] = NodeStruct(child);
2576 }
else if (isTile(j)) {
2578 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2579 child.resetBackground(other.mBackground, mBackground);
2583 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
2584 other.mBackground, mBackground);
2586 }
else if (other.isTileOn(i)) {
2587 if (j == mTable.end()) {
2588 mTable[i->first] = i->second;
2589 }
else if (!isTileOn(j)) {
2591 setTile(j, Tile(other.getTile(i).value,
true));
2598 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2599 MapIter j = mTable.find(i->first);
2600 if (other.isChild(i)) {
2601 if (j == mTable.end()) {
2602 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2603 child.resetBackground(other.mBackground, mBackground);
2604 mTable[i->first] = NodeStruct(child);
2605 }
else if (isTile(j)) {
2606 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2607 child.resetBackground(other.mBackground, mBackground);
2610 getChild(j).template merge<MERGE_NODES>(
2611 getChild(i), other.mBackground, mBackground);
2618 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2619 MapIter j = mTable.find(i->first);
2620 if (other.isChild(i)) {
2621 if (j == mTable.end()) {
2623 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2624 child.resetBackground(other.mBackground, mBackground);
2625 mTable[i->first] = NodeStruct(child);
2626 }
else if (isTile(j)) {
2628 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2629 child.resetBackground(other.mBackground, mBackground);
2630 const Tile tile = getTile(j);
2634 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2635 tile.value, tile.active);
2639 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
2640 other.mBackground, mBackground);
2642 }
else if (other.isTileOn(i)) {
2643 if (j == mTable.end()) {
2645 mTable[i->first] = i->second;
2646 }
else if (isTileOff(j)) {
2648 setTile(j, Tile(other.getTile(i).value,
true));
2649 }
else if (isChild(j)) {
2651 const Tile& tile = getTile(i);
2652 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
2653 tile.value, tile.active);
2670 template<
typename ChildT>
2671 template<
typename OtherChildType>
2676 typedef typename OtherRootT::MapCIter OtherCIterT;
2678 enforceSameConfiguration(other);
2680 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2681 MapIter j = mTable.find(i->first);
2682 if (other.isChild(i)) {
2683 if (j == mTable.end()) {
2684 mTable[i->first] = NodeStruct(
2685 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
2686 }
else if (this->isChild(j)) {
2687 this->getChild(j).topologyUnion(other.getChild(i));
2689 ChildT* child =
new ChildT(
2690 other.getChild(i), this->getTile(j).value,
TopologyCopy());
2691 if (this->isTileOn(j)) child->setValuesOn();
2692 this->setChild(j, *child);
2694 }
else if (other.isTileOn(i)) {
2695 if (j == mTable.end()) {
2696 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
2697 }
else if (this->isChild(j)) {
2698 this->getChild(j).setValuesOn();
2699 }
else if (this->isTileOff(j)) {
2700 this->setTile(j, Tile(this->getTile(j).value,
true));
2706 template<
typename ChildT>
2707 template<
typename OtherChildType>
2712 typedef typename OtherRootT::MapCIter OtherCIterT;
2714 enforceSameConfiguration(other);
2716 std::set<Coord> tmp;
2717 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2718 OtherCIterT j = other.mTable.find(i->first);
2719 if (this->isChild(i)) {
2720 if (j == other.mTable.end() || other.isTileOff(j)) {
2721 tmp.insert(i->first);
2722 }
else if (other.isChild(j)) {
2723 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
2725 }
else if (this->isTileOn(i)) {
2726 if (j == other.mTable.end() || other.isTileOff(j)) {
2727 this->setTile(i, Tile(this->getTile(i).value,
false));
2728 }
else if (other.isChild(j)) {
2729 ChildT* child =
new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
2730 this->setChild(i, *child);
2734 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) mTable.erase(*i);
2737 template<
typename ChildT>
2738 template<
typename OtherChildType>
2743 typedef typename OtherRootT::MapCIter OtherCIterT;
2745 enforceSameConfiguration(other);
2747 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2748 MapIter j = mTable.find(i->first);
2749 if (other.isChild(i)) {
2750 if (j == mTable.end() || this->isTileOff(j)) {
2752 }
else if (this->isChild(j)) {
2753 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
2754 }
else if (this->isTileOn(j)) {
2756 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
2757 child->topologyDifference(other.getChild(i), mBackground);
2758 this->setChild(j, *child);
2760 }
else if (other.isTileOn(i)) {
2761 if (j == mTable.end() || this->isTileOff(j)) {
2763 }
else if (this->isChild(j)) {
2764 mTable.erase(j->first);
2765 }
else if (this->isTileOn(j)) {
2766 this->setTile(j, Tile(this->getTile(j).value,
false));
2775 template<
typename ChildT>
2776 template<
typename CombineOp>
2783 this->insertKeys(keys);
2784 other.insertKeys(keys);
2786 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2787 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
2788 if (isTile(iter) && isTile(otherIter)) {
2791 op(args.
setARef(getTile(iter).value)
2792 .setAIsActive(isTileOn(iter))
2793 .setBRef(getTile(otherIter).value)
2794 .setBIsActive(isTileOn(otherIter)));
2797 }
else if (isChild(iter) && isTile(otherIter)) {
2799 ChildT& child = getChild(iter);
2800 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
2802 }
else if (isTile(iter) && isChild(otherIter)) {
2807 ChildT& child = getChild(otherIter);
2808 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
2811 setChild(iter, stealChild(otherIter, Tile()));
2815 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
2816 child.combine(otherChild, op);
2818 if (prune && isChild(iter)) getChild(iter).prune();
2822 op(args.
setARef(mBackground).setBRef(other.mBackground));
2823 mBackground = args.
result();
2833 template<
typename ChildT>
2834 template<
typename CombineOp>
2837 CombineOp& op,
bool prune)
2842 other0.insertKeys(keys);
2843 other1.insertKeys(keys);
2846 bg0(Tile(other0.mBackground,
false)),
2847 bg1(Tile(other1.mBackground,
false));
2849 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
2850 MapIter thisIter = this->findOrAddCoord(*i);
2851 MapCIter iter0 = other0.findKey(*i), iter1 = other1.findKey(*i);
2853 &ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0,
2854 &ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
2855 if (ns0.isTile() && ns1.isTile()) {
2858 op(args.
setARef(ns0.tile.value)
2859 .setAIsActive(ns0.isTileOn())
2860 .setBRef(ns1.tile.value)
2861 .setBIsActive(ns1.isTileOn()));
2864 ChildT& otherChild = ns0.isChild() ? *ns0.child : *ns1.child;
2865 if (!isChild(thisIter)) {
2868 *(
new ChildT(otherChild.origin(), getTile(thisIter).value)));
2870 ChildT& child = getChild(thisIter);
2875 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
2876 }
else if (ns1.isTile()) {
2879 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
2883 child.combine2(*ns0.child, *ns1.child, op);
2886 if (prune && isChild(thisIter)) getChild(thisIter).prune();
2890 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
2891 mBackground = args.
result();
2898 template<
typename ChildT>
2899 template<
typename BBoxOp>
2903 const bool descent = op.template descent<LEVEL>();
2904 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2905 if (this->isTileOff(i))
continue;
2906 if (this->isChild(i) && descent) {
2907 this->getChild(i).visitActiveBBox(op);
2910 op.operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
2912 op.template operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
2919 template<
typename ChildT>
2920 template<
typename VisitorOp>
2924 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
2928 template<
typename ChildT>
2929 template<
typename VisitorOp>
2933 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
2937 template<
typename ChildT>
2938 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
2942 typename RootNodeT::ValueType val;
2943 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
2944 if (op(iter))
continue;
2945 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2955 template<
typename ChildT>
2956 template<
typename OtherRootNodeType,
typename VisitorOp>
2961 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
2965 template<
typename ChildT>
2966 template<
typename OtherRootNodeType,
typename VisitorOp>
2971 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
2975 template<
typename ChildT>
2978 typename OtherRootNodeT,
2980 typename ChildAllIterT,
2981 typename OtherChildAllIterT>
2987 enforceSameConfiguration(other);
2989 typename RootNodeT::ValueType val;
2990 typename OtherRootNodeT::ValueType otherVal;
2995 RootNodeT copyOfSelf(
self.mBackground);
2996 copyOfSelf.mTable =
self.mTable;
2997 OtherRootNodeT copyOfOther(other.mBackground);
2998 copyOfOther.mTable = other.mTable;
3002 self.insertKeys(keys);
3003 other.insertKeys(keys);
3004 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3005 copyOfSelf.findOrAddCoord(*i);
3006 copyOfOther.findOrAddCoord(*i);
3009 ChildAllIterT iter = copyOfSelf.beginChildAll();
3010 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3012 for ( ; iter && otherIter; ++iter, ++otherIter)
3014 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3016 typename ChildAllIterT::ChildNodeType* child =
3017 (skipBranch & 1U) ? NULL : iter.probeChild(val);
3018 typename OtherChildAllIterT::ChildNodeType* otherChild =
3019 (skipBranch & 2U) ? NULL : otherIter.probeChild(otherVal);
3021 if (child != NULL && otherChild != NULL) {
3022 child->visit2Node(*otherChild, op);
3023 }
else if (child != NULL) {
3024 child->visit2(otherIter, op);
3025 }
else if (otherChild != NULL) {
3026 otherChild->visit2(iter, op,
true);
3031 copyOfSelf.eraseBackgroundTiles();
3032 copyOfOther.eraseBackgroundTiles();
3036 self.resetTable(copyOfSelf.mTable);
3037 other.resetTable(copyOfOther.mTable);
3044 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:1986
bool isOn(Index32 i) const
Definition: NodeMasks.h:1179
void pruneInactive()
Reduce the memory footprint of this tree by replacing with background tiles any nodes whose values ar...
Definition: RootNode.h:2146
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Expand the specified bbox so it includes the active tiles of this root node as well as all the active...
Definition: RootNode.h:1249
ValueOffIter beginValueOff()
Definition: RootNode.h:386
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of all voxels, both active and inactive, that intersect a given bou...
Definition: RootNode.h:1906
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:366
bool hasActiveTiles() const
Definition: RootNode.h:1428
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:2778
const NodeT * probeConstNodeAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeNode() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:2474
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2411
ChildOffIter beginChildOff()
Definition: RootNode.h:376
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: RootNode.h:1475
~RootNode()
Definition: RootNode.h:119
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:357
int32_t Int32
Definition: Types.h:58
Index64 offVoxelCount() const
Definition: RootNode.h:1362
void signedFloodFill()
Set the values of all inactive voxels and tiles of a narrow-band level set from the signs of the acti...
Definition: RootNode.h:2495
ChildOnCIter beginChildOn() const
Definition: RootNode.h:372
boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:894
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:363
Index64 onVoxelCount() const
Definition: RootNode.h:1346
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1665
Index32 leafCount() const
Definition: RootNode.h:1320
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:359
ValueOnCIter beginValueOn() const
Definition: RootNode.h:382
ChildOnIter beginChildOn()
Definition: RootNode.h:375
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1419
ValueOnIter beginValueOn()
Definition: RootNode.h:385
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:232
uint32_t Index32
Definition: Types.h:54
ChildAllCIter beginChildAll() const
Definition: RootNode.h:374
ChildType::ValueType ValueType
Definition: RootNode.h:69
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Index getWidth() const
Definition: RootNode.h:445
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: RootNode.h:2128
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool state)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
Definition: RootNode.h:2167
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1783
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
void combine2(const RootNode &other0, const RootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:2836
RootNode< typename ChildType::template ValueConverter< OtherValueType >::Type > Type
Definition: RootNode.h:81
static Index getChildDim()
Definition: RootNode.h:440
void pruneOp(PruneOp &)
Definition: RootNode.h:2116
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:369
void addTileAndCache(Index level, const Coord &xyz, const ValueType &, bool state, AccessorT &)
Same as addTile() but, if necessary, update the given accessor with pointers to the nodes along the p...
Definition: RootNode.h:2291
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:379
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() but, if necessary, update the given accessor with pointers to the nodes along the p...
Definition: RootNode.h:2221
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1018
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:85
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1378
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: RootNode.h:1511
void topologyUnion(const RootNode< OtherChildType > &other)
Union this tree's set of active values with the active values of the other tree, whose ValueType may ...
Definition: RootNode.h:2673
void topologyIntersection(const RootNode< OtherChildType > &other)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
Definition: RootNode.h:2709
Index32 nonLeafCount() const
Definition: RootNode.h:1332
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:371
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:365
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1129
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1390
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1497
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:482
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1581
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:370
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:413
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile containing voxel (x, y, z) at the specified tree level, creating a new branch if necessary...
Definition: RootNode.h:2256
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:430
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one that preserves the values and active states of all voxels.
Definition: RootNode.h:2332
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
void load(std::istream &is)
Definition: NodeMasks.h:1220
boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:900
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2561
RootNode(const RootNode &other)
Definition: RootNode.h:91
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1720
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1040
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: RootNode.h:1646
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:361
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:80
#define OPENVDB_VERSION_NAME
Definition: version.h:45
const NodeT * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2394
void addLeaf(LeafNodeType *leaf)
Add the given leaf node to this tree, creating a new branch if necessary. If a leaf node with the sam...
Definition: RootNode.h:2186
void visit(VisitorOp &)
Definition: RootNode.h:2922
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:364
RootNode & operator=(const RootNode &other)
Definition: RootNode.h:970
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:354
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1451
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1223
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:114
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:380
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:61
static Index getLevel()
Definition: RootNode.h:438
ChildType ChildNodeType
Definition: RootNode.h:67
OPENVDB_IMPORT void setGridBackgroundValuePtr(std::ios_base &, const void *background)
Specify (a pointer to) the background value of the grid currently being read from or written to the g...
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1624
ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:68
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2102
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2092
ValueAllIter beginValueAll()
Definition: RootNode.h:387
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:1830
void topologyDifference(const RootNode< OtherChildType > &other)
Difference this tree's set of active values with the active values of the other tree, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this tree and inactive in the other tree.
Definition: RootNode.h:2740
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:401
Helper class for use with Tree::pruneOp() to replace inactive branches with more memory-efficient ina...
Definition: tree/Util.h:74
void pruneTiles(const ValueType &tolerance)
Reduce the memory footprint of this tree by replacing with tiles any non-leaf nodes whose values are ...
Definition: RootNode.h:2154
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1091
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:353
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:431
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:381
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:1950
Definition: NodeMasks.h:917
OPENVDB_DEPRECATED void evalActiveVoxelBoundingBox(CoordBBox &bbox) const
Definition: RootNode.h:1236
bool hasSameTopology(const RootNode< OtherChildType > &other) const
Return true if the given tree has the same node and active value topology as this tree (but possibly ...
Definition: RootNode.h:1142
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1756
Index32 Index
Definition: Types.h:56
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:2958
Helper class for use with Tree::pruneOp() to replace constant branches (to within the provided tolera...
Definition: tree/Util.h:47
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:909
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:362
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:438
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2376
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1114
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:137
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: RootNode.h:1688
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:358
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1534
const ValueType & result() const
Get the output value.
Definition: Types.h:261
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1052
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1485
CombineArgs & setARef(const ValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:269
ChildOffCIter beginChildOff() const
Definition: RootNode.h:373
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1121
ChildAllIter beginChildAll()
Definition: RootNode.h:377
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: RootNode.h:1605
Index getHeight() const
Definition: RootNode.h:446
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1105
Index64 onTileCount() const
Definition: RootNode.h:1401
Definition: RootNode.h:64
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:443
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:2901
Definition: Exceptions.h:87
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1189
bool resultIsActive() const
Definition: Types.h:280
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
void voxelizeActiveTiles()
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2541
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:356
NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:74
uint64_t Index64
Definition: Types.h:55
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:355
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given box to a constant value, if necessary subdividing tiles that intersect ...
Definition: RootNode.h:1850
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
void clear()
Definition: RootNode.h:428
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ValueOffCIter beginValueOff() const
Definition: RootNode.h:383
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1439
void setBackground(const ValueType &value, bool updateChildNodes=true)
Change inactive tiles or voxels with a value equal to +/- the old background to the specified value (...
Definition: RootNode.h:990
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return NULL.
Definition: RootNode.h:2419
Index getDepth() const
Definition: RootNode.h:447
NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:893
NodeT * probeNodeAndCache(const Coord &xyz, AccessorT &acc)
Same as probeNode() but, if necessary, update the given accessor with pointers to the nodes along the...
Definition: RootNode.h:2455
ValueAllCIter beginValueAll() const
Definition: RootNode.h:384
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:1814