8 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 9 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 17 #include <openvdb/version.h> 18 #include <tbb/parallel_for.h> 31 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
37 template<
typename ChildType>
46 static const Index LEVEL = 1 + ChildType::LEVEL;
50 static_assert(NodeChainType::Size == LEVEL + 1,
51 "wrong number of entries in RootNode node chain");
55 template<
typename OtherValueType>
63 template<
typename OtherNodeType>
83 template<
typename OtherChildType>
94 template<
typename OtherChildType>
108 template<
typename OtherChildType>
120 template<
typename OtherChildType>
127 Tile():
value(zeroVal<ValueType>()), active(
false) {}
138 NodeStruct():
child(
nullptr) {}
139 NodeStruct(ChildType& c):
child(&c) {}
140 NodeStruct(
const Tile& t):
child(
nullptr), tile(t) {}
141 NodeStruct(
const NodeStruct&) =
default;
142 NodeStruct& operator=(
const NodeStruct&) =
default;
145 bool isChild()
const {
return child !=
nullptr; }
146 bool isTile()
const {
return child ==
nullptr; }
147 bool isTileOff()
const {
return isTile() && !tile.active; }
148 bool isTileOn()
const {
return isTile() && tile.active; }
150 void set(ChildType& c) {
delete child; child = &c; }
151 void set(
const Tile& t) {
delete child; child =
nullptr; tile = t; }
152 ChildType& steal(
const Tile& t) { ChildType* c=
child; child=
nullptr; tile=t;
return *c; }
155 using MapType = std::map<Coord, NodeStruct>;
156 using MapIter =
typename MapType::iterator;
157 using MapCIter =
typename MapType::const_iterator;
159 using CoordSet = std::set<Coord>;
160 using CoordSetIter =
typename CoordSet::iterator;
161 using CoordSetCIter =
typename CoordSet::const_iterator;
163 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
164 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
165 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
166 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
167 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
168 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
169 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
170 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
172 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
173 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
174 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
175 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
176 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
177 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
178 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
179 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
182 static inline bool test(
const MapIter&) {
return true; }
183 static inline bool test(
const MapCIter&) {
return true; }
186 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
187 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
189 struct ValueOffPred {
190 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
191 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
193 struct ValueAllPred {
194 static inline bool test(
const MapIter& i) {
return isTile(i); }
195 static inline bool test(
const MapCIter& i) {
return isTile(i); }
198 static inline bool test(
const MapIter& i) {
return isChild(i); }
199 static inline bool test(
const MapCIter& i) {
return isChild(i); }
201 struct ChildOffPred {
202 static inline bool test(
const MapIter& i) {
return isTile(i); }
203 static inline bool test(
const MapCIter& i) {
return isTile(i); }
206 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
210 using RootNodeT = _RootNodeT;
211 using MapIterT = _MapIterT;
215 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
217 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
219 RootNodeT* getParentNode()
const {
return mParentNode; }
221 RootNodeT& parent()
const 227 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
228 operator bool()
const {
return this->test(); }
230 void increment() {
if (this->test()) { ++mIter; } this->skip(); }
231 bool next() { this->increment();
return this->test(); }
232 void increment(
Index n) {
for (
Index i = 0; i < n && this->next(); ++i) {} }
238 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
241 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
242 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
243 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
244 void setValueOff()
const { mIter->second.tile.active =
false; }
247 Coord getCoord()
const {
return mIter->first; }
249 void getCoord(Coord& xyz)
const { xyz = this->getCoord(); }
252 BaseIter(): mParentNode(
nullptr) {}
253 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
255 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
257 RootNodeT* mParentNode;
261 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
262 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
265 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
266 using NodeType = RootNodeT;
269 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
270 using NonConstValueType =
typename std::remove_const<ValueType>::type;
271 using NonConstChildNodeType =
typename std::remove_const<ChildNodeType>::type;
275 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
277 ChildIter& operator++() { BaseT::increment();
return *
this; }
279 ChildNodeT& getValue()
const {
return getChild(mIter); }
280 ChildNodeT&
operator*()
const {
return this->getValue(); }
281 ChildNodeT* operator->()
const {
return &this->getValue(); }
284 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
285 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
288 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
289 using NodeType = RootNodeT;
291 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
292 using NonConstValueType =
typename std::remove_const<ValueT>::type;
296 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
298 ValueIter& operator++() { BaseT::increment();
return *
this; }
300 ValueT& getValue()
const {
return getTile(mIter).value; }
301 ValueT&
operator*()
const {
return this->getValue(); }
302 ValueT* operator->()
const {
return &(this->getValue()); }
304 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
306 template<
typename ModifyOp>
307 void modifyValue(
const ModifyOp& op)
const 309 assert(isTile(mIter));
310 op(getTile(mIter).
value);
314 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
315 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
318 using BaseT = BaseIter<RootNodeT, MapIterT, NullPred>;
319 using NodeType = RootNodeT;
322 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
323 using NonConstValueType =
typename std::remove_const<ValueT>::type;
324 using NonConstChildNodeType =
typename std::remove_const<ChildNodeT>::type;
328 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
330 DenseIter& operator++() { BaseT::increment();
return *
this; }
332 bool isChildNode()
const {
return isChild(mIter); }
334 ChildNodeT* probeChild(NonConstValueType&
value)
const 336 if (isChild(mIter))
return &getChild(mIter);
337 value = getTile(mIter).value;
340 bool probeChild(ChildNodeT*&
child, NonConstValueType& value)
const 342 child = this->probeChild(value);
343 return child !=
nullptr;
345 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
347 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
348 void setChild(ChildNodeT* c)
const { assert(c !=
nullptr); RootNodeT::setChild(mIter, *c); }
349 void setValue(
const ValueT& v)
const 351 if (isTile(mIter)) getTile(mIter).value = v;
355 else stealChild(mIter, Tile(v,
true));
360 using ChildOnIter = ChildIter<RootNode, MapIter, ChildOnPred, ChildType>;
361 using ChildOnCIter = ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>;
362 using ChildOffIter = ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>;
363 using ChildOffCIter = ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>;
364 using ChildAllIter = DenseIter<RootNode, MapIter, ChildType, ValueType>;
365 using ChildAllCIter = DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>;
367 using ValueOnIter = ValueIter<RootNode, MapIter, ValueOnPred, ValueType>;
368 using ValueOnCIter = ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>;
369 using ValueOffIter = ValueIter<RootNode, MapIter, ValueOffPred, ValueType>;
370 using ValueOffCIter = ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>;
371 using ValueAllIter = ValueIter<RootNode, MapIter, ValueAllPred, ValueType>;
372 using ValueAllCIter = ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>;
403 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
408 #if OPENVDB_ABI_VERSION_NUMBER >= 9 427 void setBackground(
const ValueType&
value,
bool updateChildNodes);
433 bool isBackgroundTile(
const Tile&)
const;
436 bool isBackgroundTile(
const MapIter&)
const;
437 bool isBackgroundTile(
const MapCIter&)
const;
441 size_t numBackgroundTiles()
const;
444 size_t eraseBackgroundTiles();
448 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
453 bool expand(
const Coord& xyz);
456 static void getNodeLog2Dims(std::vector<Index>& dims);
462 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
463 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
464 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
467 Coord getMinIndex()
const;
469 Coord getMaxIndex()
const;
471 void getIndexRange(
CoordBBox& bbox)
const;
475 template<
typename OtherChildType>
479 template<
typename OtherChildType>
484 template<
typename OtherChildType>
492 Index64 onLeafVoxelCount()
const;
493 Index64 offLeafVoxelCount()
const;
495 void nodeCount(std::vector<Index32> &vec)
const;
497 bool isValueOn(
const Coord& xyz)
const;
500 bool hasActiveTiles()
const;
502 const ValueType& getValue(
const Coord& xyz)
const;
503 bool probeValue(
const Coord& xyz,
ValueType& value)
const;
508 int getValueDepth(
const Coord& xyz)
const;
511 void setActiveState(
const Coord& xyz,
bool on);
513 void setValueOnly(
const Coord& xyz,
const ValueType& value);
515 void setValueOn(
const Coord& xyz,
const ValueType& value);
517 void setValueOff(
const Coord& xyz);
519 void setValueOff(
const Coord& xyz,
const ValueType& value);
523 template<
typename ModifyOp>
524 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
526 template<
typename ModifyOp>
527 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
541 this->fill(bbox, value, active);
562 void voxelizeActiveTiles(
bool threaded =
true);
569 template<
typename DenseT>
576 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
577 bool readTopology(std::istream&,
bool fromHalf =
false);
579 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
580 void readBuffers(std::istream&,
bool fromHalf =
false);
581 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
591 template<
typename AccessorT>
592 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
597 template<
typename AccessorT>
598 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
604 template<
typename AccessorT>
605 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
611 template<
typename AccessorT>
612 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
619 template<
typename ModifyOp,
typename AccessorT>
620 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
626 template<
typename ModifyOp,
typename AccessorT>
627 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
633 template<
typename AccessorT>
634 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
640 template<
typename AccessorT>
641 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
648 template<
typename AccessorT>
649 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
656 template<
typename AccessorT>
657 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
675 template<
typename AccessorT>
686 template<
typename NodeT>
687 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
694 bool addChild(ChildType*
child);
698 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
703 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
707 template<
typename AccessorT>
708 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
719 template<
typename AccessorT>
720 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
725 template <
typename NodeT>
726 NodeT* probeNode(
const Coord& xyz);
727 template <
typename NodeT>
728 const NodeT* probeConstNode(
const Coord& xyz)
const;
734 template<
typename NodeT,
typename AccessorT>
735 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
736 template<
typename NodeT,
typename AccessorT>
737 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
744 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
751 template<
typename AccessorT>
752 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
753 template<
typename AccessorT>
754 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
755 template<
typename AccessorT>
756 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
787 template<
typename ArrayT>
void getNodes(ArrayT& array);
788 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
815 template<
typename ArrayT>
816 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
817 template<
typename ArrayT>
828 template<MergePolicy Policy>
void merge(
RootNode& other);
846 template<
typename OtherChildType>
862 template<
typename OtherChildType>
875 template<
typename OtherChildType>
878 template<
typename CombineOp>
881 template<
typename CombineOp,
typename OtherRootNode >
882 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
883 CombineOp& op,
bool prune =
false);
890 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
892 template<
typename VisitorOp>
void visit(VisitorOp&);
893 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
895 template<
typename OtherRootNodeType,
typename VisitorOp>
896 void visit2(OtherRootNodeType& other, VisitorOp&);
897 template<
typename OtherRootNodeType,
typename VisitorOp>
898 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
912 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
913 void resetTable(
const MapType&)
const {}
916 #if OPENVDB_ABI_VERSION_NUMBER < 8 917 Index getChildCount()
const;
919 Index getTileCount()
const;
920 Index getActiveTileCount()
const;
921 Index getInactiveTileCount()
const;
924 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
927 void insertKeys(CoordSet&)
const;
930 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
934 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
935 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
940 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
941 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
946 MapIter findOrAddCoord(
const Coord& xyz);
952 template<
typename OtherChildType>
960 template<
typename OtherChildType>
963 template<
typename CombineOp,
typename OtherRootNode >
964 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
966 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
967 static inline void doVisit(RootNodeT&, VisitorOp&);
969 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
970 typename ChildAllIterT,
typename OtherChildAllIterT>
971 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
976 #if OPENVDB_ABI_VERSION_NUMBER >= 9 1006 template<
typename HeadT,
int HeadLevel>
1009 using Type =
typename SubtreeT::template Append<HeadT>;
1013 template<
typename HeadT>
1025 template<
typename ChildT1,
typename NodeT2>
1027 static const bool value =
false;
1030 template<
typename ChildT1,
typename ChildT2>
1040 template<
typename ChildT>
1048 template<
typename ChildT>
1056 template<
typename ChildT>
1057 template<
typename OtherChildType>
1061 : mBackground(backgd)
1062 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1063 , mTransientData(other.mTransientData)
1068 enforceSameConfiguration(other);
1070 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1073 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1074 mTable[i->first] = OtherRootT::isTile(i)
1075 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1076 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1081 template<
typename ChildT>
1082 template<
typename OtherChildType>
1086 : mBackground(backgd)
1087 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1088 , mTransientData(other.mTransientData)
1093 enforceSameConfiguration(other);
1095 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1097 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1098 mTable[i->first] = OtherRootT::isTile(i)
1099 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1100 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1111 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1118 self.enforceSameConfiguration(other);
1119 self.enforceCompatibleValueTypes(other);
1121 std::ostringstream ostr;
1122 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1123 <<
" to a " <<
typeid(RootT).name();
1129 template<
typename RootT,
typename OtherRootT>
1134 using ValueT =
typename RootT::ValueType;
1135 using ChildT =
typename RootT::ChildNodeType;
1136 using NodeStruct =
typename RootT::NodeStruct;
1137 using Tile =
typename RootT::Tile;
1138 using OtherValueT =
typename OtherRootT::ValueType;
1139 using OtherMapCIter =
typename OtherRootT::MapCIter;
1140 using OtherTile =
typename OtherRootT::Tile;
1144 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1147 self.mBackground = Local::convertValue(other.mBackground);
1148 #if OPENVDB_ABI_VERSION_NUMBER >= 9 1149 self.mTransientData = other.mTransientData;
1155 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1156 if (other.isTile(i)) {
1158 const OtherTile& otherTile = other.getTile(i);
1159 self.mTable[i->first] = NodeStruct(
1160 Tile(Local::convertValue(otherTile.value), otherTile.active));
1163 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1171 template<
typename ChildT>
1175 if (&other !=
this) {
1176 mBackground = other.mBackground;
1177 #if OPENVDB_ABI_VERSION_NUMBER >= 9 1178 mTransientData = other.mTransientData;
1184 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1186 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1193 template<
typename ChildT>
1194 template<
typename OtherChildType>
1199 using OtherValueT =
typename OtherRootT::ValueType;
1209 template<
typename ChildT>
1215 if (updateChildNodes) {
1218 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1219 ChildT *child = iter->second.child;
1221 child->resetBackground(mBackground, background);
1223 Tile& tile = getTile(iter);
1224 if (tile.active)
continue;
1236 template<
typename ChildT>
1243 template<
typename ChildT>
1250 template<
typename ChildT>
1258 template<
typename ChildT>
1263 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1270 template<
typename ChildT>
1274 std::set<Coord> keysToErase;
1275 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1278 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1281 return keysToErase.size();
1288 template<
typename ChildT>
1292 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1293 keys.insert(i->first);
1298 template<
typename ChildT>
1299 inline typename RootNode<ChildT>::MapIter
1302 const Coord key = coordToKey(xyz);
1303 std::pair<MapIter, bool> result = mTable.insert(
1304 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1305 return result.first;
1309 template<
typename ChildT>
1313 const Coord key = coordToKey(xyz);
1314 std::pair<MapIter, bool> result = mTable.insert(
1315 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1316 return result.second;
1323 template<
typename ChildT>
1328 ChildT::getNodeLog2Dims(dims);
1332 template<
typename ChildT>
1336 return mTable.empty() ? Coord(0) : mTable.begin()->first;
1339 template<
typename ChildT>
1343 return mTable.empty() ? Coord(0) : mTable.rbegin()->first + Coord(ChildT::DIM - 1);
1347 template<
typename ChildT>
1359 template<
typename ChildT>
1360 template<
typename OtherChildType>
1365 using OtherMapT =
typename OtherRootT::MapType;
1366 using OtherIterT =
typename OtherRootT::MapIter;
1367 using OtherCIterT =
typename OtherRootT::MapCIter;
1372 OtherMapT copyOfOtherTable = other.mTable;
1375 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1379 OtherCIterT otherIter = other.findKey(thisIter->first);
1380 if (otherIter == other.mTable.end())
return false;
1383 if (isChild(thisIter)) {
1384 if (OtherRootT::isTile(otherIter))
return false;
1386 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1388 if (OtherRootT::isChild(otherIter))
return false;
1389 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1396 copyOfOtherTable.erase(otherIter->first);
1399 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1406 template<
typename ChildT>
1407 template<
typename OtherChildType>
1411 std::vector<Index> thisDims, otherDims;
1414 return (thisDims == otherDims);
1418 template<
typename ChildT>
1419 template<
typename OtherChildType>
1423 std::vector<Index> thisDims, otherDims;
1426 if (thisDims != otherDims) {
1427 std::ostringstream ostr;
1428 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1429 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1430 ostr <<
" vs. " << otherDims[0];
1431 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1438 template<
typename ChildT>
1439 template<
typename OtherChildType>
1443 using OtherValueType =
typename OtherChildType::ValueType;
1448 template<
typename ChildT>
1449 template<
typename OtherChildType>
1453 using OtherValueType =
typename OtherChildType::ValueType;
1455 std::ostringstream ostr;
1456 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1457 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1466 template<
typename ChildT>
1471 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1472 if (
const ChildT *child = iter->second.child) {
1473 sum += child->memUsage();
1480 template<
typename ChildT>
1484 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1485 delete i->second.child;
1491 template<
typename ChildT>
1495 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1496 if (
const ChildT *child = iter->second.child) {
1497 child->evalActiveBoundingBox(bbox, visitVoxels);
1498 }
else if (isTileOn(iter)) {
1499 bbox.expand(iter->first, ChildT::DIM);
1505 #if OPENVDB_ABI_VERSION_NUMBER < 8 1506 template<
typename ChildT>
1514 template<
typename ChildT>
1519 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1520 if (isTile(i)) ++sum;
1526 template<
typename ChildT>
1531 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1532 if (isTileOn(i)) ++sum;
1538 template<
typename ChildT>
1543 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1544 if (isTileOff(i)) ++sum;
1550 template<
typename ChildT>
1555 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1556 if (isChild(i)) sum += getChild(i).leafCount();
1562 template<
typename ChildT>
1567 if (ChildT::LEVEL != 0) {
1568 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1569 if (isChild(i)) sum += getChild(i).nonLeafCount();
1576 template<
typename ChildT>
1581 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1582 if (isChild(i)) ++sum;
1588 template<
typename ChildT>
1593 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1595 sum += getChild(i).onVoxelCount();
1596 }
else if (isTileOn(i)) {
1597 sum += ChildT::NUM_VOXELS;
1604 template<
typename ChildT>
1609 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1611 sum += getChild(i).offVoxelCount();
1613 sum += ChildT::NUM_VOXELS;
1620 template<
typename ChildT>
1625 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1626 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1632 template<
typename ChildT>
1637 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1638 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1643 template<
typename ChildT>
1648 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1650 sum += getChild(i).onTileCount();
1651 }
else if (isTileOn(i)) {
1658 template<
typename ChildT>
1662 assert(vec.size() >
LEVEL);
1664 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1667 getChild(i).nodeCount(vec);
1671 vec[ChildNodeType::LEVEL] = sum;
1677 template<
typename ChildT>
1681 MapCIter iter = this->findCoord(xyz);
1682 if (iter == mTable.end() || isTileOff(iter))
return false;
1683 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1686 template<
typename ChildT>
1690 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1691 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1696 template<
typename ChildT>
1697 template<
typename AccessorT>
1701 MapCIter iter = this->findCoord(xyz);
1702 if (iter == mTable.end() || isTileOff(iter))
return false;
1703 if (isTileOn(iter))
return true;
1704 acc.insert(xyz, &getChild(iter));
1705 return getChild(iter).isValueOnAndCache(xyz, acc);
1709 template<
typename ChildT>
1710 inline const typename ChildT::ValueType&
1713 MapCIter iter = this->findCoord(xyz);
1714 return iter == mTable.end() ? mBackground
1715 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1718 template<
typename ChildT>
1719 template<
typename AccessorT>
1720 inline const typename ChildT::ValueType&
1723 MapCIter iter = this->findCoord(xyz);
1724 if (iter == mTable.end())
return mBackground;
1725 if (isChild(iter)) {
1726 acc.insert(xyz, &getChild(iter));
1727 return getChild(iter).getValueAndCache(xyz, acc);
1729 return getTile(iter).value;
1733 template<
typename ChildT>
1737 MapCIter iter = this->findCoord(xyz);
1738 return iter == mTable.end() ? -1
1739 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1742 template<
typename ChildT>
1743 template<
typename AccessorT>
1747 MapCIter iter = this->findCoord(xyz);
1748 if (iter == mTable.end())
return -1;
1749 if (isTile(iter))
return 0;
1750 acc.insert(xyz, &getChild(iter));
1751 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1755 template<
typename ChildT>
1759 MapIter iter = this->findCoord(xyz);
1760 if (iter != mTable.end() && !isTileOff(iter)) {
1761 if (isTileOn(iter)) {
1762 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1764 getChild(iter).setValueOff(xyz);
1769 template<
typename ChildT>
1773 ChildT* child =
nullptr;
1774 MapIter iter = this->findCoord(xyz);
1775 if (iter == mTable.end()) {
1777 child =
new ChildT(xyz, mBackground);
1778 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1782 }
else if (isChild(iter)) {
1783 child = &getChild(iter);
1784 }
else if (on != getTile(iter).active) {
1785 child =
new ChildT(xyz, getTile(iter).value, !on);
1786 setChild(iter, *child);
1788 if (child) child->setActiveState(xyz, on);
1791 template<
typename ChildT>
1792 template<
typename AccessorT>
1796 ChildT* child =
nullptr;
1797 MapIter iter = this->findCoord(xyz);
1798 if (iter == mTable.end()) {
1800 child =
new ChildT(xyz, mBackground);
1801 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1805 }
else if (isChild(iter)) {
1806 child = &getChild(iter);
1807 }
else if (on != getTile(iter).active) {
1808 child =
new ChildT(xyz, getTile(iter).value, !on);
1809 setChild(iter, *child);
1812 acc.insert(xyz, child);
1813 child->setActiveStateAndCache(xyz, on, acc);
1818 template<
typename ChildT>
1822 ChildT* child =
nullptr;
1823 MapIter iter = this->findCoord(xyz);
1824 if (iter == mTable.end()) {
1826 child =
new ChildT(xyz, mBackground);
1827 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1829 }
else if (isChild(iter)) {
1830 child = &getChild(iter);
1832 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1833 setChild(iter, *child);
1835 if (child) child->setValueOff(xyz, value);
1838 template<
typename ChildT>
1839 template<
typename AccessorT>
1843 ChildT* child =
nullptr;
1844 MapIter iter = this->findCoord(xyz);
1845 if (iter == mTable.end()) {
1847 child =
new ChildT(xyz, mBackground);
1848 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1850 }
else if (isChild(iter)) {
1851 child = &getChild(iter);
1853 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1854 setChild(iter, *child);
1857 acc.insert(xyz, child);
1858 child->setValueOffAndCache(xyz, value, acc);
1863 template<
typename ChildT>
1867 ChildT* child =
nullptr;
1868 MapIter iter = this->findCoord(xyz);
1869 if (iter == mTable.end()) {
1870 child =
new ChildT(xyz, mBackground);
1871 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1872 }
else if (isChild(iter)) {
1873 child = &getChild(iter);
1875 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1876 setChild(iter, *child);
1878 if (child) child->setValueOn(xyz, value);
1881 template<
typename ChildT>
1882 template<
typename AccessorT>
1886 ChildT* child =
nullptr;
1887 MapIter iter = this->findCoord(xyz);
1888 if (iter == mTable.end()) {
1889 child =
new ChildT(xyz, mBackground);
1890 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1891 }
else if (isChild(iter)) {
1892 child = &getChild(iter);
1894 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1895 setChild(iter, *child);
1898 acc.insert(xyz, child);
1899 child->setValueAndCache(xyz, value, acc);
1904 template<
typename ChildT>
1908 ChildT* child =
nullptr;
1909 MapIter iter = this->findCoord(xyz);
1910 if (iter == mTable.end()) {
1911 child =
new ChildT(xyz, mBackground);
1912 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1913 }
else if (isChild(iter)) {
1914 child = &getChild(iter);
1916 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1917 setChild(iter, *child);
1919 if (child) child->setValueOnly(xyz, value);
1922 template<
typename ChildT>
1923 template<
typename AccessorT>
1927 ChildT* child =
nullptr;
1928 MapIter iter = this->findCoord(xyz);
1929 if (iter == mTable.end()) {
1930 child =
new ChildT(xyz, mBackground);
1931 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1932 }
else if (isChild(iter)) {
1933 child = &getChild(iter);
1935 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1936 setChild(iter, *child);
1939 acc.insert(xyz, child);
1940 child->setValueOnlyAndCache(xyz, value, acc);
1945 template<
typename ChildT>
1946 template<
typename ModifyOp>
1950 ChildT* child =
nullptr;
1951 MapIter iter = this->findCoord(xyz);
1952 if (iter == mTable.end()) {
1953 child =
new ChildT(xyz, mBackground);
1954 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1955 }
else if (isChild(iter)) {
1956 child = &getChild(iter);
1960 bool createChild = isTileOff(iter);
1964 const ValueType& tileVal = getTile(iter).value;
1970 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1971 setChild(iter, *child);
1974 if (child) child->modifyValue(xyz, op);
1977 template<
typename ChildT>
1978 template<
typename ModifyOp,
typename AccessorT>
1982 ChildT* child =
nullptr;
1983 MapIter iter = this->findCoord(xyz);
1984 if (iter == mTable.end()) {
1985 child =
new ChildT(xyz, mBackground);
1986 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1987 }
else if (isChild(iter)) {
1988 child = &getChild(iter);
1992 bool createChild = isTileOff(iter);
1996 const ValueType& tileVal = getTile(iter).value;
2002 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2003 setChild(iter, *child);
2007 acc.insert(xyz, child);
2008 child->modifyValueAndCache(xyz, op, acc);
2013 template<
typename ChildT>
2014 template<
typename ModifyOp>
2018 ChildT* child =
nullptr;
2019 MapIter iter = this->findCoord(xyz);
2020 if (iter == mTable.end()) {
2021 child =
new ChildT(xyz, mBackground);
2022 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2023 }
else if (isChild(iter)) {
2024 child = &getChild(iter);
2026 const Tile& tile = getTile(iter);
2027 bool modifiedState = tile.active;
2029 op(modifiedVal, modifiedState);
2033 child =
new ChildT(xyz, tile.value, tile.active);
2034 setChild(iter, *child);
2037 if (child) child->modifyValueAndActiveState(xyz, op);
2040 template<
typename ChildT>
2041 template<
typename ModifyOp,
typename AccessorT>
2044 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2046 ChildT* child =
nullptr;
2047 MapIter iter = this->findCoord(xyz);
2048 if (iter == mTable.end()) {
2049 child =
new ChildT(xyz, mBackground);
2050 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2051 }
else if (isChild(iter)) {
2052 child = &getChild(iter);
2054 const Tile& tile = getTile(iter);
2055 bool modifiedState = tile.active;
2057 op(modifiedVal, modifiedState);
2061 child =
new ChildT(xyz, tile.value, tile.active);
2062 setChild(iter, *child);
2066 acc.insert(xyz, child);
2067 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2072 template<
typename ChildT>
2076 MapCIter iter = this->findCoord(xyz);
2077 if (iter == mTable.end()) {
2078 value = mBackground;
2080 }
else if (isChild(iter)) {
2081 return getChild(iter).probeValue(xyz, value);
2083 value = getTile(iter).value;
2084 return isTileOn(iter);
2087 template<
typename ChildT>
2088 template<
typename AccessorT>
2092 MapCIter iter = this->findCoord(xyz);
2093 if (iter == mTable.end()) {
2094 value = mBackground;
2096 }
else if (isChild(iter)) {
2097 acc.insert(xyz, &getChild(iter));
2098 return getChild(iter).probeValueAndCache(xyz, value, acc);
2100 value = getTile(iter).value;
2101 return isTileOn(iter);
2108 template<
typename ChildT>
2112 if (bbox.empty())
return;
2117 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2119 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2121 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2125 Coord tileMin = coordToKey(xyz);
2126 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2128 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
2132 ChildT* child =
nullptr;
2133 MapIter iter = this->findKey(tileMin);
2134 if (iter == mTable.end()) {
2137 child =
new ChildT(xyz, mBackground);
2138 mTable[tileMin] = NodeStruct(*child);
2139 }
else if (isTile(iter)) {
2142 const Tile& tile = getTile(iter);
2143 child =
new ChildT(xyz, tile.value, tile.active);
2144 mTable[tileMin] = NodeStruct(*child);
2145 }
else if (isChild(iter)) {
2146 child = &getChild(iter);
2151 child->fill(
CoordBBox(xyz, tmp), value, active);
2157 MapIter iter = this->findOrAddCoord(tileMin);
2158 setTile(iter, Tile(value, active));
2166 template<
typename ChildT>
2170 if (bbox.empty())
return;
2172 if (active && mTable.empty()) {
2182 Coord xyz, tileMin, tileMax;
2183 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2185 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2187 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2191 tileMin = coordToKey(xyz);
2192 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2196 const auto iter = findOrAddCoord(tileMin);
2201 const auto& tile = getTile(iter);
2202 auto* child =
new ChildT{tileMin, tile.value, tile.active};
2203 setChild(iter, *child);
2206 getChild(iter).denseFill(bbox, value, active);
2216 template<
typename ChildT>
2224 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2225 if (this->isTileOff(i))
continue;
2226 ChildT* child = i->second.child;
2227 if (child ==
nullptr) {
2230 child =
new ChildT{i->first, this->getTile(i).value,
true};
2231 i->second.child =
child;
2233 child->voxelizeActiveTiles(threaded);
2241 template<
typename ChildT>
2242 template<
typename DenseT>
2246 using DenseValueType =
typename DenseT::ValueType;
2248 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2249 const Coord&
min = dense.bbox().min();
2251 for (Coord xyz = bbox.min(); xyz[0] <= bbox.max()[0]; xyz[0] = nodeBBox.max()[0] + 1) {
2252 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] = nodeBBox.max()[1] + 1) {
2253 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] = nodeBBox.max()[2] + 1) {
2256 nodeBBox = CoordBBox::createCube(coordToKey(xyz), ChildT::DIM);
2261 MapCIter iter = this->findKey(nodeBBox.min());
2262 if (iter != mTable.end() && isChild(iter)) {
2263 getChild(iter).copyToDense(sub, dense);
2265 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2266 sub.translate(-min);
2267 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2268 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2269 DenseValueType* a1 = a0 + x*xStride;
2270 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2271 DenseValueType* a2 = a1 + y*yStride;
2272 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
2273 *a2 = DenseValueType(value);
2286 template<
typename ChildT>
2291 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(
ValueType));
2294 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(
ValueType));
2298 const Index numTiles = this->getTileCount(), numChildren = this->
childCount();
2299 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
2300 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
2302 if (numTiles == 0 && numChildren == 0)
return false;
2305 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2306 if (isChild(i))
continue;
2307 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2308 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(
ValueType));
2309 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
2312 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2313 if (isTile(i))
continue;
2314 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2315 getChild(i).writeTopology(os, toHalf);
2322 template<
typename ChildT>
2334 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
2336 is.read(reinterpret_cast<char*>(&inside),
sizeof(
ValueType));
2341 Coord rangeMin, rangeMax;
2342 is.read(reinterpret_cast<char*>(rangeMin.asPointer()), 3 *
sizeof(
Int32));
2343 is.read(reinterpret_cast<char*>(rangeMax.asPointer()), 3 *
sizeof(
Int32));
2346 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2348 for (
int i = 0; i < 3; ++i) {
2349 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2350 rangeMin[i] = offset[i] << ChildT::TOTAL;
2352 tableSize += log2Dim[i];
2353 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2355 log2Dim[3] = log2Dim[1] + log2Dim[2];
2356 tableSize = 1U << tableSize;
2364 for (
Index i = 0; i < tableSize; ++i) {
2368 origin[0] = (n >> log2Dim[3]) + offset[0];
2369 n &= (1U << log2Dim[3]) - 1;
2370 origin[1] = (n >> log2Dim[2]) + offset[1];
2371 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2372 origin <<= ChildT::TOTAL;
2374 if (childMask.isOn(i)) {
2376 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2377 child->readTopology(is);
2378 mTable[origin] = NodeStruct(*child);
2383 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2385 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2394 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
2397 Index numTiles = 0, numChildren = 0;
2398 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2399 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2401 if (numTiles == 0 && numChildren == 0)
return false;
2408 for (
Index n = 0; n < numTiles; ++n) {
2409 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2410 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2411 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2412 mTable[Coord(vec)] = NodeStruct(Tile(value, active));
2416 for (
Index n = 0; n < numChildren; ++n) {
2417 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2419 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2420 child->readTopology(is, fromHalf);
2421 mTable[Coord(vec)] = NodeStruct(*child);
2428 template<
typename ChildT>
2432 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2433 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2438 template<
typename ChildT>
2442 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2443 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2448 template<
typename ChildT>
2452 const Tile bgTile(mBackground,
false);
2454 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2460 ChildT& child = getChild(i);
2461 child.readBuffers(is, clipBBox, fromHalf);
2465 this->
clip(clipBBox);
2472 template<
typename ChildT>
2476 const Tile bgTile(mBackground,
false);
2480 MapType copyOfTable(mTable);
2481 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2482 const Coord& xyz = i->first;
2483 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
2484 if (!clipBBox.hasOverlap(tileBBox)) {
2486 setTile(this->findCoord(xyz), bgTile);
2488 }
else if (!clipBBox.isInside(tileBBox)) {
2492 getChild(i).clip(clipBBox, mBackground);
2496 tileBBox.intersect(clipBBox);
2497 const Tile& origTile = getTile(i);
2498 setTile(this->findCoord(xyz), bgTile);
2499 this->
sparseFill(tileBBox, origTile.value, origTile.active);
2512 template<
typename ChildT>
2518 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2519 if (this->isTile(i))
continue;
2520 this->getChild(i).prune(tolerance);
2521 if (this->getChild(i).isConstant(value, state, tolerance)) {
2522 this->setTile(i, Tile(value, state));
2532 template<
typename ChildT>
2533 template<
typename NodeT>
2538 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2540 MapIter iter = this->findCoord(xyz);
2541 if (iter == mTable.end() || isTile(iter))
return nullptr;
2543 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2544 : getChild(iter).template stealNode<NodeT>(xyz,
value, state);
2552 template<
typename ChildT>
2556 if (leaf ==
nullptr)
return;
2557 ChildT* child =
nullptr;
2558 const Coord& xyz = leaf->origin();
2559 MapIter iter = this->findCoord(xyz);
2560 if (iter == mTable.end()) {
2561 if (ChildT::LEVEL>0) {
2562 child =
new ChildT(xyz, mBackground,
false);
2564 child =
reinterpret_cast<ChildT*
>(leaf);
2566 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2567 }
else if (isChild(iter)) {
2568 if (ChildT::LEVEL>0) {
2569 child = &getChild(iter);
2571 child =
reinterpret_cast<ChildT*
>(leaf);
2572 setChild(iter, *child);
2575 if (ChildT::LEVEL>0) {
2576 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2578 child =
reinterpret_cast<ChildT*
>(leaf);
2580 setChild(iter, *child);
2582 child->addLeaf(leaf);
2586 template<
typename ChildT>
2587 template<
typename AccessorT>
2591 if (leaf ==
nullptr)
return;
2592 ChildT* child =
nullptr;
2593 const Coord& xyz = leaf->origin();
2594 MapIter iter = this->findCoord(xyz);
2595 if (iter == mTable.end()) {
2596 if (ChildT::LEVEL>0) {
2597 child =
new ChildT(xyz, mBackground,
false);
2599 child =
reinterpret_cast<ChildT*
>(leaf);
2601 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2602 }
else if (isChild(iter)) {
2603 if (ChildT::LEVEL>0) {
2604 child = &getChild(iter);
2606 child =
reinterpret_cast<ChildT*
>(leaf);
2607 setChild(iter, *child);
2610 if (ChildT::LEVEL>0) {
2611 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2613 child =
reinterpret_cast<ChildT*
>(leaf);
2615 setChild(iter, *child);
2617 acc.insert(xyz, child);
2618 child->addLeafAndCache(leaf, acc);
2621 template<
typename ChildT>
2625 if (!child)
return false;
2626 const Coord& xyz = child->origin();
2627 MapIter iter = this->findCoord(xyz);
2628 if (iter == mTable.end()) {
2629 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2631 setChild(iter, *child);
2636 template<
typename ChildT>
2640 MapIter iter = this->findCoord(xyz);
2641 if (iter == mTable.end()) {
2642 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2644 setTile(iter, Tile(value, state));
2648 template<
typename ChildT>
2653 if (LEVEL >= level) {
2654 MapIter iter = this->findCoord(xyz);
2655 if (iter == mTable.end()) {
2656 if (LEVEL > level) {
2657 ChildT* child =
new ChildT(xyz, mBackground,
false);
2658 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2659 child->addTile(level, xyz, value, state);
2661 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2663 }
else if (isChild(iter)) {
2664 if (LEVEL > level) {
2665 getChild(iter).addTile(level, xyz, value, state);
2667 setTile(iter, Tile(value, state));
2670 if (LEVEL > level) {
2671 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2672 setChild(iter, *child);
2673 child->addTile(level, xyz, value, state);
2675 setTile(iter, Tile(value, state));
2682 template<
typename ChildT>
2683 template<
typename AccessorT>
2686 bool state, AccessorT& acc)
2688 if (LEVEL >= level) {
2689 MapIter iter = this->findCoord(xyz);
2690 if (iter == mTable.end()) {
2691 if (LEVEL > level) {
2692 ChildT* child =
new ChildT(xyz, mBackground,
false);
2693 acc.insert(xyz, child);
2694 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2695 child->addTileAndCache(level, xyz, value, state, acc);
2697 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2699 }
else if (isChild(iter)) {
2700 if (LEVEL > level) {
2701 ChildT* child = &getChild(iter);
2702 acc.insert(xyz, child);
2703 child->addTileAndCache(level, xyz, value, state, acc);
2705 setTile(iter, Tile(value, state));
2708 if (LEVEL > level) {
2709 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2710 acc.insert(xyz, child);
2711 setChild(iter, *child);
2712 child->addTileAndCache(level, xyz, value, state, acc);
2714 setTile(iter, Tile(value, state));
2724 template<
typename ChildT>
2725 inline typename ChildT::LeafNodeType*
2728 ChildT* child =
nullptr;
2729 MapIter iter = this->findCoord(xyz);
2730 if (iter == mTable.end()) {
2731 child =
new ChildT(xyz, mBackground,
false);
2732 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2733 }
else if (isChild(iter)) {
2734 child = &getChild(iter);
2736 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2737 setChild(iter, *child);
2739 return child->touchLeaf(xyz);
2743 template<
typename ChildT>
2744 template<
typename AccessorT>
2745 inline typename ChildT::LeafNodeType*
2748 ChildT* child =
nullptr;
2749 MapIter iter = this->findCoord(xyz);
2750 if (iter == mTable.end()) {
2751 child =
new ChildT(xyz, mBackground,
false);
2752 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2753 }
else if (isChild(iter)) {
2754 child = &getChild(iter);
2756 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2757 setChild(iter, *child);
2759 acc.insert(xyz, child);
2760 return child->touchLeafAndCache(xyz, acc);
2767 template<
typename ChildT>
2768 template<
typename NodeT>
2773 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2775 MapIter iter = this->findCoord(xyz);
2776 if (iter == mTable.end() || isTile(iter))
return nullptr;
2777 ChildT* child = &getChild(iter);
2779 ?
reinterpret_cast<NodeT*
>(
child)
2780 : child->template probeNode<NodeT>(xyz);
2785 template<
typename ChildT>
2786 template<
typename NodeT>
2791 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2793 MapCIter iter = this->findCoord(xyz);
2794 if (iter == mTable.end() || isTile(iter))
return nullptr;
2795 const ChildT* child = &getChild(iter);
2797 ?
reinterpret_cast<const NodeT*
>(
child)
2798 : child->template probeConstNode<NodeT>(xyz);
2803 template<
typename ChildT>
2804 inline typename ChildT::LeafNodeType*
2807 return this->
template probeNode<LeafNodeType>(xyz);
2811 template<
typename ChildT>
2812 inline const typename ChildT::LeafNodeType*
2815 return this->
template probeConstNode<LeafNodeType>(xyz);
2819 template<
typename ChildT>
2820 template<
typename AccessorT>
2821 inline typename ChildT::LeafNodeType*
2824 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2828 template<
typename ChildT>
2829 template<
typename AccessorT>
2830 inline const typename ChildT::LeafNodeType*
2833 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2837 template<
typename ChildT>
2838 template<
typename AccessorT>
2839 inline const typename ChildT::LeafNodeType*
2846 template<
typename ChildT>
2847 template<
typename NodeT,
typename AccessorT>
2852 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2854 MapIter iter = this->findCoord(xyz);
2855 if (iter == mTable.end() || isTile(iter))
return nullptr;
2856 ChildT* child = &getChild(iter);
2857 acc.insert(xyz, child);
2859 ?
reinterpret_cast<NodeT*
>(
child)
2860 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2865 template<
typename ChildT>
2866 template<
typename NodeT,
typename AccessorT>
2871 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2873 MapCIter iter = this->findCoord(xyz);
2874 if (iter == mTable.end() || isTile(iter))
return nullptr;
2875 const ChildT* child = &getChild(iter);
2876 acc.insert(xyz, child);
2878 ?
reinterpret_cast<const NodeT*
>(
child)
2879 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2886 template<
typename ChildT>
2887 template<
typename ArrayT>
2891 using NodePtr =
typename ArrayT::value_type;
2893 "argument to getNodes() must be a pointer array");
2894 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2895 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2896 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2897 "can't extract non-const nodes from a const tree");
2898 using ArrayChildT =
typename std::conditional<
2901 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2902 if (ChildT* child = iter->second.child) {
2905 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2907 child->getNodes(array);
2914 template<
typename ChildT>
2915 template<
typename ArrayT>
2919 using NodePtr =
typename ArrayT::value_type;
2921 "argument to getNodes() must be a pointer array");
2922 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2924 "argument to getNodes() must be an array of const node pointers");
2925 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2926 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2927 "can't extract non-const nodes from a const tree");
2929 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2933 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2935 child->getNodes(array);
2944 template<
typename ChildT>
2945 template<
typename ArrayT>
2949 using NodePtr =
typename ArrayT::value_type;
2951 "argument to stealNodes() must be a pointer array");
2952 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2953 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2954 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2955 "can't extract non-const nodes from a const tree");
2956 using ArrayChildT =
typename std::conditional<
2959 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2960 if (ChildT* child = iter->second.child) {
2963 array.push_back(reinterpret_cast<NodePtr>(&stealChild(iter, Tile(value, state))));
2965 child->stealNodes(array, value, state);
2976 template<
typename ChildT>
2977 template<MergePolicy Policy>
2987 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2988 MapIter j = mTable.find(i->first);
2989 if (other.isChild(i)) {
2990 if (j == mTable.end()) {
2991 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2992 child.resetBackground(other.mBackground, mBackground);
2993 mTable[i->first] = NodeStruct(child);
2994 }
else if (isTile(j)) {
2996 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2997 child.resetBackground(other.mBackground, mBackground);
3001 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
3002 other.mBackground, mBackground);
3004 }
else if (other.isTileOn(i)) {
3005 if (j == mTable.end()) {
3006 mTable[i->first] = i->second;
3007 }
else if (!isTileOn(j)) {
3009 setTile(j, Tile(other.getTile(i).value,
true));
3016 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3017 MapIter j = mTable.find(i->first);
3018 if (other.isChild(i)) {
3019 if (j == mTable.end()) {
3020 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3021 child.resetBackground(other.mBackground, mBackground);
3022 mTable[i->first] = NodeStruct(child);
3023 }
else if (isTile(j)) {
3024 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3025 child.resetBackground(other.mBackground, mBackground);
3028 getChild(j).template merge<MERGE_NODES>(
3029 getChild(i), other.mBackground, mBackground);
3036 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3037 MapIter j = mTable.find(i->first);
3038 if (other.isChild(i)) {
3039 if (j == mTable.end()) {
3041 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3042 child.resetBackground(other.mBackground, mBackground);
3043 mTable[i->first] = NodeStruct(child);
3044 }
else if (isTile(j)) {
3046 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3047 child.resetBackground(other.mBackground, mBackground);
3048 const Tile tile = getTile(j);
3052 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3053 tile.value, tile.active);
3057 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
3058 other.mBackground, mBackground);
3060 }
else if (other.isTileOn(i)) {
3061 if (j == mTable.end()) {
3063 mTable[i->first] = i->second;
3064 }
else if (isTileOff(j)) {
3066 setTile(j, Tile(other.getTile(i).value,
true));
3067 }
else if (isChild(j)) {
3069 const Tile& tile = getTile(i);
3070 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3071 tile.value, tile.active);
3088 template<
typename ChildT>
3089 template<
typename OtherChildType>
3094 using OtherCIterT =
typename OtherRootT::MapCIter;
3096 enforceSameConfiguration(other);
3098 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3099 MapIter j = mTable.find(i->first);
3100 if (other.isChild(i)) {
3101 if (j == mTable.end()) {
3102 mTable[i->first] = NodeStruct(
3103 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
3104 }
else if (this->isChild(j)) {
3105 this->getChild(j).topologyUnion(other.getChild(i), preserveTiles);
3107 if (!preserveTiles || this->isTileOff(j)) {
3108 ChildT* child =
new ChildT(
3109 other.getChild(i), this->getTile(j).value,
TopologyCopy());
3110 if (this->isTileOn(j)) child->setValuesOn();
3111 this->setChild(j, *child);
3114 }
else if (other.isTileOn(i)) {
3115 if (j == mTable.end()) {
3116 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
3117 }
else if (this->isChild(j)) {
3118 this->getChild(j).setValuesOn();
3119 }
else if (this->isTileOff(j)) {
3120 this->setTile(j, Tile(this->getTile(j).value,
true));
3126 template<
typename ChildT>
3127 template<
typename OtherChildType>
3132 using OtherCIterT =
typename OtherRootT::MapCIter;
3134 enforceSameConfiguration(other);
3136 std::set<Coord> tmp;
3137 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3138 OtherCIterT j = other.mTable.find(i->first);
3139 if (this->isChild(i)) {
3140 if (j == other.mTable.end() || other.isTileOff(j)) {
3141 tmp.insert(i->first);
3142 }
else if (other.isChild(j)) {
3143 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3145 }
else if (this->isTileOn(i)) {
3146 if (j == other.mTable.end() || other.isTileOff(j)) {
3147 this->setTile(i, Tile(this->getTile(i).value,
false));
3148 }
else if (other.isChild(j)) {
3150 new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
3151 this->setChild(i, *child);
3155 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3156 MapIter it = this->findCoord(*i);
3157 setTile(it, Tile());
3162 template<
typename ChildT>
3163 template<
typename OtherChildType>
3168 using OtherCIterT =
typename OtherRootT::MapCIter;
3170 enforceSameConfiguration(other);
3172 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3173 MapIter j = mTable.find(i->first);
3174 if (other.isChild(i)) {
3175 if (j == mTable.end() || this->isTileOff(j)) {
3177 }
else if (this->isChild(j)) {
3178 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3179 }
else if (this->isTileOn(j)) {
3181 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
3182 child->topologyDifference(other.getChild(i), mBackground);
3183 this->setChild(j, *child);
3185 }
else if (other.isTileOn(i)) {
3186 if (j == mTable.end() || this->isTileOff(j)) {
3188 }
else if (this->isChild(j)) {
3191 }
else if (this->isTileOn(j)) {
3192 this->setTile(j, Tile(this->getTile(j).value,
false));
3201 template<
typename ChildT>
3202 template<
typename CombineOp>
3209 this->insertKeys(keys);
3210 other.insertKeys(keys);
3212 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3213 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3214 if (isTile(iter) && isTile(otherIter)) {
3217 op(args.
setARef(getTile(iter).value)
3218 .setAIsActive(isTileOn(iter))
3219 .setBRef(getTile(otherIter).value)
3220 .setBIsActive(isTileOn(otherIter)));
3223 }
else if (isChild(iter) && isTile(otherIter)) {
3225 ChildT& child = getChild(iter);
3226 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3228 }
else if (isTile(iter) && isChild(otherIter)) {
3233 ChildT& child = getChild(otherIter);
3234 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3237 setChild(iter, stealChild(otherIter, Tile()));
3241 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3242 child.combine(otherChild, op);
3244 if (prune && isChild(iter)) getChild(iter).prune();
3248 op(args.
setARef(mBackground).setBRef(other.mBackground));
3249 mBackground = args.
result();
3261 template<
typename CombineOp,
typename RootT,
typename OtherRootT,
bool Compatible = false>
3264 static inline void combine2(RootT&
self,
const RootT&,
const OtherRootT& other1,
3269 self.enforceSameConfiguration(other1);
3270 self.enforceCompatibleValueTypes(other1);
3272 std::ostringstream ostr;
3273 ostr <<
"cannot combine a " <<
typeid(OtherRootT).name()
3274 <<
" into a " <<
typeid(RootT).name();
3280 template<
typename CombineOp,
typename RootT,
typename OtherRootT>
3283 static inline void combine2(RootT&
self,
const RootT& other0,
const OtherRootT& other1,
3284 CombineOp& op,
bool prune)
3286 self.doCombine2(other0, other1, op, prune);
3291 template<
typename ChildT>
3292 template<
typename CombineOp,
typename OtherRootNode>
3295 CombineOp& op,
bool prune)
3297 using OtherValueType =
typename OtherRootNode::ValueType;
3301 *
this, other0, other1, op, prune);
3305 template<
typename ChildT>
3306 template<
typename CombineOp,
typename OtherRootNode>
3309 CombineOp& op,
bool prune)
3311 enforceSameConfiguration(other1);
3313 using OtherValueT =
typename OtherRootNode::ValueType;
3314 using OtherTileT =
typename OtherRootNode::Tile;
3315 using OtherNodeStructT =
typename OtherRootNode::NodeStruct;
3316 using OtherMapCIterT =
typename OtherRootNode::MapCIter;
3321 other0.insertKeys(keys);
3322 other1.insertKeys(keys);
3324 const NodeStruct bg0(Tile(other0.mBackground,
false));
3325 const OtherNodeStructT bg1(OtherTileT(other1.mBackground,
false));
3327 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3328 MapIter thisIter = this->findOrAddCoord(*i);
3329 MapCIter iter0 = other0.findKey(*i);
3330 OtherMapCIterT iter1 = other1.findKey(*i);
3331 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3332 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3333 if (ns0.isTile() && ns1.isTile()) {
3336 op(args.
setARef(ns0.tile.value)
3337 .setAIsActive(ns0.isTileOn())
3338 .setBRef(ns1.tile.value)
3339 .setBIsActive(ns1.isTileOn()));
3342 if (!isChild(thisIter)) {
3344 const Coord& childOrigin =
3345 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3346 setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
3348 ChildT& child = getChild(thisIter);
3353 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3354 }
else if (ns1.isTile()) {
3357 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3361 child.combine2(*ns0.child, *ns1.child, op);
3364 if (prune && isChild(thisIter)) getChild(thisIter).prune();
3368 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
3369 mBackground = args.
result();
3376 template<
typename ChildT>
3377 template<
typename BBoxOp>
3381 const bool descent = op.template descent<LEVEL>();
3382 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3383 if (this->isTileOff(i))
continue;
3384 if (this->isChild(i) && descent) {
3385 this->getChild(i).visitActiveBBox(op);
3387 op.template operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
3393 template<
typename ChildT>
3394 template<
typename VisitorOp>
3398 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
3402 template<
typename ChildT>
3403 template<
typename VisitorOp>
3407 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
3411 template<
typename ChildT>
3412 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
3416 typename RootNodeT::ValueType val;
3417 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
3418 if (op(iter))
continue;
3419 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3429 template<
typename ChildT>
3430 template<
typename OtherRootNodeType,
typename VisitorOp>
3435 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
3439 template<
typename ChildT>
3440 template<
typename OtherRootNodeType,
typename VisitorOp>
3445 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
3449 template<
typename ChildT>
3452 typename OtherRootNodeT,
3454 typename ChildAllIterT,
3455 typename OtherChildAllIterT>
3459 enforceSameConfiguration(other);
3461 typename RootNodeT::ValueType val;
3462 typename OtherRootNodeT::ValueType otherVal;
3467 RootNodeT copyOfSelf(
self.mBackground);
3468 copyOfSelf.mTable =
self.mTable;
3469 OtherRootNodeT copyOfOther(other.mBackground);
3470 copyOfOther.mTable = other.mTable;
3474 self.insertKeys(keys);
3475 other.insertKeys(keys);
3476 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3477 copyOfSelf.findOrAddCoord(*i);
3478 copyOfOther.findOrAddCoord(*i);
3481 ChildAllIterT iter = copyOfSelf.beginChildAll();
3482 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3484 for ( ; iter && otherIter; ++iter, ++otherIter)
3486 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3488 typename ChildAllIterT::ChildNodeType* child =
3489 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
3490 typename OtherChildAllIterT::ChildNodeType* otherChild =
3491 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
3493 if (child !=
nullptr && otherChild !=
nullptr) {
3494 child->visit2Node(*otherChild, op);
3495 }
else if (child !=
nullptr) {
3496 child->visit2(otherIter, op);
3497 }
else if (otherChild !=
nullptr) {
3498 otherChild->visit2(iter, op,
true);
3503 copyOfSelf.eraseBackgroundTiles();
3504 copyOfOther.eraseBackgroundTiles();
3508 self.resetTable(copyOfSelf.mTable);
3509 other.resetTable(copyOfOther.mTable);
3516 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:56
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:372
Index32 leafCount() const
Definition: RootNode.h:1552
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:2514
void sparseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: RootNode.h:539
ChildT * child
Definition: GridBuilder.h:1286
const AValueType & result() const
Get the output value.
Definition: Types.h:574
ChildOffIter beginChildOff()
Definition: RootNode.h:382
Index getHeight() const
Definition: RootNode.h:463
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:375
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
void stealNodes(ArrayT &array, const ValueType &value, bool state)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: RootNode.h:2947
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 OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3294
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1884
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2288
Index32 childCount() const
Definition: RootNode.h:1578
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1622
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:611
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
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:2589
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:2554
typename SubtreeT::template Append< HeadT > Type
Definition: RootNode.h:1009
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:376
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:362
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
void stealNodes(ArrayT &array)
Steals all nodes of a certain type from the tree and adds them to a container with the following API:...
Definition: RootNode.h:818
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:69
Index32 transientData() const
Return the transient data value.
Definition: RootNode.h:410
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:216
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:3379
ValueAllCIter beginValueAll() const
Definition: RootNode.h:390
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2430
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:448
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:2849
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:364
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:385
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:406
Definition: RootNode.h:33
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1311
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
ChildOnCIter beginChildOn() const
Definition: RootNode.h:378
Index64 onTileCount() const
Definition: RootNode.h:1645
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1634
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1757
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:370
Definition: version.h.in:236
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2043
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:367
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:1771
void load(std::istream &is)
Definition: NodeMasks.h:1372
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3264
Definition: Exceptions.h:65
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1409
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:460
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2218
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:371
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:3129
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:368
OPENVDB_API void setGridBackgroundValuePtr(std::ios_base &, const void *background)
Specify (a pointer to) the background value of the grid currently being read from or written to the g...
void clear()
Definition: RootNode.h:1482
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:1362
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1441
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1260
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:644
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1334
static const Index LEVEL
Definition: RootNode.h:46
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2440
typename NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:49
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2324
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3432
void addTile(const Coord &xyz, const ValueType &value, bool state)
Add a tile containing voxel (x, y, z) at the root level, deleting the existing branch if necessary...
Definition: RootNode.h:2638
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1679
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a openvdb::TypeList that lists the types of the...
Definition: RootNode.h:31
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:364
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1658
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:2685
bool isOn(Index32 i) const
Definition: NodeMasks.h:1331
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2074
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:582
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:1906
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:529
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:386
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:2726
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 nullptr.
Definition: RootNode.h:2788
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:159
void setTransientData(Index32 transientData)
Set the transient data value.
Definition: RootNode.h:412
ValueOnIter beginValueOn()
Definition: RootNode.h:391
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: RootNode.h:2805
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:377
ChildType ChildNodeType
Definition: RootNode.h:41
void topologyUnion(const RootNode< OtherChildType > &other, const bool preserveTiles=false)
Union this tree's set of active values with the active values of the other tree, whose ValueType may ...
Definition: RootNode.h:3091
ValueAllIter beginValueAll()
Definition: RootNode.h:393
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1980
ChildOnIter beginChildOn()
Definition: RootNode.h:381
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:64
Index64 onVoxelCount() const
Definition: RootNode.h:1590
typename ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:42
typename ChildType::ValueType ValueType
Definition: RootNode.h:43
Index64 offVoxelCount() const
Definition: RootNode.h:1606
ChildOffCIter beginChildOff() const
Definition: RootNode.h:379
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:1948
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1341
void visit(VisitorOp &)
Definition: RootNode.h:3396
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1349
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:1735
Index getWidth() const
Definition: RootNode.h:462
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1841
uint64_t Index64
Definition: Types.h:53
typename ChildType::BuildType BuildType
Definition: RootNode.h:44
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:430
Definition: Exceptions.h:13
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1173
Definition: NodeMasks.h:1066
ValueT value
Definition: GridBuilder.h:1287
ValueOnCIter beginValueOn() const
Definition: RootNode.h:388
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3204
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1325
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1238
static Index getLevel()
Definition: RootNode.h:455
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:2244
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2889
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1132
Index32 Index
Definition: Types.h:54
RootNode(const RootNode &other)
Definition: RootNode.h:75
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2474
ValueOffCIter beginValueOff() const
Definition: RootNode.h:389
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1699
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2090
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:369
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:127
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1925
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1114
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:407
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1272
typename NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:1008
~RootNode()
Definition: RootNode.h:123
ValueOffIter beginValueOff()
Definition: RootNode.h:392
Index getDepth() const
Definition: RootNode.h:464
Definition: RootNode.h:34
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:2868
int32_t Int32
Definition: Types.h:56
Definition: Exceptions.h:64
void nodeCount(std::vector< Index32 > &vec) const
Definition: RootNode.h:1660
Index32 nonLeafCount() const
Definition: RootNode.h:1564
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1468
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:650
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:363
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1042
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:508
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:32
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:2016
uint32_t Index32
Definition: Types.h:52
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1794
bool hasActiveTiles() const
Return true if this root node, or any of its child nodes, have active tiles.
Definition: RootNode.h:1688
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:3165
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:387
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2979
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1745
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:1865
Definition: RootNode.h:38
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3283
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:360
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:477
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1711
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:485
bool addChild(ChildType *child)
Add the given child node at the root level. If a child node with the same origin already exists...
Definition: RootNode.h:2623
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:141
A list of types (not necessarily unique)
Definition: TypeList.h:365
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value and ensure that those voxels are a...
Definition: RootNode.h:2168
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: RootNode.h:2770
void setBackground(const ValueType &value, bool updateChildNodes)
Change inactive tiles or voxels with a value equal to +/- the old background to the specified value (...
Definition: RootNode.h:1211
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:361
ChildAllIter beginChildAll()
Definition: RootNode.h:383
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:1493
ChildAllCIter beginChildAll() const
Definition: RootNode.h:380
bool resultIsActive() const
Definition: Types.h:593
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:2535
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 nullptr.
Definition: RootNode.h:2813
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:365
RootNode(const RootNode< OtherChildType > &other)
Construct a new tree that reproduces the topology and active states of a tree of a different ValueTyp...
Definition: RootNode.h:84
static Index getChildDim()
Definition: RootNode.h:457
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: RootNode.h:2110