8 #ifndef OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 9 #define OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED 19 #include <tbb/parallel_for.h> 21 #include <type_traits> 32 template<
typename _ChildNodeType, Index Log2Dim>
38 using ValueType =
typename ChildNodeType::ValueType;
39 using BuildType =
typename ChildNodeType::BuildType;
45 TOTAL = Log2Dim + ChildNodeType::TOTAL,
47 NUM_VALUES = 1 << (3 * Log2Dim),
48 LEVEL = 1 + ChildNodeType::LEVEL;
50 NUM_VOXELS = uint64_t(1) << (3 * TOTAL);
54 template<
typename OtherValueType>
63 template<
typename OtherNodeType>
65 static const bool value =
94 template<
typename OtherChildNodeType>
100 template<
typename OtherChildNodeType>
107 template<
typename OtherChildNodeType>
126 template<
typename NodeT,
typename ChildT,
typename MaskIterT,
typename TagT>
128 MaskIterT, ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>
132 MaskIterT,
ChildIter<NodeT, ChildT, MaskIterT, TagT>, NodeT, ChildT>(iter, parent) {}
136 assert(this->parent().isChildMaskOn(pos));
137 return *(this->parent().getChildNode(pos));
141 void setItem(
Index pos,
const ChildT& c)
const { this->parent().resetChildNode(pos, &c); }
147 template<
typename NodeT,
typename ValueT,
typename MaskIterT,
typename TagT>
149 MaskIterT, ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>
153 MaskIterT,
ValueIter<NodeT, ValueT, MaskIterT, TagT>, NodeT, ValueT>(iter, parent) {}
155 const ValueT&
getItem(
Index pos)
const {
return this->parent().mNodes[pos].getValue(); }
158 void setItem(
Index pos,
const ValueT& v)
const { this->parent().mNodes[pos].setValue(v); }
161 template<
typename ModifyOp>
164 op(this->parent().mNodes[pos].getValue());
169 template<
typename NodeT,
typename ChildT,
typename ValueT,
typename TagT>
171 MaskDenseIterator, DenseIter<NodeT, ChildT, ValueT, TagT>, NodeT, ChildT, ValueT>
182 if (this->parent().isChildMaskOn(pos)) {
183 child = this->parent().getChildNode(pos);
187 value = this->parent().mNodes[pos].getValue();
194 this->parent().resetChildNode(pos, child);
200 this->parent().unsetChildNode(pos, value);
252 static void getNodeLog2Dims(std::vector<Index>& dims);
259 static Index coordToOffset(
const Coord& xyz);
262 static void offsetToLocalCoord(
Index n, Coord& xyz);
264 Coord offsetToGlobalCoord(
Index n)
const;
267 const Coord&
origin()
const {
return mOrigin; }
269 void setOrigin(
const Coord& origin) { mOrigin = origin; }
272 void nodeCount(std::vector<Index32> &vec)
const;
277 Index64 onLeafVoxelCount()
const;
278 Index64 offLeafVoxelCount()
const;
288 void evalActiveBoundingBox(CoordBBox& bbox,
bool visitVoxels =
true)
const;
295 bool isEmpty()
const {
return mChildMask.isOff(); }
302 bool isConstant(
ValueType& firstValue,
bool& state,
303 const ValueType& tolerance = zeroVal<ValueType>())
const;
320 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
323 bool isInactive()
const {
return this->isChildMaskOff() && this->isValueMaskOff(); }
326 bool isValueOn(
const Coord& xyz)
const;
331 bool hasActiveTiles()
const;
333 const ValueType& getValue(
const Coord& xyz)
const;
334 bool probeValue(
const Coord& xyz,
ValueType& value)
const;
338 Index getValueLevel(
const Coord& xyz)
const;
348 void setActiveState(
const Coord& xyz,
bool on);
350 void setValueOnly(
const Coord& xyz,
const ValueType& value);
352 void setValueOn(
const Coord& xyz);
354 void setValueOn(
const Coord& xyz,
const ValueType& value);
356 void setValueOff(
const Coord& xyz);
358 void setValueOff(
const Coord& xyz,
const ValueType& value);
362 template<
typename ModifyOp>
363 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
365 template<
typename ModifyOp>
366 void modifyValueAndActiveState(
const Coord& xyz,
const ModifyOp& op);
372 template<
typename AccessorT>
373 const ValueType& getValueAndCache(
const Coord& xyz, AccessorT&)
const;
379 template<
typename AccessorT>
380 bool isValueOnAndCache(
const Coord& xyz, AccessorT&)
const;
386 template<
typename AccessorT>
387 void setValueAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
393 template<
typename AccessorT>
394 void setValueOnlyAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
401 template<
typename ModifyOp,
typename AccessorT>
402 void modifyValueAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
408 template<
typename ModifyOp,
typename AccessorT>
409 void modifyValueAndActiveStateAndCache(
const Coord& xyz,
const ModifyOp& op, AccessorT&);
415 template<
typename AccessorT>
416 void setValueOffAndCache(
const Coord& xyz,
const ValueType& value, AccessorT&);
422 template<
typename AccessorT>
423 void setActiveStateAndCache(
const Coord& xyz,
bool on, AccessorT&);
430 template<
typename AccessorT>
431 bool probeValueAndCache(
const Coord& xyz,
ValueType& value, AccessorT&)
const;
439 template<
typename AccessorT>
440 Index getValueLevelAndCache(
const Coord& xyz, AccessorT&)
const;
448 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
449 void readTopology(std::istream&,
bool fromHalf =
false);
450 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
451 void readBuffers(std::istream&,
bool fromHalf =
false);
452 void readBuffers(std::istream&,
const CoordBBox&,
bool fromHalf =
false);
470 void fill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
479 void denseFill(
const CoordBBox& bbox,
const ValueType& value,
bool active =
true);
484 void voxelizeActiveTiles(
bool threaded =
true);
493 template<
typename DenseT>
494 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
498 template<MergePolicy Policy>
503 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
517 template<
typename OtherChildNodeType>
533 template<
typename OtherChildNodeType>
548 template<
typename OtherChildNodeType>
552 template<
typename CombineOp>
554 template<
typename CombineOp>
557 template<
typename CombineOp,
typename OtherNodeType >
558 void combine2(
const InternalNode& other0,
const OtherNodeType& other1, CombineOp&);
559 template<
typename CombineOp,
typename OtherNodeType >
560 void combine2(
const ValueType& value,
const OtherNodeType& other,
bool valIsActive, CombineOp&);
561 template<
typename CombineOp,
typename OtherValueType>
562 void combine2(
const InternalNode& other,
const OtherValueType&,
bool valIsActive, CombineOp&);
569 template<
typename BBoxOp>
void visitActiveBBox(BBoxOp&)
const;
571 template<
typename VisitorOp>
void visit(VisitorOp&);
572 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
574 template<
typename OtherNodeType,
typename VisitorOp>
575 void visit2Node(OtherNodeType& other, VisitorOp&);
576 template<
typename OtherNodeType,
typename VisitorOp>
577 void visit2Node(OtherNodeType& other, VisitorOp&)
const;
578 template<
typename IterT,
typename VisitorOp>
579 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
580 template<
typename IterT,
typename VisitorOp>
581 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
597 template<
typename AccessorT>
608 template<
typename NodeT>
609 NodeT* stealNode(
const Coord& xyz,
const ValueType& value,
bool state);
621 void addTile(
Index level,
const Coord& xyz,
const ValueType& value,
bool state);
628 template<
typename AccessorT>
629 void addTileAndCache(
Index level,
const Coord& xyz,
const ValueType&,
bool state, AccessorT&);
632 template<
typename NodeType> NodeType* probeNode(
const Coord& xyz);
635 template<
typename NodeType>
const NodeType* probeConstNode(
const Coord& xyz)
const;
639 template<
typename NodeType,
typename AccessorT>
642 NodeType* probeNodeAndCache(
const Coord& xyz, AccessorT&);
643 template<
typename NodeType,
typename AccessorT>
644 const NodeType* probeConstNodeAndCache(
const Coord& xyz, AccessorT&)
const;
651 const LeafNodeType* probeConstLeaf(
const Coord& xyz)
const;
656 template<
typename AccessorT>
659 LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc);
660 template<
typename AccessorT>
661 const LeafNodeType* probeConstLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
662 template<
typename AccessorT>
663 const LeafNodeType* probeLeafAndCache(
const Coord& xyz, AccessorT& acc)
const;
676 template<
typename AccessorT>
677 LeafNodeType* touchLeafAndCache(
const Coord& xyz, AccessorT&);
680 template<
typename ArrayT>
703 void getNodes(ArrayT& array);
704 template<
typename ArrayT>
705 void getNodes(ArrayT& array)
const;
731 template<
typename ArrayT>
732 void stealNodes(ArrayT& array,
const ValueType& value,
bool state);
740 template<
typename OtherChildNodeType, Index OtherLog2Dim>
745 friend class IteratorBase<MaskOnIterator, InternalNode>;
754 template<
typename, Index>
friend class InternalNode;
777 void setValueMask(
Index n,
bool on) { mValueMask.set(n, mChildMask.isOn(n) ?
false : on); }
787 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
788 static inline void doVisit(NodeT&, VisitorOp&);
790 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
791 typename ChildAllIterT,
typename OtherChildAllIterT>
792 static inline void doVisit2Node(NodeT&, OtherNodeT&, VisitorOp&);
794 template<
typename NodeT,
typename VisitorOp,
795 typename ChildAllIterT,
typename OtherChildAllIterT>
796 static inline void doVisit2(NodeT&, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
809 template<
typename OtherInternalNode>
struct DeepCopy;
828 template<
typename ChildT1, Index Dim1,
typename NodeT2>
832 static const bool value =
false;
835 template<
typename ChildT1, Index Dim1,
typename ChildT2>
837 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
845 template<
typename ChildT, Index Log2Dim>
849 for (
Index i = 0; i < NUM_VALUES; ++i) mNodes[i].setValue(background);
853 template<
typename ChildT, Index Log2Dim>
856 mOrigin(origin[0] & ~(DIM - 1),
857 origin[1] & ~(DIM - 1),
858 origin[2] & ~(DIM - 1))
867 template<
typename ChildT, Index Log2Dim>
877 template<
typename ChildT, Index Log2Dim>
878 template<
typename OtherInternalNode>
882 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
886 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
887 if (s->mChildMask.isOff(i)) {
888 t->mNodes[i].setValue(
ValueType(s->mNodes[i].getValue()));
890 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild())));
894 const OtherInternalNode*
s;
898 template<
typename ChildT, Index Log2Dim>
910 template<
typename ChildT, Index Log2Dim>
911 template<
typename OtherChildNodeType>
921 template<
typename ChildT, Index Log2Dim>
922 template<
typename OtherInternalNode>
926 const ValueType& background) : s(source), t(target), b(background) {
927 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
931 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
932 if (s->isChildMaskOn(i)) {
933 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
936 t->mNodes[i].setValue(b);
940 const OtherInternalNode*
s;
945 template<
typename ChildT, Index Log2Dim>
946 template<
typename OtherChildNodeType>
957 template<
typename ChildT, Index Log2Dim>
958 template<
typename OtherInternalNode>
963 : s(source), t(target), offV(offValue), onV(onValue) {
964 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
967 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
968 if (s->isChildMaskOn(i)) {
969 t->mNodes[i].setChild(
new ChildNodeType(*(s->mNodes[i].getChild()),
972 t->mNodes[i].setValue(s->isValueMaskOn(i) ? onV : offV);
976 const OtherInternalNode*
s;
981 template<
typename ChildT, Index Log2Dim>
982 template<
typename OtherChildNodeType>
995 template<
typename ChildT, Index Log2Dim>
1008 template<
typename ChildT, Index Log2Dim>
1015 sum += iter->leafCount();
1020 template<
typename ChildT, Index Log2Dim>
1024 assert(vec.size() > ChildNodeType::LEVEL);
1026 if (ChildNodeType::LEVEL > 0 && count > 0) {
1027 for (
auto iter = this->
cbeginChildOn(); iter; ++iter) iter->nodeCount(vec);
1029 vec[ChildNodeType::LEVEL] += count;
1033 template<
typename ChildT, Index Log2Dim>
1040 sum += iter->nonLeafCount();
1046 template<
typename ChildT, Index Log2Dim>
1054 template<
typename ChildT, Index Log2Dim>
1060 sum += iter->onVoxelCount();
1066 template<
typename ChildT, Index Log2Dim>
1072 sum += iter->offVoxelCount();
1078 template<
typename ChildT, Index Log2Dim>
1090 template<
typename ChildT, Index Log2Dim>
1101 template<
typename ChildT, Index Log2Dim>
1107 sum += iter->onTileCount();
1112 template<
typename ChildT, Index Log2Dim>
1119 sum += iter->memUsage();
1125 template<
typename ChildT, Index Log2Dim>
1129 if (bbox.isInside(this->getNodeBoundingBox()))
return;
1132 bbox.expand(i.getCoord(), ChildT::DIM);
1135 i->evalActiveBoundingBox(bbox, visitVoxels);
1143 template<
typename ChildT, Index Log2Dim>
1150 const Index i = iter.pos();
1152 child->prune(tolerance);
1153 if (child->isConstant(value, state, tolerance)) {
1166 template<
typename ChildT, Index Log2Dim>
1167 template<
typename NodeT>
1171 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1172 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1177 if (std::is_same<NodeT, ChildT>::value) {
1182 return (std::is_same<NodeT, ChildT>::value)
1183 ?
reinterpret_cast<NodeT*
>(child)
1184 : child->template stealNode<NodeT>(xyz, value, state);
1192 template<
typename ChildT, Index Log2Dim>
1193 template<
typename NodeT>
1197 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1198 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1203 return (std::is_same<NodeT, ChildT>::value)
1204 ?
reinterpret_cast<NodeT*
>(child)
1205 : child->template probeNode<NodeT>(xyz);
1210 template<
typename ChildT, Index Log2Dim>
1211 template<
typename NodeT,
typename AccessorT>
1215 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1216 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1221 acc.insert(xyz, child);
1222 return (std::is_same<NodeT, ChildT>::value)
1223 ?
reinterpret_cast<NodeT*
>(child)
1224 : child->template probeNodeAndCache<NodeT>(xyz, acc);
1229 template<
typename ChildT, Index Log2Dim>
1230 template<
typename NodeT>
1234 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1235 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1240 return (std::is_same<NodeT, ChildT>::value)
1241 ?
reinterpret_cast<const NodeT*
>(child)
1242 : child->template probeConstNode<NodeT>(xyz);
1247 template<
typename ChildT, Index Log2Dim>
1248 template<
typename NodeT,
typename AccessorT>
1252 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
1253 NodeT::LEVEL > ChildT::LEVEL)
return nullptr;
1258 acc.insert(xyz, child);
1259 return (std::is_same<NodeT, ChildT>::value)
1260 ?
reinterpret_cast<const NodeT*
>(child)
1261 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
1269 template<
typename ChildT, Index Log2Dim>
1270 inline typename ChildT::LeafNodeType*
1273 return this->
template probeNode<LeafNodeType>(xyz);
1277 template<
typename ChildT, Index Log2Dim>
1278 template<
typename AccessorT>
1279 inline typename ChildT::LeafNodeType*
1282 return this->
template probeNodeAndCache<LeafNodeType>(xyz, acc);
1286 template<
typename ChildT, Index Log2Dim>
1287 template<
typename AccessorT>
1288 inline const typename ChildT::LeafNodeType*
1295 template<
typename ChildT, Index Log2Dim>
1296 inline const typename ChildT::LeafNodeType*
1299 return this->
template probeConstNode<LeafNodeType>(xyz);
1303 template<
typename ChildT, Index Log2Dim>
1304 template<
typename AccessorT>
1305 inline const typename ChildT::LeafNodeType*
1308 return this->
template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
1315 template<
typename ChildT, Index Log2Dim>
1319 assert(leaf !=
nullptr);
1320 const Coord& xyz = leaf->origin();
1322 ChildT* child =
nullptr;
1324 if (ChildT::LEVEL>0) {
1327 child =
reinterpret_cast<ChildT*
>(leaf);
1331 if (ChildT::LEVEL>0) {
1335 child =
reinterpret_cast<ChildT*
>(leaf);
1339 child->addLeaf(leaf);
1343 template<
typename ChildT, Index Log2Dim>
1344 template<
typename AccessorT>
1348 assert(leaf !=
nullptr);
1349 const Coord& xyz = leaf->origin();
1351 ChildT* child =
nullptr;
1353 if (ChildT::LEVEL>0) {
1355 acc.insert(xyz, child);
1357 child =
reinterpret_cast<ChildT*
>(leaf);
1361 if (ChildT::LEVEL>0) {
1363 acc.insert(xyz, child);
1366 child =
reinterpret_cast<ChildT*
>(leaf);
1370 child->addLeafAndCache(leaf, acc);
1377 template<
typename ChildT, Index Log2Dim>
1382 const Coord& xyz = child->origin();
1384 if (Coord((xyz & ~(
DIM-1))) != this->
origin())
return false;
1393 template<
typename ChildT, Index Log2Dim>
1403 template<
typename ChildT, Index Log2Dim>
1408 if (
LEVEL >= level) {
1411 if (
LEVEL > level) {
1414 child->addTile(level, xyz, value, state);
1421 if (
LEVEL > level) {
1422 child->addTile(level, xyz, value, state);
1434 template<
typename ChildT, Index Log2Dim>
1435 template<
typename AccessorT>
1438 const ValueType& value,
bool state, AccessorT& acc)
1440 if (
LEVEL >= level) {
1443 if (
LEVEL > level) {
1446 acc.insert(xyz, child);
1447 child->addTileAndCache(level, xyz, value, state, acc);
1454 if (
LEVEL > level) {
1455 acc.insert(xyz, child);
1456 child->addTileAndCache(level, xyz, value, state, acc);
1471 template<
typename ChildT, Index Log2Dim>
1472 inline typename ChildT::LeafNodeType*
1476 ChildT* child =
nullptr;
1483 return child->touchLeaf(xyz);
1487 template<
typename ChildT, Index Log2Dim>
1488 template<
typename AccessorT>
1489 inline typename ChildT::LeafNodeType*
1496 acc.insert(xyz,
mNodes[n].getChild());
1504 template<
typename ChildT, Index Log2Dim>
1524 template<
typename ChildT, Index Log2Dim>
1537 if ((maxValue - v) > tolerance)
return false;
1539 }
else if (v > maxValue) {
1540 if ((v - minValue) > tolerance)
return false;
1551 template<
typename ChildT, Index Log2Dim>
1557 if (
LEVEL==1 || anyActiveTiles)
return anyActiveTiles;
1559 if (iter->hasActiveTiles())
return true;
1566 template<
typename ChildT, Index Log2Dim>
1575 template<
typename ChildT, Index Log2Dim>
1576 template<
typename AccessorT>
1582 acc.insert(xyz,
mNodes[n].getChild());
1587 template<
typename ChildT, Index Log2Dim>
1588 inline const typename ChildT::ValueType&
1596 template<
typename ChildT, Index Log2Dim>
1597 template<
typename AccessorT>
1598 inline const typename ChildT::ValueType&
1603 acc.insert(xyz,
mNodes[n].getChild());
1610 template<
typename ChildT, Index Log2Dim>
1618 template<
typename ChildT, Index Log2Dim>
1619 template<
typename AccessorT>
1625 acc.insert(xyz,
mNodes[n].getChild());
1632 template<
typename ChildT, Index Log2Dim>
1644 template<
typename ChildT, Index Log2Dim>
1645 template<
typename AccessorT>
1652 acc.insert(xyz,
mNodes[n].getChild());
1653 return mNodes[n].
getChild()->probeValueAndCache(xyz, value, acc);
1660 template<
typename ChildT, Index Log2Dim>
1676 template<
typename ChildT, Index Log2Dim>
1692 template<
typename ChildT, Index Log2Dim>
1711 template<
typename ChildT, Index Log2Dim>
1712 template<
typename AccessorT>
1731 acc.insert(xyz, child);
1732 child->setValueOffAndCache(xyz, value, acc);
1737 template<
typename ChildT, Index Log2Dim>
1756 template<
typename ChildT, Index Log2Dim>
1757 template<
typename AccessorT>
1775 acc.insert(xyz,
mNodes[n].getChild());
1781 template<
typename ChildT, Index Log2Dim>
1797 template<
typename ChildT, Index Log2Dim>
1798 template<
typename AccessorT>
1813 acc.insert(xyz,
mNodes[n].getChild());
1819 template<
typename ChildT, Index Log2Dim>
1837 template<
typename ChildT, Index Log2Dim>
1838 template<
typename AccessorT>
1855 acc.insert(xyz, child);
1856 child->setActiveStateAndCache(xyz, on, acc);
1861 template<
typename ChildT, Index Log2Dim>
1872 template<
typename ChildT, Index Log2Dim>
1873 template<
typename ModifyOp>
1883 bool createChild = !active;
1900 template<
typename ChildT, Index Log2Dim>
1901 template<
typename ModifyOp,
typename AccessorT>
1912 bool createChild = !active;
1928 acc.insert(xyz, child);
1929 child->modifyValueAndCache(xyz, op, acc);
1934 template<
typename ChildT, Index Log2Dim>
1935 template<
typename ModifyOp>
1944 bool modifiedState = !tileState;
1946 op(modifiedVal, modifiedState);
1954 if (hasChild)
mNodes[n].
getChild()->modifyValueAndActiveState(xyz, op);
1957 template<
typename ChildT, Index Log2Dim>
1958 template<
typename ModifyOp,
typename AccessorT>
1961 const Coord& xyz,
const ModifyOp& op, AccessorT& acc)
1968 bool modifiedState = !tileState;
1970 op(modifiedVal, modifiedState);
1980 acc.insert(xyz, child);
1981 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
1989 template<
typename ChildT, Index Log2Dim>
1994 if (!clipBBox.hasOverlap(nodeBBox)) {
1996 this->
fill(nodeBBox, background,
false);
1997 }
else if (clipBBox.isInside(nodeBBox)) {
2008 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1));
2009 if (!clipBBox.hasOverlap(tileBBox)) {
2014 }
else if (!clipBBox.isInside(tileBBox)) {
2022 tileBBox.intersect(clipBBox);
2027 this->
fill(tileBBox, val, on);
2039 template<
typename ChildT, Index Log2Dim>
2044 clippedBBox.intersect(bbox);
2045 if (!clippedBBox)
return;
2049 Coord xyz, tileMin, tileMax;
2050 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.x() + 1) {
2052 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.y() + 1) {
2054 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.z() + 1) {
2060 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2062 if (xyz != tileMin || Coord::lessThan(clippedBBox.max(), tileMax)) {
2066 ChildT* child =
nullptr;
2079 child->fill(CoordBBox(xyz, tmp), value, active);
2095 template<
typename ChildT, Index Log2Dim>
2100 clippedBBox.intersect(bbox);
2101 if (!clippedBBox)
return;
2105 Coord xyz, tileMin, tileMax;
2106 for (
int x = clippedBBox.min().x(); x <= clippedBBox.max().x(); x = tileMax.x() + 1) {
2108 for (
int y = clippedBBox.min().y(); y <= clippedBBox.max().y(); y = tileMax.y() + 1) {
2110 for (
int z = clippedBBox.min().z(); z <= clippedBBox.max().z(); z = tileMax.z() + 1) {
2117 ChildT* child =
nullptr;
2129 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2132 child->denseFill(CoordBBox{xyz, clippedBBox.max()}, value, active);
2142 template<
typename ChildT, Index Log2Dim>
2143 template<
typename DenseT>
2147 using DenseValueType =
typename DenseT::ValueType;
2149 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2150 const Coord&
min = dense.bbox().min();
2151 for (Coord xyz = bbox.min(),
max; xyz[0] <= bbox.max()[0]; xyz[0] =
max[0] + 1) {
2152 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] =
max[1] + 1) {
2153 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] =
max[2] + 1) {
2165 sub.translate(-min);
2166 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2167 for (
Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2168 DenseValueType* a1 = a0 + x*xStride;
2169 for (
Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2170 DenseValueType* a2 = a1 + y*yStride;
2171 for (
Int32 z = sub.min()[2], ez = sub.max()[2]+1;
2172 z < ez; ++z, a2 += zStride)
2174 *a2 = DenseValueType(value);
2188 template<
typename ChildT, Index Log2Dim>
2199 const ValueType zero = zeroVal<ValueType>();
2208 iter->writeTopology(os, toHalf);
2213 template<
typename ChildT, Index Log2Dim>
2229 child->readTopology(is);
2232 is.read(reinterpret_cast<char*>(&value),
sizeof(
ValueType));
2237 const bool oldVersion =
2243 std::unique_ptr<ValueType[]> valuePtr(
new ValueType[numValues]);
2253 assert(n == numValues);
2264 child->readTopology(is, fromHalf);
2273 template<
typename ChildT, Index Log2Dim>
2274 inline const typename ChildT::ValueType&
2281 template<
typename ChildT, Index Log2Dim>
2282 inline const typename ChildT::ValueType&
2293 template<
typename ChildT, Index Log2Dim>
2311 template<
typename ChildT, Index Log2Dim>
2316 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2323 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2324 if (mNode->mChildMask.isOn(i)) {
2325 mNode->mNodes[i].getChild()->voxelizeActiveTiles(
true);
2326 }
else if (mNode->mValueMask.isOn(i)) {
2327 const Coord &ijk = mNode->offsetToGlobalCoord(i);
2329 child->voxelizeActiveTiles(
true);
2330 mNode->mNodes[i].setChild(child);
2337 template<
typename ChildT, Index Log2Dim>
2349 iter->voxelizeActiveTiles(
false);
2357 template<
typename ChildT, Index Log2Dim>
2358 template<MergePolicy Policy>
2371 const Index n = iter.pos();
2375 background, otherBackground);
2383 child->resetBackground(otherBackground, background);
2390 const Index n = iter.pos();
2403 const Index n = iter.pos();
2406 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2414 child->resetBackground(otherBackground, background);
2425 const Index n = iter.pos();
2428 mNodes[n].
getChild()->template merge<Policy>(*iter, background, otherBackground);
2435 child->resetBackground(otherBackground, background);
2448 const Index n = iter.pos();
2451 mNodes[n].
getChild()->template merge<Policy>(iter.getValue(),
true);
2466 template<
typename ChildT, Index Log2Dim>
2467 template<MergePolicy Policy>
2476 if (!tileActive)
return;
2480 const Index n = iter.pos();
2486 iter.setValue(tileValue);
2497 template<
typename ChildT, Index Log2Dim>
2498 template<
typename OtherInternalNode>
2503 { tV = (tV | sV) & ~tC; }
2507 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2510 t->mChildMask |= s->mChildMask;
2512 t->mValueMask.foreach(s->mValueMask, t->mChildMask, op);
2513 assert((t->mValueMask & t->mChildMask).isOff());
2516 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2517 if (s->mChildMask.isOn(i)) {
2518 const typename OtherInternalNode::ChildNodeType& other = *(s->mNodes[i].getChild());
2519 if (t->mChildMask.isOn(i)) {
2520 t->mNodes[i].getChild()->topologyUnion(other);
2522 ChildT* child =
new ChildT(other, t->mNodes[i].getValue(),
TopologyCopy());
2524 t->mNodes[i].setChild(child);
2526 }
else if (s->mValueMask.isOn(i) && t->mChildMask.isOn(i)) {
2527 t->mNodes[i].getChild()->setValuesOn();
2531 const OtherInternalNode*
s;
2535 template<
typename ChildT, Index Log2Dim>
2536 template<
typename OtherChildT>
2543 template<
typename ChildT, Index Log2Dim>
2544 template<
typename OtherInternalNode>
2549 { tC = (tC & (sC | sV)) | (tV & sC); }
2552 const ValueType& background) : s(source), t(target), b(background) {
2554 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2558 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op);
2560 t->mValueMask &= s->mValueMask;
2561 assert((t->mValueMask & t->mChildMask).isOff());
2564 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2565 if (t->mChildMask.isOn(i)) {
2567 if (s->mChildMask.isOn(i)) {
2568 child->topologyIntersection(*(s->mNodes[i].getChild()), b);
2569 }
else if (s->mValueMask.isOff(i)) {
2571 t->mNodes[i].setValue(b);
2573 }
else if (t->mValueMask.isOn(i) && s->mChildMask.isOn(i)) {
2574 t->mNodes[i].setChild(
new ChildT(*(s->mNodes[i].getChild()),
2579 const OtherInternalNode*
s;
2584 template<
typename ChildT, Index Log2Dim>
2585 template<
typename OtherChildT>
2593 template<
typename ChildT, Index Log2Dim>
2594 template<
typename OtherInternalNode>
2599 { tC = (tC & (sC | ~sV)) | (tV & sC); }
2602 { tV &= ~((tC & sV) | (sC | sV)); }
2605 const ValueType& background) : s(source), t(target), b(background) {
2607 tbb::parallel_for(tbb::blocked_range<Index>(0,
NUM_VALUES), *
this);
2612 t->mChildMask.foreach(s->mChildMask, s->mValueMask, t->mValueMask, op1);
2615 t->mValueMask.foreach(t->mChildMask, s->mValueMask, oldChildMask, op2);
2616 assert((t->mValueMask & t->mChildMask).isOff());
2619 for (
Index i = r.begin(), end=r.end(); i!=end; ++i) {
2620 if (t->mChildMask.isOn(i)) {
2622 if (s->mChildMask.isOn(i)) {
2623 child->topologyDifference(*(s->mNodes[i].getChild()), b);
2624 }
else if (s->mValueMask.isOn(i)) {
2626 t->mNodes[i].setValue(b);
2628 }
else if (t->mValueMask.isOn(i)) {
2629 if (s->mChildMask.isOn(i)) {
2630 const typename OtherInternalNode::ChildNodeType& other =
2631 *(s->mNodes[i].getChild());
2632 ChildT* child =
new ChildT(other.origin(), t->mNodes[i].getValue(),
true);
2634 t->mNodes[i].setChild(child);
2639 const OtherInternalNode*
s;
2644 template<
typename ChildT, Index Log2Dim>
2645 template<
typename OtherChildT>
2657 template<
typename ChildT, Index Log2Dim>
2658 template<
typename CombineOp>
2662 const ValueType zero = zeroVal<ValueType>();
2707 if (child && otherChild) {
2708 child->combine(*otherChild, op);
2715 template<
typename ChildT, Index Log2Dim>
2716 template<
typename CombineOp>
2728 .setBIsActive(valueIsActive));
2735 if (child) child->combine(value, valueIsActive, op);
2744 template<
typename ChildT, Index Log2Dim>
2745 template<
typename CombineOp,
typename OtherNodeType>
2756 .setBRef(other1.mNodes[i].getValue())
2757 .setBIsActive(other1.isValueMaskOn(i)));
2766 : other1.mNodes[i].getChild()->origin();
2775 }
else if (other1.isChildMaskOff(i)) {
2779 other1.mNodes[i].getValue(), other1.isValueMaskOn(i), op);
2784 *other1.mNodes[i].getChild(), op);
2791 template<
typename ChildT, Index Log2Dim>
2792 template<
typename CombineOp,
typename OtherNodeType>
2795 bool valueIsActive, CombineOp& op)
2800 if (other.isChildMaskOff(i)) {
2802 .setAIsActive(valueIsActive)
2803 .setBRef(other.mNodes[i].getValue())
2804 .setBIsActive(other.isValueMaskOn(i)));
2809 typename OtherNodeType::ChildNodeType* otherChild = other.mNodes[i].getChild();
2818 mNodes[i].
getChild()->combine2(value, *otherChild, valueIsActive, op);
2824 template<
typename ChildT, Index Log2Dim>
2825 template<
typename CombineOp,
typename OtherValueType>
2828 bool valueIsActive, CombineOp& op)
2837 .setBIsActive(valueIsActive));
2851 mNodes[i].
getChild()->combine2(*otherChild, value, valueIsActive, op);
2860 template<
typename ChildT, Index Log2Dim>
2861 template<
typename BBoxOp>
2866 op.template operator()<
LEVEL>(CoordBBox::createCube(i.getCoord(), ChildNodeType::DIM));
2868 if (op.template descent<LEVEL>()) {
2872 op.template operator()<
LEVEL>(i->getNodeBoundingBox());
2878 template<
typename ChildT, Index Log2Dim>
2879 template<
typename VisitorOp>
2883 doVisit<InternalNode, VisitorOp, ChildAllIter>(*
this, op);
2887 template<
typename ChildT, Index Log2Dim>
2888 template<
typename VisitorOp>
2892 doVisit<const InternalNode, VisitorOp, ChildAllCIter>(*
this, op);
2896 template<
typename ChildT, Index Log2Dim>
2897 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
2901 typename NodeT::ValueType val;
2902 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
2903 if (op(iter))
continue;
2904 if (
typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
2914 template<
typename ChildT, Index Log2Dim>
2915 template<
typename OtherNodeType,
typename VisitorOp>
2920 typename OtherNodeType::ChildAllIter>(*
this, other, op);
2924 template<
typename ChildT, Index Log2Dim>
2925 template<
typename OtherNodeType,
typename VisitorOp>
2930 typename OtherNodeType::ChildAllCIter>(*
this, other, op);
2934 template<
typename ChildT, Index Log2Dim>
2937 typename OtherNodeT,
2939 typename ChildAllIterT,
2940 typename OtherChildAllIterT>
2945 static_assert(OtherNodeT::NUM_VALUES == NodeT::NUM_VALUES,
2946 "visit2() requires nodes to have the same dimensions");
2947 static_assert(OtherNodeT::LEVEL == NodeT::LEVEL,
2948 "visit2() requires nodes to be at the same tree level");
2950 typename NodeT::ValueType val;
2951 typename OtherNodeT::ValueType otherVal;
2953 ChildAllIterT iter =
self.beginChildAll();
2954 OtherChildAllIterT otherIter = other.beginChildAll();
2956 for ( ; iter && otherIter; ++iter, ++otherIter)
2958 const size_t skipBranch =
static_cast<size_t>(op(iter, otherIter));
2960 typename ChildAllIterT::ChildNodeType* child =
2961 (skipBranch & 1U) ?
nullptr : iter.probeChild(val);
2962 typename OtherChildAllIterT::ChildNodeType* otherChild =
2963 (skipBranch & 2U) ?
nullptr : otherIter.probeChild(otherVal);
2965 if (child !=
nullptr && otherChild !=
nullptr) {
2966 child->visit2Node(*otherChild, op);
2967 }
else if (child !=
nullptr) {
2968 child->visit2(otherIter, op);
2969 }
else if (otherChild !=
nullptr) {
2970 otherChild->visit2(iter, op,
true);
2979 template<
typename ChildT, Index Log2Dim>
2980 template<
typename OtherChildAllIterType,
typename VisitorOp>
2983 VisitorOp& op,
bool otherIsLHS)
2985 doVisit2<InternalNode, VisitorOp, ChildAllIter, OtherChildAllIterType>(
2986 *
this, otherIter, op, otherIsLHS);
2990 template<
typename ChildT, Index Log2Dim>
2991 template<
typename OtherChildAllIterType,
typename VisitorOp>
2994 VisitorOp& op,
bool otherIsLHS)
const 2996 doVisit2<const InternalNode, VisitorOp, ChildAllCIter, OtherChildAllIterType>(
2997 *
this, otherIter, op, otherIsLHS);
3001 template<
typename ChildT, Index Log2Dim>
3002 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT,
typename OtherChildAllIterT>
3005 VisitorOp& op,
bool otherIsLHS)
3007 if (!otherIter)
return;
3009 const size_t skipBitMask = (otherIsLHS ? 2U : 1U);
3011 typename NodeT::ValueType val;
3012 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
3013 const size_t skipBranch =
static_cast<size_t>(
3014 otherIsLHS ? op(otherIter, iter) : op(iter, otherIter));
3016 typename ChildAllIterT::ChildNodeType* child =
3017 (skipBranch & skipBitMask) ?
nullptr : iter.probeChild(val);
3019 if (child !=
nullptr) child->visit2(otherIter, op, otherIsLHS);
3027 template<
typename ChildT, Index Log2Dim>
3032 iter->writeBuffers(os, toHalf);
3037 template<
typename ChildT, Index Log2Dim>
3042 iter->readBuffers(is, fromHalf);
3047 template<
typename ChildT, Index Log2Dim>
3050 const CoordBBox& clipBBox,
bool fromHalf)
3057 iter->readBuffers(is, clipBBox, fromHalf);
3061 ValueType background = zeroVal<ValueType>();
3063 background = *
static_cast<const ValueType*
>(bgPtr);
3065 this->
clip(clipBBox, background);
3072 template<
typename ChildT, Index Log2Dim>
3076 dims.push_back(Log2Dim);
3077 ChildNodeType::getNodeLog2Dims(dims);
3081 template<
typename ChildT, Index Log2Dim>
3085 assert(n<(1<<3*Log2Dim));
3086 xyz.setX(n >> 2*Log2Dim);
3087 n &= ((1<<2*Log2Dim)-1);
3088 xyz.setY(n >> Log2Dim);
3089 xyz.setZ(n & ((1<<Log2Dim)-1));
3093 template<
typename ChildT, Index Log2Dim>
3097 return (((xyz[0] & (
DIM-1u)) >> ChildNodeType::TOTAL) << 2*Log2Dim)
3098 + (((xyz[1] & (
DIM-1u)) >> ChildNodeType::TOTAL) << Log2Dim)
3099 + ((xyz[2] & (
DIM-1u)) >> ChildNodeType::TOTAL);
3103 template<
typename ChildT, Index Log2Dim>
3109 local <<= ChildT::TOTAL;
3110 return local + this->
origin();
3117 template<
typename ChildT, Index Log2Dim>
3118 template<
typename ArrayT>
3122 using T =
typename ArrayT::value_type;
3123 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3124 using ArrayChildT =
typename std::conditional<
3125 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3128 if (std::is_same<T, ArrayChildT*>::value) {
3129 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3131 iter->getNodes(array);
3137 template<
typename ChildT, Index Log2Dim>
3138 template<
typename ArrayT>
3142 using T =
typename ArrayT::value_type;
3143 static_assert(std::is_pointer<T>::value,
"argument to getNodes() must be a pointer array");
3144 static_assert(std::is_const<
typename std::remove_pointer<T>::type>::value,
3145 "argument to getNodes() must be an array of const node pointers");
3148 if (std::is_same<T, const ChildT*>::value) {
3149 array.push_back(reinterpret_cast<T>(
mNodes[iter.pos()].
getChild()));
3151 iter->getNodes(array);
3161 template<
typename ChildT, Index Log2Dim>
3162 template<
typename ArrayT>
3166 using T =
typename ArrayT::value_type;
3167 static_assert(std::is_pointer<T>::value,
"argument to stealNodes() must be a pointer array");
3168 using ArrayChildT =
typename std::conditional<
3169 std::is_const<typename std::remove_pointer<T>::type>::value,
const ChildT, ChildT>::type;
3172 const Index n = iter.pos();
3173 if (std::is_same<T, ArrayChildT*>::value) {
3174 array.push_back(reinterpret_cast<T>(
mNodes[n].getChild()));
3178 iter->stealNodes(array, value, state);
3189 template<
typename ChildT, Index Log2Dim>
3197 mNodes[i].
getChild()->resetBackground(oldBackground, newBackground);
3208 template<
typename ChildT, Index Log2Dim>
3209 template<
typename OtherChildNodeType, Index OtherLog2Dim>
3217 if (!iter->hasSameTopology(other->
mNodes[iter.pos()].getChild()))
return false;
3223 template<
typename ChildT, Index Log2Dim>
3237 template<
typename ChildT, Index Log2Dim>
3249 template<
typename ChildT, Index Log2Dim>
3264 template<
typename ChildT, Index Log2Dim>
3271 template<
typename ChildT, Index Log2Dim>
3280 template<
typename ChildT, Index Log2Dim>
3281 inline const ChildT*
3292 #endif // OPENVDB_TREE_INTERNALNODE_HAS_BEEN_INCLUDED Definition: openvdb/Types.h:367
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: InternalNode.h:1821
int32_t Int32
Definition: openvdb/Types.h:34
Definition: InternalNode.h:119
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Definition: InternalNode.h:1578
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
typename NodeMaskType::Word W
Definition: InternalNode.h:2597
const ValueT & getItem(Index pos) const
Definition: InternalNode.h:155
Definition: InternalNode.h:127
Definition: InternalNode.h:2598
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Definition: InternalNode.h:1840
InternalNode * t
Definition: InternalNode.h:941
Definition: InternalNode.h:813
void setItem(Index pos, const ChildT &c) const
Definition: InternalNode.h:141
ValueOffCIter cbeginValueOff() const
Definition: InternalNode.h:232
const UnionType * getTable() const
Definition: InternalNode.h:774
Base class for dense iterators over internal and leaf nodes.
Definition: Iterator.h:178
DenseIter()
Definition: InternalNode.h:176
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2515
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
Definition: InternalNode.h:1506
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: InternalNode.h:1875
bool isValueMaskOn() const
Definition: InternalNode.h:759
void setItem(Index pos, ChildT *child) const
Definition: InternalNode.h:192
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of an Intern...
Definition: InternalNode.h:64
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Definition: InternalNode.h:328
Definition: NodeMasks.h:270
ChildOffCIter cbeginChildOff() const
Definition: InternalNode.h:221
static void offsetToLocalCoord(Index n, Coord &xyz)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
Definition: InternalNode.h:3083
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition: InternalNode.h:812
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
Definition: InternalNode.h:177
void nodeCount(std::vector< Index32 > &vec) const
Definition: InternalNode.h:1022
InternalNode * t
Definition: InternalNode.h:895
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Definition: InternalNode.h:1960
void topologyDifference(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Difference this node's set of active values with the active values of the other node, whose ValueType may be different. So a resulting voxel will be active only if the original voxel is active in this node and inactive in the other node.
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: InternalNode.h:1937
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
Definition: openvdb/Types.h:481
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:502
Level getLevel()
Return the current logging level.
Definition: logging.h:138
ValueConverter<T>::Type is the type of an InternalNode having the same child hierarchy and dimensions...
Definition: InternalNode.h:55
void readTopology(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:2215
Definition: version.h:178
void setValueOnlyAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1800
const ValueType & b
Definition: InternalNode.h:2641
Index getValueLevelAndCache(const Coord &xyz, AccessorT &) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1621
ValueAllCIter beginValueAll() const
Definition: InternalNode.h:237
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:465
VoxelizeActiveTiles(InternalNode &node)
Definition: InternalNode.h:2314
void getNodes(ArrayT &array)
Adds all nodes of a certain type to a container with the following API:
Definition: InternalNode.h:3120
Definition: InternalNode.h:120
NodeMaskType mValueMask
Definition: InternalNode.h:818
Definition: InternalNode.h:170
ChildIter()
Definition: InternalNode.h:130
Index64 onLeafVoxelCount() const
Definition: InternalNode.h:1080
static void doVisit(NodeT &, VisitorOp &)
Definition: InternalNode.h:2899
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Change inactive tiles or voxels with value oldBackground to newBackground or -oldBackground to -newBa...
Definition: InternalNode.h:3191
bool probeValue(const Coord &xyz, ValueType &value) const
Definition: InternalNode.h:1634
void topologyUnion(const InternalNode< OtherChildNodeType, Log2Dim > &other)
Union this branch's set of active values with the other branch's active values. The value type of the...
ChildAllCIter beginChildAll() const
Definition: InternalNode.h:225
bool isValueMaskOff(Index n) const
Definition: InternalNode.h:760
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
Definition: InternalNode.h:3095
void addLeaf(LeafNodeType *leaf)
Add the specified leaf to this node, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: InternalNode.h:1317
ValueOnCIter cbeginValueOn() const
Definition: InternalNode.h:230
Definition: InternalNode.h:810
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:966
ChildIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:131
ChildNodeType * getChildNode(Index n)
Returns a pointer to the child node at the linear offset n.
Definition: InternalNode.h:3273
void setValuesOn()
Mark all values (both tiles and voxels) as active.
Definition: InternalNode.h:1863
void voxelizeActiveTiles(bool threaded=true)
Densify active tiles, i.e., replace them with leaf-level active voxels.
Definition: InternalNode.h:2339
void writeBuffers(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:3029
bool resultIsActive() const
Definition: openvdb/Types.h:492
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2321
Index32 childCount() const
Definition: InternalNode.h:1048
void setItem(Index pos, const ValueT &v) const
Definition: InternalNode.h:158
void setValue(const ValueT &val)
Definition: NodeUnion.h:46
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:29
Definition: InternalNode.h:2601
ChildOnCIter beginChildOn() const
Definition: InternalNode.h:223
bool isChildMaskOff() const
Definition: InternalNode.h:764
void addLeafAndCache(LeafNodeType *leaf, AccessorT &)
Same as addLeaf() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1346
InternalNode * t
Definition: InternalNode.h:2532
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
Definition: InternalNode.h:820
ValueAllIter beginValueAll()
Definition: InternalNode.h:241
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Definition: InternalNode.h:3105
const NodeMaskType & getChildMask() const
Definition: InternalNode.h:766
Definition: InternalNode.h:814
static const Index NUM_VALUES
Definition: InternalNode.h:47
void merge(InternalNode &other, const ValueType &background, const ValueType &otherBackground)
Efficiently merge another tree into this tree using one of several schemes.
Definition: InternalNode.h:2360
DenseIter< const InternalNode, const ChildNodeType, ValueType, ChildAll > ChildAllCIter
Definition: InternalNode.h:211
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
Expand the specified bounding box so that it includes the active tiles of this internal node as well ...
Definition: InternalNode.h:1127
NodeMaskType getValueOffMask() const
Definition: InternalNode.h:767
const NodeType * probeConstNode(const Coord &xyz) const
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
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: InternalNode.h:1169
static void doVisit2Node(NodeT &, OtherNodeT &, VisitorOp &)
Definition: InternalNode.h:2942
static Index getChildDim()
Definition: InternalNode.h:256
ChildOnCIter cbeginChildOn() const
Definition: InternalNode.h:220
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2598
Index64 Word
Definition: NodeMasks.h:316
typename BaseT::NonConstValueType NonConstValueT
Definition: InternalNode.h:174
InternalNode * t
Definition: InternalNode.h:2640
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: InternalNode.h:1145
LeafNodeType * probeLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:1271
NodeType * probeNodeAndCache(const Coord &xyz, AccessorT &)
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
const OtherInternalNode * s
Definition: InternalNode.h:976
Index getValueLevel(const Coord &xyz) const
Return the level of the tree (0 = leaf) at which the value at the given coordinates resides...
Definition: InternalNode.h:1612
NodeUnion< ValueType, ChildNodeType > UnionType
Definition: InternalNode.h:40
ChildT * getChild() const
Definition: NodeUnion.h:41
void load(std::istream &is)
Definition: NodeMasks.h:569
Index64 onVoxelCount() const
Definition: InternalNode.h:1056
ChildNodeType * unsetChildNode(Index i, const ValueType &value)
Definition: InternalNode.h:3251
Definition: InternalNode.h:119
ValueOffCIter beginValueOff() const
Definition: InternalNode.h:236
Definition: InternalNode.h:809
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
typename ChildNodeType::BuildType BuildType
Definition: InternalNode.h:39
void addTileAndCache(Index level, const Coord &xyz, const ValueType &, bool state, AccessorT &)
Same as addTile() except, if necessary, update the accessor with pointers to the nodes along the path...
Definition: InternalNode.h:1437
uint64_t Index64
Definition: openvdb/Types.h:31
typename ChildNodeType::LeafNodeType LeafNodeType
Definition: InternalNode.h:37
Definition: openvdb/Types.h:368
UnionType mNodes[NUM_VALUES]
Definition: InternalNode.h:814
ValueOnIter beginValueOn()
Definition: InternalNode.h:238
ChildAllCIter cbeginChildAll() const
Definition: InternalNode.h:222
TopologyCopy2(const OtherInternalNode *source, InternalNode *target, const ValueType &offValue, const ValueType &onValue)
Definition: InternalNode.h:961
void visit2Node(OtherNodeType &other, VisitorOp &)
Definition: InternalNode.h:2917
static Index dim()
Definition: InternalNode.h:246
void setChild(ChildT *child)
Definition: NodeUnion.h:42
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2618
typename NodeMaskType::Word W
Definition: InternalNode.h:2547
Definition: version.h:187
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
Definition: InternalNode.h:1991
static const Index LEVEL
Definition: InternalNode.h:48
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:508
typename NodeMaskType::OnIterator MaskOnIterator
Definition: InternalNode.h:114
Base class for sparse iterators over internal and leaf nodes.
Definition: Iterator.h:114
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:117
const OtherInternalNode * s
Definition: InternalNode.h:2531
InternalNode * t
Definition: InternalNode.h:977
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:94
const ValueType & getLastValue() const
If the last entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getLastValue() on the child.
Definition: InternalNode.h:2283
Definition: InternalNode.h:120
bool isChildMaskOff(Index n) const
Definition: InternalNode.h:763
bool isValueMaskOn(Index n) const
Definition: InternalNode.h:758
typename NodeMaskType::Word W
Definition: InternalNode.h:2501
Definition: InternalNode.h:2548
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
Definition: InternalNode.h:1568
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: InternalNode.h:3164
Definition: InternalNode.h:119
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition: Iterator.h:184
void setValueAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1759
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:526
void topologyIntersection(const InternalNode< OtherChildNodeType, Log2Dim > &other, const ValueType &background)
Intersects this tree's set of active values with the active values of the other tree, whose ValueType may be different.
bool isValueMaskOff() const
Definition: InternalNode.h:761
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly creating a parent bran...
Definition: InternalNode.h:1405
const ValueType & b
Definition: InternalNode.h:942
void readBuffers(std::istream &, bool fromHalf=false)
Definition: InternalNode.h:3039
InternalNode()
Default constructor.
Definition: InternalNode.h:72
const NodeMaskType & getValueMask() const
Definition: InternalNode.h:765
bool hasSameTopology(const InternalNode< OtherChildNodeType, OtherLog2Dim > *other) const
Return true if the given tree branch has the same node and active value topology as this tree branch ...
Definition: InternalNode.h:3211
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:443
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
Definition: InternalNode.h:267
Index32 leafCount() const
Definition: InternalNode.h:1010
const ValueType & getFirstValue() const
If the first entry in this node's table is a tile, return the tile's value. Otherwise, return the result of calling getFirstValue() on the child.
Definition: InternalNode.h:2275
ChildAllIter beginChildAll()
Definition: InternalNode.h:228
static void getNodeLog2Dims(std::vector< Index > &dims)
Populated an stil::vector with the dimension of all the nodes in the branch starting with this node...
Definition: InternalNode.h:3074
Definition: InternalNode.h:29
const OtherInternalNode * s
Definition: InternalNode.h:2579
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:885
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Definition: InternalNode.h:1714
void writeTopology(std::ostream &, bool toHalf=false) const
Definition: InternalNode.h:2190
Definition: openvdb/Exceptions.h:13
Definition: openvdb/Types.h:369
~InternalNode()
Definition: InternalNode.h:997
bool hasActiveTiles() const
Return true if this node or any of its child nodes have any active tiles.
Definition: InternalNode.h:1553
Definition: NodeMasks.h:239
static const Index DIM
Definition: InternalNode.h:46
Definition: InternalNode.h:120
ChildOnIter beginChildOn()
Definition: InternalNode.h:226
void copyToDense(const CoordBBox &bbox, DenseT &dense) const
Copy into a dense grid the values of the voxels that lie within a given bounding box.
Definition: InternalNode.h:2145
const OtherInternalNode * s
Definition: InternalNode.h:894
Index64 offLeafVoxelCount() const
Definition: InternalNode.h:1092
bool isChildMaskOn(Index n) const
Definition: InternalNode.h:762
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:645
Definition: InternalNode.h:148
InternalNode * mNode
Definition: InternalNode.h:2334
ValueAllCIter cbeginValueAll() const
Definition: InternalNode.h:233
void modifyValueAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: InternalNode.h:1903
Definition: InternalNode.h:33
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:434
ValueOffIter beginValueOff()
Definition: InternalNode.h:240
bool probeValueAndCache(const Coord &xyz, ValueType &value, AccessorT &) const
Definition: InternalNode.h:1647
const ValueType & onV
Definition: InternalNode.h:978
ChildOffCIter beginChildOff() const
Definition: InternalNode.h:224
TopologyCopy1(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:925
Library and file format version numbers.
OPENVDB_API const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
const ValueType & getValue(const Coord &xyz) const
Definition: InternalNode.h:1589
Definition: InternalNode.h:2312
ValueOnCIter beginValueOn() const
Definition: InternalNode.h:234
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:503
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information for all active tiles and leaf nodes ...
Definition: InternalNode.h:2863
typename ChildNodeType::ValueType ValueType
Definition: InternalNode.h:38
uint32_t Index32
Definition: openvdb/Types.h:30
void modifyItem(Index pos, const ModifyOp &op) const
Definition: InternalNode.h:162
const ValueType & b
Definition: InternalNode.h:2581
TopologyUnion(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:2505
ValueIter()
Definition: InternalNode.h:151
NodeMaskType mChildMask
Definition: InternalNode.h:818
static Index getLevel()
Definition: InternalNode.h:249
Index64 onTileCount() const
Definition: InternalNode.h:1103
void combine2(const InternalNode &other0, const OtherNodeType &other1, CombineOp &)
Definition: InternalNode.h:2747
const AValueType & result() const
Get the output value.
Definition: openvdb/Types.h:473
bool isInactive() const
Return true if this node has no children and only contains inactive values.
Definition: InternalNode.h:323
Definition: InternalNode.h:2502
const OtherInternalNode * s
Definition: InternalNode.h:940
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
Definition: InternalNode.h:269
const ValueT & getValue() const
Definition: NodeUnion.h:44
LeafNodeType * touchLeaf(const Coord &xyz)
Return the leaf node that contains voxel (x, y, z). If no such node exists, create one...
Definition: InternalNode.h:1473
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: InternalNode.h:2097
TopologyDifference(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2604
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: InternalNode.h:1662
void combine(InternalNode &other, CombineOp &)
Definition: InternalNode.h:2660
void operator()(W &tV, const W &sV, const W &tC) const
Definition: InternalNode.h:2502
Index64 offVoxelCount() const
Definition: InternalNode.h:1068
typename NodeMaskType::OffIterator MaskOffIterator
Definition: InternalNode.h:115
LeafNodeType * probeLeafAndCache(const Coord &xyz, AccessorT &acc)
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ChildOffIter beginChildOff()
Definition: InternalNode.h:227
void save(std::ostream &os) const
Definition: NodeMasks.h:565
Index64 memUsage() const
Return the total amount of memory in bytes occupied by this node and its children.
Definition: InternalNode.h:1114
Index32 nonLeafCount() const
Definition: InternalNode.h:1035
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
Definition: openvdb/Types.h:519
void visit(VisitorOp &)
Definition: InternalNode.h:2881
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: InternalNode.h:2041
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:930
DeepCopy(const OtherInternalNode *source, InternalNode *target)
Definition: InternalNode.h:881
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:450
InternalNode * t
Definition: InternalNode.h:2580
void makeChildNodeEmpty(Index n, const ValueType &value)
Definition: InternalNode.h:3266
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: openvdb/Types.h:542
DenseIter< InternalNode, ChildNodeType, ValueType, ChildAll > ChildAllIter
Definition: InternalNode.h:210
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:441
void operator()(const tbb::blocked_range< Index > &r) const
Definition: InternalNode.h:2563
void setChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3239
TopologyIntersection(const OtherInternalNode *source, InternalNode *target, const ValueType &background)
Definition: InternalNode.h:2551
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:146
ValueIter(const MaskIterT &iter, NodeT *parent)
Definition: InternalNode.h:152
ChildT & getItem(Index pos) const
Definition: InternalNode.h:134
void unsetItem(Index pos, const ValueT &value) const
Definition: InternalNode.h:198
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: InternalNode.h:116
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: InternalNode.h:1678
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
Index32 Index
Definition: openvdb/Types.h:32
Tag dispatch class that distinguishes constructors during file input.
Definition: openvdb/Types.h:548
const OtherInternalNode * s
Definition: InternalNode.h:2639
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
Definition: openvdb/Types.h:428
bool addChild(ChildNodeType *child)
Add the given child node at this level deducing the offset from it's origin. If a child node with thi...
Definition: InternalNode.h:1379
NodeType * probeNode(const Coord &xyz)
Return a pointer to the node that contains voxel (x, y, z). If no such node exists, return nullptr.
static void doVisit2(NodeT &, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
Definition: InternalNode.h:3004
const LeafNodeType * probeConstLeafAndCache(const Coord &xyz, AccessorT &acc) const
Same as probeLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:462
bool getItem(Index pos, ChildT *&child, NonConstValueT &value) const
Definition: InternalNode.h:180
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:397
const LeafNodeType * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, return nullptr.
Definition: InternalNode.h:1297
bool isEmpty() const
Definition: InternalNode.h:295
Definition: NodeMasks.h:208
void resetChildNode(Index i, ChildNodeType *child)
Definition: InternalNode.h:3225
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by the node regardless of it...
Definition: InternalNode.h:292
void operator()(W &tC, const W &sC, const W &sV, const W &tV) const
Definition: InternalNode.h:2548
void operator()(W &tV, const W &sC, const W &sV, const W &tC) const
Definition: InternalNode.h:2601
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: InternalNode.h:1783
LeafNodeType * touchLeafAndCache(const Coord &xyz, AccessorT &)
Same as touchLeaf() except, if necessary, update the accessor with pointers to the nodes along the pa...
const NodeType * probeConstNodeAndCache(const Coord &xyz, AccessorT &) const
Same as probeNode() except, if necessary, update the accessor with pointers to the nodes along the pa...
void negate()
Change the sign of all the values represented in this node and its child nodes.
Definition: InternalNode.h:2295
Definition: InternalNode.h:811
_ChildNodeType ChildNodeType
Definition: InternalNode.h:36