35 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 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>
128 const ValueType& background,
const ValueType& foreground,
TopologyCopy);
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 255 if (!mParentNode)
OPENVDB_THROW(ValueError,
"iterator references a null parent node");
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;
299 using ValueType = NodeType;
300 using ChildNodeType = ChildNodeT;
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;
322 using ValueType = ValueT;
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;
352 using ValueType = ValueT;
353 using ChildNodeType = ChildNodeT;
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;
525 const ValueType& getValue(
const Coord& xyz)
const;
526 bool probeValue(
const Coord& xyz, ValueType& value)
const;
531 int getValueDepth(
const Coord& xyz)
const;
534 void setActiveState(
const Coord& xyz,
bool on);
536 void setValueOnly(
const Coord& xyz,
const ValueType& value);
538 void setValueOn(
const Coord& xyz,
const ValueType& value);
540 void setValueOff(
const Coord& xyz);
542 void setValueOff(
const Coord& xyz,
const ValueType& value);
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);
553 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
564 this->fill(bbox, value, active);
575 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
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;
690 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
694 void addLeaf(LeafNodeType* leaf);
698 template<
typename AccessorT>
699 void addLeafAndCache(LeafNodeType* leaf, 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);
719 void addTile(
Index level,
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&);
731 LeafNodeType* touchLeaf(
const Coord& xyz);
735 template<
typename AccessorT>
736 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
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;
757 LeafNodeType* probeLeaf(
const Coord& xyz);
760 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
761 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
765 template<
typename AccessorT>
768 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
769 template<
typename AccessorT>
770 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
771 template<
typename AccessorT>
772 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
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>
964 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
971 template<
typename OtherChildType>
972 static void enforceCompatibleValueTypes(
const RootNode<OtherChildType>& other);
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&);
986 ValueType mBackground;
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>
1170 inline RootNode<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;
1221 tile.value = background;
1228 mBackground = background;
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) {
1259 if (this->isBackgroundTile(i)) ++count;
1265 template<
typename ChildT>
1269 std::set<Coord> keysToErase;
1270 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1271 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
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
1295 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
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>
1346 bbox.
min() = this->getMinIndex();
1347 bbox.
max() = this->getMaxIndex();
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;
1364 if (!hasSameConfiguration(other))
return false;
1367 OtherMapT copyOfOtherTable = other.mTable;
1370 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1371 if (this->isBackgroundTile(thisIter))
continue;
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>
1513 RootNode<ChildT>::getTileCount()
const 1516 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1517 if (isTile(i)) ++sum;
1523 template<
typename ChildT>
1525 RootNode<ChildT>::getActiveTileCount()
const 1528 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1529 if (isTileOn(i)) ++sum;
1535 template<
typename ChildT>
1537 RootNode<ChildT>::getInactiveTileCount()
const 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();
1597 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
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()) {
2144 sparseFill(bbox, value, active);
2145 voxelizeActiveTiles(
true);
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));
2502 this->eraseBackgroundTiles();
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*
2804 return this->probeConstLeafAndCache(xyz, acc);
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 static Index getChildDim()
Definition: RootNode.h:482
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:408
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
ChildOffIter beginChildOff()
Definition: RootNode.h:414
Coord & setY(Int32 y)
Definition: Coord.h:107
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
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
Coord & setZ(Int32 z)
Definition: Coord.h:108
void read(std::istream &is)
Definition: Coord.h:246
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
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3254
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
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
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1853
ValueOffCIter beginValueOff() const
Definition: RootNode.h:421
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1255
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:158
ValueAllCIter beginValueAll() const
Definition: RootNode.h:422
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2059
Index32 Index
Definition: Types.h:61
Index64 onVoxelCount() const
Definition: RootNode.h:1575
ValueOnCIter beginValueOn() const
Definition: RootNode.h:420
uint64_t Index64
Definition: Types.h:60
Definition: RootNode.h:66
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition: RootNode.h:65
Coord & setX(Int32 x)
Definition: Coord.h:106
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
Index64 offVoxelCount() const
Definition: RootNode.h:1591
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
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1329
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2043
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2407
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1607
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:88
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:394
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:395
Int32 z() const
Definition: Coord.h:159
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:518
const Coord & max() const
Definition: Coord.h:338
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:419
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
ChildAllCIter beginChildAll() const
Definition: RootNode.h:412
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2012
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
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
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:399
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
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:438
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2187
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2417
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:400
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:473
const AValueType & result() const
Get the output value.
Definition: Types.h:431
void clear()
Definition: RootNode.h:1477
bool hasActiveTiles() const
Return true if this root node, or any of its child nodes, have active tiles.
Definition: RootNode.h:1657
const Int32 * asPointer() const
Definition: Coord.h:168
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1436
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:407
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
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
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
int32_t Int32
Definition: Types.h:63
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:86
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:63
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
Index getDepth() const
Definition: RootNode.h:489
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
Int32 x() const
Definition: Coord.h:157
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2293
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3396
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1726
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1115
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:402
bool resultIsActive() const
Definition: Types.h:450
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:417
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
Definition: Exceptions.h:91
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
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
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:403
typename boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:1016
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:404
typename NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode.
Definition: RootNode.h:81
void topologyIntersection(const RootNode< OtherChildType > &other)
Intersects this tree's set of active values with the active values of the other tree,...
Definition: RootNode.h:3089
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1344
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
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1233
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: RootNode.h:2767
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:409
Index32 nonLeafCount() const
Definition: RootNode.h:1561
uint32_t Index32
Definition: Types.h:59
ChildOnIter beginChildOn()
Definition: RootNode.h:413
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
Index getWidth() const
Definition: RootNode.h:487
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...
Index64 onTileCount() const
Definition: RootNode.h:1630
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
ChildType ChildNodeType
Definition: RootNode.h:73
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void visit(VisitorOp &)
Definition: RootNode.h:3360
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
ValueAllIter beginValueAll()
Definition: RootNode.h:425
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:396
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1949
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1668
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:416
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1171
ValueOnIter beginValueOn()
Definition: RootNode.h:423
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2257
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:96
LeafNodeType * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: RootNode.h:2688
const Coord & min() const
Definition: Coord.h:337
ChildOffCIter beginChildOff() const
Definition: RootNode.h:411
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
Definition: RootNode.h:70
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
Definition: Exceptions.h:40
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
const NodeT * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists,...
Definition: RootNode.h:2750
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1320
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2451
static Index getLevel()
Definition: RootNode.h:480
typename ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:74
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
typename ChildType::ValueType ValueType
Definition: RootNode.h:75
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:246
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1810
ChildOnCIter beginChildOn() const
Definition: RootNode.h:410
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1714
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
typename ChildType::BuildType BuildType
Definition: RootNode.h:76
void load(std::istream &is)
Definition: NodeMasks.h:1374
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:455
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1267
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2851
Definition: NodeMasks.h:1068
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:386
typename boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:1022
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1680
Library and file format version numbers.
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3164
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1648
Int32 y() const
Definition: Coord.h:158
Index getHeight() const
Definition: RootNode.h:488
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3243
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:401
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:485
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:335
RootNode(const RootNode &other)
Definition: RootNode.h:107
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1336
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1894
ValueOffIter beginValueOff()
Definition: RootNode.h:424
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1985
void topologyDifference(const RootNode< OtherChildType > &other)
Difference this tree's set of active values with the active values of the other tree,...
Definition: RootNode.h:3125
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:520
Index32 leafCount() const
Definition: RootNode.h:1549
~RootNode()
Definition: RootNode.h:155
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
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1619
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:439
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:329
Definition: version.h:219
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:395
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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2941
typename NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:1015
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:202
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3224
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1133
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:418
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:397
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:235
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
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1049
Definition: RootNode.h:64
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists,...
Definition: RootNode.h:2732
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 setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1763
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,...
Definition: RootNode.h:2775
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:404
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
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:496
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
bool isOn(Index32 i) const
Definition: NodeMasks.h:1333
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...
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1463
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:393
ChildAllIter beginChildAll()
Definition: RootNode.h:415
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:372
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:392
void translate(const Coord &t)
Definition: Coord.h:462
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:118