8#ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 
    9#define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED 
   18#include <openvdb/version.h> 
   19#include <tbb/parallel_for.h> 
   32template<
typename HeadType, 
int HeadLevel> 
struct NodeChain;
 
   33template<
typename, 
typename> 
struct SameRootConfig;
 
   34template<
typename, 
typename, 
bool> 
struct RootNodeCopyHelper;
 
   35template<
typename, 
typename, 
typename, 
bool> 
struct RootNodeCombineHelper;
 
   38template<
typename ChildType>
 
   51    static_assert(NodeChainType::Size == 
LEVEL + 1,
 
   52        "wrong number of entries in RootNode node chain");
 
   56    template<
typename OtherValueType>
 
   64    template<
typename OtherNodeType>
 
   84    template<
typename OtherChildType>
 
   95    template<
typename OtherChildType>
 
  109    template<
typename OtherChildType>
 
  121    template<
typename OtherChildType>
 
  128        Tile(): value(
zeroVal<ValueType>()), active(false) {}
 
  129        Tile(
const ValueType& v, 
bool b): value(v), active(b) {}
 
  139        NodeStruct(): child(nullptr) {}
 
  140        NodeStruct(ChildType& c): child(&c) {}
 
  141        NodeStruct(
const Tile& t): child(nullptr), tile(t) {}
 
  142        NodeStruct(
const NodeStruct&) = 
default;
 
  143        NodeStruct(NodeStruct&&) noexcept = default;
 
  144        NodeStruct& operator=(const NodeStruct&) = default;
 
  147        bool isChild()
 const { 
return child != 
nullptr; }
 
  148        bool isTile()
 const { 
return child == 
nullptr; }
 
  149        bool isTileOff()
 const { 
return isTile() && !tile.active; }
 
  150        bool isTileOn()
 const { 
return isTile() && tile.active; }
 
  152        void set(ChildType& c) { 
delete child; child = &c; }
 
  153        void set(
const Tile& t) { 
delete child; child = 
nullptr; tile = t; }
 
  154        ChildType& steal(
const Tile& t) { ChildType* c=child; child=
nullptr; tile=t; 
return *c; }
 
  157    using MapType = std::map<Coord, NodeStruct>;
 
  158    using MapIter = 
typename MapType::iterator;
 
  159    using MapCIter = 
typename MapType::const_iterator;
 
  161    using CoordSet = std::set<Coord>;
 
  162    using CoordSetIter = 
typename CoordSet::iterator;
 
  163    using CoordSetCIter = 
typename CoordSet::const_iterator;
 
  165    static void             setTile(
const MapIter& i, 
const Tile& t) { i->second.set(t); }
 
  166    static void             setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
 
  167    static Tile&            getTile(
const MapIter& i) { 
return i->second.tile; }
 
  168    static const Tile&      getTile(
const MapCIter& i) { 
return i->second.tile; }
 
  169    static ChildType&       getChild(
const MapIter& i) { 
return *(i->second.child); }
 
  170    static const ChildType& getChild(
const MapCIter& i) { 
return *(i->second.child); }
 
  171    static ChildType&       stealChild(
const MapIter& i, 
const Tile& t) {
return i->second.steal(t);}
 
  172    static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
 
  174    static bool isChild(
const MapCIter& i)   { 
return i->second.isChild(); }
 
  175    static bool isChild(
const MapIter& i)    { 
return i->second.isChild(); }
 
  176    static bool isTile(
const MapCIter& i)    { 
return i->second.isTile(); }
 
  177    static bool isTile(
const MapIter& i)     { 
return i->second.isTile(); }
 
  178    static bool isTileOff(
const MapCIter& i) { 
return i->second.isTileOff(); }
 
  179    static bool isTileOff(
const MapIter& i)  { 
return i->second.isTileOff(); }
 
  180    static bool isTileOn(
const MapCIter& i)  { 
return i->second.isTileOn(); }
 
  181    static bool isTileOn(
const MapIter& i)   { 
return i->second.isTileOn(); }
 
  184        static inline bool test(
const MapIter&) { 
return true; }
 
  185        static inline bool test(
const MapCIter&) { 
return true; }
 
  188        static inline bool test(
const MapIter& i) { 
return isTileOn(i); }
 
  189        static inline bool test(
const MapCIter& i) { 
return isTileOn(i); }
 
  191    struct ValueOffPred {
 
  192        static inline bool test(
const MapIter& i) { 
return isTileOff(i); }
 
  193        static inline bool test(
const MapCIter& i) { 
return isTileOff(i); }
 
  195    struct ValueAllPred {
 
  196        static inline bool test(
const MapIter& i) { 
return isTile(i); }
 
  197        static inline bool test(
const MapCIter& i) { 
return isTile(i); }
 
  200        static inline bool test(
const MapIter& i) { 
return isChild(i); }
 
  201        static inline bool test(
const MapCIter& i) { 
return isChild(i); }
 
  203    struct ChildOffPred {
 
  204        static inline bool test(
const MapIter& i) { 
return isTile(i); }
 
  205        static inline bool test(
const MapCIter& i) { 
return isTile(i); }
 
  208    template<
typename _RootNodeT, 
typename _MapIterT, 
typename FilterPredT>
 
  212        using RootNodeT = _RootNodeT;
 
  213        using MapIterT = _MapIterT; 
 
  217            return (mParentNode == other.mParentNode) && (mIter == other.mIter);
 
  219        bool operator!=(
const BaseIter& other)
 const { 
return !(*
this == other); }
 
  221        RootNodeT* getParentNode()
 const { 
return mParentNode; }
 
  223        RootNodeT& parent()
 const 
  225            if (!mParentNode) 
OPENVDB_THROW(ValueError, 
"iterator references a null parent node");
 
  229        bool test()
 const { 
OPENVDB_ASSERT(mParentNode); 
return mIter != mParentNode->mTable.end(); }
 
  230        operator bool()
 const { 
return this->test(); }
 
  232        void increment() { 
if (this->test()) { ++mIter; } this->skip(); }
 
  233        bool next() { this->increment(); 
return this->test(); }
 
  234        void increment(Index n) { 
for (Index i = 0; i < n && this->next(); ++i) {} }
 
  240            return !mParentNode ? 0U : 
Index(std::distance(mParentNode->mTable.begin(), mIter));
 
  243        bool isValueOn()
 const { 
return RootNodeT::isTileOn(mIter); }
 
  244        bool isValueOff()
 const { 
return RootNodeT::isTileOff(mIter); }
 
  245        void setValueOn(
bool on = 
true)
 const { mIter->second.tile.active = on; }
 
  246        void setValueOff()
 const { mIter->second.tile.active = 
false; }
 
  249        Coord getCoord()
 const { 
return mIter->first; }
 
  251        void getCoord(Coord& xyz)
 const { xyz = this->getCoord(); }
 
  254        BaseIter(): mParentNode(nullptr) {}
 
  255        BaseIter(RootNodeT& parent, 
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
 
  257        void skip() { 
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
 
  259        RootNodeT* mParentNode;
 
  263    template<
typename RootNodeT, 
typename MapIterT, 
typename FilterPredT, 
typename ChildNodeT>
 
  264    class ChildIter: 
public BaseIter<RootNodeT, MapIterT, FilterPredT>
 
  267        using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
 
  268        using NodeType = RootNodeT;
 
  269        using ValueType = NodeType;
 
  270        using ChildNodeType = ChildNodeT;
 
  271        using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
  272        using NonConstValueType = 
typename std::remove_const<ValueType>::type;
 
  273        using NonConstChildNodeType = 
typename std::remove_const<ChildNodeType>::type;
 
  277        ChildIter(RootNodeT& parent, 
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
 
  279        ChildIter& operator++() { BaseT::increment(); 
return *
this; }
 
  281        ChildNodeT& getValue()
 const { 
return getChild(mIter); }
 
  282        ChildNodeT& 
operator*()
 const { 
return this->getValue(); }
 
  283        ChildNodeT* operator->()
 const { 
return &this->getValue(); }
 
  286    template<
typename RootNodeT, 
typename MapIterT, 
typename FilterPredT, 
typename ValueT>
 
  287    class ValueIter: 
public BaseIter<RootNodeT, MapIterT, FilterPredT>
 
  290        using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
 
  291        using NodeType = RootNodeT;
 
  292        using ValueType = ValueT;
 
  293        using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
  294        using NonConstValueType = 
typename std::remove_const<ValueT>::type;
 
  298        ValueIter(RootNodeT& parent, 
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
 
  300        ValueIter& operator++() { BaseT::increment(); 
return *
this; }
 
  302        ValueT& getValue()
 const { 
return getTile(mIter).value; }
 
  303        ValueT& 
operator*()
 const { 
return this->getValue(); }
 
  304        ValueT* operator->()
 const { 
return &(this->getValue()); }
 
  306        void setValue(
const ValueT& v)
 const { 
OPENVDB_ASSERT(isTile(mIter)); getTile(mIter).value = v; }
 
  308        template<
typename ModifyOp>
 
  309        void modifyValue(
const ModifyOp& op)
 const 
  312            op(getTile(mIter).value);
 
  316    template<
typename RootNodeT, 
typename MapIterT, 
typename ChildNodeT, 
typename ValueT>
 
  317    class DenseIter: 
public BaseIter<RootNodeT, MapIterT, NullPred>
 
  320        using BaseT = BaseIter<RootNodeT, MapIterT, NullPred>;
 
  321        using NodeType = RootNodeT;
 
  322        using ValueType = ValueT;
 
  323        using ChildNodeType = ChildNodeT;
 
  324        using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
  325        using NonConstValueType = 
typename std::remove_const<ValueT>::type;
 
  326        using NonConstChildNodeType = 
typename std::remove_const<ChildNodeT>::type;
 
  330        DenseIter(RootNodeT& parent, 
const MapIterT& iter): BaseT(parent, iter) {}
 
  332        DenseIter& operator++() { BaseT::increment(); 
return *
this; }
 
  334        bool isChildNode()
 const { 
return isChild(mIter); }
 
  336        ChildNodeT* probeChild(NonConstValueType& value)
 const 
  338            if (isChild(mIter)) 
return &getChild(mIter);
 
  339            value = getTile(mIter).value;
 
  342        bool probeChild(ChildNodeT*& child, NonConstValueType& value)
 const 
  344            child = this->probeChild(value);
 
  345            return child != 
nullptr;
 
  347        bool probeValue(NonConstValueType& value)
 const { 
return !this->probeChild(value); }
 
  349        void setChild(ChildNodeT& c)
 const { RootNodeT::setChild(mIter, c); }
 
  350        void setChild(ChildNodeT* c)
 const { 
OPENVDB_ASSERT(c != 
nullptr); RootNodeT::setChild(mIter, *c); }
 
  351        void setValue(
const ValueT& v)
 const 
  353            if (isTile(mIter)) getTile(mIter).value = v;
 
  357            else stealChild(mIter, Tile(v, 
true));
 
  362    using ChildOnIter = ChildIter<RootNode, MapIter, ChildOnPred, ChildType>;
 
  363    using ChildOnCIter = ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>;
 
  364    using ChildOffIter = ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>;
 
  365    using ChildOffCIter = ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>;
 
  366    using ChildAllIter = DenseIter<RootNode, MapIter, ChildType, ValueType>;
 
  367    using ChildAllCIter = DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>;
 
  369    using ValueOnIter = ValueIter<RootNode, MapIter, ValueOnPred, ValueType>;
 
  370    using ValueOnCIter = ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>;
 
  371    using ValueOffIter = ValueIter<RootNode, MapIter, ValueOffPred, ValueType>;
 
  372    using ValueOffCIter = ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>;
 
  373    using ValueAllIter = ValueIter<RootNode, MapIter, ValueAllPred, ValueType>;
 
  374    using ValueAllCIter = ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>;
 
  475    template<
typename OtherChildType>
 
  479    template<
typename OtherChildType>
 
  484    template<
typename OtherChildType>
 
  528    template<typename ModifyOp>
 
  531    template<typename ModifyOp>
 
  546        this->
fill(bbox, value, active);
 
 
  574    template<
typename DenseT>
 
  596    template<
typename AccessorT>
 
  602    template<
typename AccessorT>
 
  609    template<
typename AccessorT>
 
  616    template<
typename AccessorT>
 
  624    template<
typename ModifyOp, 
typename AccessorT>
 
  631    template<
typename ModifyOp, 
typename AccessorT>
 
  638    template<
typename AccessorT>
 
  645    template<
typename AccessorT>
 
  653    template<
typename AccessorT>
 
  661    template<
typename AccessorT>
 
  680    template<
typename AccessorT>
 
  691    template<
typename NodeT>
 
  712    template<
typename AccessorT>
 
  730    template<
typename AccessorT>
 
  736    template <
typename NodeT>
 
  738    template <
typename NodeT>
 
  740    template <
typename NodeT>
 
  756    template<
typename NodeT, 
typename AccessorT>
 
  758    template<
typename NodeT, 
typename AccessorT>
 
  781    template<
typename AccessorT>
 
  783    template<
typename AccessorT>
 
  785    template<
typename AccessorT>
 
  846    template<
typename ArrayT> 
void getNodes(ArrayT& array);
 
  847    template<
typename ArrayT> 
void getNodes(ArrayT& array) 
const;
 
  874    template<
typename ArrayT>
 
  876    template<
typename ArrayT>
 
  905    template<
typename OtherChildType>
 
  921    template<
typename OtherChildType>
 
  934    template<
typename OtherChildType>
 
  937    template<
typename CombineOp>
 
  940    template<
typename CombineOp, 
typename OtherRootNode >
 
  942                  CombineOp& op, 
bool prune = 
false);
 
  957    bool hasKey(
const Coord& key)
 const { 
return mTable.find(key) != mTable.end(); }
 
  968    void insertKeys(CoordSet&) 
const;
 
  973    MapIter findKey(
const Coord& key) { 
return mTable.find(key); }
 
  974    MapCIter findKey(
const Coord& key)
 const { 
return mTable.find(key); }
 
  979    MapIter findCoord(
const Coord& xyz) { 
return mTable.find(coordToKey(xyz)); }
 
  980    MapCIter findCoord(
const Coord& xyz)
 const { 
return mTable.find(coordToKey(xyz)); }
 
  985    MapIter findOrAddCoord(
const Coord& xyz);
 
  991    template<
typename OtherChildType>
 
  992    static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
 
  999    template<
typename OtherChildType>
 
 1000    static void enforceCompatibleValueTypes(
const RootNode<OtherChildType>& other);
 
 1002    template<
typename CombineOp, 
typename OtherRootNode >
 
 1003    void doCombine2(
const RootNode&, 
const OtherRootNode&, CombineOp&, 
bool prune);
 
 1006    ValueType mBackground;
 
 1009    Index32 mTransientData = 0;
 
 
 1036template<
typename HeadT, 
int HeadLevel>
 
 1039    using Type = 
typename SubtreeT::template Append<HeadT>;
 
 
 1043template<
typename HeadT>
 
 1055template<
typename ChildT1, 
typename NodeT2>
 
 1060template<
typename ChildT1, 
typename ChildT2>
 
 1062    static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
 
 
 1070template<
typename ChildT>
 
 1079template<
typename ChildT>
 
 1088template<
typename ChildT>
 
 1089template<
typename OtherChildType>
 
 1093    : mBackground(backgd)
 
 1094    , mOrigin(other.mOrigin)
 
 1095    , mTransientData(other.mTransientData)
 
 1099    if (mOrigin != 
Coord(0,0,0)) {
 
 1103    enforceSameConfiguration(other);
 
 1105    const Tile bgTile(backgd, 
false), fgTile(foregd, 
true);
 
 1107    for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
 
 1108        mTable.emplace(i->first, OtherRootT::isTile(i)
 
 1109            ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
 
 1110            : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd, 
TopologyCopy()))));
 
 
 1115template<
typename ChildT>
 
 1116template<
typename OtherChildType>
 
 1120    : mBackground(backgd)
 
 1121    , mOrigin(other.mOrigin)
 
 1122    , mTransientData(other.mTransientData)
 
 1126    if (mOrigin != 
Coord(0,0,0)) {
 
 1130    enforceSameConfiguration(other);
 
 1132    const Tile bgTile(backgd, 
false), fgTile(backgd, 
true);
 
 1134    for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
 
 1135        mTable.emplace(i->first,
 
 1136            OtherRootT::isTile(i)
 
 1137            ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
 
 1138            : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, 
TopologyCopy()))));
 
 
 1149template<
typename RootT, 
typename OtherRootT, 
bool Compatible = false>
 
 1156        self.enforceSameConfiguration(other);
 
 1157        self.enforceCompatibleValueTypes(other);
 
 1159        std::ostringstream ostr;
 
 1160        ostr << 
"cannot convert a " << 
typeid(OtherRootT).name()
 
 1161            << 
" to a " << 
typeid(RootT).name();
 
 
 
 1167template<
typename RootT, 
typename OtherRootT>
 
 1172        using ValueT = 
typename RootT::ValueType;
 
 1173        using ChildT = 
typename RootT::ChildNodeType;
 
 1174        using Tile = 
typename RootT::Tile;
 
 1175        using OtherValueT = 
typename OtherRootT::ValueType;
 
 1176        using OtherMapCIter = 
typename OtherRootT::MapCIter;
 
 1177        using OtherTile = 
typename OtherRootT::Tile;
 
 1181            static inline ValueT convertValue(
const OtherValueT& val) { 
return ValueT(val); }
 
 1184        self.mBackground = Local::convertValue(other.mBackground);
 
 1185        if (other.mOrigin != 
Coord(0,0,0)) {
 
 1186            OPENVDB_THROW(
ValueError, 
"RootNodeCopyHelper::copyWithValueConversion: non-zero offsets are currently not supported");
 
 1188        self.mOrigin = other.mOrigin;
 
 1189        self.mTransientData = other.mTransientData;
 
 1193        for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 1194            if (other.isTile(i)) {
 
 1196                const OtherTile& otherTile = other.getTile(i);
 
 1197                self.mTable.emplace(i->first,
 
 1198                    Tile(Local::convertValue(otherTile.value), otherTile.active));
 
 1201                self.mTable.emplace(i->first, *(
new ChildT(other.getChild(i))));
 
 
 
 1209template<
typename ChildT>
 
 1210inline RootNode<ChildT>&
 
 1213    if (&other != 
this) {
 
 1214        mBackground = other.mBackground;
 
 1215        mOrigin = other.mOrigin;
 
 1216        if (mOrigin != 
Coord(0,0,0)) {
 
 1219        mTransientData = other.mTransientData;
 
 1223        for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 1224            mTable.emplace(i->first,
 
 1225                isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i)))));
 
 
 1232template<
typename ChildT>
 
 1233template<
typename OtherChildType>
 
 1238    using OtherValueT = 
typename OtherRootT::ValueType;
 
 
 1248template<
typename ChildT>
 
 1254    if (updateChildNodes) {
 
 1257        for (MapIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 1258            ChildT *child = 
iter->second.child;
 
 1260                child->resetBackground(mBackground, 
background);
 
 1262                Tile& tile = getTile(
iter);
 
 1263                if (tile.active) 
continue;
 
 
 1275template<
typename ChildT>
 
 1282template<
typename ChildT>
 
 1289template<
typename ChildT>
 
 1297template<
typename ChildT>
 
 1302    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 
 1309template<
typename ChildT>
 
 1313    std::set<Coord> keysToErase;
 
 1314    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1317    for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
 
 1320    return keysToErase.size();
 
 
 1327template<
typename ChildT>
 
 1329RootNode<ChildT>::insertKeys(CoordSet& keys)
 const 
 1331    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1332        keys.insert(i->first);
 
 1337template<
typename ChildT>
 
 1338inline typename RootNode<ChildT>::MapIter
 
 1339RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
 
 1341    const Coord key = coordToKey(xyz);
 
 1342    std::pair<MapIter, bool> result = mTable.try_emplace(key,
 
 1343        Tile(mBackground, 
false));
 
 1344    return result.first;
 
 1348template<
typename ChildT>
 
 1353    std::pair<MapIter, bool> result = mTable.try_emplace(key,
 
 1354        Tile(mBackground, 
false));
 
 1355    return result.second; 
 
 
 1362template<
typename ChildT>
 
 1367    ChildT::getNodeLog2Dims(dims);
 
 
 1371template<
typename ChildT>
 
 1375    return mTable.empty() ? 
Coord(0) : mTable.begin()->first;
 
 
 1378template<
typename ChildT>
 
 1382    return mTable.empty() ? 
Coord(0) : mTable.rbegin()->first + 
Coord(ChildT::DIM - 1);
 
 
 1386template<
typename ChildT>
 
 1398template<
typename ChildT>
 
 1399template<
typename OtherChildType>
 
 1404    using OtherMapT = 
typename OtherRootT::MapType;
 
 1405    using OtherIterT = 
typename OtherRootT::MapIter;
 
 1406    using OtherCIterT = 
typename OtherRootT::MapCIter;
 
 1411    OtherMapT copyOfOtherTable = other.mTable;
 
 1414    for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
 
 1418        OtherCIterT otherIter = other.findKey(thisIter->first);
 
 1419        if (otherIter == other.mTable.end()) 
return false;
 
 1422        if (isChild(thisIter)) {
 
 1423            if (OtherRootT::isTile(otherIter)) 
return false;
 
 1425            if (!getChild(thisIter).
hasSameTopology(&OtherRootT::getChild(otherIter))) 
return false;
 
 1427            if (OtherRootT::isChild(otherIter)) 
return false;
 
 1428            if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active) 
return false;
 
 1435        copyOfOtherTable.erase(otherIter->first);
 
 1438    for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
 
 
 1445template<
typename ChildT>
 
 1446template<
typename OtherChildType>
 
 1450    std::vector<Index> thisDims, otherDims;
 
 1453    return (thisDims == otherDims);
 
 
 1457template<
typename ChildT>
 
 1458template<
typename OtherChildType>
 
 1462    std::vector<Index> thisDims, otherDims;
 
 1465    if (thisDims != otherDims) {
 
 1466        std::ostringstream ostr;
 
 1467        ostr << 
"grids have incompatible configurations (" << thisDims[0];
 
 1468        for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr << 
" x " << thisDims[i];
 
 1469        ostr << 
" vs. " << otherDims[0];
 
 1470        for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr << 
" x " << otherDims[i];
 
 1477template<
typename ChildT>
 
 1478template<
typename OtherChildType>
 
 1482    using OtherValueType = 
typename OtherChildType::ValueType;
 
 
 1487template<
typename ChildT>
 
 1488template<
typename OtherChildType>
 
 1492    using OtherValueType = 
typename OtherChildType::ValueType;
 
 1494        std::ostringstream ostr;
 
 1505template<
typename ChildT>
 
 1510    for (MapCIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 1511        if (
const ChildT *child = 
iter->second.child) {
 
 1512            sum += child->memUsage();
 
 
 1519template<
typename ChildT>
 
 1523    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1524        delete i->second.child;
 
 
 1530template<
typename ChildT>
 
 1534    for (MapCIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 1535        if (
const ChildT *child = 
iter->second.child) {
 
 1536            child->evalActiveBoundingBox(bbox, visitVoxels);
 
 1537        } 
else if (isTileOn(
iter)) {
 
 
 1544template<
typename ChildT>
 
 1549    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1550        if (isChild(i)) sum += getChild(i).leafCount();
 
 
 1556template<
typename ChildT>
 
 1561    if (ChildT::LEVEL != 0) {
 
 1562        for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1563            if (isChild(i)) sum += getChild(i).nonLeafCount();
 
 
 1570template<
typename ChildT>
 
 1575    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1576        if (isChild(i)) ++sum;
 
 
 1582template<
typename ChildT>
 
 1587    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1588        if (isTile(i)) ++sum;
 
 
 1594template<
typename ChildT>
 
 1599    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1600        if (isTileOn(i)) ++sum;
 
 
 1606template<
typename ChildT>
 
 1611    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1612        if (isTileOff(i)) ++sum;
 
 
 1618template<
typename ChildT>
 
 1623    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1625            sum += getChild(i).onVoxelCount();
 
 1626        } 
else if (isTileOn(i)) {
 
 1627            sum += ChildT::NUM_VOXELS;
 
 
 1634template<
typename ChildT>
 
 1639    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1641            sum += getChild(i).offVoxelCount();
 
 1643            sum += ChildT::NUM_VOXELS;
 
 
 1650template<
typename ChildT>
 
 1655    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1656        if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
 
 
 1662template<
typename ChildT>
 
 1667    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1668        if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
 
 
 1673template<
typename ChildT>
 
 1678    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1680            sum += getChild(i).onTileCount();
 
 1681        } 
else if (isTileOn(i)) {
 
 
 1688template<
typename ChildT>
 
 1694    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1697            getChild(i).nodeCount(vec);
 
 1701    vec[ChildNodeType::LEVEL] = sum;
 
 
 1704template<
typename ChildT>
 
 1710    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1714            getChild(i).nodeCount(vec);
 
 1719    vec[ChildNodeType::LEVEL] = sum;
 
 
 1725template<
typename ChildT>
 
 1729    MapCIter 
iter = this->findCoord(xyz);
 
 1730    if (
iter == mTable.end() || isTileOff(
iter)) 
return false;
 
 1731    return isTileOn(
iter) ? true : getChild(
iter).isValueOn(xyz);
 
 
 1734template<
typename ChildT>
 
 1738    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 1739        if (isChild(i) ? getChild(i).
hasActiveTiles() : getTile(i).active) 
return true;
 
 
 1744template<
typename ChildT>
 
 1745template<
typename AccessorT>
 
 1749    MapCIter 
iter = this->findCoord(xyz);
 
 1750    if (
iter == mTable.end() || isTileOff(
iter)) 
return false;
 
 1751    if (isTileOn(
iter)) 
return true;
 
 1752    acc.insert(xyz, &getChild(
iter));
 
 1753    return getChild(
iter).isValueOnAndCache(xyz, acc);
 
 
 1757template<
typename ChildT>
 
 1758inline const typename ChildT::ValueType&
 
 1761    MapCIter 
iter = this->findCoord(xyz);
 
 1762    return iter == mTable.end() ? mBackground
 
 1763        : (isTile(
iter) ? getTile(
iter).value : getChild(
iter).getValue(xyz));
 
 
 1766template<
typename ChildT>
 
 1767template<
typename AccessorT>
 
 1768inline const typename ChildT::ValueType&
 
 1771    MapCIter 
iter = this->findCoord(xyz);
 
 1772    if (
iter == mTable.end()) 
return mBackground;
 
 1773    if (isChild(
iter)) {
 
 1774        acc.insert(xyz, &getChild(
iter));
 
 1775        return getChild(
iter).getValueAndCache(xyz, acc);
 
 1777    return getTile(
iter).value;
 
 
 1781template<
typename ChildT>
 
 1785    MapCIter 
iter = this->findCoord(xyz);
 
 1786    return iter == mTable.end() ? -1
 
 1787        : (isTile(
iter) ? 0 : int(
LEVEL) - int(getChild(
iter).getValueLevel(xyz)));
 
 
 1790template<
typename ChildT>
 
 1791template<
typename AccessorT>
 
 1795    MapCIter 
iter = this->findCoord(xyz);
 
 1796    if (
iter == mTable.end()) 
return -1;
 
 1797    if (isTile(
iter)) 
return 0;
 
 1798    acc.insert(xyz, &getChild(
iter));
 
 1799    return int(
LEVEL) - int(getChild(
iter).getValueLevelAndCache(xyz, acc));
 
 
 1803template<
typename ChildT>
 
 1807    MapIter 
iter = this->findCoord(xyz);
 
 1808    if (
iter != mTable.end() && !isTileOff(
iter)) {
 
 1809        if (isTileOn(
iter)) {
 
 1810            setChild(
iter, *
new ChildT(xyz, getTile(
iter).value, 
true));
 
 1812        getChild(
iter).setValueOff(xyz);
 
 
 1817template<
typename ChildT>
 
 1821    ChildT* child = 
nullptr;
 
 1823    MapIter 
iter = this->findKey(key);
 
 1824    if (
iter == mTable.end()) {
 
 1826            child = 
new ChildT(xyz, mBackground);
 
 1827            mTable.emplace(key, *child);
 
 1831    } 
else if (isChild(
iter)) {
 
 1832        child = &getChild(
iter);
 
 1833    } 
else if (on != getTile(
iter).active) {
 
 1834        child = 
new ChildT(xyz, getTile(
iter).value, !on);
 
 1835        setChild(
iter, *child);
 
 1837    if (child) child->setActiveState(xyz, on);
 
 
 1840template<
typename ChildT>
 
 1841template<
typename AccessorT>
 
 1845    ChildT* child = 
nullptr;
 
 1847    MapIter 
iter = this->findKey(key);
 
 1848    if (
iter == mTable.end()) {
 
 1850            child = 
new ChildT(xyz, mBackground);
 
 1851            mTable.emplace(key, *child);
 
 1855    } 
else if (isChild(
iter)) {
 
 1856        child = &getChild(
iter);
 
 1857    } 
else if (on != getTile(
iter).active) {
 
 1858        child = 
new ChildT(xyz, getTile(
iter).value, !on);
 
 1859        setChild(
iter, *child);
 
 1862        acc.insert(xyz, child);
 
 1863        child->setActiveStateAndCache(xyz, on, acc);
 
 
 1868template<
typename ChildT>
 
 1872    ChildT* child = 
nullptr;
 
 1874    MapIter 
iter = this->findKey(key);
 
 1875    if (
iter == mTable.end()) {
 
 1877            child = 
new ChildT(xyz, mBackground);
 
 1878            mTable.emplace(key, *child);
 
 1880    } 
else if (isChild(
iter)) {
 
 1881        child = &getChild(
iter);
 
 1883        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1884        setChild(
iter, *child);
 
 1886    if (child) child->setValueOff(xyz, value);
 
 
 1889template<
typename ChildT>
 
 1890template<
typename AccessorT>
 
 1894    ChildT* child = 
nullptr;
 
 1896    MapIter 
iter = this->findKey(key);
 
 1897    if (
iter == mTable.end()) {
 
 1899            child = 
new ChildT(xyz, mBackground);
 
 1900            mTable.emplace(key, *child);
 
 1902    } 
else if (isChild(
iter)) {
 
 1903        child = &getChild(
iter);
 
 1905        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1906        setChild(
iter, *child);
 
 1909        acc.insert(xyz, child);
 
 1910        child->setValueOffAndCache(xyz, value, acc);
 
 
 1915template<
typename ChildT>
 
 1919    ChildT* child = 
nullptr;
 
 1921    MapIter 
iter = this->findKey(key);
 
 1922    if (
iter == mTable.end()) {
 
 1923        child = 
new ChildT(xyz, mBackground);
 
 1924        mTable.emplace(key, *child);
 
 1925    } 
else if (isChild(
iter)) {
 
 1926        child = &getChild(
iter);
 
 1928        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1929        setChild(
iter, *child);
 
 1931    if (child) child->setValueOn(xyz, value);
 
 
 1934template<
typename ChildT>
 
 1935template<
typename AccessorT>
 
 1939    ChildT* child = 
nullptr;
 
 1941    MapIter 
iter = this->findKey(key);
 
 1942    if (
iter == mTable.end()) {
 
 1943        child = 
new ChildT(xyz, mBackground);
 
 1944        mTable.emplace(key, *child);
 
 1945    } 
else if (isChild(
iter)) {
 
 1946        child = &getChild(
iter);
 
 1948        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1949        setChild(
iter, *child);
 
 1952        acc.insert(xyz, child);
 
 1953        child->setValueAndCache(xyz, value, acc);
 
 
 1958template<
typename ChildT>
 
 1962    ChildT* child = 
nullptr;
 
 1964    MapIter 
iter = this->findKey(key);
 
 1965    if (
iter == mTable.end()) {
 
 1966        child = 
new ChildT(xyz, mBackground);
 
 1967        mTable.emplace(key, *child);
 
 1968    } 
else if (isChild(
iter)) {
 
 1969        child = &getChild(
iter);
 
 1971        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1972        setChild(
iter, *child);
 
 1974    if (child) child->setValueOnly(xyz, value);
 
 
 1977template<
typename ChildT>
 
 1978template<
typename AccessorT>
 
 1982    ChildT* child = 
nullptr;
 
 1984    MapIter 
iter = this->findKey(key);
 
 1985    if (
iter == mTable.end()) {
 
 1986        child = 
new ChildT(xyz, mBackground);
 
 1987        mTable.emplace(key, *child);
 
 1988    } 
else if (isChild(
iter)) {
 
 1989        child = &getChild(
iter);
 
 1991        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 1992        setChild(
iter, *child);
 
 1995        acc.insert(xyz, child);
 
 1996        child->setValueOnlyAndCache(xyz, value, acc);
 
 
 2001template<
typename ChildT>
 
 2002template<
typename ModifyOp>
 
 2006    ChildT* child = 
nullptr;
 
 2008    MapIter 
iter = this->findKey(key);
 
 2009    if (
iter == mTable.end()) {
 
 2010        child = 
new ChildT(xyz, mBackground);
 
 2011        mTable.emplace(key, *child);
 
 2012    } 
else if (isChild(
iter)) {
 
 2013        child = &getChild(
iter);
 
 2017        bool createChild = isTileOff(
iter);
 
 2027            child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2028            setChild(
iter, *child);
 
 2031    if (child) child->modifyValue(xyz, op);
 
 
 2034template<
typename ChildT>
 
 2035template<
typename ModifyOp, 
typename AccessorT>
 
 2039    ChildT* child = 
nullptr;
 
 2041    MapIter 
iter = this->findKey(key);
 
 2042    if (
iter == mTable.end()) {
 
 2043        child = 
new ChildT(xyz, mBackground);
 
 2044        mTable.emplace(key, *child);
 
 2045    } 
else if (isChild(
iter)) {
 
 2046        child = &getChild(
iter);
 
 2050        bool createChild = isTileOff(
iter);
 
 2060            child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2061            setChild(
iter, *child);
 
 2065        acc.insert(xyz, child);
 
 2066        child->modifyValueAndCache(xyz, op, acc);
 
 
 2071template<
typename ChildT>
 
 2072template<
typename ModifyOp>
 
 2076    ChildT* child = 
nullptr;
 
 2078    MapIter 
iter = this->findKey(key);
 
 2079    if (
iter == mTable.end()) {
 
 2080        child = 
new ChildT(xyz, mBackground);
 
 2081        mTable.emplace(key, *child);
 
 2082    } 
else if (isChild(
iter)) {
 
 2083        child = &getChild(
iter);
 
 2085        const Tile& tile = getTile(
iter);
 
 2086        bool modifiedState = tile.active;
 
 2088        op(modifiedVal, modifiedState);
 
 2092            child = 
new ChildT(xyz, tile.value, tile.active);
 
 2093            setChild(
iter, *child);
 
 2096    if (child) child->modifyValueAndActiveState(xyz, op);
 
 
 2099template<
typename ChildT>
 
 2100template<
typename ModifyOp, 
typename AccessorT>
 
 2103    const Coord& xyz, 
const ModifyOp& op, AccessorT& acc)
 
 2105    ChildT* child = 
nullptr;
 
 2107    MapIter 
iter = this->findKey(key);
 
 2108    if (
iter == mTable.end()) {
 
 2109        child = 
new ChildT(xyz, mBackground);
 
 2110        mTable.emplace(key, *child);
 
 2111    } 
else if (isChild(
iter)) {
 
 2112        child = &getChild(
iter);
 
 2114        const Tile& tile = getTile(
iter);
 
 2115        bool modifiedState = tile.active;
 
 2117        op(modifiedVal, modifiedState);
 
 2121            child = 
new ChildT(xyz, tile.value, tile.active);
 
 2122            setChild(
iter, *child);
 
 2126        acc.insert(xyz, child);
 
 2127        child->modifyValueAndActiveStateAndCache(xyz, op, acc);
 
 
 2132template<
typename ChildT>
 
 2136    MapCIter 
iter = this->findCoord(xyz);
 
 2137    if (
iter == mTable.end()) {
 
 2138        value = mBackground;
 
 2140    } 
else if (isChild(
iter)) {
 
 2141        return getChild(
iter).probeValue(xyz, value);
 
 2143    value = getTile(
iter).value;
 
 2144    return isTileOn(
iter);
 
 
 2147template<
typename ChildT>
 
 2148template<
typename AccessorT>
 
 2152    MapCIter 
iter = this->findCoord(xyz);
 
 2153    if (
iter == mTable.end()) {
 
 2154        value = mBackground;
 
 2156    } 
else if (isChild(
iter)) {
 
 2157        acc.insert(xyz, &getChild(
iter));
 
 2158        return getChild(
iter).probeValueAndCache(xyz, value, acc);
 
 2160    value = getTile(
iter).value;
 
 2161    return isTileOn(
iter);
 
 
 2168template<
typename ChildT>
 
 2172    if (bbox.
empty()) 
return;
 
 2177    for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
 
 2179        for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
 
 2181            for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
 
 2186                tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
 
 2192                    ChildT* child = 
nullptr;
 
 2193                    MapIter 
iter = this->findKey(tileMin);
 
 2194                    if (
iter == mTable.end()) {
 
 2197                        child = 
new ChildT(xyz, mBackground);
 
 2198                        mTable.emplace(tileMin, *child);
 
 2199                    } 
else if (isTile(
iter)) {
 
 2202                        const Tile& tile = getTile(
iter);
 
 2203                        child = 
new ChildT(xyz, tile.value, tile.active);
 
 2204                        setChild(
iter, *child);
 
 2205                    } 
else if (isChild(
iter)) {
 
 2206                        child = &getChild(
iter);
 
 2211                        child->fill(
CoordBBox(xyz, tmp), value, active);
 
 2217                    MapIter 
iter = this->findOrAddCoord(tileMin);
 
 2218                    setTile(
iter, Tile(value, active));
 
 
 2226template<
typename ChildT>
 
 2230    if (bbox.
empty()) 
return;
 
 2232    if (active && mTable.empty()) {
 
 2242    Coord xyz, tileMin, tileMax;
 
 2243    for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
 
 2245        for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
 
 2247            for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
 
 2252                tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
 
 2256                const auto iter = findOrAddCoord(tileMin);
 
 2261                    const auto& tile = getTile(
iter);
 
 2262                    auto* child = 
new ChildT{tileMin, tile.value, tile.active};
 
 2263                    setChild(
iter, *child);
 
 2266                getChild(
iter).denseFill(bbox, value, active);
 
 
 2276template<
typename ChildT>
 
 2284    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2285        if (this->isTileOff(i)) 
continue;
 
 2286        ChildT* child = i->second.child;
 
 2287        if (child == 
nullptr) {
 
 2290            child = 
new ChildT{i->first, this->getTile(i).value, 
true};
 
 2291            i->second.child = child;
 
 2293        child->voxelizeActiveTiles(threaded);
 
 
 2301template<
typename ChildT>
 
 2302template<
typename DenseT>
 
 2306    using DenseValueType = 
typename DenseT::ValueType;
 
 2308    const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
 
 2309    const Coord& min = dense.bbox().min();
 
 2311    for (
Coord xyz = bbox.
min(); xyz[0] <= bbox.
max()[0]; xyz[0] = nodeBBox.
max()[0] + 1) {
 
 2312        for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] = nodeBBox.
max()[1] + 1) {
 
 2313            for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] = nodeBBox.
max()[2] + 1) {
 
 2321                MapCIter 
iter = this->findKey(nodeBBox.
min());
 
 2322                if (
iter != mTable.end() && isChild(
iter)) {
 
 2323                    getChild(
iter).copyToDense(sub, dense);
 
 2327                    DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
 
 2328                    for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
 
 2329                        DenseValueType* a1 = a0 + x*xStride;
 
 2330                        for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
 
 2331                            DenseValueType* a2 = a1 + y*yStride;
 
 2332                            for (
Int32 z=sub.
min()[2], ez=sub.
max()[2]+1; z<ez; ++z, a2 += zStride) {
 
 2333                                *a2 =  DenseValueType(value);
 
 
 2346template<
typename ChildT>
 
 2351        os.write(
reinterpret_cast<const char*
>(&mBackground), 
sizeof(
ValueType));
 
 2354        os.write(
reinterpret_cast<const char*
>(&truncatedVal), 
sizeof(
ValueType));
 
 2359    os.write(
reinterpret_cast<const char*
>(&numTiles), 
sizeof(
Index));
 
 2360    os.write(
reinterpret_cast<const char*
>(&numChildren), 
sizeof(
Index));
 
 2362    if (numTiles == 0 && numChildren == 0) 
return false;
 
 2365    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2366        if (isChild(i)) 
continue;
 
 2367        os.write(
reinterpret_cast<const char*
>(i->first.asPointer()), 3 * 
sizeof(
Int32));
 
 2368        os.write(
reinterpret_cast<const char*
>(&getTile(i).value), 
sizeof(
ValueType));
 
 2369        os.write(
reinterpret_cast<const char*
>(&getTile(i).active), 
sizeof(
bool));
 
 2372    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2373        if (isTile(i)) 
continue;
 
 2374        os.write(
reinterpret_cast<const char*
>(i->first.asPointer()), 3 * 
sizeof(
Int32));
 
 2375        getChild(i).writeTopology(os, toHalf);
 
 
 2382template<
typename ChildT>
 
 2394        is.read(
reinterpret_cast<char*
>(&mBackground), 
sizeof(
ValueType));
 
 2396        is.read(
reinterpret_cast<char*
>(&inside), 
sizeof(
ValueType));
 
 2401        Coord rangeMin, rangeMax;
 
 2403        is.read(
reinterpret_cast<char*
>(rangeMax.
asPointer()), 3 * 
sizeof(
Int32));
 
 2405        Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
 
 2407        for (
int i = 0; i < 3; ++i) {
 
 2408            offset[i] = rangeMin[i] >> ChildT::TOTAL;
 
 2409            rangeMin[i] = offset[i] << ChildT::TOTAL;
 
 2411            tableSize += log2Dim[i];
 
 2412            rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
 
 2414        log2Dim[3] = log2Dim[1] + log2Dim[2];
 
 2415        tableSize = 1U << tableSize;
 
 2423        for (
Index i = 0; i < tableSize; ++i) {
 
 2427            origin[0] = (n >> log2Dim[3]) + offset[0];
 
 2428            n &= (1U << log2Dim[3]) - 1;
 
 2429            origin[1] = (n >> log2Dim[2]) + offset[1];
 
 2430            origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
 
 2431            origin <<= ChildT::TOTAL;
 
 2433            if (childMask.isOn(i)) {
 
 2436                child->readTopology(is);
 
 2437                mTable.emplace(
origin, *child);
 
 2442                is.read(
reinterpret_cast<char*
>(&value), 
sizeof(
ValueType));
 
 2444                    mTable.emplace(
origin, Tile(value, valueMask.
isOn(i)));
 
 2453    is.read(
reinterpret_cast<char*
>(&mBackground), 
sizeof(
ValueType));
 
 2456    Index numTiles = 0, numChildren = 0;
 
 2457    is.read(
reinterpret_cast<char*
>(&numTiles), 
sizeof(
Index));
 
 2458    is.read(
reinterpret_cast<char*
>(&numChildren), 
sizeof(
Index));
 
 2460    if (numTiles == 0 && numChildren == 0) 
return false;
 
 2467    for (
Index n = 0; n < numTiles; ++n) {
 
 2468        is.read(
reinterpret_cast<char*
>(vec), 3 * 
sizeof(
Int32));
 
 2469        is.read(
reinterpret_cast<char*
>(&value), 
sizeof(
ValueType));
 
 2470        is.read(
reinterpret_cast<char*
>(&active), 
sizeof(
bool));
 
 2471        mTable.emplace(
Coord(vec), Tile(value, active));
 
 2475    for (
Index n = 0; n < numChildren; ++n) {
 
 2476        is.read(
reinterpret_cast<char*
>(vec), 3 * 
sizeof(
Int32));
 
 2479        child->readTopology(is, fromHalf);
 
 2480        mTable.emplace(
Coord(vec), *child);
 
 
 2487template<
typename ChildT>
 
 2491    for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2492        if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
 
 
 2497template<
typename ChildT>
 
 2501    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2502        if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
 
 
 2507template<
typename ChildT>
 
 2511    const Tile bgTile(mBackground, 
false);
 
 2513    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2519            ChildT& child = getChild(i);
 
 2520            child.readBuffers(is, clipBBox, fromHalf);
 
 2524    this->
clip(clipBBox);
 
 
 2531template<
typename ChildT>
 
 2535    const Tile bgTile(mBackground, 
false);
 
 2539    MapType copyOfTable(mTable);
 
 2540    for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
 
 2541        const Coord& xyz = i->first; 
 
 2545            setTile(this->findCoord(xyz), bgTile); 
 
 2547        } 
else if (!clipBBox.
isInside(tileBBox)) {
 
 2551                getChild(i).clip(clipBBox, mBackground);
 
 2556                const Tile& origTile = getTile(i);
 
 2557                setTile(this->findCoord(xyz), bgTile);
 
 2558                this->
sparseFill(tileBBox, origTile.value, origTile.active);
 
 
 2571template<
typename ChildT>
 
 2577    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 2578        if (this->isTile(i)) 
continue;
 
 2579        this->getChild(i).prune(tolerance);
 
 2580        if (this->getChild(i).isConstant(value, state, tolerance)) {
 
 2581            this->setTile(i, Tile(value, state));
 
 
 2591template<
typename ChildT>
 
 2592template<
typename NodeT>
 
 2596    if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
 
 2597         NodeT::LEVEL >  ChildT::LEVEL) 
return nullptr;
 
 2599    MapIter 
iter = this->findCoord(xyz);
 
 2600    if (
iter == mTable.end() || isTile(
iter)) 
return nullptr;
 
 2601    return (std::is_same<NodeT, ChildT>::value)
 
 2602        ? 
reinterpret_cast<NodeT*
>(&stealChild(
iter, Tile(value, state)))
 
 
 2611template<
typename ChildT>
 
 2615    if (leaf == 
nullptr) 
return;
 
 2616    ChildT* child = 
nullptr;
 
 2617    const Coord& xyz = leaf->origin();
 
 2619    MapIter 
iter = this->findKey(key);
 
 2620    if (
iter == mTable.end()) {
 
 2621        if (ChildT::LEVEL>0) {
 
 2622            child = 
new ChildT(xyz, mBackground, 
false);
 
 2624            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2626        mTable.emplace(key, *child);
 
 2627    } 
else if (isChild(
iter)) {
 
 2628        if (ChildT::LEVEL>0) {
 
 2629            child = &getChild(
iter);
 
 2631            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2632            setChild(
iter, *child);
 
 2635        if (ChildT::LEVEL>0) {
 
 2636            child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2638            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2640        setChild(
iter, *child);
 
 2642    child->addLeaf(leaf);
 
 
 2646template<
typename ChildT>
 
 2647template<
typename AccessorT>
 
 2651    if (leaf == 
nullptr) 
return;
 
 2652    ChildT* child = 
nullptr;
 
 2653    const Coord& xyz = leaf->origin();
 
 2655    MapIter 
iter = this->findKey(key);
 
 2656    if (
iter == mTable.end()) {
 
 2657        if (ChildT::LEVEL>0) {
 
 2658            child = 
new ChildT(xyz, mBackground, 
false);
 
 2660            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2662        mTable.emplace(key, *child);
 
 2663    } 
else if (isChild(
iter)) {
 
 2664        if (ChildT::LEVEL>0) {
 
 2665            child = &getChild(
iter);
 
 2667            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2668            setChild(
iter, *child);
 
 2671        if (ChildT::LEVEL>0) {
 
 2672            child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2674            child = 
reinterpret_cast<ChildT*
>(leaf);
 
 2676        setChild(
iter, *child);
 
 2678    acc.insert(xyz, child);
 
 2679    child->addLeafAndCache(leaf, acc);
 
 
 2682template<
typename ChildT>
 
 2686    if (!child) 
return false;
 
 2687    const Coord& xyz = child->origin();
 
 2689    MapIter 
iter = this->findKey(key);
 
 2690    if (
iter == mTable.end()) {
 
 2691        mTable.emplace(key, *child);
 
 2693        setChild(
iter, *child);
 
 
 2698template<
typename ChildT>
 
 2708template<
typename ChildT>
 
 2713    MapIter 
iter = this->findKey(key);
 
 2714    if (
iter == mTable.end()) {
 
 2715        mTable.emplace(key, Tile(value, state));
 
 2717        setTile(
iter, Tile(value, state));
 
 
 2721template<
typename ChildT>
 
 2726    if (
LEVEL >= level) {
 
 2728        MapIter 
iter = this->findKey(key);
 
 2729        if (
iter == mTable.end()) {
 
 2730            if (
LEVEL > level) {
 
 2731                ChildT* child = 
new ChildT(xyz, mBackground, 
false);
 
 2732                mTable.emplace(key, *child);
 
 2733                child->addTile(level, xyz, value, state);
 
 2735                mTable.emplace(key, Tile(value, state));
 
 2737        } 
else if (isChild(
iter)) {
 
 2738            if (
LEVEL > level) {
 
 2739                getChild(
iter).addTile(level, xyz, value, state);
 
 2741                setTile(
iter, Tile(value, state));
 
 2744            if (
LEVEL > level) {
 
 2745                ChildT* child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2746                setChild(
iter, *child);
 
 2747                child->addTile(level, xyz, value, state);
 
 2749                setTile(
iter, Tile(value, state));
 
 
 2756template<
typename ChildT>
 
 2757template<
typename AccessorT>
 
 2760                                  bool state, AccessorT& acc)
 
 2762    if (
LEVEL >= level) {
 
 2764        MapIter 
iter = this->findKey(key);
 
 2765        if (
iter == mTable.end()) {
 
 2766            if (
LEVEL > level) {
 
 2767                ChildT* child = 
new ChildT(xyz, mBackground, 
false);
 
 2768                acc.insert(xyz, child);
 
 2769                mTable.emplace(key, *child);
 
 2770                child->addTileAndCache(level, xyz, value, state, acc);
 
 2772                mTable.emplace(key, Tile(value, state));
 
 2774        } 
else if (isChild(
iter)) {
 
 2775            if (
LEVEL > level) {
 
 2776                ChildT* child = &getChild(
iter);
 
 2777                acc.insert(xyz, child);
 
 2778                child->addTileAndCache(level, xyz, value, state, acc);
 
 2780                setTile(
iter, Tile(value, state));
 
 2783            if (
LEVEL > level) {
 
 2784                ChildT* child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2785                acc.insert(xyz, child);
 
 2786                setChild(
iter, *child);
 
 2787                child->addTileAndCache(level, xyz, value, state, acc);
 
 2789                setTile(
iter, Tile(value, state));
 
 
 2796template<
typename ChildT>
 
 2801    MapIter 
iter = this->findKey(key);
 
 2802    if (
iter != mTable.end()) {
 
 2804        if (isChild(
iter))  
delete iter->second.child;
 
 
 2815template<
typename ChildT>
 
 2816inline typename ChildT::LeafNodeType*
 
 2819    ChildT* child = 
nullptr;
 
 2821    MapIter 
iter = this->findKey(key);
 
 2822    if (
iter == mTable.end()) {
 
 2823        child = 
new ChildT(xyz, mBackground, 
false);
 
 2824        mTable.emplace(key, *child);
 
 2825    } 
else if (isChild(
iter)) {
 
 2826        child = &getChild(
iter);
 
 2828        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2829        setChild(
iter, *child);
 
 2831    return child->touchLeaf(xyz);
 
 
 2835template<
typename ChildT>
 
 2836template<
typename AccessorT>
 
 2837inline typename ChildT::LeafNodeType*
 
 2840    ChildT* child = 
nullptr;
 
 2842    MapIter 
iter = this->findKey(key);
 
 2843    if (
iter == mTable.end()) {
 
 2844        child = 
new ChildT(xyz, mBackground, 
false);
 
 2845        mTable.emplace(key, *child);
 
 2846    } 
else if (isChild(
iter)) {
 
 2847        child = &getChild(
iter);
 
 2849        child = 
new ChildT(xyz, getTile(
iter).value, isTileOn(
iter));
 
 2850        setChild(
iter, *child);
 
 2852    acc.insert(xyz, child);
 
 2853    return child->touchLeafAndCache(xyz, acc);
 
 
 2860template<
typename ChildT>
 
 2861template<
typename NodeT>
 
 2865    if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
 
 2866         NodeT::LEVEL >  ChildT::LEVEL) 
return nullptr;
 
 2868    MapIter 
iter = this->findCoord(xyz);
 
 2869    if (
iter == mTable.end() || isTile(
iter)) 
return nullptr;
 
 2870    ChildT* child = &getChild(
iter);
 
 2871    return (std::is_same<NodeT, ChildT>::value)
 
 2872        ? 
reinterpret_cast<NodeT*
>(child)
 
 
 2878template<
typename ChildT>
 
 2879template<
typename NodeT>
 
 2887template<
typename ChildT>
 
 2888template<
typename NodeT>
 
 2892    if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
 
 2893         NodeT::LEVEL >  ChildT::LEVEL) 
return nullptr;
 
 2895    MapCIter 
iter = this->findCoord(xyz);
 
 2896    if (
iter == mTable.end() || isTile(
iter)) 
return nullptr;
 
 2897    const ChildT* child = &getChild(
iter);
 
 2898    return (std::is_same<NodeT, ChildT>::value)
 
 2899        ? 
reinterpret_cast<const NodeT*
>(child)
 
 
 2905template<
typename ChildT>
 
 2909    MapIter 
iter = this->findCoord(xyz);
 
 2910    if (
iter == mTable.end()) {
 
 2913    } 
else if (isChild(
iter)) {
 
 2914        child = &getChild(
iter);
 
 2917    const Tile& tile = getTile(
iter);
 
 2920    active = tile.active;
 
 
 2925template<
typename ChildT>
 
 2929    MapCIter 
iter = this->findCoord(xyz);
 
 2930    if (
iter == mTable.end()) {
 
 2933    } 
else if (isChild(
iter)) {
 
 2934        child = &getChild(
iter);
 
 2937    const Tile& tile = getTile(
iter);
 
 2940    active = tile.active;
 
 
 2945template<
typename ChildT>
 
 2953template<
typename ChildT>
 
 2961template<
typename ChildT>
 
 2962inline typename ChildT::LeafNodeType*
 
 2969template<
typename ChildT>
 
 2970inline const typename ChildT::LeafNodeType*
 
 2977template<
typename ChildT>
 
 2978template<
typename AccessorT>
 
 2979inline typename ChildT::LeafNodeType*
 
 2986template<
typename ChildT>
 
 2987template<
typename AccessorT>
 
 2988inline const typename ChildT::LeafNodeType*
 
 2995template<
typename ChildT>
 
 2996template<
typename AccessorT>
 
 2997inline const typename ChildT::LeafNodeType*
 
 3004template<
typename ChildT>
 
 3005template<
typename NodeT, 
typename AccessorT>
 
 3009    if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
 
 3010         NodeT::LEVEL >  ChildT::LEVEL) 
return nullptr;
 
 3012    MapIter 
iter = this->findCoord(xyz);
 
 3013    if (
iter == mTable.end() || isTile(
iter)) 
return nullptr;
 
 3014    ChildT* child = &getChild(
iter);
 
 3015    acc.insert(xyz, child);
 
 3016    return (std::is_same<NodeT, ChildT>::value)
 
 3017        ? 
reinterpret_cast<NodeT*
>(child)
 
 
 3023template<
typename ChildT>
 
 3024template<
typename NodeT,
typename AccessorT>
 
 3028    if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
 
 3029         NodeT::LEVEL >  ChildT::LEVEL) 
return nullptr;
 
 3031    MapCIter 
iter = this->findCoord(xyz);
 
 3032    if (
iter == mTable.end() || isTile(
iter)) 
return nullptr;
 
 3033    const ChildT* child = &getChild(
iter);
 
 3034    acc.insert(xyz, child);
 
 3035    return (std::is_same<NodeT, ChildT>::value)
 
 3036        ? 
reinterpret_cast<const NodeT*
>(child)
 
 
 3045template<
typename ChildT>
 
 3046inline const typename ChildT::ValueType&
 
 3049    MapCIter 
iter = this->findCoord(xyz);
 
 3052    return getTile(
iter).value;
 
 
 3056template<
typename ChildT>
 
 3060    MapCIter 
iter = this->findCoord(xyz);
 
 3063    const Tile& tile = getTile(
iter);
 
 
 3069template<
typename ChildT>
 
 3073    MapIter 
iter = this->findCoord(xyz);
 
 3076    return &getChild(
iter);
 
 
 3080template<
typename ChildT>
 
 3084    MapCIter 
iter = this->findCoord(xyz);
 
 3087    return &getChild(
iter);
 
 
 3091template<
typename ChildT>
 
 3102template<
typename ChildT>
 
 3103template<
typename ArrayT>
 
 3107    using NodePtr = 
typename ArrayT::value_type;
 
 3108    static_assert(std::is_pointer<NodePtr>::value,
 
 3109        "argument to getNodes() must be a pointer array");
 
 3110    using NodeType = 
typename std::remove_pointer<NodePtr>::type;
 
 3111    using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
 3112    static_assert(NodeChainType::template Contains<NonConstNodeType>,
 
 3113        "can't extract non-const nodes from a const tree");
 
 3114    using ArrayChildT = 
typename std::conditional<
 
 3115        std::is_const<NodeType>::value, 
const ChildT, ChildT>::type;
 
 3117    for (MapIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 3118        if (ChildT* child = 
iter->second.child) {
 
 3120            if (std::is_same<NodePtr, ArrayChildT*>::value) {
 
 3121                array.push_back(
reinterpret_cast<NodePtr
>(
iter->second.child));
 
 3123                child->getNodes(array);
 
 
 3130template<
typename ChildT>
 
 3131template<
typename ArrayT>
 
 3135    using NodePtr = 
typename ArrayT::value_type;
 
 3136    static_assert(std::is_pointer<NodePtr>::value,
 
 3137        "argument to getNodes() must be a pointer array");
 
 3138    using NodeType = 
typename std::remove_pointer<NodePtr>::type;
 
 3139    static_assert(std::is_const<NodeType>::value,
 
 3140        "argument to getNodes() must be an array of const node pointers");
 
 3141    using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
 3142    static_assert(NodeChainType::template Contains<NonConstNodeType>,
 
 3143        "can't extract non-const nodes from a const tree");
 
 3145    for (MapCIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 3148            if (std::is_same<NodePtr, const ChildT*>::value) {
 
 3149                array.push_back(
reinterpret_cast<NodePtr
>(
iter->second.child));
 
 3151                child->getNodes(array);
 
 
 3160template<
typename ChildT>
 
 3161template<
typename ArrayT>
 
 3165    using NodePtr = 
typename ArrayT::value_type;
 
 3166    static_assert(std::is_pointer<NodePtr>::value,
 
 3167        "argument to stealNodes() must be a pointer array");
 
 3168    using NodeType = 
typename std::remove_pointer<NodePtr>::type;
 
 3169    using NonConstNodeType = 
typename std::remove_const<NodeType>::type;
 
 3170    static_assert(NodeChainType::template Contains<NonConstNodeType>,
 
 3171        "can't extract non-const nodes from a const tree");
 
 3172    using ArrayChildT = 
typename std::conditional<
 
 3173        std::is_const<NodeType>::value, 
const ChildT, ChildT>::type;
 
 3175    for (MapIter 
iter=mTable.begin(); 
iter!=mTable.end(); ++
iter) {
 
 3176        if (ChildT* child = 
iter->second.child) {
 
 3178            if (std::is_same<NodePtr, ArrayChildT*>::value) {
 
 3179                array.push_back(
reinterpret_cast<NodePtr
>(&stealChild(
iter, Tile(value, state))));
 
 3181                child->stealNodes(array, value, state);
 
 
 3192template<
typename ChildT>
 
 3193template<MergePolicy Policy>
 
 3203        for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 3204            MapIter j = mTable.find(i->first);
 
 3205            if (other.isChild(i)) {
 
 3206                if (j == mTable.end()) { 
 
 3207                    ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3208                    child.resetBackground(other.mBackground, mBackground);
 
 3209                    mTable.emplace(i->first, child);
 
 3210                } 
else if (isTile(j)) {
 
 3212                        ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3213                        child.resetBackground(other.mBackground, mBackground);
 
 3218                        other.mBackground, mBackground);
 
 3220            } 
else if (other.isTileOn(i)) {
 
 3221                if (j == mTable.end()) { 
 
 3222                    mTable.emplace(i->first, i->second);
 
 3223                } 
else if (!isTileOn(j)) {
 
 3225                    setTile(j, Tile(other.getTile(i).value, 
true));
 
 3232        for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 3233            MapIter j = mTable.find(i->first);
 
 3234            if (other.isChild(i)) {
 
 3235                if (j == mTable.end()) { 
 
 3236                    ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3237                    child.resetBackground(other.mBackground, mBackground);
 
 3238                    mTable.emplace(i->first, child);
 
 3239                } 
else if (isTile(j)) { 
 
 3240                    ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3241                    child.resetBackground(other.mBackground, mBackground);
 
 3245                        getChild(i), other.mBackground, mBackground);
 
 3252        for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 3253            MapIter j = mTable.find(i->first);
 
 3254            if (other.isChild(i)) {
 
 3255                if (j == mTable.end()) {
 
 3257                    ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3258                    child.resetBackground(other.mBackground, mBackground);
 
 3259                    mTable.emplace(i->first, child);
 
 3260                } 
else if (isTile(j)) {
 
 3262                    ChildNodeType& child = stealChild(i, Tile(other.mBackground, 
false));
 
 3263                    child.resetBackground(other.mBackground, mBackground);
 
 3264                    const Tile tile = getTile(j);
 
 3269                            tile.value, tile.active);
 
 3274                        other.mBackground, mBackground);
 
 3276            } 
else if (other.isTileOn(i)) {
 
 3277                if (j == mTable.end()) {
 
 3279                    mTable.emplace(i->first, i->second);
 
 3280                } 
else if (isTileOff(j)) {
 
 3282                    setTile(j, Tile(other.getTile(i).value, 
true));
 
 3283                } 
else if (isChild(j)) {
 
 3285                    const Tile& tile = getTile(i);
 
 3287                        tile.value, tile.active);
 
 
 3304template<
typename ChildT>
 
 3305template<
typename OtherChildType>
 
 3310    using OtherCIterT = 
typename OtherRootT::MapCIter;
 
 3312    enforceSameConfiguration(other);
 
 3314    for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 3315        MapIter j = mTable.find(i->first);
 
 3316        if (other.isChild(i)) {
 
 3317            if (j == mTable.end()) { 
 
 3318                mTable.emplace(i->first,
 
 3319                    *(
new ChildT(other.getChild(i), mBackground, 
TopologyCopy())));
 
 3320            } 
else if (this->isChild(j)) { 
 
 3321                this->getChild(j).topologyUnion(other.getChild(i), preserveTiles);
 
 3323                if (!preserveTiles || this->isTileOff(j)) { 
 
 3324                    ChildT* child = 
new ChildT(
 
 3325                        other.getChild(i), this->getTile(j).value, 
TopologyCopy());
 
 3326                    if (this->isTileOn(j)) child->setValuesOn();
 
 3327                    this->setChild(j, *child);
 
 3330        } 
else if (other.isTileOn(i)) { 
 
 3331            if (j == mTable.end()) { 
 
 3332                mTable.emplace(i->first, Tile(mBackground, 
true));
 
 3333            } 
else if (this->isChild(j)) {
 
 3334                this->getChild(j).setValuesOn();
 
 3335            } 
else if (this->isTileOff(j)) {
 
 3336                this->setTile(j, Tile(this->getTile(j).value, 
true));
 
 
 3342template<
typename ChildT>
 
 3343template<
typename OtherChildType>
 
 3348    using OtherCIterT = 
typename OtherRootT::MapCIter;
 
 3350    enforceSameConfiguration(other);
 
 3352    std::set<Coord> tmp;
 
 3353    for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
 
 3354        OtherCIterT j = other.mTable.find(i->first);
 
 3355        if (this->isChild(i)) {
 
 3356            if (j == other.mTable.end() || other.isTileOff(j)) {
 
 3357                tmp.insert(i->first);
 
 3358            } 
else if (other.isChild(j)) { 
 
 3359                this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
 
 3361        } 
else if (this->isTileOn(i)) {
 
 3362            if (j == other.mTable.end() || other.isTileOff(j)) {
 
 3363                this->setTile(i, Tile(this->getTile(i).value, 
false));
 
 3364            } 
else if (other.isChild(j)) { 
 
 3366                    new ChildT(other.getChild(j), this->getTile(i).value, 
TopologyCopy());
 
 3367                this->setChild(i, *child);
 
 3371    for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
 
 3372        MapIter it = this->findCoord(*i);
 
 3373        setTile(it, Tile()); 
 
 
 3378template<
typename ChildT>
 
 3379template<
typename OtherChildType>
 
 3384    using OtherCIterT = 
typename OtherRootT::MapCIter;
 
 3386    enforceSameConfiguration(other);
 
 3388    for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
 
 3389        MapIter j = mTable.find(i->first);
 
 3390        if (other.isChild(i)) {
 
 3391            if (j == mTable.end() || this->isTileOff(j)) {
 
 3393            } 
else if (this->isChild(j)) { 
 
 3394                this->getChild(j).topologyDifference(other.getChild(i), mBackground);
 
 3395            } 
else if (this->isTileOn(j)) {
 
 3397                ChildT* child = 
new ChildT(j->first, this->getTile(j).value, 
true);
 
 3398                child->topologyDifference(other.getChild(i), mBackground);
 
 3399                this->setChild(j, *child);
 
 3401        } 
else if (other.isTileOn(i)) { 
 
 3402            if (j == mTable.end() || this->isTileOff(j)) {
 
 3404            } 
else if (this->isChild(j)) {
 
 3407            } 
else if (this->isTileOn(j)) {
 
 3408                this->setTile(j, Tile(this->getTile(j).value, 
false));
 
 
 3417template<
typename ChildT>
 
 3418template<
typename CombineOp>
 
 3425    this->insertKeys(keys);
 
 3426    other.insertKeys(keys);
 
 3428    for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
 
 3429        MapIter 
iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
 
 3430        if (isTile(
iter) && isTile(otherIter)) {
 
 3434                .setAIsActive(isTileOn(
iter))
 
 3435                .setBRef(getTile(otherIter).value)
 
 3436                .setBIsActive(isTileOn(otherIter)));
 
 3439        } 
else if (isChild(
iter) && isTile(otherIter)) {
 
 3441            ChildT& child = getChild(
iter);
 
 3442            child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
 
 3444        } 
else if (isTile(
iter) && isChild(otherIter)) {
 
 3449            ChildT& child = getChild(otherIter);
 
 3450            child.combine(getTile(
iter).value, isTileOn(
iter), swappedOp);
 
 3453            setChild(
iter, stealChild(otherIter, Tile()));
 
 3457            ChildT &child = getChild(
iter), &otherChild = getChild(otherIter);
 
 3458            child.combine(otherChild, op);
 
 3465    mBackground = args.
result();
 
 
 3477template<
typename CombineOp, 
typename RootT, 
typename OtherRootT, 
bool Compatible = false>
 
 3480    static inline void combine2(RootT& self, 
const RootT&, 
const OtherRootT& other1,
 
 3485        self.enforceSameConfiguration(other1);
 
 3486        self.enforceCompatibleValueTypes(other1);
 
 3488        std::ostringstream ostr;
 
 3489        ostr << 
"cannot combine a " << 
typeid(OtherRootT).name()
 
 3490            << 
" into a " << 
typeid(RootT).name();
 
 
 
 3496template<
typename CombineOp, 
typename RootT, 
typename OtherRootT>
 
 3499    static inline void combine2(RootT& self, 
const RootT& other0, 
const OtherRootT& other1,
 
 3500        CombineOp& op, 
bool prune)
 
 3502        self.doCombine2(other0, other1, op, prune);
 
 
 
 3507template<
typename ChildT>
 
 3508template<
typename CombineOp, 
typename OtherRootNode>
 
 3511    CombineOp& op, 
bool prune)
 
 3513    using OtherValueType = 
typename OtherRootNode::ValueType;
 
 3517        *
this, other0, other1, op, 
prune);
 
 
 3521template<
typename ChildT>
 
 3522template<
typename CombineOp, 
typename OtherRootNode>
 
 3524RootNode<ChildT>::doCombine2(
const RootNode& other0, 
const OtherRootNode& other1,
 
 3525    CombineOp& op, 
bool prune)
 
 3527    enforceSameConfiguration(other1);
 
 3529    using OtherValueT = 
typename OtherRootNode::ValueType;
 
 3530    using OtherTileT = 
typename OtherRootNode::Tile;
 
 3531    using OtherNodeStructT = 
typename OtherRootNode::NodeStruct;
 
 3532    using OtherMapCIterT = 
typename OtherRootNode::MapCIter;
 
 3537    other0.insertKeys(keys);
 
 3538    other1.insertKeys(keys);
 
 3540    const NodeStruct bg0(Tile(other0.mBackground, 
false));
 
 3541    const OtherNodeStructT bg1(OtherTileT(other1.mBackground, 
false));
 
 3543    for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
 
 3544        MapIter thisIter = this->findOrAddCoord(*i);
 
 3545        MapCIter iter0 = other0.findKey(*i);
 
 3546        OtherMapCIterT iter1 = other1.findKey(*i);
 
 3547        const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
 
 3548        const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
 
 3549        if (ns0.isTile() && ns1.isTile()) {
 
 3552            op(args.
setARef(ns0.tile.value)
 
 3558            if (!isChild(thisIter)) {
 
 3560                const Coord& childOrigin =
 
 3561                    ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
 
 3562                setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
 
 3564            ChildT& child = getChild(thisIter);
 
 3569                child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
 
 3570            } 
else if (ns1.isTile()) {
 
 3573                child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
 
 3577                child.combine2(*ns0.child, *ns1.child, op);
 
 3580        if (prune && isChild(thisIter)) getChild(thisIter).prune();
 
 3585    mBackground = args.
result();
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition Types.h:569
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition Types.h:621
const AValueType & result() const
Get the output value.
Definition Types.h:613
CombineArgs & setBIsActive(bool b)
Set the active state of the B value.
Definition Types.h:637
CombineArgs & setBRef(const BValueType &b)
Redirect the B value to a new external source.
Definition Types.h:623
bool resultIsActive() const
Definition Types.h:632
CombineArgs & setAIsActive(bool b)
Set the active state of the A value.
Definition Types.h:635
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition Coord.h:322
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition Coord.h:316
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition Coord.h:176
static bool lessThan(const Coord &a, const Coord &b)
Definition Coord.h:209
Tag dispatch class that distinguishes constructors during file input.
Definition Types.h:689
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
Definition Exceptions.h:64
Definition Exceptions.h:65
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition Coord.h:461
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition Coord.h:421
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition Coord.h:359
const Coord & min() const
Definition Coord.h:324
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition Coord.h:415
const Coord & max() const
Definition Coord.h:325
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition Coord.h:403
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition Coord.h:447
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Int32 y() const
Definition Coord.h:132
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition Coord.h:92
const Int32 * asPointer() const
Definition Coord.h:142
Int32 x() const
Definition Coord.h:131
Coord & setZ(Int32 z)
Definition Coord.h:82
Coord & setY(Int32 y)
Definition Coord.h:81
Int32 z() const
Definition Coord.h:133
Coord & setX(Int32 x)
Definition Coord.h:80
void read(std::istream &is)
Definition Coord.h:220
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition RootNode.h:408
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition RootNode.h:1937
DenseIter< RootNode, MapIter, typename SubtreeT::Back, ValueType > ChildAllIter
Definition RootNode.h:366
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition RootNode.h:1448
int getValueDepth(const Coord &xyz) const
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition RootNode.h:372
RootNode(const RootNode &other)
Definition RootNode.h:76
ChildOnCIter cbeginChildOn() const
Definition RootNode.h:377
ChildOnCIter beginChildOn() const
Definition RootNode.h:380
ChildOnIter beginChildOn()
Definition RootNode.h:383
Index getDepth() const
Definition RootNode.h:464
bool probe(const Coord &xyz, ChildNodeType *&child, ValueType &value, bool &active)
Return a pointer to the root child node that contains voxel (x, y, z). If no such node exists,...
Definition RootNode.h:2907
RootNode(const RootNode< OtherChildType > &other, const ValueType &background, TopologyCopy)
Construct a new tree that reproduces the topology and active states of another tree (which may have a...
Definition RootNode.h:1118
bool isValueOn(const Coord &xyz) const
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition RootNode.h:370
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition RootNode.h:1388
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:2304
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition RootNode.h:1211
Coord getMaxIndex() const
ValueOffCIter cbeginValueOff() const
Definition RootNode.h:388
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
Index32 transientData() const
Return the transient data value.
Definition RootNode.h:411
bool isBackgroundTile(const MapCIter &) const
Definition RootNode.h:1291
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:2649
static Index getChildDim()
Definition RootNode.h:457
const ChildNodeType * getConstChildUnsafe(const Coord &xyz) const
Return the child node at the given coordinate.
Definition RootNode.h:3082
RootNode & operator=(const RootNode< OtherChildType > &other)
Copy a root node of the same tree configuration as this node but a different ValueType.
Coord coordToKey(const Coord &xyz) const
Return a MapType key for the given coordinates, offset by the mOrigin.
Definition RootNode.h:954
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition RootNode.h:3420
bool addChild(ChildType *child)
Add the given child node at the root level. If a child node with the same origin already exists,...
Definition RootNode.h:2684
bool getTileValueUnsafe(const Coord &xyz, ValueType &value) const
Return the tile value and active state at the given coordinate.
Definition RootNode.h:3058
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition RootNode.h:3105
const ValueType & getTileValueUnsafe(const Coord &xyz) const
Return the tile value at the given coordinate.
Definition RootNode.h:3047
Index64 nonLeafCount() const
Definition RootNode.h:1558
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:2594
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition RootNode.h:2278
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition RootNode.h:371
Index32 activeTileCount() const
Definition RootNode.h:1596
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition RootNode.h:373
void topologyUnion(const RootNode< OtherChildType > &other, const bool preserveTiles=false)
Union this tree's set of active values with the active values of the other tree, whose ValueType may ...
Definition RootNode.h:3307
Index64 onLeafVoxelCount() const
Definition RootNode.h:1652
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition RootNode.h:2533
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:2963
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition RootNode.h:1480
ValueAllCIter cbeginValueAll() const
Definition RootNode.h:389
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:3007
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:2573
typename NodeChain< RootNode, LEVEL >::Type NodeChainType
Definition RootNode.h:50
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition RootNode.h:1277
typename typename SubtreeT::Back::LeafNodeType LeafNodeType
Definition RootNode.h:43
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition RootNode.h:1311
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:3381
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition RootNode.h:369
ValueOnCIter beginValueOn() const
Definition RootNode.h:390
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition RootNode.h:3195
ChildIter< RootNode, MapIter, ChildOnPred, typename SubtreeT::Back > ChildOnIter
Definition RootNode.h:362
Index64 offLeafVoxelCount() const
Definition RootNode.h:1664
Index getWidth() const
Definition RootNode.h:462
Index getTableSize() const
Return the number of entries in this node's table.
Definition RootNode.h:460
bool probe(const Coord &xyz, const ChildNodeType *&child, ValueType &value, bool &active) const
Definition RootNode.h:750
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile containing voxel (x, y, z) at the specified tree level, creating a new branch if necessary...
Definition RootNode.h:2723
void setOrigin(const Coord &origin)
change the origin on this root node
Definition RootNode.h:2700
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition RootNode.h:3510
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition RootNode.h:945
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition RootNode.h:1980
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition RootNode.h:1299
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition RootNode.h:365
void setValueOnly(const Coord &xyz, const ValueType &value)
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition RootNode.h:448
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition RootNode.h:2971
ChildNodeType * probeChild(const Coord &xyz)
Return a pointer to the root child node that contains voxel (x, y, z). If no such node exists,...
Definition RootNode.h:2947
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
ValueOffCIter beginValueOff() const
Definition RootNode.h:391
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition RootNode.h:1892
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:2613
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
ChildAllCIter cbeginChildAll() const
Definition RootNode.h:379
Index64 leafCount() const
Definition RootNode.h:1546
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:2710
ChildAllIter beginChildAll()
Definition RootNode.h:385
bool probeConst(const Coord &xyz, const ChildNodeType *&child, ValueType &value, bool &active) const
Definition RootNode.h:2927
friend struct RootNodeCombineHelper
Definition RootNode.h:965
static Index getLevel()
Definition RootNode.h:455
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition RootNode.h:2348
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition RootNode.h:374
const ChildNodeType * getChildUnsafe(const Coord &xyz) const
Return the child node at the given coordinate.
Definition RootNode.h:3093
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition RootNode.h:1747
const NodeT * probeConstNodeAndCache(const Coord &xyz, AccessorT &acc) const
Definition RootNode.h:3026
bool probeValue(const Coord &xyz, ValueType &value) const
void setActiveState(const Coord &xyz, bool on)
ValueOnIter beginValueOn()
Definition RootNode.h:393
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition RootNode.h:2037
static const Index LEVEL
Definition RootNode.h:47
Index32 inactiveTileCount() const
Definition RootNode.h:1608
ChildOffCIter cbeginChildOff() const
Definition RootNode.h:378
ChildOffIter beginChildOff()
Definition RootNode.h:384
Index64 onVoxelCount() const
Definition RootNode.h:1620
ChildOffCIter beginChildOff() const
Definition RootNode.h:381
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:2759
typename typename SubtreeT::Back::ValueType ValueType
Definition RootNode.h:44
void setValueOff(const Coord &xyz)
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition RootNode.h:2489
void nodeCount(std::vector< Index64 > &vec) const
Definition RootNode.h:1690
ValueOnCIter cbeginValueOn() const
Definition RootNode.h:387
RootNode(const ValueType &background)
Construct a new tree with the given background value.
Definition RootNode.h:1081
const LeafNodeType * probeLeaf(const Coord &xyz) const
Definition RootNode.h:775
Index32 tileCount() const
Definition RootNode.h:1584
void readBuffers(std::istream &, const CoordBBox &, bool fromHalf=false)
Definition RootNode.h:2509
Index32 childCount() const
Definition RootNode.h:1572
Index64 onTileCount() const
Definition RootNode.h:1675
RootNode()
Construct a new tree with a background value of 0.
Definition RootNode.h:1072
void modifyValue(const Coord &xyz, const ModifyOp &op)
bool isBackgroundTile(const MapIter &) const
Return true if the given iterator points to an inactive tile with the background value.
Definition RootNode.h:1284
~RootNode()
Definition RootNode.h:124
Index64 offVoxelCount() const
Definition RootNode.h:1636
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:2817
void getNodes(ArrayT &array) const
Definition RootNode.h:3133
RootNode(const RootNode< OtherChildType > &other, const ValueType &background, const ValueType &foreground, TopologyCopy)
Construct a new tree that reproduces the topology and active states of another tree (which may have a...
Definition RootNode.h:1091
typename typename SubtreeT::Back::BuildType BuildType
Definition RootNode.h:45
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:1250
ChildNodeType * getChildUnsafe(const Coord &xyz)
Return the child node at the given coordinate.
Definition RootNode.h:3071
DenseIter< const RootNode, MapCIter, const typename SubtreeT::Back, const ValueType > ChildAllCIter
Definition RootNode.h:367
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:1401
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:2228
const NodeT * probeNode(const Coord &xyz) const
Definition RootNode.h:2881
ChildAllCIter beginChildAll() const
Definition RootNode.h:382
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition RootNode.h:1843
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:3345
void setTransientData(Index32 transientData)
Set the transient data value.
Definition RootNode.h:413
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:3163
Index getHeight() const
Definition RootNode.h:463
const LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc) const
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition RootNode.h:2150
const NodeT * probeConstNode(const Coord &xyz) const
Definition RootNode.h:2890
bool hasKey(const Coord &key) const
Return true if this node's mTable contains the given key.
Definition RootNode.h:957
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:1532
const ChildNodeType * probeChild(const Coord &xyz) const
Definition RootNode.h:767
const ValueType & background() const
Definition RootNode.h:430
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition RootNode.h:1364
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:85
ValueOffIter beginValueOff()
Definition RootNode.h:394
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition RootNode.h:364
void sparseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition RootNode.h:544
Coord getMinIndex() const
friend struct RootNodeCopyHelper
Definition RootNode.h:964
const ChildNodeType * probeConstChild(const Coord &xyz) const
Definition RootNode.h:2955
typename SubtreeT::Back ChildNodeType
Definition RootNode.h:42
bool deleteChildOrTile(const Coord &xyz)
Delete any child or tile containing voxel (x, y, z) at the root level. Do nothing if no child or tile...
Definition RootNode.h:2798
bool hasActiveTiles() const
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition RootNode.h:1793
const ValueType & getValue(const Coord &xyz) const
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition RootNode.h:1507
void setValueOn(const Coord &xyz, const ValueType &value)
void stealNodes(ArrayT &array)
Definition RootNode.h:877
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition RootNode.h:1350
void readBuffers(std::istream &, bool fromHalf=false)
Definition RootNode.h:2499
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition RootNode.h:2102
ValueAllCIter beginValueAll() const
Definition RootNode.h:392
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:2863
bool readTopology(std::istream &, bool fromHalf=false)
Definition RootNode.h:2384
ChildIter< const RootNode, MapCIter, ChildOnPred, const typename SubtreeT::Back > ChildOnCIter
Definition RootNode.h:363
ValueAllIter beginValueAll()
Definition RootNode.h:395
friend class RootNode
Definition RootNode.h:962
Definition NodeMasks.h:1067
bool isOn(Index32 i) const
Definition NodeMasks.h:1331
void load(std::istream &is)
Definition NodeMasks.h:1372
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...
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition Compression.h:217
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition Vec3.h:474
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:597
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition Math.h:406
T negative(const T &val)
Return the unary negation of the given value.
Definition Math.h:128
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:443
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition Vec3.h:482
Definition TreeIterator.h:30
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition NodeMasks.h:159
Index32 Index
Definition Types.h:54
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
@ OPENVDB_FILE_VERSION_ROOTNODE_MAP
Definition version.h.in:252
uint32_t Index32
Definition Types.h:52
int32_t Int32
Definition Types.h:56
uint64_t Index64
Definition Types.h:53
@ MERGE_ACTIVE_STATES
Definition Types.h:507
@ MERGE_NODES
Definition Types.h:508
@ MERGE_ACTIVE_STATES_AND_NODES
Definition Types.h:509
const char * typeNameAsString()
Definition Types.h:516
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition Types.h:403
@ value
Definition Types.h:403
A list of types (not necessarily unique)
Definition TypeList.h:578
TypeList< typename HeadT::ChildNodeType, HeadT > Type
Definition RootNode.h:1045
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a openvdb::TypeList that lists the types of the...
Definition RootNode.h:1037
typename NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition RootNode.h:1038
typename SubtreeT::template Append< HeadT > Type
Definition RootNode.h:1039
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition RootNode.h:3499
Definition RootNode.h:3479
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition RootNode.h:3480
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition RootNode.h:1170
Definition RootNode.h:1151
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition RootNode.h:1152
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition RootNode.h:65
static const bool value
Definition RootNode.h:66
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition RootNode.h:57
RootNode< typename ChildType::template ValueConverter< OtherValueType >::Type > Type
Definition RootNode.h:58
static const bool value
Definition RootNode.h:1062
Definition RootNode.h:1056
static const bool value
Definition RootNode.h:1057
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218