4 #ifndef OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
5 #define OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
16 #include <type_traits>
27 template<Index Log2Dim>
49 template<
typename ValueType>
54 template<
typename OtherNodeType>
55 struct SameConfiguration {
67 explicit LeafNode(
const Coord& xyz,
bool value =
false,
bool active =
false);
79 template<
typename OtherValueType>
83 template<
typename ValueType>
89 template<
typename ValueType>
91 template<
typename ValueType>
154 const Coord&
origin()
const {
return mOrigin; }
167 #if OPENVDB_ABI_VERSION_NUMBER >= 9
169 Index32 transientData()
const {
return mTransientData; }
171 void setTransientData(
Index32 transientData) { mTransientData = transientData; }
179 template<
typename OtherType, Index OtherLog2Dim>
180 bool hasSameTopology(
const LeafNode<OtherType, OtherLog2Dim>* other)
const;
199 void readTopology(std::istream&,
bool fromHalf =
false);
201 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
204 void readBuffers(std::istream&,
bool fromHalf =
false);
205 void readBuffers(std::istream& is,
const CoordBBox&,
bool fromHalf =
false);
207 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
213 const bool&
getValue(
const Coord& xyz)
const;
259 template<
typename ModifyOp>
263 template<
typename ModifyOp>
264 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
267 template<
typename ModifyOp>
284 void clip(
const CoordBBox&,
bool background);
287 void fill(
const CoordBBox& bbox,
bool value,
bool active =
true);
289 void denseFill(
const CoordBBox& bbox,
bool val,
bool on =
true) { this->
fill(bbox, val, on); }
294 void fill(
const bool&
value,
bool active);
307 template<
typename DenseT>
308 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
326 template<
typename DenseT>
327 void copyFromDense(
const CoordBBox& bbox,
const DenseT& dense,
bool background,
bool tolerance);
331 template<
typename AccessorT>
336 template<
typename AccessorT>
341 template<
typename AccessorT>
347 template<
typename AccessorT>
352 template<
typename AccessorT>
361 template<
typename ModifyOp,
typename AccessorT>
369 template<
typename ModifyOp,
typename AccessorT>
378 template<
typename AccessorT>
387 template<
typename AccessorT>
395 template<
typename AccessorT>
401 const bool&
getFirstValue()
const {
if (mValueMask.
isOn(0))
return Buffer::sOn;
else return Buffer::sOff; }
405 const bool&
getLastValue()
const {
if (mValueMask.
isOn(
SIZE-1))
return Buffer::sOn;
else return Buffer::sOff; }
410 bool isConstant(
bool& constValue,
bool& state,
bool tolerance = 0)
const;
442 template<MergePolicy Policy>
443 void merge(
const LeafNode& other,
bool bg =
false,
bool otherBG =
false);
444 template<MergePolicy Policy>
void merge(
bool tileValue,
bool tileActive);
456 template<
typename OtherType>
470 template<
typename OtherType>
484 template<
typename OtherType>
487 template<
typename CombineOp>
489 template<
typename CombineOp>
490 void combine(
bool,
bool valueIsActive, CombineOp& op);
492 template<
typename CombineOp,
typename OtherType >
493 void combine2(
const LeafNode& other,
const OtherType&,
bool valueIsActive, CombineOp&);
494 template<
typename CombineOp,
typename OtherNodeT >
495 void combine2(
bool,
const OtherNodeT& other,
bool valueIsActive, CombineOp&);
496 template<
typename CombineOp,
typename OtherNodeT >
505 template<
typename VisitorOp>
void visit(VisitorOp&);
506 template<
typename VisitorOp>
void visit(VisitorOp&)
const;
508 template<
typename OtherLeafNodeType,
typename VisitorOp>
509 void visit2Node(OtherLeafNodeType& other, VisitorOp&);
510 template<
typename OtherLeafNodeType,
typename VisitorOp>
511 void visit2Node(OtherLeafNodeType& other, VisitorOp&)
const;
512 template<
typename IterT,
typename VisitorOp>
513 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false);
514 template<
typename IterT,
typename VisitorOp>
515 void visit2(IterT& otherIter, VisitorOp&,
bool otherIsLHS =
false)
const;
521 template<
typename AccessorT>
523 template<
typename NodeT>
525 template<
typename NodeT>
527 template<
typename NodeT>
529 template<
typename ArrayT>
void getNodes(ArrayT&)
const {}
535 template<
typename AccessorT>
541 template<
typename AccessorT>
544 template<
typename AccessorT>
546 template<
typename NodeT,
typename AccessorT>
551 return reinterpret_cast<NodeT*
>(
this);
558 template<
typename AccessorT>
561 template<
typename AccessorT>
563 template<
typename NodeT,
typename AccessorT>
568 return reinterpret_cast<const NodeT*
>(
this);
581 template<
typename MaskIterT,
typename NodeT,
typename ValueT>
585 public SparseIteratorBase<MaskIterT, ValueIter<MaskIterT, NodeT, ValueT>, NodeT, ValueT>
601 template<
typename ModifyOp>
604 template<
typename ModifyOp>
609 template<
typename MaskIterT,
typename NodeT>
615 MaskIterT,
ChildIter<MaskIterT, NodeT>, NodeT, bool>(iter, parent) {}
618 template<
typename NodeT,
typename ValueT>
620 MaskDenseIter, DenseIter<NodeT, ValueT>, NodeT, void, ValueT>
630 value = this->
parent().getValue(pos);
644 using ValueOnCIter = ValueIter<MaskOnIter, const LeafNode, const bool>;
720 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
721 static inline void doVisit(NodeT&, VisitorOp&);
723 template<
typename NodeT,
typename OtherNodeT,
typename VisitorOp,
724 typename ChildAllIterT,
typename OtherChildAllIterT>
725 static inline void doVisit2Node(NodeT&
self, OtherNodeT& other, VisitorOp&);
727 template<
typename NodeT,
typename VisitorOp,
728 typename ChildAllIterT,
typename OtherChildAllIterT>
729 static inline void doVisit2(NodeT&
self, OtherChildAllIterT&, VisitorOp&,
bool otherIsLHS);
738 #if OPENVDB_ABI_VERSION_NUMBER >= 9
769 template<Index Log2Dim>
777 template<Index Log2Dim>
782 , mOrigin(xyz & (~(DIM - 1)))
787 template<Index Log2Dim>
792 , mOrigin(xyz & (~(DIM - 1)))
800 template<Index Log2Dim>
803 : mValueMask(other.valueMask())
804 , mBuffer(other.mBuffer)
805 , mOrigin(other.mOrigin)
807 , mTransientData(other.mTransientData)
814 template<Index Log2Dim>
815 template<
typename ValueT>
818 : mValueMask(other.valueMask())
819 , mOrigin(other.origin())
821 , mTransientData(other.mTransientData)
826 static inline bool convertValue(
const ValueT&
val) {
return bool(val); }
830 mBuffer.
setValue(i, Local::convertValue(other.mBuffer[i]));
835 template<Index Log2Dim>
836 template<
typename ValueT>
840 : mValueMask(other.valueMask())
841 , mBuffer(background)
842 , mOrigin(other.origin())
844 , mTransientData(other.mTransientData)
850 template<Index Log2Dim>
851 template<
typename ValueT>
854 : mValueMask(other.valueMask())
855 , mBuffer(other.valueMask())
856 , mOrigin(other.origin())
858 , mTransientData(other.mTransientData)
864 template<Index Log2Dim>
865 template<
typename ValueT>
869 : mValueMask(other.valueMask())
870 , mBuffer(other.valueMask())
871 , mOrigin(other.origin())
873 , mTransientData(other.mTransientData)
876 if (offValue) {
if (!onValue) mBuffer.
mData.toggle();
else mBuffer.
mData.setOn(); }
880 template<Index Log2Dim>
890 template<Index Log2Dim>
895 return sizeof(*this);
899 template<Index Log2Dim>
904 if (bbox.isInside(this_bbox))
return;
908 for(; iter; ++iter) this_bbox.expand(
this->offsetToLocalCoord(iter.pos()));
909 this_bbox.translate(this->
origin());
911 bbox.expand(this_bbox);
916 template<Index Log2Dim>
917 template<
typename OtherType, Index OtherLog2Dim>
922 return (Log2Dim == OtherLog2Dim && mValueMask == other->
getValueMask());
926 template<Index Log2Dim>
930 std::ostringstream ostr;
931 ostr <<
"LeafNode @" << mOrigin <<
": ";
940 template<Index Log2Dim>
944 assert ((xyz[0] & (
DIM-1u)) <
DIM && (xyz[1] & (
DIM-1u)) <
DIM && (xyz[2] & (
DIM-1u)) <
DIM);
945 return ((xyz[0] & (
DIM-1u)) << 2*Log2Dim)
946 + ((xyz[1] & (
DIM-1u)) << Log2Dim)
947 + (xyz[2] & (
DIM-1u));
951 template<Index Log2Dim>
955 assert(n < (1 << 3*Log2Dim));
957 xyz.setX(n >> 2*Log2Dim);
958 n &= ((1 << 2*Log2Dim) - 1);
959 xyz.setY(n >> Log2Dim);
960 xyz.setZ(n & ((1 << Log2Dim) - 1));
965 template<Index Log2Dim>
976 template<Index Log2Dim>
984 template<Index Log2Dim>
992 template<Index Log2Dim>
1002 bool background =
false;
1004 background = *
static_cast<const bool*
>(bgPtr);
1006 this->
clip(clipBBox, background);
1010 template<Index Log2Dim>
1015 mValueMask.
load(is);
1017 is.read(reinterpret_cast<char*>(&mOrigin),
sizeof(Coord::ValueType) * 3);
1021 mBuffer.
mData.load(is);
1026 int8_t numBuffers = 0;
1027 is.read(reinterpret_cast<char*>(&numBuffers),
sizeof(int8_t));
1031 std::unique_ptr<bool[]>
buf{
new bool[
SIZE]};
1032 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1035 mBuffer.
mData.setOff();
1037 if (
buf[i]) mBuffer.
mData.setOn(i);
1040 if (numBuffers > 1) {
1043 for (
int i = 1; i < numBuffers; ++i) {
1044 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1051 template<Index Log2Dim>
1056 mValueMask.
save(os);
1058 os.write(reinterpret_cast<const char*>(&mOrigin),
sizeof(Coord::ValueType) * 3);
1060 mBuffer.
mData.save(os);
1067 template<Index Log2Dim>
1071 return mOrigin == other.mOrigin &&
1073 mBuffer == other.mBuffer;
1077 template<Index Log2Dim>
1088 template<Index Log2Dim>
1092 if (!mValueMask.
isConstant(state))
return false;
1095 if (!tolerance && !(mBuffer.
mData.isOn() || mBuffer.
mData.isOff()))
return false;
1097 constValue = mBuffer.
mData.isOn();
1103 template<Index Log2Dim>
1107 const Index countTrue = mBuffer.
mData.countOn();
1111 template<Index Log2Dim>
1121 template<Index Log2Dim>
1134 template<Index Log2Dim>
1141 template<Index Log2Dim>
1145 assert(offset <
SIZE);
1150 template<Index Log2Dim>
1151 template<
typename AccessorT>
1154 bool val,
bool active, AccessorT&)
1156 this->
addTile(level, xyz, val, active);
1163 template<Index Log2Dim>
1168 if (mBuffer.
mData.isOn(
this->coordToOffset(xyz)))
return Buffer::sOn;
else return Buffer::sOff;
1172 template<Index Log2Dim>
1176 assert(offset <
SIZE);
1178 if (mBuffer.
mData.isOn(offset))
return Buffer::sOn;
else return Buffer::sOff;
1182 template<Index Log2Dim>
1187 val = mBuffer.
mData.isOn(offset);
1188 return mValueMask.
isOn(offset);
1192 template<Index Log2Dim>
1200 template<Index Log2Dim>
1204 assert(offset <
SIZE);
1205 mValueMask.
setOn(offset);
1206 mBuffer.
mData.set(offset, val);
1210 template<Index Log2Dim>
1218 template<Index Log2Dim>
1226 template<Index Log2Dim>
1234 template<Index Log2Dim>
1238 assert(offset <
SIZE);
1239 mValueMask.
setOff(offset);
1240 mBuffer.
mData.set(offset, val);
1244 template<Index Log2Dim>
1245 template<
typename ModifyOp>
1249 bool val = mBuffer.
mData.isOn(offset);
1251 mBuffer.
mData.set(offset, val);
1252 mValueMask.
setOn(offset);
1256 template<Index Log2Dim>
1257 template<
typename ModifyOp>
1265 template<Index Log2Dim>
1266 template<
typename ModifyOp>
1271 bool val = mBuffer.
mData.isOn(offset), state = mValueMask.
isOn(offset);
1273 mBuffer.
mData.set(offset, val);
1274 mValueMask.
set(offset, state);
1281 template<Index Log2Dim>
1285 if (newBackground != oldBackground) {
1289 mBuffer.
mData = (mBuffer.
mData & mValueMask) | bgMask;
1297 template<Index Log2Dim>
1298 template<MergePolicy Policy>
1305 const Index n = iter.pos();
1306 if (mValueMask.
isOff(n)) {
1307 mBuffer.
mData.set(n, other.mBuffer.
mData.isOn(n));
1308 mValueMask.
setOn(n);
1314 template<Index Log2Dim>
1315 template<MergePolicy Policy>
1321 if (!tileActive)
return;
1323 if (tileValue) mBuffer.
mData |= !mValueMask;
1324 else mBuffer.
mData &= mValueMask;
1333 template<Index Log2Dim>
1334 template<
typename OtherType>
1342 template<Index Log2Dim>
1343 template<
typename OtherType>
1352 template<Index Log2Dim>
1353 template<
typename OtherType>
1365 template<Index Log2Dim>
1370 if (!clipBBox.hasOverlap(nodeBBox)) {
1372 this->
fill(nodeBBox, background,
false);
1373 }
else if (clipBBox.isInside(nodeBBox)) {
1383 nodeBBox.intersect(clipBBox);
1385 int &
x = xyz.x(), &
y = xyz.y(), &
z = xyz.z();
1386 for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++
x) {
1387 for (
y = nodeBBox.min().y();
y <= nodeBBox.max().y(); ++
y) {
1388 for (
z = nodeBBox.min().z();
z <= nodeBBox.max().z(); ++
z) {
1405 template<Index Log2Dim>
1410 clippedBBox.intersect(bbox);
1411 if (!clippedBBox)
return;
1413 for (
Int32 x = clippedBBox.min().x();
x <= clippedBBox.max().x(); ++
x) {
1414 const Index offsetX = (
x & (
DIM-1u))<<2*Log2Dim;
1415 for (
Int32 y = clippedBBox.min().y();
y <= clippedBBox.max().y(); ++
y) {
1416 const Index offsetXY = offsetX + ((
y & (
DIM-1u))<< Log2Dim);
1417 for (
Int32 z = clippedBBox.min().z();
z <= clippedBBox.max().z(); ++
z) {
1419 mValueMask.
set(offset, active);
1420 mBuffer.
mData.set(offset, value);
1426 template<Index Log2Dim>
1430 mBuffer.
fill(value);
1433 template<Index Log2Dim>
1437 mBuffer.
fill(value);
1438 mValueMask.
set(active);
1445 template<Index Log2Dim>
1446 template<
typename DenseT>
1450 using DenseValueType =
typename DenseT::ValueType;
1452 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1453 const Coord&
min = dense.bbox().min();
1454 DenseValueType*
t0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1455 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1456 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1457 DenseValueType*
t1 = t0 + xStride * (
x - min[0]);
1459 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1460 DenseValueType* t2 = t1 + yStride * (
y - min[1]);
1462 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1;
z < ez; ++
z, t2 += zStride) {
1463 *t2 = DenseValueType(mBuffer.
mData.isOn(n2++));
1470 template<Index Log2Dim>
1471 template<
typename DenseT>
1474 bool background,
bool tolerance)
1476 using DenseValueType =
typename DenseT::ValueType;
1478 inline static bool toBool(
const DenseValueType&
v) {
return !
math::isZero(v); }
1481 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1482 const Coord&
min = dense.bbox().min();
1483 const DenseValueType*
s0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1484 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1485 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1486 const DenseValueType*
s1 = s0 + xStride * (
x - min[0]);
1488 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1489 const DenseValueType* s2 = s1 + yStride * (
y - min[1]);
1491 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2]+1;
z < ez; ++
z, ++n2, s2 += zStride) {
1493 if (tolerance || (background == Local::toBool(*s2))) {
1495 mBuffer.
mData.set(n2, background);
1497 mValueMask.
setOn(n2);
1498 mBuffer.
mData.set(n2, Local::toBool(*s2));
1509 template<Index Log2Dim>
1510 template<
typename CombineOp>
1516 bool result =
false, aVal = mBuffer.
mData.isOn(i), bVal = other.mBuffer.
mData.isOn(i);
1518 .setAIsActive(mValueMask.
isOn(i))
1521 .setResultRef(result));
1523 mBuffer.
mData.set(i, result);
1528 template<Index Log2Dim>
1529 template<
typename CombineOp>
1534 args.
setBRef(value).setBIsActive(valueIsActive);
1536 bool result =
false, aVal = mBuffer.
mData.isOn(i);
1538 .setAIsActive(mValueMask.
isOn(i))
1539 .setResultRef(result));
1541 mBuffer.
mData.set(i, result);
1549 template<Index Log2Dim>
1550 template<
typename CombineOp,
typename OtherType>
1553 bool valueIsActive, CombineOp& op)
1556 args.
setBRef(value).setBIsActive(valueIsActive);
1558 bool result =
false, aVal = other.mBuffer.
mData.isOn(i);
1561 .setResultRef(result));
1563 mBuffer.
mData.set(i, result);
1568 template<Index Log2Dim>
1569 template<
typename CombineOp,
typename OtherNodeT>
1572 bool valueIsActive, CombineOp& op)
1575 args.
setARef(value).setAIsActive(valueIsActive);
1577 bool result =
false, bVal = other.mBuffer.mData.isOn(i);
1579 .setBIsActive(other.valueMask().isOn(i))
1580 .setResultRef(result));
1582 mBuffer.
mData.set(i, result);
1587 template<Index Log2Dim>
1588 template<
typename CombineOp,
typename OtherNodeT>
1597 bool result =
false, b0Val = b0.mBuffer.
mData.isOn(i), b1Val = b1.mBuffer.mData.isOn(i);
1601 .setBIsActive(b1.valueMask().isOn(i))
1602 .setResultRef(result));
1604 mBuffer.
mData.set(i, result);
1611 template<Index Log2Dim>
1612 template<
typename BBoxOp>
1616 if (op.template descent<LEVEL>()) {
1618 op.template operator()<
LEVEL>(CoordBBox::createCube(i.getCoord(), 1));
1626 template<Index Log2Dim>
1627 template<
typename VisitorOp>
1631 doVisit<LeafNode, VisitorOp, ChildAllIter>(*
this, op);
1635 template<Index Log2Dim>
1636 template<
typename VisitorOp>
1640 doVisit<const LeafNode, VisitorOp, ChildAllCIter>(*
this, op);
1644 template<Index Log2Dim>
1645 template<
typename NodeT,
typename VisitorOp,
typename ChildAllIterT>
1649 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
1658 template<Index Log2Dim>
1659 template<
typename OtherLeafNodeType,
typename VisitorOp>
1664 typename OtherLeafNodeType::ChildAllIter>(*
this, other, op);
1668 template<Index Log2Dim>
1669 template<
typename OtherLeafNodeType,
typename VisitorOp>
1674 typename OtherLeafNodeType::ChildAllCIter>(*
this, other, op);
1678 template<Index Log2Dim>
1681 typename OtherNodeT,
1683 typename ChildAllIterT,
1684 typename OtherChildAllIterT>
1690 "can't visit nodes of different sizes simultaneously");
1691 static_assert(OtherNodeT::LEVEL == NodeT::LEVEL,
1692 "can't visit nodes at different tree levels simultaneously");
1694 ChildAllIterT iter =
self.beginChildAll();
1695 OtherChildAllIterT otherIter = other.beginChildAll();
1697 for ( ; iter && otherIter; ++iter, ++otherIter) {
1698 op(iter, otherIter);
1706 template<Index Log2Dim>
1707 template<
typename IterT,
typename VisitorOp>
1711 doVisit2<LeafNode, VisitorOp, ChildAllIter, IterT>(*
this, otherIter, op, otherIsLHS);
1715 template<Index Log2Dim>
1716 template<
typename IterT,
typename VisitorOp>
1720 doVisit2<const LeafNode, VisitorOp, ChildAllCIter, IterT>(*
this, otherIter, op, otherIsLHS);
1724 template<Index Log2Dim>
1728 typename ChildAllIterT,
1729 typename OtherChildAllIterT>
1732 VisitorOp& op,
bool otherIsLHS)
1734 if (!otherIter)
return;
1737 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
1738 op(otherIter, iter);
1741 for (ChildAllIterT iter =
self.
beginChildAll(); iter; ++iter) {
1742 op(iter, otherIter);
1751 #endif // OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
void getNodes(ArrayT &) const
This function exists only to enable template instantiation.
void setValueOffAndCache(const Coord &xyz, bool value, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as inactive.
void setValueMask(Index n, bool on)
void setValuesOff()
Mark all voxels as inactive but don't change their values.
void merge(const LeafNode &)
void setItem(Index pos, bool value) const
static void getNodeLog2Dims(std::vector< Index > &dims)
void topologyUnion(const LeafNode< OtherType, Log2Dim > &other, const bool preserveTiles=false)
Union this node's set of active values with the active values of the other node, whose ValueType may ...
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
static const Index NUM_VOXELS
This struct collects both input and output arguments to "grid combiner" functors used with the tree::...
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...
void setValuesOn()
Mark all voxels as active but don't change their values.
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
typename NodeMaskType::OffIterator MaskOffIter
ValueOnIter beginValueOn()
const NodeMaskType & valueMask() const
void setValueOff(Index offset)
Mark the voxel at the given offset as inactive but don't change its value.
Index32 countOn() const
Return the total number of on bits.
const bool & getValueAndCache(const Coord &xyz, AccessorT &) const
Return the value of the voxel at the given coordinates.
ChildAllIter beginChildAll()
void readBuffers(std::istream &is, bool fromHalf=false)
Read buffers from a stream.
ChildOnCIter cbeginChildOn() const
ChildOffCIter cendChildOff() const
ChildIter< MaskOffIterator, LeafNode, ChildOff > ChildOffIter
ValueIter< MaskOnIter, const LeafNode, const bool > ValueOnCIter
void setValueOnly(const Coord &xyz, const ValueType &val)
Set the value of the voxel at the given coordinates but don't change its active state.
void readTopology(std::istream &is, bool fromHalf=false)
Read in just the topology.
void setValueMask(const NodeMaskType &mask)
void setValueAndCache(const Coord &xyz, bool val, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as active.
LeafNode specialization for values of type bool that stores both the active states and the values of ...
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
void getOrigin(Int32 &x, Int32 &y, Int32 &z) const
Return the grid index coordinates of this node's local origin.
ChildOnIter beginChildOn()
Index64 offVoxelCount() const
Return the number of inactive voxels.
NodeMaskType & getValueMask()
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
const LeafNode * probeConstLeaf(const Coord &) const
Return a pointer to this node.
LeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
static const Index NUM_VALUES
static void doVisit(NodeT &, VisitorOp &)
static Index log2dim()
Return log2 of the size of the buffer storage.
void setOff(Index32 n)
Set the nth bit off.
Index pos() const
Identical to offset.
void swap(Buffer &other)
Exchange this node's data buffer with the given data buffer without changing the active states of the...
const LeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
const bool & getLastValue() const
Return a const reference to the last entry in the buffer.
LeafNode * touchLeaf(const Coord &)
Return a pointer to this node.
ValueOnCIter cbeginValueOn() const
void setValueMaskOn(Index n)
void addLeaf(LeafNode *)
This function exists only to enable template instantiation.
DenseIterator endDense() const
Index64 memUsage() const
Return the memory in bytes occupied by this node.
const NodeMaskType & getValueMask() const
#define OPENVDB_USE_VERSION_NAMESPACE
bool isValueMaskOn(Index n) const
Coord mOrigin
Global grid index coordinates (x,y,z) of the local origin of this node.
ValueOffCIter beginValueOff() const
NodeT * stealNode(const Coord &, const ValueType &, bool)
This function exists only to enable template instantiation.
Base class for iterators over internal and leaf nodes.
ChildIter< MaskOnIterator, const LeafNode, ChildOn > ChildOnCIter
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
ChildIter< MaskOnIter, const LeafNode > ChildOnCIter
**But if you need a or simply need to know when the task has note that the like this
ChildOffCIter cbeginChildOff() const
const bool & getValue() const
ValueT & getItem(Index pos) const
ChildIter< MaskOnIterator, LeafNode, ChildOn > ChildOnIter
DenseIterator beginDense() const
DenseIter< const LeafNode, const bool > ChildAllCIter
ChildAllCIter cbeginChildAll() const
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
bool isValueMaskOff(Index n) const
bool allocate()
Allocate memory for this node's buffer if it has not already been allocated.
ValueAllIter endValueAll()
NodeT & parent() const
Return a reference to the node over which this iterator is iterating.
bool isValueMaskOn() const
const NodeT * probeConstNode(const Coord &) const
This function exists only to enable template instantiation.
void topologyIntersection(const LeafNode< OtherType, Log2Dim > &other, const ValueType &)
Intersect 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 both of the original voxels were active.
const LeafNode * probeLeaf(const Coord &) const
Return a pointer to this node.
Index64 onLeafVoxelCount() const
bool isValueMaskOff() const
Tag dispatch class that distinguishes constructors during file input.
#define OPENVDB_ABI_VERSION_NUMBER
The ABI version that OpenVDB was built with.
ValueOnCIter cbeginValueOn() const
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
const NodeMaskType & valueMask() const
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates but don't change its value.
ValueIter< MaskDenseIter, LeafNode, const bool > ValueAllIter
ValueIter< MaskOffIterator, const LeafNode, const ValueType, ValueOff > ValueOffCIter
static Index getValueLevelAndCache(const Coord &, AccessorT &)
Return the LEVEL (=0) at which leaf node values reside.
static Coord offsetToLocalCoord(Index n)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
ValueOffCIter cendValueOff() const
Index32 countOff() const
Return the total number of on bits.
void writeBuffers(std::ostream &os, bool toHalf=false) const
Write buffers to a stream.
ValueIter< MaskDenseIterator, LeafNode, const ValueType, ValueAll > ValueAllIter
ChildAllCIter cendChildAll() const
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
std::shared_ptr< T > SharedPtr
ChildOffCIter beginChildOff() const
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
ValueAllCIter beginValueAll() const
void stealNodes(ArrayT &, const ValueType &, bool)
This function exists only to enable template instantiation.
void modifyValue(Index offset, const ModifyOp &op)
Apply a functor to the value of the voxel at the given offset and mark the voxel as active...
const LeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
void modifyItem(Index n, const ModifyOp &op) const
const bool & getItem(Index pos) const
static Index32 leafCount()
OffMaskIterator< NodeMask > OffIterator
ChildAllCIter beginChildAll() const
Buffer mBuffer
Bitmask representing the values of voxels.
void save(std::ostream &os) const
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
ValueIter< MaskOnIter, LeafNode, const bool > ValueOnIter
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
ValueOnCIter beginValueOn() const
ValueOnCIter cendValueOn() const
bool isOn(Index32 n) const
Return true if the nth bit is on.
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
void swap(LeafBuffer &)
Exchange this buffer's values with the other buffer's values.
void addTile(Index level, const Coord &, const ValueType &, bool)
void denseFill(const CoordBBox &bbox, bool val, bool on=true)
Set all voxels within an axis-aligned box to the specified value and active state.
Index64 onVoxelCount() const
Return the number of voxels marked On.
bool resultIsActive() const
ChildAllIter endChildAll()
static bool hasActiveTiles()
Return false since leaf nodes never contain tiles.
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim...
void modifyValue(const ModifyOp &op) const
void topologyDifference(const LeafNode< OtherType, Log2Dim > &other, const ValueType &)
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 LeafNode and inactive in the other LeafNode.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
ValueOnCIter endValueOn() const
ValueIter< MaskOnIterator, LeafNode, const ValueType, ValueOn > ValueOnIter
GLsizei const GLchar *const * string
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.
void modifyItem(Index n, const ModifyOp &op) const
void setValueMaskOff(Index n)
static Index64 offTileCount()
bool isAllocated() const
Return true if memory for this node's buffer has been allocated.
const NodeMaskType & getValueMask() const
bool operator!=(const LeafNode &other) const
GLdouble GLdouble GLdouble z
const bool & getFirstValue() const
Return a const reference to the first entry in the buffer.
bool isConstant(bool &isOn) const
std::string str() const
Return a string representation of this node.
void set(Index32 n, bool On)
Set the nth bit to the specified state.
OnIterator beginOn() const
typename std::remove_const< UnsetItemT >::type NonConstValueType
ValueIter(const MaskIterT &iter, NodeT *parent)
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Replace inactive occurrences of oldBackground with newBackground, and inactive occurrences of -oldBac...
bool isChildMaskOff() const
ValueType medianAll(ValueType *tmp=nullptr) const
Computes the median value of all the active AND inactive voxels in this node.
static const Index LOG2DIM
LeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
void setOn(Index32 n)
Set the nth bit on.
ValueOffIter endValueOff()
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Index64 offVoxelCount() const
Return the number of voxels marked Off.
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
const Coord & origin() const
Return the grid index coordinates of this node's local origin.
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
OffIterator beginOff() const
ValueAllCIter cbeginValueAll() const
ChildOnCIter endChildOn() const
ValueIter< MaskOffIter, LeafNode, const bool > ValueOffIter
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...
Coord offsetToGlobalCoord(Index n) const
Return the global coordinates for a linear table offset.
Base class for sparse iterators over internal and leaf nodes.
void setValueOnlyAndCache(const Coord &xyz, bool val, AccessorT &)
Change the value of the voxel at the given coordinates but preserve its state.
static Index64 onTileCount()
void combine2(const LeafNode &other, const OtherType &, bool valueIsActive, CombineOp &)
GLenum GLuint GLenum GLsizei const GLchar * buf
Index medianOn(ValueType &value, ValueType *tmp=nullptr) const
Computes the median value of all the active voxels in this node.
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
LeafNode()
Default constructor.
void visit2Node(OtherLeafNodeType &other, VisitorOp &)
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
ChildOnCIter beginChildOn() const
bool isChildMaskOff(Index) const
Base class for dense iterators over internal and leaf nodes.
void fill(const ValueType &)
Populate this buffer with a constant value.
ChildIter< MaskOffIter, const LeafNode > ChildOffCIter
OffIterator endOff() const
ChildAllCIter endChildAll() const
DenseMaskIterator< NodeMask > DenseIterator
void setValueOn(Index offset)
Mark the voxel at the given offset as active but don't change its value.
static void evalNodeOrigin(Coord &xyz)
Compute the origin of the leaf node that contains the voxel with the given coordinates.
ValueIter< MaskOnIterator, const LeafNode, const ValueType, ValueOn > ValueOnCIter
ChildIter< MaskOffIter, LeafNode > ChildOffIter
void setItem(Index pos, const ValueT &value) const
DenseIter< LeafNode, bool > ChildAllIter
void setActiveState(Index offset, bool on)
Set the active state of the voxel at the given offset but don't change its value. ...
typename NodeMaskType::OnIterator MaskOnIter
Index64 onVoxelCount() const
Return the number of active voxels.
ValueAllCIter endValueAll() const
bool probeValue(const Coord &xyz, ValueType &val) const
Return true if the voxel at the given coordinates is active.
CombineArgs & setBRef(const BValueType &b)
Redirect the B value to a new external source.
void combine(const LeafNode &other, CombineOp &op)
void prune(const ValueType &=zeroVal< ValueType >())
This function exists only to enable template instantiation.
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
Index medianOff(ValueType &value, ValueType *tmp=nullptr) const
Computes the median value of all the inactive voxels in this node.
void addTileAndCache(Index, const Coord &, const ValueType &, bool, AccessorT &)
ValueIter< MaskOffIter, const LeafNode, const bool > ValueOffCIter
bool isEmpty() const
Return true if this node has no active voxels.
ValueIter< MaskDenseIter, const LeafNode, const bool > ValueAllCIter
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
void unsetItem(Index pos, const ValueT &val) const
NodeT * probeNode(const Coord &)
This function exists only to enable template instantiation.
void getOrigin(Coord &origin) const
Return the grid index coordinates of this node's local origin.
ValueIter< MaskDenseIterator, const LeafNode, const ValueType, ValueAll > ValueAllCIter
OnMaskIterator< NodeMask > OnIterator
void setValue(const Coord &xyz, bool val)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
LeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
void voxelizeActiveTiles(bool=true)
No-op.
Index64 offLeafVoxelCount() const
static Index getValueLevel(const Coord &)
Return the level (0) at which leaf node values reside.
typename NodeMaskType::DenseIterator MaskDenseIter
GLsizei const GLfloat * value
**If you just want to fire and args
bool isInactive() const
Return true if all of this node's values are inactive.
bool isDense() const
Return true if this node only contains active voxels.
LeafNode & operator=(const LeafNode &)=default
Deep assignment operator.
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
void copyFromDense(const CoordBBox &bbox, const DenseT &dense, const ValueType &background, const ValueType &tolerance)
Copy from a dense grid into this node the values of the voxels that lie within a given bounding box...
ChildIter(const MaskIterT &iter, NodeT *parent)
bool getItem(Index pos, void *&child, NonConstValueT &value) const
static Index32 nonLeafCount()
void visit2(IterT &otherIter, VisitorOp &, bool otherIsLHS=false)
static Index dim()
Return the number of voxels in each dimension.
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
SharedPtr< LeafNodeType > Ptr
void load(std::istream &is)
void visitActiveBBox(BBoxOp &) const
Calls the templated functor BBoxOp with bounding box information. An additional level argument is pro...
void addLeafAndCache(LeafNode *, AccessorT &)
This function exists only to enable template instantiation.
ChildOnCIter cendChildOn() const
bool isChildMaskOn(Index) const
void setValue(Index i, const ValueType &)
Set the i'th value of this buffer to the specified value.
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Set the active state of the voxel at the given coordinates without changing its value.
DenseIter< const LeafNode, const ValueType, ChildAll > ChildAllCIter
bool hasSameTopology(const LeafNode< OtherType, OtherLog2Dim > *other) const
Return true if the given node (which may have a different ValueType than this node) has the same acti...
typename BaseT::NonConstValueType NonConstValueT
ValueAllIter beginValueAll()
bool operator==(const LeafNode &other) const
Check for buffer, state and origin equivalence.
ChildOffIter beginChildOff()
ChildIter< MaskOnIter, LeafNode > ChildOnIter
ChildOffCIter endChildOff() const
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
ValueAllCIter cendValueAll() const
void setValueOnly(Index offset, bool val)
Set the value of the voxel at the given offset but don't change its active state. ...
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
void setValue(bool value) const
DenseIter(const MaskDenseIter &iter, NodeT *parent)
ValueOffCIter endValueOff() const
void nodeCount(std::vector< Index32 > &) const
no-op
static void doVisit2(NodeT &self, OtherChildAllIterT &, VisitorOp &, bool otherIsLHS)
bool probeValueAndCache(const Coord &xyz, bool &val, AccessorT &) const
Return true if the voxel at the given coordinates is active and return the voxel value in val...
NodeMaskType mValueMask
Bitmask that determines which voxels are active.
ChildIter< MaskOffIterator, const LeafNode, ChildOff > ChildOffCIter
const Buffer & buffer() const
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
ChildOffIter endChildOff()
static Index getChildDim()
ChildAllCIter beginChildAll() const
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
void writeTopology(std::ostream &os, bool toHalf=false) const
Write out just the topology.
bool isOff(Index32 n) const
Return true if the nth bit is off.
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Return true if the voxel at the given coordinates is active.
ValueOffIter beginValueOff()
DenseIter< LeafNode, ValueType, ChildAll > ChildAllIter
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
ValueIter< MaskOffIterator, LeafNode, const ValueType, ValueOff > ValueOffIter
void fill(const CoordBBox &bbox, const ValueType &, bool active=true)
Set all voxels within an axis-aligned box to the specified value and active state.
static void doVisit2Node(NodeT &self, OtherNodeT &other, VisitorOp &)
ValueOffCIter cbeginValueOff() const