35 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 38 #include <openvdb/Exceptions.h> 39 #include <openvdb/Types.h> 40 #include <openvdb/io/Compression.h> 41 #include <openvdb/math/Math.h> 42 #include <openvdb/math/BBox.h> 43 #include <openvdb/util/NodeMasks.h> 44 #include <openvdb/version.h> 45 #include <boost/mpl/contains.hpp> 46 #include <boost/mpl/vector.hpp> 47 #include <boost/mpl/at.hpp> 48 #include <boost/mpl/push_back.hpp> 49 #include <boost/mpl/size.hpp> 50 #include <tbb/parallel_for.h> 63 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
69 template<
typename ChildType>
78 static const Index LEVEL = 1 + ChildType::LEVEL;
82 static_assert(boost::mpl::size<NodeChainType>::value == LEVEL + 1,
83 "wrong number of entries in RootNode node chain");
87 template<
typename OtherValueType>
95 template<
typename OtherNodeType>
115 template<
typename OtherChildType>
126 template<
typename OtherChildType>
140 template<
typename OtherChildType>
152 template<
typename OtherChildType>
159 Tile(): value(zeroVal<ValueType>()), active(
false) {}
160 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
170 NodeStruct(): child(
nullptr) {}
171 NodeStruct(ChildType& c): child(&c) {}
172 NodeStruct(
const Tile& t): child(
nullptr), tile(t) {}
173 NodeStruct(
const NodeStruct&) =
default;
174 NodeStruct& operator=(
const NodeStruct&) =
default;
177 bool isChild()
const {
return child !=
nullptr; }
178 bool isTile()
const {
return child ==
nullptr; }
179 bool isTileOff()
const {
return isTile() && !tile.active; }
180 bool isTileOn()
const {
return isTile() && tile.active; }
182 void set(ChildType& c) {
delete child; child = &c; }
183 void set(
const Tile& t) {
delete child; child =
nullptr; tile = t; }
184 ChildType& steal(
const Tile& t) { ChildType* c=child; child=
nullptr; tile=t;
return *c; }
187 using MapType = std::map<Coord, NodeStruct>;
188 using MapIter =
typename MapType::iterator;
189 using MapCIter =
typename MapType::const_iterator;
191 using CoordSet = std::set<Coord>;
192 using CoordSetIter =
typename CoordSet::iterator;
193 using CoordSetCIter =
typename CoordSet::const_iterator;
195 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
196 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
197 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
198 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
199 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
200 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
201 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
202 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
204 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
205 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
206 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
207 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
208 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
209 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
210 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
211 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
214 static inline bool test(
const MapIter&) {
return true; }
215 static inline bool test(
const MapCIter&) {
return true; }
218 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
219 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
221 struct ValueOffPred {
222 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
223 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
225 struct ValueAllPred {
226 static inline bool test(
const MapIter& i) {
return isTile(i); }
227 static inline bool test(
const MapCIter& i) {
return isTile(i); }
230 static inline bool test(
const MapIter& i) {
return isChild(i); }
231 static inline bool test(
const MapCIter& i) {
return isChild(i); }
233 struct ChildOffPred {
234 static inline bool test(
const MapIter& i) {
return isTile(i); }
235 static inline bool test(
const MapCIter& i) {
return isTile(i); }
238 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
242 using RootNodeT = _RootNodeT;
243 using MapIterT = _MapIterT;
247 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
249 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
251 RootNodeT* getParentNode()
const {
return mParentNode; }
253 RootNodeT& parent()
const 259 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
260 operator bool()
const {
return this->test(); }
262 void increment() {
if (this->test()) { ++mIter; } this->skip(); }
263 bool next() { this->increment();
return this->test(); }
264 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
270 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
273 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
274 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
275 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
276 void setValueOff()
const { mIter->second.tile.active =
false; }
279 Coord getCoord()
const {
return mIter->first; }
281 void getCoord(
Coord& xyz)
const { xyz = this->getCoord(); }
284 BaseIter(): mParentNode(
nullptr) {}
285 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
287 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
289 RootNodeT* mParentNode;
293 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
294 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
297 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
298 using NodeType = RootNodeT;
301 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
302 using NonConstValueType =
typename std::remove_const<ValueType>::type;
303 using NonConstChildNodeType =
typename std::remove_const<ChildNodeType>::type;
307 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
309 ChildIter& operator++() { BaseT::increment();
return *
this; }
311 ChildNodeT& getValue()
const {
return getChild(mIter); }
312 ChildNodeT&
operator*()
const {
return this->getValue(); }
313 ChildNodeT* operator->()
const {
return &this->getValue(); }
316 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
317 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
320 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
321 using NodeType = RootNodeT;
323 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
324 using NonConstValueType =
typename std::remove_const<ValueT>::type;
328 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
330 ValueIter& operator++() { BaseT::increment();
return *
this; }
332 ValueT& getValue()
const {
return getTile(mIter).value; }
333 ValueT&
operator*()
const {
return this->getValue(); }
334 ValueT* operator->()
const {
return &(this->getValue()); }
336 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
338 template<
typename ModifyOp>
339 void modifyValue(
const ModifyOp& op)
const 341 assert(isTile(mIter));
342 op(getTile(mIter).value);
346 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
347 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
350 using BaseT = BaseIter<RootNodeT, MapIterT, NullPred>;
351 using NodeType = RootNodeT;
354 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
355 using NonConstValueType =
typename std::remove_const<ValueT>::type;
356 using NonConstChildNodeType =
typename std::remove_const<ChildNodeT>::type;
360 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
362 DenseIter& operator++() { BaseT::increment();
return *
this; }
364 bool isChildNode()
const {
return isChild(mIter); }
366 ChildNodeT* probeChild(NonConstValueType& value)
const 368 if (isChild(mIter))
return &getChild(mIter);
369 value = getTile(mIter).value;
372 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const 374 child = this->probeChild(value);
375 return child !=
nullptr;
377 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
379 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
380 void setChild(ChildNodeT* c)
const { assert(c !=
nullptr); RootNodeT::setChild(mIter, *c); }
381 void setValue(
const ValueT& v)
const 383 if (isTile(mIter)) getTile(mIter).value = v;
387 else stealChild(mIter, Tile(v,
true));
392 using ChildOnIter = ChildIter<RootNode, MapIter, ChildOnPred, ChildType>;
393 using ChildOnCIter = ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>;
394 using ChildOffIter = ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>;
395 using ChildOffCIter = ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>;
396 using ChildAllIter = DenseIter<RootNode, MapIter, ChildType, ValueType>;
397 using ChildAllCIter = DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>;
399 using ValueOnIter = ValueIter<RootNode, MapIter, ValueOnPred, ValueType>;
400 using ValueOnCIter = ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>;
401 using ValueOffIter = ValueIter<RootNode, MapIter, ValueOffPred, ValueType>;
402 using ValueOffCIter = ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>;
403 using ValueAllIter = ValueIter<RootNode, MapIter, ValueAllPred, ValueType>;
404 using ValueAllCIter = ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>;
435 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
452 void setBackground(
const ValueType& value,
bool updateChildNodes);
458 bool isBackgroundTile(
const Tile&)
const;
460 bool isBackgroundTile(
const MapIter&)
const;
462 bool isBackgroundTile(
const MapCIter&)
const;
466 size_t numBackgroundTiles()
const;
469 size_t eraseBackgroundTiles();
473 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
478 bool expand(
const Coord& xyz);
481 static void getNodeLog2Dims(std::vector<Index>& dims);
487 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
488 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
489 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
492 Coord getMinIndex()
const;
494 Coord getMaxIndex()
const;
496 void getIndexRange(
CoordBBox& bbox)
const;
500 template<
typename OtherChildType>
504 template<
typename OtherChildType>
509 template<
typename OtherChildType>
516 Index64 onLeafVoxelCount()
const;
517 Index64 offLeafVoxelCount()
const;
520 bool isValueOn(
const Coord& xyz)
const;
523 bool hasActiveTiles()
const;
531 int getValueDepth(
const Coord& xyz)
const;
534 void setActiveState(
const Coord& xyz,
bool on);
540 void setValueOff(
const Coord& xyz);
546 template<
typename ModifyOp>
547 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
549 template<
typename ModifyOp>
550 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
564 this->fill(bbox, value, active);
585 void voxelizeActiveTiles(
bool threaded =
true);
592 template<
typename DenseT>
599 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
600 bool readTopology(std::istream&,
bool fromHalf =
false);
602 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
603 void readBuffers(std::istream&,
bool fromHalf =
false);
604 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
614 template<
typename AccessorT>
615 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
620 template<
typename AccessorT>
621 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
627 template<
typename AccessorT>
628 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
634 template<
typename AccessorT>
635 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
642 template<
typename ModifyOp,
typename AccessorT>
643 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
649 template<
typename ModifyOp,
typename AccessorT>
650 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
656 template<
typename AccessorT>
657 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
663 template<
typename AccessorT>
664 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
671 template<
typename AccessorT>
672 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
679 template<
typename AccessorT>
680 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
698 template<
typename AccessorT>
709 template<
typename NodeT>
710 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
714 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
723 template<
typename AccessorT>
724 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
735 template<
typename AccessorT>
739 template <
typename NodeT>
742 NodeT* probeNode(
const Coord& xyz);
743 template <
typename NodeT>
744 const NodeT* probeConstNode(
const Coord& xyz)
const;
748 template<
typename NodeT,
typename AccessorT>
751 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
752 template<
typename NodeT,
typename AccessorT>
753 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
765 template<
typename AccessorT>
769 template<
typename AccessorT>
770 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
771 template<
typename AccessorT>
781 template<
typename ArrayT>
void getNodes(ArrayT& array);
804 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
808 template<
typename ArrayT>
832 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
833 template<
typename ArrayT>
844 template<MergePolicy Policy>
void merge(
RootNode& other);
859 template<
typename OtherChildType>
875 template<
typename OtherChildType>
888 template<
typename OtherChildType>
891 template<
typename CombineOp>
892 void combine(
RootNode& other, CombineOp&,
bool prune =
false);
894 template<
typename CombineOp,
typename OtherRootNode >
895 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
896 CombineOp& op,
bool prune =
false);
903 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
905 template<
typename VisitorOp>
void visit(VisitorOp&);
906 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
908 template<
typename OtherRootNodeType,
typename VisitorOp>
909 void visit2(OtherRootNodeType& other, VisitorOp&);
910 template<
typename OtherRootNodeType,
typename VisitorOp>
911 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
924 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
926 void resetTable(
const MapType&)
const {}
929 Index getChildCount()
const;
930 Index getTileCount()
const;
931 Index getActiveTileCount()
const;
932 Index getInactiveTileCount()
const;
935 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
938 void insertKeys(CoordSet&)
const;
941 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
943 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
946 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
949 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
952 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
954 MapIter findOrAddCoord(
const Coord& xyz);
963 template<
typename OtherChildType>
971 template<
typename OtherChildType>
974 template<
typename CombineOp,
typename OtherRootNode >
975 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
977 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
978 static inline void doVisit(RootNodeT&, VisitorOp&);
980 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
981 typename ChildAllIterT,
typename OtherChildAllIterT>
982 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
1013 template<
typename HeadT,
int HeadLevel>
1016 using Type =
typename boost::mpl::push_back<SubtreeT, HeadT>::type;
1020 template<
typename HeadT>
1022 using Type =
typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type;
1030 template<
typename ChildT1,
typename NodeT2>
1034 static const bool value =
false;
1037 template<
typename ChildT1,
typename ChildT2>
1039 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1047 template<
typename ChildT>
1055 template<
typename ChildT>
1063 template<
typename ChildT>
1064 template<
typename OtherChildType>
1072 enforceSameConfiguration(other);
1074 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1077 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1078 mTable[i->first] = OtherRootT::isTile(i)
1079 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1080 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1085 template<
typename ChildT>
1086 template<
typename OtherChildType>
1094 enforceSameConfiguration(other);
1096 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1098 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1099 mTable[i->first] = OtherRootT::isTile(i)
1100 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1101 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1112 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1119 self.enforceSameConfiguration(other);
1120 self.enforceCompatibleValueTypes(other);
1122 std::ostringstream ostr;
1123 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1124 <<
" to a " <<
typeid(RootT).name();
1130 template<
typename RootT,
typename OtherRootT>
1135 using ValueT =
typename RootT::ValueType;
1136 using ChildT =
typename RootT::ChildNodeType;
1137 using NodeStruct =
typename RootT::NodeStruct;
1138 using Tile =
typename RootT::Tile;
1139 using OtherValueT =
typename OtherRootT::ValueType;
1140 using OtherMapCIter =
typename OtherRootT::MapCIter;
1141 using OtherTile =
typename OtherRootT::Tile;
1145 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1148 self.mBackground = Local::convertValue(other.mBackground);
1153 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1154 if (other.isTile(i)) {
1156 const OtherTile& otherTile = other.getTile(i);
1157 self.mTable[i->first] = NodeStruct(
1158 Tile(Local::convertValue(otherTile.value), otherTile.active));
1161 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1169 template<
typename ChildT>
1173 if (&other !=
this) {
1174 mBackground = other.mBackground;
1179 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1181 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1188 template<
typename ChildT>
1189 template<
typename OtherChildType>
1194 using OtherValueT =
typename OtherRootT::ValueType;
1204 template<
typename ChildT>
1210 if (updateChildNodes) {
1213 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1214 ChildT *child = iter->second.child;
1216 child->resetBackground(mBackground, background);
1218 Tile& tile = getTile(iter);
1219 if (tile.active)
continue;
1231 template<
typename ChildT>
1238 template<
typename ChildT>
1245 template<
typename ChildT>
1253 template<
typename ChildT>
1258 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1265 template<
typename ChildT>
1269 std::set<Coord> keysToErase;
1270 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1273 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1276 return keysToErase.size();
1283 template<
typename ChildT>
1287 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1288 keys.insert(i->first);
1293 template<
typename ChildT>
1294 inline typename RootNode<ChildT>::MapIter
1297 const Coord key = coordToKey(xyz);
1298 std::pair<MapIter, bool> result = mTable.insert(
1299 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1300 return result.first;
1304 template<
typename ChildT>
1308 const Coord key = coordToKey(xyz);
1309 std::pair<MapIter, bool> result = mTable.insert(
1310 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1311 return result.second;
1318 template<
typename ChildT>
1323 ChildT::getNodeLog2Dims(dims);
1327 template<
typename ChildT>
1331 return mTable.empty() ?
Coord(0) : mTable.begin()->first;
1334 template<
typename ChildT>
1338 return mTable.empty() ?
Coord(0) : mTable.rbegin()->first +
Coord(ChildT::DIM - 1);
1342 template<
typename ChildT>
1354 template<
typename ChildT>
1355 template<
typename OtherChildType>
1360 using OtherMapT =
typename OtherRootT::MapType;
1361 using OtherIterT =
typename OtherRootT::MapIter;
1362 using OtherCIterT =
typename OtherRootT::MapCIter;
1367 OtherMapT copyOfOtherTable = other.mTable;
1370 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1374 OtherCIterT otherIter = other.findKey(thisIter->first);
1375 if (otherIter == other.mTable.end())
return false;
1378 if (isChild(thisIter)) {
1379 if (OtherRootT::isTile(otherIter))
return false;
1381 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1383 if (OtherRootT::isChild(otherIter))
return false;
1384 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1391 copyOfOtherTable.erase(otherIter->first);
1394 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1401 template<
typename ChildT>
1402 template<
typename OtherChildType>
1406 std::vector<Index> thisDims, otherDims;
1409 return (thisDims == otherDims);
1413 template<
typename ChildT>
1414 template<
typename OtherChildType>
1418 std::vector<Index> thisDims, otherDims;
1421 if (thisDims != otherDims) {
1422 std::ostringstream ostr;
1423 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1424 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1425 ostr <<
" vs. " << otherDims[0];
1426 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1433 template<
typename ChildT>
1434 template<
typename OtherChildType>
1438 using OtherValueType =
typename OtherChildType::ValueType;
1443 template<
typename ChildT>
1444 template<
typename OtherChildType>
1448 using OtherValueType =
typename OtherChildType::ValueType;
1450 std::ostringstream ostr;
1451 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1452 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1461 template<
typename ChildT>
1466 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1467 if (
const ChildT *child = iter->second.child) {
1468 sum += child->memUsage();
1475 template<
typename ChildT>
1479 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1480 delete i->second.child;
1486 template<
typename ChildT>
1490 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1491 if (
const ChildT *child = iter->second.child) {
1492 child->evalActiveBoundingBox(bbox, visitVoxels);
1493 }
else if (isTileOn(iter)) {
1494 bbox.
expand(iter->first, ChildT::DIM);
1500 template<
typename ChildT>
1504 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1505 if (isChild(i)) ++sum;
1511 template<
typename ChildT>
1516 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1517 if (isTile(i)) ++sum;
1523 template<
typename ChildT>
1528 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1529 if (isTileOn(i)) ++sum;
1535 template<
typename ChildT>
1540 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1541 if (isTileOff(i)) ++sum;
1547 template<
typename ChildT>
1552 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1553 if (isChild(i)) sum += getChild(i).leafCount();
1559 template<
typename ChildT>
1564 if (ChildT::LEVEL != 0) {
1565 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1566 if (isChild(i)) sum += getChild(i).nonLeafCount();
1573 template<
typename ChildT>
1578 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1580 sum += getChild(i).onVoxelCount();
1581 }
else if (isTileOn(i)) {
1582 sum += ChildT::NUM_VOXELS;
1589 template<
typename ChildT>
1594 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1596 sum += getChild(i).offVoxelCount();
1598 sum += ChildT::NUM_VOXELS;
1605 template<
typename ChildT>
1610 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1611 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1617 template<
typename ChildT>
1622 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1623 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1628 template<
typename ChildT>
1633 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1635 sum += getChild(i).onTileCount();
1636 }
else if (isTileOn(i)) {
1646 template<
typename ChildT>
1650 MapCIter iter = this->findCoord(xyz);
1651 if (iter == mTable.end() || isTileOff(iter))
return false;
1652 return isTileOn(iter) ? true : getChild(iter).isValueOn(xyz);
1655 template<
typename ChildT>
1659 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1660 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1665 template<
typename ChildT>
1666 template<
typename AccessorT>
1670 MapCIter iter = this->findCoord(xyz);
1671 if (iter == mTable.end() || isTileOff(iter))
return false;
1672 if (isTileOn(iter))
return true;
1673 acc.insert(xyz, &getChild(iter));
1674 return getChild(iter).isValueOnAndCache(xyz, acc);
1678 template<
typename ChildT>
1679 inline const typename ChildT::ValueType&
1682 MapCIter iter = this->findCoord(xyz);
1683 return iter == mTable.end() ? mBackground
1684 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1687 template<
typename ChildT>
1688 template<
typename AccessorT>
1689 inline const typename ChildT::ValueType&
1692 MapCIter iter = this->findCoord(xyz);
1693 if (iter == mTable.end())
return mBackground;
1694 if (isChild(iter)) {
1695 acc.insert(xyz, &getChild(iter));
1696 return getChild(iter).getValueAndCache(xyz, acc);
1698 return getTile(iter).value;
1702 template<
typename ChildT>
1706 MapCIter iter = this->findCoord(xyz);
1707 return iter == mTable.end() ? -1
1708 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1711 template<
typename ChildT>
1712 template<
typename AccessorT>
1716 MapCIter iter = this->findCoord(xyz);
1717 if (iter == mTable.end())
return -1;
1718 if (isTile(iter))
return 0;
1719 acc.insert(xyz, &getChild(iter));
1720 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1724 template<
typename ChildT>
1728 MapIter iter = this->findCoord(xyz);
1729 if (iter != mTable.end() && !isTileOff(iter)) {
1730 if (isTileOn(iter)) {
1731 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1733 getChild(iter).setValueOff(xyz);
1738 template<
typename ChildT>
1742 ChildT* child =
nullptr;
1743 MapIter iter = this->findCoord(xyz);
1744 if (iter == mTable.end()) {
1746 child =
new ChildT(xyz, mBackground);
1747 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1751 }
else if (isChild(iter)) {
1752 child = &getChild(iter);
1753 }
else if (on != getTile(iter).active) {
1754 child =
new ChildT(xyz, getTile(iter).value, !on);
1755 setChild(iter, *child);
1757 if (child) child->setActiveState(xyz, on);
1760 template<
typename ChildT>
1761 template<
typename AccessorT>
1765 ChildT* child =
nullptr;
1766 MapIter iter = this->findCoord(xyz);
1767 if (iter == mTable.end()) {
1769 child =
new ChildT(xyz, mBackground);
1770 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1774 }
else if (isChild(iter)) {
1775 child = &getChild(iter);
1776 }
else if (on != getTile(iter).active) {
1777 child =
new ChildT(xyz, getTile(iter).value, !on);
1778 setChild(iter, *child);
1781 acc.insert(xyz, child);
1782 child->setActiveStateAndCache(xyz, on, acc);
1787 template<
typename ChildT>
1791 ChildT* child =
nullptr;
1792 MapIter iter = this->findCoord(xyz);
1793 if (iter == mTable.end()) {
1795 child =
new ChildT(xyz, mBackground);
1796 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1798 }
else if (isChild(iter)) {
1799 child = &getChild(iter);
1801 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1802 setChild(iter, *child);
1804 if (child) child->setValueOff(xyz, value);
1807 template<
typename ChildT>
1808 template<
typename AccessorT>
1812 ChildT* child =
nullptr;
1813 MapIter iter = this->findCoord(xyz);
1814 if (iter == mTable.end()) {
1816 child =
new ChildT(xyz, mBackground);
1817 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1819 }
else if (isChild(iter)) {
1820 child = &getChild(iter);
1822 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1823 setChild(iter, *child);
1826 acc.insert(xyz, child);
1827 child->setValueOffAndCache(xyz, value, acc);
1832 template<
typename ChildT>
1836 ChildT* child =
nullptr;
1837 MapIter iter = this->findCoord(xyz);
1838 if (iter == mTable.end()) {
1839 child =
new ChildT(xyz, mBackground);
1840 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1841 }
else if (isChild(iter)) {
1842 child = &getChild(iter);
1844 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1845 setChild(iter, *child);
1847 if (child) child->setValueOn(xyz, value);
1850 template<
typename ChildT>
1851 template<
typename AccessorT>
1855 ChildT* child =
nullptr;
1856 MapIter iter = this->findCoord(xyz);
1857 if (iter == mTable.end()) {
1858 child =
new ChildT(xyz, mBackground);
1859 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1860 }
else if (isChild(iter)) {
1861 child = &getChild(iter);
1863 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1864 setChild(iter, *child);
1867 acc.insert(xyz, child);
1868 child->setValueAndCache(xyz, value, acc);
1873 template<
typename ChildT>
1877 ChildT* child =
nullptr;
1878 MapIter iter = this->findCoord(xyz);
1879 if (iter == mTable.end()) {
1880 child =
new ChildT(xyz, mBackground);
1881 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1882 }
else if (isChild(iter)) {
1883 child = &getChild(iter);
1885 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1886 setChild(iter, *child);
1888 if (child) child->setValueOnly(xyz, value);
1891 template<
typename ChildT>
1892 template<
typename AccessorT>
1896 ChildT* child =
nullptr;
1897 MapIter iter = this->findCoord(xyz);
1898 if (iter == mTable.end()) {
1899 child =
new ChildT(xyz, mBackground);
1900 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1901 }
else if (isChild(iter)) {
1902 child = &getChild(iter);
1904 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1905 setChild(iter, *child);
1908 acc.insert(xyz, child);
1909 child->setValueOnlyAndCache(xyz, value, acc);
1914 template<
typename ChildT>
1915 template<
typename ModifyOp>
1919 ChildT* child =
nullptr;
1920 MapIter iter = this->findCoord(xyz);
1921 if (iter == mTable.end()) {
1922 child =
new ChildT(xyz, mBackground);
1923 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1924 }
else if (isChild(iter)) {
1925 child = &getChild(iter);
1929 bool createChild = isTileOff(iter);
1933 const ValueType& tileVal = getTile(iter).value;
1939 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1940 setChild(iter, *child);
1943 if (child) child->modifyValue(xyz, op);
1946 template<
typename ChildT>
1947 template<
typename ModifyOp,
typename AccessorT>
1951 ChildT* child =
nullptr;
1952 MapIter iter = this->findCoord(xyz);
1953 if (iter == mTable.end()) {
1954 child =
new ChildT(xyz, mBackground);
1955 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1956 }
else if (isChild(iter)) {
1957 child = &getChild(iter);
1961 bool createChild = isTileOff(iter);
1965 const ValueType& tileVal = getTile(iter).value;
1971 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1972 setChild(iter, *child);
1976 acc.insert(xyz, child);
1977 child->modifyValueAndCache(xyz, op, acc);
1982 template<
typename ChildT>
1983 template<
typename ModifyOp>
1987 ChildT* child =
nullptr;
1988 MapIter iter = this->findCoord(xyz);
1989 if (iter == mTable.end()) {
1990 child =
new ChildT(xyz, mBackground);
1991 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1992 }
else if (isChild(iter)) {
1993 child = &getChild(iter);
1995 const Tile& tile = getTile(iter);
1996 bool modifiedState = tile.active;
1998 op(modifiedVal, modifiedState);
2002 child =
new ChildT(xyz, tile.value, tile.active);
2003 setChild(iter, *child);
2006 if (child) child->modifyValueAndActiveState(xyz, op);
2009 template<
typename ChildT>
2010 template<
typename ModifyOp,
typename AccessorT>
2013 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2015 ChildT* child =
nullptr;
2016 MapIter iter = this->findCoord(xyz);
2017 if (iter == mTable.end()) {
2018 child =
new ChildT(xyz, mBackground);
2019 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2020 }
else if (isChild(iter)) {
2021 child = &getChild(iter);
2023 const Tile& tile = getTile(iter);
2024 bool modifiedState = tile.active;
2026 op(modifiedVal, modifiedState);
2030 child =
new ChildT(xyz, tile.value, tile.active);
2031 setChild(iter, *child);
2035 acc.insert(xyz, child);
2036 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2041 template<
typename ChildT>
2045 MapCIter iter = this->findCoord(xyz);
2046 if (iter == mTable.end()) {
2047 value = mBackground;
2049 }
else if (isChild(iter)) {
2050 return getChild(iter).probeValue(xyz, value);
2052 value = getTile(iter).value;
2053 return isTileOn(iter);
2056 template<
typename ChildT>
2057 template<
typename AccessorT>
2061 MapCIter iter = this->findCoord(xyz);
2062 if (iter == mTable.end()) {
2063 value = mBackground;
2065 }
else if (isChild(iter)) {
2066 acc.insert(xyz, &getChild(iter));
2067 return getChild(iter).probeValueAndCache(xyz, value, acc);
2069 value = getTile(iter).value;
2070 return isTileOn(iter);
2077 template<
typename ChildT>
2081 if (bbox.
empty())
return;
2086 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
2088 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
2090 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
2094 Coord tileMin = coordToKey(xyz);
2095 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2101 ChildT* child =
nullptr;
2102 MapIter iter = this->findKey(tileMin);
2103 if (iter == mTable.end()) {
2106 child =
new ChildT(xyz, mBackground);
2107 mTable[tileMin] = NodeStruct(*child);
2108 }
else if (isTile(iter)) {
2111 const Tile& tile = getTile(iter);
2112 child =
new ChildT(xyz, tile.value, tile.active);
2113 mTable[tileMin] = NodeStruct(*child);
2114 }
else if (isChild(iter)) {
2115 child = &getChild(iter);
2120 child->fill(
CoordBBox(xyz, tmp), value, active);
2126 MapIter iter = this->findOrAddCoord(tileMin);
2127 setTile(iter, Tile(value, active));
2135 template<
typename ChildT>
2139 if (bbox.
empty())
return;
2141 if (active && mTable.empty()) {
2151 Coord xyz, tileMin, tileMax;
2152 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
2154 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
2156 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
2160 tileMin = coordToKey(xyz);
2161 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2165 const auto iter = findOrAddCoord(tileMin);
2170 const auto& tile = getTile(iter);
2171 auto* child =
new ChildT{tileMin, tile.value, tile.active};
2172 setChild(iter, *child);
2175 getChild(iter).denseFill(bbox, value, active);
2185 template<
typename ChildT>
2193 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2194 if (this->isTileOff(i))
continue;
2195 ChildT* child = i->second.child;
2196 if (child ==
nullptr) {
2199 child =
new ChildT{i->first, this->getTile(i).value,
true};
2200 i->second.child = child;
2202 child->voxelizeActiveTiles(threaded);
2210 template<
typename ChildT>
2211 template<
typename DenseT>
2215 using DenseValueType =
typename DenseT::ValueType;
2217 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2218 const Coord&
min = dense.bbox().min();
2220 for (
Coord xyz = bbox.
min(); xyz[0] <= bbox.
max()[0]; xyz[0] = nodeBBox.
max()[0] + 1) {
2221 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] = nodeBBox.
max()[1] + 1) {
2222 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] = nodeBBox.
max()[2] + 1) {
2230 MapCIter iter = this->findKey(nodeBBox.
min());
2231 if (iter != mTable.end() && isChild(iter)) {
2232 getChild(iter).copyToDense(sub, dense);
2234 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2236 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2237 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2238 DenseValueType* a1 = a0 + x*xStride;
2239 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2240 DenseValueType* a2 = a1 + y*yStride;
2241 for (
Int32 z=sub.
min()[2], ez=sub.
max()[2]+1; z<ez; ++z, a2 += zStride) {
2242 *a2 = DenseValueType(value);
2255 template<
typename ChildT>
2260 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(
ValueType));
2263 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(
ValueType));
2267 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
2268 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
2269 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
2271 if (numTiles == 0 && numChildren == 0)
return false;
2274 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2275 if (isChild(i))
continue;
2276 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2277 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(
ValueType));
2278 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
2281 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2282 if (isTile(i))
continue;
2283 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2284 getChild(i).writeTopology(os, toHalf);
2291 template<
typename ChildT>
2303 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
2305 is.read(reinterpret_cast<char*>(&inside),
sizeof(
ValueType));
2310 Coord rangeMin, rangeMax;
2312 is.read(reinterpret_cast<char*>(rangeMax.
asPointer()), 3 *
sizeof(
Int32));
2315 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2317 for (
int i = 0; i < 3; ++i) {
2318 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2319 rangeMin[i] = offset[i] << ChildT::TOTAL;
2321 tableSize += log2Dim[i];
2322 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2324 log2Dim[3] = log2Dim[1] + log2Dim[2];
2325 tableSize = 1U << tableSize;
2333 for (
Index i = 0; i < tableSize; ++i) {
2337 origin[0] = (n >> log2Dim[3]) + offset[0];
2338 n &= (1U << log2Dim[3]) - 1;
2339 origin[1] = (n >> log2Dim[2]) + offset[1];
2340 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2341 origin <<= ChildT::TOTAL;
2343 if (childMask.isOn(i)) {
2345 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2346 ChildT* child =
new ChildT(origin, mBackground);
2348 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2350 child->readTopology(is);
2351 mTable[origin] = NodeStruct(*child);
2356 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2358 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2367 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(
ValueType));
2370 Index numTiles = 0, numChildren = 0;
2371 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2372 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2374 if (numTiles == 0 && numChildren == 0)
return false;
2381 for (
Index n = 0; n < numTiles; ++n) {
2382 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2383 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2384 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2385 mTable[
Coord(vec)] = NodeStruct(Tile(value, active));
2389 for (
Index n = 0; n < numChildren; ++n) {
2390 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2392 #if OPENVDB_ABI_VERSION_NUMBER <= 2 2393 ChildT* child =
new ChildT(origin, mBackground);
2395 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2397 child->readTopology(is, fromHalf);
2398 mTable[
Coord(vec)] = NodeStruct(*child);
2405 template<
typename ChildT>
2409 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2410 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2415 template<
typename ChildT>
2419 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2420 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2425 template<
typename ChildT>
2429 const Tile bgTile(mBackground,
false);
2431 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2437 ChildT& child = getChild(i);
2438 child.readBuffers(is, clipBBox, fromHalf);
2442 this->
clip(clipBBox);
2449 template<
typename ChildT>
2453 const Tile bgTile(mBackground,
false);
2457 MapType copyOfTable(mTable);
2458 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2459 const Coord& xyz = i->first;
2463 setTile(this->findCoord(xyz), bgTile);
2465 }
else if (!clipBBox.
isInside(tileBBox)) {
2469 getChild(i).clip(clipBBox, mBackground);
2473 tileBBox.intersect(clipBBox);
2474 const Tile& origTile = getTile(i);
2475 setTile(this->findCoord(xyz), bgTile);
2476 this->
sparseFill(tileBBox, origTile.value, origTile.active);
2489 template<
typename ChildT>
2495 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2496 if (this->isTile(i))
continue;
2497 this->getChild(i).prune(tolerance);
2498 if (this->getChild(i).isConstant(value, state, tolerance)) {
2499 this->setTile(i, Tile(value, state));
2509 template<
typename ChildT>
2510 template<
typename NodeT>
2514 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2515 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2517 MapIter iter = this->findCoord(xyz);
2518 if (iter == mTable.end() || isTile(iter))
return nullptr;
2519 return (std::is_same<NodeT, ChildT>::value)
2520 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2521 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2529 template<
typename ChildT>
2533 if (leaf ==
nullptr)
return;
2534 ChildT* child =
nullptr;
2535 const Coord& xyz = leaf->origin();
2536 MapIter iter = this->findCoord(xyz);
2537 if (iter == mTable.end()) {
2538 if (ChildT::LEVEL>0) {
2539 child =
new ChildT(xyz, mBackground,
false);
2541 child =
reinterpret_cast<ChildT*
>(leaf);
2543 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2544 }
else if (isChild(iter)) {
2545 if (ChildT::LEVEL>0) {
2546 child = &getChild(iter);
2548 child =
reinterpret_cast<ChildT*
>(leaf);
2549 setChild(iter, *child);
2552 if (ChildT::LEVEL>0) {
2553 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2555 child =
reinterpret_cast<ChildT*
>(leaf);
2557 setChild(iter, *child);
2559 child->addLeaf(leaf);
2563 template<
typename ChildT>
2564 template<
typename AccessorT>
2568 if (leaf ==
nullptr)
return;
2569 ChildT* child =
nullptr;
2570 const Coord& xyz = leaf->origin();
2571 MapIter iter = this->findCoord(xyz);
2572 if (iter == mTable.end()) {
2573 if (ChildT::LEVEL>0) {
2574 child =
new ChildT(xyz, mBackground,
false);
2576 child =
reinterpret_cast<ChildT*
>(leaf);
2578 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2579 }
else if (isChild(iter)) {
2580 if (ChildT::LEVEL>0) {
2581 child = &getChild(iter);
2583 child =
reinterpret_cast<ChildT*
>(leaf);
2584 setChild(iter, *child);
2587 if (ChildT::LEVEL>0) {
2588 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2590 child =
reinterpret_cast<ChildT*
>(leaf);
2592 setChild(iter, *child);
2594 acc.insert(xyz, child);
2595 child->addLeafAndCache(leaf, acc);
2598 template<
typename ChildT>
2602 MapIter iter = this->findCoord(xyz);
2603 if (iter == mTable.end()) {
2604 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2606 setTile(iter, Tile(value, state));
2610 template<
typename ChildT>
2615 if (LEVEL >= level) {
2616 MapIter iter = this->findCoord(xyz);
2617 if (iter == mTable.end()) {
2618 if (LEVEL > level) {
2619 ChildT* child =
new ChildT(xyz, mBackground,
false);
2620 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2621 child->addTile(level, xyz, value, state);
2623 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2625 }
else if (isChild(iter)) {
2626 if (LEVEL > level) {
2627 getChild(iter).addTile(level, xyz, value, state);
2629 setTile(iter, Tile(value, state));
2632 if (LEVEL > level) {
2633 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2634 setChild(iter, *child);
2635 child->addTile(level, xyz, value, state);
2637 setTile(iter, Tile(value, state));
2644 template<
typename ChildT>
2645 template<
typename AccessorT>
2648 bool state, AccessorT& acc)
2650 if (LEVEL >= level) {
2651 MapIter iter = this->findCoord(xyz);
2652 if (iter == mTable.end()) {
2653 if (LEVEL > level) {
2654 ChildT* child =
new ChildT(xyz, mBackground,
false);
2655 acc.insert(xyz, child);
2656 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2657 child->addTileAndCache(level, xyz, value, state, acc);
2659 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2661 }
else if (isChild(iter)) {
2662 if (LEVEL > level) {
2663 ChildT* child = &getChild(iter);
2664 acc.insert(xyz, child);
2665 child->addTileAndCache(level, xyz, value, state, acc);
2667 setTile(iter, Tile(value, state));
2670 if (LEVEL > level) {
2671 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2672 acc.insert(xyz, child);
2673 setChild(iter, *child);
2674 child->addTileAndCache(level, xyz, value, state, acc);
2676 setTile(iter, Tile(value, state));
2686 template<
typename ChildT>
2687 inline typename ChildT::LeafNodeType*
2690 ChildT* child =
nullptr;
2691 MapIter iter = this->findCoord(xyz);
2692 if (iter == mTable.end()) {
2693 child =
new ChildT(xyz, mBackground,
false);
2694 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2695 }
else if (isChild(iter)) {
2696 child = &getChild(iter);
2698 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2699 setChild(iter, *child);
2701 return child->touchLeaf(xyz);
2705 template<
typename ChildT>
2706 template<
typename AccessorT>
2707 inline typename ChildT::LeafNodeType*
2710 ChildT* child =
nullptr;
2711 MapIter iter = this->findCoord(xyz);
2712 if (iter == mTable.end()) {
2713 child =
new ChildT(xyz, mBackground,
false);
2714 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2715 }
else if (isChild(iter)) {
2716 child = &getChild(iter);
2718 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2719 setChild(iter, *child);
2721 acc.insert(xyz, child);
2722 return child->touchLeafAndCache(xyz, acc);
2729 template<
typename ChildT>
2730 template<
typename NodeT>
2734 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2735 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2737 MapIter iter = this->findCoord(xyz);
2738 if (iter == mTable.end() || isTile(iter))
return nullptr;
2739 ChildT* child = &getChild(iter);
2740 return (std::is_same<NodeT, ChildT>::value)
2741 ?
reinterpret_cast<NodeT*
>(child)
2742 : child->template probeNode<NodeT>(xyz);
2747 template<
typename ChildT>
2748 template<
typename NodeT>
2752 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2753 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2755 MapCIter iter = this->findCoord(xyz);
2756 if (iter == mTable.end() || isTile(iter))
return nullptr;
2757 const ChildT* child = &getChild(iter);
2758 return (std::is_same<NodeT, ChildT>::value)
2759 ?
reinterpret_cast<const NodeT*
>(child)
2760 : child->template probeConstNode<NodeT>(xyz);
2765 template<
typename ChildT>
2766 inline typename ChildT::LeafNodeType*
2769 return this->
template probeNode<LeafNodeType>(xyz);
2773 template<
typename ChildT>
2774 inline const typename ChildT::LeafNodeType*
2777 return this->
template probeConstNode<LeafNodeType>(xyz);
2781 template<
typename ChildT>
2782 template<
typename AccessorT>
2783 inline typename ChildT::LeafNodeType*
2786 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2790 template<
typename ChildT>
2791 template<
typename AccessorT>
2792 inline const typename ChildT::LeafNodeType*
2795 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2799 template<
typename ChildT>
2800 template<
typename AccessorT>
2801 inline const typename ChildT::LeafNodeType*
2808 template<
typename ChildT>
2809 template<
typename NodeT,
typename AccessorT>
2813 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2814 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2816 MapIter iter = this->findCoord(xyz);
2817 if (iter == mTable.end() || isTile(iter))
return nullptr;
2818 ChildT* child = &getChild(iter);
2819 acc.insert(xyz, child);
2820 return (std::is_same<NodeT, ChildT>::value)
2821 ?
reinterpret_cast<NodeT*
>(child)
2822 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2827 template<
typename ChildT>
2828 template<
typename NodeT,
typename AccessorT>
2832 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2833 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2835 MapCIter iter = this->findCoord(xyz);
2836 if (iter == mTable.end() || isTile(iter))
return nullptr;
2837 const ChildT* child = &getChild(iter);
2838 acc.insert(xyz, child);
2839 return (std::is_same<NodeT, ChildT>::value)
2840 ?
reinterpret_cast<const NodeT*
>(child)
2841 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2848 template<
typename ChildT>
2849 template<
typename ArrayT>
2853 using NodePtr =
typename ArrayT::value_type;
2854 static_assert(std::is_pointer<NodePtr>::value,
2855 "argument to getNodes() must be a pointer array");
2856 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2857 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2858 using result =
typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type;
2859 static_assert(result::value,
"can't extract non-const nodes from a const tree");
2860 using ArrayChildT =
typename std::conditional<
2861 std::is_const<NodeType>::value,
const ChildT, ChildT>::type;
2863 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2864 if (ChildT* child = iter->second.child) {
2866 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2867 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2869 child->getNodes(array);
2876 template<
typename ChildT>
2877 template<
typename ArrayT>
2881 using NodePtr =
typename ArrayT::value_type;
2882 static_assert(std::is_pointer<NodePtr>::value,
2883 "argument to getNodes() must be a pointer array");
2884 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2885 static_assert(std::is_const<NodeType>::value,
2886 "argument to getNodes() must be an array of const node pointers");
2887 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2888 using result =
typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type;
2889 static_assert(result::value,
"can't extract non-const nodes from a const tree");
2891 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2894 if (std::is_same<NodePtr, const ChildT*>::value) {
2895 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2897 child->getNodes(array);
2906 template<
typename ChildT>
2907 template<
typename ArrayT>
2911 using NodePtr =
typename ArrayT::value_type;
2912 static_assert(std::is_pointer<NodePtr>::value,
2913 "argument to stealNodes() must be a pointer array");
2914 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2915 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2916 using result =
typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type;
2917 static_assert(result::value,
"can't extract non-const nodes from a const tree");
2918 using ArrayChildT =
typename std::conditional<
2919 std::is_const<NodeType>::value,
const ChildT, ChildT>::type;
2921 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2922 if (ChildT* child = iter->second.child) {
2924 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2925 array.push_back(reinterpret_cast<NodePtr>(&stealChild(iter, Tile(value, state))));
2927 child->stealNodes(array, value, state);
2938 template<
typename ChildT>
2939 template<MergePolicy Policy>
2949 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2950 MapIter j = mTable.find(i->first);
2951 if (other.isChild(i)) {
2952 if (j == mTable.end()) {
2953 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2954 child.resetBackground(other.mBackground, mBackground);
2955 mTable[i->first] = NodeStruct(child);
2956 }
else if (isTile(j)) {
2958 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2959 child.resetBackground(other.mBackground, mBackground);
2963 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
2964 other.mBackground, mBackground);
2966 }
else if (other.isTileOn(i)) {
2967 if (j == mTable.end()) {
2968 mTable[i->first] = i->second;
2969 }
else if (!isTileOn(j)) {
2971 setTile(j, Tile(other.getTile(i).value,
true));
2978 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2979 MapIter j = mTable.find(i->first);
2980 if (other.isChild(i)) {
2981 if (j == mTable.end()) {
2982 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2983 child.resetBackground(other.mBackground, mBackground);
2984 mTable[i->first] = NodeStruct(child);
2985 }
else if (isTile(j)) {
2986 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2987 child.resetBackground(other.mBackground, mBackground);
2990 getChild(j).template merge<MERGE_NODES>(
2991 getChild(i), other.mBackground, mBackground);
2998 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2999 MapIter j = mTable.find(i->first);
3000 if (other.isChild(i)) {
3001 if (j == mTable.end()) {
3003 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3004 child.resetBackground(other.mBackground, mBackground);
3005 mTable[i->first] = NodeStruct(child);
3006 }
else if (isTile(j)) {
3008 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3009 child.resetBackground(other.mBackground, mBackground);
3010 const Tile tile = getTile(j);
3014 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3015 tile.value, tile.active);
3019 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
3020 other.mBackground, mBackground);
3022 }
else if (other.isTileOn(i)) {
3023 if (j == mTable.end()) {
3025 mTable[i->first] = i->second;
3026 }
else if (isTileOff(j)) {
3028 setTile(j, Tile(other.getTile(i).value,
true));
3029 }
else if (isChild(j)) {
3031 const Tile& tile = getTile(i);
3032 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3033 tile.value, tile.active);
3050 template<
typename ChildT>
3051 template<
typename OtherChildType>
3056 using OtherCIterT =
typename OtherRootT::MapCIter;
3058 enforceSameConfiguration(other);
3060 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3061 MapIter j = mTable.find(i->first);
3062 if (other.isChild(i)) {
3063 if (j == mTable.end()) {
3064 mTable[i->first] = NodeStruct(
3065 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
3066 }
else if (this->isChild(j)) {
3067 this->getChild(j).topologyUnion(other.getChild(i));
3069 ChildT* child =
new ChildT(
3070 other.getChild(i), this->getTile(j).value,
TopologyCopy());
3071 if (this->isTileOn(j)) child->setValuesOn();
3072 this->setChild(j, *child);
3074 }
else if (other.isTileOn(i)) {
3075 if (j == mTable.end()) {
3076 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
3077 }
else if (this->isChild(j)) {
3078 this->getChild(j).setValuesOn();
3079 }
else if (this->isTileOff(j)) {
3080 this->setTile(j, Tile(this->getTile(j).value,
true));
3086 template<
typename ChildT>
3087 template<
typename OtherChildType>
3092 using OtherCIterT =
typename OtherRootT::MapCIter;
3094 enforceSameConfiguration(other);
3096 std::set<Coord> tmp;
3097 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3098 OtherCIterT j = other.mTable.find(i->first);
3099 if (this->isChild(i)) {
3100 if (j == other.mTable.end() || other.isTileOff(j)) {
3101 tmp.insert(i->first);
3102 }
else if (other.isChild(j)) {
3103 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3105 }
else if (this->isTileOn(i)) {
3106 if (j == other.mTable.end() || other.isTileOff(j)) {
3107 this->setTile(i, Tile(this->getTile(i).value,
false));
3108 }
else if (other.isChild(j)) {
3110 new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
3111 this->setChild(i, *child);
3115 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3116 MapIter it = this->findCoord(*i);
3117 setTile(it, Tile());
3122 template<
typename ChildT>
3123 template<
typename OtherChildType>
3128 using OtherCIterT =
typename OtherRootT::MapCIter;
3130 enforceSameConfiguration(other);
3132 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3133 MapIter j = mTable.find(i->first);
3134 if (other.isChild(i)) {
3135 if (j == mTable.end() || this->isTileOff(j)) {
3137 }
else if (this->isChild(j)) {
3138 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3139 }
else if (this->isTileOn(j)) {
3141 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
3142 child->topologyDifference(other.getChild(i), mBackground);
3143 this->setChild(j, *child);
3145 }
else if (other.isTileOn(i)) {
3146 if (j == mTable.end() || this->isTileOff(j)) {
3148 }
else if (this->isChild(j)) {
3151 }
else if (this->isTileOn(j)) {
3152 this->setTile(j, Tile(this->getTile(j).value,
false));
3161 template<
typename ChildT>
3162 template<
typename CombineOp>
3169 this->insertKeys(keys);
3170 other.insertKeys(keys);
3172 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3173 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3174 if (isTile(iter) && isTile(otherIter)) {
3177 op(args.
setARef(getTile(iter).value)
3178 .setAIsActive(isTileOn(iter))
3179 .setBRef(getTile(otherIter).value)
3180 .setBIsActive(isTileOn(otherIter)));
3183 }
else if (isChild(iter) && isTile(otherIter)) {
3185 ChildT& child = getChild(iter);
3186 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3188 }
else if (isTile(iter) && isChild(otherIter)) {
3193 ChildT& child = getChild(otherIter);
3194 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3197 setChild(iter, stealChild(otherIter, Tile()));
3201 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3202 child.combine(otherChild, op);
3204 if (prune && isChild(iter)) getChild(iter).prune();
3208 op(args.
setARef(mBackground).setBRef(other.mBackground));
3209 mBackground = args.
result();
3221 template<
typename CombineOp,
typename RootT,
typename OtherRootT,
bool Compatible = false>
3224 static inline void combine2(RootT&
self,
const RootT&,
const OtherRootT& other1,
3229 self.enforceSameConfiguration(other1);
3230 self.enforceCompatibleValueTypes(other1);
3232 std::ostringstream ostr;
3233 ostr <<
"cannot combine a " <<
typeid(OtherRootT).name()
3234 <<
" into a " <<
typeid(RootT).name();
3240 template<
typename CombineOp,
typename RootT,
typename OtherRootT>
3243 static inline void combine2(RootT&
self,
const RootT& other0,
const OtherRootT& other1,
3244 CombineOp& op,
bool prune)
3246 self.doCombine2(other0, other1, op, prune);
3251 template<
typename ChildT>
3252 template<
typename CombineOp,
typename OtherRootNode>
3255 CombineOp& op,
bool prune)
3257 using OtherValueType =
typename OtherRootNode::ValueType;
3261 *
this, other0, other1, op, prune);
3265 template<
typename ChildT>
3266 template<
typename CombineOp,
typename OtherRootNode>
3269 CombineOp& op,
bool prune)
3271 enforceSameConfiguration(other1);
3273 using OtherValueT =
typename OtherRootNode::ValueType;
3274 using OtherTileT =
typename OtherRootNode::Tile;
3275 using OtherNodeStructT =
typename OtherRootNode::NodeStruct;
3276 using OtherMapCIterT =
typename OtherRootNode::MapCIter;
3281 other0.insertKeys(keys);
3282 other1.insertKeys(keys);
3284 const NodeStruct bg0(Tile(other0.mBackground,
false));
3285 const OtherNodeStructT bg1(OtherTileT(other1.mBackground,
false));
3287 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3288 MapIter thisIter = this->findOrAddCoord(*i);
3289 MapCIter iter0 = other0.findKey(*i);
3290 OtherMapCIterT iter1 = other1.findKey(*i);
3291 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3292 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3293 if (ns0.isTile() && ns1.isTile()) {
3296 op(args.
setARef(ns0.tile.value)
3297 .setAIsActive(ns0.isTileOn())
3298 .setBRef(ns1.tile.value)
3299 .setBIsActive(ns1.isTileOn()));
3302 if (!isChild(thisIter)) {
3304 const Coord& childOrigin =
3305 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3306 setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
3308 ChildT& child = getChild(thisIter);
3313 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3314 }
else if (ns1.isTile()) {
3317 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3321 child.combine2(*ns0.child, *ns1.child, op);
3324 if (prune && isChild(thisIter)) getChild(thisIter).prune();
3328 op(args.
setARef(other0.mBackground).setBRef(other1.mBackground));
3329 mBackground = args.
result();
3336 template<
typename ChildT>
3337 template<
typename BBoxOp>
3341 const bool descent = op.template descent<LEVEL>();
3342 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3343 if (this->isTileOff(i))
continue;
3344 if (this->isChild(i) && descent) {
3345 this->getChild(i).visitActiveBBox(op);
3357 template<
typename ChildT>
3358 template<
typename VisitorOp>
3362 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
3366 template<
typename ChildT>
3367 template<
typename VisitorOp>
3371 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
3375 template<
typename ChildT>
3376 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
3380 typename RootNodeT::ValueType val;
3381 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
3382 if (op(iter))
continue;
3383 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3393 template<
typename ChildT>
3394 template<
typename OtherRootNodeType,
typename VisitorOp>
3399 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
3403 template<
typename ChildT>
3404 template<
typename OtherRootNodeType,
typename VisitorOp>
3409 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
3413 template<
typename ChildT>
3416 typename OtherRootNodeT,
3418 typename ChildAllIterT,
3419 typename OtherChildAllIterT>
3423 enforceSameConfiguration(other);
3425 typename RootNodeT::ValueType val;
3426 typename OtherRootNodeT::ValueType otherVal;
3431 RootNodeT copyOfSelf(
self.mBackground);
3432 copyOfSelf.mTable =
self.mTable;
3433 OtherRootNodeT copyOfOther(other.mBackground);
3434 copyOfOther.mTable = other.mTable;
3438 self.insertKeys(keys);
3439 other.insertKeys(keys);
3440 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3441 copyOfSelf.findOrAddCoord(*i);
3442 copyOfOther.findOrAddCoord(*i);
3445 ChildAllIterT iter = copyOfSelf.beginChildAll();
3446 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3448 for ( ; iter && otherIter; ++iter, ++otherIter)
3450 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3452 typename ChildAllIterT::ChildNodeType* child =
3453 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
3454 typename OtherChildAllIterT::ChildNodeType* otherChild =
3455 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
3457 if (child !=
nullptr && otherChild !=
nullptr) {
3458 child->visit2Node(*otherChild, op);
3459 }
else if (child !=
nullptr) {
3460 child->visit2(otherIter, op);
3461 }
else if (otherChild !=
nullptr) {
3462 otherChild->visit2(iter, op,
true);
3467 copyOfSelf.eraseBackgroundTiles();
3468 copyOfOther.eraseBackgroundTiles();
3472 self.resetTable(copyOfSelf.mTable);
3473 other.resetTable(copyOfOther.mTable);
3480 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:372
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:485
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:419
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1233
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2417
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1949
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
Int32 x() const
Definition: Coord.h:157
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:473
Index getWidth() const
Definition: RootNode.h:487
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1680
Definition: RootNode.h:66
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:2647
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:329
ChildType ChildNodeType
Definition: RootNode.h:73
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:417
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2012
typename boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:1016
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2257
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:395
Definition: NodeMasks.h:1068
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1436
~RootNode()
Definition: RootNode.h:155
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:455
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
ChildOnIter beginChildOn()
Definition: RootNode.h:413
typename ChildType::BuildType BuildType
Definition: RootNode.h:76
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:2600
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:397
Index64 onTileCount() const
Definition: RootNode.h:1630
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:116
static Index getChildDim()
Definition: RootNode.h:482
RootNode(const RootNode &other)
Definition: RootNode.h:107
bool resultIsActive() const
Definition: Types.h:450
ChildOffCIter beginChildOff() const
Definition: RootNode.h:411
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:416
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1320
const Coord & min() const
Definition: Coord.h:337
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
ValueOffIter beginValueOff()
Definition: RootNode.h:424
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1894
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:562
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
Definition: Exceptions.h:91
bool isOn(Index32 i) const
Definition: NodeMasks.h:1333
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:1875
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1853
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:2137
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:1206
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1463
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:2566
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:392
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:496
Coord & setY(Int32 y)
Definition: Coord.h:107
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1985
const Int32 * asPointer() const
Definition: Coord.h:168
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:2079
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1763
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:3125
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:63
typename boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:1022
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:1488
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:1834
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:404
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1115
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2851
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:2491
void read(std::istream &is)
Definition: Coord.h:246
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1049
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:394
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2059
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1133
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3224
Index64 offVoxelCount() const
Definition: RootNode.h:1591
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2451
ValueAllCIter beginValueAll() const
Definition: RootNode.h:422
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:202
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
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:3089
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:235
Definition: Exceptions.h:92
int32_t Int32
Definition: Types.h:63
Int32 z() const
Definition: Coord.h:159
Index32 leafCount() const
Definition: RootNode.h:1549
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1607
Definition: version.h:219
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1267
ValueOffCIter beginValueOff() const
Definition: RootNode.h:421
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3254
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:1704
typename NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:81
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1306
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1336
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:3339
bool hasActiveTiles() const
Return true if this root node, or any of its child nodes, have active tiles.
Definition: RootNode.h:1657
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1329
ChildAllIter beginChildAll()
Definition: RootNode.h:415
Definition: Exceptions.h:40
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1648
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:409
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:2775
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:2512
ChildOffIter beginChildOff()
Definition: RootNode.h:414
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1726
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:96
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:418
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:118
Index getDepth() const
Definition: RootNode.h:489
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2407
ValueOnCIter beginValueOn() const
Definition: RootNode.h:420
Coord & setZ(Int32 z)
Definition: Coord.h:108
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:386
Index32 Index
Definition: Types.h:61
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:393
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:395
const AValueType & result() const
Get the output value.
Definition: Types.h:431
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:246
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1255
Definition: RootNode.h:64
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:834
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:402
Int32 y() const
Definition: Coord.h:158
uint64_t Index64
Definition: Types.h:60
Definition: RootNode.h:65
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:335
Index32 nonLeafCount() const
Definition: RootNode.h:1561
ValueAllIter beginValueAll()
Definition: RootNode.h:425
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2293
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:408
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:403
typename ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:74
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:439
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:2531
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2941
Definition: RootNode.h:70
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:86
Coord & setX(Int32 x)
Definition: Coord.h:106
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:438
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:2909
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:158
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1344
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:399
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:2750
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:2732
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:400
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:2213
void clear()
Definition: RootNode.h:1477
ChildAllCIter beginChildAll() const
Definition: RootNode.h:412
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:407
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:3053
ValueOnIter beginValueOn()
Definition: RootNode.h:423
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...
static Index getLevel()
Definition: RootNode.h:480
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:2767
const Coord & max() const
Definition: Coord.h:338
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:1357
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3243
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:88
typename ChildType::ValueType ValueType
Definition: RootNode.h:75
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:358
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:645
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
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:1917
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:401
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:404
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1810
void translate(const Coord &t)
Definition: Coord.h:462
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:1740
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...
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1171
typename NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:1015
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2187
void load(std::istream &is)
Definition: NodeMasks.h:1374
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:396
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:520
void visit(VisitorOp &)
Definition: RootNode.h:3360
Index64 onVoxelCount() const
Definition: RootNode.h:1575
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:518
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1668
ChildOnCIter beginChildOn() const
Definition: RootNode.h:410
Index getHeight() const
Definition: RootNode.h:488
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:2830
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3396
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1404
uint32_t Index32
Definition: Types.h:59
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2043
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:2811
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1714
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:2688
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3164
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1619