Loading...
Searching...
No Matches
PointDataGrid.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/// @author Dan Bailey
///
/// @file points/PointDataGrid.h
///
/// @brief Attribute-owned data structure for points. Point attributes are
/// stored in leaf nodes and ordered by voxel for fast random and
/// sequential access.
#ifndef OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
#define OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
#include <openvdb/version.h>
#include <openvdb/Grid.h>
#include <openvdb/tree/Tree.h>
#include <openvdb/tree/LeafNode.h>
#include <openvdb/tools/PointIndexGrid.h>
#include "AttributeArray.h"
#include "AttributeArrayString.h"
#include "AttributeGroup.h"
#include "AttributeSet.h"
#include "StreamCompression.h"
#include <cstring> // std::memcpy
#include <iostream>
#include <limits>
#include <memory>
#include <type_traits> // std::is_same
#include <utility> // std::pair, std::make_pair
#include <vector>
class TestPointDataLeaf;
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace io
{
/// @brief openvdb::io::readCompressedValues specialized on PointDataIndex32 arrays to
/// ignore the value mask, use a larger block size and use 16-bit size instead of 64-bit
template<>
inline void
readCompressedValues( std::istream& is, PointDataIndex32* destBuf, Index destCount,
const util::NodeMask<3>& /*valueMask*/, bool /*fromHalf*/)
{
using compression::bloscDecompress;
const bool seek = destBuf == nullptr;
const size_t destBytes = destCount*sizeof(PointDataIndex32);
const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
if (destBytes >= maximumBytes) {
OPENVDB_THROW(openvdb::IoError, "Cannot read more than " <<
maximumBytes << " bytes in voxel values.")
}
uint16_t bytes16;
const io::StreamMetadata::Ptr meta = io::getStreamMetadataPtr(is);
if (seek && meta) {
// buffer size temporarily stored in the StreamMetadata pass
// to avoid having to perform an expensive disk read for 2-bytes
bytes16 = static_cast<uint16_t>(meta->pass());
// seek over size of the compressed buffer
is.seekg(sizeof(uint16_t), std::ios_base::cur);
}
else {
// otherwise read from disk
is.read(reinterpret_cast<char*>(&bytes16), sizeof(uint16_t));
}
if (bytes16 == std::numeric_limits<uint16_t>::max()) {
// read or seek uncompressed data
if (seek) {
is.seekg(destBytes, std::ios_base::cur);
}
else {
is.read(reinterpret_cast<char*>(destBuf), destBytes);
}
}
else {
// read or seek uncompressed data
if (seek) {
is.seekg(int(bytes16), std::ios_base::cur);
}
else {
// decompress into the destination buffer
std::unique_ptr<char[]> bloscBuffer(new char[int(bytes16)]);
is.read(bloscBuffer.get(), bytes16);
std::unique_ptr<char[]> buffer = bloscDecompress( bloscBuffer.get(),
destBytes,
/*resize=*/false);
std::memcpy(destBuf, buffer.get(), destBytes);
}
}
}
/// @brief openvdb::io::writeCompressedValues specialized on PointDataIndex32 arrays to
/// ignore the value mask, use a larger block size and use 16-bit size instead of 64-bit
template<>
inline void
writeCompressedValues( std::ostream& os, PointDataIndex32* srcBuf, Index srcCount,
const util::NodeMask<3>& /*valueMask*/,
const util::NodeMask<3>& /*childMask*/, bool /*toHalf*/)
{
using compression::bloscCompress;
const size_t srcBytes = srcCount*sizeof(PointDataIndex32);
const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
if (srcBytes >= maximumBytes) {
OPENVDB_THROW(openvdb::IoError, "Cannot write more than " <<
maximumBytes << " bytes in voxel values.")
}
const char* charBuffer = reinterpret_cast<const char*>(srcBuf);
size_t compressedBytes;
std::unique_ptr<char[]> buffer = bloscCompress( charBuffer, srcBytes,
compressedBytes, /*resize=*/false);
if (compressedBytes > 0) {
auto bytes16 = static_cast<uint16_t>(compressedBytes); // clamp to 16-bit unsigned integer
os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
os.write(reinterpret_cast<const char*>(buffer.get()), compressedBytes);
}
else {
auto bytes16 = static_cast<uint16_t>(maximumBytes); // max value indicates uncompressed
os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
os.write(reinterpret_cast<const char*>(srcBuf), srcBytes);
}
}
template <typename T>
inline void
writeCompressedValuesSize(std::ostream& os, const T* srcBuf, Index srcCount)
{
using compression::bloscCompressedSize;
const size_t srcBytes = srcCount*sizeof(T);
const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
if (srcBytes >= maximumBytes) {
OPENVDB_THROW(openvdb::IoError, "Cannot write more than " <<
maximumBytes << " bytes in voxel values.")
}
const char* charBuffer = reinterpret_cast<const char*>(srcBuf);
// calculate voxel buffer size after compression
size_t compressedBytes = bloscCompressedSize(charBuffer, srcBytes);
if (compressedBytes > 0) {
auto bytes16 = static_cast<uint16_t>(compressedBytes); // clamp to 16-bit unsigned integer
os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
}
else {
auto bytes16 = static_cast<uint16_t>(maximumBytes); // max value indicates uncompressed
os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
}
}
} // namespace io
// forward declaration
namespace tree {
template<Index, typename> struct SameLeafConfig;
}
////////////////////////////////////////
namespace points {
// forward declaration
template<typename T, Index Log2Dim> class PointDataLeafNode;
// these aliases are disabled in one of the unit tests to ensure that
// they are not used by the Point headers
#ifndef OPENVDB_DISABLE_POINT_DATA_TREE_ALIAS
/// @brief Point index tree configured to match the default VDB configurations.
using PointDataTree = tree::Tree<tree::RootNode<tree::InternalNode<tree::InternalNode
<PointDataLeafNode<PointDataIndex32, 3>, 4>, 5>>>;
/// @brief Point data grid.
using PointDataGrid = Grid<PointDataTree>;
#endif
/// @brief Deep copy the descriptor across all leaf nodes.
///
/// @param tree the PointDataTree.
///
/// @return the new descriptor.
///
/// @note This method will fail if the Descriptors in the tree are not all identical.
template <typename PointDataTreeT>
inline AttributeSet::Descriptor::Ptr
makeDescriptorUnique(PointDataTreeT& tree);
/// @brief Toggle the streaming mode on all attributes in the tree to collapse the attributes
/// after deconstructing a bound AttributeHandle to each array. This results in better
/// memory efficiency when the data is streamed into another data structure
/// (typically for rendering).
///
/// @param tree the PointDataTree.
/// @param on @c true to enable streaming
///
/// @note Multiple threads cannot safely access the same AttributeArray when using streaming.
template <typename PointDataTreeT>
inline void
setStreamingMode(PointDataTreeT& tree, bool on = true);
/// @brief Sequentially pre-fetch all delayed-load voxel and attribute data from disk in order
/// to accelerate subsequent random access.
///
/// @param tree the PointDataTree.
/// @param position if enabled, prefetch the position attribute (default is on)
/// @param otherAttributes if enabled, prefetch all other attributes (default is on)
template <typename PointDataTreeT>
inline void
prefetch(PointDataTreeT& tree, bool position = true, bool otherAttributes = true);
////////////////////////////////////////
template <typename T, Index Log2Dim>
class PointDataLeafNode : public tree::LeafNode<T, Log2Dim>, io::MultiPass {
public:
using LeafNodeType = PointDataLeafNode<T, Log2Dim>;
using Ptr = std::shared_ptr<PointDataLeafNode>;
using ValueType = T;
using ValueTypePair = std::pair<ValueType, ValueType>;
using IndexArray = std::vector<ValueType>;
using Descriptor = AttributeSet::Descriptor;
////////////////////////////////////////
// The following methods had to be copied from the LeafNode class
// to make the derived PointDataLeafNode class compatible with the tree structure.
using BaseLeaf = tree::LeafNode<T, Log2Dim>;
using NodeMaskType = util::NodeMask<Log2Dim>;
using BaseLeaf::LOG2DIM;
using BaseLeaf::TOTAL;
using BaseLeaf::DIM;
using BaseLeaf::NUM_VALUES;
using BaseLeaf::NUM_VOXELS;
using BaseLeaf::SIZE;
using BaseLeaf::LEVEL;
/// Default constructor
PointDataLeafNode()
: mAttributeSet(new AttributeSet) { }
~PointDataLeafNode() = default;
/// Construct using deep copy of other PointDataLeafNode
explicit PointDataLeafNode(const PointDataLeafNode& other)
: BaseLeaf(other)
, mAttributeSet(new AttributeSet(*other.mAttributeSet)) { }
/// Construct using supplied origin, value and active status
explicit
PointDataLeafNode(const Coord& coords, const T& value = zeroVal<T>(), bool active = false)
: BaseLeaf(coords, zeroVal<T>(), active)
, mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
/// Construct using supplied origin, value and active status
/// use attribute map from another PointDataLeafNode
PointDataLeafNode(const PointDataLeafNode& other, const Coord& coords,
const T& value = zeroVal<T>(), bool active = false)
: BaseLeaf(coords, zeroVal<T>(), active)
, mAttributeSet(new AttributeSet(*other.mAttributeSet))
{
assertNonModifiableUnlessZero(value);
}
// Copy-construct from a PointIndexLeafNode with the same configuration but a different ValueType.
template<typename OtherValueType>
PointDataLeafNode(const tools::PointIndexLeafNode<OtherValueType, Log2Dim>& other)
: BaseLeaf(other)
, mAttributeSet(new AttributeSet) { }
// Copy-construct from a LeafNode with the same configuration but a different ValueType.
// Used for topology copies - explicitly sets the value (background) to zeroVal
template <typename ValueType>
PointDataLeafNode(const tree::LeafNode<ValueType, Log2Dim>& other, const T& value, TopologyCopy)
: BaseLeaf(other, zeroVal<T>(), TopologyCopy())
, mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
// Copy-construct from a LeafNode with the same configuration but a different ValueType.
// Used for topology copies - explicitly sets the on and off value (background) to zeroVal
template <typename ValueType>
PointDataLeafNode(const tree::LeafNode<ValueType, Log2Dim>& other, const T& /*offValue*/, const T& /*onValue*/, TopologyCopy)
: BaseLeaf(other, zeroVal<T>(), zeroVal<T>(), TopologyCopy())
, mAttributeSet(new AttributeSet) { }
PointDataLeafNode(PartialCreate, const Coord& coords,
const T& value = zeroVal<T>(), bool active = false)
: BaseLeaf(PartialCreate(), coords, value, active)
, mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
public:
/// Retrieve the attribute set.
const AttributeSet& attributeSet() const { return *mAttributeSet; }
/// @brief Steal the attribute set, a new, empty attribute set is inserted in it's place.
AttributeSet::UniquePtr stealAttributeSet();
/// @brief Create a new attribute set. Existing attributes will be removed.
void initializeAttributes(const Descriptor::Ptr& descriptor, const Index arrayLength,
const AttributeArray::ScopedRegistryLock* lock = nullptr);
/// @brief Clear the attribute set.
void clearAttributes(const bool updateValueMask = true,
const AttributeArray::ScopedRegistryLock* lock = nullptr);
/// @brief Returns @c true if an attribute with this index exists.
/// @param pos Index of the attribute
bool hasAttribute(const size_t pos) const;
/// @brief Returns @c true if an attribute with this name exists.
/// @param attributeName Name of the attribute
bool hasAttribute(const Name& attributeName) const;
/// @brief Append an attribute to the leaf.
/// @param expected Existing descriptor is expected to match this parameter.
/// @param replacement New descriptor to replace the existing one.
/// @param pos Index of the new attribute in the descriptor replacement.
/// @param strideOrTotalSize Stride of the attribute array (if constantStride), total size otherwise
/// @param constantStride if @c false, stride is interpreted as total size of the array
/// @param metadata optional default value metadata
/// @param lock an optional scoped registry lock to avoid contention
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);
/// @brief Drop list of attributes.
/// @param pos vector of attribute indices to drop
/// @param expected Existing descriptor is expected to match this parameter.
/// @param replacement New descriptor to replace the existing one.
void dropAttributes(const std::vector<size_t>& pos,
const Descriptor& expected, Descriptor::Ptr& replacement);
/// @brief Reorder attribute set.
/// @param replacement New descriptor to replace the existing one.
void reorderAttributes(const Descriptor::Ptr& replacement);
/// @brief Rename attributes in attribute set (order must remain the same).
/// @param expected Existing descriptor is expected to match this parameter.
/// @param replacement New descriptor to replace the existing one.
void renameAttributes(const Descriptor& expected, Descriptor::Ptr& replacement);
/// @brief Compact all attributes in attribute set.
void compactAttributes();
/// @brief Replace the underlying attribute set with the given @a attributeSet.
/// @details This leaf will assume ownership of the given attribute set. The descriptors must
/// match and the voxel offsets values will need updating if the point order is different.
/// @throws ValueError if @a allowMismatchingDescriptors is @c false and the descriptors
/// do not match
void replaceAttributeSet(AttributeSet* attributeSet, bool allowMismatchingDescriptors = false);
/// @brief Replace the descriptor with a new one
/// The new Descriptor must exactly match the old one
void resetDescriptor(const Descriptor::Ptr& replacement);
/// @brief Sets all of the voxel offset values on this leaf, from the given vector
/// of @a offsets. If @a updateValueMask is true, then the active value mask will
/// be updated so voxels with points are active and empty voxels are inactive.
void setOffsets(const std::vector<ValueType>& offsets, const bool updateValueMask = true);
/// @brief Throws an error if the voxel values on this leaf are not monotonically
/// increasing or within the bounds of the attribute arrays
void validateOffsets() const;
/// @brief Read-write attribute array reference from index
/// @details Attribute arrays can be shared across leaf nodes, so non-const
/// access will deep-copy the array to make it unique. Always prefer
/// accessing const arrays where possible to eliminate this copying.
/// {
AttributeArray& attributeArray(const size_t pos);
const AttributeArray& attributeArray(const size_t pos) const;
const AttributeArray& constAttributeArray(const size_t pos) const;
/// }
/// @brief Read-write attribute array reference from name
/// @details Attribute arrays can be shared across leaf nodes, so non-const
/// access will deep-copy the array to make it unique. Always prefer
/// accessing const arrays where possible to eliminate this copying.
/// {
AttributeArray& attributeArray(const Name& attributeName);
const AttributeArray& attributeArray(const Name& attributeName) const;
const AttributeArray& constAttributeArray(const Name& attributeName) const;
/// }
/// @brief Read-only group handle from group index
GroupHandle groupHandle(const AttributeSet::Descriptor::GroupIndex& index) const;
/// @brief Read-only group handle from group name
GroupHandle groupHandle(const Name& group) const;
/// @brief Read-write group handle from group index
GroupWriteHandle groupWriteHandle(const AttributeSet::Descriptor::GroupIndex& index);
/// @brief Read-write group handle from group name
GroupWriteHandle groupWriteHandle(const Name& name);
/// @brief Compute the total point count for the leaf
Index64 pointCount() const;
/// @brief Compute the total active (on) point count for the leaf
Index64 onPointCount() const;
/// @brief Compute the total inactive (off) point count for the leaf
Index64 offPointCount() const;
/// @brief Compute the point count in a specific group for the leaf
Index64 groupPointCount(const Name& groupName) const;
/// @brief Activate voxels with non-zero points, deactivate voxels with zero points.
void updateValueMask();
////////////////////////////////////////
void setOffsetOn(Index offset, const ValueType& val);
void setOffsetOnly(Index offset, const ValueType& val);
/// @brief Return @c true if the given node (which may have a different @c ValueType
/// than this node) has the same active value topology as this node.
template<typename OtherType, Index OtherLog2Dim>
bool hasSameTopology(const PointDataLeafNode<OtherType, OtherLog2Dim>* other) const {
return BaseLeaf::hasSameTopology(other);
}
/// Check for buffer, state and origin equivalence first.
/// If this returns true, do a deeper comparison on the attribute set to check
bool operator==(const PointDataLeafNode& other) const {
if(BaseLeaf::operator==(other) != true) return false;
return (*this->mAttributeSet == *other.mAttributeSet);
}
bool operator!=(const PointDataLeafNode& other) const { return !(other == *this); }
void addLeaf(PointDataLeafNode*) {}
template<typename AccessorT>
void addLeafAndCache(PointDataLeafNode*, AccessorT&) {}
//@{
/// @brief Return a pointer to this node.
PointDataLeafNode* touchLeaf(const Coord&) { return this; }
template<typename AccessorT>
PointDataLeafNode* touchLeafAndCache(const Coord&, AccessorT&) { return this; }
template<typename NodeT, typename AccessorT>
NodeT* probeNodeAndCache(const Coord&, AccessorT&)
{
OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
if (!(std::is_same<NodeT,PointDataLeafNode>::value)) return nullptr;
return reinterpret_cast<NodeT*>(this);
OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
}
PointDataLeafNode* probeLeaf(const Coord&) { return this; }
template<typename AccessorT>
PointDataLeafNode* probeLeafAndCache(const Coord&, AccessorT&) { return this; }
//@}
//@{
/// @brief Return a @const pointer to this node.
const PointDataLeafNode* probeConstLeaf(const Coord&) const { return this; }
template<typename AccessorT>
const PointDataLeafNode* probeConstLeafAndCache(const Coord&, AccessorT&) const { return this; }
template<typename AccessorT>
const PointDataLeafNode* probeLeafAndCache(const Coord&, AccessorT&) const { return this; }
const PointDataLeafNode* probeLeaf(const Coord&) const { return this; }
template<typename NodeT, typename AccessorT>
const NodeT* probeConstNodeAndCache(const Coord&, AccessorT&) const
{
OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
if (!(std::is_same<NodeT,PointDataLeafNode>::value)) return nullptr;
return reinterpret_cast<const NodeT*>(this);
OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
}
//@}
// I/O methods
void readTopology(std::istream& is, bool fromHalf = false);
void writeTopology(std::ostream& os, bool toHalf = false) const;
Index buffers() const;
void readBuffers(std::istream& is, bool fromHalf = false);
void readBuffers(std::istream& is, const CoordBBox&, bool fromHalf = false);
void writeBuffers(std::ostream& os, bool toHalf = false) const;
Index64 memUsage() const;
#if OPENVDB_ABI_VERSION_NUMBER >= 10
Index64 memUsageIfLoaded() const;
#endif
void evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels = true) const;
/// @brief Return the bounding box of this node, i.e., the full index space
/// spanned by this leaf node.
CoordBBox getNodeBoundingBox() const;
////////////////////////////////////////
// Disable all write methods to avoid unintentional changes
// to the point-array offsets.
void assertNonmodifiable() {
assert(false && "Cannot modify voxel values in a PointDataTree.");
}
// some methods silently ignore attempts to modify the
// point-array offsets if a zero value is used
void assertNonModifiableUnlessZero(const ValueType& value) {
if (value != zeroVal<T>()) this->assertNonmodifiable();
}
void setActiveState(const Coord& xyz, bool on) { BaseLeaf::setActiveState(xyz, on); }
void setActiveState(Index offset, bool on) { BaseLeaf::setActiveState(offset, on); }
void setValueOnly(const Coord&, const ValueType&) { assertNonmodifiable(); }
void setValueOnly(Index, const ValueType&) { assertNonmodifiable(); }
void setValueOff(const Coord& xyz) { BaseLeaf::setValueOff(xyz); }
void setValueOff(Index offset) { BaseLeaf::setValueOff(offset); }
void setValueOff(const Coord&, const ValueType&) { assertNonmodifiable(); }
void setValueOff(Index, const ValueType&) { assertNonmodifiable(); }
void setValueOn(const Coord& xyz) { BaseLeaf::setValueOn(xyz); }
void setValueOn(Index offset) { BaseLeaf::setValueOn(offset); }
void setValueOn(const Coord&, const ValueType&) { assertNonmodifiable(); }
void setValueOn(Index, const ValueType&) { assertNonmodifiable(); }
void setValue(const Coord&, const ValueType&) { assertNonmodifiable(); }
void setValuesOn() { BaseLeaf::setValuesOn(); }
void setValuesOff() { BaseLeaf::setValuesOff(); }
template<typename ModifyOp>
void modifyValue(Index, const ModifyOp&) { assertNonmodifiable(); }
template<typename ModifyOp>
void modifyValue(const Coord&, const ModifyOp&) { assertNonmodifiable(); }
template<typename ModifyOp>
void modifyValueAndActiveState(const Coord&, const ModifyOp&) { assertNonmodifiable(); }
// clipping is not yet supported
void clip(const CoordBBox&, const ValueType& value) { assertNonModifiableUnlessZero(value); }
void fill(const CoordBBox&, const ValueType&, bool);
void fill(const ValueType& value) { assertNonModifiableUnlessZero(value); }
void fill(const ValueType&, bool);
template<typename AccessorT>
void setValueOnlyAndCache(const Coord&, const ValueType&, AccessorT&) {assertNonmodifiable();}
template<typename ModifyOp, typename AccessorT>
void modifyValueAndActiveStateAndCache(const Coord&, const ModifyOp&, AccessorT&) {
assertNonmodifiable();
}
template<typename AccessorT>
void setValueOffAndCache(const Coord&, const ValueType&, AccessorT&) { assertNonmodifiable(); }
template<typename AccessorT>
void setActiveStateAndCache(const Coord& xyz, bool on, AccessorT& parent) {
BaseLeaf::setActiveStateAndCache(xyz, on, parent);
}
void resetBackground(const ValueType&, const ValueType& newBackground) {
assertNonModifiableUnlessZero(newBackground);
}
void signedFloodFill(const ValueType&) { assertNonmodifiable(); }
void signedFloodFill(const ValueType&, const ValueType&) { assertNonmodifiable(); }
void negate() { assertNonmodifiable(); }
friend class ::TestPointDataLeaf;
using ValueOn = typename BaseLeaf::ValueOn;
using ValueOff = typename BaseLeaf::ValueOff;
using ValueAll = typename BaseLeaf::ValueAll;
private:
AttributeSet::UniquePtr mAttributeSet;
uint16_t mVoxelBufferSize = 0;
protected:
using ChildOn = typename BaseLeaf::ChildOn;
using ChildOff = typename BaseLeaf::ChildOff;
using ChildAll = typename BaseLeaf::ChildAll;
using MaskOnIterator = typename NodeMaskType::OnIterator;
using MaskOffIterator = typename NodeMaskType::OffIterator;
using MaskDenseIterator = typename NodeMaskType::DenseIterator;
// During topology-only construction, access is needed
// to protected/private members of other template instances.
template<typename, Index> friend class PointDataLeafNode;
friend class tree::IteratorBase<MaskOnIterator, PointDataLeafNode>;
friend class tree::IteratorBase<MaskOffIterator, PointDataLeafNode>;
friend class tree::IteratorBase<MaskDenseIterator, PointDataLeafNode>;
public:
/// @brief Leaf value voxel iterator
ValueVoxelCIter beginValueVoxel(const Coord& ijk) const;
public:
using ValueOnIter = typename BaseLeaf::template ValueIter<
MaskOnIterator, PointDataLeafNode, const ValueType, ValueOn>;
using ValueOnCIter = typename BaseLeaf::template ValueIter<
MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn>;
using ValueOffIter = typename BaseLeaf::template ValueIter<
MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff>;
using ValueOffCIter = typename BaseLeaf::template ValueIter<
MaskOffIterator,const PointDataLeafNode,const ValueType,ValueOff>;
using ValueAllIter = typename BaseLeaf::template ValueIter<
MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll>;
using ValueAllCIter = typename BaseLeaf::template ValueIter<
MaskDenseIterator,const PointDataLeafNode,const ValueType,ValueAll>;
using ChildOnIter = typename BaseLeaf::template ChildIter<
MaskOnIterator, PointDataLeafNode, ChildOn>;
using ChildOnCIter = typename BaseLeaf::template ChildIter<
MaskOnIterator, const PointDataLeafNode, ChildOn>;
using ChildOffIter = typename BaseLeaf::template ChildIter<
MaskOffIterator, PointDataLeafNode, ChildOff>;
using ChildOffCIter = typename BaseLeaf::template ChildIter<
MaskOffIterator, const PointDataLeafNode, ChildOff>;
using ChildAllIter = typename BaseLeaf::template DenseIter<
PointDataLeafNode, ValueType, ChildAll>;
using ChildAllCIter = typename BaseLeaf::template DenseIter<
const PointDataLeafNode, const ValueType, ChildAll>;
using IndexVoxelIter = IndexIter<ValueVoxelCIter, NullFilter>;
using IndexAllIter = IndexIter<ValueAllCIter, NullFilter>;
using IndexOnIter = IndexIter<ValueOnCIter, NullFilter>;
using IndexOffIter = IndexIter<ValueOffCIter, NullFilter>;
/// @brief Leaf index iterator
IndexAllIter beginIndexAll() const
{
NullFilter filter;
return this->beginIndex<ValueAllCIter, NullFilter>(filter);
}
IndexOnIter beginIndexOn() const
{
NullFilter filter;
return this->beginIndex<ValueOnCIter, NullFilter>(filter);
}
IndexOffIter beginIndexOff() const
{
NullFilter filter;
return this->beginIndex<ValueOffCIter, NullFilter>(filter);
}
template<typename IterT, typename FilterT>
IndexIter<IterT, FilterT> beginIndex(const FilterT& filter) const;
/// @brief Filtered leaf index iterator
template<typename FilterT>
IndexIter<ValueAllCIter, FilterT> beginIndexAll(const FilterT& filter) const
{
return this->beginIndex<ValueAllCIter, FilterT>(filter);
}
template<typename FilterT>
IndexIter<ValueOnCIter, FilterT> beginIndexOn(const FilterT& filter) const
{
return this->beginIndex<ValueOnCIter, FilterT>(filter);
}
template<typename FilterT>
IndexIter<ValueOffCIter, FilterT> beginIndexOff(const FilterT& filter) const
{
return this->beginIndex<ValueOffCIter, FilterT>(filter);
}
/// @brief Leaf index iterator from voxel
IndexVoxelIter beginIndexVoxel(const Coord& ijk) const;
/// @brief Filtered leaf index iterator from voxel
template<typename FilterT>
IndexIter<ValueVoxelCIter, FilterT> beginIndexVoxel(const Coord& ijk, const FilterT& filter) const;
#define VMASK_ this->getValueMask()
ValueOnCIter cbeginValueOn() const { return ValueOnCIter(VMASK_.beginOn(), this); }
ValueOnCIter beginValueOn() const { return ValueOnCIter(VMASK_.beginOn(), this); }
ValueOnIter beginValueOn() { return ValueOnIter(VMASK_.beginOn(), this); }
ValueOffCIter cbeginValueOff() const { return ValueOffCIter(VMASK_.beginOff(), this); }
ValueOffCIter beginValueOff() const { return ValueOffCIter(VMASK_.beginOff(), this); }
ValueOffIter beginValueOff() { return ValueOffIter(VMASK_.beginOff(), this); }
ValueAllCIter cbeginValueAll() const { return ValueAllCIter(VMASK_.beginDense(), this); }
ValueAllCIter beginValueAll() const { return ValueAllCIter(VMASK_.beginDense(), this); }
ValueAllIter beginValueAll() { return ValueAllIter(VMASK_.beginDense(), this); }
ValueOnCIter cendValueOn() const { return ValueOnCIter(VMASK_.endOn(), this); }
ValueOnCIter endValueOn() const { return ValueOnCIter(VMASK_.endOn(), this); }
ValueOnIter endValueOn() { return ValueOnIter(VMASK_.endOn(), this); }
ValueOffCIter cendValueOff() const { return ValueOffCIter(VMASK_.endOff(), this); }
ValueOffCIter endValueOff() const { return ValueOffCIter(VMASK_.endOff(), this); }
ValueOffIter endValueOff() { return ValueOffIter(VMASK_.endOff(), this); }
ValueAllCIter cendValueAll() const { return ValueAllCIter(VMASK_.endDense(), this); }
ValueAllCIter endValueAll() const { return ValueAllCIter(VMASK_.endDense(), this); }
ValueAllIter endValueAll() { return ValueAllIter(VMASK_.endDense(), this); }
ChildOnCIter cbeginChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
ChildOnCIter beginChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
ChildOnIter beginChildOn() { return ChildOnIter(VMASK_.endOn(), this); }
ChildOffCIter cbeginChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
ChildOffCIter beginChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
ChildOffIter beginChildOff() { return ChildOffIter(VMASK_.endOff(), this); }
ChildAllCIter cbeginChildAll() const { return ChildAllCIter(VMASK_.beginDense(), this); }
ChildAllCIter beginChildAll() const { return ChildAllCIter(VMASK_.beginDense(), this); }
ChildAllIter beginChildAll() { return ChildAllIter(VMASK_.beginDense(), this); }
ChildOnCIter cendChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
ChildOnCIter endChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
ChildOnIter endChildOn() { return ChildOnIter(VMASK_.endOn(), this); }
ChildOffCIter cendChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
ChildOffCIter endChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
ChildOffIter endChildOff() { return ChildOffIter(VMASK_.endOff(), this); }
ChildAllCIter cendChildAll() const { return ChildAllCIter(VMASK_.endDense(), this); }
ChildAllCIter endChildAll() const { return ChildAllCIter(VMASK_.endDense(), this); }
ChildAllIter endChildAll() { return ChildAllIter(VMASK_.endDense(), this); }
#undef VMASK_
}; // struct PointDataLeafNode
////////////////////////////////////////
// PointDataLeafNode implementation
template<typename T, Index Log2Dim>
inline AttributeSet::UniquePtr
PointDataLeafNode<T, Log2Dim>::stealAttributeSet()
{
AttributeSet::UniquePtr ptr = std::make_unique<AttributeSet>();
std::swap(ptr, mAttributeSet);
return ptr;
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::initializeAttributes(const Descriptor::Ptr& descriptor, const Index arrayLength,
const AttributeArray::ScopedRegistryLock* lock)
{
if (descriptor->size() != 1 ||
descriptor->find("P") == AttributeSet::INVALID_POS ||
descriptor->valueType(0) != typeNameAsString<Vec3f>())
{
OPENVDB_THROW(IndexError, "Initializing attributes only allowed with one Vec3f position attribute.");
}
mAttributeSet.reset(new AttributeSet(descriptor, arrayLength, lock));
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::clearAttributes(const bool updateValueMask,
const AttributeArray::ScopedRegistryLock* lock)
{
mAttributeSet.reset(new AttributeSet(*mAttributeSet, 0, lock));
// zero voxel values
this->buffer().fill(ValueType(0));
// if updateValueMask, also de-activate all voxels
if (updateValueMask) this->setValuesOff();
}
template<typename T, Index Log2Dim>
inline bool
PointDataLeafNode<T, Log2Dim>::hasAttribute(const size_t pos) const
{
return pos < mAttributeSet->size();
}
template<typename T, Index Log2Dim>
inline bool
PointDataLeafNode<T, Log2Dim>::hasAttribute(const Name& attributeName) const
{
const size_t pos = mAttributeSet->find(attributeName);
return pos != AttributeSet::INVALID_POS;
}
template<typename T, Index Log2Dim>
inline AttributeArray::Ptr
PointDataLeafNode<T, Log2Dim>::appendAttribute( const Descriptor& expected, Descriptor::Ptr& replacement,
const size_t pos, const Index strideOrTotalSize,
const bool constantStride,
const Metadata* metadata,
const AttributeArray::ScopedRegistryLock* lock)
{
return mAttributeSet->appendAttribute(
expected, replacement, pos, strideOrTotalSize, constantStride, metadata, lock);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::dropAttributes(const std::vector<size_t>& pos,
const Descriptor& expected, Descriptor::Ptr& replacement)
{
mAttributeSet->dropAttributes(pos, expected, replacement);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::reorderAttributes(const Descriptor::Ptr& replacement)
{
mAttributeSet->reorderAttributes(replacement);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::renameAttributes(const Descriptor& expected, Descriptor::Ptr& replacement)
{
mAttributeSet->renameAttributes(expected, replacement);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::compactAttributes()
{
for (size_t i = 0; i < mAttributeSet->size(); i++) {
AttributeArray* array = mAttributeSet->get(i);
array->compact();
}
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::replaceAttributeSet(AttributeSet* attributeSet, bool allowMismatchingDescriptors)
{
if (!attributeSet) {
OPENVDB_THROW(ValueError, "Cannot replace with a null attribute set");
}
if (!allowMismatchingDescriptors && mAttributeSet->descriptor() != attributeSet->descriptor()) {
OPENVDB_THROW(ValueError, "Attribute set descriptors are not equal.");
}
mAttributeSet.reset(attributeSet);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::resetDescriptor(const Descriptor::Ptr& replacement)
{
mAttributeSet->resetDescriptor(replacement);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::setOffsets(const std::vector<ValueType>& offsets, const bool updateValueMask)
{
if (offsets.size() != LeafNodeType::NUM_VALUES) {
OPENVDB_THROW(ValueError, "Offset vector size doesn't match number of voxels.")
}
for (Index index = 0; index < offsets.size(); ++index) {
setOffsetOnly(index, offsets[index]);
}
if (updateValueMask) this->updateValueMask();
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::validateOffsets() const
{
// Ensure all of the offset values are monotonically increasing
for (Index index = 1; index < BaseLeaf::SIZE; ++index) {
if (this->getValue(index-1) > this->getValue(index)) {
OPENVDB_THROW(ValueError, "Voxel offset values are not monotonically increasing");
}
}
// Ensure all attribute arrays are of equal length
for (size_t attributeIndex = 1; attributeIndex < mAttributeSet->size(); ++attributeIndex ) {
if (mAttributeSet->getConst(attributeIndex-1)->size() != mAttributeSet->getConst(attributeIndex)->size()) {
OPENVDB_THROW(ValueError, "Attribute arrays have inconsistent length");
}
}
// Ensure the last voxel's offset value matches the size of each attribute array
if (mAttributeSet->size() > 0 && this->getValue(BaseLeaf::SIZE-1) != mAttributeSet->getConst(0)->size()) {
OPENVDB_THROW(ValueError, "Last voxel offset value does not match attribute array length");
}
}
template<typename T, Index Log2Dim>
inline AttributeArray&
PointDataLeafNode<T, Log2Dim>::attributeArray(const size_t pos)
{
if (pos >= mAttributeSet->size()) OPENVDB_THROW(LookupError, "Attribute Out Of Range - " << pos);
return *mAttributeSet->get(pos);
}
template<typename T, Index Log2Dim>
inline const AttributeArray&
PointDataLeafNode<T, Log2Dim>::attributeArray(const size_t pos) const
{
if (pos >= mAttributeSet->size()) OPENVDB_THROW(LookupError, "Attribute Out Of Range - " << pos);
return *mAttributeSet->getConst(pos);
}
template<typename T, Index Log2Dim>
inline const AttributeArray&
PointDataLeafNode<T, Log2Dim>::constAttributeArray(const size_t pos) const
{
return this->attributeArray(pos);
}
template<typename T, Index Log2Dim>
inline AttributeArray&
PointDataLeafNode<T, Log2Dim>::attributeArray(const Name& attributeName)
{
const size_t pos = mAttributeSet->find(attributeName);
if (pos == AttributeSet::INVALID_POS) OPENVDB_THROW(LookupError, "Attribute Not Found - " << attributeName);
return *mAttributeSet->get(pos);
}
template<typename T, Index Log2Dim>
inline const AttributeArray&
PointDataLeafNode<T, Log2Dim>::attributeArray(const Name& attributeName) const
{
const size_t pos = mAttributeSet->find(attributeName);
if (pos == AttributeSet::INVALID_POS) OPENVDB_THROW(LookupError, "Attribute Not Found - " << attributeName);
return *mAttributeSet->getConst(pos);
}
template<typename T, Index Log2Dim>
inline const AttributeArray&
PointDataLeafNode<T, Log2Dim>::constAttributeArray(const Name& attributeName) const
{
return this->attributeArray(attributeName);
}
template<typename T, Index Log2Dim>
inline GroupHandle
PointDataLeafNode<T, Log2Dim>::groupHandle(const AttributeSet::Descriptor::GroupIndex& index) const
{
const AttributeArray& array = this->attributeArray(index.first);
assert(isGroup(array));
const GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
return GroupHandle(groupArray, index.second);
}
template<typename T, Index Log2Dim>
inline GroupHandle
PointDataLeafNode<T, Log2Dim>::groupHandle(const Name& name) const
{
const AttributeSet::Descriptor::GroupIndex index = this->attributeSet().groupIndex(name);
return this->groupHandle(index);
}
template<typename T, Index Log2Dim>
inline GroupWriteHandle
PointDataLeafNode<T, Log2Dim>::groupWriteHandle(const AttributeSet::Descriptor::GroupIndex& index)
{
AttributeArray& array = this->attributeArray(index.first);
assert(isGroup(array));
GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
return GroupWriteHandle(groupArray, index.second);
}
template<typename T, Index Log2Dim>
inline GroupWriteHandle
PointDataLeafNode<T, Log2Dim>::groupWriteHandle(const Name& name)
{
const AttributeSet::Descriptor::GroupIndex index = this->attributeSet().groupIndex(name);
return this->groupWriteHandle(index);
}
template<typename T, Index Log2Dim>
template<typename ValueIterT, typename FilterT>
inline IndexIter<ValueIterT, FilterT>
PointDataLeafNode<T, Log2Dim>::beginIndex(const FilterT& filter) const
{
// generate no-op iterator if filter evaluates no indices
if (filter.state() == index::NONE) {
return IndexIter<ValueIterT, FilterT>(ValueIterT(), filter);
}
// copy filter to ensure thread-safety
FilterT newFilter(filter);
newFilter.reset(*this);
using IterTraitsT = tree::IterTraits<LeafNodeType, ValueIterT>;
// construct the value iterator and reset the filter to use this leaf
ValueIterT valueIter = IterTraitsT::begin(*this);
return IndexIter<ValueIterT, FilterT>(valueIter, newFilter);
}
template<typename T, Index Log2Dim>
inline ValueVoxelCIter
PointDataLeafNode<T, Log2Dim>::beginValueVoxel(const Coord& ijk) const
{
const Index index = LeafNodeType::coordToOffset(ijk);
assert(index < BaseLeaf::SIZE);
const ValueType end = this->getValue(index);
const ValueType start = (index == 0) ? ValueType(0) : this->getValue(index - 1);
return ValueVoxelCIter(start, end);
}
template<typename T, Index Log2Dim>
inline typename PointDataLeafNode<T, Log2Dim>::IndexVoxelIter
PointDataLeafNode<T, Log2Dim>::beginIndexVoxel(const Coord& ijk) const
{
ValueVoxelCIter iter = this->beginValueVoxel(ijk);
return IndexVoxelIter(iter, NullFilter());
}
template<typename T, Index Log2Dim>
template<typename FilterT>
inline IndexIter<ValueVoxelCIter, FilterT>
PointDataLeafNode<T, Log2Dim>::beginIndexVoxel(const Coord& ijk, const FilterT& filter) const
{
ValueVoxelCIter iter = this->beginValueVoxel(ijk);
FilterT newFilter(filter);
newFilter.reset(*this);
return IndexIter<ValueVoxelCIter, FilterT>(iter, newFilter);
}
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::pointCount() const
{
return this->getLastValue();
}
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::onPointCount() const
{
if (this->isEmpty()) return 0;
else if (this->isDense()) return this->pointCount();
return iterCount(this->beginIndexOn());
}
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::offPointCount() const
{
if (this->isEmpty()) return this->pointCount();
else if (this->isDense()) return 0;
return iterCount(this->beginIndexOff());
}
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::groupPointCount(const Name& groupName) const
{
if (!this->attributeSet().descriptor().hasGroup(groupName)) {
return Index64(0);
}
GroupFilter filter(groupName, this->attributeSet());
if (filter.state() == index::ALL) {
return this->pointCount();
} else {
return iterCount(this->beginIndexAll(filter));
}
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::updateValueMask()
{
ValueType start = 0, end = 0;
for (Index n = 0; n < LeafNodeType::NUM_VALUES; n++) {
end = this->getValue(n);
this->setValueMask(n, (end - start) > 0);
start = end;
}
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::setOffsetOn(Index offset, const ValueType& val)
{
this->buffer().setValue(offset, val);
this->setValueMaskOn(offset);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::setOffsetOnly(Index offset, const ValueType& val)
{
this->buffer().setValue(offset, val);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::readTopology(std::istream& is, bool fromHalf)
{
BaseLeaf::readTopology(is, fromHalf);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::writeTopology(std::ostream& os, bool toHalf) const
{
BaseLeaf::writeTopology(os, toHalf);
}
template<typename T, Index Log2Dim>
inline Index
PointDataLeafNode<T, Log2Dim>::buffers() const
{
return Index( /*voxel buffer sizes*/ 1 +
/*voxel buffers*/ 1 +
/*attribute metadata*/ 1 +
/*attribute uniform values*/ mAttributeSet->size() +
/*attribute buffers*/ mAttributeSet->size() +
/*cleanup*/ 1);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::readBuffers(std::istream& is, bool fromHalf)
{
this->readBuffers(is, CoordBBox::inf(), fromHalf);
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::readBuffers(std::istream& is, const CoordBBox& /*bbox*/, bool fromHalf)
{
struct Local
{
static void destroyPagedStream(const io::StreamMetadata::AuxDataMap& auxData, const Index index)
{
// if paged stream exists, delete it
std::string key("paged:" + std::to_string(index));
auto it = auxData.find(key);
if (it != auxData.end()) {
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(it);
}
}
static compression::PagedInputStream& getOrInsertPagedStream( const io::StreamMetadata::AuxDataMap& auxData,
const Index index)
{
std::string key("paged:" + std::to_string(index));
auto it = auxData.find(key);
if (it != auxData.end()) {
return *(std::any_cast<compression::PagedInputStream::Ptr>(it->second));
}
else {
compression::PagedInputStream::Ptr pagedStream = std::make_shared<compression::PagedInputStream>();
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[key] = pagedStream;
return *pagedStream;
}
}
static bool hasMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string matchingKey("hasMatchingDescriptor");
auto itMatching = auxData.find(matchingKey);
return itMatching != auxData.end();
}
static void clearMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string matchingKey("hasMatchingDescriptor");
std::string descriptorKey("descriptorPtr");
auto itMatching = auxData.find(matchingKey);
auto itDescriptor = auxData.find(descriptorKey);
if (itMatching != auxData.end()) (const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
if (itDescriptor != auxData.end()) (const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
}
static void insertDescriptor( const io::StreamMetadata::AuxDataMap& auxData,
const Descriptor::Ptr descriptor)
{
std::string descriptorKey("descriptorPtr");
std::string matchingKey("hasMatchingDescriptor");
auto itMatching = auxData.find(matchingKey);
if (itMatching == auxData.end()) {
// if matching bool is not found, insert "true" and the descriptor
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = true;
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[descriptorKey] = descriptor;
}
}
static AttributeSet::Descriptor::Ptr retrieveMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string descriptorKey("descriptorPtr");
auto itDescriptor = auxData.find(descriptorKey);
assert(itDescriptor != auxData.end());
const Descriptor::Ptr descriptor = std::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
return descriptor;
}
};
const io::StreamMetadata::Ptr meta = io::getStreamMetadataPtr(is);
if (!meta) {
OPENVDB_THROW(IoError, "Cannot read in a PointDataLeaf without StreamMetadata.");
}
const Index pass(static_cast<uint16_t>(meta->pass()));
const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
const Index attributes = (maximumPass - 4) / 2;
if (pass == 0) {
// pass 0 - voxel data sizes
is.read(reinterpret_cast<char*>(&mVoxelBufferSize), sizeof(uint16_t));
Local::clearMatchingDescriptor(meta->auxData());
}
else if (pass == 1) {
// pass 1 - descriptor and attribute metadata
if (Local::hasMatchingDescriptor(meta->auxData())) {
AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
mAttributeSet->resetDescriptor(descriptor, /*allowMismatchingDescriptors=*/true);
}
else {
uint8_t header;
is.read(reinterpret_cast<char*>(&header), sizeof(uint8_t));
mAttributeSet->readDescriptor(is);
if (header & uint8_t(1)) {
AttributeSet::DescriptorPtr descriptor = mAttributeSet->descriptorPtr();
Local::insertDescriptor(meta->auxData(), descriptor);
}
// a forwards-compatibility mechanism for future use,
// if a 0x2 bit is set, read and skip over a specific number of bytes
if (header & uint8_t(2)) {
uint64_t bytesToSkip;
is.read(reinterpret_cast<char*>(&bytesToSkip), sizeof(uint64_t));
if (bytesToSkip > uint64_t(0)) {
auto metadata = io::getStreamMetadataPtr(is);
if (metadata && metadata->seekable()) {
is.seekg(bytesToSkip, std::ios_base::cur);
}
else {
std::vector<uint8_t> tempData(bytesToSkip);
is.read(reinterpret_cast<char*>(&tempData[0]), bytesToSkip);
}
}
}
// this reader is only able to read headers with 0x1 and 0x2 bits set
if (header > uint8_t(3)) {
OPENVDB_THROW(IoError, "Unrecognised header flags in PointDataLeafNode");
}
}
mAttributeSet->readMetadata(is);
}
else if (pass < (attributes + 2)) {
// pass 2...n+2 - attribute uniform values
const size_t attributeIndex = pass - 2;
AttributeArray* array = attributeIndex < mAttributeSet->size() ?
mAttributeSet->get(attributeIndex) : nullptr;
if (array) {
compression::PagedInputStream& pagedStream =
Local::getOrInsertPagedStream(meta->auxData(), static_cast< Index >(attributeIndex));
pagedStream.setInputStream(is);
pagedStream.setSizeOnly(true);
array->readPagedBuffers(pagedStream);
}
}
else if (pass == attributes + 2) {
// pass n+2 - voxel data
const Index passValue(meta->pass());
// StreamMetadata pass variable used to temporarily store voxel buffer size
io::StreamMetadata& nonConstMeta = const_cast< io::StreamMetadata&>(*meta);
nonConstMeta.setPass(mVoxelBufferSize);
// readBuffers() calls readCompressedValues specialization above
BaseLeaf::readBuffers(is, fromHalf);
// pass now reset to original value
nonConstMeta.setPass(passValue);
}
else if (pass < (attributes*2 + 3)) {
// pass n+2..2n+2 - attribute buffers
const Index attributeIndex = pass - attributes - 3;
AttributeArray* array = attributeIndex < mAttributeSet->size() ?
mAttributeSet->get(attributeIndex) : nullptr;
if (array) {
compression::PagedInputStream& pagedStream =
Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
pagedStream.setInputStream(is);
pagedStream.setSizeOnly(false);
array->readPagedBuffers(pagedStream);
}
// cleanup paged stream reference in auxiliary metadata
if (pass > attributes + 3) {
Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
}
}
else if (pass < buffers()) {
// pass 2n+3 - cleanup last paged stream
const Index attributeIndex = pass - attributes - 4;
Local::destroyPagedStream(meta->auxData(), attributeIndex);
}
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::writeBuffers(std::ostream& os, bool toHalf) const
{
struct Local
{
static void destroyPagedStream(const io::StreamMetadata::AuxDataMap& auxData, const Index index)
{
// if paged stream exists, flush and delete it
std::string key("paged:" + std::to_string(index));
auto it = auxData.find(key);
if (it != auxData.end()) {
compression::PagedOutputStream& stream = *(std::any_cast<compression::PagedOutputStream::Ptr>(it->second));
stream.flush();
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(it);
}
}
static compression::PagedOutputStream& getOrInsertPagedStream( const io::StreamMetadata::AuxDataMap& auxData,
const Index index)
{
std::string key("paged:" + std::to_string(index));
auto it = auxData.find(key);
if (it != auxData.end()) {
return *(std::any_cast<compression::PagedOutputStream::Ptr>(it->second));
}
else {
compression::PagedOutputStream::Ptr pagedStream = std::make_shared<compression::PagedOutputStream>();
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[key] = pagedStream;
return *pagedStream;
}
}
static void insertDescriptor( const io::StreamMetadata::AuxDataMap& auxData,
const Descriptor::Ptr descriptor)
{
std::string descriptorKey("descriptorPtr");
std::string matchingKey("hasMatchingDescriptor");
auto itMatching = auxData.find(matchingKey);
auto itDescriptor = auxData.find(descriptorKey);
if (itMatching == auxData.end()) {
// if matching bool is not found, insert "true" and the descriptor
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = true;
assert(itDescriptor == auxData.end());
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[descriptorKey] = descriptor;
}
else {
// if matching bool is found and is false, early exit (a previous descriptor did not match)
bool matching = std::any_cast<bool>(itMatching->second);
if (!matching) return;
assert(itDescriptor != auxData.end());
// if matching bool is true, check whether the existing descriptor matches the current one and set
// matching bool to false if not
const Descriptor::Ptr existingDescriptor = std::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
if (*existingDescriptor != *descriptor) {
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = false;
}
}
}
static bool hasMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string matchingKey("hasMatchingDescriptor");
auto itMatching = auxData.find(matchingKey);
// if matching key is not found, no matching descriptor
if (itMatching == auxData.end()) return false;
// if matching key is found and is false, no matching descriptor
if (!std::any_cast<bool>(itMatching->second)) return false;
return true;
}
static AttributeSet::Descriptor::Ptr retrieveMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string descriptorKey("descriptorPtr");
auto itDescriptor = auxData.find(descriptorKey);
// if matching key is true, however descriptor is not found, it has already been retrieved
if (itDescriptor == auxData.end()) return nullptr;
// otherwise remove it and return it
const Descriptor::Ptr descriptor = std::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
(const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
return descriptor;
}
static void clearMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
{
std::string matchingKey("hasMatchingDescriptor");
std::string descriptorKey("descriptorPtr");
auto itMatching = auxData.find(matchingKey);
auto itDescriptor = auxData.find(descriptorKey);
if (itMatching != auxData.end()) (const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
if (itDescriptor != auxData.end()) (const_cast< io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
}
};
const io::StreamMetadata::Ptr meta = io::getStreamMetadataPtr(os);
if (!meta) {
OPENVDB_THROW(IoError, "Cannot write out a PointDataLeaf without StreamMetadata.");
}
const Index pass(static_cast<uint16_t>(meta->pass()));
// leaf traversal analysis deduces the number of passes to perform for this leaf
// then updates the leaf traversal value to ensure all passes will be written
if (meta->countingPasses()) {
const Index requiredPasses = this->buffers();
if (requiredPasses > pass) {
meta->setPass(requiredPasses);
}
return;
}
const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
const Index attributes = (maximumPass - 4) / 2;
if (pass == 0) {
// pass 0 - voxel data sizes
io::writeCompressedValuesSize(os, this->buffer().data(), SIZE);
// track if descriptor is shared or not
Local::insertDescriptor(meta->auxData(), mAttributeSet->descriptorPtr());
}
else if (pass == 1) {
// pass 1 - descriptor and attribute metadata
bool matchingDescriptor = Local::hasMatchingDescriptor(meta->auxData());
if (matchingDescriptor) {
AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
if (descriptor) {
// write a header to indicate a shared descriptor
uint8_t header(1);
os.write(reinterpret_cast<const char*>(&header), sizeof(uint8_t));
mAttributeSet->writeDescriptor(os, /*transient=*/false);
}
}
else {
// write a header to indicate a non-shared descriptor
uint8_t header(0);
os.write(reinterpret_cast<const char*>(&header), sizeof(uint8_t));
mAttributeSet->writeDescriptor(os, /*transient=*/false);
}
mAttributeSet->writeMetadata(os, /*transient=*/false, /*paged=*/true);
}
else if (pass < attributes + 2) {
// pass 2...n+2 - attribute buffer sizes
const Index attributeIndex = pass - 2;
// destroy previous paged stream
if (pass > 2) {
Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
}
const AttributeArray* array = attributeIndex < mAttributeSet->size() ?
mAttributeSet->getConst(attributeIndex) : nullptr;
if (array) {
compression::PagedOutputStream& pagedStream =
Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
pagedStream.setOutputStream(os);
pagedStream.setSizeOnly(true);
array->writePagedBuffers(pagedStream, /*outputTransient*/false);
}
}
else if (pass == attributes + 2) {
const Index attributeIndex = pass - 3;
Local::destroyPagedStream(meta->auxData(), attributeIndex);
// pass n+2 - voxel data
BaseLeaf::writeBuffers(os, toHalf);
}
else if (pass < (attributes*2 + 3)) {
// pass n+3...2n+3 - attribute buffers
const Index attributeIndex = pass - attributes - 3;
// destroy previous paged stream
if (pass > attributes + 2) {
Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
}
const AttributeArray* array = attributeIndex < mAttributeSet->size() ?
mAttributeSet->getConst(attributeIndex) : nullptr;
if (array) {
compression::PagedOutputStream& pagedStream =
Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
pagedStream.setOutputStream(os);
pagedStream.setSizeOnly(false);
array->writePagedBuffers(pagedStream, /*outputTransient*/false);
}
}
else if (pass < buffers()) {
Local::clearMatchingDescriptor(meta->auxData());
// pass 2n+3 - cleanup last paged stream
const Index attributeIndex = pass - attributes - 4;
Local::destroyPagedStream(meta->auxData(), attributeIndex);
}
}
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::memUsage() const
{
return BaseLeaf::memUsage() + mAttributeSet->memUsage();
}
#if OPENVDB_ABI_VERSION_NUMBER >= 10
template<typename T, Index Log2Dim>
inline Index64
PointDataLeafNode<T, Log2Dim>::memUsageIfLoaded() const
{
return BaseLeaf::memUsageIfLoaded() + mAttributeSet->memUsageIfLoaded();
}
#endif
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const
{
BaseLeaf::evalActiveBoundingBox(bbox, visitVoxels);
}
template<typename T, Index Log2Dim>
inline CoordBBox
PointDataLeafNode<T, Log2Dim>::getNodeBoundingBox() const
{
return BaseLeaf::getNodeBoundingBox();
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
{
if (!this->allocate()) return;
this->assertNonModifiableUnlessZero(value);
// active state is permitted to be updated
for (Int32 x = bbox.min().x(); x <= bbox.max().x(); ++x) {
const Index offsetX = (x & (DIM-1u)) << 2*Log2Dim;
for (Int32 y = bbox.min().y(); y <= bbox.max().y(); ++y) {
const Index offsetXY = offsetX + ((y & (DIM-1u)) << Log2Dim);
for (Int32 z = bbox.min().z(); z <= bbox.max().z(); ++z) {
const Index offset = offsetXY + (z & (DIM-1u));
this->setValueMask(offset, active);
}
}
}
}
template<typename T, Index Log2Dim>
inline void
PointDataLeafNode<T, Log2Dim>::fill(const ValueType& value, bool active)
{
this->assertNonModifiableUnlessZero(value);
// active state is permitted to be updated
if (active) this->setValuesOn();
else this->setValuesOff();
}
////////////////////////////////////////
template <typename PointDataTreeT>
inline AttributeSet::Descriptor::Ptr
makeDescriptorUnique(PointDataTreeT& tree)
{
auto leafIter = tree.beginLeaf();
if (!leafIter) return nullptr;
const AttributeSet::Descriptor& descriptor = leafIter->attributeSet().descriptor();
auto newDescriptor = std::make_shared<AttributeSet::Descriptor>(descriptor);
for (; leafIter; ++leafIter) {
leafIter->resetDescriptor(newDescriptor);
}
return newDescriptor;
}
template <typename PointDataTreeT>
inline void
setStreamingMode(PointDataTreeT& tree, bool on)
{
auto leafIter = tree.beginLeaf();
for (; leafIter; ++leafIter) {
for (size_t i = 0; i < leafIter->attributeSet().size(); i++) {
leafIter->attributeArray(i).setStreaming(on);
}
}
}
template <typename PointDataTreeT>
inline void
prefetch(PointDataTreeT& tree, bool position, bool otherAttributes)
{
// NOTE: the following is intentionally not multi-threaded, as the I/O
// is faster if done in the order in which it is stored in the file
auto leaf = tree.cbeginLeaf();
if (!leaf) return;
const auto& attributeSet = leaf->attributeSet();
// pre-fetch leaf data
for ( ; leaf; ++leaf) {
leaf->buffer().data();
}
// pre-fetch position attribute data (position will typically have index 0)
size_t positionIndex = attributeSet.find("P");
if (position && positionIndex != AttributeSet::INVALID_POS) {
for (leaf = tree.cbeginLeaf(); leaf; ++leaf) {
assert(leaf->hasAttribute(positionIndex));
leaf->constAttributeArray(positionIndex).loadData();
}
}
// pre-fetch other attribute data
if (otherAttributes) {
const size_t attributes = attributeSet.size();
for (size_t attributeIndex = 0; attributeIndex < attributes; attributeIndex++) {
if (attributeIndex == positionIndex) continue;
for (leaf = tree.cbeginLeaf(); leaf; ++leaf) {
assert(leaf->hasAttribute(attributeIndex));
leaf->constAttributeArray(attributeIndex).loadData();
}
}
}
}
namespace internal {
/// @brief Global registration of point data-related types
/// @note This is called from @c openvdb::initialize, so there is
/// no need to call it directly.
void initialize();
/// @brief Global deregistration of point data-related types
/// @note This is called from @c openvdb::uninitialize, so there is
/// no need to call it directly.
void uninitialize();
/// @brief Recursive node chain which generates a openvdb::TypeList value
/// converted types of nodes to PointDataGrid nodes of the same configuration,
/// rooted at RootNodeType in reverse order, from LeafNode to RootNode.
/// See also TreeConverter<>.
template<typename HeadT, int HeadLevel>
struct PointDataNodeChain
{
using SubtreeT = typename PointDataNodeChain<typename HeadT::ChildNodeType, HeadLevel-1>::Type;
using RootNodeT = tree::RootNode<typename SubtreeT::Back>;
using Type = typename SubtreeT::template Append<RootNodeT>;
};
// Specialization for internal nodes which require their embedded child type to
// be switched
template <typename ChildT, Index Log2Dim, int HeadLevel>
struct PointDataNodeChain<tree::InternalNode<ChildT, Log2Dim>, HeadLevel>
{
using SubtreeT = typename PointDataNodeChain<ChildT, HeadLevel-1>::Type;
using InternalNodeT = tree::InternalNode<typename SubtreeT::Back, Log2Dim>;
using Type = typename SubtreeT::template Append<InternalNodeT>;
};
// Specialization for the last internal node of a node chain, expected
// to be templated on a leaf node
template <typename ChildT, Index Log2Dim>
struct PointDataNodeChain<tree::InternalNode<ChildT, Log2Dim>, /*HeadLevel=*/1>
{
using LeafNodeT = PointDataLeafNode<PointDataIndex32, ChildT::LOG2DIM>;
using InternalNodeT = tree::InternalNode<LeafNodeT, Log2Dim>;
using Type = TypeList<LeafNodeT, InternalNodeT>;
};
} // namespace internal
/// @brief 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
template <typename TreeType>
struct TreeConverter {
using RootNodeT = typename TreeType::RootNodeType;
using NodeChainT = typename internal::PointDataNodeChain<RootNodeT, RootNodeT::LEVEL>::Type;
using Type = tree::Tree<typename NodeChainT::Back>;
};
} // namespace points
////////////////////////////////////////
namespace tree
{
/// Helper metafunction used to implement LeafNode::SameConfiguration
/// (which, as an inner class, can't be independently specialized)
template<Index Dim1, typename T2>
struct SameLeafConfig<Dim1, points::PointDataLeafNode<T2, Dim1>> { static const bool value = true; };
} // namespace tree
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
AttributeArray.h
Attribute Array storage templated on type and compression codec.
AttributeArrayString.h
Attribute array storage for string data using Descriptor Metadata.
AttributeGroup.h
Attribute Group access and filtering for iteration.
AttributeSet.h
Set of Attribute Arrays which tracks metadata about each array.
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Grid.h
LeafNode.h
OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition Platform.h:141
OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition Platform.h:140
VMASK_
#define VMASK_
Definition PointDataGrid.h:703
PointIndexGrid.h
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
StreamCompression.h
Convenience wrappers to using Blosc and reading and writing of Paged data.
Tree.h
openvdb::v11_0::Grid
Container class that associates a tree with a transform and metadata.
Definition Grid.h:571
openvdb::v11_0::IndexError
Definition Exceptions.h:57
openvdb::v11_0::IoError
Definition Exceptions.h:58
openvdb::v11_0::LookupError
Definition Exceptions.h:60
openvdb::v11_0::Metadata
Base class for storing metadata information in a grid.
Definition Metadata.h:24
openvdb::v11_0::PartialCreate
Tag dispatch class that distinguishes constructors during file input.
Definition Types.h:689
openvdb::v11_0::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition Types.h:683
openvdb::v11_0::ValueError
Definition Exceptions.h:65
openvdb::v11_0::compression::PagedInputStream
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition StreamCompression.h:207
openvdb::v11_0::compression::PagedInputStream::setSizeOnly
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only reading size data.
Definition StreamCompression.h:216
openvdb::v11_0::compression::PagedInputStream::setInputStream
void setInputStream(std::istream &is)
Definition StreamCompression.h:221
openvdb::v11_0::compression::PagedInputStream::Ptr
std::shared_ptr< PagedInputStream > Ptr
Definition StreamCompression.h:209
openvdb::v11_0::compression::PagedOutputStream
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition StreamCompression.h:244
openvdb::v11_0::compression::PagedOutputStream::setSizeOnly
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only writing size data.
Definition StreamCompression.h:253
openvdb::v11_0::compression::PagedOutputStream::setOutputStream
void setOutputStream(std::ostream &os)
Definition StreamCompression.h:258
openvdb::v11_0::compression::PagedOutputStream::Ptr
std::shared_ptr< PagedOutputStream > Ptr
Definition StreamCompression.h:246
openvdb::v11_0::compression::PagedOutputStream::flush
void flush()
Manually flushes the current page to disk if non-zero.
openvdb::v11_0::io::StreamMetadata
Container for metadata describing how to unserialize grids from and/or serialize grids to a stream (w...
Definition io.h:31
openvdb::v11_0::io::StreamMetadata::AuxDataMap
std::map< std::string, std::any > AuxDataMap
Definition io.h:92
openvdb::v11_0::io::StreamMetadata::Ptr
SharedPtr< StreamMetadata > Ptr
Definition io.h:33
openvdb::v11_0::io::StreamMetadata::setPass
void setPass(uint32_t)
openvdb::v11_0::math::CoordBBox
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:251
openvdb::v11_0::math::CoordBBox::min
const Coord & min() const
Definition Coord.h:323
openvdb::v11_0::math::CoordBBox::max
const Coord & max() const
Definition Coord.h:324
openvdb::v11_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
openvdb::v11_0::math::Coord::y
Int32 y() const
Definition Coord.h:131
openvdb::v11_0::math::Coord::x
Int32 x() const
Definition Coord.h:130
openvdb::v11_0::math::Coord::z
Int32 z() const
Definition Coord.h:132
openvdb::v11_0::points::AttributeArray::ScopedRegistryLock
Definition AttributeArray.h:119
openvdb::v11_0::points::AttributeArray
Base class for storing attribute data.
Definition AttributeArray.h:93
openvdb::v11_0::points::AttributeArray::Ptr
std::shared_ptr< AttributeArray > Ptr
Definition AttributeArray.h:125
openvdb::v11_0::points::AttributeArray::size
virtual Index size() const =0
openvdb::v11_0::points::AttributeArray::compact
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
openvdb::v11_0::points::AttributeArray::readPagedBuffers
virtual void readPagedBuffers(compression::PagedInputStream &)=0
Read attribute buffers from a paged stream.
openvdb::v11_0::points::AttributeArray::writePagedBuffers
virtual void writePagedBuffers(compression::PagedOutputStream &, bool outputTransient) const =0
openvdb::v11_0::points::AttributeSet
Ordered collection of uniquely-named attribute arrays.
Definition AttributeSet.h:39
openvdb::v11_0::points::AttributeSet::descriptor
Descriptor & descriptor()
Return a reference to this attribute set's descriptor, which might be shared with other sets.
Definition AttributeSet.h:102
openvdb::v11_0::points::AttributeSet::UniquePtr
std::unique_ptr< AttributeSet > UniquePtr
Definition AttributeSet.h:45
openvdb::v11_0::points::AttributeSet::DescriptorPtr
std::shared_ptr< Descriptor > DescriptorPtr
Definition AttributeSet.h:49
openvdb::v11_0::points::GroupFilter
Index filtering on group membership.
Definition AttributeGroup.h:135
openvdb::v11_0::points::GroupFilter::state
static index::State state()
Definition AttributeGroup.h:145
openvdb::v11_0::points::GroupHandle
Definition AttributeGroup.h:73
openvdb::v11_0::points::GroupWriteHandle
Definition AttributeGroup.h:102
openvdb::v11_0::points::IndexIter
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Definition IndexIterator.h:140
openvdb::v11_0::points::NullFilter
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:51
openvdb::v11_0::points::PointDataLeafNode
Definition PointDataGrid.h:239
openvdb::v11_0::points::PointDataLeafNode::cbeginChildOn
ChildOnCIter cbeginChildOn() const
Definition PointDataGrid.h:724
openvdb::v11_0::points::PointDataLeafNode::setValueOn
void setValueOn(Index offset)
Definition PointDataGrid.h:545
openvdb::v11_0::points::PointDataLeafNode::setValueOff
void setValueOff(const Coord &, const ValueType &)
Definition PointDataGrid.h:541
openvdb::v11_0::points::PointDataLeafNode::beginChildOn
ChildOnCIter beginChildOn() const
Definition PointDataGrid.h:725
openvdb::v11_0::points::PointDataLeafNode::beginChildOn
ChildOnIter beginChildOn()
Definition PointDataGrid.h:726
openvdb::v11_0::points::PointDataLeafNode::setActiveStateAndCache
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &parent)
Definition PointDataGrid.h:583
openvdb::v11_0::points::PointDataLeafNode::endValueOn
ValueOnIter endValueOn()
Definition PointDataGrid.h:716
openvdb::v11_0::points::PointDataLeafNode::appendAttribute
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.
Definition PointDataGrid.h:807
openvdb::v11_0::points::PointDataLeafNode::touchLeaf
PointDataLeafNode * touchLeaf(const Coord &)
Return a pointer to this node.
Definition PointDataGrid.h:458
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const tools::PointIndexLeafNode< OtherValueType, Log2Dim > &other)
Definition PointDataGrid.h:296
openvdb::v11_0::points::PointDataLeafNode::cbeginValueOff
ValueOffCIter cbeginValueOff() const
Definition PointDataGrid.h:707
openvdb::v11_0::points::PointDataLeafNode::ChildOnIter
typename BaseLeaf::template ChildIter< MaskOnIterator, PointDataLeafNode, ChildOn > ChildOnIter
Definition PointDataGrid.h:642
openvdb::v11_0::points::PointDataLeafNode::touchLeafAndCache
PointDataLeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Definition PointDataGrid.h:460
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const PointDataLeafNode &other, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Definition PointDataGrid.h:286
openvdb::v11_0::points::PointDataLeafNode::operator==
bool operator==(const PointDataLeafNode &other) const
Definition PointDataGrid.h:445
openvdb::v11_0::points::PointDataLeafNode::hasSameTopology
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...
Definition PointDataGrid.h:439
openvdb::v11_0::points::PointDataLeafNode::endChildOn
ChildOnIter endChildOn()
Definition PointDataGrid.h:736
openvdb::v11_0::points::PointDataLeafNode::endValueAll
ValueAllIter endValueAll()
Definition PointDataGrid.h:722
openvdb::v11_0::points::PointDataLeafNode::modifyValue
void modifyValue(Index, const ModifyOp &)
Definition PointDataGrid.h:556
openvdb::v11_0::points::PointDataLeafNode::setValueOn
void setValueOn(Index, const ValueType &)
Definition PointDataGrid.h:548
openvdb::v11_0::points::PointDataLeafNode::setValuesOff
void setValuesOff()
Definition PointDataGrid.h:553
openvdb::v11_0::points::PointDataLeafNode::endValueAll
ValueAllCIter endValueAll() const
Definition PointDataGrid.h:721
openvdb::v11_0::points::PointDataLeafNode::probeLeaf
const PointDataLeafNode * probeLeaf(const Coord &) const
Definition PointDataGrid.h:482
openvdb::v11_0::points::PointDataLeafNode::endChildOff
ChildOffCIter endChildOff() const
Definition PointDataGrid.h:738
openvdb::v11_0::points::PointDataLeafNode::setValueOff
void setValueOff(Index, const ValueType &)
Definition PointDataGrid.h:542
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(PartialCreate, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Definition PointDataGrid.h:314
openvdb::v11_0::points::PointDataLeafNode::cbeginValueAll
ValueAllCIter cbeginValueAll() const
Definition PointDataGrid.h:710
openvdb::v11_0::points::PointDataLeafNode::ChildOff
typename BaseLeaf::ChildOff ChildOff
Definition PointDataGrid.h:608
openvdb::v11_0::points::PointDataLeafNode::probeConstLeaf
const PointDataLeafNode * probeConstLeaf(const Coord &) const
Return a const pointer to this node.
Definition PointDataGrid.h:477
openvdb::v11_0::points::PointDataLeafNode::setValueOnly
void setValueOnly(Index, const ValueType &)
Definition PointDataGrid.h:536
openvdb::v11_0::points::PointDataLeafNode::Ptr
std::shared_ptr< PointDataLeafNode > Ptr
Definition PointDataGrid.h:243
openvdb::v11_0::points::PointDataLeafNode::beginIndexAll
IndexAllIter beginIndexAll() const
Leaf index iterator.
Definition PointDataGrid.h:660
openvdb::v11_0::points::PointDataLeafNode::beginValueOn
ValueOnCIter beginValueOn() const
Definition PointDataGrid.h:705
openvdb::v11_0::points::PointDataLeafNode::ChildOn
typename BaseLeaf::ChildOn ChildOn
Definition PointDataGrid.h:607
openvdb::v11_0::points::PointDataLeafNode::signedFloodFill
void signedFloodFill(const ValueType &, const ValueType &)
Definition PointDataGrid.h:592
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const PointDataLeafNode &other)
Construct using deep copy of other PointDataLeafNode.
Definition PointDataGrid.h:274
openvdb::v11_0::points::PointDataLeafNode::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &, const ModifyOp &)
Definition PointDataGrid.h:562
openvdb::v11_0::points::PointDataLeafNode::ValueAllIter
typename BaseLeaf::template ValueIter< MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll > ValueAllIter
Definition PointDataGrid.h:638
openvdb::v11_0::points::PointDataLeafNode::ChildAll
typename BaseLeaf::ChildAll ChildAll
Definition PointDataGrid.h:609
openvdb::v11_0::points::PointDataLeafNode::beginIndex
IndexIter< IterT, FilterT > beginIndex(const FilterT &filter) const
openvdb::v11_0::points::PointDataLeafNode::ValueOffIter
typename BaseLeaf::template ValueIter< MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff > ValueOffIter
Definition PointDataGrid.h:634
openvdb::v11_0::points::PointDataLeafNode::cendValueOn
ValueOnCIter cendValueOn() const
Definition PointDataGrid.h:714
openvdb::v11_0::points::PointDataLeafNode::beginValueOff
ValueOffCIter beginValueOff() const
Definition PointDataGrid.h:708
openvdb::v11_0::points::PointDataLeafNode::resetDescriptor
void resetDescriptor(const Descriptor::Ptr &replacement)
Replace the descriptor with a new one The new Descriptor must exactly match the old one.
Definition PointDataGrid.h:866
openvdb::v11_0::points::PointDataLeafNode::beginIndexOff
IndexOffIter beginIndexOff() const
Definition PointDataGrid.h:670
openvdb::v11_0::points::PointDataLeafNode::cbeginChildAll
ChildAllCIter cbeginChildAll() const
Definition PointDataGrid.h:730
openvdb::v11_0::points::PointDataLeafNode::endChildOff
ChildOffIter endChildOff()
Definition PointDataGrid.h:739
openvdb::v11_0::points::PointDataLeafNode::modifyValueAndActiveStateAndCache
void modifyValueAndActiveStateAndCache(const Coord &, const ModifyOp &, AccessorT &)
Definition PointDataGrid.h:575
openvdb::v11_0::points::PointDataLeafNode::setValueOnly
void setValueOnly(const Coord &, const ValueType &)
Definition PointDataGrid.h:535
openvdb::v11_0::points::PointDataLeafNode::beginChildAll
ChildAllIter beginChildAll()
Definition PointDataGrid.h:732
openvdb::v11_0::points::PointDataLeafNode::renameAttributes
void renameAttributes(const Descriptor &expected, Descriptor::Ptr &replacement)
Rename attributes in attribute set (order must remain the same).
Definition PointDataGrid.h:834
openvdb::v11_0::points::PointDataLeafNode::probeConstLeafAndCache
const PointDataLeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Definition PointDataGrid.h:479
openvdb::v11_0::points::PointDataLeafNode::setActiveState
void setActiveState(const Coord &xyz, bool on)
Definition PointDataGrid.h:532
openvdb::v11_0::points::PointDataLeafNode::beginValueOn
ValueOnIter beginValueOn()
Definition PointDataGrid.h:706
openvdb::v11_0::points::PointDataLeafNode::ChildOffCIter
typename BaseLeaf::template ChildIter< MaskOffIterator, const PointDataLeafNode, ChildOff > ChildOffCIter
Definition PointDataGrid.h:648
openvdb::v11_0::points::PointDataLeafNode::probeNodeAndCache
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Definition PointDataGrid.h:463
openvdb::v11_0::points::PointDataLeafNode::beginIndexAll
IndexIter< ValueAllCIter, FilterT > beginIndexAll(const FilterT &filter) const
Filtered leaf index iterator.
Definition PointDataGrid.h:681
openvdb::v11_0::points::PointDataLeafNode::assertNonModifiableUnlessZero
void assertNonModifiableUnlessZero(const ValueType &value)
Definition PointDataGrid.h:528
openvdb::v11_0::points::PointDataLeafNode::probeLeafAndCache
const PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Definition PointDataGrid.h:481
openvdb::v11_0::points::PointDataLeafNode::cbeginChildOff
ChildOffCIter cbeginChildOff() const
Definition PointDataGrid.h:727
openvdb::v11_0::points::PointDataLeafNode::beginChildOff
ChildOffIter beginChildOff()
Definition PointDataGrid.h:729
openvdb::v11_0::points::PointDataLeafNode::beginChildOff
ChildOffCIter beginChildOff() const
Definition PointDataGrid.h:728
openvdb::v11_0::points::PointDataLeafNode::dropAttributes
void dropAttributes(const std::vector< size_t > &pos, const Descriptor &expected, Descriptor::Ptr &replacement)
Drop list of attributes.
Definition PointDataGrid.h:819
openvdb::v11_0::points::PointDataLeafNode::setValueOff
void setValueOff(const Coord &xyz)
Definition PointDataGrid.h:538
openvdb::v11_0::points::PointDataLeafNode::operator!=
bool operator!=(const PointDataLeafNode &other) const
Definition PointDataGrid.h:450
openvdb::v11_0::points::PointDataLeafNode::endValueOff
ValueOffIter endValueOff()
Definition PointDataGrid.h:719
openvdb::v11_0::points::PointDataLeafNode::setValueOff
void setValueOff(Index offset)
Definition PointDataGrid.h:539
openvdb::v11_0::points::PointDataLeafNode::beginIndexOn
IndexIter< ValueOnCIter, FilterT > beginIndexOn(const FilterT &filter) const
Definition PointDataGrid.h:686
openvdb::v11_0::points::PointDataLeafNode::endChildAll
ChildAllCIter endChildAll() const
Definition PointDataGrid.h:741
openvdb::v11_0::points::PointDataLeafNode::probeConstNodeAndCache
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Definition PointDataGrid.h:484
openvdb::v11_0::points::PointDataLeafNode::cbeginValueOn
ValueOnCIter cbeginValueOn() const
Definition PointDataGrid.h:704
openvdb::v11_0::points::PointDataLeafNode::ChildAllCIter
typename BaseLeaf::template DenseIter< const PointDataLeafNode, const ValueType, ChildAll > ChildAllCIter
Definition PointDataGrid.h:652
openvdb::v11_0::points::PointDataLeafNode::clip
void clip(const CoordBBox &, const ValueType &value)
Definition PointDataGrid.h:565
openvdb::v11_0::points::PointDataLeafNode::endChildOn
ChildOnCIter endChildOn() const
Definition PointDataGrid.h:735
openvdb::v11_0::points::PointDataLeafNode::reorderAttributes
void reorderAttributes(const Descriptor::Ptr &replacement)
Reorder attribute set.
Definition PointDataGrid.h:827
openvdb::v11_0::points::PointDataLeafNode::ValueOnCIter
typename BaseLeaf::template ValueIter< MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn > ValueOnCIter
Definition PointDataGrid.h:632
openvdb::v11_0::points::PointDataLeafNode::cendChildOn
ChildOnCIter cendChildOn() const
Definition PointDataGrid.h:734
openvdb::v11_0::points::PointDataLeafNode::cendChildAll
ChildAllCIter cendChildAll() const
Definition PointDataGrid.h:740
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode()
Default constructor.
Definition PointDataGrid.h:268
openvdb::v11_0::points::PointDataLeafNode::attributeSet
const AttributeSet & attributeSet() const
Retrieve the attribute set.
Definition PointDataGrid.h:322
openvdb::v11_0::points::PointDataLeafNode::assertNonmodifiable
void assertNonmodifiable()
Definition PointDataGrid.h:521
openvdb::v11_0::points::PointDataLeafNode::memUsageIfLoaded
Index64 memUsageIfLoaded() const
Definition PointDataGrid.h:1529
openvdb::v11_0::points::PointDataLeafNode::setValueOffAndCache
void setValueOffAndCache(const Coord &, const ValueType &, AccessorT &)
Definition PointDataGrid.h:580
openvdb::v11_0::points::PointDataLeafNode::endChildAll
ChildAllIter endChildAll()
Definition PointDataGrid.h:742
openvdb::v11_0::points::PointDataLeafNode::beginIndexOff
IndexIter< ValueOffCIter, FilterT > beginIndexOff(const FilterT &filter) const
Definition PointDataGrid.h:691
openvdb::v11_0::points::PointDataLeafNode::resetBackground
void resetBackground(const ValueType &, const ValueType &newBackground)
Definition PointDataGrid.h:587
openvdb::v11_0::points::PointDataLeafNode::MaskOffIterator
typename NodeMaskType::OffIterator MaskOffIterator
Definition PointDataGrid.h:612
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &value, TopologyCopy)
Definition PointDataGrid.h:303
openvdb::v11_0::points::PointDataLeafNode::setValue
void setValue(const Coord &, const ValueType &)
Definition PointDataGrid.h:550
openvdb::v11_0::points::PointDataLeafNode::cendValueAll
ValueAllCIter cendValueAll() const
Definition PointDataGrid.h:720
openvdb::v11_0::points::PointDataLeafNode::~PointDataLeafNode
~PointDataLeafNode()=default
openvdb::v11_0::points::PointDataLeafNode::negate
void negate()
Definition PointDataGrid.h:594
openvdb::v11_0::points::PointDataLeafNode::beginChildAll
ChildAllCIter beginChildAll() const
Definition PointDataGrid.h:731
openvdb::v11_0::points::PointDataLeafNode::ValueAll
typename BaseLeaf::ValueAll ValueAll
Definition PointDataGrid.h:600
openvdb::v11_0::points::PointDataLeafNode::ValueTypePair
std::pair< ValueType, ValueType > ValueTypePair
Definition PointDataGrid.h:246
openvdb::v11_0::points::PointDataLeafNode::setValuesOn
void setValuesOn()
Definition PointDataGrid.h:552
openvdb::v11_0::points::PointDataLeafNode::Descriptor
AttributeSet::Descriptor Descriptor
Definition PointDataGrid.h:249
openvdb::v11_0::points::PointDataLeafNode::ValueOn
typename BaseLeaf::ValueOn ValueOn
Definition PointDataGrid.h:598
openvdb::v11_0::points::PointDataLeafNode::cendChildOff
ChildOffCIter cendChildOff() const
Definition PointDataGrid.h:737
openvdb::v11_0::points::PointDataLeafNode::addLeafAndCache
void addLeafAndCache(PointDataLeafNode *, AccessorT &)
Definition PointDataGrid.h:454
openvdb::v11_0::points::PointDataLeafNode::setValueOnlyAndCache
void setValueOnlyAndCache(const Coord &, const ValueType &, AccessorT &)
Definition PointDataGrid.h:572
openvdb::v11_0::points::PointDataLeafNode::fill
void fill(const ValueType &value)
Definition PointDataGrid.h:568
openvdb::v11_0::points::PointDataLeafNode::MaskOnIterator
typename NodeMaskType::OnIterator MaskOnIterator
Definition PointDataGrid.h:611
openvdb::v11_0::points::PointDataLeafNode::ChildOffIter
typename BaseLeaf::template ChildIter< MaskOffIterator, PointDataLeafNode, ChildOff > ChildOffIter
Definition PointDataGrid.h:646
openvdb::v11_0::points::PointDataLeafNode::addLeaf
void addLeaf(PointDataLeafNode *)
Definition PointDataGrid.h:452
openvdb::v11_0::points::PointDataLeafNode::signedFloodFill
void signedFloodFill(const ValueType &)
Definition PointDataGrid.h:591
openvdb::v11_0::points::PointDataLeafNode::beginValueOff
ValueOffIter beginValueOff()
Definition PointDataGrid.h:709
openvdb::v11_0::points::PointDataLeafNode::setValueOn
void setValueOn(const Coord &xyz)
Definition PointDataGrid.h:544
openvdb::v11_0::points::PointDataLeafNode::setActiveState
void setActiveState(Index offset, bool on)
Definition PointDataGrid.h:533
openvdb::v11_0::points::PointDataLeafNode::ValueOffCIter
typename BaseLeaf::template ValueIter< MaskOffIterator, const PointDataLeafNode, const ValueType, ValueOff > ValueOffCIter
Definition PointDataGrid.h:636
openvdb::v11_0::points::PointDataLeafNode::beginIndexOn
IndexOnIter beginIndexOn() const
Definition PointDataGrid.h:665
openvdb::v11_0::points::PointDataLeafNode::ValueOff
typename BaseLeaf::ValueOff ValueOff
Definition PointDataGrid.h:599
openvdb::v11_0::points::PointDataLeafNode::modifyValue
void modifyValue(const Coord &, const ModifyOp &)
Definition PointDataGrid.h:559
openvdb::v11_0::points::PointDataLeafNode::cendValueOff
ValueOffCIter cendValueOff() const
Definition PointDataGrid.h:717
openvdb::v11_0::points::PointDataLeafNode::memUsage
Index64 memUsage() const
Definition PointDataGrid.h:1521
openvdb::v11_0::points::PointDataLeafNode::ChildOnCIter
typename BaseLeaf::template ChildIter< MaskOnIterator, const PointDataLeafNode, ChildOn > ChildOnCIter
Definition PointDataGrid.h:644
openvdb::v11_0::points::PointDataLeafNode::fill
void fill(const CoordBBox &, const ValueType &, bool)
Definition PointDataGrid.h:1551
openvdb::v11_0::points::PointDataLeafNode::endValueOff
ValueOffCIter endValueOff() const
Definition PointDataGrid.h:718
openvdb::v11_0::points::PointDataLeafNode::ValueOnIter
typename BaseLeaf::template ValueIter< MaskOnIterator, PointDataLeafNode, const ValueType, ValueOn > ValueOnIter
Definition PointDataGrid.h:630
openvdb::v11_0::points::PointDataLeafNode::probeLeaf
PointDataLeafNode * probeLeaf(const Coord &)
Definition PointDataGrid.h:470
openvdb::v11_0::points::PointDataLeafNode::ValueType
T ValueType
Definition PointDataGrid.h:245
openvdb::v11_0::points::PointDataLeafNode::probeLeafAndCache
PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Definition PointDataGrid.h:472
openvdb::v11_0::points::PointDataLeafNode::endValueOn
ValueOnCIter endValueOn() const
Definition PointDataGrid.h:715
openvdb::v11_0::points::PointDataLeafNode::MaskDenseIterator
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition PointDataGrid.h:613
openvdb::v11_0::points::PointDataLeafNode::beginValueAll
ValueAllCIter beginValueAll() const
Definition PointDataGrid.h:711
openvdb::v11_0::points::PointDataLeafNode::ChildAllIter
typename BaseLeaf::template DenseIter< PointDataLeafNode, ValueType, ChildAll > ChildAllIter
Definition PointDataGrid.h:650
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Construct using supplied origin, value and active status.
Definition PointDataGrid.h:280
openvdb::v11_0::points::PointDataLeafNode::PointDataLeafNode
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &, const T &, TopologyCopy)
Definition PointDataGrid.h:310
openvdb::v11_0::points::PointDataLeafNode::ValueAllCIter
typename BaseLeaf::template ValueIter< MaskDenseIterator, const PointDataLeafNode, const ValueType, ValueAll > ValueAllCIter
Definition PointDataGrid.h:640
openvdb::v11_0::points::PointDataLeafNode::setValueOn
void setValueOn(const Coord &, const ValueType &)
Definition PointDataGrid.h:547
openvdb::v11_0::points::PointDataLeafNode::beginValueAll
ValueAllIter beginValueAll()
Definition PointDataGrid.h:712
openvdb::v11_0::points::PointDataLeafNode::IndexArray
std::vector< ValueType > IndexArray
Definition PointDataGrid.h:247
openvdb::v11_0::points::TypedAttributeArray
Typed class for storing attribute data.
Definition AttributeArray.h:545
openvdb::v11_0::points::ValueVoxelCIter
A forward iterator over array indices in a single voxel.
Definition IndexIterator.h:65
openvdb::v11_0::tree::InternalNode
Definition InternalNode.h:34
openvdb::v11_0::tree::IteratorBase
Base class for iterators over internal and leaf nodes.
Definition Iterator.h:30
openvdb::v11_0::tree::LeafNode
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim....
Definition LeafNode.h:38
openvdb::v11_0::tree::LeafNode::size
static Index size()
Return the total number of voxels represented by this LeafNode.
Definition LeafNode.h:121
openvdb::v11_0::tree::RootNode
Definition RootNode.h:39
openvdb::v11_0::tree::Tree
Definition Tree.h:178
openvdb::v11_0::util::DenseMaskIterator
Definition NodeMasks.h:271
openvdb::v11_0::util::NodeMask
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition NodeMasks.h:308
openvdb::v11_0::util::OffMaskIterator
Definition NodeMasks.h:240
openvdb::v11_0::util::OnMaskIterator
Definition NodeMasks.h:209
openvdb::v11_0::io::writeCompressedValues
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition Compression.h:645
openvdb::v11_0::io::readCompressedValues
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition Compression.h:465
openvdb::v11_0::io::writeCompressedValuesSize
size_t writeCompressedValuesSize(ValueT *srcBuf, Index srcCount, const MaskT &valueMask, uint8_t maskMetadata, bool toHalf, uint32_t compress)
Definition Compression.h:591
openvdb::v11_0::points::setStreamingMode
void setStreamingMode(PointDataTreeT &tree, bool on=true)
Toggle the streaming mode on all attributes in the tree to collapse the attributes after deconstructi...
Definition PointDataGrid.h:1606
openvdb::v11_0::points::prefetch
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...
Definition PointDataGrid.h:1619
openvdb::v11_0::points::compactAttributes
void compactAttributes(PointDataTreeT &tree)
Compact attributes in a VDB tree (if possible).
Definition PointAttributeImpl.h:385
openvdb::v11_0::points::pointCount
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.
Definition PointCountImpl.h:18
openvdb::v11_0::points::isGroup
bool isGroup(const AttributeArray &array)
Definition AttributeGroup.h:63
openvdb::v11_0::points::appendAttribute
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)
Definition PointAttributeImpl.h:103
openvdb::v11_0::points::dropAttributes
void dropAttributes(PointDataTreeT &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition PointAttributeImpl.h:238
openvdb::v11_0::points::renameAttributes
void renameAttributes(PointDataTreeT &tree, const std::vector< Name > &oldNames, const std::vector< Name > &newNames)
Rename attributes in a VDB tree.
Definition PointAttributeImpl.h:326
openvdb::v11_0::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition IndexIterator.h:314
openvdb::v11_0::points::makeDescriptorUnique
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition PointDataGrid.h:1589
openvdb::v11_0::Name
std::string Name
Definition Name.h:19
openvdb::v11_0::Index
Index32 Index
Definition Types.h:54
openvdb::v11_0::initialize
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types....
openvdb::v11_0::uninitialize
OPENVDB_IMPORT void uninitialize()
Global deregistration of native Grid, Transform, Metadata and Point attribute types.
openvdb::v11_0::zeroVal
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
openvdb::v11_0::Int32
int32_t Int32
Definition Types.h:56
openvdb::v11_0::Index64
uint64_t Index64
Definition Types.h:53
openvdb
Definition Exceptions.h:13
allocate
static pnanovdb_uint32_t allocate(pnanovdb_uint32_t *poffset, pnanovdb_uint32_t size, pnanovdb_uint32_t alignment)
Definition pnanovdb_validate_strides.h:20
openvdb::v11_0::PointIndex
Integer wrapper, required to distinguish PointIndexGrid and PointDataGrid from Int32Grid and Int64Gri...
Definition Types.h:157
openvdb::v11_0::TypeList
A list of types (not necessarily unique)
Definition TypeList.h:578
openvdb::v11_0::io::MultiPass
Leaf nodes that require multi-pass I/O must inherit from this struct.
Definition io.h:124
openvdb::v11_0::points::TreeConverter
Similiar to ValueConverter, but allows for tree configuration conversion to a PointDataTree....
Definition PointDataGrid.h:1713
openvdb::v11_0::points::TreeConverter::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition PointDataGrid.h:1714
openvdb::v11_0::points::TreeConverter::NodeChainT
typename internal::PointDataNodeChain< RootNodeT, RootNodeT::LEVEL >::Type NodeChainT
Definition PointDataGrid.h:1715
openvdb::v11_0::points::internal::PointDataNodeChain< tree::InternalNode< ChildT, Log2Dim >, HeadLevel >::SubtreeT
typename PointDataNodeChain< ChildT, HeadLevel-1 >::Type SubtreeT
Definition PointDataGrid.h:1691
openvdb::v11_0::points::internal::PointDataNodeChain< tree::InternalNode< ChildT, Log2Dim >, HeadLevel >::Type
typename SubtreeT::template Append< InternalNodeT > Type
Definition PointDataGrid.h:1693
openvdb::v11_0::points::internal::PointDataNodeChain
Recursive node chain which generates a openvdb::TypeList value converted types of nodes to PointDataG...
Definition PointDataGrid.h:1680
openvdb::v11_0::points::internal::PointDataNodeChain::SubtreeT
typename PointDataNodeChain< typename HeadT::ChildNodeType, HeadLevel-1 >::Type SubtreeT
Definition PointDataGrid.h:1681
openvdb::v11_0::points::internal::PointDataNodeChain::Type
typename SubtreeT::template Append< RootNodeT > Type
Definition PointDataGrid.h:1683
openvdb::v11_0::tools::PointIndexLeafNode
Definition PointIndexGrid.h:1358
openvdb::v11_0::tree::IterTraits
Definition TreeIterator.h:60
openvdb::v11_0::tree::LeafNode::ChildAll
Definition LeafNode.h:210
openvdb::v11_0::tree::LeafNode::ChildIter
Leaf nodes have no children, so their child iterators have no get/set accessors.
Definition LeafNode.h:250
openvdb::v11_0::tree::LeafNode::ChildOff
Definition LeafNode.h:210
openvdb::v11_0::tree::LeafNode::ChildOn
Definition LeafNode.h:210
openvdb::v11_0::tree::LeafNode::DenseIter
Definition LeafNode.h:259
openvdb::v11_0::tree::LeafNode::ValueAll
Definition LeafNode.h:209
openvdb::v11_0::tree::LeafNode::ValueIter
Definition LeafNode.h:218
openvdb::v11_0::tree::LeafNode::ValueOff
Definition LeafNode.h:209
openvdb::v11_0::tree::LeafNode::ValueOn
Definition LeafNode.h:209
openvdb::v11_0::tree::SameLeafConfig
Definition LeafNode.h:890
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212