4 #ifndef OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
5 #define OPENVDB_TREE_LEAF_NODE_BOOL_HAS_BEEN_INCLUDED
17 #include <type_traits>
28 template<Index Log2Dim>
50 template<
typename ValueType>
55 template<
typename OtherNodeType>
56 struct SameConfiguration {
80 template<
typename OtherValueType>
96 template<
typename ValueType>
112 template<typename ValueType>
113 LeafNode(const
LeafNode<ValueType, Log2Dim>& other,
bool offValue,
bool onValue, TopologyCopy);
114 template<typename ValueType>
115 LeafNode(const
LeafNode<ValueType, Log2Dim>& other,
bool background, TopologyCopy);
180 const Coord&
origin()
const {
return mOrigin; }
199 std::string
str()
const;
203 template<
typename OtherType, Index OtherLog2Dim>
223 void readTopology(std::istream&,
bool fromHalf =
false);
225 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
228 void readBuffers(std::istream&,
bool fromHalf =
false);
231 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
237 const bool&
getValue(
const Coord& xyz)
const;
287 template<
typename ModifyOp>
291 template<
typename ModifyOp>
295 template<
typename ModifyOp>
339 template<
typename DenseT>
358 template<
typename DenseT>
363 template<
typename AccessorT>
368 template<
typename AccessorT>
373 template<
typename AccessorT>
379 template<
typename AccessorT>
384 template<
typename AccessorT>
393 template<
typename ModifyOp,
typename AccessorT>
401 template<
typename ModifyOp,
typename AccessorT>
410 template<
typename AccessorT>
419 template<
typename AccessorT>
427 template<
typename AccessorT>
433 const bool&
getFirstValue()
const {
if (mValueMask.
isOn(0))
return Buffer::sOn;
else return Buffer::sOff; }
437 const bool&
getLastValue()
const {
if (mValueMask.
isOn(
SIZE-1))
return Buffer::sOn;
else return Buffer::sOff; }
442 bool isConstant(
bool& constValue,
bool&
state,
bool tolerance = 0)
const;
495 void negate() { mBuffer.mData.toggle(); }
497 template<MergePolicy Policy>
498 void merge(
const LeafNode& other,
bool bg =
false,
bool otherBG =
false);
499 template<MergePolicy Policy>
void merge(
bool tileValue,
bool tileActive);
511 template<
typename OtherType>
525 template<
typename OtherType>
539 template<
typename OtherType>
542 template<
typename CombineOp>
544 template<
typename CombineOp>
545 void combine(
bool,
bool valueIsActive, CombineOp&
op);
547 template<
typename CombineOp,
typename OtherType >
548 void combine2(
const LeafNode& other,
const OtherType&,
bool valueIsActive, CombineOp&);
549 template<
typename CombineOp,
typename OtherNodeT >
550 void combine2(
bool,
const OtherNodeT& other,
bool valueIsActive, CombineOp&);
551 template<
typename CombineOp,
typename OtherNodeT >
558 template<
typename AccessorT>
560 template<
typename NodeT>
562 template<
typename NodeT>
564 template<
typename NodeT>
566 template<
typename ArrayT>
void getNodes(ArrayT&)
const {}
572 template<
typename AccessorT>
578 template<
typename AccessorT>
581 template<
typename AccessorT>
583 template<
typename NodeT,
typename AccessorT>
588 return reinterpret_cast<NodeT*
>(
this);
595 template<
typename AccessorT>
598 template<
typename AccessorT>
600 template<
typename NodeT,
typename AccessorT>
605 return reinterpret_cast<const NodeT*
>(
this);
618 template<
typename MaskIterT,
typename NodeT,
typename ValueT>
622 public SparseIteratorBase<MaskIterT, ValueIter<MaskIterT, NodeT, ValueT>, NodeT, ValueT>
638 template<
typename ModifyOp>
641 template<
typename ModifyOp>
646 template<
typename MaskIterT,
typename NodeT>
652 MaskIterT,
ChildIter<MaskIterT, NodeT>, NodeT,
bool>(iter, parent) {}
655 template<
typename NodeT,
typename ValueT>
657 MaskDenseIter, DenseIter<NodeT, ValueT>, NodeT, void, ValueT>
667 value = this->
parent().getValue(pos);
681 using ValueOnCIter = ValueIter<MaskOnIter, const LeafNode, const bool>;
792 template<Index Log2Dim>
800 template<Index Log2Dim>
805 , mOrigin(xyz & (~(DIM - 1)))
810 template<Index Log2Dim>
815 , mOrigin(xyz & (~(DIM - 1)))
823 template<Index Log2Dim>
827 , mBuffer(other.mBuffer)
828 , mOrigin(other.mOrigin)
829 , mTransientData(other.mTransientData)
835 template<Index Log2Dim>
836 template<
typename ValueT>
840 , mOrigin(other.origin())
841 , mTransientData(other.mTransientData)
845 static inline bool convertValue(
const ValueT&
val) {
return bool(val); }
849 mBuffer.
setValue(i, Local::convertValue(other.mBuffer[i]));
854 template<Index Log2Dim>
855 template<
typename ValueT>
860 , mBuffer(background)
861 , mOrigin(other.origin())
862 , mTransientData(other.mTransientData)
867 template<Index Log2Dim>
868 template<
typename ValueT>
872 , mBuffer(other.valueMask())
873 , mOrigin(other.origin())
874 , mTransientData(other.mTransientData)
878 template<Index Log2Dim>
886 , mOrigin(xyz & (~(DIM - 1)))
887 , mTransientData(trans)
891 template<Index Log2Dim>
892 template<
typename ValueT>
898 , mOrigin(other.origin())
899 , mTransientData(other.mTransientData)
902 if (mValueMask.
isOn(i)) {
909 template<Index Log2Dim>
919 template<Index Log2Dim>
924 return sizeof(*this);
928 template<Index Log2Dim>
933 return sizeof(*this);
937 template<Index Log2Dim>
942 if (bbox.isInside(this_bbox))
return;
946 for(; iter; ++iter) this_bbox.expand(
this->offsetToLocalCoord(iter.pos()));
947 this_bbox.translate(this->
origin());
949 bbox.expand(this_bbox);
954 template<Index Log2Dim>
955 template<
typename OtherType, Index OtherLog2Dim>
960 return (Log2Dim == OtherLog2Dim && mValueMask == other->
getValueMask());
964 template<Index Log2Dim>
968 std::ostringstream ostr;
969 ostr <<
"LeafNode @" << mOrigin <<
": ";
978 template<Index Log2Dim>
983 return ((xyz[0] & (
DIM-1u)) << 2*Log2Dim)
984 + ((xyz[1] & (
DIM-1u)) << Log2Dim)
985 + (xyz[2] & (
DIM-1u));
989 template<Index Log2Dim>
995 xyz.setX(n >> 2*Log2Dim);
996 n &= ((1 << 2*Log2Dim) - 1);
997 xyz.setY(n >> Log2Dim);
998 xyz.setZ(n & ((1 << Log2Dim) - 1));
1003 template<Index Log2Dim>
1014 template<Index Log2Dim>
1018 mValueMask.
load(is);
1022 template<Index Log2Dim>
1026 mValueMask.
save(os);
1030 template<Index Log2Dim>
1040 bool background =
false;
1042 background = *
static_cast<const bool*
>(bgPtr);
1044 this->
clip(clipBBox, background);
1048 template<Index Log2Dim>
1053 mValueMask.
load(is);
1059 mBuffer.mData.load(is);
1064 int8_t numBuffers = 0;
1065 is.read(reinterpret_cast<char*>(&numBuffers),
sizeof(int8_t));
1069 std::unique_ptr<bool[]>
buf{
new bool[
SIZE]};
1070 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1073 mBuffer.mData.setOff();
1075 if (
buf[i]) mBuffer.mData.setOn(i);
1078 if (numBuffers > 1) {
1081 for (
int i = 1; i < numBuffers; ++i) {
1082 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1089 template<Index Log2Dim>
1094 mValueMask.
save(os);
1096 os.write(reinterpret_cast<const char*>(&mOrigin),
sizeof(
Coord::ValueType) * 3);
1098 mBuffer.mData.save(os);
1105 template<Index Log2Dim>
1109 return mOrigin == other.mOrigin &&
1111 mBuffer == other.mBuffer;
1115 template<Index Log2Dim>
1126 template<Index Log2Dim>
1130 if (!mValueMask.
isConstant(state))
return false;
1133 if (!tolerance && !(mBuffer.mData.isOn() || mBuffer.mData.isOff()))
return false;
1135 constValue = mBuffer.mData.isOn();
1141 template<Index Log2Dim>
1145 const Index countTrue = mBuffer.mData.countOn();
1149 template<Index Log2Dim>
1159 template<Index Log2Dim>
1163 const NodeMaskType tmp = mBuffer.mData & (!mValueMask);
1172 template<Index Log2Dim>
1179 template<Index Log2Dim>
1188 template<Index Log2Dim>
1189 template<
typename AccessorT>
1194 this->
addTile(level, xyz, val, active);
1201 template<Index Log2Dim>
1206 if (mBuffer.mData.isOn(
this->coordToOffset(xyz)))
return Buffer::sOn;
else return Buffer::sOff;
1210 template<Index Log2Dim>
1216 if (mBuffer.mData.isOn(offset))
return Buffer::sOn;
else return Buffer::sOff;
1220 template<Index Log2Dim>
1227 template<Index Log2Dim>
1232 val = mBuffer.mData.isOn(offset);
1233 return mValueMask.
isOn(offset);
1236 template<Index Log2Dim>
1244 template<Index Log2Dim>
1249 mValueMask.
setOn(offset);
1250 mBuffer.mData.set(offset, val);
1254 template<Index Log2Dim>
1262 template<Index Log2Dim>
1270 template<Index Log2Dim>
1278 template<Index Log2Dim>
1283 mValueMask.
setOff(offset);
1284 mBuffer.mData.set(offset, val);
1288 template<Index Log2Dim>
1289 template<
typename ModifyOp>
1293 bool val = mBuffer.mData.isOn(offset);
1295 mBuffer.mData.set(offset, val);
1296 mValueMask.
setOn(offset);
1300 template<Index Log2Dim>
1301 template<
typename ModifyOp>
1309 template<Index Log2Dim>
1310 template<
typename ModifyOp>
1315 bool val = mBuffer.mData.isOn(offset),
state = mValueMask.
isOn(offset);
1317 mBuffer.mData.set(offset, val);
1325 template<Index Log2Dim>
1329 if (newBackground != oldBackground) {
1333 mBuffer.mData = (mBuffer.mData & mValueMask) | bgMask;
1341 template<Index Log2Dim>
1342 template<MergePolicy Policy>
1349 const Index n = iter.pos();
1350 if (mValueMask.
isOff(n)) {
1351 mBuffer.mData.set(n, other.mBuffer.mData.isOn(n));
1352 mValueMask.
setOn(n);
1358 template<Index Log2Dim>
1359 template<MergePolicy Policy>
1365 if (!tileActive)
return;
1367 if (tileValue) mBuffer.mData |= !mValueMask;
1368 else mBuffer.mData &= mValueMask;
1377 template<Index Log2Dim>
1378 template<
typename OtherType>
1386 template<Index Log2Dim>
1387 template<
typename OtherType>
1396 template<Index Log2Dim>
1397 template<
typename OtherType>
1409 template<Index Log2Dim>
1414 if (!clipBBox.hasOverlap(nodeBBox)) {
1416 this->
fill(nodeBBox, background,
false);
1417 }
else if (clipBBox.isInside(nodeBBox)) {
1427 nodeBBox.intersect(clipBBox);
1429 int &
x = xyz.x(), &
y = xyz.y(), &
z = xyz.z();
1430 for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++
x) {
1431 for (
y = nodeBBox.min().y();
y <= nodeBBox.max().y(); ++
y) {
1432 for (
z = nodeBBox.min().z();
z <= nodeBBox.max().z(); ++
z) {
1449 template<Index Log2Dim>
1454 clippedBBox.intersect(bbox);
1455 if (!clippedBBox)
return;
1457 for (
Int32 x = clippedBBox.min().x();
x <= clippedBBox.max().x(); ++
x) {
1458 const Index offsetX = (
x & (
DIM-1u))<<2*Log2Dim;
1459 for (
Int32 y = clippedBBox.min().y();
y <= clippedBBox.max().y(); ++
y) {
1460 const Index offsetXY = offsetX + ((
y & (
DIM-1u))<< Log2Dim);
1461 for (
Int32 z = clippedBBox.min().z();
z <= clippedBBox.max().z(); ++
z) {
1463 mValueMask.
set(offset, active);
1464 mBuffer.mData.set(offset, value);
1470 template<Index Log2Dim>
1474 mBuffer.
fill(value);
1477 template<Index Log2Dim>
1481 mBuffer.
fill(value);
1482 mValueMask.
set(active);
1489 template<Index Log2Dim>
1490 template<
typename DenseT>
1496 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1497 const Coord&
min = dense.bbox().min();
1498 DenseValueType* t0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1499 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1500 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1501 DenseValueType* t1 = t0 + xStride * (
x - min[0]);
1503 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1504 DenseValueType* t2 = t1 + yStride * (
y - min[1]);
1506 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1;
z < ez; ++
z, t2 += zStride) {
1507 *t2 = DenseValueType(mBuffer.mData.isOn(n2++));
1514 template<Index Log2Dim>
1515 template<
typename DenseT>
1518 bool background,
bool tolerance)
1522 inline static bool toBool(
const DenseValueType&
v) {
return !
math::isZero(v); }
1525 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1526 const Coord&
min = dense.bbox().min();
1527 const DenseValueType* s0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1528 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1529 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1530 const DenseValueType* s1 = s0 + xStride * (
x - min[0]);
1532 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1533 const DenseValueType* s2 = s1 + yStride * (
y - min[1]);
1535 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2]+1;
z < ez; ++
z, ++n2, s2 += zStride) {
1537 if (tolerance || (background == Local::toBool(*s2))) {
1539 mBuffer.mData.set(n2, background);
1541 mValueMask.
setOn(n2);
1542 mBuffer.mData.set(n2, Local::toBool(*s2));
1553 template<Index Log2Dim>
1554 template<
typename CombineOp>
1560 bool result =
false, aVal = mBuffer.mData.isOn(i), bVal = other.mBuffer.mData.isOn(i);
1562 .setAIsActive(mValueMask.
isOn(i))
1565 .setResultRef(result));
1567 mBuffer.mData.set(i, result);
1572 template<Index Log2Dim>
1573 template<
typename CombineOp>
1578 args.
setBRef(value).setBIsActive(valueIsActive);
1580 bool result =
false, aVal = mBuffer.mData.isOn(i);
1582 .setAIsActive(mValueMask.
isOn(i))
1583 .setResultRef(result));
1585 mBuffer.mData.set(i, result);
1593 template<Index Log2Dim>
1594 template<
typename CombineOp,
typename OtherType>
1597 bool valueIsActive, CombineOp&
op)
1600 args.
setBRef(value).setBIsActive(valueIsActive);
1602 bool result =
false, aVal = other.mBuffer.mData.isOn(i);
1605 .setResultRef(result));
1607 mBuffer.mData.set(i, result);
1612 template<Index Log2Dim>
1613 template<
typename CombineOp,
typename OtherNodeT>
1616 bool valueIsActive, CombineOp&
op)
1619 args.
setARef(value).setAIsActive(valueIsActive);
1621 bool result =
false, bVal = other.mBuffer.mData.isOn(i);
1623 .setBIsActive(other.valueMask().isOn(i))
1624 .setResultRef(result));
1626 mBuffer.mData.set(i, result);
1631 template<Index Log2Dim>
1632 template<
typename CombineOp,
typename OtherNodeT>
1641 bool result =
false, b0Val = b0.mBuffer.mData.isOn(i), b1Val = b1.mBuffer.mData.isOn(i);
1645 .setBIsActive(b1.valueMask().isOn(i))
1646 .setResultRef(result));
1648 mBuffer.mData.set(i, result);
1657 #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 setValueOffUnsafe(Index offset)
Mark the voxel at the given offset as inactive but don't change its value.
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.
void setValueOnUnsafe(Index offset, const bool &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
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.
void setValueOnlyUnsafe(Index offset, const bool &value)
Set the value of the voxel at the given coordinates but don't change its active state.
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 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.
const bool & getValueUnsafe(Index offset) const
Return the value of the voxel at the given offset.
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.
#define OPENVDB_ASSERT(X)
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
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
void setValueOnUnsafe(Index offset)
Mark the voxel at the given offset as active but don't change its value.
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
bool isValueOff(Index offset) const
Return true if the voxel at the given offset is inactive.
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
void setValueOffUnsafe(Index offset, const bool &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
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 nodeCount(std::vector< Index64 > &) const
no-op
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 &)
bool getValueUnsafe(Index offset, bool &value) const
Return true if the voxel at the given offset is active and set value.
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
void setActiveStateUnsafe(Index offset, bool on)
Set the active state of the voxel at the given offset but don't change its value. ...
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.
static Index64 nonLeafCount()
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 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
static Index64 leafCount()
void load(std::istream &is)
void addLeafAndCache(LeafNode *, AccessorT &)
This function exists only to enable template instantiation.
ChildOnCIter cendChildOn() const
bool isChildMaskOn(Index) const
bool isValueOff(const Coord &xyz) const
Return true if the voxel at the given coordinates is inactive.
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
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.
void nodeCount(std::vector< Index64 > &) const
no-op
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