35 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 36 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 42 #include <boost/type_traits/remove_const.hpp> 43 #include <boost/type_traits/remove_pointer.hpp> 44 #include <boost/type_traits/is_pointer.hpp> 45 #include <boost/type_traits/is_const.hpp> 46 #include <boost/mpl/contains.hpp> 47 #include <boost/mpl/if.hpp> 48 #include <boost/mpl/vector.hpp> 49 #include <boost/mpl/at.hpp> 50 #include <boost/mpl/push_back.hpp> 51 #include <boost/mpl/size.hpp> 52 #include <tbb/parallel_for.h> 68 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
74 template<
typename ChildType>
83 static const Index LEVEL = 1 + ChildType::LEVEL;
87 BOOST_STATIC_ASSERT(boost::mpl::size<NodeChainType>::value == LEVEL + 1);
91 template<
typename OtherValueType>
99 template<
typename OtherNodeType>
109 explicit RootNode(
const ValueType& background);
119 template<
typename OtherChildType>
130 template<
typename OtherChildType>
132 const ValueType& background,
const ValueType& foreground,
TopologyCopy);
144 template<
typename OtherChildType>
156 template<
typename OtherChildType>
163 Tile(): value(zeroVal<ValueType>()), active(
false) {}
164 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
174 NodeStruct(): child(
nullptr) {}
175 NodeStruct(ChildType& c): child(&c) {}
176 NodeStruct(
const Tile& t): child(
nullptr), tile(t) {}
177 NodeStruct(
const NodeStruct&) =
default;
178 NodeStruct& operator=(
const NodeStruct&) =
default;
181 bool isChild()
const {
return child !=
nullptr; }
182 bool isTile()
const {
return child ==
nullptr; }
183 bool isTileOff()
const {
return isTile() && !tile.active; }
184 bool isTileOn()
const {
return isTile() && tile.active; }
186 void set(ChildType& c) {
delete child; child = &c; }
187 void set(
const Tile& t) {
delete child; child =
nullptr; tile = t; }
188 ChildType& steal(
const Tile& t) { ChildType* c=child; child=
nullptr; tile=t;
return *c; }
191 typedef std::map<Coord, NodeStruct> MapType;
192 typedef typename MapType::iterator MapIter;
193 typedef typename MapType::const_iterator MapCIter;
195 typedef std::set<Coord> CoordSet;
196 typedef typename CoordSet::iterator CoordSetIter;
197 typedef typename CoordSet::const_iterator CoordSetCIter;
199 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
200 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
201 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
202 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
203 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
204 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
205 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
206 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
208 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
209 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
210 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
211 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
212 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
213 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
214 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
215 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
218 static inline bool test(
const MapIter&) {
return true; }
219 static inline bool test(
const MapCIter&) {
return true; }
222 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
223 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
225 struct ValueOffPred {
226 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
227 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
229 struct ValueAllPred {
230 static inline bool test(
const MapIter& i) {
return isTile(i); }
231 static inline bool test(
const MapCIter& i) {
return isTile(i); }
234 static inline bool test(
const MapIter& i) {
return isChild(i); }
235 static inline bool test(
const MapCIter& i) {
return isChild(i); }
237 struct ChildOffPred {
238 static inline bool test(
const MapIter& i) {
return isTile(i); }
239 static inline bool test(
const MapCIter& i) {
return isTile(i); }
242 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
246 typedef _RootNodeT RootNodeT;
247 typedef _MapIterT MapIterT;
251 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
253 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
255 RootNodeT* getParentNode()
const {
return mParentNode; }
257 RootNodeT& parent()
const 263 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
264 operator bool()
const {
return this->test(); }
266 void increment() { ++mIter; this->skip(); }
267 bool next() { this->increment();
return this->test(); }
268 void increment(
Index n) {
for (
int i = 0; i < n && this->next(); ++i) {} }
274 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
277 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
278 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
279 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
280 void setValueOff()
const { mIter->second.tile.active =
false; }
283 Coord getCoord()
const {
return mIter->first; }
285 void getCoord(Coord& xyz)
const { xyz = this->getCoord(); }
288 BaseIter(): mParentNode(
nullptr) {}
289 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
291 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
293 RootNodeT* mParentNode;
297 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
298 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
301 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
302 typedef RootNodeT NodeType;
303 typedef NodeType ValueType;
304 typedef ChildNodeT ChildNodeType;
305 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
306 typedef typename boost::remove_const<ValueType>::type NonConstValueType;
307 typedef typename boost::remove_const<ChildNodeType>::type NonConstChildNodeType;
311 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
313 ChildIter& operator++() { BaseT::increment();
return *
this; }
315 ChildNodeT& getValue()
const {
return getChild(mIter); }
316 ChildNodeT&
operator*()
const {
return this->getValue(); }
317 ChildNodeT* operator->()
const {
return &this->getValue(); }
320 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
321 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
324 typedef BaseIter<RootNodeT, MapIterT, FilterPredT> BaseT;
325 typedef RootNodeT NodeType;
326 typedef ValueT ValueType;
327 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
328 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
332 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
334 ValueIter& operator++() { BaseT::increment();
return *
this; }
336 ValueT& getValue()
const {
return getTile(mIter).value; }
337 ValueT&
operator*()
const {
return this->getValue(); }
338 ValueT* operator->()
const {
return &(this->getValue()); }
340 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
342 template<
typename ModifyOp>
343 void modifyValue(
const ModifyOp& op)
const 345 assert(isTile(mIter));
346 op(getTile(mIter).value);
350 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
351 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
354 typedef BaseIter<RootNodeT, MapIterT, NullPred> BaseT;
355 typedef RootNodeT NodeType;
356 typedef ValueT ValueType;
357 typedef ChildNodeT ChildNodeType;
358 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
359 typedef typename boost::remove_const<ValueT>::type NonConstValueType;
360 typedef typename boost::remove_const<ChildNodeT>::type NonConstChildNodeType;
364 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
366 DenseIter& operator++() { BaseT::increment();
return *
this; }
368 bool isChildNode()
const {
return isChild(mIter); }
370 ChildNodeT* probeChild(NonConstValueType& value)
const 372 if (isChild(mIter))
return &getChild(mIter);
373 value = getTile(mIter).value;
376 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const 378 child = this->probeChild(value);
379 return child !=
nullptr;
381 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
383 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
384 void setChild(ChildNodeT* c)
const { assert(c !=
nullptr); RootNodeT::setChild(mIter, *c); }
385 void setValue(
const ValueT& v)
const 387 if (isTile(mIter)) getTile(mIter).value = v;
391 else stealChild(mIter, Tile(v,
true));
396 typedef ChildIter<RootNode, MapIter, ChildOnPred, ChildType>
ChildOnIter;
397 typedef ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>
ChildOnCIter;
398 typedef ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>
ChildOffIter;
399 typedef ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>
ChildOffCIter;
400 typedef DenseIter<RootNode, MapIter, ChildType, ValueType>
ChildAllIter;
401 typedef DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>
ChildAllCIter;
403 typedef ValueIter<RootNode, MapIter, ValueOnPred, ValueType>
ValueOnIter;
404 typedef ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>
ValueOnCIter;
405 typedef ValueIter<RootNode, MapIter, ValueOffPred, ValueType>
ValueOffIter;
406 typedef ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>
ValueOffCIter;
407 typedef ValueIter<RootNode, MapIter, ValueAllPred, ValueType>
ValueAllIter;
408 typedef ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>
ValueAllCIter;
411 ChildOnCIter
cbeginChildOn()
const {
return ChildOnCIter(*
this, mTable.begin()); }
412 ChildOffCIter
cbeginChildOff()
const {
return ChildOffCIter(*
this, mTable.begin()); }
413 ChildAllCIter
cbeginChildAll()
const {
return ChildAllCIter(*
this, mTable.begin()); }
417 ChildOnIter
beginChildOn() {
return ChildOnIter(*
this, mTable.begin()); }
418 ChildOffIter
beginChildOff() {
return ChildOffIter(*
this, mTable.begin()); }
419 ChildAllIter
beginChildAll() {
return ChildAllIter(*
this, mTable.begin()); }
421 ValueOnCIter
cbeginValueOn()
const {
return ValueOnCIter(*
this, mTable.begin()); }
422 ValueOffCIter
cbeginValueOff()
const {
return ValueOffCIter(*
this, mTable.begin()); }
423 ValueAllCIter
cbeginValueAll()
const {
return ValueAllCIter(*
this, mTable.begin()); }
427 ValueOnIter
beginValueOn() {
return ValueOnIter(*
this, mTable.begin()); }
428 ValueOffIter
beginValueOff() {
return ValueOffIter(*
this, mTable.begin()); }
429 ValueAllIter
beginValueAll() {
return ValueAllIter(*
this, mTable.begin()); }
439 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
456 void setBackground(
const ValueType& value,
bool updateChildNodes);
462 bool isBackgroundTile(
const Tile&)
const;
464 bool isBackgroundTile(
const MapIter&)
const;
466 bool isBackgroundTile(
const MapCIter&)
const;
470 size_t numBackgroundTiles()
const;
473 size_t eraseBackgroundTiles();
477 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
482 bool expand(
const Coord& xyz);
485 static void getNodeLog2Dims(std::vector<Index>& dims);
491 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
492 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
493 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
496 Coord getMinIndex()
const;
498 Coord getMaxIndex()
const;
500 void getIndexRange(CoordBBox& bbox)
const;
504 template<
typename OtherChildType>
508 template<
typename OtherChildType>
513 template<
typename OtherChildType>
520 Index64 onLeafVoxelCount()
const;
521 Index64 offLeafVoxelCount()
const;
524 bool isValueOn(
const Coord& xyz)
const;
527 bool hasActiveTiles()
const;
529 const ValueType& getValue(
const Coord& xyz)
const;
530 bool probeValue(
const Coord& xyz, ValueType& value)
const;
535 int getValueDepth(
const Coord& xyz)
const;
538 void setActiveState(
const Coord& xyz,
bool on);
540 void setValueOnly(
const Coord& xyz,
const ValueType& value);
542 void setValueOn(
const Coord& xyz,
const ValueType& value);
544 void setValueOff(
const Coord& xyz);
546 void setValueOff(
const Coord& xyz,
const ValueType& value);
550 template<
typename ModifyOp>
551 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
553 template<
typename ModifyOp>
554 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
557 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
566 void sparseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true)
568 this->fill(bbox, value, active);
579 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
589 void voxelizeActiveTiles(
bool threaded =
true);
596 template<
typename DenseT>
597 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
603 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
604 bool readTopology(std::istream&,
bool fromHalf =
false);
606 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
607 void readBuffers(std::istream&,
bool fromHalf =
false);
608 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
618 template<
typename AccessorT>
619 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
624 template<
typename AccessorT>
625 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
631 template<
typename AccessorT>
632 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
638 template<
typename AccessorT>
639 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
646 template<
typename ModifyOp,
typename AccessorT>
647 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
653 template<
typename ModifyOp,
typename AccessorT>
654 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
660 template<
typename AccessorT>
661 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
667 template<
typename AccessorT>
668 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
675 template<
typename AccessorT>
676 bool probeValueAndCache(
const Coord& xyz, ValueType& value, AccessorT&)
const;
683 template<
typename AccessorT>
684 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
687 void clip(
const CoordBBox&);
694 void prune(
const ValueType& tolerance = zeroVal<ValueType>());
698 void addLeaf(LeafNodeType* leaf);
702 template<
typename AccessorT>
703 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
713 template<
typename NodeT>
714 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
718 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
723 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
727 template<
typename AccessorT>
728 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
735 LeafNodeType* touchLeaf(
const Coord& xyz);
739 template<
typename AccessorT>
740 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT& acc);
743 template <
typename NodeT>
746 NodeT* probeNode(
const Coord& xyz);
747 template <
typename NodeT>
748 const NodeT* probeConstNode(
const Coord& xyz)
const;
752 template<
typename NodeT,
typename AccessorT>
755 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
756 template<
typename NodeT,
typename AccessorT>
757 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
761 LeafNodeType* probeLeaf(
const Coord& xyz);
764 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
765 const LeafNodeType* probeLeaf(
const Coord& xyz)
const;
769 template<
typename AccessorT>
772 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
773 template<
typename AccessorT>
774 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
775 template<
typename AccessorT>
776 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
785 template<
typename ArrayT>
void getNodes(ArrayT& array);
808 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
812 template<
typename ArrayT>
836 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
837 template<
typename ArrayT>
848 template<MergePolicy Policy>
void merge(
RootNode& other);
863 template<
typename OtherChildType>
879 template<
typename OtherChildType>
892 template<
typename OtherChildType>
895 template<
typename CombineOp>
896 void combine(
RootNode& other, CombineOp&,
bool prune =
false);
898 template<
typename CombineOp,
typename OtherRootNode >
899 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
900 CombineOp& op,
bool prune =
false);
907 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
909 template<
typename VisitorOp>
void visit(VisitorOp&);
910 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
912 template<
typename OtherRootNodeType,
typename VisitorOp>
913 void visit2(OtherRootNodeType& other, VisitorOp&);
914 template<
typename OtherRootNodeType,
typename VisitorOp>
915 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
928 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
930 void resetTable(
const MapType&)
const {}
933 Index getChildCount()
const;
934 Index getTileCount()
const;
935 Index getActiveTileCount()
const;
936 Index getInactiveTileCount()
const;
939 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
942 void insertKeys(CoordSet&)
const;
945 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
947 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
950 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
953 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
956 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
958 MapIter findOrAddCoord(
const Coord& xyz);
967 template<
typename OtherChildType>
975 template<
typename OtherChildType>
978 template<
typename CombineOp,
typename OtherRootNode >
979 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
981 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
982 static inline void doVisit(RootNodeT&, VisitorOp&);
984 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
985 typename ChildAllIterT,
typename OtherChildAllIterT>
986 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
990 ValueType mBackground;
1017 template<
typename HeadT,
int HeadLevel>
1020 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
1024 template<
typename HeadT>
1026 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
1034 template<
typename ChildT1,
typename NodeT2>
1038 static const bool value =
false;
1041 template<
typename ChildT1,
typename ChildT2>
1043 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1051 template<
typename ChildT>
1059 template<
typename ChildT>
1067 template<
typename ChildT>
1068 template<
typename OtherChildType>
1071 const ValueType& backgd,
const ValueType& foregd,
TopologyCopy):
1076 enforceSameConfiguration(other);
1078 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1081 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1082 mTable[i->first] = OtherRootT::isTile(i)
1083 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1084 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1089 template<
typename ChildT>
1090 template<
typename OtherChildType>
1098 enforceSameConfiguration(other);
1100 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1102 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1103 mTable[i->first] = OtherRootT::isTile(i)
1104 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1105 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1116 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1123 self.enforceSameConfiguration(other);
1124 self.enforceCompatibleValueTypes(other);
1126 std::ostringstream ostr;
1127 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1128 <<
" to a " <<
typeid(RootT).name();
1134 template<
typename RootT,
typename OtherRootT>
1139 typedef typename RootT::ValueType ValueT;
1140 typedef typename RootT::ChildNodeType ChildT;
1141 typedef typename RootT::NodeStruct NodeStruct;
1142 typedef typename RootT::Tile Tile;
1143 typedef typename OtherRootT::ValueType OtherValueT;
1144 typedef typename OtherRootT::MapCIter OtherMapCIter;
1145 typedef typename OtherRootT::Tile OtherTile;
1149 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1152 self.mBackground = Local::convertValue(other.mBackground);
1157 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1158 if (other.isTile(i)) {
1160 const OtherTile& otherTile = other.getTile(i);
1161 self.mTable[i->first] = NodeStruct(
1162 Tile(Local::convertValue(otherTile.value), otherTile.active));
1165 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1173 template<
typename ChildT>
1177 if (&other !=
this) {
1178 mBackground = other.mBackground;
1183 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1185 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1192 template<
typename ChildT>
1193 template<
typename OtherChildType>
1198 typedef typename OtherRootT::ValueType OtherValueT;
1208 template<
typename ChildT>
1214 if (updateChildNodes) {
1217 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1218 ChildT *child = iter->second.child;
1220 child->resetBackground(mBackground, background);
1222 Tile& tile = getTile(iter);
1223 if (tile.active)
continue;
1235 template<
typename ChildT>
1242 template<
typename ChildT>
1249 template<
typename ChildT>
1257 template<
typename ChildT>
1262 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1269 template<
typename ChildT>
1273 std::set<Coord> keysToErase;
1274 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1277 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1280 return keysToErase.size();
1287 template<
typename ChildT>
1291 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1292 keys.insert(i->first);
1297 template<
typename ChildT>
1298 inline typename RootNode<ChildT>::MapIter
1301 const Coord key = coordToKey(xyz);
1302 std::pair<MapIter, bool> result = mTable.insert(
1303 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1304 return result.first;
1308 template<
typename ChildT>
1312 const Coord key = coordToKey(xyz);
1313 std::pair<MapIter, bool> result = mTable.insert(
1314 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1315 return result.second;
1322 template<
typename ChildT>
1327 ChildT::getNodeLog2Dims(dims);
1331 template<
typename ChildT>
1335 return mTable.empty() ? Coord(0) : mTable.begin()->first;
1338 template<
typename ChildT>
1342 return mTable.empty() ? Coord(0) : mTable.rbegin()->first + Coord(ChildT::DIM - 1);
1346 template<
typename ChildT>
1358 template<
typename ChildT>
1359 template<
typename OtherChildType>
1364 typedef typename OtherRootT::MapType OtherMapT;
1365 typedef typename OtherRootT::MapIter OtherIterT;
1366 typedef typename OtherRootT::MapCIter OtherCIterT;
1371 OtherMapT copyOfOtherTable = other.mTable;
1374 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1378 OtherCIterT otherIter = other.findKey(thisIter->first);
1379 if (otherIter == other.mTable.end())
return false;
1382 if (isChild(thisIter)) {
1383 if (OtherRootT::isTile(otherIter))
return false;
1385 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1387 if (OtherRootT::isChild(otherIter))
return false;
1388 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1395 copyOfOtherTable.erase(otherIter->first);
1398 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1405 template<
typename ChildT>
1406 template<
typename OtherChildType>
1410 std::vector<Index> thisDims, otherDims;
1413 return (thisDims == otherDims);
1417 template<
typename ChildT>
1418 template<
typename OtherChildType>
1422 std::vector<Index> thisDims, otherDims;
1425 if (thisDims != otherDims) {
1426 std::ostringstream ostr;
1427 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1428 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1429 ostr <<
" vs. " << otherDims[0];
1430 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1437 template<
typename ChildT>
1438 template<
typename OtherChildType>
1442 typedef typename OtherChildType::ValueType OtherValueType;
1447 template<
typename ChildT>
1448 template<
typename OtherChildType>
1452 typedef typename OtherChildType::ValueType OtherValueType;
1454 std::ostringstream ostr;
1455 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1456 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1465 template<
typename ChildT>
1470 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1471 if (
const ChildT *child = iter->second.child) {
1472 sum += child->memUsage();
1479 template<
typename ChildT>
1483 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1484 delete i->second.child;
1490 template<
typename ChildT>
1494 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1495 if (
const ChildT *child = iter->second.child) {
1496 child->evalActiveBoundingBox(bbox, visitVoxels);
1497 }
else if (isTileOn(iter)) {
1498 bbox.expand(iter->first, ChildT::DIM);
1504 template<
typename ChildT>
1508 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1509 if (isChild(i)) ++sum;
1515 template<
typename ChildT>
1520 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1521 if (isTile(i)) ++sum;
1527 template<
typename ChildT>
1532 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1533 if (isTileOn(i)) ++sum;
1539 template<
typename ChildT>
1544 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1545 if (isTileOff(i)) ++sum;
1551 template<
typename ChildT>
1556 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1557 if (isChild(i)) sum += getChild(i).leafCount();
1563 template<
typename ChildT>
1568 if (ChildT::LEVEL != 0) {
1569 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1570 if (isChild(i)) sum += getChild(i).nonLeafCount();
1577 template<
typename ChildT>
1582 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1584 sum += getChild(i).onVoxelCount();
1585 }
else if (isTileOn(i)) {
1586 sum += ChildT::NUM_VOXELS;
1593 template<
typename ChildT>
1598 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1600 sum += getChild(i).offVoxelCount();
1602 sum += ChildT::NUM_VOXELS;
1609 template<
typename ChildT>
1614 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1615 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1621 template<
typename ChildT>
1626 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1627 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1632 template<
typename ChildT>
1637 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1639 sum += getChild(i).onTileCount();
1640 }
else if (isTileOn(i)) {
1650 template<
typename ChildT>
1654 MapCIter iter = this->findCoord(xyz);
1655 if (iter == mTable.end() || isTileOff(iter))
return false;
1656 return isTileOn(iter) ?
true : getChild(iter).isValueOn(xyz);
1659 template<
typename ChildT>
1663 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1664 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1669 template<
typename ChildT>
1670 template<
typename AccessorT>
1674 MapCIter iter = this->findCoord(xyz);
1675 if (iter == mTable.end() || isTileOff(iter))
return false;
1676 if (isTileOn(iter))
return true;
1677 acc.insert(xyz, &getChild(iter));
1678 return getChild(iter).isValueOnAndCache(xyz, acc);
1682 template<
typename ChildT>
1683 inline const typename ChildT::ValueType&
1686 MapCIter iter = this->findCoord(xyz);
1687 return iter == mTable.end() ? mBackground
1688 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1691 template<
typename ChildT>
1692 template<
typename AccessorT>
1693 inline const typename ChildT::ValueType&
1696 MapCIter iter = this->findCoord(xyz);
1697 if (iter == mTable.end())
return mBackground;
1698 if (isChild(iter)) {
1699 acc.insert(xyz, &getChild(iter));
1700 return getChild(iter).getValueAndCache(xyz, acc);
1702 return getTile(iter).value;
1706 template<
typename ChildT>
1710 MapCIter iter = this->findCoord(xyz);
1711 return iter == mTable.end() ? -1
1712 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1715 template<
typename ChildT>
1716 template<
typename AccessorT>
1720 MapCIter iter = this->findCoord(xyz);
1721 if (iter == mTable.end())
return -1;
1722 if (isTile(iter))
return 0;
1723 acc.insert(xyz, &getChild(iter));
1724 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1728 template<
typename ChildT>
1732 MapIter iter = this->findCoord(xyz);
1733 if (iter != mTable.end() && !isTileOff(iter)) {
1734 if (isTileOn(iter)) {
1735 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1737 getChild(iter).setValueOff(xyz);
1742 template<
typename ChildT>
1746 ChildT* child =
nullptr;
1747 MapIter iter = this->findCoord(xyz);
1748 if (iter == mTable.end()) {
1750 child =
new ChildT(xyz, mBackground);
1751 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1755 }
else if (isChild(iter)) {
1756 child = &getChild(iter);
1757 }
else if (on != getTile(iter).active) {
1758 child =
new ChildT(xyz, getTile(iter).value, !on);
1759 setChild(iter, *child);
1761 if (child) child->setActiveState(xyz, on);
1764 template<
typename ChildT>
1765 template<
typename AccessorT>
1769 ChildT* child =
nullptr;
1770 MapIter iter = this->findCoord(xyz);
1771 if (iter == mTable.end()) {
1773 child =
new ChildT(xyz, mBackground);
1774 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1778 }
else if (isChild(iter)) {
1779 child = &getChild(iter);
1780 }
else if (on != getTile(iter).active) {
1781 child =
new ChildT(xyz, getTile(iter).value, !on);
1782 setChild(iter, *child);
1785 acc.insert(xyz, child);
1786 child->setActiveStateAndCache(xyz, on, acc);
1791 template<
typename ChildT>
1795 ChildT* child =
nullptr;
1796 MapIter iter = this->findCoord(xyz);
1797 if (iter == mTable.end()) {
1799 child =
new ChildT(xyz, mBackground);
1800 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1802 }
else if (isChild(iter)) {
1803 child = &getChild(iter);
1805 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1806 setChild(iter, *child);
1808 if (child) child->setValueOff(xyz, value);
1811 template<
typename ChildT>
1812 template<
typename AccessorT>
1816 ChildT* child =
nullptr;
1817 MapIter iter = this->findCoord(xyz);
1818 if (iter == mTable.end()) {
1820 child =
new ChildT(xyz, mBackground);
1821 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1823 }
else if (isChild(iter)) {
1824 child = &getChild(iter);
1826 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1827 setChild(iter, *child);
1830 acc.insert(xyz, child);
1831 child->setValueOffAndCache(xyz, value, acc);
1836 template<
typename ChildT>
1840 ChildT* child =
nullptr;
1841 MapIter iter = this->findCoord(xyz);
1842 if (iter == mTable.end()) {
1843 child =
new ChildT(xyz, mBackground);
1844 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1845 }
else if (isChild(iter)) {
1846 child = &getChild(iter);
1848 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1849 setChild(iter, *child);
1851 if (child) child->setValueOn(xyz, value);
1854 template<
typename ChildT>
1855 template<
typename AccessorT>
1859 ChildT* child =
nullptr;
1860 MapIter iter = this->findCoord(xyz);
1861 if (iter == mTable.end()) {
1862 child =
new ChildT(xyz, mBackground);
1863 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1864 }
else if (isChild(iter)) {
1865 child = &getChild(iter);
1867 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1868 setChild(iter, *child);
1871 acc.insert(xyz, child);
1872 child->setValueAndCache(xyz, value, acc);
1877 template<
typename ChildT>
1881 ChildT* child =
nullptr;
1882 MapIter iter = this->findCoord(xyz);
1883 if (iter == mTable.end()) {
1884 child =
new ChildT(xyz, mBackground);
1885 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1886 }
else if (isChild(iter)) {
1887 child = &getChild(iter);
1889 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1890 setChild(iter, *child);
1892 if (child) child->setValueOnly(xyz, value);
1895 template<
typename ChildT>
1896 template<
typename AccessorT>
1900 ChildT* child =
nullptr;
1901 MapIter iter = this->findCoord(xyz);
1902 if (iter == mTable.end()) {
1903 child =
new ChildT(xyz, mBackground);
1904 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1905 }
else if (isChild(iter)) {
1906 child = &getChild(iter);
1908 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1909 setChild(iter, *child);
1912 acc.insert(xyz, child);
1913 child->setValueOnlyAndCache(xyz, value, acc);
1918 template<
typename ChildT>
1919 template<
typename ModifyOp>
1923 ChildT* child =
nullptr;
1924 MapIter iter = this->findCoord(xyz);
1925 if (iter == mTable.end()) {
1926 child =
new ChildT(xyz, mBackground);
1927 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1928 }
else if (isChild(iter)) {
1929 child = &getChild(iter);
1933 bool createChild = isTileOff(iter);
1937 const ValueType& tileVal = getTile(iter).value;
1938 ValueType modifiedVal = tileVal;
1943 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1944 setChild(iter, *child);
1947 if (child) child->modifyValue(xyz, op);
1950 template<
typename ChildT>
1951 template<
typename ModifyOp,
typename AccessorT>
1955 ChildT* child =
nullptr;
1956 MapIter iter = this->findCoord(xyz);
1957 if (iter == mTable.end()) {
1958 child =
new ChildT(xyz, mBackground);
1959 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1960 }
else if (isChild(iter)) {
1961 child = &getChild(iter);
1965 bool createChild = isTileOff(iter);
1969 const ValueType& tileVal = getTile(iter).value;
1970 ValueType modifiedVal = tileVal;
1975 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1976 setChild(iter, *child);
1980 acc.insert(xyz, child);
1981 child->modifyValueAndCache(xyz, op, acc);
1986 template<
typename ChildT>
1987 template<
typename ModifyOp>
1991 ChildT* child =
nullptr;
1992 MapIter iter = this->findCoord(xyz);
1993 if (iter == mTable.end()) {
1994 child =
new ChildT(xyz, mBackground);
1995 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1996 }
else if (isChild(iter)) {
1997 child = &getChild(iter);
1999 const Tile& tile = getTile(iter);
2000 bool modifiedState = tile.active;
2001 ValueType modifiedVal = tile.value;
2002 op(modifiedVal, modifiedState);
2006 child =
new ChildT(xyz, tile.value, tile.active);
2007 setChild(iter, *child);
2010 if (child) child->modifyValueAndActiveState(xyz, op);
2013 template<
typename ChildT>
2014 template<
typename ModifyOp,
typename AccessorT>
2017 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2019 ChildT* child =
nullptr;
2020 MapIter iter = this->findCoord(xyz);
2021 if (iter == mTable.end()) {
2022 child =
new ChildT(xyz, mBackground);
2023 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2024 }
else if (isChild(iter)) {
2025 child = &getChild(iter);
2027 const Tile& tile = getTile(iter);
2028 bool modifiedState = tile.active;
2029 ValueType modifiedVal = tile.value;
2030 op(modifiedVal, modifiedState);
2034 child =
new ChildT(xyz, tile.value, tile.active);
2035 setChild(iter, *child);
2039 acc.insert(xyz, child);
2040 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2045 template<
typename ChildT>
2049 MapCIter iter = this->findCoord(xyz);
2050 if (iter == mTable.end()) {
2051 value = mBackground;
2053 }
else if (isChild(iter)) {
2054 return getChild(iter).probeValue(xyz, value);
2056 value = getTile(iter).value;
2057 return isTileOn(iter);
2060 template<
typename ChildT>
2061 template<
typename AccessorT>
2065 MapCIter iter = this->findCoord(xyz);
2066 if (iter == mTable.end()) {
2067 value = mBackground;
2069 }
else if (isChild(iter)) {
2070 acc.insert(xyz, &getChild(iter));
2071 return getChild(iter).probeValueAndCache(xyz, value, acc);
2073 value = getTile(iter).value;
2074 return isTileOn(iter);
2081 template<
typename ChildT>
2085 if (bbox.empty())
return;
2090 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2092 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2094 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2098 Coord tileMin = coordToKey(xyz);
2099 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2101 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
2105 ChildT* child =
nullptr;
2106 MapIter iter = this->findKey(tileMin);
2107 if (iter == mTable.end()) {
2110 child =
new ChildT(xyz, mBackground);
2111 mTable[tileMin] = NodeStruct(*child);
2112 }
else if (isTile(iter)) {
2115 const Tile& tile = getTile(iter);
2116 child =
new ChildT(xyz, tile.value, tile.active);
2117 mTable[tileMin] = NodeStruct(*child);
2118 }
else if (isChild(iter)) {
2119 child = &getChild(iter);
2124 child->fill(CoordBBox(xyz, tmp), value, active);
2130 MapIter iter = this->findOrAddCoord(tileMin);
2131 setTile(iter, Tile(value, active));
2139 template<
typename ChildT>
2143 if (bbox.empty())
return;
2145 if (active && mTable.empty()) {
2155 Coord xyz, tileMin, tileMax;
2156 for (
int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2158 for (
int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2160 for (
int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2164 tileMin = coordToKey(xyz);
2165 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2169 const auto iter = findOrAddCoord(tileMin);
2174 const auto& tile = getTile(iter);
2175 auto* child =
new ChildT{tileMin, tile.value, tile.active};
2176 setChild(iter, *child);
2179 getChild(iter).denseFill(bbox, value, active);
2189 template<
typename ChildT>
2197 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2198 if (this->isTileOff(i))
continue;
2199 ChildT* child = i->second.child;
2200 if (child ==
nullptr) {
2203 child =
new ChildT{i->first, this->getTile(i).value,
true};
2204 i->second.child = child;
2206 child->voxelizeActiveTiles(threaded);
2214 template<
typename ChildT>
2215 template<
typename DenseT>
2219 typedef typename DenseT::ValueType DenseValueType;
2221 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2222 const Coord&
min = dense.bbox().min();
2224 for (Coord xyz = bbox.min(); xyz[0] <= bbox.max()[0]; xyz[0] = nodeBBox.max()[0] + 1) {
2225 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] = nodeBBox.max()[1] + 1) {
2226 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] = nodeBBox.max()[2] + 1) {
2229 nodeBBox = CoordBBox::createCube(coordToKey(xyz), ChildT::DIM);
2234 MapCIter iter = this->findKey(nodeBBox.min());
2235 if (iter != mTable.end() && isChild(iter)) {
2236 getChild(iter).copyToDense(sub, dense);
2238 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2239 sub.translate(-min);
2240 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2241 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2242 DenseValueType* a1 = a0 + x*xStride;
2243 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2244 DenseValueType* a2 = a1 + y*yStride;
2245 for (
Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
2246 *a2 = DenseValueType(value);
2259 template<
typename ChildT>
2264 os.write(reinterpret_cast<const char*>(&mBackground),
sizeof(ValueType));
2267 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueType));
2271 const Index numTiles = this->getTileCount(), numChildren = this->getChildCount();
2272 os.write(reinterpret_cast<const char*>(&numTiles),
sizeof(
Index));
2273 os.write(reinterpret_cast<const char*>(&numChildren),
sizeof(
Index));
2275 if (numTiles == 0 && numChildren == 0)
return false;
2278 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2279 if (isChild(i))
continue;
2280 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2281 os.write(reinterpret_cast<const char*>(&getTile(i).value),
sizeof(ValueType));
2282 os.write(reinterpret_cast<const char*>(&getTile(i).active),
sizeof(
bool));
2285 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2286 if (isTile(i))
continue;
2287 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 *
sizeof(
Int32));
2288 getChild(i).writeTopology(os, toHalf);
2295 template<
typename ChildT>
2307 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2309 is.read(reinterpret_cast<char*>(&inside),
sizeof(ValueType));
2314 Coord rangeMin, rangeMax;
2315 is.read(reinterpret_cast<char*>(rangeMin.asPointer()), 3 *
sizeof(
Int32));
2316 is.read(reinterpret_cast<char*>(rangeMax.asPointer()), 3 *
sizeof(
Int32));
2319 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2321 for (
int i = 0; i < 3; ++i) {
2322 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2323 rangeMin[i] = offset[i] << ChildT::TOTAL;
2325 tableSize += log2Dim[i];
2326 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2328 log2Dim[3] = log2Dim[1] + log2Dim[2];
2329 tableSize = 1U << tableSize;
2337 for (
Index i = 0; i < tableSize; ++i) {
2341 origin[0] = (n >> log2Dim[3]) + offset[0];
2342 n &= (1U << log2Dim[3]) - 1;
2343 origin[1] = (n >> log2Dim[2]) + offset[1];
2344 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2345 origin <<= ChildT::TOTAL;
2347 if (childMask.isOn(i)) {
2349 #ifdef OPENVDB_2_ABI_COMPATIBLE 2350 ChildT* child =
new ChildT(origin, mBackground);
2352 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2354 child->readTopology(is);
2355 mTable[origin] = NodeStruct(*child);
2360 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2362 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2371 is.read(reinterpret_cast<char*>(&mBackground),
sizeof(ValueType));
2374 Index numTiles = 0, numChildren = 0;
2375 is.read(reinterpret_cast<char*>(&numTiles),
sizeof(
Index));
2376 is.read(reinterpret_cast<char*>(&numChildren),
sizeof(
Index));
2378 if (numTiles == 0 && numChildren == 0)
return false;
2385 for (
Index n = 0; n < numTiles; ++n) {
2386 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2387 is.read(reinterpret_cast<char*>(&value),
sizeof(ValueType));
2388 is.read(reinterpret_cast<char*>(&active),
sizeof(
bool));
2389 mTable[Coord(vec)] = NodeStruct(Tile(value, active));
2393 for (
Index n = 0; n < numChildren; ++n) {
2394 is.read(reinterpret_cast<char*>(vec), 3 *
sizeof(
Int32));
2396 #ifdef OPENVDB_2_ABI_COMPATIBLE 2397 ChildT* child =
new ChildT(origin, mBackground);
2399 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2401 child->readTopology(is, fromHalf);
2402 mTable[Coord(vec)] = NodeStruct(*child);
2409 template<
typename ChildT>
2413 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2414 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2419 template<
typename ChildT>
2423 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2424 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2429 template<
typename ChildT>
2433 const Tile bgTile(mBackground,
false);
2435 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2441 ChildT& child = getChild(i);
2442 child.readBuffers(is, clipBBox, fromHalf);
2446 this->
clip(clipBBox);
2453 template<
typename ChildT>
2457 const Tile bgTile(mBackground,
false);
2461 MapType copyOfTable(mTable);
2462 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2463 const Coord& xyz = i->first;
2464 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
2465 if (!clipBBox.hasOverlap(tileBBox)) {
2467 setTile(this->findCoord(xyz), bgTile);
2469 }
else if (!clipBBox.isInside(tileBBox)) {
2473 getChild(i).clip(clipBBox, mBackground);
2477 tileBBox.intersect(clipBBox);
2478 const Tile& origTile = getTile(i);
2479 setTile(this->findCoord(xyz), bgTile);
2480 this->
sparseFill(tileBBox, origTile.value, origTile.active);
2493 template<
typename ChildT>
2498 ValueType value = zeroVal<ValueType>();
2499 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2500 if (this->isTile(i))
continue;
2501 this->getChild(i).prune(tolerance);
2502 if (this->getChild(i).isConstant(value, state, tolerance)) {
2503 this->setTile(i, Tile(value, state));
2513 template<
typename ChildT>
2514 template<
typename NodeT>
2518 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2519 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2521 MapIter iter = this->findCoord(xyz);
2522 if (iter == mTable.end() || isTile(iter))
return nullptr;
2523 return (boost::is_same<NodeT, ChildT>::value)
2524 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2525 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2533 template<
typename ChildT>
2537 if (leaf ==
nullptr)
return;
2538 ChildT* child =
nullptr;
2539 const Coord& xyz = leaf->origin();
2540 MapIter iter = this->findCoord(xyz);
2541 if (iter == mTable.end()) {
2542 if (ChildT::LEVEL>0) {
2543 child =
new ChildT(xyz, mBackground,
false);
2545 child =
reinterpret_cast<ChildT*
>(leaf);
2547 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2548 }
else if (isChild(iter)) {
2549 if (ChildT::LEVEL>0) {
2550 child = &getChild(iter);
2552 child =
reinterpret_cast<ChildT*
>(leaf);
2553 setChild(iter, *child);
2556 if (ChildT::LEVEL>0) {
2557 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2559 child =
reinterpret_cast<ChildT*
>(leaf);
2561 setChild(iter, *child);
2563 child->addLeaf(leaf);
2567 template<
typename ChildT>
2568 template<
typename AccessorT>
2572 if (leaf ==
nullptr)
return;
2573 ChildT* child =
nullptr;
2574 const Coord& xyz = leaf->origin();
2575 MapIter iter = this->findCoord(xyz);
2576 if (iter == mTable.end()) {
2577 if (ChildT::LEVEL>0) {
2578 child =
new ChildT(xyz, mBackground,
false);
2580 child =
reinterpret_cast<ChildT*
>(leaf);
2582 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2583 }
else if (isChild(iter)) {
2584 if (ChildT::LEVEL>0) {
2585 child = &getChild(iter);
2587 child =
reinterpret_cast<ChildT*
>(leaf);
2588 setChild(iter, *child);
2591 if (ChildT::LEVEL>0) {
2592 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2594 child =
reinterpret_cast<ChildT*
>(leaf);
2596 setChild(iter, *child);
2598 acc.insert(xyz, child);
2599 child->addLeafAndCache(leaf, acc);
2602 template<
typename ChildT>
2606 MapIter iter = this->findCoord(xyz);
2607 if (iter == mTable.end()) {
2608 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2610 setTile(iter, Tile(value, state));
2614 template<
typename ChildT>
2617 const ValueType& value,
bool state)
2619 if (LEVEL >= level) {
2620 MapIter iter = this->findCoord(xyz);
2621 if (iter == mTable.end()) {
2622 if (LEVEL > level) {
2623 ChildT* child =
new ChildT(xyz, mBackground,
false);
2624 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2625 child->addTile(level, xyz, value, state);
2627 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2629 }
else if (isChild(iter)) {
2630 if (LEVEL > level) {
2631 getChild(iter).addTile(level, xyz, value, state);
2633 setTile(iter, Tile(value, state));
2636 if (LEVEL > level) {
2637 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2638 setChild(iter, *child);
2639 child->addTile(level, xyz, value, state);
2641 setTile(iter, Tile(value, state));
2648 template<
typename ChildT>
2649 template<
typename AccessorT>
2652 bool state, AccessorT& acc)
2654 if (LEVEL >= level) {
2655 MapIter iter = this->findCoord(xyz);
2656 if (iter == mTable.end()) {
2657 if (LEVEL > level) {
2658 ChildT* child =
new ChildT(xyz, mBackground,
false);
2659 acc.insert(xyz, child);
2660 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2661 child->addTileAndCache(level, xyz, value, state, acc);
2663 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2665 }
else if (isChild(iter)) {
2666 if (LEVEL > level) {
2667 ChildT* child = &getChild(iter);
2668 acc.insert(xyz, child);
2669 child->addTileAndCache(level, xyz, value, state, acc);
2671 setTile(iter, Tile(value, state));
2674 if (LEVEL > level) {
2675 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2676 acc.insert(xyz, child);
2677 setChild(iter, *child);
2678 child->addTileAndCache(level, xyz, value, state, acc);
2680 setTile(iter, Tile(value, state));
2690 template<
typename ChildT>
2691 inline typename ChildT::LeafNodeType*
2694 ChildT* child =
nullptr;
2695 MapIter iter = this->findCoord(xyz);
2696 if (iter == mTable.end()) {
2697 child =
new ChildT(xyz, mBackground,
false);
2698 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2699 }
else if (isChild(iter)) {
2700 child = &getChild(iter);
2702 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2703 setChild(iter, *child);
2705 return child->touchLeaf(xyz);
2709 template<
typename ChildT>
2710 template<
typename AccessorT>
2711 inline typename ChildT::LeafNodeType*
2714 ChildT* child =
nullptr;
2715 MapIter iter = this->findCoord(xyz);
2716 if (iter == mTable.end()) {
2717 child =
new ChildT(xyz, mBackground,
false);
2718 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2719 }
else if (isChild(iter)) {
2720 child = &getChild(iter);
2722 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2723 setChild(iter, *child);
2725 acc.insert(xyz, child);
2726 return child->touchLeafAndCache(xyz, acc);
2733 template<
typename ChildT>
2734 template<
typename NodeT>
2738 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2739 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2741 MapIter iter = this->findCoord(xyz);
2742 if (iter == mTable.end() || isTile(iter))
return nullptr;
2743 ChildT* child = &getChild(iter);
2744 return (boost::is_same<NodeT, ChildT>::value)
2745 ?
reinterpret_cast<NodeT*
>(child)
2746 : child->template probeNode<NodeT>(xyz);
2751 template<
typename ChildT>
2752 template<
typename NodeT>
2756 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2757 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2759 MapCIter iter = this->findCoord(xyz);
2760 if (iter == mTable.end() || isTile(iter))
return nullptr;
2761 const ChildT* child = &getChild(iter);
2762 return (boost::is_same<NodeT, ChildT>::value)
2763 ?
reinterpret_cast<const NodeT*
>(child)
2764 : child->template probeConstNode<NodeT>(xyz);
2769 template<
typename ChildT>
2770 inline typename ChildT::LeafNodeType*
2773 return this->
template probeNode<LeafNodeType>(xyz);
2777 template<
typename ChildT>
2778 inline const typename ChildT::LeafNodeType*
2781 return this->
template probeConstNode<LeafNodeType>(xyz);
2785 template<
typename ChildT>
2786 template<
typename AccessorT>
2787 inline typename ChildT::LeafNodeType*
2790 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2794 template<
typename ChildT>
2795 template<
typename AccessorT>
2796 inline const typename ChildT::LeafNodeType*
2799 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2803 template<
typename ChildT>
2804 template<
typename AccessorT>
2805 inline const typename ChildT::LeafNodeType*
2812 template<
typename ChildT>
2813 template<
typename NodeT,
typename AccessorT>
2817 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2818 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2820 MapIter iter = this->findCoord(xyz);
2821 if (iter == mTable.end() || isTile(iter))
return nullptr;
2822 ChildT* child = &getChild(iter);
2823 acc.insert(xyz, child);
2824 return (boost::is_same<NodeT, ChildT>::value)
2825 ?
reinterpret_cast<NodeT*
>(child)
2826 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2831 template<
typename ChildT>
2832 template<
typename NodeT,
typename AccessorT>
2836 if ((NodeT::LEVEL == ChildT::LEVEL && !(boost::is_same<NodeT, ChildT>::value)) ||
2837 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2839 MapCIter iter = this->findCoord(xyz);
2840 if (iter == mTable.end() || isTile(iter))
return nullptr;
2841 const ChildT* child = &getChild(iter);
2842 acc.insert(xyz, child);
2843 return (boost::is_same<NodeT, ChildT>::value)
2844 ?
reinterpret_cast<const NodeT*
>(child)
2845 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2852 template<
typename ChildT>
2853 template<
typename ArrayT>
2857 typedef typename ArrayT::value_type NodePtr;
2859 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2860 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2861 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2863 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2864 const ChildT, ChildT>::type ArrayChildT;
2866 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2867 if (ChildT* child = iter->second.child) {
2869 if (boost::is_same<NodePtr, ArrayChildT*>::value) {
2870 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2872 child->getNodes(array);
2879 template<
typename ChildT>
2880 template<
typename ArrayT>
2884 typedef typename ArrayT::value_type NodePtr;
2886 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2888 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2889 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2892 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2893 if (
const ChildNodeType *child = iter->second.child) {
2895 if (boost::is_same<NodePtr, const ChildT*>::value) {
2896 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2898 child->getNodes(array);
2907 template<
typename ChildT>
2908 template<
typename ArrayT>
2912 typedef typename ArrayT::value_type NodePtr;
2914 typedef typename boost::remove_pointer<NodePtr>::type NodeType;
2915 typedef typename boost::remove_const<NodeType>::type NonConstNodeType;
2916 typedef typename boost::mpl::contains<NodeChainType, NonConstNodeType>::type result;
2918 typedef typename boost::mpl::if_<boost::is_const<NodeType>,
2919 const ChildT, ChildT>::type ArrayChildT;
2921 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2922 if (ChildT* child = iter->second.child) {
2924 if (boost::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 typedef typename OtherRootT::MapCIter OtherCIterT;
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 typedef typename OtherRootT::MapCIter OtherCIterT;
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 typedef typename OtherRootT::MapCIter OtherCIterT;
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 typedef typename OtherRootNode::ValueType OtherValueType;
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 typedef typename OtherRootNode::ValueType OtherValueT;
3274 typedef typename OtherRootNode::Tile OtherTileT;
3275 typedef typename OtherRootNode::NodeStruct OtherNodeStructT;
3276 typedef typename OtherRootNode::MapCIter OtherMapCIterT;
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);
3348 op.operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
3350 op.template operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
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 void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1119
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:1921
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:1361
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1652
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:370
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:2535
uint32_t Index32
Definition: Types.h:55
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3396
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1684
ChildOffCIter beginChildOff() const
Definition: RootNode.h:415
Index getHeight() const
Definition: RootNode.h:492
RootNode(const RootNode &other)
Definition: RootNode.h:111
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:423
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2455
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Index getDepth() const
Definition: RootNode.h:493
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode. ...
Definition: RootNode.h:86
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1271
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:421
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:406
boost::mpl::vector< typename HeadT::ChildNodeType, HeadT >::type Type
Definition: RootNode.h:1026
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:2141
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3243
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...
ChildAllIter beginChildAll()
Definition: RootNode.h:419
Definition: RootNode.h:71
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:654
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1324
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ValueOffCIter beginValueOff() const
Definition: RootNode.h:425
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2855
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1259
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:502
BOOST_STATIC_ASSERT(boost::mpl::size< NodeChainType >::value==LEVEL+1)
Definition: RootNode.h:70
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1857
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2421
bool resultIsActive() const
Definition: Types.h:435
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:399
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2297
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:1838
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:422
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:510
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: Types.h:424
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:2217
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:2779
ChildType::BuildType BuildType
Definition: RootNode.h:81
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:442
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:2604
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:156
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:398
ChildAllCIter beginChildAll() const
Definition: RootNode.h:416
ChildType::ValueType ValueType
Definition: RootNode.h:80
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:2495
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1175
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3224
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:396
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1718
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
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:411
ChildOnIter beginChildOn()
Definition: RootNode.h:417
ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:79
ChildOffIter beginChildOff()
Definition: RootNode.h:418
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3254
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2191
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:2815
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:1708
Index getWidth() const
Definition: RootNode.h:491
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:2516
~RootNode()
Definition: RootNode.h:159
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2047
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1408
NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:1019
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1237
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a boost::mpl::vector that lists the types of th...
Definition: RootNode.h:68
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:400
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:92
#define OPENVDB_VERSION_NAME
Definition: version.h:43
ChildOnCIter beginChildOn() const
Definition: RootNode.h:414
ValueAllIter beginValueAll()
Definition: RootNode.h:429
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:100
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1730
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3164
Index32 leafCount() const
Definition: RootNode.h:1553
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:401
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:838
Definition: Exceptions.h:91
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:2083
Definition: version.h:100
ValueOnIter beginValueOn()
Definition: RootNode.h:427
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:477
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:2910
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: Types.h:371
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1333
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 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:2570
Index64 offVoxelCount() const
Definition: RootNode.h:1595
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1767
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
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1953
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:407
Definition: Exceptions.h:39
Index64 onVoxelCount() const
Definition: RootNode.h:1579
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1989
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1814
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:412
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:459
RootNode()
Construct a new tree with a background value of 0.
Definition: RootNode.h:1053
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:404
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:2736
void clear()
Definition: RootNode.h:1481
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:1492
void load(std::istream &is)
Definition: NodeMasks.h:1382
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:2692
const AValueType & result() const
Get the output value.
Definition: Types.h:416
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:2771
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:413
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:1879
ValueAllCIter beginValueAll() const
Definition: RootNode.h:426
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:397
Definition: RootNode.h:69
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:120
Definition: Exceptions.h:92
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:2754
Index64 onTileCount() const
Definition: RootNode.h:1634
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:489
uint64_t Index64
Definition: Types.h:56
bool hasActiveTiles() const
Return true if this root node, or any of its child nodes, have active tiles.
Definition: RootNode.h:1661
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1137
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2411
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1611
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:1744
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
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
static Index getLevel()
Definition: RootNode.h:484
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1623
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
boost::mpl::push_back< SubtreeT, HeadT >::type Type
Definition: RootNode.h:1020
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1310
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1672
ValueOffIter beginValueOff()
Definition: RootNode.h:428
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: Types.h:233
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:408
ValueOnCIter beginValueOn() const
Definition: RootNode.h:424
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2063
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:403
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:505
ChildType ChildNodeType
Definition: RootNode.h:78
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Definition: RootNode.h:75
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:566
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1440
RootNode< typename ChildType::template ValueConverter< OtherValueType >::Type > Type
Definition: RootNode.h:93
int32_t Int32
Definition: Types.h:59
Index32 Index
Definition: Types.h:57
Index32 nonLeafCount() const
Definition: RootNode.h:1565
void visit(VisitorOp &)
Definition: RootNode.h:3360
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:553
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1348
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:2834
static Index getChildDim()
Definition: RootNode.h:486
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:1210
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1467
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:2651
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2941
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2016
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1340
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...
bool isOn(Index32 i) const
Definition: NodeMasks.h:1341
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
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:405
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2261
Definition: NodeMasks.h:1076
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1898