4 #ifndef OPENVDB_TREE_LEAFNODE_HAS_BEEN_INCLUDED
5 #define OPENVDB_TREE_LEAFNODE_HAS_BEEN_INCLUDED
17 #include <type_traits>
29 template<Index,
typename>
struct SameLeafConfig;
36 template<
typename T, Index Log2Dim>
58 template<
typename OtherValueType>
63 template<
typename OtherNodeType>
97 template<
typename OtherValueType>
101 template<
typename OtherValueType>
106 template<
typename OtherValueType>
173 const Coord&
origin()
const {
return mOrigin; }
196 template<
typename OtherType, Index OtherLog2Dim>
212 template<
typename MaskIterT,
typename NodeT,
typename ValueT,
typename TagT>
217 MaskIterT, ValueIter<MaskIterT, NodeT, ValueT, TagT>, NodeT, ValueT>
230 this->
parent().setValueOnly(pos, value);
235 this->
parent().setValueOnly(this->
pos(), value);
239 template<
typename ModifyOp>
242 template<
typename ModifyOp>
247 template<
typename MaskIterT,
typename NodeT,
typename TagT>
249 public SparseIteratorBase<MaskIterT, ChildIter<MaskIterT, NodeT, TagT>, NodeT, ValueType>
256 template<
typename NodeT,
typename ValueT,
typename TagT>
258 MaskDenseIterator, DenseIter<NodeT, ValueT, TagT>, NodeT, void, ValueT>
268 value = this->
parent().getValue(pos);
279 this->
parent().setValueOnly(pos, value);
354 void readTopology(std::istream& is,
bool fromHalf =
false);
358 void writeTopology(std::ostream& os,
bool toHalf =
false)
const;
363 void readBuffers(std::istream& is,
bool fromHalf =
false);
372 void writeBuffers(std::ostream& os,
bool toHalf =
false)
const;
429 mValueMask.
setOn(offset);
434 template<
typename ModifyOp>
437 mBuffer.loadValues();
438 if (!mBuffer.
empty()) {
442 mValueMask.
setOn(offset);
448 template<
typename ModifyOp>
455 template<
typename ModifyOp>
458 mBuffer.loadValues();
459 if (!mBuffer.
empty()) {
461 bool state = mValueMask.
isOn(offset);
465 mValueMask.
set(offset, state);
509 template<
typename DenseT>
528 template<
typename DenseT>
534 template<
typename AccessorT>
542 template<
typename AccessorT>
547 template<
typename AccessorT>
556 template<
typename AccessorT>
565 template<
typename ModifyOp,
typename AccessorT>
573 template<
typename ModifyOp,
typename AccessorT>
581 template<
typename AccessorT>
590 template<
typename AccessorT>
599 template<
typename AccessorT>
608 template<
typename AccessorT>
612 state = mValueMask.
isOn(offset);
619 template<
typename AccessorT>
640 template<MergePolicy Policy>
void merge(
const ValueType& tileValue,
bool tileActive);
641 template<MergePolicy Policy>
650 template<
typename OtherType>
664 template<
typename OtherType>
678 template<
typename OtherType>
681 template<
typename CombineOp>
683 template<
typename CombineOp>
686 template<
typename CombineOp,
typename OtherType >
687 void combine2(
const LeafNode& other,
const OtherType&,
bool valueIsActive, CombineOp&);
688 template<
typename CombineOp,
typename OtherNodeT >
689 void combine2(
const ValueType&,
const OtherNodeT& other,
bool valueIsActive, CombineOp&);
690 template<
typename CombineOp,
typename OtherNodeT >
697 template<
typename AccessorT>
699 template<
typename NodeT>
701 template<
typename NodeT>
703 template<
typename NodeT>
705 template<
typename ArrayT>
void getNodes(ArrayT&)
const {}
711 template<
typename AccessorT>
717 template<
typename AccessorT>
719 template<
typename NodeT,
typename AccessorT>
724 return reinterpret_cast<NodeT*
>(
this);
728 template<
typename AccessorT>
734 template<
typename AccessorT>
736 template<
typename AccessorT>
739 template<
typename NodeT,
typename AccessorT>
744 return reinterpret_cast<const NodeT*
>(
this);
759 const ValueType& tolerance = zeroVal<ValueType>())
const;
773 bool& state,
const ValueType& tolerance = zeroVal<ValueType>())
const;
828 friend class ::TestLeaf;
829 template<
typename>
friend class ::TestLeafIO;
889 template<Index Dim1,
typename NodeT2>
892 template<Index Dim1,
typename T2>
900 template<
typename T, Index Log2Dim>
909 template<
typename T, Index Log2Dim>
914 mOrigin(xyz & (~(DIM - 1)))
919 template<
typename T, Index Log2Dim>
924 mOrigin(xyz & (~(DIM - 1)))
929 template<
typename T, Index Log2Dim>
932 : mBuffer(other.mBuffer)
934 , mOrigin(other.mOrigin)
935 , mTransientData(other.mTransientData)
941 template<
typename T, Index Log2Dim>
942 template<
typename OtherValueType>
946 , mOrigin(other.mOrigin)
947 , mTransientData(other.mTransientData)
955 mBuffer[i] = Local::convertValue(other.mBuffer[i]);
960 template<
typename T, Index Log2Dim>
961 template<
typename OtherValueType>
965 : mBuffer(background)
967 , mOrigin(other.mOrigin)
968 , mTransientData(other.mTransientData)
973 template<
typename T, Index Log2Dim>
974 template<
typename OtherValueType>
979 , mOrigin(other.mOrigin)
980 , mTransientData(other.mTransientData)
983 mBuffer[i] = (mValueMask.
isOn(i) ? onValue : offValue);
988 template<
typename T, Index Log2Dim>
995 template<
typename T, Index Log2Dim>
999 std::ostringstream ostr;
1000 ostr <<
"LeafNode @" << mOrigin <<
": " << mBuffer;
1008 template<
typename T, Index Log2Dim>
1012 assert ((xyz[0] & (DIM-1u)) < DIM && (xyz[1] & (DIM-1u)) < DIM && (xyz[2] & (DIM-1u)) < DIM);
1013 return ((xyz[0] & (DIM-1u)) << 2*Log2Dim)
1014 + ((xyz[1] & (DIM-1u)) << Log2Dim)
1015 + (xyz[2] & (DIM-1u));
1018 template<
typename T, Index Log2Dim>
1022 assert(n<(1<< 3*Log2Dim));
1024 xyz.setX(n >> 2*Log2Dim);
1025 n &= ((1<<2*Log2Dim)-1);
1026 xyz.setY(n >> Log2Dim);
1027 xyz.setZ(n & ((1<<Log2Dim)-1));
1032 template<
typename T, Index Log2Dim>
1036 return (this->offsetToLocalCoord(n) + this->origin());
1043 template<
typename ValueT, Index Log2Dim>
1044 inline const ValueT&
1050 template<
typename ValueT, Index Log2Dim>
1051 inline const ValueT&
1054 assert(offset <
SIZE);
1059 template<
typename T, Index Log2Dim>
1066 template<
typename T, Index Log2Dim>
1070 assert(offset <
SIZE);
1076 template<
typename T, Index Log2Dim>
1083 template<
typename T, Index Log2Dim>
1087 assert(offset <
SIZE);
1088 mBuffer.setValue(offset, val);
1093 template<
typename T, Index Log2Dim>
1097 mValueMask.set(this->coordToOffset(xyz), on);
1101 template<
typename T, Index Log2Dim>
1108 template<
typename T, Index Log2Dim>
1112 assert(offset<
SIZE); mBuffer.setValue(offset, val);
1119 template<
typename T, Index Log2Dim>
1123 CoordBBox nodeBBox = this->getNodeBoundingBox();
1124 if (!clipBBox.hasOverlap(nodeBBox)) {
1126 this->
fill(background,
false);
1127 }
else if (clipBBox.isInside(nodeBBox)) {
1137 nodeBBox.intersect(clipBBox);
1139 int &
x = xyz.x(), &
y = xyz.y(), &
z = xyz.z();
1140 for (x = nodeBBox.min().x(); x <= nodeBBox.max().x(); ++
x) {
1141 for (
y = nodeBBox.min().y();
y <= nodeBBox.max().y(); ++
y) {
1142 for (
z = nodeBBox.min().z();
z <= nodeBBox.max().z(); ++
z) {
1143 mask.
setOn(static_cast<Index32>(this->coordToOffset(xyz)));
1151 this->setValueOff(maskIter.pos(), background);
1159 template<
typename T, Index Log2Dim>
1163 if (!this->allocate())
return;
1165 auto clippedBBox = this->getNodeBoundingBox();
1166 clippedBBox.intersect(bbox);
1167 if (!clippedBBox)
return;
1169 for (
Int32 x = clippedBBox.min().x();
x <= clippedBBox.max().x(); ++
x) {
1170 const Index offsetX = (
x & (DIM-1u)) << 2*Log2Dim;
1171 for (
Int32 y = clippedBBox.min().y();
y <= clippedBBox.max().y(); ++
y) {
1172 const Index offsetXY = offsetX + ((
y & (DIM-1u)) << Log2Dim);
1173 for (
Int32 z = clippedBBox.min().z();
z <= clippedBBox.max().z(); ++
z) {
1182 template<
typename T, Index Log2Dim>
1186 mBuffer.fill(value);
1189 template<
typename T, Index Log2Dim>
1193 mBuffer.fill(value);
1201 template<
typename T, Index Log2Dim>
1202 template<
typename DenseT>
1206 mBuffer.loadValues();
1210 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1211 const Coord&
min = dense.bbox().min();
1212 DenseValueType* t0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1213 const T* s0 = &mBuffer[bbox.min()[2] & (DIM-1u)];
1214 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0] + 1;
x < ex; ++
x) {
1215 DenseValueType* t1 = t0 + xStride * (
x - min[0]);
1216 const T* s1 = s0 + ((
x & (DIM-1u)) << 2*Log2Dim);
1217 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1] + 1;
y < ey; ++
y) {
1218 DenseValueType* t2 = t1 + yStride * (
y - min[1]);
1219 const T* s2 = s1 + ((
y & (DIM-1u)) << Log2Dim);
1220 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2] + 1;
z < ez; ++
z, t2 += zStride) {
1221 *t2 = DenseValueType(*s2++);
1228 template<
typename T, Index Log2Dim>
1229 template<
typename DenseT>
1234 if (!this->allocate())
return;
1238 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
1239 const Coord&
min = dense.bbox().min();
1241 const DenseValueType* s0 = dense.data() + zStride * (bbox.min()[2] - min[2]);
1242 const Int32 n0 = bbox.min()[2] & (DIM-1u);
1243 for (
Int32 x = bbox.min()[0], ex = bbox.max()[0]+1;
x < ex; ++
x) {
1244 const DenseValueType* s1 = s0 + xStride * (
x - min[0]);
1245 const Int32 n1 = n0 + ((
x & (DIM-1u)) << 2*LOG2DIM);
1246 for (
Int32 y = bbox.min()[1], ey = bbox.max()[1]+1;
y < ey; ++
y) {
1247 const DenseValueType* s2 = s1 + yStride * (
y - min[1]);
1248 Int32 n2 = n1 + ((
y & (DIM-1u)) << LOG2DIM);
1249 for (
Int32 z = bbox.min()[2], ez = bbox.max()[2]+1;
z < ez; ++
z, ++n2, s2 += zStride) {
1252 mBuffer[n2] = background;
1266 template<
typename T, Index Log2Dim>
1274 template<
typename T, Index Log2Dim>
1286 template<
typename T, Index Log2Dim>
1292 io::readCompressedValues<ValueType, NodeMaskType>(
1302 template<
typename T, Index Log2Dim>
1306 this->readBuffers(is, CoordBBox::inf(), fromHalf);
1310 template<
typename T, Index Log2Dim>
1315 const bool seekable = meta && meta->seekable();
1317 #ifdef OPENVDB_USE_DELAYED_LOADING
1318 std::streamoff maskpos = is.tellg();
1329 int8_t numBuffers = 1;
1335 is.read(reinterpret_cast<char*>(&numBuffers),
sizeof(int8_t));
1338 CoordBBox nodeBBox = this->getNodeBoundingBox();
1339 if (!clipBBox.hasOverlap(nodeBBox)) {
1341 skipCompressedValues(seekable, is, fromHalf);
1343 mBuffer.setOutOfCore(
false);
1345 #ifdef OPENVDB_USE_DELAYED_LOADING
1350 io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is);
1351 const bool delayLoad = ((mappedFile.get() !=
nullptr) && clipBBox.isInside(nodeBBox));
1354 mBuffer.setOutOfCore(
true);
1355 mBuffer.mFileInfo =
new typename Buffer::FileInfo;
1356 mBuffer.mFileInfo->meta = meta;
1357 mBuffer.mFileInfo->bufpos = is.tellg();
1358 mBuffer.mFileInfo->mapping = mappedFile;
1361 mBuffer.mFileInfo->maskpos = maskpos;
1363 skipCompressedValues(seekable, is, fromHalf);
1368 mBuffer.setOutOfCore(
false);
1371 T background = zeroVal<T>();
1373 background = *
static_cast<const T*
>(bgPtr);
1375 this->
clip(clipBBox, background);
1376 #ifdef OPENVDB_USE_DELAYED_LOADING
1381 if (numBuffers > 1) {
1386 for (
int i = 1; i < numBuffers; ++i) {
1390 io::readData<T>(is, temp.mData,
SIZE, zipped);
1396 if (meta) meta->setLeaf(meta->leaf() + 1);
1400 template<
typename T, Index Log2Dim>
1407 mBuffer.loadValues();
1417 template<
typename T, Index Log2Dim>
1421 return mOrigin == other.mOrigin &&
1423 mBuffer == other.mBuffer;
1427 template<
typename T, Index Log2Dim>
1433 return sizeof(*this) + mBuffer.memUsage() -
sizeof(mBuffer);
1437 template<
typename T, Index Log2Dim>
1443 return sizeof(*this) + mBuffer.memUsageIfLoaded() -
sizeof(mBuffer);
1447 template<
typename T, Index Log2Dim>
1451 CoordBBox this_bbox = this->getNodeBoundingBox();
1452 if (bbox.isInside(this_bbox))
return;
1456 for(; iter; ++iter) this_bbox.expand(
this->offsetToLocalCoord(iter.pos()));
1457 this_bbox.translate(this->origin());
1459 bbox.expand(this_bbox);
1464 template<
typename T, Index Log2Dim>
1465 template<
typename OtherType, Index OtherLog2Dim>
1473 template<
typename T, Index Log2Dim>
1479 if (!
mValueMask.isConstant(state))
return false;
1480 firstValue = mBuffer[0];
1487 template<
typename T, Index Log2Dim>
1494 if (!
mValueMask.isConstant(state))
return false;
1495 minValue = maxValue = mBuffer[0];
1497 const T&
v = mBuffer[i];
1499 if ((maxValue - v) > tolerance)
return false;
1501 }
else if (v > maxValue) {
1502 if ((v - minValue) > tolerance)
return false;
1509 template<
typename T, Index Log2Dim>
1513 std::unique_ptr<T[]>
data(
nullptr);
1514 if (tmp ==
nullptr) {
1515 data.reset(
new T[NUM_VALUES]);
1518 if (tmp != mBuffer.data()) {
1519 const T*
src = mBuffer.data();
1520 for (
T*
dst = tmp;
dst-tmp < NUM_VALUES;) *
dst++ = *src++;
1522 static const size_t midpoint = (NUM_VALUES - 1) >> 1;
1523 std::nth_element(tmp, tmp + midpoint, tmp + NUM_VALUES);
1524 return tmp[midpoint];
1527 template<
typename T, Index Log2Dim>
1532 if (count == NUM_VALUES) {
1533 value = this->medianAll(tmp);
1535 }
else if (count == 0) {
1538 std::unique_ptr<T[]>
data(
nullptr);
1539 if (tmp ==
nullptr) {
1540 data.reset(
new T[count]);
1543 for (
auto iter=this->cbeginValueOn(); iter; ++iter) *tmp++ = *iter;
1545 const size_t midpoint = (count - 1) >> 1;
1546 std::nth_element(begin, begin + midpoint, tmp);
1547 value = begin[midpoint];
1551 template<
typename T, Index Log2Dim>
1556 if (count == NUM_VALUES) {
1557 value = this->medianAll(tmp);
1559 }
else if (count == 0) {
1562 std::unique_ptr<T[]>
data(
nullptr);
1563 if (tmp ==
nullptr) {
1564 data.reset(
new T[count]);
1567 for (
auto iter=this->cbeginValueOff(); iter; ++iter) *tmp++ = *iter;
1569 const size_t midpoint = (count - 1) >> 1;
1570 std::nth_element(begin, begin + midpoint, tmp);
1571 value = begin[midpoint];
1578 template<
typename T, Index Log2Dim>
1582 this->addTile(this->coordToOffset(xyz), val, active);
1585 template<
typename T, Index Log2Dim>
1589 assert(offset <
SIZE);
1591 setActiveState(offset, active);
1594 template<
typename T, Index Log2Dim>
1595 template<
typename AccessorT>
1600 this->addTile(level, xyz, val, active);
1607 template<
typename T, Index Log2Dim>
1612 if (!this->allocate())
return;
1616 for (iter = this->
mValueMask.beginOff(); iter; ++iter) {
1619 inactiveValue = newBackground;
1627 template<
typename T, Index Log2Dim>
1628 template<MergePolicy Policy>
1632 if (!this->allocate())
return;
1637 for (; iter; ++iter) {
1640 mBuffer[
n] = other.mBuffer[
n];
1647 template<
typename T, Index Log2Dim>
1648 template<MergePolicy Policy>
1653 this->
template merge<Policy>(other);
1656 template<
typename T, Index Log2Dim>
1657 template<MergePolicy Policy>
1661 if (!this->allocate())
return;
1665 if (!tileActive)
return;
1668 const Index n = iter.pos();
1669 mBuffer[
n] = tileValue;
1676 template<
typename T, Index Log2Dim>
1677 template<
typename OtherType>
1684 template<
typename T, Index Log2Dim>
1685 template<
typename OtherType>
1693 template<
typename T, Index Log2Dim>
1694 template<
typename OtherType>
1702 template<
typename T, Index Log2Dim>
1706 if (!this->allocate())
return;
1709 mBuffer[i] = -mBuffer[i];
1717 template<
typename T, Index Log2Dim>
1718 template<
typename CombineOp>
1722 if (!this->allocate())
return;
1728 .setBRef(other.mBuffer[i])
1730 .setResultRef(mBuffer[i]));
1736 template<
typename T, Index Log2Dim>
1737 template<
typename CombineOp>
1741 if (!this->allocate())
return;
1744 args.
setBRef(value).setBIsActive(valueIsActive);
1748 .setResultRef(mBuffer[i]));
1757 template<
typename T, Index Log2Dim>
1758 template<
typename CombineOp,
typename OtherType>
1761 bool valueIsActive, CombineOp& op)
1763 if (!this->allocate())
return;
1766 args.
setBRef(value).setBIsActive(valueIsActive);
1768 op(args.
setARef(other.mBuffer[i])
1770 .setResultRef(mBuffer[i]));
1776 template<
typename T, Index Log2Dim>
1777 template<
typename CombineOp,
typename OtherNodeT>
1780 bool valueIsActive, CombineOp& op)
1782 if (!this->allocate())
return;
1785 args.
setARef(value).setAIsActive(valueIsActive);
1787 op(args.
setBRef(other.mBuffer[i])
1788 .setBIsActive(other.valueMask().isOn(i))
1789 .setResultRef(mBuffer[i]));
1795 template<
typename T, Index Log2Dim>
1796 template<
typename CombineOp,
typename OtherNodeT>
1800 if (!this->allocate())
return;
1805 op(args.
setARef(b0.mBuffer[i])
1807 .setBRef(b1.mBuffer[i])
1808 .setBIsActive(b1.valueMask().isOn(i))
1809 .setResultRef(mBuffer[i]));
1818 template<
typename T, Index Log2Dim>
1819 inline std::ostream&
1820 operator<<(std::ostream& os, const typename LeafNode<T, Log2Dim>::Buffer&
buf)
1822 for (
Index32 i = 0,
N =
buf.size(); i <
N; ++i) os <<
buf.mData[i] <<
", ";
1840 #endif // OPENVDB_TREE_LEAFNODE_HAS_BEEN_INCLUDED
typename NodeMaskType::OnIterator MaskOnIterator
NodeT * stealNode(const Coord &, const ValueType &, bool)
This function exists only to enable template instantiation.
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Index64 memUsageIfLoaded() const
void merge(const LeafNode &)
GLenum GLuint GLenum GLsizei const GLchar * buf
Leaf nodes have no children, so their child iterators have no get/set accessors.
void stealNodes(ArrayT &, const ValueType &, bool)
This function exists only to enable template instantiation.
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 ...
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...
ValueAllCIter cbeginValueAll() const
void setValueOff(Index offset)
Mark the voxel at the given offset as inactive but don't change its value.
const NodeMaskType & valueMask() const
const ValueType & getFirstValue() const
Return a const reference to the first value in the buffer.
ChildOffCIter cendChildOff() const
ValueOffCIter beginValueOff() const
Index32 countOn() const
Return the total number of on bits.
void readBuffers(std::istream &is, bool fromHalf=false)
Read buffers from a stream.
bool isChildMaskOff() const
NodeMaskType & getValueMask()
bool isValueMaskOn() const
bool isValueOnAndCache(const Coord &xyz, AccessorT &) const
Return true if the voxel at the given coordinates is active.
ChildAllCIter endChildAll() const
ChildIter< MaskOffIterator, LeafNode, ChildOff > ChildOffIter
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 setValueAndCache(const Coord &xyz, const ValueType &val, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as active.
void setActiveState(Index offset, bool on)
Set the active state of the voxel at the given offset but don't change its value. ...
ChildOnIter beginChildOn()
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
ChildAllIter beginChildAll()
static bool hasActiveTiles()
Return false since leaf nodes never contain tiles.
ChildAllCIter cendChildAll() const
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
T negative(const T &val)
Return the unary negation of the given value.
bool isDense() const
Return true if this node contains only active voxels.
bool isConstant(ValueType &firstValue, bool &state, const ValueType &tolerance=zeroVal< ValueType >()) const
LeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
ValueOffCIter cbeginValueOff() const
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
ChildOnCIter cbeginChildOn() const
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
static const Index NUM_VALUES
void setValueOn(Index offset)
Mark the voxel at the given offset as active but don't change its value.
ValueAllCIter cendValueAll() const
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK, etc.) specifying whether and how input data is compressed or output data should be compressed.
static Index32 childCount()
Return the child count for this node, which is zero.
void setOff(Index32 n)
Set the nth bit off.
GLdouble GLdouble GLdouble z
Index pos() const
Identical to offset.
const LeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
bool getItem(Index pos, void *&child, NonConstValueT &value) const
DenseIterator endDense() const
Index64 memUsage() const
Return the memory in bytes occupied by this node.
static Index size()
Return the total number of voxels represented by this LeafNode.
ValueIter(const MaskIterT &iter, NodeT *parent)
util::NodeMask< Log2Dim > NodeMaskType
#define OPENVDB_USE_VERSION_NAMESPACE
SameConfiguration<OtherNodeType>::value is true if and only if OtherNodeType is the type of a LeafNod...
ChildOffCIter cbeginChildOff() const
ChildOffCIter endChildOff() const
bool isValueOn(Index offset) const
Return true if the voxel at the given offset is active.
Base class for iterators over internal and leaf nodes.
ValueOffIter endValueOff()
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
ChildIter< MaskOnIterator, const LeafNode, ChildOn > ChildOnCIter
**But if you need a or simply need to know when the task has note that the like this
ValueOffCIter endValueOff() const
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
ValueT & getItem(Index pos) const
ChildIter< MaskOnIterator, LeafNode, ChildOn > ChildOnIter
DenseIterator beginDense() const
void clip(const CoordBBox &, const ValueType &background)
Set all voxels that lie outside the given axis-aligned box to the background.
bool empty() const
Return true if memory for this buffer has not yet been allocated.
NodeT & parent() const
Return a reference to the node over which this iterator is iterating.
void modifyValue(const ModifyOp &op) const
ValueOnCIter endValueOn() const
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.
void setTransientData(Index32 transientData)
Set the transient data value.
__hostdev__ void setValueOnly(uint32_t offset, uint16_t value)
LeafBuffer< ValueType, Log2Dim > Buffer
bool probeValueAndCache(const Coord &xyz, ValueType &val, AccessorT &) const
Return true if the voxel at the given coordinates is active and return the voxel value in val...
bool isEmpty() const
Return true if this node has no active voxels.
ValueAllCIter endValueAll() const
Index64 offLeafVoxelCount() const
NodeT * probeNode(const Coord &)
This function exists only to enable template instantiation.
Tag dispatch class that distinguishes constructors during file input.
ValueOnCIter cbeginValueOn() const
ChildAllCIter cbeginChildAll() 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.
void setValuesOn()
Mark all voxels as active but don't change their values.
ValueIter< MaskOffIterator, const LeafNode, const ValueType, ValueOff > ValueOffCIter
Index64 onLeafVoxelCount() const
void setValueOffAndCache(const Coord &xyz, const ValueType &value, AccessorT &)
Change the value of the voxel at the given coordinates and mark it as inactive.
static Index getLevel()
Return the level of this node, which by definition is zero for LeafNodes.
__hostdev__ float getValue(uint32_t i) const
static Coord offsetToLocalCoord(Index n)
Return the local coordinates for a linear table offset, where offset 0 has coordinates (0...
bool isChildMaskOn(Index) const
static Index numValues()
Return the total number of voxels represented by this LeafNode.
Index32 countOff() const
Return the total number of on bits.
static void evalNodeOrigin(Coord &xyz)
Compute the origin of the leaf node that contains the voxel with the given coordinates.
void writeBuffers(std::ostream &os, bool toHalf=false) const
Write buffers to a stream.
ValueIter< MaskDenseIterator, LeafNode, const ValueType, ValueAll > ValueAllIter
ValueAllIter endValueAll()
void denseFill(const CoordBBox &bbox, const ValueType &value, bool active=true)
Set all voxels within an axis-aligned box to the specified value and active state.
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
void getOrigin(Int32 &x, Int32 &y, Int32 &z) const
Return the grid index coordinates of this node's local origin.
std::shared_ptr< T > SharedPtr
const LeafNode * probeConstLeaf(const Coord &) const
Return a pointer to this node.
bool isValueOn(const Coord &xyz) const
Return true if the voxel at the given coordinates is active.
const ValueType & getLastValue() const
Return a const reference to the last value in the buffer.
bool isChildMaskOff(Index) const
static Index64 onTileCount()
void addLeaf(LeafNode *)
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...
ValueOnCIter cendValueOn() const
void nodeCount(std::vector< Index32 > &) const
no-op
void addLeafAndCache(LeafNode *, AccessorT &)
This function exists only to enable template instantiation.
void setOrigin(const Coord &origin)
Set the grid index coordinates of this node's local origin.
OffMaskIterator< NodeMask > OffIterator
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
static Index log2dim()
Return log2 of the dimension of this LeafNode, e.g. 3 if dimensions are 8^3.
ChildOffCIter beginChildOff() const
bool isValueMaskOff(Index n) const
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...
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &)
Set the active state of the voxel at the given coordinates without changing its value.
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
bool isValueMaskOn(Index n) 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.
ChildOnCIter endChildOn() const
void addTile(Index level, const Coord &, const ValueType &, bool)
Index64 onVoxelCount() const
Return the number of voxels marked On.
void setValue(const ValueT &value) const
bool resultIsActive() const
bool isValueMaskOff() const
ValueT & getValue() const
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim...
LeafNode * touchLeaf(const Coord &)
Return a pointer to this node.
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.
ChildOnCIter beginChildOn() const
bool allocate()
Allocate memory for this buffer if it has not already been allocated.
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
ValueOffIter beginValueOff()
DenseIter(const MaskDenseIterator &iter, NodeT *parent)
const NodeMaskType & getValueMask() const
bool operator!=(const LeafNode &other) const
ChildOnCIter cendChildOn() 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
ChildOffIter endChildOff()
ValueOnIter beginValueOn()
void resetBackground(const ValueType &oldBackground, const ValueType &newBackground)
Replace inactive occurrences of oldBackground with newBackground, and inactive occurrences of -oldBac...
ValueType medianAll(ValueType *tmp=nullptr) const
Computes the median value of all the active AND inactive voxels in this node.
static const Index LOG2DIM
static Index getChildDim()
Return the dimension of child nodes of this LeafNode, which is one for voxels.
void setOn(Index32 n)
Set the nth bit on.
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
ChildAllIter endChildAll()
typename BaseT::NonConstValueType NonConstValueT
Index64 offVoxelCount() const
Return the number of voxels marked Off.
typename NodeMaskType::DenseIterator MaskDenseIterator
static Index getValueLevelAndCache(const Coord &, AccessorT &)
Return the LEVEL (=0) at which leaf node values reside.
static Index getValueLevel(const Coord &)
Return the level (i.e., 0) at which leaf node values reside.
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
void getOrigin(Coord &origin) const
Return the grid index coordinates of this node's local origin.
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
static Index dim()
Return the number of voxels in each coordinate dimension.
static Index32 leafCount()
Return the leaf count for this node, which is one.
void setValueMask(Index n, bool on)
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 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.
void setValueOnlyAndCache(const Coord &xyz, const ValueType &val, AccessorT &)
Change the value of the voxel at the given coordinates but preserve its state.
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
LeafNode()
Default constructor.
Base class for dense iterators over internal and leaf nodes.
OffIterator endOff() const
void modifyValueAndActiveStateAndCache(const Coord &xyz, const ModifyOp &op, AccessorT &)
void prune(const ValueType &=zeroVal< ValueType >())
This function exists only to enable template instantiation.
DenseMaskIterator< NodeMask > DenseIterator
ValueIter< MaskOnIterator, const LeafNode, const ValueType, ValueOn > ValueOnCIter
void setItem(Index pos, const ValueT &value) const
const ValueType & getValueAndCache(const Coord &xyz, AccessorT &) const
Return the value of the voxel at the given coordinates.
ValueAllIter beginValueAll()
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 setValueOn(const Coord &xyz, const ValueType &val)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
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 &)
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
ValueIter< MaskDenseIterator, const LeafNode, const ValueType, ValueAll > ValueAllCIter
OnMaskIterator< NodeMask > OnIterator
const NodeT * probeConstNode(const Coord &) const
This function exists only to enable template instantiation.
ValueOffCIter cendValueOff() const
const LeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
const ValueType & getValue(const Coord &xyz, bool &state, int &level, AccessorT &) const
Return the value of the voxel at the given coordinates and return its active state and level (i...
void setValueMask(const NodeMaskType &mask)
GA_API const UT_StringHolder N
void skipCompressedValues(bool seekable, std::istream &, bool fromHalf)
bool isInactive() const
Return true if all of this node's values are inactive.
static void getNodeLog2Dims(std::vector< Index > &dims)
Append the Log2Dim of this LeafNode to the specified vector.
void setValueMaskOff(Index n)
**If you just want to fire and args
void setValueOn(Index offset, const ValueType &val)
Set the value of the voxel at the given offset and mark the voxel as active.
ValueConverter<T>::Type is the type of a LeafNode having the same dimensions as this node but a diffe...
LeafNode & operator=(const LeafNode &)=default
Deep assignment operator.
CombineArgs & setARef(const AValueType &a)
Redirect the A value to a new external source.
OPENVDB_API SharedPtr< StreamMetadata > getStreamMetadataPtr(std::ios_base &)
Return a shared pointer to an object that stores metadata (file format, compression scheme...
void setValue(const Coord &xyz, const ValueType &val)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
void unsetItem(Index pos, const ValueT &value) const
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...
size_t streamingSize(bool toHalf=false) const
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
bool isAllocated() const
Return true if memory for this node's buffer has been allocated.
void setValuesOff()
Mark all voxels as inactive but don't change their values.
void voxelizeActiveTiles(bool=true)
No-op.
ChildIter(const MaskIterT &iter, NodeT *parent)
SharedPtr< LeafNode > Ptr
void setValue(Index i, const ValueType &)
Set the i'th value of this buffer to the specified 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...
ChildOffIter beginChildOff()
bool operator==(const LeafNode &other) const
Check for buffer, state and origin equivalence.
ValueOnCIter beginValueOn() const
const Buffer & buffer() const
typename NodeMaskType::OffIterator MaskOffIterator
bool allocate()
Allocate memory for this node's buffer if it has not already been allocated.
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T clip(const T &p, const Box< T > &box) IMATH_NOEXCEPT
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
static Index coordToOffset(const Coord &xyz)
Return the linear table offset of the given global or local coordinates.
ValueAllCIter beginValueAll() const
void getNodes(ArrayT &) const
This function exists only to enable template instantiation.
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
static Index64 offTileCount()
LeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
void setValueMaskOn(Index n)
ChildIter< MaskOffIterator, const LeafNode, ChildOff > ChildOffCIter
const LeafNode * probeLeaf(const Coord &) const
Return a pointer to this node.
ChildAllCIter beginChildAll() const
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.
static Index32 nonLeafCount()
Return the non-leaf count for this node, which is zero.
DenseIter< LeafNode, ValueType, ChildAll > ChildAllIter
ValueIter< MaskOffIterator, LeafNode, const ValueType, ValueOff > ValueOffIter
void swap(Buffer &other)
Exchange this node's data buffer with the given data buffer without changing the active states of the...
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.
LeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.