12 #ifndef OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
13 #define OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
29 #include <type_traits>
33 class TestPointDataLeaf;
51 const bool seek = destBuf ==
nullptr;
55 if (destBytes >= maximumBytes) {
57 maximumBytes <<
" bytes in voxel values.")
67 bytes16 =
static_cast<uint16_t
>(meta->pass());
69 is.seekg(
sizeof(uint16_t), std::ios_base::cur);
73 is.read(reinterpret_cast<char*>(&bytes16),
sizeof(uint16_t));
79 is.seekg(destBytes, std::ios_base::cur);
82 is.read(reinterpret_cast<char*>(destBuf), destBytes);
88 is.seekg(
int(bytes16), std::ios_base::cur);
92 std::unique_ptr<char[]> bloscBuffer(
new char[
int(bytes16)]);
93 is.read(bloscBuffer.get(), bytes16);
97 std::memcpy(destBuf, buffer.get(), destBytes);
114 if (srcBytes >= maximumBytes) {
116 maximumBytes <<
" bytes in voxel values.")
119 const char* charBuffer =
reinterpret_cast<const char*
>(srcBuf);
121 size_t compressedBytes;
123 compressedBytes,
false);
125 if (compressedBytes > 0) {
126 auto bytes16 =
static_cast<uint16_t
>(compressedBytes);
127 os.write(reinterpret_cast<const char*>(&bytes16),
sizeof(uint16_t));
128 os.write(reinterpret_cast<const char*>(buffer.get()), compressedBytes);
131 auto bytes16 =
static_cast<uint16_t
>(maximumBytes);
132 os.write(reinterpret_cast<const char*>(&bytes16),
sizeof(uint16_t));
133 os.write(reinterpret_cast<const char*>(srcBuf), srcBytes);
137 template <
typename T>
143 const size_t srcBytes = srcCount*
sizeof(
T);
145 if (srcBytes >= maximumBytes) {
147 maximumBytes <<
" bytes in voxel values.")
150 const char* charBuffer =
reinterpret_cast<const char*
>(srcBuf);
155 if (compressedBytes > 0) {
156 auto bytes16 =
static_cast<uint16_t
>(compressedBytes);
157 os.write(reinterpret_cast<const char*>(&bytes16),
sizeof(uint16_t));
160 auto bytes16 =
static_cast<uint16_t
>(maximumBytes);
161 os.write(reinterpret_cast<const char*>(&bytes16),
sizeof(uint16_t));
199 template <
typename Po
intDataTreeT>
200 inline AttributeSet::Descriptor::Ptr
213 template <
typename Po
intDataTreeT>
224 template <
typename Po
intDataTreeT>
226 prefetch(PointDataTreeT& tree,
bool position =
true,
bool otherAttributes =
true);
232 template <
typename T, Index Log2Dim>
237 using Ptr = std::shared_ptr<PointDataLeafNode>;
253 using BaseLeaf::LOG2DIM;
254 using BaseLeaf::TOTAL;
256 using BaseLeaf::NUM_VALUES;
257 using BaseLeaf::NUM_VOXELS;
259 using BaseLeaf::LEVEL;
270 , mAttributeSet(new
AttributeSet(*other.mAttributeSet)) { }
281 const T&
value = zeroVal<T>(),
bool active =
false)
289 template<
typename OtherValueType>
296 template <
typename ValueType>
303 template <
typename ValueType>
309 const T&
value = zeroVal<T>(),
bool active =
false)
344 const size_t pos,
const Index strideOrTotalSize = 1,
345 const bool constantStride =
true,
351 const size_t pos,
const Index strideOrTotalSize,
352 const bool constantStride,
360 const Descriptor& expected, Descriptor::Ptr& replacement);
438 template<
typename OtherType, Index OtherLog2Dim>
440 return BaseLeaf::hasSameTopology(other);
446 if(BaseLeaf::operator==(other) !=
true)
return false;
447 return (*this->mAttributeSet == *other.mAttributeSet);
453 template<
typename AccessorT>
459 template<
typename AccessorT>
462 template<
typename NodeT,
typename AccessorT>
467 return reinterpret_cast<NodeT*
>(
this);
471 template<
typename AccessorT>
478 template<
typename AccessorT>
480 template<
typename AccessorT>
483 template<
typename NodeT,
typename AccessorT>
488 return reinterpret_cast<const NodeT*
>(
this);
495 void readTopology(std::istream& is,
bool fromHalf =
false);
496 void writeTopology(std::ostream& os,
bool toHalf =
false)
const;
500 void readBuffers(std::istream& is,
bool fromHalf =
false);
501 void readBuffers(std::istream& is,
const CoordBBox&,
bool fromHalf =
false);
502 void writeBuffers(std::ostream& os,
bool toHalf =
false)
const;
519 assert(
false &&
"Cannot modify voxel values in a PointDataTree.");
529 void setActiveState(
const Coord& xyz,
bool on) { BaseLeaf::setActiveState(xyz, on); }
535 void setValueOff(
const Coord& xyz) { BaseLeaf::setValueOff(xyz); }
541 void setValueOn(
const Coord& xyz) { BaseLeaf::setValueOn(xyz); }
552 template<
typename ModifyOp>
555 template<
typename ModifyOp>
558 template<
typename ModifyOp>
568 template<
typename AccessorT>
571 template<
typename ModifyOp,
typename AccessorT>
576 template<
typename AccessorT>
579 template<
typename AccessorT>
581 BaseLeaf::setActiveStateAndCache(xyz, on, parent);
593 friend class ::TestPointDataLeaf;
601 uint16_t mVoxelBufferSize = 0;
660 return this->beginIndex<ValueAllCIter, NullFilter>(
filter);
665 return this->beginIndex<ValueOnCIter, NullFilter>(
filter);
670 return this->beginIndex<ValueOffCIter, NullFilter>(
filter);
673 template<
typename IterT,
typename FilterT>
677 template<
typename FilterT>
680 return this->beginIndex<ValueAllCIter, FilterT>(
filter);
682 template<
typename FilterT>
685 return this->beginIndex<ValueOnCIter, FilterT>(
filter);
687 template<
typename FilterT>
690 return this->beginIndex<ValueOffCIter, FilterT>(
filter);
697 template<
typename FilterT>
700 #define VMASK_ this->getValueMask()
747 template<
typename T, Index Log2Dim>
756 template<
typename T, Index Log2Dim>
761 if (descriptor->size() != 1 ||
765 OPENVDB_THROW(IndexError,
"Initializing attributes only allowed with one Vec3f position attribute.");
768 mAttributeSet.reset(
new AttributeSet(descriptor, arrayLength, lock));
771 template<
typename T, Index Log2Dim>
776 mAttributeSet.reset(
new AttributeSet(*mAttributeSet, 0, lock));
784 if (updateValueMask) this->setValuesOff();
787 template<
typename T, Index Log2Dim>
791 return pos < mAttributeSet->size();
794 template<
typename T, Index Log2Dim>
798 const size_t pos = mAttributeSet->find(attributeName);
802 template<
typename T, Index Log2Dim>
805 const size_t pos,
const Index strideOrTotalSize,
806 const bool constantStride,
810 return mAttributeSet->appendAttribute(
811 expected, replacement, pos, strideOrTotalSize, constantStride, metadata, lock);
815 template<
typename T, Index Log2Dim>
818 const size_t pos,
const Index strideOrTotalSize,
819 const bool constantStride,
823 strideOrTotalSize, constantStride,
nullptr, lock);
826 template<
typename T, Index Log2Dim>
829 const Descriptor& expected, Descriptor::Ptr& replacement)
831 mAttributeSet->dropAttributes(pos, expected, replacement);
834 template<
typename T, Index Log2Dim>
838 mAttributeSet->reorderAttributes(replacement);
841 template<
typename T, Index Log2Dim>
845 mAttributeSet->renameAttributes(expected, replacement);
848 template<
typename T, Index Log2Dim>
852 for (
size_t i = 0; i < mAttributeSet->size(); i++) {
858 template<
typename T, Index Log2Dim>
863 OPENVDB_THROW(ValueError,
"Cannot replace with a null attribute set");
866 if (!allowMismatchingDescriptors && mAttributeSet->descriptor() != attributeSet->
descriptor()) {
867 OPENVDB_THROW(ValueError,
"Attribute set descriptors are not equal.");
870 mAttributeSet.reset(attributeSet);
873 template<
typename T, Index Log2Dim>
877 mAttributeSet->resetDescriptor(replacement);
880 template<
typename T, Index Log2Dim>
884 if (offsets.size() != LeafNodeType::NUM_VALUES) {
885 OPENVDB_THROW(ValueError,
"Offset vector size doesn't match number of voxels.")
892 if (updateValueMask) this->updateValueMask();
895 template<
typename T, Index Log2Dim>
901 if (this->getValue(
index-1) > this->getValue(
index)) {
902 OPENVDB_THROW(ValueError,
"Voxel offset values are not monotonically increasing");
907 for (
size_t attributeIndex = 1; attributeIndex < mAttributeSet->size(); ++attributeIndex ) {
908 if (mAttributeSet->getConst(attributeIndex-1)->size() != mAttributeSet->getConst(attributeIndex)->size()) {
909 OPENVDB_THROW(ValueError,
"Attribute arrays have inconsistent length");
914 if (mAttributeSet->size() > 0 && this->getValue(BaseLeaf::SIZE-1) != mAttributeSet->getConst(0)->size()) {
915 OPENVDB_THROW(ValueError,
"Last voxel offset value does not match attribute array length");
919 template<
typename T, Index Log2Dim>
923 if (pos >= mAttributeSet->size())
OPENVDB_THROW(LookupError,
"Attribute Out Of Range - " << pos);
924 return *mAttributeSet->get(pos);
927 template<
typename T, Index Log2Dim>
931 if (pos >= mAttributeSet->size())
OPENVDB_THROW(LookupError,
"Attribute Out Of Range - " << pos);
932 return *mAttributeSet->getConst(pos);
935 template<
typename T, Index Log2Dim>
939 return this->attributeArray(pos);
942 template<
typename T, Index Log2Dim>
946 const size_t pos = mAttributeSet->find(attributeName);
948 return *mAttributeSet->get(pos);
951 template<
typename T, Index Log2Dim>
955 const size_t pos = mAttributeSet->find(attributeName);
957 return *mAttributeSet->getConst(pos);
960 template<
typename T, Index Log2Dim>
964 return this->attributeArray(attributeName);
967 template<
typename T, Index Log2Dim>
979 template<
typename T, Index Log2Dim>
983 const AttributeSet::Descriptor::GroupIndex
index = this->attributeSet().groupIndex(name);
984 return this->groupHandle(index);
987 template<
typename T, Index Log2Dim>
999 template<
typename T, Index Log2Dim>
1003 const AttributeSet::Descriptor::GroupIndex
index = this->attributeSet().groupIndex(name);
1004 return this->groupWriteHandle(index);
1007 template<
typename T, Index Log2Dim>
1008 template<
typename ValueIterT,
typename FilterT>
1020 FilterT newFilter(filter);
1021 newFilter.reset(*
this);
1032 template<
typename T, Index Log2Dim>
1036 const Index index = LeafNodeType::coordToOffset(ijk);
1043 template<
typename T, Index Log2Dim>
1051 template<
typename T, Index Log2Dim>
1052 template<
typename FilterT>
1057 FilterT newFilter(filter);
1058 newFilter.reset(*
this);
1062 template<
typename T, Index Log2Dim>
1066 return this->getLastValue();
1069 template<
typename T, Index Log2Dim>
1073 if (this->isEmpty())
return 0;
1074 else if (this->isDense())
return this->
pointCount();
1078 template<
typename T, Index Log2Dim>
1082 if (this->isEmpty())
return this->
pointCount();
1083 else if (this->isDense())
return 0;
1084 return iterCount(this->beginIndexOff());
1087 template<
typename T, Index Log2Dim>
1091 if (!this->attributeSet().descriptor().hasGroup(groupName)) {
1098 return iterCount(this->beginIndexAll(filter));
1102 template<
typename T, Index Log2Dim>
1107 for (
Index n = 0;
n < LeafNodeType::NUM_VALUES;
n++) {
1108 end = this->getValue(
n);
1109 this->setValueMask(
n, (
end - start) > 0);
1114 template<
typename T, Index Log2Dim>
1118 this->
buffer().setValue(offset, val);
1119 this->setValueMaskOn(offset);
1122 template<
typename T, Index Log2Dim>
1126 this->
buffer().setValue(offset, val);
1129 template<
typename T, Index Log2Dim>
1133 BaseLeaf::readTopology(is, fromHalf);
1136 template<
typename T, Index Log2Dim>
1140 BaseLeaf::writeTopology(os, toHalf);
1143 template<
typename T, Index Log2Dim>
1150 mAttributeSet->size() +
1151 mAttributeSet->size() +
1155 template<
typename T, Index Log2Dim>
1159 this->readBuffers(is, CoordBBox::inf(), fromHalf);
1162 template<
typename T, Index Log2Dim>
1172 auto it = auxData.find(key);
1173 if (it != auxData.end()) {
1182 auto it = auxData.find(key);
1183 if (it != auxData.end()) {
1189 return *pagedStream;
1196 auto itMatching = auxData.find(matchingKey);
1197 return itMatching != auxData.end();
1204 auto itMatching = auxData.find(matchingKey);
1205 auto itDescriptor = auxData.find(descriptorKey);
1206 if (itMatching != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
1207 if (itDescriptor != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
1211 const Descriptor::Ptr descriptor)
1215 auto itMatching = auxData.find(matchingKey);
1216 if (itMatching == auxData.end()) {
1226 auto itDescriptor = auxData.find(descriptorKey);
1227 assert(itDescriptor != auxData.end());
1228 const Descriptor::Ptr descriptor = hboost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1236 OPENVDB_THROW(IoError,
"Cannot read in a PointDataLeaf without StreamMetadata.");
1239 const Index pass(static_cast<uint16_t>(meta->pass()));
1240 const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
1242 const Index attributes = (maximumPass - 4) / 2;
1246 is.read(reinterpret_cast<char*>(&mVoxelBufferSize),
sizeof(uint16_t));
1247 Local::clearMatchingDescriptor(meta->auxData());
1249 else if (pass == 1) {
1251 if (Local::hasMatchingDescriptor(meta->auxData())) {
1252 AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
1253 mAttributeSet->resetDescriptor(descriptor,
true);
1257 is.read(reinterpret_cast<char*>(&header),
sizeof(uint8_t));
1258 mAttributeSet->readDescriptor(is);
1259 if (header & uint8_t(1)) {
1261 Local::insertDescriptor(meta->auxData(), descriptor);
1265 if (header & uint8_t(2)) {
1266 uint64_t bytesToSkip;
1267 is.read(reinterpret_cast<char*>(&bytesToSkip),
sizeof(uint64_t));
1268 if (bytesToSkip > uint64_t(0)) {
1270 if (metadata && metadata->seekable()) {
1271 is.seekg(bytesToSkip, std::ios_base::cur);
1274 std::vector<uint8_t> tempData(bytesToSkip);
1275 is.read(reinterpret_cast<char*>(&tempData[0]), bytesToSkip);
1280 if (header > uint8_t(3)) {
1281 OPENVDB_THROW(IoError,
"Unrecognised header flags in PointDataLeafNode");
1284 mAttributeSet->readMetadata(is);
1286 else if (pass < (attributes + 2)) {
1288 const size_t attributeIndex = pass - 2;
1290 mAttributeSet->get(attributeIndex) :
nullptr;
1293 Local::getOrInsertPagedStream(meta->auxData(),
static_cast<Index>(attributeIndex));
1299 else if (pass == attributes + 2) {
1302 const Index passValue(meta->pass());
1306 nonConstMeta.
setPass(mVoxelBufferSize);
1309 BaseLeaf::readBuffers(is, fromHalf);
1312 nonConstMeta.setPass(passValue);
1314 else if (pass < (attributes*2 + 3)) {
1316 const Index attributeIndex = pass - attributes - 3;
1318 mAttributeSet->get(attributeIndex) :
nullptr;
1321 Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1327 if (pass > attributes + 3) {
1328 Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
1333 const Index attributeIndex = pass - attributes - 4;
1334 Local::destroyPagedStream(meta->auxData(), attributeIndex);
1338 template<
typename T, Index Log2Dim>
1348 auto it = auxData.find(key);
1349 if (it != auxData.end()) {
1360 auto it = auxData.find(key);
1361 if (it != auxData.end()) {
1367 return *pagedStream;
1372 const Descriptor::Ptr descriptor)
1376 auto itMatching = auxData.find(matchingKey);
1377 auto itDescriptor = auxData.find(descriptorKey);
1378 if (itMatching == auxData.end()) {
1381 assert(itDescriptor == auxData.end());
1386 bool matching = hboost::any_cast<
bool>(itMatching->second);
1387 if (!matching)
return;
1388 assert(itDescriptor != auxData.end());
1391 const Descriptor::Ptr existingDescriptor = hboost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1392 if (*existingDescriptor != *descriptor) {
1401 auto itMatching = auxData.find(matchingKey);
1403 if (itMatching == auxData.end())
return false;
1405 if (!hboost::any_cast<bool>(itMatching->second))
return false;
1412 auto itDescriptor = auxData.find(descriptorKey);
1414 if (itDescriptor == auxData.end())
return nullptr;
1416 const Descriptor::Ptr descriptor = hboost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1425 auto itMatching = auxData.find(matchingKey);
1426 auto itDescriptor = auxData.find(descriptorKey);
1427 if (itMatching != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
1428 if (itDescriptor != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
1435 OPENVDB_THROW(IoError,
"Cannot write out a PointDataLeaf without StreamMetadata.");
1438 const Index pass(static_cast<uint16_t>(meta->pass()));
1443 if (meta->countingPasses()) {
1445 if (requiredPasses > pass) {
1446 meta->setPass(requiredPasses);
1451 const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
1452 const Index attributes = (maximumPass - 4) / 2;
1458 Local::insertDescriptor(meta->auxData(), mAttributeSet->descriptorPtr());
1460 else if (pass == 1) {
1462 bool matchingDescriptor = Local::hasMatchingDescriptor(meta->auxData());
1463 if (matchingDescriptor) {
1464 AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
1468 os.write(reinterpret_cast<const char*>(&header),
sizeof(uint8_t));
1469 mAttributeSet->writeDescriptor(os,
false);
1475 os.write(reinterpret_cast<const char*>(&header),
sizeof(uint8_t));
1476 mAttributeSet->writeDescriptor(os,
false);
1478 mAttributeSet->writeMetadata(os,
false,
true);
1480 else if (pass < attributes + 2) {
1482 const Index attributeIndex = pass - 2;
1485 Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
1488 mAttributeSet->getConst(attributeIndex) :
nullptr;
1491 Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1497 else if (pass == attributes + 2) {
1498 const Index attributeIndex = pass - 3;
1499 Local::destroyPagedStream(meta->auxData(), attributeIndex);
1501 BaseLeaf::writeBuffers(os, toHalf);
1503 else if (pass < (attributes*2 + 3)) {
1505 const Index attributeIndex = pass - attributes - 3;
1507 if (pass > attributes + 2) {
1508 Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
1511 mAttributeSet->getConst(attributeIndex) :
nullptr;
1514 Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1521 Local::clearMatchingDescriptor(meta->auxData());
1523 const Index attributeIndex = pass - attributes - 4;
1524 Local::destroyPagedStream(meta->auxData(), attributeIndex);
1528 template<
typename T, Index Log2Dim>
1532 return BaseLeaf::memUsage() + mAttributeSet->memUsage();
1535 template<
typename T, Index Log2Dim>
1539 BaseLeaf::evalActiveBoundingBox(bbox, visitVoxels);
1542 template<
typename T, Index Log2Dim>
1546 return BaseLeaf::getNodeBoundingBox();
1549 template<
typename T, Index Log2Dim>
1555 this->assertNonModifiableUnlessZero(value);
1559 for (
Int32 x = bbox.min().x();
x <= bbox.max().x(); ++
x) {
1560 const Index offsetX = (
x & (DIM-1u)) << 2*Log2Dim;
1561 for (
Int32 y = bbox.min().y();
y <= bbox.max().y(); ++
y) {
1562 const Index offsetXY = offsetX + ((
y & (DIM-1u)) << Log2Dim);
1563 for (
Int32 z = bbox.min().z();
z <= bbox.max().z(); ++
z) {
1565 this->setValueMask(offset, active);
1571 template<
typename T, Index Log2Dim>
1575 this->assertNonModifiableUnlessZero(value);
1579 if (active) this->setValuesOn();
1580 else this->setValuesOff();
1587 template <
typename Po
intDataTreeT>
1588 inline AttributeSet::Descriptor::Ptr
1591 auto leafIter = tree.beginLeaf();
1592 if (!leafIter)
return nullptr;
1595 auto newDescriptor = std::make_shared<AttributeSet::Descriptor>(descriptor);
1596 for (; leafIter; ++leafIter) {
1597 leafIter->resetDescriptor(newDescriptor);
1600 return newDescriptor;
1604 template <
typename Po
intDataTreeT>
1608 auto leafIter = tree.beginLeaf();
1609 for (; leafIter; ++leafIter) {
1610 for (
size_t i = 0; i < leafIter->attributeSet().size(); i++) {
1611 leafIter->attributeArray(i).setStreaming(on);
1617 template <
typename Po
intDataTreeT>
1619 prefetch(PointDataTreeT& tree,
bool position,
bool otherAttributes)
1624 auto leaf = tree.cbeginLeaf();
1627 const auto& attributeSet = leaf->attributeSet();
1631 for ( ; leaf; ++leaf) {
1632 leaf->buffer().data();
1637 size_t positionIndex = attributeSet.find(
"P");
1640 for (leaf = tree.cbeginLeaf(); leaf; ++leaf) {
1641 assert(leaf->hasAttribute(positionIndex));
1642 leaf->constAttributeArray(positionIndex).loadData();
1648 if (otherAttributes) {
1649 const size_t attributes = attributeSet.size();
1650 for (
size_t attributeIndex = 0; attributeIndex < attributes; attributeIndex++) {
1651 if (attributeIndex == positionIndex)
continue;
1652 for (leaf = tree.cbeginLeaf(); leaf; ++leaf) {
1653 assert(leaf->hasAttribute(attributeIndex));
1654 leaf->constAttributeArray(attributeIndex).loadData();
1661 namespace internal {
1678 template<
typename HeadT,
int HeadLevel>
1683 using Type =
typename SubtreeT::template Append<RootNodeT>;
1688 template <
typename ChildT, Index Log2Dim,
int HeadLevel>
1693 using Type =
typename SubtreeT::template Append<InternalNodeT>;
1698 template <
typename ChildT, Index Log2Dim>
1712 template <
typename TreeType>
1731 template<Index Dim1,
typename T2>
1738 #endif // OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
void modifyValueAndActiveStateAndCache(const Coord &, const ModifyOp &, AccessorT &)
void initializeAttributes(const Descriptor::Ptr &descriptor, const Index arrayLength, const AttributeArray::ScopedRegistryLock *lock=nullptr)
Create a new attribute set. Existing attributes will be removed.
PointIndex< Index32, 1 > PointDataIndex32
Index64 onPointCount() const
Compute the total active (on) point count for the leaf.
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
ValueOnCIter beginValueOn() const
vint4 max(const vint4 &a, const vint4 &b)
AttributeSet::UniquePtr stealAttributeSet()
Steal the attribute set, a new, empty attribute set is inserted in it's place.
typename BaseLeaf::ValueOn ValueOn
void setValue(const Coord &, const ValueType &)
Leaf nodes have no children, so their child iterators have no get/set accessors.
std::vector< ValueType > IndexArray
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets...
bool operator!=(const PointDataLeafNode &other) const
std::shared_ptr< Descriptor > DescriptorPtr
virtual void readPagedBuffers(compression::PagedInputStream &)=0
Read attribute buffers from a paged stream.
typename BaseLeaf::template DenseIter< const PointDataLeafNode, const ValueType, ChildAll > ChildAllCIter
PointDataLeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
ValueAllCIter cendValueAll() const
const PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
GLuint const GLchar * name
void assertNonModifiableUnlessZero(const ValueType &value)
IndexVoxelIter beginIndexVoxel(const Coord &ijk) const
Leaf index iterator from voxel.
typename BaseLeaf::template ValueIter< MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff > ValueOffIter
void modifyValueAndActiveState(const Coord &, const ModifyOp &)
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &value, TopologyCopy)
void setOffsets(const std::vector< ValueType > &offsets, const bool updateValueMask=true)
Sets all of the voxel offset values on this leaf, from the given vector of offsets. If updateValueMask is true, then the active value mask will be updated so voxels with points are active and empty voxels are inactive.
void modifyValue(const Coord &, const ModifyOp &)
GroupWriteHandle groupWriteHandle(const AttributeSet::Descriptor::GroupIndex &index)
Read-write group handle from group index.
bool hasSameTopology(const PointDataLeafNode< OtherType, OtherLog2Dim > *other) const
Return true if the given node (which may have a different ValueType than this node) has the same acti...
ValueOffIter endValueOff()
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin())
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
void setValueOff(const Coord &, const ValueType &)
ChildAllIter beginChildAll()
void setValueOnly(Index, const ValueType &)
GLuint const GLfloat * val
GLuint GLsizei const GLuint const GLintptr * offsets
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
void renameAttributes(const Descriptor &expected, Descriptor::Ptr &replacement)
Rename attributes in attribute set (order must remain the same).
void writeTopology(std::ostream &os, bool toHalf=false) const
void dropAttributes(const std::vector< size_t > &pos, const Descriptor &expected, Descriptor::Ptr &replacement)
Drop list of attributes.
void prefetch(PointDataTreeT &tree, bool position=true, bool otherAttributes=true)
Sequentially pre-fetch all delayed-load voxel and attribute data from disk in order to accelerate sub...
ValueOffIter beginValueOff()
void addLeaf(PointDataLeafNode *)
void setValueOff(const Coord &xyz)
~PointDataLeafNode()=default
void setActiveState(Index offset, bool on)
bool hasAttribute(const size_t pos) const
Returns true if an attribute with this index exists.
typename BaseLeaf::template ValueIter< MaskOnIterator, PointDataLeafNode, const ValueType, ValueOn > ValueOnIter
PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
void validateOffsets() const
Throws an error if the voxel values on this leaf are not monotonically increasing or within the bound...
ValueOffCIter cbeginValueOff() const
Leaf nodes that require multi-pass I/O must inherit from this struct.
void updateValueMask()
Activate voxels with non-zero points, deactivate voxels with zero points.
PointDataLeafNode * touchLeaf(const Coord &)
Return a pointer to this node.
ChildOnIter beginChildOn()
ValueOnIter beginValueOn()
typename BaseLeaf::template ChildIter< MaskOnIterator, const PointDataLeafNode, ChildOn > ChildOnCIter
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only reading size data.
typename BaseLeaf::template ValueIter< MaskDenseIterator, const PointDataLeafNode, const ValueType, ValueAll > ValueAllCIter
typename internal::PointDataNodeChain< RootNodeT, RootNodeT::LEVEL >::Type NodeChainT
#define OPENVDB_USE_VERSION_NAMESPACE
typename BaseLeaf::template ChildIter< MaskOffIterator, const PointDataLeafNode, ChildOff > ChildOffCIter
ValueOffCIter beginValueOff() const
IndexIter< IterT, FilterT > beginIndex(const FilterT &filter) const
void assertNonmodifiable()
void readBuffers(std::istream &is, bool fromHalf=false)
Base class for iterators over internal and leaf nodes.
const PointDataLeafNode * probeLeaf(const Coord &) const
Return a pointer to this node.
void signedFloodFill(const ValueType &, const ValueType &)
typename BaseLeaf::template DenseIter< PointDataLeafNode, ValueType, ChildAll > ChildAllIter
CoordBBox getNodeBoundingBox() const
Return the bounding box of this node, i.e., the full index space spanned by this leaf node...
void initialize()
Global registration of point data-related types.
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
A no-op filter that can be used when iterating over all indices.
void setValueOn(Index, const ValueType &)
Tag dispatch class that distinguishes constructors during file input.
virtual void writePagedBuffers(compression::PagedOutputStream &, bool outputTransient) const =0
void readTopology(std::istream &is, bool fromHalf=false)
ChildAllCIter beginChildAll() const
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &, const T &, TopologyCopy)
typename SubtreeT::template Append< RootNodeT > Type
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only writing size data.
typename TreeType::RootNodeType RootNodeT
AttributeSet::Descriptor Descriptor
bool isGroup(const AttributeArray &array)
ChildAllCIter cendChildAll() const
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
ValueOnCIter cbeginValueOn() const
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
PointDataLeafNode(const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Construct using supplied origin, value and active status.
const PointDataLeafNode * probeConstLeaf(const Coord &) const
Return a pointer to this node.
typename BaseLeaf::template ChildIter< MaskOffIterator, PointDataLeafNode, ChildOff > ChildOffIter
void compactAttributes()
Compact all attributes in attribute set.
IndexIter< ValueAllCIter, FilterT > beginIndexAll(const FilterT &filter) const
Filtered leaf index iterator.
ChildAllCIter endChildAll() const
const char * typeNameAsString< Vec3f >()
static index::State state()
void appendAttribute(PointDataTreeT &tree, const Name &name, const NamePair &type, const Index strideOrTotalSize=1, const bool constantStride=true, const Metadata *defaultValue=nullptr, const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree (this method does not require a templated AttributeType) ...
IndexOffIter beginIndexOff() const
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
void setValueOff(Index offset)
ChildOffIter endChildOff()
Base class for storing attribute data.
typename NodeMaskType::OffIterator MaskOffIterator
void setInputStream(std::istream &is)
typename PointDataNodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
IndexIter< ValueVoxelCIter, NullFilter > IndexVoxelIter
size_t writeCompressedValuesSize(ValueT *srcBuf, Index srcCount, const MaskT &valueMask, uint8_t maskMetadata, bool toHalf, uint32_t compress)
A forward iterator over array indices in a single voxel.
GLint GLint GLint GLint GLint x
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &parent)
GLint GLint GLint GLint GLint GLint y
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
PointDataLeafNode()
Default constructor.
void setStreamingMode(PointDataTreeT &tree, bool on=true)
Toggle the streaming mode on all attributes in the tree to collapse the attributes after deconstructi...
GLint GLenum GLsizei GLint GLsizei const void * data
const PointDataLeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Return a pointer to this node.
void uninitialize()
Global deregistration of point data-related types.
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim...
IndexAllIter beginIndexAll() const
Leaf index iterator.
void clearAttributes(const bool updateValueMask=true, const AttributeArray::ScopedRegistryLock *lock=nullptr)
Clear the attribute set.
bool operator==(const PointDataLeafNode &other) const
Attribute array storage for string data using Descriptor Metadata.
typename BaseLeaf::template ValueIter< MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn > ValueOnCIter
typename BaseLeaf::template ChildIter< MaskOnIterator, PointDataLeafNode, ChildOn > ChildOnIter
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
void clip(const CoordBBox &, const ValueType &value)
std::shared_ptr< AttributeArray > Ptr
void evalActiveBoundingBox(CoordBBox &bbox, bool visitVoxels=true) const
AttributeArray::Ptr appendAttribute(const Descriptor &expected, Descriptor::Ptr &replacement, const size_t pos, const Index strideOrTotalSize=1, const bool constantStride=true, const Metadata *metadata=nullptr, const AttributeArray::ScopedRegistryLock *lock=nullptr)
Append an attribute to the leaf.
void signedFloodFill(const ValueType &)
void setValueOnly(const Coord &, const ValueType &)
void setOffsetOn(Index offset, const ValueType &val)
Convenience wrappers to using Blosc and reading and writing of Paged data.
ValueAllCIter cbeginValueAll() const
virtual Index size() const =0
ChildOffIter beginChildOff()
Recursive node chain which generates a openvdb::TypeList value converted types of nodes to PointDataG...
Index64 pointCount(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Count the total number of points in a PointDataTree.
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Index64 offPointCount() const
Compute the total inactive (off) point count for the leaf.
std::pair< ValueType, ValueType > ValueTypePair
typename BaseLeaf::ChildAll ChildAll
ChildOnCIter cendChildOn() const
void setValueOffAndCache(const Coord &, const ValueType &, AccessorT &)
void reorderAttributes(const Descriptor::Ptr &replacement)
Reorder attribute set.
PointDataLeafNode(const PointDataLeafNode &other, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Index filtering on group membership.
typename SubtreeT::template Append< InternalNodeT > Type
Container class that associates a tree with a transform and metadata.
const AttributeArray & constAttributeArray(const size_t pos) const
ChildOnCIter endChildOn() const
PointDataLeafNode(const PointDataLeafNode &other)
Construct using deep copy of other PointDataLeafNode.
typename BaseLeaf::template ValueIter< MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll > ValueAllIter
void setActiveState(const Coord &xyz, bool on)
void flush()
Manually flushes the current page to disk if non-zero.
ValueAllIter endValueAll()
IndexIter< ValueOffCIter, FilterT > beginIndexOff(const FilterT &filter) const
typename BaseLeaf::ValueAll ValueAll
GLsizei const GLchar *const * string
std::shared_ptr< PointDataLeafNode > Ptr
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
std::unique_ptr< AttributeSet > UniquePtr
Allocator::value_type * allocate(Allocator &alloc, std::size_t n)
void fill(const CoordBBox &, const ValueType &, bool)
Library and file format version numbers.
ValueVoxelCIter beginValueVoxel(const Coord &ijk) const
Leaf value voxel iterator.
ChildOffCIter endChildOff() const
GroupHandle groupHandle(const AttributeSet::Descriptor::GroupIndex &index) const
}
void setOffsetOnly(Index offset, const ValueType &val)
Typed class for storing attribute data.
Set of Attribute Arrays which tracks metadata about each array.
typename BaseLeaf::ChildOff ChildOff
ChildOffCIter cbeginChildOff() const
PointDataLeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
Attribute Group access and filtering for iteration.
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
typename BaseLeaf::ValueOff ValueOff
ValueAllCIter beginValueAll() const
void setValueOn(const Coord &xyz)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
void resetBackground(const ValueType &, const ValueType &newBackground)
Ordered collection of uniquely-named attribute arrays.
ChildAllCIter cbeginChildAll() const
ChildOnCIter cbeginChildOn() const
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
void replaceAttributeSet(AttributeSet *attributeSet, bool allowMismatchingDescriptors=false)
Replace the underlying attribute set with the given attributeSet.
typename NodeMaskType::OnIterator MaskOnIterator
OPENVDB_API SharedPtr< StreamMetadata > getStreamMetadataPtr(std::ios_base &)
Return a shared pointer to an object that stores metadata (file format, compression scheme...
Integer wrapper, required to distinguish PointIndexGrid and PointDataGrid from Int32Grid and Int64Gri...
void setValueOn(Index offset)
ValueOnCIter cendValueOn() const
PointDataLeafNode(PartialCreate, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
void writeBuffers(std::ostream &os, bool toHalf=false) const
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
std::shared_ptr< PagedOutputStream > Ptr
std::shared_ptr< PagedInputStream > Ptr
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
typename BaseLeaf::template ValueIter< MaskOffIterator, const PointDataLeafNode, const ValueType, ValueOff > ValueOffCIter
ChildOffCIter beginChildOff() const
T zeroVal()
Return the value of type T that corresponds to zero.
Index64 groupPointCount(const Name &groupName) const
Compute the point count in a specific group for the leaf.
ValueOffCIter cendValueOff() const
PointDataLeafNode(const tools::PointIndexLeafNode< OtherValueType, Log2Dim > &other)
void setOutputStream(std::ostream &os)
void addLeafAndCache(PointDataLeafNode *, AccessorT &)
void setValueOff(Index, const ValueType &)
Attribute Array storage templated on type and compression codec.
void modifyValue(Index, const ModifyOp &)
const AttributeSet & attributeSet() const
Retrieve the attribute set.
Similiar to ValueConverter, but allows for tree configuration conversion to a PointDataTree. ValueConverter<PointDataIndex32> cannot be used as a PointDataLeafNode is not a specialization of LeafNode.
typename NodeMaskType::DenseIterator MaskDenseIterator
void setValueOnlyAndCache(const Coord &, const ValueType &, AccessorT &)
ValueOnCIter endValueOn() const
ChildOnCIter beginChildOn() const
AttributeArray & attributeArray(const size_t pos)
Read-write attribute array reference from index.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
IndexIter< ValueOnCIter, FilterT > beginIndexOn(const FilterT &filter) const
GLsizei const GLfloat * value
void setValueOn(const Coord &, const ValueType &)
A list of types (not necessarily unique)
ValueOffCIter endValueOff() const
ChildAllIter endChildAll()
ChildOffCIter cendChildOff() const
ValueAllCIter endValueAll() const
void fill(const ValueType &value)
Index64 pointCount() const
Compute the total point count for the leaf.
typename BaseLeaf::ChildOn ChildOn
#define OPENVDB_THROW(exception, message)
IndexOnIter beginIndexOn() const
void resetDescriptor(const Descriptor::Ptr &replacement)
Replace the descriptor with a new one The new Descriptor must exactly match the old one...
ValueAllIter beginValueAll()
typename PointDataNodeChain< ChildT, HeadLevel-1 >::Type SubtreeT