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>
95 template<
typename ValueType>
111 template<typename ValueType>
113 template<typename ValueType>
177 const Coord&
origin()
const {
return mOrigin; }
190 #if OPENVDB_ABI_VERSION_NUMBER >= 9
192 Index32 transientData()
const {
return mTransientData; }
194 void setTransientData(
Index32 transientData) { mTransientData = transientData; }
202 template<
typename OtherType, Index OtherLog2Dim>
203 bool hasSameTopology(
const LeafNode<OtherType, OtherLog2Dim>* other)
const;
222 void readTopology(std::istream&,
bool fromHalf =
false);
224 void writeTopology(std::ostream&,
bool toHalf =
false)
const;
227 void readBuffers(std::istream&,
bool fromHalf =
false);
228 void readBuffers(std::istream& is,
const CoordBBox&,
bool fromHalf =
false);
230 void writeBuffers(std::ostream&,
bool toHalf =
false)
const;
236 const bool&
getValue(
const Coord& xyz)
const;
282 template<
typename ModifyOp>
286 template<
typename ModifyOp>
287 void modifyValue(
const Coord& xyz,
const ModifyOp& op);
290 template<
typename ModifyOp>
307 void clip(
const CoordBBox&,
bool background);
310 void fill(
const CoordBBox& bbox,
bool value,
bool active =
true);
312 void denseFill(
const CoordBBox& bbox,
bool val,
bool on =
true) { this->
fill(bbox, val, on); }
317 void fill(
const bool&
value,
bool active);
330 template<
typename DenseT>
331 void copyToDense(
const CoordBBox& bbox, DenseT& dense)
const;
349 template<
typename DenseT>
350 void copyFromDense(
const CoordBBox& bbox,
const DenseT& dense,
bool background,
bool tolerance);
354 template<
typename AccessorT>
359 template<
typename AccessorT>
364 template<
typename AccessorT>
370 template<
typename AccessorT>
375 template<
typename AccessorT>
384 template<
typename ModifyOp,
typename AccessorT>
392 template<
typename ModifyOp,
typename AccessorT>
401 template<
typename AccessorT>
410 template<
typename AccessorT>
418 template<
typename AccessorT>
424 const bool&
getFirstValue()
const {
if (mValueMask.
isOn(0))
return Buffer::sOn;
else return Buffer::sOff; }
428 const bool&
getLastValue()
const {
if (mValueMask.
isOn(
SIZE-1))
return Buffer::sOn;
else return Buffer::sOff; }
433 bool isConstant(
bool& constValue,
bool& state,
bool tolerance = 0)
const;
463 void negate() { mBuffer.mData.toggle(); }
465 template<MergePolicy Policy>
466 void merge(
const LeafNode& other,
bool bg =
false,
bool otherBG =
false);
467 template<MergePolicy Policy>
void merge(
bool tileValue,
bool tileActive);
479 template<
typename OtherType>
493 template<
typename OtherType>
507 template<
typename OtherType>
510 template<
typename CombineOp>
512 template<
typename CombineOp>
513 void combine(
bool,
bool valueIsActive, CombineOp& op);
515 template<
typename CombineOp,
typename OtherType >
516 void combine2(
const LeafNode& other,
const OtherType&,
bool valueIsActive, CombineOp&);
517 template<
typename CombineOp,
typename OtherNodeT >
518 void combine2(
bool,
const OtherNodeT& other,
bool valueIsActive, CombineOp&);
519 template<
typename CombineOp,
typename OtherNodeT >
526 template<
typename AccessorT>
528 template<
typename NodeT>
530 template<
typename NodeT>
532 template<
typename NodeT>
534 template<
typename ArrayT>
void getNodes(ArrayT&)
const {}
540 template<
typename AccessorT>
546 template<
typename AccessorT>
549 template<
typename AccessorT>
551 template<
typename NodeT,
typename AccessorT>
556 return reinterpret_cast<NodeT*
>(
this);
563 template<
typename AccessorT>
566 template<
typename AccessorT>
568 template<
typename NodeT,
typename AccessorT>
573 return reinterpret_cast<const NodeT*
>(
this);
586 template<
typename MaskIterT,
typename NodeT,
typename ValueT>
590 public SparseIteratorBase<MaskIterT, ValueIter<MaskIterT, NodeT, ValueT>, NodeT, ValueT>
606 template<
typename ModifyOp>
609 template<
typename ModifyOp>
614 template<
typename MaskIterT,
typename NodeT>
620 MaskIterT,
ChildIter<MaskIterT, NodeT>, NodeT, bool>(iter, parent) {}
623 template<
typename NodeT,
typename ValueT>
625 MaskDenseIter, DenseIter<NodeT, ValueT>, NodeT, void, ValueT>
635 value = this->
parent().getValue(pos);
649 using ValueOnCIter = ValueIter<MaskOnIter, const LeafNode, const bool>;
731 #if OPENVDB_ABI_VERSION_NUMBER >= 9
762 template<Index Log2Dim>
770 template<Index Log2Dim>
775 , mOrigin(xyz & (~(DIM - 1)))
780 template<Index Log2Dim>
785 , mOrigin(xyz & (~(DIM - 1)))
793 template<Index Log2Dim>
796 : mValueMask(other.valueMask())
797 , mBuffer(other.mBuffer)
798 , mOrigin(other.mOrigin)
800 , mTransientData(other.mTransientData)
807 template<Index Log2Dim>
808 template<
typename ValueT>
811 : mValueMask(other.valueMask())
812 , mOrigin(other.origin())
814 , mTransientData(other.mTransientData)
819 static inline bool convertValue(
const ValueT&
val) {
return bool(val); }
823 mBuffer.
setValue(i, Local::convertValue(other.mBuffer[i]));
828 template<Index Log2Dim>
829 template<
typename ValueT>
833 : mValueMask(other.valueMask())
834 , mBuffer(background)
835 , mOrigin(other.origin())
837 , mTransientData(other.mTransientData)
843 template<Index Log2Dim>
844 template<
typename ValueT>
847 : mValueMask(other.valueMask())
848 , mBuffer(other.valueMask())
849 , mOrigin(other.origin())
851 , mTransientData(other.mTransientData)
856 template<Index Log2Dim>
867 , mOrigin(xyz & (~(DIM - 1)))
869 , mTransientData(trans)
874 template<Index Log2Dim>
875 template<
typename ValueT>
879 : mValueMask(other.valueMask())
881 , mOrigin(other.origin())
883 , mTransientData(other.mTransientData)
887 if (mValueMask.
isOn(i)) {
894 template<Index Log2Dim>
904 template<Index Log2Dim>
909 return sizeof(*this);
913 template<Index Log2Dim>
918 return sizeof(*this);
922 template<Index Log2Dim>
927 if (bbox.isInside(this_bbox))
return;
931 for(; iter; ++iter) this_bbox.expand(
this->offsetToLocalCoord(iter.pos()));
932 this_bbox.translate(this->
origin());
934 bbox.expand(this_bbox);
939 template<Index Log2Dim>
940 template<
typename OtherType, Index OtherLog2Dim>
945 return (Log2Dim == OtherLog2Dim && mValueMask == other->
getValueMask());
949 template<Index Log2Dim>
953 std::ostringstream ostr;
954 ostr <<
"LeafNode @" << mOrigin <<
": ";
963 template<Index Log2Dim>
967 assert ((xyz[0] & (
DIM-1u)) <
DIM && (xyz[1] & (
DIM-1u)) <
DIM && (xyz[2] & (
DIM-1u)) <
DIM);
968 return ((xyz[0] & (
DIM-1u)) << 2*Log2Dim)
969 + ((xyz[1] & (
DIM-1u)) << Log2Dim)
970 + (xyz[2] & (
DIM-1u));
974 template<Index Log2Dim>
978 assert(n < (1 << 3*Log2Dim));
980 xyz.setX(n >> 2*Log2Dim);
981 n &= ((1 << 2*Log2Dim) - 1);
982 xyz.setY(n >> Log2Dim);
983 xyz.setZ(n & ((1 << Log2Dim) - 1));
988 template<Index Log2Dim>
999 template<Index Log2Dim>
1003 mValueMask.
load(is);
1007 template<Index Log2Dim>
1011 mValueMask.
save(os);
1015 template<Index Log2Dim>
1025 bool background =
false;
1027 background = *
static_cast<const bool*
>(bgPtr);
1029 this->
clip(clipBBox, background);
1033 template<Index Log2Dim>
1038 mValueMask.
load(is);
1040 is.read(reinterpret_cast<char*>(&mOrigin),
sizeof(Coord::ValueType) * 3);
1044 mBuffer.mData.load(is);
1049 int8_t numBuffers = 0;
1050 is.read(reinterpret_cast<char*>(&numBuffers),
sizeof(int8_t));
1054 std::unique_ptr<bool[]>
buf{
new bool[
SIZE]};
1055 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1058 mBuffer.mData.setOff();
1060 if (
buf[i]) mBuffer.mData.setOn(i);
1063 if (numBuffers > 1) {
1066 for (
int i = 1; i < numBuffers; ++i) {
1067 io::readData<bool>(is,
buf.get(),
SIZE,
true);
1074 template<Index Log2Dim>
1079 mValueMask.
save(os);
1081 os.write(reinterpret_cast<const char*>(&mOrigin),
sizeof(Coord::ValueType) * 3);
1083 mBuffer.mData.save(os);
1090 template<Index Log2Dim>
1094 return mOrigin == other.mOrigin &&
1096 mBuffer == other.mBuffer;
1100 template<Index Log2Dim>
1111 template<Index Log2Dim>
1115 if (!mValueMask.
isConstant(state))
return false;
1118 if (!tolerance && !(mBuffer.mData.isOn() || mBuffer.mData.isOff()))
return false;
1120 constValue = mBuffer.mData.isOn();
1126 template<Index Log2Dim>
1130 const Index countTrue = mBuffer.mData.countOn();
1134 template<Index Log2Dim>
1144 template<Index Log2Dim>
1148 const NodeMaskType tmp = mBuffer.mData & (!mValueMask);
1157 template<Index Log2Dim>
1164 template<Index Log2Dim>
1168 assert(offset <
SIZE);
1173 template<Index Log2Dim>
1174 template<
typename AccessorT>
1177 bool val,
bool active, AccessorT&)
1179 this->
addTile(level, xyz, val, active);
1186 template<Index Log2Dim>
1191 if (mBuffer.mData.isOn(
this->coordToOffset(xyz)))
return Buffer::sOn;
else return Buffer::sOff;
1195 template<Index Log2Dim>
1199 assert(offset <
SIZE);
1201 if (mBuffer.mData.isOn(offset))
return Buffer::sOn;
else return Buffer::sOff;
1205 template<Index Log2Dim>
1210 val = mBuffer.mData.isOn(offset);
1211 return mValueMask.
isOn(offset);
1215 template<Index Log2Dim>
1223 template<Index Log2Dim>
1227 assert(offset <
SIZE);
1228 mValueMask.
setOn(offset);
1229 mBuffer.mData.set(offset, val);
1233 template<Index Log2Dim>
1241 template<Index Log2Dim>
1249 template<Index Log2Dim>
1257 template<Index Log2Dim>
1261 assert(offset <
SIZE);
1262 mValueMask.
setOff(offset);
1263 mBuffer.mData.set(offset, val);
1267 template<Index Log2Dim>
1268 template<
typename ModifyOp>
1272 bool val = mBuffer.mData.isOn(offset);
1274 mBuffer.mData.set(offset, val);
1275 mValueMask.
setOn(offset);
1279 template<Index Log2Dim>
1280 template<
typename ModifyOp>
1288 template<Index Log2Dim>
1289 template<
typename ModifyOp>
1294 bool val = mBuffer.mData.isOn(offset), state = mValueMask.
isOn(offset);
1296 mBuffer.mData.set(offset, val);
1297 mValueMask.
set(offset, state);
1304 template<Index Log2Dim>
1308 if (newBackground != oldBackground) {
1312 mBuffer.mData = (mBuffer.mData & mValueMask) | bgMask;
1320 template<Index Log2Dim>
1321 template<MergePolicy Policy>
1328 const Index n = iter.pos();
1329 if (mValueMask.
isOff(n)) {
1330 mBuffer.mData.set(n, other.mBuffer.mData.isOn(n));
1331 mValueMask.
setOn(n);
1337 template<Index Log2Dim>
1338 template<MergePolicy Policy>
1344 if (!tileActive)
return;
1346 if (tileValue) mBuffer.mData |= !mValueMask;
1347 else mBuffer.mData &= mValueMask;
1356 template<Index Log2Dim>
1357 template<
typename OtherType>
1365 template<Index Log2Dim>
1366 template<
typename OtherType>
1375 template<Index Log2Dim>
1376 template<
typename OtherType>
1388 template<Index Log2Dim>
1393 if (!clipBBox.hasOverlap(nodeBBox)) {
1395 this->
fill(nodeBBox, background,
false);
1396 }
else if (clipBBox.isInside(nodeBBox)) {
1406 nodeBBox.intersect(clipBBox);
1408 int &
x = xyz.x(), &
y = xyz.y(), &
z = xyz.z();
1409 for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++
x) {
1410 for (
y = nodeBBox.min().y();
y <= nodeBBox.max().y(); ++
y) {
1411 for (
z = nodeBBox.min().z();
z <= nodeBBox.max().z(); ++
z) {
1428 template<Index Log2Dim>
1433 clippedBBox.intersect(bbox);
1434 if (!clippedBBox)
return;
1436 for (
Int32 x = clippedBBox.min().x();
x <= clippedBBox.max().x(); ++
x) {
1437 const Index offsetX = (
x & (
DIM-1u))<<2*Log2Dim;
1438 for (
Int32 y = clippedBBox.min().y();
y <= clippedBBox.max().y(); ++
y) {
1439 const Index offsetXY = offsetX + ((
y & (
DIM-1u))<< Log2Dim);
1440 for (
Int32 z = clippedBBox.min().z();
z <= clippedBBox.max().z(); ++
z) {
1442 mValueMask.
set(offset, active);
1443 mBuffer.mData.set(offset, value);
1449 template<Index Log2Dim>
1453 mBuffer.
fill(value);
1456 template<Index Log2Dim>
1460 mBuffer.
fill(value);
1461 mValueMask.
set(active);
1468 template<Index Log2Dim>
1469 template<
typename DenseT>
1473 using DenseValueType =
typename DenseT::ValueType;
1475 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1476 const Coord&
min = dense.bbox().min();
1477 DenseValueType* t0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1478 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1479 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1480 DenseValueType* t1 = t0 + xStride * (
x - min[0]);
1482 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1483 DenseValueType* t2 = t1 + yStride * (
y - min[1]);
1485 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1;
z < ez; ++
z, t2 += zStride) {
1486 *t2 = DenseValueType(mBuffer.mData.isOn(n2++));
1493 template<Index Log2Dim>
1494 template<
typename DenseT>
1497 bool background,
bool tolerance)
1499 using DenseValueType =
typename DenseT::ValueType;
1501 inline static bool toBool(
const DenseValueType&
v) {
return !
math::isZero(v); }
1504 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1505 const Coord&
min = dense.bbox().min();
1506 const DenseValueType* s0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1507 const Int32 n0 = bbox.min()[2] & (
DIM-1u);
1508 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1509 const DenseValueType* s1 = s0 + xStride * (
x - min[0]);
1511 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1512 const DenseValueType* s2 = s1 + yStride * (
y - min[1]);
1514 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2]+1;
z < ez; ++
z, ++n2, s2 += zStride) {
1516 if (tolerance || (background == Local::toBool(*s2))) {
1518 mBuffer.mData.set(n2, background);
1520 mValueMask.
setOn(n2);
1521 mBuffer.mData.set(n2, Local::toBool(*s2));
1532 template<Index Log2Dim>
1533 template<
typename CombineOp>
1539 bool result =
false, aVal = mBuffer.mData.isOn(i), bVal = other.mBuffer.mData.isOn(i);
1541 .setAIsActive(mValueMask.
isOn(i))
1544 .setResultRef(result));
1546 mBuffer.mData.set(i, result);
1551 template<Index Log2Dim>
1552 template<
typename CombineOp>
1557 args.
setBRef(value).setBIsActive(valueIsActive);
1559 bool result =
false, aVal = mBuffer.mData.isOn(i);
1561 .setAIsActive(mValueMask.
isOn(i))
1562 .setResultRef(result));
1564 mBuffer.mData.set(i, result);
1572 template<Index Log2Dim>
1573 template<
typename CombineOp,
typename OtherType>
1576 bool valueIsActive, CombineOp& op)
1579 args.
setBRef(value).setBIsActive(valueIsActive);
1581 bool result =
false, aVal = other.mBuffer.mData.isOn(i);
1584 .setResultRef(result));
1586 mBuffer.mData.set(i, result);
1591 template<Index Log2Dim>
1592 template<
typename CombineOp,
typename OtherNodeT>
1595 bool valueIsActive, CombineOp& op)
1598 args.
setARef(value).setAIsActive(valueIsActive);
1600 bool result =
false, bVal = other.mBuffer.mData.isOn(i);
1602 .setBIsActive(other.valueMask().isOn(i))
1603 .setResultRef(result));
1605 mBuffer.mData.set(i, result);
1610 template<Index Log2Dim>
1611 template<
typename CombineOp,
typename OtherNodeT>
1620 bool result =
false, b0Val = b0.mBuffer.mData.isOn(i), b1Val = b1.mBuffer.mData.isOn(i);
1624 .setBIsActive(b1.valueMask().isOn(i))
1625 .setResultRef(result));
1627 mBuffer.mData.set(i, result);
1636 #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.
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.
#define OPENVDB_ABI_VERSION_NUMBER
The ABI version that OpenVDB was built with.
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
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. ...
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.
ValueOffCIter cbeginValueOff() const