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 {
79 template<
typename OtherValueType>
95 template<
typename ValueType>
111 template<typename ValueType>
112 LeafNode(const
LeafNode<ValueType, Log2Dim>& other,
bool offValue,
bool onValue, TopologyCopy);
113 template<typename ValueType>
114 LeafNode(const
LeafNode<ValueType, Log2Dim>& other,
bool background, TopologyCopy);
177 const Coord&
origin()
const {
return mOrigin; }
200 template<
typename OtherType, Index OtherLog2Dim>
220 void readTopology(std::istream&,
bool fromHalf =
false);
222 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
225 void readBuffers(std::istream&,
bool fromHalf =
false);
228 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
234 const bool&
getValue(
const Coord& xyz)
const;
280 template<
typename ModifyOp>
284 template<
typename ModifyOp>
285 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
288 template<
typename ModifyOp>
328 template<
typename DenseT>
347 template<
typename DenseT>
352 template<
typename AccessorT>
357 template<
typename AccessorT>
362 template<
typename AccessorT>
368 template<
typename AccessorT>
373 template<
typename AccessorT>
382 template<
typename ModifyOp,
typename AccessorT>
390 template<
typename ModifyOp,
typename AccessorT>
399 template<
typename AccessorT>
408 template<
typename AccessorT>
416 template<
typename AccessorT>
422 const bool&
getFirstValue()
const {
if (mValueMask.
isOn(0))
return Buffer::sOn;
else return Buffer::sOff; }
426 const bool&
getLastValue()
const {
if (mValueMask.
isOn(
SIZE-1))
return Buffer::sOn;
else return Buffer::sOff; }
431 bool isConstant(
bool& constValue,
bool& state,
bool tolerance = 0)
const;
461 void negate() { mBuffer.mData.toggle(); }
463 template<MergePolicy Policy>
464 void merge(
const LeafNode& other,
bool bg =
false,
bool otherBG =
false);
465 template<MergePolicy Policy>
void merge(
bool tileValue,
bool tileActive);
477 template<
typename OtherType>
491 template<
typename OtherType>
505 template<
typename OtherType>
508 template<
typename CombineOp>
510 template<
typename CombineOp>
511 void combine(
bool,
bool valueIsActive, CombineOp& op);
513 template<
typename CombineOp,
typename OtherType >
514 void combine2(
const LeafNode& other,
const OtherType&,
bool valueIsActive, CombineOp&);
515 template<
typename CombineOp,
typename OtherNodeT >
516 void combine2(
bool,
const OtherNodeT& other,
bool valueIsActive, CombineOp&);
517 template<
typename CombineOp,
typename OtherNodeT >
524 template<
typename AccessorT>
526 template<
typename NodeT>
528 template<
typename NodeT>
530 template<
typename NodeT>
532 template<
typename ArrayT>
void getNodes(ArrayT&)
const {}
538 template<
typename AccessorT>
544 template<
typename AccessorT>
547 template<
typename AccessorT>
549 template<
typename NodeT,
typename AccessorT>
554 return reinterpret_cast<NodeT*
>(
this);
561 template<
typename AccessorT>
564 template<
typename AccessorT>
566 template<
typename NodeT,
typename AccessorT>
571 return reinterpret_cast<const NodeT*
>(
this);
584 template<
typename MaskIterT,
typename NodeT,
typename ValueT>
588 public SparseIteratorBase<MaskIterT, ValueIter<MaskIterT, NodeT, ValueT>, NodeT, ValueT>
604 template<
typename ModifyOp>
607 template<
typename ModifyOp>
612 template<
typename MaskIterT,
typename NodeT>
618 MaskIterT,
ChildIter<MaskIterT, NodeT>, NodeT, bool>(iter, parent) {}
621 template<
typename NodeT,
typename ValueT>
623 MaskDenseIter, DenseIter<NodeT, ValueT>, NodeT, void, ValueT>
633 value = this->
parent().getValue(pos);
647 using ValueOnCIter = ValueIter<MaskOnIter, const LeafNode, const bool>;
758 template<Index Log2Dim>
766 template<Index Log2Dim>
771 , mOrigin(xyz & (~(DIM - 1)))
776 template<Index Log2Dim>
781 , mOrigin(xyz & (~(DIM - 1)))
789 template<Index Log2Dim>
793 , mBuffer(other.mBuffer)
794 , mOrigin(other.mOrigin)
795 , mTransientData(other.mTransientData)
801 template<Index Log2Dim>
802 template<
typename ValueT>
806 , mOrigin(other.origin())
807 , mTransientData(other.mTransientData)
811 static inline bool convertValue(
const ValueT&
val) {
return bool(val); }
815 mBuffer.
setValue(i, Local::convertValue(other.mBuffer[i]));
820 template<Index Log2Dim>
821 template<
typename ValueT>
826 , mBuffer(background)
827 , mOrigin(other.origin())
828 , mTransientData(other.mTransientData)
833 template<Index Log2Dim>
834 template<
typename ValueT>
838 , mBuffer(other.valueMask())
839 , mOrigin(other.origin())
840 , mTransientData(other.mTransientData)
844 template<Index Log2Dim>
852 , mOrigin(xyz & (~(DIM - 1)))
853 , mTransientData(trans)
857 template<Index Log2Dim>
858 template<
typename ValueT>
864 , mOrigin(other.origin())
865 , mTransientData(other.mTransientData)
868 if (mValueMask.
isOn(i)) {
875 template<Index Log2Dim>
885 template<Index Log2Dim>
890 return sizeof(*this);
894 template<Index Log2Dim>
899 return sizeof(*this);
903 template<Index Log2Dim>
908 if (bbox.isInside(this_bbox))
return;
912 for(; iter; ++iter) this_bbox.expand(
this->offsetToLocalCoord(iter.pos()));
913 this_bbox.translate(this->
origin());
915 bbox.expand(this_bbox);
920 template<Index Log2Dim>
921 template<
typename OtherType, Index OtherLog2Dim>
926 return (Log2Dim == OtherLog2Dim && mValueMask == other->
getValueMask());
930 template<Index Log2Dim>
934 std::ostringstream ostr;
935 ostr <<
"LeafNode @" << mOrigin <<
": ";
944 template<Index Log2Dim>
948 assert ((xyz[0] & (
DIM-1u)) <
DIM && (xyz[1] & (
DIM-1u)) <
DIM && (xyz[2] & (
DIM-1u)) <
DIM);
949 return ((xyz[0] & (
DIM-1u)) << 2*Log2Dim)
950 + ((xyz[1] & (
DIM-1u)) << Log2Dim)
951 + (xyz[2] & (
DIM-1u));
955 template<Index Log2Dim>
959 assert(n < (1 << 3*Log2Dim));
961 xyz.setX(n >> 2*Log2Dim);
962 n &= ((1 << 2*Log2Dim) - 1);
963 xyz.setY(n >> Log2Dim);
964 xyz.setZ(n & ((1 << Log2Dim) - 1));
969 template<Index Log2Dim>
980 template<Index Log2Dim>
988 template<Index Log2Dim>
996 template<Index Log2Dim>
1006 bool background =
false;
1008 background = *
static_cast<const bool*
>(bgPtr);
1010 this->
clip(clipBBox, background);
1014 template<Index Log2Dim>
1019 mValueMask.
load(is);
1025 mBuffer.mData.load(is);
1030 int8_t numBuffers = 0;
1031 is.read(reinterpret_cast<char*>(&numBuffers),
sizeof(int8_t));
1035 std::unique_ptr<bool[]>
buf{
new bool[
SIZE]};
1036 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1039 mBuffer.mData.setOff();
1041 if (
buf[i]) mBuffer.mData.setOn(i);
1044 if (numBuffers > 1) {
1047 for (
int i = 1; i < numBuffers; ++i) {
1048 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1055 template<Index Log2Dim>
1060 mValueMask.
save(os);
1062 os.write(reinterpret_cast<const char*>(&mOrigin),
sizeof(
Coord::ValueType) * 3);
1064 mBuffer.mData.save(os);
1071 template<Index Log2Dim>
1075 return mOrigin == other.mOrigin &&
1077 mBuffer == other.mBuffer;
1081 template<Index Log2Dim>
1092 template<Index Log2Dim>
1096 if (!mValueMask.
isConstant(state))
return false;
1099 if (!tolerance && !(mBuffer.mData.isOn() || mBuffer.mData.isOff()))
return false;
1101 constValue = mBuffer.mData.isOn();
1107 template<Index Log2Dim>
1111 const Index countTrue = mBuffer.mData.countOn();
1115 template<Index Log2Dim>
1125 template<Index Log2Dim>
1129 const NodeMaskType tmp = mBuffer.mData & (!mValueMask);
1138 template<Index Log2Dim>
1145 template<Index Log2Dim>
1149 assert(offset <
SIZE);
1154 template<Index Log2Dim>
1155 template<
typename AccessorT>
1160 this->
addTile(level, xyz, val, active);
1167 template<Index Log2Dim>
1172 if (mBuffer.mData.isOn(
this->coordToOffset(xyz)))
return Buffer::sOn;
else return Buffer::sOff;
1176 template<Index Log2Dim>
1180 assert(offset <
SIZE);
1182 if (mBuffer.mData.isOn(offset))
return Buffer::sOn;
else return Buffer::sOff;
1186 template<Index Log2Dim>
1191 val = mBuffer.mData.isOn(offset);
1192 return mValueMask.
isOn(offset);
1196 template<Index Log2Dim>
1204 template<Index Log2Dim>
1208 assert(offset <
SIZE);
1209 mValueMask.
setOn(offset);
1210 mBuffer.mData.set(offset, val);
1214 template<Index Log2Dim>
1222 template<Index Log2Dim>
1230 template<Index Log2Dim>
1238 template<Index Log2Dim>
1242 assert(offset <
SIZE);
1243 mValueMask.
setOff(offset);
1244 mBuffer.mData.set(offset, val);
1248 template<Index Log2Dim>
1249 template<
typename ModifyOp>
1253 bool val = mBuffer.mData.isOn(offset);
1255 mBuffer.mData.set(offset, val);
1256 mValueMask.
setOn(offset);
1260 template<Index Log2Dim>
1261 template<
typename ModifyOp>
1269 template<Index Log2Dim>
1270 template<
typename ModifyOp>
1275 bool val = mBuffer.mData.isOn(offset), state = mValueMask.
isOn(offset);
1277 mBuffer.mData.set(offset, val);
1278 mValueMask.
set(offset, state);
1285 template<Index Log2Dim>
1289 if (newBackground != oldBackground) {
1293 mBuffer.mData = (mBuffer.mData & mValueMask) | bgMask;
1301 template<Index Log2Dim>
1302 template<MergePolicy Policy>
1309 const Index n = iter.pos();
1310 if (mValueMask.
isOff(n)) {
1311 mBuffer.mData.set(n, other.mBuffer.mData.isOn(n));
1312 mValueMask.
setOn(n);
1318 template<Index Log2Dim>
1319 template<MergePolicy Policy>
1325 if (!tileActive)
return;
1327 if (tileValue) mBuffer.mData |= !mValueMask;
1328 else mBuffer.mData &= mValueMask;
1337 template<Index Log2Dim>
1338 template<
typename OtherType>
1346 template<Index Log2Dim>
1347 template<
typename OtherType>
1356 template<Index Log2Dim>
1357 template<
typename OtherType>
1369 template<Index Log2Dim>
1374 if (!clipBBox.hasOverlap(nodeBBox)) {
1376 this->
fill(nodeBBox, background,
false);
1377 }
else if (clipBBox.isInside(nodeBBox)) {
1387 nodeBBox.intersect(clipBBox);
1389 int &
x = xyz.x(), &
y = xyz.y(), &
z = xyz.z();
1390 for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++
x) {
1391 for (
y = nodeBBox.min().y();
y <= nodeBBox.max().y(); ++
y) {
1392 for (
z = nodeBBox.min().z();
z <= nodeBBox.max().z(); ++
z) {
1409 template<Index Log2Dim>
1414 clippedBBox.intersect(bbox);
1415 if (!clippedBBox)
return;
1417 for (
Int32 x = clippedBBox.min().x();
x <= clippedBBox.max().x(); ++
x) {
1418 const Index offsetX = (
x & (
DIM-1u))<<2*Log2Dim;
1419 for (
Int32 y = clippedBBox.min().y();
y <= clippedBBox.max().y(); ++
y) {
1420 const Index offsetXY = offsetX + ((
y & (
DIM-1u))<< Log2Dim);
1421 for (
Int32 z = clippedBBox.min().z();
z <= clippedBBox.max().z(); ++
z) {
1423 mValueMask.
set(offset, active);
1424 mBuffer.mData.set(offset, value);
1430 template<Index Log2Dim>
1434 mBuffer.
fill(value);
1437 template<Index Log2Dim>
1441 mBuffer.
fill(value);
1442 mValueMask.
set(active);
1449 template<Index Log2Dim>
1450 template<
typename DenseT>
1456 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1457 const Coord&
min = dense.bbox().min();
1458 DenseValueType* t0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1459 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1460 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1461 DenseValueType* t1 = t0 + xStride * (
x - min[0]);
1463 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1464 DenseValueType* t2 = t1 + yStride * (
y - min[1]);
1466 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1;
z < ez; ++
z, t2 += zStride) {
1467 *t2 = DenseValueType(mBuffer.mData.isOn(n2++));
1474 template<Index Log2Dim>
1475 template<
typename DenseT>
1478 bool background,
bool tolerance)
1482 inline static bool toBool(
const DenseValueType&
v) {
return !
math::isZero(v); }
1485 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1486 const Coord&
min = dense.bbox().min();
1487 const DenseValueType* s0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1488 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1489 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1490 const DenseValueType* s1 = s0 + xStride * (
x - min[0]);
1492 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1493 const DenseValueType* s2 = s1 + yStride * (
y - min[1]);
1495 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2]+1;
z < ez; ++
z, ++n2, s2 += zStride) {
1497 if (tolerance || (background == Local::toBool(*s2))) {
1499 mBuffer.mData.set(n2, background);
1501 mValueMask.
setOn(n2);
1502 mBuffer.mData.set(n2, Local::toBool(*s2));
1513 template<Index Log2Dim>
1514 template<
typename CombineOp>
1520 bool result =
false, aVal = mBuffer.mData.isOn(i), bVal = other.mBuffer.mData.isOn(i);
1522 .setAIsActive(mValueMask.
isOn(i))
1525 .setResultRef(result));
1527 mBuffer.mData.set(i, result);
1532 template<Index Log2Dim>
1533 template<
typename CombineOp>
1538 args.
setBRef(value).setBIsActive(valueIsActive);
1540 bool result =
false, aVal = mBuffer.mData.isOn(i);
1542 .setAIsActive(mValueMask.
isOn(i))
1543 .setResultRef(result));
1545 mBuffer.mData.set(i, result);
1553 template<Index Log2Dim>
1554 template<
typename CombineOp,
typename OtherType>
1557 bool valueIsActive, CombineOp& op)
1560 args.
setBRef(value).setBIsActive(valueIsActive);
1562 bool result =
false, aVal = other.mBuffer.mData.isOn(i);
1565 .setResultRef(result));
1567 mBuffer.mData.set(i, result);
1572 template<Index Log2Dim>
1573 template<
typename CombineOp,
typename OtherNodeT>
1576 bool valueIsActive, CombineOp& op)
1579 args.
setARef(value).setAIsActive(valueIsActive);
1581 bool result =
false, bVal = other.mBuffer.mData.isOn(i);
1583 .setBIsActive(other.valueMask().isOn(i))
1584 .setResultRef(result));
1586 mBuffer.mData.set(i, result);
1591 template<Index Log2Dim>
1592 template<
typename CombineOp,
typename OtherNodeT>
1601 bool result =
false, b0Val = b0.mBuffer.mData.isOn(i), b1Val = b1.mBuffer.mData.isOn(i);
1605 .setBIsActive(b1.valueMask().isOn(i))
1606 .setResultRef(result));
1608 mBuffer.mData.set(i, result);
1617 #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.
Index64 memUsageIfLoaded() const
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
GLenum GLuint GLenum GLsizei const GLchar * buf
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.
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
LeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
static const Index NUM_VALUES
void setOff(Index32 n)
Set the nth bit off.
GLdouble GLdouble GLdouble z
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.
Index32 transientData() const
Return the transient data value.
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.
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
ChildIter< MaskOnIterator, const LeafNode, ChildOn > ChildOnCIter
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.
**But if you need a result
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.
ValueOnCIter cbeginValueOn() const
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.
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.
static Index log2dim()
Return log2 of the dimension of this LeafNode, e.g. 3 if dimensions are 8^3.
void save(std::ostream &os) const
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.
GA_API const UT_StringHolder trans
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
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
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
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate active
MaskT< LOG2DIM > mValueMask
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 &)
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.
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
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. ...
void setTransientData(Index32 transientData)
Set the transient data value.
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
**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()
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 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
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()
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.
Index32 transientData() const
Return the transient data value.
ValueOffCIter cbeginValueOff() const