8 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
9 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
17 #include <openvdb/version.h>
18 #include <tbb/parallel_for.h>
31 template<
typename HeadType,
int HeadLevel>
struct NodeChain;
32 template<
typename,
typename>
struct SameRootConfig;
33 template<
typename,
typename,
bool>
struct RootNodeCopyHelper;
34 template<
typename,
typename,
typename,
bool>
struct RootNodeCombineHelper;
37 template<
typename ChildType>
46 static const Index LEVEL = 1 + ChildType::LEVEL;
50 static_assert(NodeChainType::Size == LEVEL + 1,
51 "wrong number of entries in RootNode node chain");
55 template<
typename OtherValueType>
63 template<
typename OtherNodeType>
83 template<
typename OtherChildType>
94 template<
typename OtherChildType>
96 const ValueType& background,
const ValueType& foreground,
TopologyCopy);
108 template<
typename OtherChildType>
120 template<
typename OtherChildType>
127 Tile(): value(
zeroVal<ValueType>()), active(false) {}
128 Tile(
const ValueType& v,
bool b): value(v), active(b) {}
138 NodeStruct(): child(nullptr) {}
139 NodeStruct(ChildType& c): child(&c) {}
140 NodeStruct(
const Tile& t): child(nullptr), tile(t) {}
141 NodeStruct(
const NodeStruct&) =
default;
142 NodeStruct& operator=(
const NodeStruct&) =
default;
145 bool isChild()
const {
return child !=
nullptr; }
146 bool isTile()
const {
return child ==
nullptr; }
147 bool isTileOff()
const {
return isTile() && !tile.active; }
148 bool isTileOn()
const {
return isTile() && tile.active; }
150 void set(ChildType& c) {
delete child; child = &c; }
151 void set(
const Tile& t) {
delete child; child =
nullptr; tile = t; }
152 ChildType& steal(
const Tile& t) { ChildType* c=child; child=
nullptr; tile=t;
return *c; }
155 using MapType = std::map<Coord, NodeStruct>;
156 using MapIter =
typename MapType::iterator;
157 using MapCIter =
typename MapType::const_iterator;
159 using CoordSet = std::set<Coord>;
160 using CoordSetIter =
typename CoordSet::iterator;
161 using CoordSetCIter =
typename CoordSet::const_iterator;
163 static void setTile(
const MapIter& i,
const Tile& t) { i->second.set(t); }
164 static void setChild(
const MapIter& i, ChildType& c) { i->second.set(c); }
165 static Tile& getTile(
const MapIter& i) {
return i->second.tile; }
166 static const Tile& getTile(
const MapCIter& i) {
return i->second.tile; }
167 static ChildType& getChild(
const MapIter& i) {
return *(i->second.child); }
168 static const ChildType& getChild(
const MapCIter& i) {
return *(i->second.child); }
169 static ChildType& stealChild(
const MapIter& i,
const Tile& t) {
return i->second.steal(t);}
170 static const ChildType& stealChild(
const MapCIter& i,
const Tile& t) {
return i->second.steal(t);}
172 static bool isChild(
const MapCIter& i) {
return i->second.isChild(); }
173 static bool isChild(
const MapIter& i) {
return i->second.isChild(); }
174 static bool isTile(
const MapCIter& i) {
return i->second.isTile(); }
175 static bool isTile(
const MapIter& i) {
return i->second.isTile(); }
176 static bool isTileOff(
const MapCIter& i) {
return i->second.isTileOff(); }
177 static bool isTileOff(
const MapIter& i) {
return i->second.isTileOff(); }
178 static bool isTileOn(
const MapCIter& i) {
return i->second.isTileOn(); }
179 static bool isTileOn(
const MapIter& i) {
return i->second.isTileOn(); }
182 static inline bool test(
const MapIter&) {
return true; }
183 static inline bool test(
const MapCIter&) {
return true; }
186 static inline bool test(
const MapIter& i) {
return isTileOn(i); }
187 static inline bool test(
const MapCIter& i) {
return isTileOn(i); }
189 struct ValueOffPred {
190 static inline bool test(
const MapIter& i) {
return isTileOff(i); }
191 static inline bool test(
const MapCIter& i) {
return isTileOff(i); }
193 struct ValueAllPred {
194 static inline bool test(
const MapIter& i) {
return isTile(i); }
195 static inline bool test(
const MapCIter& i) {
return isTile(i); }
198 static inline bool test(
const MapIter& i) {
return isChild(i); }
199 static inline bool test(
const MapCIter& i) {
return isChild(i); }
201 struct ChildOffPred {
202 static inline bool test(
const MapIter& i) {
return isTile(i); }
203 static inline bool test(
const MapCIter& i) {
return isTile(i); }
206 template<
typename _RootNodeT,
typename _MapIterT,
typename FilterPredT>
210 using RootNodeT = _RootNodeT;
211 using MapIterT = _MapIterT;
215 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
217 bool operator!=(
const BaseIter& other)
const {
return !(*
this == other); }
219 RootNodeT* getParentNode()
const {
return mParentNode; }
221 RootNodeT& parent()
const
223 if (!mParentNode)
OPENVDB_THROW(ValueError,
"iterator references a null parent node");
227 bool test()
const { assert(mParentNode);
return mIter != mParentNode->mTable.end(); }
228 operator bool()
const {
return this->test(); }
230 void increment() {
if (this->test()) { ++mIter; } this->skip(); }
231 bool next() { this->increment();
return this->test(); }
232 void increment(
Index n) {
for (
Index i = 0; i < n && this->next(); ++i) {} }
238 return !mParentNode ? 0U :
Index(std::distance(mParentNode->mTable.begin(), mIter));
241 bool isValueOn()
const {
return RootNodeT::isTileOn(mIter); }
242 bool isValueOff()
const {
return RootNodeT::isTileOff(mIter); }
243 void setValueOn(
bool on =
true)
const { mIter->second.tile.active = on; }
244 void setValueOff()
const { mIter->second.tile.active =
false; }
247 Coord getCoord()
const {
return mIter->first; }
249 void getCoord(Coord& xyz)
const { xyz = this->getCoord(); }
252 BaseIter(): mParentNode(nullptr) {}
253 BaseIter(RootNodeT& parent,
const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
255 void skip() {
while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
257 RootNodeT* mParentNode;
261 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ChildNodeT>
262 class ChildIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
265 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
266 using NodeType = RootNodeT;
267 using ValueType = NodeType;
268 using ChildNodeType = ChildNodeT;
269 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
270 using NonConstValueType =
typename std::remove_const<ValueType>::type;
271 using NonConstChildNodeType =
typename std::remove_const<ChildNodeType>::type;
275 ChildIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
277 ChildIter& operator++() { BaseT::increment();
return *
this; }
279 ChildNodeT& getValue()
const {
return getChild(mIter); }
280 ChildNodeT&
operator*()
const {
return this->getValue(); }
281 ChildNodeT* operator->()
const {
return &this->getValue(); }
284 template<
typename RootNodeT,
typename MapIterT,
typename FilterPredT,
typename ValueT>
285 class ValueIter:
public BaseIter<RootNodeT, MapIterT, FilterPredT>
288 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
289 using NodeType = RootNodeT;
290 using ValueType = ValueT;
291 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
292 using NonConstValueType =
typename std::remove_const<ValueT>::type;
296 ValueIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
298 ValueIter& operator++() { BaseT::increment();
return *
this; }
300 ValueT& getValue()
const {
return getTile(mIter).value; }
301 ValueT&
operator*()
const {
return this->getValue(); }
302 ValueT* operator->()
const {
return &(this->getValue()); }
304 void setValue(
const ValueT& v)
const { assert(isTile(mIter)); getTile(mIter).value = v; }
306 template<
typename ModifyOp>
307 void modifyValue(
const ModifyOp& op)
const
309 assert(isTile(mIter));
310 op(getTile(mIter).value);
314 template<
typename RootNodeT,
typename MapIterT,
typename ChildNodeT,
typename ValueT>
315 class DenseIter:
public BaseIter<RootNodeT, MapIterT, NullPred>
318 using BaseT = BaseIter<RootNodeT, MapIterT, NullPred>;
319 using NodeType = RootNodeT;
320 using ValueType = ValueT;
321 using ChildNodeType = ChildNodeT;
322 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
323 using NonConstValueType =
typename std::remove_const<ValueT>::type;
324 using NonConstChildNodeType =
typename std::remove_const<ChildNodeT>::type;
328 DenseIter(RootNodeT& parent,
const MapIterT& iter): BaseT(parent, iter) {}
330 DenseIter& operator++() { BaseT::increment();
return *
this; }
332 bool isChildNode()
const {
return isChild(mIter); }
334 ChildNodeT* probeChild(NonConstValueType& value)
const
336 if (isChild(mIter))
return &getChild(mIter);
337 value = getTile(mIter).value;
340 bool probeChild(ChildNodeT*& child, NonConstValueType& value)
const
342 child = this->probeChild(value);
343 return child !=
nullptr;
345 bool probeValue(NonConstValueType& value)
const {
return !this->probeChild(value); }
347 void setChild(ChildNodeT& c)
const { RootNodeT::setChild(mIter, c); }
348 void setChild(ChildNodeT* c)
const { assert(c !=
nullptr); RootNodeT::setChild(mIter, *c); }
349 void setValue(
const ValueT& v)
const
351 if (isTile(mIter)) getTile(mIter).value = v;
355 else stealChild(mIter, Tile(v,
true));
360 using ChildOnIter = ChildIter<RootNode, MapIter, ChildOnPred, ChildType>;
361 using ChildOnCIter = ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>;
362 using ChildOffIter = ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>;
363 using ChildOffCIter = ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>;
364 using ChildAllIter = DenseIter<RootNode, MapIter, ChildType, ValueType>;
365 using ChildAllCIter = DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>;
367 using ValueOnIter = ValueIter<RootNode, MapIter, ValueOnPred, ValueType>;
368 using ValueOnCIter = ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>;
369 using ValueOffIter = ValueIter<RootNode, MapIter, ValueOffPred, ValueType>;
370 using ValueOffCIter = ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>;
371 using ValueAllIter = ValueIter<RootNode, MapIter, ValueAllPred, ValueType>;
372 using ValueAllCIter = ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>;
403 void evalActiveBoundingBox(
CoordBBox& bbox,
bool visitVoxels =
true)
const;
420 void setBackground(
const ValueType& value,
bool updateChildNodes);
426 bool isBackgroundTile(
const Tile&)
const;
428 bool isBackgroundTile(
const MapIter&)
const;
430 bool isBackgroundTile(
const MapCIter&)
const;
434 size_t numBackgroundTiles()
const;
437 size_t eraseBackgroundTiles();
441 bool empty()
const {
return mTable.size() == numBackgroundTiles(); }
446 bool expand(
const Coord& xyz);
449 static void getNodeLog2Dims(std::vector<Index>& dims);
455 Index getWidth()
const {
return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
456 Index getHeight()
const {
return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
457 Index getDepth()
const {
return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
460 Coord getMinIndex()
const;
462 Coord getMaxIndex()
const;
464 void getIndexRange(
CoordBBox& bbox)
const;
468 template<
typename OtherChildType>
472 template<
typename OtherChildType>
477 template<
typename OtherChildType>
485 Index64 onLeafVoxelCount()
const;
486 Index64 offLeafVoxelCount()
const;
488 void nodeCount(std::vector<Index32> &vec)
const;
490 bool isValueOn(
const Coord& xyz)
const;
493 bool hasActiveTiles()
const;
495 const ValueType& getValue(
const Coord& xyz)
const;
496 bool probeValue(
const Coord& xyz, ValueType& value)
const;
501 int getValueDepth(
const Coord& xyz)
const;
504 void setActiveState(
const Coord& xyz,
bool on);
506 void setValueOnly(
const Coord& xyz,
const ValueType& value);
508 void setValueOn(
const Coord& xyz,
const ValueType& value);
510 void setValueOff(
const Coord& xyz);
512 void setValueOff(
const Coord& xyz,
const ValueType& value);
516 template<
typename ModifyOp>
517 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
519 template<
typename ModifyOp>
520 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
523 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
534 this->fill(bbox, value, active);
545 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
555 void voxelizeActiveTiles(
bool threaded =
true);
562 template<
typename DenseT>
569 bool writeTopology(std::ostream&,
bool toHalf =
false)
const;
570 bool readTopology(std::istream&,
bool fromHalf =
false);
572 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
573 void readBuffers(std::istream&,
bool fromHalf =
false);
574 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
584 template<
typename AccessorT>
590 template<
typename AccessorT>
591 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
597 template<
typename AccessorT>
598 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
604 template<
typename AccessorT>
605 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
612 template<
typename ModifyOp,
typename AccessorT>
613 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
619 template<
typename ModifyOp,
typename AccessorT>
620 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
626 template<
typename AccessorT>
627 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
633 template<
typename AccessorT>
634 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
641 template<
typename AccessorT>
642 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
649 template<
typename AccessorT>
650 int getValueDepthAndCache(
const Coord& xyz, AccessorT&)
const;
668 template<
typename AccessorT>
679 template<
typename NodeT>
680 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
687 bool addChild(ChildType* child);
691 void addTile(
const Coord& xyz,
const ValueType& value,
bool state);
700 template<
typename AccessorT>
701 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
712 template<
typename AccessorT>
716 template <
typename NodeT>
719 NodeT* probeNode(
const Coord& xyz);
720 template <
typename NodeT>
721 const NodeT* probeConstNode(
const Coord& xyz)
const;
725 template<
typename NodeT,
typename AccessorT>
728 NodeT* probeNodeAndCache(
const Coord& xyz, AccessorT& acc);
729 template<
typename NodeT,
typename AccessorT>
730 const NodeT* probeConstNodeAndCache(
const Coord& xyz, AccessorT& acc)
const;
742 template<
typename AccessorT>
746 template<
typename AccessorT>
748 template<
typename AccessorT>
758 template<
typename ArrayT>
void getNodes(ArrayT& array);
781 template<
typename ArrayT>
void getNodes(ArrayT& array)
const;
785 template<
typename ArrayT>
809 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
810 template<
typename ArrayT>
821 template<MergePolicy Policy>
void merge(
RootNode& other);
839 template<
typename OtherChildType>
855 template<
typename OtherChildType>
868 template<
typename OtherChildType>
871 template<
typename CombineOp>
874 template<
typename CombineOp,
typename OtherRootNode >
875 void combine2(
const RootNode& other0,
const OtherRootNode& other1,
876 CombineOp& op,
bool prune =
false);
883 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
885 template<
typename VisitorOp>
void visit(VisitorOp&);
886 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
888 template<
typename OtherRootNodeType,
typename VisitorOp>
889 void visit2(OtherRootNodeType& other, VisitorOp&);
890 template<
typename OtherRootNodeType,
typename VisitorOp>
891 void visit2(OtherRootNodeType& other, VisitorOp&)
const;
904 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
906 void resetTable(
const MapType&)
const {}
909 #if OPENVDB_ABI_VERSION_NUMBER < 8
910 Index getChildCount()
const;
912 Index getTileCount()
const;
913 Index getActiveTileCount()
const;
914 Index getInactiveTileCount()
const;
917 static Coord coordToKey(
const Coord& xyz) {
return xyz & ~(ChildType::DIM - 1); }
920 void insertKeys(CoordSet&)
const;
923 bool hasKey(
const Coord& key)
const {
return mTable.find(key) != mTable.end(); }
925 MapIter findKey(
const Coord& key) {
return mTable.find(key); }
928 MapCIter findKey(
const Coord& key)
const {
return mTable.find(key); }
931 MapIter findCoord(
const Coord& xyz) {
return mTable.find(coordToKey(xyz)); }
934 MapCIter findCoord(
const Coord& xyz)
const {
return mTable.find(coordToKey(xyz)); }
936 MapIter findOrAddCoord(
const Coord& xyz);
945 template<
typename OtherChildType>
946 static void enforceSameConfiguration(
const RootNode<OtherChildType>& other);
953 template<
typename OtherChildType>
954 static void enforceCompatibleValueTypes(
const RootNode<OtherChildType>& other);
956 template<
typename CombineOp,
typename OtherRootNode >
957 void doCombine2(
const RootNode&,
const OtherRootNode&, CombineOp&,
bool prune);
959 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
960 static inline void doVisit(RootNodeT&, VisitorOp&);
962 template<
typename RootNodeT,
typename OtherRootNodeT,
typename VisitorOp,
963 typename ChildAllIterT,
typename OtherChildAllIterT>
964 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
968 ValueType mBackground;
995 template<
typename HeadT,
int HeadLevel>
998 using Type =
typename SubtreeT::template Append<HeadT>;
1002 template<
typename HeadT>
1012 template<
typename ChildT1,
typename NodeT2>
1016 static const bool value =
false;
1019 template<
typename ChildT1,
typename ChildT2>
1021 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1029 template<
typename ChildT>
1037 template<
typename ChildT>
1045 template<
typename ChildT>
1046 template<
typename OtherChildType>
1054 enforceSameConfiguration(other);
1056 const Tile bgTile(backgd,
false), fgTile(foregd,
true);
1059 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1060 mTable[i->first] = OtherRootT::isTile(i)
1061 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1062 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd, foregd,
TopologyCopy())));
1067 template<
typename ChildT>
1068 template<
typename OtherChildType>
1076 enforceSameConfiguration(other);
1078 const Tile bgTile(backgd,
false), fgTile(backgd,
true);
1080 for (
typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1081 mTable[i->first] = OtherRootT::isTile(i)
1082 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1083 : NodeStruct(*(
new ChildT(OtherRootT::getChild(i), backgd,
TopologyCopy())));
1094 template<
typename RootT,
typename OtherRootT,
bool Compatible = false>
1101 self.enforceSameConfiguration(other);
1102 self.enforceCompatibleValueTypes(other);
1104 std::ostringstream ostr;
1105 ostr <<
"cannot convert a " <<
typeid(OtherRootT).name()
1106 <<
" to a " <<
typeid(RootT).name();
1112 template<
typename RootT,
typename OtherRootT>
1117 using ValueT =
typename RootT::ValueType;
1118 using ChildT =
typename RootT::ChildNodeType;
1119 using NodeStruct =
typename RootT::NodeStruct;
1120 using Tile =
typename RootT::Tile;
1121 using OtherValueT =
typename OtherRootT::ValueType;
1122 using OtherMapCIter =
typename OtherRootT::MapCIter;
1123 using OtherTile =
typename OtherRootT::Tile;
1127 static inline ValueT convertValue(
const OtherValueT& val) {
return ValueT(val); }
1130 self.mBackground = Local::convertValue(other.mBackground);
1135 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1136 if (other.isTile(i)) {
1138 const OtherTile& otherTile = other.getTile(i);
1139 self.mTable[i->first] = NodeStruct(
1140 Tile(Local::convertValue(otherTile.value), otherTile.active));
1143 self.mTable[i->first] = NodeStruct(*(
new ChildT(other.getChild(i))));
1151 template<
typename ChildT>
1152 inline RootNode<ChildT>&
1155 if (&other !=
this) {
1156 mBackground = other.mBackground;
1161 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1163 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(
new ChildT(getChild(i))));
1170 template<
typename ChildT>
1171 template<
typename OtherChildType>
1176 using OtherValueT =
typename OtherRootT::ValueType;
1186 template<
typename ChildT>
1192 if (updateChildNodes) {
1195 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1196 ChildT *child = iter->second.child;
1198 child->resetBackground(mBackground, background);
1200 Tile& tile = getTile(iter);
1201 if (tile.active)
continue;
1203 tile.value = background;
1210 mBackground = background;
1213 template<
typename ChildT>
1220 template<
typename ChildT>
1227 template<
typename ChildT>
1235 template<
typename ChildT>
1240 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1241 if (this->isBackgroundTile(i)) ++count;
1247 template<
typename ChildT>
1251 std::set<Coord> keysToErase;
1252 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1253 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
1255 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1258 return keysToErase.size();
1265 template<
typename ChildT>
1269 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1270 keys.insert(i->first);
1275 template<
typename ChildT>
1276 inline typename RootNode<ChildT>::MapIter
1277 RootNode<ChildT>::findOrAddCoord(
const Coord& xyz)
1279 const Coord key = coordToKey(xyz);
1280 std::pair<MapIter, bool> result = mTable.insert(
1281 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1282 return result.first;
1286 template<
typename ChildT>
1290 const Coord key = coordToKey(xyz);
1291 std::pair<MapIter, bool> result = mTable.insert(
1292 typename MapType::value_type(key, NodeStruct(Tile(mBackground,
false))));
1293 return result.second;
1300 template<
typename ChildT>
1305 ChildT::getNodeLog2Dims(dims);
1309 template<
typename ChildT>
1313 return mTable.empty() ?
Coord(0) : mTable.begin()->first;
1316 template<
typename ChildT>
1320 return mTable.empty() ?
Coord(0) : mTable.rbegin()->first +
Coord(ChildT::DIM - 1);
1324 template<
typename ChildT>
1328 bbox.
min() = this->getMinIndex();
1329 bbox.
max() = this->getMaxIndex();
1336 template<
typename ChildT>
1337 template<
typename OtherChildType>
1342 using OtherMapT =
typename OtherRootT::MapType;
1343 using OtherIterT =
typename OtherRootT::MapIter;
1344 using OtherCIterT =
typename OtherRootT::MapCIter;
1346 if (!hasSameConfiguration(other))
return false;
1349 OtherMapT copyOfOtherTable = other.mTable;
1352 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1353 if (this->isBackgroundTile(thisIter))
continue;
1356 OtherCIterT otherIter = other.findKey(thisIter->first);
1357 if (otherIter == other.mTable.end())
return false;
1360 if (isChild(thisIter)) {
1361 if (OtherRootT::isTile(otherIter))
return false;
1363 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter)))
return false;
1365 if (OtherRootT::isChild(otherIter))
return false;
1366 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active)
return false;
1373 copyOfOtherTable.erase(otherIter->first);
1376 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1383 template<
typename ChildT>
1384 template<
typename OtherChildType>
1388 std::vector<Index> thisDims, otherDims;
1391 return (thisDims == otherDims);
1395 template<
typename ChildT>
1396 template<
typename OtherChildType>
1400 std::vector<Index> thisDims, otherDims;
1403 if (thisDims != otherDims) {
1404 std::ostringstream ostr;
1405 ostr <<
"grids have incompatible configurations (" << thisDims[0];
1406 for (
size_t i = 1, N = thisDims.size(); i < N; ++i) ostr <<
" x " << thisDims[i];
1407 ostr <<
" vs. " << otherDims[0];
1408 for (
size_t i = 1, N = otherDims.size(); i < N; ++i) ostr <<
" x " << otherDims[i];
1415 template<
typename ChildT>
1416 template<
typename OtherChildType>
1420 using OtherValueType =
typename OtherChildType::ValueType;
1425 template<
typename ChildT>
1426 template<
typename OtherChildType>
1430 using OtherValueType =
typename OtherChildType::ValueType;
1432 std::ostringstream ostr;
1433 ostr <<
"values of type " << typeNameAsString<OtherValueType>()
1434 <<
" cannot be converted to type " << typeNameAsString<ValueType>();
1443 template<
typename ChildT>
1448 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1449 if (
const ChildT *child = iter->second.child) {
1450 sum += child->memUsage();
1457 template<
typename ChildT>
1461 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1462 delete i->second.child;
1468 template<
typename ChildT>
1472 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1473 if (
const ChildT *child = iter->second.child) {
1474 child->evalActiveBoundingBox(bbox, visitVoxels);
1475 }
else if (isTileOn(iter)) {
1476 bbox.
expand(iter->first, ChildT::DIM);
1482 #if OPENVDB_ABI_VERSION_NUMBER < 8
1483 template<
typename ChildT>
1486 return this->childCount();
1491 template<
typename ChildT>
1493 RootNode<ChildT>::getTileCount()
const
1496 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1497 if (isTile(i)) ++sum;
1503 template<
typename ChildT>
1505 RootNode<ChildT>::getActiveTileCount()
const
1508 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1509 if (isTileOn(i)) ++sum;
1515 template<
typename ChildT>
1517 RootNode<ChildT>::getInactiveTileCount()
const
1520 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1521 if (isTileOff(i)) ++sum;
1527 template<
typename ChildT>
1532 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1533 if (isChild(i)) sum += getChild(i).leafCount();
1539 template<
typename ChildT>
1544 if (ChildT::LEVEL != 0) {
1545 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1546 if (isChild(i)) sum += getChild(i).nonLeafCount();
1553 template<
typename ChildT>
1558 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1559 if (isChild(i)) ++sum;
1565 template<
typename ChildT>
1570 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1572 sum += getChild(i).onVoxelCount();
1573 }
else if (isTileOn(i)) {
1574 sum += ChildT::NUM_VOXELS;
1581 template<
typename ChildT>
1586 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1588 sum += getChild(i).offVoxelCount();
1589 }
else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1590 sum += ChildT::NUM_VOXELS;
1597 template<
typename ChildT>
1602 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1603 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1609 template<
typename ChildT>
1614 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1615 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1620 template<
typename ChildT>
1625 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1627 sum += getChild(i).onTileCount();
1628 }
else if (isTileOn(i)) {
1635 template<
typename ChildT>
1639 assert(vec.size() > LEVEL);
1641 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1644 getChild(i).nodeCount(vec);
1648 vec[ChildNodeType::LEVEL] = sum;
1654 template<
typename ChildT>
1658 MapCIter iter = this->findCoord(xyz);
1659 if (iter == mTable.end() || isTileOff(iter))
return false;
1660 return isTileOn(iter) ? true : getChild(iter).isValueOn(xyz);
1663 template<
typename ChildT>
1667 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1668 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active)
return true;
1673 template<
typename ChildT>
1674 template<
typename AccessorT>
1678 MapCIter iter = this->findCoord(xyz);
1679 if (iter == mTable.end() || isTileOff(iter))
return false;
1680 if (isTileOn(iter))
return true;
1681 acc.insert(xyz, &getChild(iter));
1682 return getChild(iter).isValueOnAndCache(xyz, acc);
1686 template<
typename ChildT>
1687 inline const typename ChildT::ValueType&
1690 MapCIter iter = this->findCoord(xyz);
1691 return iter == mTable.end() ? mBackground
1692 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1695 template<
typename ChildT>
1696 template<
typename AccessorT>
1697 inline const typename ChildT::ValueType&
1700 MapCIter iter = this->findCoord(xyz);
1701 if (iter == mTable.end())
return mBackground;
1702 if (isChild(iter)) {
1703 acc.insert(xyz, &getChild(iter));
1704 return getChild(iter).getValueAndCache(xyz, acc);
1706 return getTile(iter).value;
1710 template<
typename ChildT>
1714 MapCIter iter = this->findCoord(xyz);
1715 return iter == mTable.end() ? -1
1716 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1719 template<
typename ChildT>
1720 template<
typename AccessorT>
1724 MapCIter iter = this->findCoord(xyz);
1725 if (iter == mTable.end())
return -1;
1726 if (isTile(iter))
return 0;
1727 acc.insert(xyz, &getChild(iter));
1728 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1732 template<
typename ChildT>
1736 MapIter iter = this->findCoord(xyz);
1737 if (iter != mTable.end() && !isTileOff(iter)) {
1738 if (isTileOn(iter)) {
1739 setChild(iter, *
new ChildT(xyz, getTile(iter).value,
true));
1741 getChild(iter).setValueOff(xyz);
1746 template<
typename ChildT>
1750 ChildT* child =
nullptr;
1751 MapIter iter = this->findCoord(xyz);
1752 if (iter == mTable.end()) {
1754 child =
new ChildT(xyz, mBackground);
1755 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1759 }
else if (isChild(iter)) {
1760 child = &getChild(iter);
1761 }
else if (on != getTile(iter).active) {
1762 child =
new ChildT(xyz, getTile(iter).value, !on);
1763 setChild(iter, *child);
1765 if (child) child->setActiveState(xyz, on);
1768 template<
typename ChildT>
1769 template<
typename AccessorT>
1773 ChildT* child =
nullptr;
1774 MapIter iter = this->findCoord(xyz);
1775 if (iter == mTable.end()) {
1777 child =
new ChildT(xyz, mBackground);
1778 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1782 }
else if (isChild(iter)) {
1783 child = &getChild(iter);
1784 }
else if (on != getTile(iter).active) {
1785 child =
new ChildT(xyz, getTile(iter).value, !on);
1786 setChild(iter, *child);
1789 acc.insert(xyz, child);
1790 child->setActiveStateAndCache(xyz, on, acc);
1795 template<
typename ChildT>
1799 ChildT* child =
nullptr;
1800 MapIter iter = this->findCoord(xyz);
1801 if (iter == mTable.end()) {
1803 child =
new ChildT(xyz, mBackground);
1804 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1806 }
else if (isChild(iter)) {
1807 child = &getChild(iter);
1809 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1810 setChild(iter, *child);
1812 if (child) child->setValueOff(xyz, value);
1815 template<
typename ChildT>
1816 template<
typename AccessorT>
1820 ChildT* child =
nullptr;
1821 MapIter iter = this->findCoord(xyz);
1822 if (iter == mTable.end()) {
1824 child =
new ChildT(xyz, mBackground);
1825 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1827 }
else if (isChild(iter)) {
1828 child = &getChild(iter);
1830 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1831 setChild(iter, *child);
1834 acc.insert(xyz, child);
1835 child->setValueOffAndCache(xyz, value, acc);
1840 template<
typename ChildT>
1844 ChildT* child =
nullptr;
1845 MapIter iter = this->findCoord(xyz);
1846 if (iter == mTable.end()) {
1847 child =
new ChildT(xyz, mBackground);
1848 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1849 }
else if (isChild(iter)) {
1850 child = &getChild(iter);
1852 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1853 setChild(iter, *child);
1855 if (child) child->setValueOn(xyz, value);
1858 template<
typename ChildT>
1859 template<
typename AccessorT>
1863 ChildT* child =
nullptr;
1864 MapIter iter = this->findCoord(xyz);
1865 if (iter == mTable.end()) {
1866 child =
new ChildT(xyz, mBackground);
1867 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1868 }
else if (isChild(iter)) {
1869 child = &getChild(iter);
1871 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1872 setChild(iter, *child);
1875 acc.insert(xyz, child);
1876 child->setValueAndCache(xyz, value, acc);
1881 template<
typename ChildT>
1885 ChildT* child =
nullptr;
1886 MapIter iter = this->findCoord(xyz);
1887 if (iter == mTable.end()) {
1888 child =
new ChildT(xyz, mBackground);
1889 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1890 }
else if (isChild(iter)) {
1891 child = &getChild(iter);
1893 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1894 setChild(iter, *child);
1896 if (child) child->setValueOnly(xyz, value);
1899 template<
typename ChildT>
1900 template<
typename AccessorT>
1904 ChildT* child =
nullptr;
1905 MapIter iter = this->findCoord(xyz);
1906 if (iter == mTable.end()) {
1907 child =
new ChildT(xyz, mBackground);
1908 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1909 }
else if (isChild(iter)) {
1910 child = &getChild(iter);
1912 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1913 setChild(iter, *child);
1916 acc.insert(xyz, child);
1917 child->setValueOnlyAndCache(xyz, value, acc);
1922 template<
typename ChildT>
1923 template<
typename ModifyOp>
1927 ChildT* child =
nullptr;
1928 MapIter iter = this->findCoord(xyz);
1929 if (iter == mTable.end()) {
1930 child =
new ChildT(xyz, mBackground);
1931 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1932 }
else if (isChild(iter)) {
1933 child = &getChild(iter);
1937 bool createChild = isTileOff(iter);
1941 const ValueType& tileVal = getTile(iter).value;
1947 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1948 setChild(iter, *child);
1951 if (child) child->modifyValue(xyz, op);
1954 template<
typename ChildT>
1955 template<
typename ModifyOp,
typename AccessorT>
1959 ChildT* child =
nullptr;
1960 MapIter iter = this->findCoord(xyz);
1961 if (iter == mTable.end()) {
1962 child =
new ChildT(xyz, mBackground);
1963 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1964 }
else if (isChild(iter)) {
1965 child = &getChild(iter);
1969 bool createChild = isTileOff(iter);
1973 const ValueType& tileVal = getTile(iter).value;
1979 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1980 setChild(iter, *child);
1984 acc.insert(xyz, child);
1985 child->modifyValueAndCache(xyz, op, acc);
1990 template<
typename ChildT>
1991 template<
typename ModifyOp>
1995 ChildT* child =
nullptr;
1996 MapIter iter = this->findCoord(xyz);
1997 if (iter == mTable.end()) {
1998 child =
new ChildT(xyz, mBackground);
1999 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2000 }
else if (isChild(iter)) {
2001 child = &getChild(iter);
2003 const Tile& tile = getTile(iter);
2004 bool modifiedState = tile.active;
2006 op(modifiedVal, modifiedState);
2010 child =
new ChildT(xyz, tile.value, tile.active);
2011 setChild(iter, *child);
2014 if (child) child->modifyValueAndActiveState(xyz, op);
2017 template<
typename ChildT>
2018 template<
typename ModifyOp,
typename AccessorT>
2021 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
2023 ChildT* child =
nullptr;
2024 MapIter iter = this->findCoord(xyz);
2025 if (iter == mTable.end()) {
2026 child =
new ChildT(xyz, mBackground);
2027 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2028 }
else if (isChild(iter)) {
2029 child = &getChild(iter);
2031 const Tile& tile = getTile(iter);
2032 bool modifiedState = tile.active;
2034 op(modifiedVal, modifiedState);
2038 child =
new ChildT(xyz, tile.value, tile.active);
2039 setChild(iter, *child);
2043 acc.insert(xyz, child);
2044 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2049 template<
typename ChildT>
2053 MapCIter iter = this->findCoord(xyz);
2054 if (iter == mTable.end()) {
2055 value = mBackground;
2057 }
else if (isChild(iter)) {
2058 return getChild(iter).probeValue(xyz, value);
2060 value = getTile(iter).value;
2061 return isTileOn(iter);
2064 template<
typename ChildT>
2065 template<
typename AccessorT>
2069 MapCIter iter = this->findCoord(xyz);
2070 if (iter == mTable.end()) {
2071 value = mBackground;
2073 }
else if (isChild(iter)) {
2074 acc.insert(xyz, &getChild(iter));
2075 return getChild(iter).probeValueAndCache(xyz, value, acc);
2077 value = getTile(iter).value;
2078 return isTileOn(iter);
2085 template<
typename ChildT>
2089 if (bbox.
empty())
return;
2094 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
2096 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
2098 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
2102 Coord tileMin = coordToKey(xyz);
2103 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2109 ChildT* child =
nullptr;
2110 MapIter iter = this->findKey(tileMin);
2111 if (iter == mTable.end()) {
2114 child =
new ChildT(xyz, mBackground);
2115 mTable[tileMin] = NodeStruct(*child);
2116 }
else if (isTile(iter)) {
2119 const Tile& tile = getTile(iter);
2120 child =
new ChildT(xyz, tile.value, tile.active);
2121 mTable[tileMin] = NodeStruct(*child);
2122 }
else if (isChild(iter)) {
2123 child = &getChild(iter);
2128 child->fill(
CoordBBox(xyz, tmp), value, active);
2134 MapIter iter = this->findOrAddCoord(tileMin);
2135 setTile(iter, Tile(value, active));
2143 template<
typename ChildT>
2147 if (bbox.
empty())
return;
2149 if (active && mTable.empty()) {
2152 sparseFill(bbox, value, active);
2153 voxelizeActiveTiles(
true);
2159 Coord xyz, tileMin, tileMax;
2160 for (
int x = bbox.
min().
x(); x <= bbox.
max().
x(); x = tileMax.
x() + 1) {
2162 for (
int y = bbox.
min().
y(); y <= bbox.
max().
y(); y = tileMax.
y() + 1) {
2164 for (
int z = bbox.
min().
z(); z <= bbox.
max().
z(); z = tileMax.
z() + 1) {
2168 tileMin = coordToKey(xyz);
2169 tileMax = tileMin.
offsetBy(ChildT::DIM - 1);
2173 const auto iter = findOrAddCoord(tileMin);
2178 const auto& tile = getTile(iter);
2179 auto* child =
new ChildT{tileMin, tile.value, tile.active};
2180 setChild(iter, *child);
2183 getChild(iter).denseFill(bbox, value, active);
2193 template<
typename ChildT>
2201 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2202 if (this->isTileOff(i))
continue;
2203 ChildT* child = i->second.child;
2204 if (child ==
nullptr) {
2207 child =
new ChildT{i->first, this->getTile(i).value,
true};
2208 i->second.child = child;
2210 child->voxelizeActiveTiles(threaded);
2218 template<
typename ChildT>
2219 template<
typename DenseT>
2223 using DenseValueType =
typename DenseT::ValueType;
2225 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2226 const Coord&
min = dense.bbox().min();
2228 for (
Coord xyz = bbox.
min(); xyz[0] <= bbox.
max()[0]; xyz[0] = nodeBBox.
max()[0] + 1) {
2229 for (xyz[1] = bbox.
min()[1]; xyz[1] <= bbox.
max()[1]; xyz[1] = nodeBBox.
max()[1] + 1) {
2230 for (xyz[2] = bbox.
min()[2]; xyz[2] <= bbox.
max()[2]; xyz[2] = nodeBBox.
max()[2] + 1) {
2238 MapCIter iter = this->findKey(nodeBBox.
min());
2239 if (iter != mTable.end() && isChild(iter)) {
2240 getChild(iter).copyToDense(sub, dense);
2242 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2244 DenseValueType* a0 = dense.data() + zStride*sub.
min()[2];
2245 for (
Int32 x=sub.
min()[0], ex=sub.
max()[0]+1; x<ex; ++x) {
2246 DenseValueType* a1 = a0 + x*xStride;
2247 for (
Int32 y=sub.
min()[1], ey=sub.
max()[1]+1; y<ey; ++y) {
2248 DenseValueType* a2 = a1 + y*yStride;
2249 for (
Int32 z=sub.
min()[2], ez=sub.
max()[2]+1; z<ez; ++z, a2 += zStride) {
2250 *a2 = DenseValueType(value);
2263 template<
typename ChildT>
2268 os.write(
reinterpret_cast<const char*
>(&mBackground),
sizeof(
ValueType));
2271 os.write(
reinterpret_cast<const char*
>(&truncatedVal),
sizeof(
ValueType));
2275 const Index numTiles = this->getTileCount(), numChildren = this->childCount();
2276 os.write(
reinterpret_cast<const char*
>(&numTiles),
sizeof(
Index));
2277 os.write(
reinterpret_cast<const char*
>(&numChildren),
sizeof(
Index));
2279 if (numTiles == 0 && numChildren == 0)
return false;
2282 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2283 if (isChild(i))
continue;
2284 os.write(
reinterpret_cast<const char*
>(i->first.asPointer()), 3 *
sizeof(
Int32));
2285 os.write(
reinterpret_cast<const char*
>(&getTile(i).value),
sizeof(
ValueType));
2286 os.write(
reinterpret_cast<const char*
>(&getTile(i).active),
sizeof(
bool));
2289 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2290 if (isTile(i))
continue;
2291 os.write(
reinterpret_cast<const char*
>(i->first.asPointer()), 3 *
sizeof(
Int32));
2292 getChild(i).writeTopology(os, toHalf);
2299 template<
typename ChildT>
2311 is.read(
reinterpret_cast<char*
>(&mBackground),
sizeof(
ValueType));
2313 is.read(
reinterpret_cast<char*
>(&inside),
sizeof(
ValueType));
2318 Coord rangeMin, rangeMax;
2320 is.read(
reinterpret_cast<char*
>(rangeMax.
asPointer()), 3 *
sizeof(
Int32));
2323 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2325 for (
int i = 0; i < 3; ++i) {
2326 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2327 rangeMin[i] = offset[i] << ChildT::TOTAL;
2329 tableSize += log2Dim[i];
2330 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2332 log2Dim[3] = log2Dim[1] + log2Dim[2];
2333 tableSize = 1U << tableSize;
2341 for (
Index i = 0; i < tableSize; ++i) {
2345 origin[0] = (n >> log2Dim[3]) + offset[0];
2346 n &= (1U << log2Dim[3]) - 1;
2347 origin[1] = (n >> log2Dim[2]) + offset[1];
2348 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2349 origin <<= ChildT::TOTAL;
2351 if (childMask.isOn(i)) {
2353 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2354 child->readTopology(is);
2355 mTable[origin] = NodeStruct(*child);
2360 is.read(
reinterpret_cast<char*
>(&value),
sizeof(
ValueType));
2362 mTable[origin] = NodeStruct(Tile(value, valueMask.
isOn(i)));
2371 is.read(
reinterpret_cast<char*
>(&mBackground),
sizeof(
ValueType));
2374 Index numTiles = 0, numChildren = 0;
2375 is.read(
reinterpret_cast<char*
>(&numTiles),
sizeof(
Index));
2376 is.read(
reinterpret_cast<char*
>(&numChildren),
sizeof(
Index));
2378 if (numTiles == 0 && numChildren == 0)
return false;
2385 for (
Index n = 0; n < numTiles; ++n) {
2386 is.read(
reinterpret_cast<char*
>(vec), 3 *
sizeof(
Int32));
2387 is.read(
reinterpret_cast<char*
>(&value),
sizeof(
ValueType));
2388 is.read(
reinterpret_cast<char*
>(&active),
sizeof(
bool));
2389 mTable[
Coord(vec)] = NodeStruct(Tile(value, active));
2393 for (
Index n = 0; n < numChildren; ++n) {
2394 is.read(
reinterpret_cast<char*
>(vec), 3 *
sizeof(
Int32));
2396 ChildT* child =
new ChildT(
PartialCreate(), origin, mBackground);
2397 child->readTopology(is, fromHalf);
2398 mTable[
Coord(vec)] = NodeStruct(*child);
2405 template<
typename ChildT>
2409 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2410 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2415 template<
typename ChildT>
2419 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2420 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2425 template<
typename ChildT>
2429 const Tile bgTile(mBackground,
false);
2431 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2437 ChildT& child = getChild(i);
2438 child.readBuffers(is, clipBBox, fromHalf);
2442 this->
clip(clipBBox);
2449 template<
typename ChildT>
2453 const Tile bgTile(mBackground,
false);
2457 MapType copyOfTable(mTable);
2458 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2459 const Coord& xyz = i->first;
2463 setTile(this->findCoord(xyz), bgTile);
2465 }
else if (!clipBBox.
isInside(tileBBox)) {
2469 getChild(i).clip(clipBBox, mBackground);
2474 const Tile& origTile = getTile(i);
2475 setTile(this->findCoord(xyz), bgTile);
2476 this->sparseFill(tileBBox, origTile.value, origTile.active);
2489 template<
typename ChildT>
2495 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2496 if (this->isTile(i))
continue;
2497 this->getChild(i).prune(tolerance);
2498 if (this->getChild(i).isConstant(value, state, tolerance)) {
2499 this->setTile(i, Tile(value, state));
2502 this->eraseBackgroundTiles();
2509 template<
typename ChildT>
2510 template<
typename NodeT>
2514 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2515 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2517 MapIter iter = this->findCoord(xyz);
2518 if (iter == mTable.end() || isTile(iter))
return nullptr;
2519 return (std::is_same<NodeT, ChildT>::value)
2520 ?
reinterpret_cast<NodeT*
>(&stealChild(iter, Tile(value, state)))
2521 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2529 template<
typename ChildT>
2533 if (leaf ==
nullptr)
return;
2534 ChildT* child =
nullptr;
2535 const Coord& xyz = leaf->origin();
2536 MapIter iter = this->findCoord(xyz);
2537 if (iter == mTable.end()) {
2538 if (ChildT::LEVEL>0) {
2539 child =
new ChildT(xyz, mBackground,
false);
2541 child =
reinterpret_cast<ChildT*
>(leaf);
2543 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2544 }
else if (isChild(iter)) {
2545 if (ChildT::LEVEL>0) {
2546 child = &getChild(iter);
2548 child =
reinterpret_cast<ChildT*
>(leaf);
2549 setChild(iter, *child);
2552 if (ChildT::LEVEL>0) {
2553 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2555 child =
reinterpret_cast<ChildT*
>(leaf);
2557 setChild(iter, *child);
2559 child->addLeaf(leaf);
2563 template<
typename ChildT>
2564 template<
typename AccessorT>
2568 if (leaf ==
nullptr)
return;
2569 ChildT* child =
nullptr;
2570 const Coord& xyz = leaf->origin();
2571 MapIter iter = this->findCoord(xyz);
2572 if (iter == mTable.end()) {
2573 if (ChildT::LEVEL>0) {
2574 child =
new ChildT(xyz, mBackground,
false);
2576 child =
reinterpret_cast<ChildT*
>(leaf);
2578 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2579 }
else if (isChild(iter)) {
2580 if (ChildT::LEVEL>0) {
2581 child = &getChild(iter);
2583 child =
reinterpret_cast<ChildT*
>(leaf);
2584 setChild(iter, *child);
2587 if (ChildT::LEVEL>0) {
2588 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2590 child =
reinterpret_cast<ChildT*
>(leaf);
2592 setChild(iter, *child);
2594 acc.insert(xyz, child);
2595 child->addLeafAndCache(leaf, acc);
2598 template<
typename ChildT>
2602 if (!child)
return false;
2603 const Coord& xyz = child->origin();
2604 MapIter iter = this->findCoord(xyz);
2605 if (iter == mTable.end()) {
2606 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2608 setChild(iter, *child);
2613 template<
typename ChildT>
2617 MapIter iter = this->findCoord(xyz);
2618 if (iter == mTable.end()) {
2619 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2621 setTile(iter, Tile(value, state));
2625 template<
typename ChildT>
2630 if (LEVEL >= level) {
2631 MapIter iter = this->findCoord(xyz);
2632 if (iter == mTable.end()) {
2633 if (LEVEL > level) {
2634 ChildT* child =
new ChildT(xyz, mBackground,
false);
2635 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2636 child->addTile(level, xyz, value, state);
2638 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2640 }
else if (isChild(iter)) {
2641 if (LEVEL > level) {
2642 getChild(iter).addTile(level, xyz, value, state);
2644 setTile(iter, Tile(value, state));
2647 if (LEVEL > level) {
2648 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2649 setChild(iter, *child);
2650 child->addTile(level, xyz, value, state);
2652 setTile(iter, Tile(value, state));
2659 template<
typename ChildT>
2660 template<
typename AccessorT>
2663 bool state, AccessorT& acc)
2665 if (LEVEL >= level) {
2666 MapIter iter = this->findCoord(xyz);
2667 if (iter == mTable.end()) {
2668 if (LEVEL > level) {
2669 ChildT* child =
new ChildT(xyz, mBackground,
false);
2670 acc.insert(xyz, child);
2671 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2672 child->addTileAndCache(level, xyz, value, state, acc);
2674 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2676 }
else if (isChild(iter)) {
2677 if (LEVEL > level) {
2678 ChildT* child = &getChild(iter);
2679 acc.insert(xyz, child);
2680 child->addTileAndCache(level, xyz, value, state, acc);
2682 setTile(iter, Tile(value, state));
2685 if (LEVEL > level) {
2686 ChildT* child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2687 acc.insert(xyz, child);
2688 setChild(iter, *child);
2689 child->addTileAndCache(level, xyz, value, state, acc);
2691 setTile(iter, Tile(value, state));
2701 template<
typename ChildT>
2702 inline typename ChildT::LeafNodeType*
2705 ChildT* child =
nullptr;
2706 MapIter iter = this->findCoord(xyz);
2707 if (iter == mTable.end()) {
2708 child =
new ChildT(xyz, mBackground,
false);
2709 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2710 }
else if (isChild(iter)) {
2711 child = &getChild(iter);
2713 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2714 setChild(iter, *child);
2716 return child->touchLeaf(xyz);
2720 template<
typename ChildT>
2721 template<
typename AccessorT>
2722 inline typename ChildT::LeafNodeType*
2725 ChildT* child =
nullptr;
2726 MapIter iter = this->findCoord(xyz);
2727 if (iter == mTable.end()) {
2728 child =
new ChildT(xyz, mBackground,
false);
2729 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2730 }
else if (isChild(iter)) {
2731 child = &getChild(iter);
2733 child =
new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2734 setChild(iter, *child);
2736 acc.insert(xyz, child);
2737 return child->touchLeafAndCache(xyz, acc);
2744 template<
typename ChildT>
2745 template<
typename NodeT>
2749 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2750 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2752 MapIter iter = this->findCoord(xyz);
2753 if (iter == mTable.end() || isTile(iter))
return nullptr;
2754 ChildT* child = &getChild(iter);
2755 return (std::is_same<NodeT, ChildT>::value)
2756 ?
reinterpret_cast<NodeT*
>(child)
2757 : child->template probeNode<NodeT>(xyz);
2762 template<
typename ChildT>
2763 template<
typename NodeT>
2767 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2768 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2770 MapCIter iter = this->findCoord(xyz);
2771 if (iter == mTable.end() || isTile(iter))
return nullptr;
2772 const ChildT* child = &getChild(iter);
2773 return (std::is_same<NodeT, ChildT>::value)
2774 ?
reinterpret_cast<const NodeT*
>(child)
2775 : child->template probeConstNode<NodeT>(xyz);
2780 template<
typename ChildT>
2781 inline typename ChildT::LeafNodeType*
2784 return this->
template probeNode<LeafNodeType>(xyz);
2788 template<
typename ChildT>
2789 inline const typename ChildT::LeafNodeType*
2792 return this->
template probeConstNode<LeafNodeType>(xyz);
2796 template<
typename ChildT>
2797 template<
typename AccessorT>
2798 inline typename ChildT::LeafNodeType*
2801 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
2805 template<
typename ChildT>
2806 template<
typename AccessorT>
2807 inline const typename ChildT::LeafNodeType*
2810 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2814 template<
typename ChildT>
2815 template<
typename AccessorT>
2816 inline const typename ChildT::LeafNodeType*
2819 return this->probeConstLeafAndCache(xyz, acc);
2823 template<
typename ChildT>
2824 template<
typename NodeT,
typename AccessorT>
2828 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2829 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2831 MapIter iter = this->findCoord(xyz);
2832 if (iter == mTable.end() || isTile(iter))
return nullptr;
2833 ChildT* child = &getChild(iter);
2834 acc.insert(xyz, child);
2835 return (std::is_same<NodeT, ChildT>::value)
2836 ?
reinterpret_cast<NodeT*
>(child)
2837 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2842 template<
typename ChildT>
2843 template<
typename NodeT,
typename AccessorT>
2847 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2848 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
2850 MapCIter iter = this->findCoord(xyz);
2851 if (iter == mTable.end() || isTile(iter))
return nullptr;
2852 const ChildT* child = &getChild(iter);
2853 acc.insert(xyz, child);
2854 return (std::is_same<NodeT, ChildT>::value)
2855 ?
reinterpret_cast<const NodeT*
>(child)
2856 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2863 template<
typename ChildT>
2864 template<
typename ArrayT>
2868 using NodePtr =
typename ArrayT::value_type;
2869 static_assert(std::is_pointer<NodePtr>::value,
2870 "argument to getNodes() must be a pointer array");
2871 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2872 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2873 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2874 "can't extract non-const nodes from a const tree");
2875 using ArrayChildT =
typename std::conditional<
2876 std::is_const<NodeType>::value,
const ChildT, ChildT>::type;
2878 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2879 if (ChildT* child = iter->second.child) {
2881 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2882 array.push_back(
reinterpret_cast<NodePtr
>(iter->second.child));
2884 child->getNodes(array);
2891 template<
typename ChildT>
2892 template<
typename ArrayT>
2896 using NodePtr =
typename ArrayT::value_type;
2897 static_assert(std::is_pointer<NodePtr>::value,
2898 "argument to getNodes() must be a pointer array");
2899 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2900 static_assert(std::is_const<NodeType>::value,
2901 "argument to getNodes() must be an array of const node pointers");
2902 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2903 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2904 "can't extract non-const nodes from a const tree");
2906 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2909 if (std::is_same<NodePtr, const ChildT*>::value) {
2910 array.push_back(
reinterpret_cast<NodePtr
>(iter->second.child));
2912 child->getNodes(array);
2921 template<
typename ChildT>
2922 template<
typename ArrayT>
2926 using NodePtr =
typename ArrayT::value_type;
2927 static_assert(std::is_pointer<NodePtr>::value,
2928 "argument to stealNodes() must be a pointer array");
2929 using NodeType =
typename std::remove_pointer<NodePtr>::type;
2930 using NonConstNodeType =
typename std::remove_const<NodeType>::type;
2931 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2932 "can't extract non-const nodes from a const tree");
2933 using ArrayChildT =
typename std::conditional<
2934 std::is_const<NodeType>::value,
const ChildT, ChildT>::type;
2936 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2937 if (ChildT* child = iter->second.child) {
2939 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2940 array.push_back(
reinterpret_cast<NodePtr
>(&stealChild(iter, Tile(value, state))));
2942 child->stealNodes(array, value, state);
2953 template<
typename ChildT>
2954 template<MergePolicy Policy>
2964 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2965 MapIter j = mTable.find(i->first);
2966 if (other.isChild(i)) {
2967 if (j == mTable.end()) {
2968 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2969 child.resetBackground(other.mBackground, mBackground);
2970 mTable[i->first] = NodeStruct(child);
2971 }
else if (isTile(j)) {
2973 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2974 child.resetBackground(other.mBackground, mBackground);
2978 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
2979 other.mBackground, mBackground);
2981 }
else if (other.isTileOn(i)) {
2982 if (j == mTable.end()) {
2983 mTable[i->first] = i->second;
2984 }
else if (!isTileOn(j)) {
2986 setTile(j, Tile(other.getTile(i).value,
true));
2993 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2994 MapIter j = mTable.find(i->first);
2995 if (other.isChild(i)) {
2996 if (j == mTable.end()) {
2997 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
2998 child.resetBackground(other.mBackground, mBackground);
2999 mTable[i->first] = NodeStruct(child);
3000 }
else if (isTile(j)) {
3001 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3002 child.resetBackground(other.mBackground, mBackground);
3005 getChild(j).template merge<MERGE_NODES>(
3006 getChild(i), other.mBackground, mBackground);
3013 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3014 MapIter j = mTable.find(i->first);
3015 if (other.isChild(i)) {
3016 if (j == mTable.end()) {
3018 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3019 child.resetBackground(other.mBackground, mBackground);
3020 mTable[i->first] = NodeStruct(child);
3021 }
else if (isTile(j)) {
3023 ChildNodeType& child = stealChild(i, Tile(other.mBackground,
false));
3024 child.resetBackground(other.mBackground, mBackground);
3025 const Tile tile = getTile(j);
3029 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3030 tile.value, tile.active);
3034 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
3035 other.mBackground, mBackground);
3037 }
else if (other.isTileOn(i)) {
3038 if (j == mTable.end()) {
3040 mTable[i->first] = i->second;
3041 }
else if (isTileOff(j)) {
3043 setTile(j, Tile(other.getTile(i).value,
true));
3044 }
else if (isChild(j)) {
3046 const Tile& tile = getTile(i);
3047 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3048 tile.value, tile.active);
3065 template<
typename ChildT>
3066 template<
typename OtherChildType>
3071 using OtherCIterT =
typename OtherRootT::MapCIter;
3073 enforceSameConfiguration(other);
3075 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3076 MapIter j = mTable.find(i->first);
3077 if (other.isChild(i)) {
3078 if (j == mTable.end()) {
3079 mTable[i->first] = NodeStruct(
3080 *(
new ChildT(other.getChild(i), mBackground,
TopologyCopy())));
3081 }
else if (this->isChild(j)) {
3082 this->getChild(j).topologyUnion(other.getChild(i), preserveTiles);
3084 if (!preserveTiles || this->isTileOff(j)) {
3085 ChildT* child =
new ChildT(
3086 other.getChild(i), this->getTile(j).value,
TopologyCopy());
3087 if (this->isTileOn(j)) child->setValuesOn();
3088 this->setChild(j, *child);
3091 }
else if (other.isTileOn(i)) {
3092 if (j == mTable.end()) {
3093 mTable[i->first] = NodeStruct(Tile(mBackground,
true));
3094 }
else if (this->isChild(j)) {
3095 this->getChild(j).setValuesOn();
3096 }
else if (this->isTileOff(j)) {
3097 this->setTile(j, Tile(this->getTile(j).value,
true));
3103 template<
typename ChildT>
3104 template<
typename OtherChildType>
3109 using OtherCIterT =
typename OtherRootT::MapCIter;
3111 enforceSameConfiguration(other);
3113 std::set<Coord> tmp;
3114 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3115 OtherCIterT j = other.mTable.find(i->first);
3116 if (this->isChild(i)) {
3117 if (j == other.mTable.end() || other.isTileOff(j)) {
3118 tmp.insert(i->first);
3119 }
else if (other.isChild(j)) {
3120 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3122 }
else if (this->isTileOn(i)) {
3123 if (j == other.mTable.end() || other.isTileOff(j)) {
3124 this->setTile(i, Tile(this->getTile(i).value,
false));
3125 }
else if (other.isChild(j)) {
3127 new ChildT(other.getChild(j), this->getTile(i).value,
TopologyCopy());
3128 this->setChild(i, *child);
3132 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3133 MapIter it = this->findCoord(*i);
3134 setTile(it, Tile());
3139 template<
typename ChildT>
3140 template<
typename OtherChildType>
3145 using OtherCIterT =
typename OtherRootT::MapCIter;
3147 enforceSameConfiguration(other);
3149 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3150 MapIter j = mTable.find(i->first);
3151 if (other.isChild(i)) {
3152 if (j == mTable.end() || this->isTileOff(j)) {
3154 }
else if (this->isChild(j)) {
3155 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3156 }
else if (this->isTileOn(j)) {
3158 ChildT* child =
new ChildT(j->first, this->getTile(j).value,
true);
3159 child->topologyDifference(other.getChild(i), mBackground);
3160 this->setChild(j, *child);
3162 }
else if (other.isTileOn(i)) {
3163 if (j == mTable.end() || this->isTileOff(j)) {
3165 }
else if (this->isChild(j)) {
3168 }
else if (this->isTileOn(j)) {
3169 this->setTile(j, Tile(this->getTile(j).value,
false));
3178 template<
typename ChildT>
3179 template<
typename CombineOp>
3186 this->insertKeys(keys);
3187 other.insertKeys(keys);
3189 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3190 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3191 if (isTile(iter) && isTile(otherIter)) {
3194 op(args.
setARef(getTile(iter).value)
3195 .setAIsActive(isTileOn(iter))
3196 .setBRef(getTile(otherIter).value)
3197 .setBIsActive(isTileOn(otherIter)));
3200 }
else if (isChild(iter) && isTile(otherIter)) {
3202 ChildT& child = getChild(iter);
3203 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3205 }
else if (isTile(iter) && isChild(otherIter)) {
3210 ChildT& child = getChild(otherIter);
3211 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3214 setChild(iter, stealChild(otherIter, Tile()));
3218 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3219 child.combine(otherChild, op);
3221 if (
prune && isChild(iter)) getChild(iter).prune();
3226 mBackground = args.
result();
3238 template<
typename CombineOp,
typename RootT,
typename OtherRootT,
bool Compatible = false>
3241 static inline void combine2(RootT&
self,
const RootT&,
const OtherRootT& other1,
3246 self.enforceSameConfiguration(other1);
3247 self.enforceCompatibleValueTypes(other1);
3249 std::ostringstream ostr;
3250 ostr <<
"cannot combine a " <<
typeid(OtherRootT).name()
3251 <<
" into a " <<
typeid(RootT).name();
3257 template<
typename CombineOp,
typename RootT,
typename OtherRootT>
3260 static inline void combine2(RootT&
self,
const RootT& other0,
const OtherRootT& other1,
3261 CombineOp& op,
bool prune)
3263 self.doCombine2(other0, other1, op,
prune);
3268 template<
typename ChildT>
3269 template<
typename CombineOp,
typename OtherRootNode>
3272 CombineOp& op,
bool prune)
3274 using OtherValueType =
typename OtherRootNode::ValueType;
3278 *
this, other0, other1, op,
prune);
3282 template<
typename ChildT>
3283 template<
typename CombineOp,
typename OtherRootNode>
3286 CombineOp& op,
bool prune)
3288 enforceSameConfiguration(other1);
3290 using OtherValueT =
typename OtherRootNode::ValueType;
3291 using OtherTileT =
typename OtherRootNode::Tile;
3292 using OtherNodeStructT =
typename OtherRootNode::NodeStruct;
3293 using OtherMapCIterT =
typename OtherRootNode::MapCIter;
3298 other0.insertKeys(keys);
3299 other1.insertKeys(keys);
3301 const NodeStruct bg0(Tile(other0.mBackground,
false));
3302 const OtherNodeStructT bg1(OtherTileT(other1.mBackground,
false));
3304 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3305 MapIter thisIter = this->findOrAddCoord(*i);
3306 MapCIter iter0 = other0.findKey(*i);
3307 OtherMapCIterT iter1 = other1.findKey(*i);
3308 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3309 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3310 if (ns0.isTile() && ns1.isTile()) {
3313 op(args.
setARef(ns0.tile.value)
3319 if (!isChild(thisIter)) {
3321 const Coord& childOrigin =
3322 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3323 setChild(thisIter, *(
new ChildT(childOrigin, getTile(thisIter).value)));
3325 ChildT& child = getChild(thisIter);
3330 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3331 }
else if (ns1.isTile()) {
3334 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3338 child.combine2(*ns0.child, *ns1.child, op);
3341 if (
prune && isChild(thisIter)) getChild(thisIter).prune();
3345 op(args.
setARef(other0.mBackground).
setBRef(other1.mBackground));
3346 mBackground = args.
result();
3353 template<
typename ChildT>
3354 template<
typename BBoxOp>
3358 const bool descent = op.template descent<LEVEL>();
3359 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3360 if (this->isTileOff(i))
continue;
3361 if (this->isChild(i) && descent) {
3362 this->getChild(i).visitActiveBBox(op);
3370 template<
typename ChildT>
3371 template<
typename VisitorOp>
3375 doVisit<RootNode, VisitorOp, ChildAllIter>(*
this, op);
3379 template<
typename ChildT>
3380 template<
typename VisitorOp>
3384 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*
this, op);
3388 template<
typename ChildT>
3389 template<
typename RootNodeT,
typename VisitorOp,
typename ChildAllIterT>
3393 typename RootNodeT::ValueType val;
3394 for (ChildAllIterT iter =
self.beginChildAll(); iter; ++iter) {
3395 if (op(iter))
continue;
3396 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3406 template<
typename ChildT>
3407 template<
typename OtherRootNodeType,
typename VisitorOp>
3412 typename OtherRootNodeType::ChildAllIter>(*
this, other, op);
3416 template<
typename ChildT>
3417 template<
typename OtherRootNodeType,
typename VisitorOp>
3422 typename OtherRootNodeType::ChildAllCIter>(*
this, other, op);
3426 template<
typename ChildT>
3429 typename OtherRootNodeT,
3431 typename ChildAllIterT,
3432 typename OtherChildAllIterT>
3436 enforceSameConfiguration(other);
3438 typename RootNodeT::ValueType val;
3439 typename OtherRootNodeT::ValueType otherVal;
3444 RootNodeT copyOfSelf(
self.mBackground);
3445 copyOfSelf.mTable =
self.mTable;
3446 OtherRootNodeT copyOfOther(other.mBackground);
3447 copyOfOther.mTable = other.mTable;
3451 self.insertKeys(keys);
3452 other.insertKeys(keys);
3453 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3454 copyOfSelf.findOrAddCoord(*i);
3455 copyOfOther.findOrAddCoord(*i);
3458 ChildAllIterT iter = copyOfSelf.beginChildAll();
3459 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3461 for ( ; iter && otherIter; ++iter, ++otherIter)
3463 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
3465 typename ChildAllIterT::ChildNodeType* child =
3466 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
3467 typename OtherChildAllIterT::ChildNodeType* otherChild =
3468 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
3470 if (child !=
nullptr && otherChild !=
nullptr) {
3471 child->visit2Node(*otherChild, op);
3472 }
else if (child !=
nullptr) {
3473 child->visit2(otherIter, op);
3474 }
else if (otherChild !=
nullptr) {
3475 otherChild->visit2(iter, op,
true);
3480 copyOfSelf.eraseBackgroundTiles();
3481 copyOfOther.eraseBackgroundTiles();
3485 self.resetTable(copyOfSelf.mTable);
3486 other.resetTable(copyOfOther.mTable);
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: openvdb/Types.h:447
CombineArgs & setBIsActive(bool b)
Set the active state of the B value.
Definition: openvdb/Types.h:515
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: openvdb/Types.h:499
CombineArgs & setAIsActive(bool b)
Set the active state of the A value.
Definition: openvdb/Types.h:513
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:491
bool resultIsActive() const
Definition: openvdb/Types.h:510
CombineArgs & setBRef(const BValueType &b)
Redirect the B value to a new external source.
Definition: openvdb/Types.h:501
Tag dispatch class that distinguishes constructors during file input.
Definition: openvdb/Types.h:566
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:560
Definition: openvdb/Exceptions.h:64
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:249
const Coord & min() const
Definition: Coord.h:321
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition: Coord.h:458
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:418
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:356
const Coord & max() const
Definition: Coord.h:322
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:412
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:319
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:400
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:444
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:313
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
Coord & setX(Int32 x)
Definition: Coord.h:80
Int32 y() const
Definition: Coord.h:132
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:92
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:176
Coord & setY(Int32 y)
Definition: Coord.h:81
Int32 x() const
Definition: Coord.h:131
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:209
Int32 z() const
Definition: Coord.h:133
const Int32 * asPointer() const
Definition: Coord.h:142
Coord & setZ(Int32 z)
Definition: Coord.h:82
void read(std::istream &is)
Definition: Coord.h:220
Definition: RootNode.h:39
static CoordBBox getNodeBoundingBox()
Return the bounding box of this RootNode, i.e., an infinite bounding box.
Definition: RootNode.h:406
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1861
DenseIter< RootNode, MapIter, ChildType, ValueType > ChildAllIter
Definition: RootNode.h:364
void visit(VisitorOp &)
Definition: RootNode.h:3373
static bool hasSameConfiguration(const RootNode< OtherChildType > &other)
Return false if the other node's dimensions don't match this node's.
Definition: RootNode.h:1386
int getValueDepth(const Coord &xyz) const
Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
Definition: RootNode.h:1712
RootNode & operator=(const RootNode< OtherChildType > &other)
Copy a root node of the same tree configuration as this node but a different ValueType.
ValueIter< const RootNode, MapCIter, ValueOffPred, const ValueType > ValueOffCIter
Definition: RootNode.h:370
RootNode(const RootNode &other)
Definition: RootNode.h:75
ChildOnCIter cbeginChildOn() const
Definition: RootNode.h:375
ChildOnCIter beginChildOn() const
Definition: RootNode.h:378
ChildOnIter beginChildOn()
Definition: RootNode.h:381
Index getDepth() const
Definition: RootNode.h:457
bool isValueOn(const Coord &xyz) const
Definition: RootNode.h:1656
ValueIter< const RootNode, MapCIter, ValueOnPred, const ValueType > ValueOnCIter
Definition: RootNode.h:368
void getIndexRange(CoordBBox &bbox) const
Return the current index range. Both min and max are inclusive.
Definition: RootNode.h:1326
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:2221
const ValueType & background() const
Return this node's background value.
Definition: RootNode.h:423
RootNode & operator=(const RootNode &other)
Copy a root node of the same type as this node.
Definition: RootNode.h:1153
Coord getMaxIndex() const
Return the largest index of the current tree.
Definition: RootNode.h:1318
ValueOffCIter cbeginValueOff() const
Definition: RootNode.h:386
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() but, if necessary, update the given accessor with pointers to the nodes along the p...
Definition: RootNode.h:2566
static Index getChildDim()
Definition: RootNode.h:450
Index32 nonLeafCount() const
Definition: RootNode.h:1541
void combine(RootNode &other, CombineOp &, bool prune=false)
Definition: RootNode.h:3181
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:2600
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: RootNode.h:2866
NodeT * stealNode(const Coord &xyz, const ValueType &value, bool state)
Return a pointer to the node of type NodeT that contains voxel (x, y, z) and replace it with a tile o...
Definition: RootNode.h:2512
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: RootNode.h:2195
ValueIter< RootNode, MapIter, ValueOffPred, ValueType > ValueOffIter
Definition: RootNode.h:369
ValueIter< RootNode, MapIter, ValueAllPred, ValueType > ValueAllIter
Definition: RootNode.h:371
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:3068
Index64 onLeafVoxelCount() const
Definition: RootNode.h:1599
void clip(const CoordBBox &)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: RootNode.h:2451
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:2782
static bool hasCompatibleValueType(const RootNode< OtherChildType > &other)
Definition: RootNode.h:1418
ValueAllCIter cbeginValueAll() const
Definition: RootNode.h:387
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:2826
void prune(const ValueType &tolerance=zeroVal< ValueType >())
Reduce the memory footprint of this tree by replacing with tiles any nodes whose values are all the s...
Definition: RootNode.h:2491
typename NodeChain< RootNode, LEVEL >::Type NodeChainType
NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode.
Definition: RootNode.h:49
bool isBackgroundTile(const Tile &) const
Return true if the given tile is inactive and has the background value.
Definition: RootNode.h:1215
typename ChildType::LeafNodeType LeafNodeType
Definition: RootNode.h:42
size_t eraseBackgroundTiles()
Remove all background tiles.
Definition: RootNode.h:1249
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:3142
ValueIter< RootNode, MapIter, ValueOnPred, ValueType > ValueOnIter
Definition: RootNode.h:367
ValueOnCIter beginValueOn() const
Definition: RootNode.h:388
void merge(RootNode &other)
Efficiently merge another tree into this tree using one of several schemes.
Definition: RootNode.h:2956
ChildIter< RootNode, MapIter, ChildOnPred, ChildType > ChildOnIter
Definition: RootNode.h:360
Index64 offLeafVoxelCount() const
Definition: RootNode.h:1611
Index getWidth() const
Definition: RootNode.h:455
Index getTableSize() const
Return the number of entries in this node's table.
Definition: RootNode.h:453
void combine2(const RootNode &other0, const OtherRootNode &other1, CombineOp &op, bool prune=false)
Definition: RootNode.h:3271
const LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc) const
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: RootNode.h:1993
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1902
size_t numBackgroundTiles() const
Return the number of background tiles.
Definition: RootNode.h:1237
ValueIter< const RootNode, MapCIter, ChildOffPred, ValueType > ChildOffCIter
Definition: RootNode.h:363
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates but don't change its active state.
Definition: RootNode.h:1883
bool empty() const
Return true if this node's table is either empty or contains only background tiles.
Definition: RootNode.h:441
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Definition: RootNode.h:2790
void fill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within a given axis-aligned box to a constant value.
Definition: RootNode.h:2087
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
ValueOffCIter beginValueOff() const
Definition: RootNode.h:389
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: RootNode.h:1818
void addLeaf(LeafNodeType *leaf)
Add the given leaf node to this tree, creating a new branch if necessary. If a leaf node with the sam...
Definition: RootNode.h:2531
ChildAllCIter cbeginChildAll() const
Definition: RootNode.h:377
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:2615
ChildAllIter beginChildAll()
Definition: RootNode.h:383
static Index getLevel()
Definition: RootNode.h:448
bool writeTopology(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2265
ValueIter< const RootNode, MapCIter, ValueAllPred, const ValueType > ValueAllCIter
Definition: RootNode.h:372
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1676
const NodeT * probeConstNodeAndCache(const Coord &xyz, AccessorT &acc) const
Definition: RootNode.h:2845
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: RootNode.h:2051
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: RootNode.h:1748
ValueOnIter beginValueOn()
Definition: RootNode.h:391
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:1957
void visit2(OtherRootNodeType &other, VisitorOp &)
Definition: RootNode.h:3409
ChildOffCIter cbeginChildOff() const
Definition: RootNode.h:376
ChildOffIter beginChildOff()
Definition: RootNode.h:382
Index64 onVoxelCount() const
Definition: RootNode.h:1567
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as touchLeaf() but, if necessary, update the given accessor with pointers to the nodes along the...
ChildOffCIter beginChildOff() const
Definition: RootNode.h:379
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:2662
typename ChildType::ValueType ValueType
Definition: RootNode.h:43
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: RootNode.h:1734
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: RootNode.h:2407
ValueOnCIter cbeginValueOn() const
Definition: RootNode.h:385
Index32 leafCount() const
Definition: RootNode.h:1529
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Index32 childCount() const
Definition: RootNode.h:1555
Index64 onTileCount() const
Definition: RootNode.h:1622
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active.
Definition: RootNode.h:1925
void visitActiveBBox(BBoxOp &) const
Call the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes i...
Definition: RootNode.h:3356
~RootNode()
Definition: RootNode.h:123
Index64 offVoxelCount() const
Definition: RootNode.h:1583
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:2703
typename ChildType::BuildType BuildType
Definition: RootNode.h:44
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:1188
DenseIter< const RootNode, MapCIter, const ChildType, const ValueType > ChildAllCIter
Definition: RootNode.h:365
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:1339
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:2145
ChildAllCIter beginChildAll() const
Definition: RootNode.h:380
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: RootNode.h:1771
const LeafNodeType * probeLeaf(const Coord &xyz) const
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:3106
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:2924
Index getHeight() const
Definition: RootNode.h:456
void clear()
Definition: RootNode.h:1459
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: RootNode.h:2067
const NodeT * probeConstNode(const Coord &xyz) const
Definition: RootNode.h:2765
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:1470
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
static void getNodeLog2Dims(std::vector< Index > &dims)
Definition: RootNode.h:1302
RootNode(const RootNode< OtherChildType > &other)
Construct a new tree that reproduces the topology and active states of a tree of a different ValueTyp...
Definition: RootNode.h:84
ValueOffIter beginValueOff()
Definition: RootNode.h:392
ValueIter< RootNode, MapIter, ChildOffPred, const ValueType > ChildOffIter
Definition: RootNode.h:362
void sparseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Definition: RootNode.h:532
Coord getMinIndex() const
Return the smallest index of the current tree.
Definition: RootNode.h:1311
ChildType ChildNodeType
Definition: RootNode.h:41
bool hasActiveTiles() const
Return true if this root node, or any of its child nodes, have active tiles.
Definition: RootNode.h:1665
int getValueDepthAndCache(const Coord &xyz, AccessorT &) const
Definition: RootNode.h:1722
const ValueType & getValue(const Coord &xyz) const
Definition: RootNode.h:1688
void nodeCount(std::vector< Index32 > &vec) const
Definition: RootNode.h:1637
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: RootNode.h:1445
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active.
Definition: RootNode.h:1842
void stealNodes(ArrayT &array)
Definition: RootNode.h:811
bool expand(const Coord &xyz)
Expand this node's table so that (x, y, z) is included in the index range.
Definition: RootNode.h:1288
void readBuffers(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2417
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: RootNode.h:2020
ValueAllCIter beginValueAll() const
Definition: RootNode.h:390
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:2747
bool readTopology(std::istream &, bool fromHalf=false)
Definition: RootNode.h:2301
ChildIter< const RootNode, MapCIter, ChildOnPred, const ChildType > ChildOnCIter
Definition: RootNode.h:361
ValueAllIter beginValueAll()
Definition: RootNode.h:393
friend class RootNode
Definition: RootNode.h:896
Definition: NodeMasks.h:1067
bool isOn(Index32 i) const
Definition: NodeMasks.h:1331
void load(std::istream &is)
Definition: NodeMasks.h:1372
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:216
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...
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:407
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:611
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:485
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:477
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:127
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:159
Index32 Index
Definition: openvdb/Types.h:50
uint32_t Index32
Definition: openvdb/Types.h:48
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:69
@ OPENVDB_FILE_VERSION_ROOTNODE_MAP
Definition: version.h.in:212
int32_t Int32
Definition: openvdb/Types.h:52
uint64_t Index64
Definition: openvdb/Types.h:49
@ MERGE_ACTIVE_STATES
Definition: openvdb/Types.h:385
@ MERGE_NODES
Definition: openvdb/Types.h:386
@ MERGE_ACTIVE_STATES_AND_NODES
Definition: openvdb/Types.h:387
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
Definition: openvdb/Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
CanConvertType<FromType, ToType>::value is true if a value of type ToType can be constructed from a v...
Definition: openvdb/Types.h:281
Definition: openvdb/Types.h:538
A list of types (not necessarily unique)
Definition: TypeList.h:366
NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a openvdb::TypeList that lists the types of the...
Definition: RootNode.h:996
typename NodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition: RootNode.h:997
typename SubtreeT::template Append< HeadT > Type
Definition: RootNode.h:998
static void combine2(RootT &self, const RootT &other0, const OtherRootT &other1, CombineOp &op, bool prune)
Definition: RootNode.h:3260
Definition: RootNode.h:3240
static void combine2(RootT &self, const RootT &, const OtherRootT &other1, CombineOp &, bool)
Definition: RootNode.h:3241
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1115
Definition: RootNode.h:1096
static void copyWithValueConversion(RootT &self, const OtherRootT &other)
Definition: RootNode.h:1097
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a RootNod...
Definition: RootNode.h:64
ValueConverter<T>::Type is the type of a RootNode having the same child hierarchy as this node but a ...
Definition: RootNode.h:56
Definition: RootNode.h:1015
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178