Loading...
Searching...
No Matches
AttributeArray.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/// @file points/AttributeArray.h
///
/// @authors Dan Bailey, Mihai Alden, Nick Avramoussis, James Bird, Khang Ngo
///
/// @brief Attribute Array storage templated on type and compression codec.
#ifndef OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
#define OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
#include <openvdb/Types.h>
#include <openvdb/math/QuantizedUnitVec.h>
#include <openvdb/util/Name.h>
#include <openvdb/util/logging.h>
#include <openvdb/io/io.h> // MappedFile
#include <openvdb/io/Compression.h> // COMPRESS_BLOSC
#include "IndexIterator.h"
#include "StreamCompression.h"
#include <tbb/spin_mutex.h>
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
class TestAttributeArray;
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
using NamePair = std::pair<Name, Name>;
namespace points {
////////////////////////////////////////
// Utility methods
template <typename IntegerT, typename FloatT>
inline IntegerT
floatingPointToFixedPoint(const FloatT s)
{
static_assert(std::is_unsigned<IntegerT>::value, "IntegerT must be unsigned");
if (FloatT(0.0) > s) return std::numeric_limits<IntegerT>::min();
else if (FloatT(1.0) <= s) return std::numeric_limits<IntegerT>::max();
return IntegerT(s * FloatT(std::numeric_limits<IntegerT>::max()));
}
template <typename FloatT, typename IntegerT>
inline FloatT
fixedPointToFloatingPoint(const IntegerT s)
{
static_assert(std::is_unsigned<IntegerT>::value, "IntegerT must be unsigned");
return FloatT(s) / FloatT((std::numeric_limits<IntegerT>::max()));
}
template <typename IntegerVectorT, typename FloatT>
inline IntegerVectorT
floatingPointToFixedPoint(const math::Vec3<FloatT>& v)
{
return IntegerVectorT(
floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.x()),
floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.y()),
floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.z()));
}
template <typename FloatVectorT, typename IntegerT>
inline FloatVectorT
fixedPointToFloatingPoint(const math::Vec3<IntegerT>& v)
{
return FloatVectorT(
fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.x()),
fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.y()),
fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.z()));
}
////////////////////////////////////////
/// Base class for storing attribute data
class OPENVDB_API AttributeArray
{
protected:
struct AccessorBase;
template <typename T> struct Accessor;
using AccessorBasePtr = std::shared_ptr<AccessorBase>;
public:
enum Flag {
TRANSIENT = 0x1, /// by default not written to disk
HIDDEN = 0x2, /// hidden from UIs or iterators
CONSTANTSTRIDE = 0x8, /// stride size does not vary in the array
STREAMING = 0x10, /// streaming mode collapses attributes when first accessed
PARTIALREAD = 0x20 /// data has been partially read (compressed bytes is used)
};
enum SerializationFlag {
WRITESTRIDED = 0x1, /// data is marked as strided when written
WRITEUNIFORM = 0x2, /// data is marked as uniform when written
WRITEMEMCOMPRESS = 0x4, /// data is marked as compressed in-memory when written
/// (deprecated flag as of ABI=6)
WRITEPAGED = 0x8 /// data is written out in pages
};
// Scoped Lock wrapper class that locks the AttributeArray registry mutex
class OPENVDB_API ScopedRegistryLock
{
tbb::spin_mutex::scoped_lock lock;
public:
ScopedRegistryLock();
}; // class ScopedRegistryLock
using Ptr = std::shared_ptr<AttributeArray>;
using ConstPtr = std::shared_ptr<const AttributeArray>;
using FactoryMethod = Ptr (*)(Index, Index, bool, const Metadata*);
template <typename ValueType, typename CodecType> friend class AttributeHandle;
AttributeArray(): mPageHandle() { mOutOfCore = 0; }
virtual ~AttributeArray()
{
// if this AttributeArray has been partially read, zero the compressed bytes,
// so the page handle won't attempt to clean up invalid memory
if (mFlags & PARTIALREAD) mCompressedBytes = 0;
}
AttributeArray(const AttributeArray& rhs);
AttributeArray& operator=(const AttributeArray& rhs);
AttributeArray(AttributeArray&&) = delete;
AttributeArray& operator=(AttributeArray&&) = delete;
/// Return a copy of this attribute.
virtual AttributeArray::Ptr copy() const = 0;
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// Return a copy of this attribute.
#ifndef _MSC_VER
OPENVDB_DEPRECATED_MESSAGE("In-memory compression no longer supported, use AttributeArray::copy() instead")
#endif
virtual AttributeArray::Ptr copyUncompressed() const = 0;
#endif
/// Return the number of elements in this array.
/// @note This does not count each data element in a strided array
virtual Index size() const = 0;
/// Return the stride of this array.
/// @note a return value of zero means a non-constant stride
virtual Index stride() const = 0;
/// Return the total number of data elements in this array.
/// @note This counts each data element in a strided array
virtual Index dataSize() const = 0;
/// Return the name of the value type of a single element in this array (e.g., "float" or "vec3d").
virtual Name valueType() const = 0;
/// Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
virtual Name codecType() const = 0;
/// Return the size in bytes of the value type of a single element in this array.
/// (e.g. "float" -> 4 bytes, "vec3d" -> 24 bytes").
virtual Index valueTypeSize() const = 0;
/// Return the size in bytes of the storage type of a single element of this array.
/// @note If the Codec is a NullCodec, valueSize() == storageSize()
virtual Index storageTypeSize() const = 0;
/// Return @c true if the value type is floating point
virtual bool valueTypeIsFloatingPoint() const = 0;
/// Return @c true if the value type is a class (ie vector, matrix or quaternion return true)
virtual bool valueTypeIsClass() const = 0;
/// Return @c true if the value type is a vector
virtual bool valueTypeIsVector() const = 0;
/// Return @c true if the value type is a quaternion
virtual bool valueTypeIsQuaternion() const = 0;
/// Return @c true if the value type is a matrix
virtual bool valueTypeIsMatrix() const = 0;
/// Return the number of bytes of memory used by this attribute.
virtual size_t memUsage() const = 0;
#if OPENVDB_ABI_VERSION_NUMBER >= 10
/// Return the number of bytes of memory used by this attribute array once it
/// has been deserialized (this may be different to memUsage() if delay-loading
/// is in use). Note that this method does NOT consider the fact that a
/// uniform attribute could be expanded and only deals with delay-loading.
virtual size_t memUsageIfLoaded() const = 0;
#endif
/// Create a new attribute array of the given (registered) type, length and stride.
/// @details If @a lock is non-null, the AttributeArray registry mutex
/// has already been locked
static Ptr create(const NamePair& type, Index length, Index stride = 1,
bool constantStride = true,
const Metadata* metadata = nullptr,
const ScopedRegistryLock* lock = nullptr);
/// Return @c true if the given attribute type name is registered.
static bool isRegistered(const NamePair& type, const ScopedRegistryLock* lock = nullptr);
/// Clear the attribute type registry.
static void clearRegistry(const ScopedRegistryLock* lock = nullptr);
/// Return the name of this attribute's type.
virtual const NamePair& type() const = 0;
/// Return @c true if this attribute is of the same type as the template parameter.
template<typename AttributeArrayType>
bool isType() const { return this->type() == AttributeArrayType::attributeType(); }
/// Return @c true if this attribute has a value type the same as the template parameter
template<typename ValueType>
bool hasValueType() const { return this->type().first == typeNameAsString<ValueType>(); }
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// @brief Set value at given index @a n from @a sourceIndex of another @a sourceArray.
// Windows does not allow base classes to be easily deprecated.
#ifndef _MSC_VER
OPENVDB_DEPRECATED_MESSAGE("Use copyValues() with source-target index pairs")
#endif
virtual void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) = 0;
#endif
/// @brief Copy values into this array from a source array to a target array
/// as referenced by an iterator.
/// @details Iterators must adhere to the ForwardIterator interface described
/// in the example below:
/// @code
/// struct MyIterator
/// {
/// // returns true if the iterator is referencing valid copying indices
/// operator bool() const;
/// // increments the iterator
/// MyIterator& operator++();
/// // returns the source index that the iterator is referencing for copying
/// Index sourceIndex() const;
/// // returns the target index that the iterator is referencing for copying
/// Index targetIndex() const;
/// };
/// @endcode
/// @note It is assumed that the strided storage sizes match, the arrays are both in-core,
/// and both value types are floating-point or both integer.
/// @note It is possible to use this method to write to a uniform target array
/// if the iterator does not have non-zero target indices.
/// @note This method is not thread-safe, it must be guaranteed that this array is not
/// concurrently modified by another thread and that the source array is also not modified.
template<typename IterT>
void copyValuesUnsafe(const AttributeArray& sourceArray, const IterT& iter);
/// @brief Like copyValuesUnsafe(), but if @a compact is true, attempt to collapse this array.
/// @note This method is not thread-safe, it must be guaranteed that this array is not
/// concurrently modified by another thread and that the source array is also not modified.
template<typename IterT>
void copyValues(const AttributeArray& sourceArray, const IterT& iter, bool compact = true);
/// Return @c true if this array is stored as a single uniform value.
virtual bool isUniform() const = 0;
/// @brief If this array is uniform, replace it with an array of length size().
/// @param fill if true, assign the uniform value to each element of the array.
virtual void expand(bool fill = true) = 0;
/// Replace the existing array with a uniform zero value.
virtual void collapse() = 0;
/// Compact the existing array to become uniform if all values are identical
virtual bool compact() = 0;
#if OPENVDB_ABI_VERSION_NUMBER < 10
// Windows does not allow base classes to be deprecated
#ifndef _MSC_VER
OPENVDB_DEPRECATED_MESSAGE("Previously this compressed the attribute array, now it does nothing")
#endif
virtual bool compress() = 0;
// Windows does not allow base classes to be deprecated
#ifndef _MSC_VER
OPENVDB_DEPRECATED_MESSAGE("Previously this uncompressed the attribute array, now it does nothing")
#endif
virtual bool decompress() = 0;
#endif
/// @brief Specify whether this attribute should be hidden (e.g., from UI or iterators).
/// @details This is useful if the attribute is used for blind data or as scratch space
/// for a calculation.
/// @note Attributes are not hidden by default.
void setHidden(bool state);
/// Return @c true if this attribute is hidden (e.g., from UI or iterators).
bool isHidden() const { return bool(mFlags & HIDDEN); }
/// @brief Specify whether this attribute should only exist in memory
/// and not be serialized during stream output.
/// @note Attributes are not transient by default.
void setTransient(bool state);
/// Return @c true if this attribute is not serialized during stream output.
bool isTransient() const { return bool(mFlags & TRANSIENT); }
/// @brief Specify whether this attribute is to be streamed off disk, in which
/// case, the attributes are collapsed after being first loaded leaving them
/// in a destroyed state.
/// @note This operation is not thread-safe.
void setStreaming(bool state);
/// Return @c true if this attribute is in streaming mode.
bool isStreaming() const { return bool(mFlags & STREAMING); }
/// Return @c true if this attribute has a constant stride
bool hasConstantStride() const { return bool(mFlags & CONSTANTSTRIDE); }
/// @brief Retrieve the attribute array flags
uint8_t flags() const { return mFlags; }
/// Read attribute metadata and buffers from a stream.
virtual void read(std::istream&) = 0;
/// Write attribute metadata and buffers to a stream.
/// @param outputTransient if true, write out transient attributes
virtual void write(std::ostream&, bool outputTransient) const = 0;
/// Write attribute metadata and buffers to a stream, don't write transient attributes.
virtual void write(std::ostream&) const = 0;
/// Read attribute metadata from a stream.
virtual void readMetadata(std::istream&) = 0;
/// Write attribute metadata to a stream.
/// @param outputTransient if true, write out transient attributes
/// @param paged if true, data is written out in pages
virtual void writeMetadata(std::ostream&, bool outputTransient, bool paged) const = 0;
/// Read attribute buffers from a stream.
virtual void readBuffers(std::istream&) = 0;
/// Write attribute buffers to a stream.
/// @param outputTransient if true, write out transient attributes
virtual void writeBuffers(std::ostream&, bool outputTransient) const = 0;
/// Read attribute buffers from a paged stream.
virtual void readPagedBuffers(compression::PagedInputStream&) = 0;
/// Write attribute buffers to a paged stream.
/// @param outputTransient if true, write out transient attributes
virtual void writePagedBuffers(compression::PagedOutputStream&, bool outputTransient) const = 0;
/// Ensures all data is in-core
virtual void loadData() const = 0;
/// Return @c true if all data has been loaded
virtual bool isDataLoaded() const = 0;
/// Check the compressed bytes and flags. If they are equal, perform a deeper
/// comparison check necessary on the inherited types (TypedAttributeArray)
/// Requires non operator implementation due to inheritance
bool operator==(const AttributeArray& other) const;
bool operator!=(const AttributeArray& other) const { return !this->operator==(other); }
#if OPENVDB_ABI_VERSION_NUMBER >= 9
/// Indirect virtual function to retrieve the data buffer cast to a char byte array
const char* constDataAsByteArray() const { return this->dataAsByteArray(); }
#endif
private:
friend class ::TestAttributeArray;
/// Virtual function used by the comparison operator to perform
/// comparisons on inherited types
virtual bool isEqual(const AttributeArray& other) const = 0;
/// Virtual function to retrieve the data buffer cast to a char byte array
virtual char* dataAsByteArray() = 0;
virtual const char* dataAsByteArray() const = 0;
/// Private implementation for copyValues/copyValuesUnsafe
template <typename IterT>
void doCopyValues(const AttributeArray& sourceArray, const IterT& iter,
bool rangeChecking = true);
protected:
AttributeArray(const AttributeArray& rhs, const tbb::spin_mutex::scoped_lock&);
/// @brief Specify whether this attribute has a constant stride or not.
void setConstantStride(bool state);
/// Obtain an Accessor that stores getter and setter functors.
virtual AccessorBasePtr getAccessor() const = 0;
/// Register a attribute type along with a factory function.
static void registerType(const NamePair& type, FactoryMethod,
const ScopedRegistryLock* lock = nullptr);
/// Remove a attribute type from the registry.
static void unregisterType(const NamePair& type,
const ScopedRegistryLock* lock = nullptr);
bool mIsUniform = true;
mutable tbb::spin_mutex mMutex;
uint8_t mFlags = 0;
uint8_t mUsePagedRead = 0;
std::atomic<Index32> mOutOfCore; // interpreted as bool
/// used for out-of-core, paged reading
union {
compression::PageHandle::Ptr mPageHandle;
size_t mCompressedBytes;
};
}; // class AttributeArray
////////////////////////////////////////
/// Accessor base class for AttributeArray storage where type is not available
struct AttributeArray::AccessorBase { virtual ~AccessorBase() = default; };
/// Templated Accessor stores typed function pointers used in binding
/// AttributeHandles
template <typename T>
struct AttributeArray::Accessor : public AttributeArray::AccessorBase
{
using GetterPtr = T (*)(const AttributeArray* array, const Index n);
using SetterPtr = void (*)(AttributeArray* array, const Index n, const T& value);
using ValuePtr = void (*)(AttributeArray* array, const T& value);
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler) :
mGetter(getter), mSetter(setter), mCollapser(collapser), mFiller(filler) { }
GetterPtr mGetter;
SetterPtr mSetter;
ValuePtr mCollapser;
ValuePtr mFiller;
}; // struct AttributeArray::Accessor
////////////////////////////////////////
namespace attribute_traits
{
template <typename T> struct TruncateTrait { };
template <> struct TruncateTrait<float> { using Type = math::half; };
template <> struct TruncateTrait<int> { using Type = short; };
template <typename T> struct TruncateTrait<math::Vec3<T>> {
using Type = math::Vec3<typename TruncateTrait<T>::Type>;
};
template <bool OneByte, typename T> struct UIntTypeTrait { };
template<typename T> struct UIntTypeTrait</*OneByte=*/true, T> { using Type = uint8_t; };
template<typename T> struct UIntTypeTrait</*OneByte=*/false, T> { using Type = uint16_t; };
template<typename T> struct UIntTypeTrait</*OneByte=*/true, math::Vec3<T>> {
using Type = math::Vec3<uint8_t>;
};
template<typename T> struct UIntTypeTrait</*OneByte=*/false, math::Vec3<T>> {
using Type = math::Vec3<uint16_t>;
};
}
////////////////////////////////////////
// Attribute codec schemes
struct UnknownCodec { };
struct NullCodec
{
template <typename T>
struct Storage { using Type = T; };
template<typename ValueType> static void decode(const ValueType&, ValueType&);
template<typename ValueType> static void encode(const ValueType&, ValueType&);
static const char* name() { return "null"; }
};
struct TruncateCodec
{
template <typename T>
struct Storage { using Type = typename attribute_traits::TruncateTrait<T>::Type; };
template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
static const char* name() { return "trnc"; }
};
// Fixed-point codec range for voxel-space positions [-0.5,0.5]
struct PositionRange
{
static const char* name() { return "fxpt"; }
template <typename ValueType> static ValueType encode(const ValueType& value) { return value + ValueType(0.5); }
template <typename ValueType> static ValueType decode(const ValueType& value) { return value - ValueType(0.5); }
};
// Fixed-point codec range for unsigned values in the unit range [0.0,1.0]
struct UnitRange
{
static const char* name() { return "ufxpt"; }
template <typename ValueType> static ValueType encode(const ValueType& value) { return value; }
template <typename ValueType> static ValueType decode(const ValueType& value) { return value; }
};
template <bool OneByte, typename Range=PositionRange>
struct FixedPointCodec
{
template <typename T>
struct Storage { using Type = typename attribute_traits::UIntTypeTrait<OneByte, T>::Type; };
template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
static const char* name() {
static const std::string Name = std::string(Range::name()) + (OneByte ? "8" : "16");
return Name.c_str();
}
};
struct UnitVecCodec
{
using StorageType = uint16_t;
template <typename T>
struct Storage { using Type = StorageType; };
template<typename T> static void decode(const StorageType&, math::Vec3<T>&);
template<typename T> static void encode(const math::Vec3<T>&, StorageType&);
static const char* name() { return "uvec"; }
};
////////////////////////////////////////
/// Typed class for storing attribute data
template<typename ValueType_, typename Codec_ = NullCodec>
class TypedAttributeArray final: public AttributeArray
{
public:
using Ptr = std::shared_ptr<TypedAttributeArray>;
using ConstPtr = std::shared_ptr<const TypedAttributeArray>;
using ValueType = ValueType_;
using Codec = Codec_;
using StorageType = typename Codec::template Storage<ValueType>::Type;
//////////
/// Default constructor, always constructs a uniform attribute.
explicit TypedAttributeArray(Index n = 1, Index strideOrTotalSize = 1, bool constantStride = true,
const ValueType& uniformValue = zeroVal<ValueType>());
/// Deep copy constructor.
/// @note This method is thread-safe (as of ABI=7) for concurrently reading from the
/// source attribute array while being deep-copied. Specifically, this means that the
/// attribute array being deep-copied can be out-of-core and safely loaded in one thread
/// while being copied using this copy-constructor in another thread.
/// It is not thread-safe for write.
TypedAttributeArray(const TypedAttributeArray&);
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// Deep copy constructor.
OPENVDB_DEPRECATED_MESSAGE("Use copy-constructor without unused bool parameter")
TypedAttributeArray(const TypedAttributeArray&, bool /*unused*/);
#endif
/// Deep copy assignment operator.
/// @note this operator is thread-safe.
TypedAttributeArray& operator=(const TypedAttributeArray&);
/// Move constructor disabled.
TypedAttributeArray(TypedAttributeArray&&) = delete;
/// Move assignment operator disabled.
TypedAttributeArray& operator=(TypedAttributeArray&&) = delete;
~TypedAttributeArray() override { this->deallocate(); }
/// Return a copy of this attribute.
/// @note This method is thread-safe.
AttributeArray::Ptr copy() const override;
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// Return a copy of this attribute.
/// @note This method is thread-safe.
OPENVDB_DEPRECATED_MESSAGE("In-memory compression no longer supported, use AttributeArray::copy() instead")
AttributeArray::Ptr copyUncompressed() const override;
#endif
/// Return a new attribute array of the given length @a n and @a stride with uniform value zero.
static Ptr create(Index n, Index strideOrTotalSize = 1, bool constantStride = true,
const Metadata* metadata = nullptr);
/// Cast an AttributeArray to TypedAttributeArray<T>
static TypedAttributeArray& cast(AttributeArray& attributeArray);
/// Cast an AttributeArray to TypedAttributeArray<T>
static const TypedAttributeArray& cast(const AttributeArray& attributeArray);
/// Return the name of this attribute's type (includes codec)
static const NamePair& attributeType();
/// Return the name of this attribute's type.
const NamePair& type() const override { return attributeType(); }
/// Return @c true if this attribute type is registered.
static bool isRegistered();
/// Register this attribute type along with a factory function.
static void registerType();
/// Remove this attribute type from the registry.
static void unregisterType();
/// Return the number of elements in this array.
Index size() const override { return mSize; }
/// Return the stride of this array.
/// @note A return value of zero means a variable stride
Index stride() const override { return hasConstantStride() ? mStrideOrTotalSize : 0; }
/// Return the size of the data in this array.
Index dataSize() const override {
return hasConstantStride() ? mSize * mStrideOrTotalSize : mStrideOrTotalSize;
}
/// Return the name of the value type of a single element in this array (e.g., "float" or "vec3d").
Name valueType() const override { return typeNameAsString<ValueType>(); }
/// Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
Name codecType() const override { return Codec::name(); }
/// Return the size in bytes of the value type of a single element in this array.
Index valueTypeSize() const override { return sizeof(ValueType); }
/// Return the size in bytes of the storage type of a single element of this array.
/// @note If the Codec is a NullCodec, valueSize() == storageSize()
Index storageTypeSize() const override { return sizeof(StorageType); }
/// Return @c true if the value type is floating point
bool valueTypeIsFloatingPoint() const override;
/// Return @c true if the value type is a class (ie vector, matrix or quaternion return true)
bool valueTypeIsClass() const override;
/// Return @c true if the value type is a vector
bool valueTypeIsVector() const override;
/// Return @c true if the value type is a quaternion
bool valueTypeIsQuaternion() const override;
/// Return @c true if the value type is a matrix
bool valueTypeIsMatrix() const override;
/// Return the number of bytes of memory used by this attribute.
size_t memUsage() const override;
#if OPENVDB_ABI_VERSION_NUMBER >= 10
/// Return the number of bytes of memory used by this attribute array once it
/// has been deserialized (this may be different to memUsage() if delay-loading
/// is in use). Note that this method does NOT consider the fact that a
/// uniform attribute could be expanded and only deals with delay-loading.
size_t memUsageIfLoaded() const override;
#endif
/// Return the value at index @a n (assumes in-core)
ValueType getUnsafe(Index n) const;
/// Return the value at index @a n
ValueType get(Index n) const;
/// Return the @a value at index @a n (assumes in-core)
template<typename T> void getUnsafe(Index n, T& value) const;
/// Return the @a value at index @a n
template<typename T> void get(Index n, T& value) const;
/// Non-member equivalent to getUnsafe() that static_casts array to this TypedAttributeArray
/// (assumes in-core)
static ValueType getUnsafe(const AttributeArray* array, const Index n);
/// Set @a value at the given index @a n (assumes in-core)
void setUnsafe(Index n, const ValueType& value);
/// Set @a value at the given index @a n
void set(Index n, const ValueType& value);
/// Set @a value at the given index @a n (assumes in-core)
template<typename T> void setUnsafe(Index n, const T& value);
/// Set @a value at the given index @a n
template<typename T> void set(Index n, const T& value);
/// Non-member equivalent to setUnsafe() that static_casts array to this TypedAttributeArray
/// (assumes in-core)
static void setUnsafe(AttributeArray* array, const Index n, const ValueType& value);
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// Set value at given index @a n from @a sourceIndex of another @a sourceArray
OPENVDB_DEPRECATED_MESSAGE("Use copyValues() with source-target index pairs")
void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) override;
#endif
/// Return @c true if this array is stored as a single uniform value.
bool isUniform() const override { return mIsUniform; }
/// @brief Replace the single value storage with an array of length size().
/// @note Non-uniform attributes are unchanged.
/// @param fill toggle to initialize the array elements with the pre-expanded value.
void expand(bool fill = true) override;
/// Replace the existing array with a uniform zero value.
void collapse() override;
/// Compact the existing array to become uniform if all values are identical
bool compact() override;
/// Replace the existing array with the given uniform value.
void collapse(const ValueType& uniformValue);
/// @brief Fill the existing array with the given value.
/// @note Identical to collapse() except a non-uniform array will not become uniform.
void fill(const ValueType& value);
/// Non-member equivalent to collapse() that static_casts array to this TypedAttributeArray
static void collapse(AttributeArray* array, const ValueType& value);
/// Non-member equivalent to fill() that static_casts array to this TypedAttributeArray
static void fill(AttributeArray* array, const ValueType& value);
#if OPENVDB_ABI_VERSION_NUMBER < 10
/// Compress the attribute array.
OPENVDB_DEPRECATED_MESSAGE("Previously this compressed the attribute array, now it does nothing")
bool compress() override;
/// Uncompress the attribute array.
OPENVDB_DEPRECATED_MESSAGE("Previously this uncompressed the attribute array, now it does nothing")
bool decompress() override;
#endif
/// Read attribute data from a stream.
void read(std::istream&) override;
/// Write attribute data to a stream.
/// @param os the output stream
/// @param outputTransient if true, write out transient attributes
void write(std::ostream& os, bool outputTransient) const override;
/// Write attribute data to a stream, don't write transient attributes.
void write(std::ostream&) const override;
/// Read attribute metadata from a stream.
void readMetadata(std::istream&) override;
/// Write attribute metadata to a stream.
/// @param os the output stream
/// @param outputTransient if true, write out transient attributes
/// @param paged if true, data is written out in pages
void writeMetadata(std::ostream& os, bool outputTransient, bool paged) const override;
/// Read attribute buffers from a stream.
void readBuffers(std::istream&) override;
/// Write attribute buffers to a stream.
/// @param os the output stream
/// @param outputTransient if true, write out transient attributes
void writeBuffers(std::ostream& os, bool outputTransient) const override;
/// Read attribute buffers from a paged stream.
void readPagedBuffers(compression::PagedInputStream&) override;
/// Write attribute buffers to a paged stream.
/// @param os the output stream
/// @param outputTransient if true, write out transient attributes
void writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const override;
/// Return @c true if this buffer's values have not yet been read from disk.
inline bool isOutOfCore() const;
/// Ensures all data is in-core
void loadData() const override;
/// Return @c true if all data has been loaded
bool isDataLoaded() const override;
#if OPENVDB_ABI_VERSION_NUMBER >= 9
/// Return the raw data buffer
inline const StorageType* constData() const { return this->data(); }
#endif
protected:
AccessorBasePtr getAccessor() const override;
/// Return the raw data buffer
inline StorageType* data() { assert(validData()); return mData.get(); }
inline const StorageType* data() const { assert(validData()); return mData.get(); }
/// Verify that data is not out-of-core or in a partially-read state
inline bool validData() const { return !(isOutOfCore() || (flags() & PARTIALREAD)); }
private:
friend class ::TestAttributeArray;
TypedAttributeArray(const TypedAttributeArray&, const tbb::spin_mutex::scoped_lock&);
/// Load data from memory-mapped file.
inline void doLoad() const;
/// Load data from memory-mapped file (unsafe as this function is not protected by a mutex).
#if OPENVDB_ABI_VERSION_NUMBER >= 10
inline void doLoadUnsafe() const;
#else
/// @param compression parameter no longer used
inline void doLoadUnsafe(const bool compression = true) const;
/// Compress in-core data assuming mutex is locked
inline bool compressUnsafe();
#endif
/// Toggle out-of-core state
inline void setOutOfCore(const bool);
/// Compare the this data to another attribute array. Used by the base class comparison operator
bool isEqual(const AttributeArray& other) const override;
/// Virtual function to retrieve the data buffer from the derived class cast to a char byte array
char* dataAsByteArray() override;
const char* dataAsByteArray() const override;
size_t arrayMemUsage() const;
void allocate();
void deallocate();
/// Helper function for use with registerType()
static AttributeArray::Ptr factory(Index n, Index strideOrTotalSize, bool constantStride,
const Metadata* metadata) {
return TypedAttributeArray::create(n, strideOrTotalSize, constantStride, metadata);
}
static std::unique_ptr<const NamePair> sTypeName;
std::unique_ptr<StorageType[]> mData;
Index mSize;
Index mStrideOrTotalSize;
}; // class TypedAttributeArray
////////////////////////////////////////
/// AttributeHandles provide access to specific TypedAttributeArray methods without needing
/// to know the compression codec, however these methods also incur the cost of a function pointer
template <typename ValueType, typename CodecType = UnknownCodec>
class AttributeHandle
{
public:
using Handle = AttributeHandle<ValueType, CodecType>;
using Ptr = std::shared_ptr<Handle>;
using UniquePtr = std::unique_ptr<Handle>;
protected:
using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
using ValuePtr = void (*)(AttributeArray* array, const ValueType& value);
public:
static Ptr create(const AttributeArray& array, const bool collapseOnDestruction = true);
AttributeHandle(const AttributeArray& array, const bool collapseOnDestruction = true);
AttributeHandle(const AttributeHandle&) = default;
AttributeHandle& operator=(const AttributeHandle&) = default;
virtual ~AttributeHandle();
Index stride() const { return mStrideOrTotalSize; }
Index size() const { return mSize; }
bool isUniform() const;
bool hasConstantStride() const;
ValueType get(Index n, Index m = 0) const;
const AttributeArray& array() const;
protected:
Index index(Index n, Index m) const;
const AttributeArray* mArray;
GetterPtr mGetter;
SetterPtr mSetter;
ValuePtr mCollapser;
ValuePtr mFiller;
private:
friend class ::TestAttributeArray;
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, bool>::type compatibleType() const;
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, bool>::type compatibleType() const;
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, ValueType>::type get(Index index) const;
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, ValueType>::type get(Index index) const;
// local copy of AttributeArray (to preserve compression)
AttributeArray::Ptr mLocalArray;
Index mStrideOrTotalSize;
Index mSize;
bool mCollapseOnDestruction;
}; // class AttributeHandle
////////////////////////////////////////
/// Write-able version of AttributeHandle
template <typename ValueType, typename CodecType = UnknownCodec>
class AttributeWriteHandle : public AttributeHandle<ValueType, CodecType>
{
public:
using Handle = AttributeWriteHandle<ValueType, CodecType>;
using Ptr = std::shared_ptr<Handle>;
using ScopedPtr = std::unique_ptr<Handle>;
static Ptr create(AttributeArray& array, const bool expand = true);
AttributeWriteHandle(AttributeArray& array, const bool expand = true);
virtual ~AttributeWriteHandle() = default;
/// @brief If this array is uniform, replace it with an array of length size().
/// @param fill if true, assign the uniform value to each element of the array.
void expand(bool fill = true);
/// Replace the existing array with a uniform value (zero if none provided).
void collapse();
void collapse(const ValueType& uniformValue);
/// Compact the existing array to become uniform if all values are identical
bool compact();
/// @brief Fill the existing array with the given value.
/// @note Identical to collapse() except a non-uniform array will not become uniform.
void fill(const ValueType& value);
void set(Index n, const ValueType& value);
void set(Index n, Index m, const ValueType& value);
AttributeArray& array();
private:
friend class ::TestAttributeArray;
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
}; // class AttributeWriteHandle
////////////////////////////////////////
// Attribute codec implementation
template<typename ValueType>
inline void
NullCodec::decode(const ValueType& data, ValueType& val)
{
val = data;
}
template<typename ValueType>
inline void
NullCodec::encode(const ValueType& val, ValueType& data)
{
data = val;
}
template<typename StorageType, typename ValueType>
inline void
TruncateCodec::decode(const StorageType& data, ValueType& val)
{
val = static_cast<ValueType>(data);
}
template<typename StorageType, typename ValueType>
inline void
TruncateCodec::encode(const ValueType& val, StorageType& data)
{
data = static_cast<StorageType>(val);
}
template <bool OneByte, typename Range>
template<typename StorageType, typename ValueType>
inline void
FixedPointCodec<OneByte, Range>::decode(const StorageType& data, ValueType& val)
{
val = fixedPointToFloatingPoint<ValueType>(data);
// shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
val = Range::template decode<ValueType>(val);
}
template <bool OneByte, typename Range>
template<typename StorageType, typename ValueType>
inline void
FixedPointCodec<OneByte, Range>::encode(const ValueType& val, StorageType& data)
{
// shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
const ValueType newVal = Range::template encode<ValueType>(val);
data = floatingPointToFixedPoint<StorageType>(newVal);
}
template<typename T>
inline void
UnitVecCodec::decode(const StorageType& data, math::Vec3<T>& val)
{
val = math::QuantizedUnitVec::unpack(data);
}
template<typename T>
inline void
UnitVecCodec::encode(const math::Vec3<T>& val, StorageType& data)
{
data = math::QuantizedUnitVec::pack(val);
}
////////////////////////////////////////
// AttributeArray implementation
template <typename IterT>
void AttributeArray::doCopyValues(const AttributeArray& sourceArray, const IterT& iter,
bool rangeChecking/*=true*/)
{
// ensure both arrays have float-float or integer-integer value types
assert(sourceArray.valueTypeIsFloatingPoint() == this->valueTypeIsFloatingPoint());
// ensure both arrays have been loaded from disk (if delay-loaded)
assert(sourceArray.isDataLoaded() && this->isDataLoaded());
// ensure storage size * stride matches on both arrays
assert(this->storageTypeSize()*this->stride() ==
sourceArray.storageTypeSize()*sourceArray.stride());
const size_t bytes(sourceArray.storageTypeSize()*sourceArray.stride());
const char* const sourceBuffer = sourceArray.dataAsByteArray();
char* const targetBuffer = this->dataAsByteArray();
assert(sourceBuffer && targetBuffer);
if (rangeChecking && this->isUniform()) {
OPENVDB_THROW(IndexError, "Cannot copy array data as target array is uniform.");
}
const bool sourceIsUniform = sourceArray.isUniform();
const Index sourceDataSize = rangeChecking ? sourceArray.dataSize() : 0;
const Index targetDataSize = rangeChecking ? this->dataSize() : 0;
for (IterT it(iter); it; ++it) {
const Index sourceIndex = sourceIsUniform ? 0 : it.sourceIndex();
const Index targetIndex = it.targetIndex();
if (rangeChecking) {
if (sourceIndex >= sourceDataSize) {
OPENVDB_THROW(IndexError,
"Cannot copy array data as source index exceeds size of source array.");
}
if (targetIndex >= targetDataSize) {
OPENVDB_THROW(IndexError,
"Cannot copy array data as target index exceeds size of target array.");
}
} else {
// range-checking asserts
assert(sourceIndex < sourceArray.dataSize());
assert(targetIndex < this->dataSize());
if (this->isUniform()) assert(targetIndex == Index(0));
}
const size_t targetOffset(targetIndex * bytes);
const size_t sourceOffset(sourceIndex * bytes);
std::memcpy(targetBuffer + targetOffset, sourceBuffer + sourceOffset, bytes);
}
}
template <typename IterT>
void AttributeArray::copyValuesUnsafe(const AttributeArray& sourceArray, const IterT& iter)
{
this->doCopyValues(sourceArray, iter, /*range-checking=*/false);
}
template <typename IterT>
void AttributeArray::copyValues(const AttributeArray& sourceArray, const IterT& iter,
bool compact/* = true*/)
{
const Index bytes = sourceArray.storageTypeSize();
if (bytes != this->storageTypeSize()) {
OPENVDB_THROW(TypeError, "Cannot copy array data due to mis-match in storage type sizes.");
}
// ensure both arrays have been loaded from disk
sourceArray.loadData();
this->loadData();
// if the target array is uniform, expand it first
this->expand();
// TODO: Acquire mutex locks for source and target arrays to ensure that
// value copying is always thread-safe. Note that the unsafe method will be
// faster, but can only be used if neither the source or target arrays are
// modified during copying. Note that this will require a new private
// virtual method with ABI=7 to access the mutex from the derived class.
this->doCopyValues(sourceArray, iter, true);
// attempt to compact target array
if (compact) {
this->compact();
}
}
////////////////////////////////////////
// TypedAttributeArray implementation
template<typename ValueType_, typename Codec_>
std::unique_ptr<const NamePair> TypedAttributeArray<ValueType_, Codec_>::sTypeName;
template<typename ValueType_, typename Codec_>
TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(
Index n, Index strideOrTotalSize, bool constantStride, const ValueType& uniformValue)
: AttributeArray()
, mData(new StorageType[1])
, mSize(n)
, mStrideOrTotalSize(strideOrTotalSize)
{
if (constantStride) {
this->setConstantStride(true);
if (strideOrTotalSize == 0) {
OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a constant stride requires that " \
"stride to be at least one.")
}
}
else {
this->setConstantStride(false);
if (mStrideOrTotalSize < n) {
OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a non-constant stride must have " \
"a total size of at least the number of elements in the array.")
}
}
mSize = std::max(Index(1), mSize);
mStrideOrTotalSize = std::max(Index(1), mStrideOrTotalSize);
Codec::encode(uniformValue, this->data()[0]);
}
template<typename ValueType_, typename Codec_>
TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs)
: TypedAttributeArray(rhs, tbb::spin_mutex::scoped_lock(rhs.mMutex))
{
}
template<typename ValueType_, typename Codec_>
TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs,
const tbb::spin_mutex::scoped_lock& lock)
: AttributeArray(rhs, lock)
, mSize(rhs.mSize)
, mStrideOrTotalSize(rhs.mStrideOrTotalSize)
{
if (this->validData()) {
this->allocate();
std::memcpy(static_cast<void*>(this->data()), rhs.data(), this->arrayMemUsage());
}
}
template<typename ValueType_, typename Codec_>
TypedAttributeArray<ValueType_, Codec_>&
TypedAttributeArray<ValueType_, Codec_>::operator=(const TypedAttributeArray& rhs)
{
if (&rhs != this) {
// lock both the source and target arrays to ensure thread-safety
tbb::spin_mutex::scoped_lock lock(mMutex);
tbb::spin_mutex::scoped_lock rhsLock(rhs.mMutex);
this->deallocate();
mFlags = rhs.mFlags;
mUsePagedRead = rhs.mUsePagedRead;
mSize = rhs.mSize;
mStrideOrTotalSize = rhs.mStrideOrTotalSize;
mIsUniform = rhs.mIsUniform;
if (this->validData()) {
this->allocate();
std::memcpy(static_cast<void*>(this->data()), rhs.data(), this->arrayMemUsage());
}
}
return *this;
}
template<typename ValueType_, typename Codec_>
inline const NamePair&
TypedAttributeArray<ValueType_, Codec_>::attributeType()
{
static std::once_flag once;
std::call_once(once, []()
{
sTypeName.reset(new NamePair(typeNameAsString<ValueType>(), Codec::name()));
});
return *sTypeName;
}
template<typename ValueType_, typename Codec_>
inline bool
TypedAttributeArray<ValueType_, Codec_>::isRegistered()
{
return AttributeArray::isRegistered(TypedAttributeArray::attributeType());
}
template<typename ValueType_, typename Codec_>
inline void
TypedAttributeArray<ValueType_, Codec_>::registerType()
{
AttributeArray::registerType(TypedAttributeArray::attributeType(), TypedAttributeArray::factory);
}
template<typename ValueType_, typename Codec_>
inline void
TypedAttributeArray<ValueType_, Codec_>::unregisterType()
{
AttributeArray::unregisterType(TypedAttributeArray::attributeType());
}
template<typename ValueType_, typename Codec_>
inline typename TypedAttributeArray<ValueType_, Codec_>::Ptr
TypedAttributeArray<ValueType_, Codec_>::create(Index n, Index stride, bool constantStride,
const Metadata* metadata)
{
const TypedMetadata<ValueType>* typedMetadata = metadata ?
dynamic_cast<const TypedMetadata<ValueType>*>(metadata) : nullptr;
return Ptr(new TypedAttributeArray(n, stride, constantStride,
typedMetadata ? typedMetadata->value() : zeroVal<ValueType>()));
}
template<typename ValueType_, typename Codec_>
inline TypedAttributeArray<ValueType_, Codec_>&
TypedAttributeArray<ValueType_, Codec_>::cast(AttributeArray& attributeArray)
{
if (!attributeArray.isType<TypedAttributeArray>()) {
OPENVDB_THROW(TypeError, "Invalid Attribute Type");
}
return static_cast<TypedAttributeArray&>(attributeArray);
}
template<typename ValueType_, typename Codec_>
inline const TypedAttributeArray<ValueType_, Codec_>&
TypedAttributeArray<ValueType_, Codec_>::cast(const AttributeArray& attributeArray)
{
if (!attributeArray.isType<TypedAttributeArray>()) {
OPENVDB_THROW(TypeError, "Invalid Attribute Type");
}
return static_cast<const TypedAttributeArray&>(attributeArray);
}
template<typename ValueType_, typename Codec_>
AttributeArray::Ptr
TypedAttributeArray<ValueType_, Codec_>::copy() const
{
return AttributeArray::Ptr(new TypedAttributeArray<ValueType, Codec>(*this));
}
#if OPENVDB_ABI_VERSION_NUMBER < 10
template<typename ValueType_, typename Codec_>
AttributeArray::Ptr
TypedAttributeArray<ValueType_, Codec_>::copyUncompressed() const
{
return this->copy();
}
#endif
template<typename ValueType_, typename Codec_>
size_t
TypedAttributeArray<ValueType_, Codec_>::arrayMemUsage() const
{
if (this->isOutOfCore()) return 0;
return (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::allocate()
{
assert(!mData);
if (mIsUniform) {
mData.reset(new StorageType[1]);
}
else {
const size_t size(this->dataSize());
assert(size > 0);
mData.reset(new StorageType[size]);
}
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::deallocate()
{
// detach from file if delay-loaded
if (this->isOutOfCore()) {
this->setOutOfCore(false);
this->mPageHandle.reset();
}
if (mData) mData.reset();
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::valueTypeIsFloatingPoint() const
{
// TODO: Update to use Traits that correctly handle matrices and quaternions.
if (std::is_same<ValueType, Quats>::value ||
std::is_same<ValueType, Quatd>::value ||
std::is_same<ValueType, Mat3s>::value ||
std::is_same<ValueType, Mat3d>::value ||
std::is_same<ValueType, Mat4s>::value ||
std::is_same<ValueType, Mat4d>::value) return true;
using ElementT = typename VecTraits<ValueType>::ElementType;
// half is not defined as float point as expected, so explicitly handle it
return std::is_floating_point<ElementT>::value || std::is_same<math::half, ElementT>::value;
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::valueTypeIsClass() const
{
// half is not defined as a non-class type as expected, so explicitly exclude it
return std::is_class<ValueType>::value && !std::is_same<math::half, ValueType>::value;
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::valueTypeIsVector() const
{
return VecTraits<ValueType>::IsVec;
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::valueTypeIsQuaternion() const
{
// TODO: improve performance by making this a compile-time check using type traits
return !this->valueType().compare(0, 4, "quat");
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::valueTypeIsMatrix() const
{
// TODO: improve performance by making this a compile-time check using type traits
return !this->valueType().compare(0, 3, "mat");
}
template<typename ValueType_, typename Codec_>
size_t
TypedAttributeArray<ValueType_, Codec_>::memUsage() const
{
return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
}
#if OPENVDB_ABI_VERSION_NUMBER >= 10
template<typename ValueType_, typename Codec_>
size_t
TypedAttributeArray<ValueType_, Codec_>::memUsageIfLoaded() const
{
return sizeof(*this) + (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType);
}
#endif
template<typename ValueType_, typename Codec_>
typename TypedAttributeArray<ValueType_, Codec_>::ValueType
TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n) const
{
assert(n < this->dataSize());
ValueType val;
Codec::decode(/*in=*/this->data()[mIsUniform ? 0 : n], /*out=*/val);
return val;
}
template<typename ValueType_, typename Codec_>
typename TypedAttributeArray<ValueType_, Codec_>::ValueType
TypedAttributeArray<ValueType_, Codec_>::get(Index n) const
{
if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
if (this->isOutOfCore()) this->doLoad();
return this->getUnsafe(n);
}
template<typename ValueType_, typename Codec_>
template<typename T>
void
TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n, T& val) const
{
val = static_cast<T>(this->getUnsafe(n));
}
template<typename ValueType_, typename Codec_>
template<typename T>
void
TypedAttributeArray<ValueType_, Codec_>::get(Index n, T& val) const
{
val = static_cast<T>(this->get(n));
}
template<typename ValueType_, typename Codec_>
typename TypedAttributeArray<ValueType_, Codec_>::ValueType
TypedAttributeArray<ValueType_, Codec_>::getUnsafe(const AttributeArray* array, const Index n)
{
return static_cast<const TypedAttributeArray<ValueType, Codec>*>(array)->getUnsafe(n);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const ValueType& val)
{
assert(n < this->dataSize());
assert(!this->isOutOfCore());
assert(!this->isUniform());
// this unsafe method assumes the data is not uniform, however if it is, this redirects the index
// to zero, which is marginally less efficient but ensures not writing to an illegal address
Codec::encode(/*in=*/val, /*out=*/this->data()[mIsUniform ? 0 : n]);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::set(Index n, const ValueType& val)
{
if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
if (this->isOutOfCore()) this->doLoad();
if (this->isUniform()) this->expand();
this->setUnsafe(n, val);
}
template<typename ValueType_, typename Codec_>
template<typename T>
void
TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const T& val)
{
this->setUnsafe(n, static_cast<ValueType>(val));
}
template<typename ValueType_, typename Codec_>
template<typename T>
void
TypedAttributeArray<ValueType_, Codec_>::set(Index n, const T& val)
{
this->set(n, static_cast<ValueType>(val));
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::setUnsafe(AttributeArray* array, const Index n, const ValueType& value)
{
static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->setUnsafe(n, value);
}
#if OPENVDB_ABI_VERSION_NUMBER < 10
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::set(Index n, const AttributeArray& sourceArray, const Index sourceIndex)
{
const TypedAttributeArray& sourceTypedArray = static_cast<const TypedAttributeArray&>(sourceArray);
ValueType sourceValue;
sourceTypedArray.get(sourceIndex, sourceValue);
this->set(n, sourceValue);
}
#endif
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::expand(bool fill)
{
if (!mIsUniform) return;
const StorageType val = this->data()[0];
{
tbb::spin_mutex::scoped_lock lock(mMutex);
this->deallocate();
mIsUniform = false;
this->allocate();
}
if (fill) {
for (Index i = 0; i < this->dataSize(); ++i) this->data()[i] = val;
}
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::compact()
{
if (mIsUniform) return true;
// compaction is not possible if any values are different
const ValueType_ val = this->get(0);
for (Index i = 1; i < this->dataSize(); i++) {
if (!math::isExactlyEqual(this->get(i), val)) return false;
}
this->collapse(this->get(0));
return true;
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::collapse()
{
this->collapse(zeroVal<ValueType>());
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::collapse(const ValueType& uniformValue)
{
if (!mIsUniform) {
tbb::spin_mutex::scoped_lock lock(mMutex);
this->deallocate();
mIsUniform = true;
this->allocate();
}
Codec::encode(uniformValue, this->data()[0]);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::collapse(AttributeArray* array, const ValueType& value)
{
static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->collapse(value);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::fill(const ValueType& value)
{
if (this->isOutOfCore()) {
tbb::spin_mutex::scoped_lock lock(mMutex);
this->deallocate();
this->allocate();
}
const Index size = mIsUniform ? 1 : this->dataSize();
for (Index i = 0; i < size; ++i) {
Codec::encode(value, this->data()[i]);
}
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::fill(AttributeArray* array, const ValueType& value)
{
static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->fill(value);
}
#if OPENVDB_ABI_VERSION_NUMBER < 10
template<typename ValueType_, typename Codec_>
inline bool
TypedAttributeArray<ValueType_, Codec_>::compress()
{
return false;
}
template<typename ValueType_, typename Codec_>
inline bool
TypedAttributeArray<ValueType_, Codec_>::compressUnsafe()
{
return false;
}
template<typename ValueType_, typename Codec_>
inline bool
TypedAttributeArray<ValueType_, Codec_>::decompress()
{
return false;
}
#endif
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::isOutOfCore() const
{
return mOutOfCore;
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::setOutOfCore(const bool b)
{
mOutOfCore = b;
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::doLoad() const
{
if (!(this->isOutOfCore())) return;
TypedAttributeArray<ValueType_, Codec_>* self =
const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
// This lock will be contended at most once, after which this buffer
// will no longer be out-of-core.
tbb::spin_mutex::scoped_lock lock(self->mMutex);
this->doLoadUnsafe();
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::loadData() const
{
this->doLoad();
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::isDataLoaded() const
{
return !this->isOutOfCore();
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::read(std::istream& is)
{
this->readMetadata(is);
this->readBuffers(is);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::readMetadata(std::istream& is)
{
// read data
Index64 bytes = Index64(0);
is.read(reinterpret_cast<char*>(&bytes), sizeof(Index64));
bytes = bytes - /*flags*/sizeof(Int16) - /*size*/sizeof(Index);
uint8_t flags = uint8_t(0);
is.read(reinterpret_cast<char*>(&flags), sizeof(uint8_t));
mFlags = flags;
uint8_t serializationFlags = uint8_t(0);
is.read(reinterpret_cast<char*>(&serializationFlags), sizeof(uint8_t));
Index size = Index(0);
is.read(reinterpret_cast<char*>(&size), sizeof(Index));
mSize = size;
// warn if an unknown flag has been set
if (mFlags >= 0x20) {
OPENVDB_LOG_WARN("Unknown attribute flags for VDB file format.");
}
// error if an unknown serialization flag has been set,
// as this will adjust the layout of the data and corrupt the ability to read
if (serializationFlags >= 0x10) {
OPENVDB_THROW(IoError, "Unknown attribute serialization flags for VDB file format.");
}
// set uniform, compressed and page read state
mIsUniform = serializationFlags & WRITEUNIFORM;
mUsePagedRead = serializationFlags & WRITEPAGED;
mCompressedBytes = bytes;
mFlags |= PARTIALREAD; // mark data as having been partially read
// read strided value (set to 1 if array is not strided)
if (serializationFlags & WRITESTRIDED) {
Index stride = Index(0);
is.read(reinterpret_cast<char*>(&stride), sizeof(Index));
mStrideOrTotalSize = stride;
}
else {
mStrideOrTotalSize = 1;
}
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::readBuffers(std::istream& is)
{
if (mUsePagedRead) {
// use readBuffers(PagedInputStream&) for paged buffers
OPENVDB_THROW(IoError, "Cannot read paged AttributeArray buffers.");
}
tbb::spin_mutex::scoped_lock lock(mMutex);
this->deallocate();
uint8_t bloscCompressed(0);
if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed), sizeof(uint8_t));
assert(mFlags & PARTIALREAD);
std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
is.read(buffer.get(), mCompressedBytes);
mCompressedBytes = 0;
mFlags = static_cast<uint8_t>(mFlags & ~PARTIALREAD); // mark data read as having completed
// compressed on-disk
if (bloscCompressed == uint8_t(1)) {
// decompress buffer
const size_t inBytes = this->dataSize() * sizeof(StorageType);
std::unique_ptr<char[]> newBuffer = compression::bloscDecompress(buffer.get(), inBytes);
if (newBuffer) buffer.reset(newBuffer.release());
}
// set data to buffer
mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::readPagedBuffers(compression::PagedInputStream& is)
{
if (!mUsePagedRead) {
if (!is.sizeOnly()) this->readBuffers(is.getInputStream());
return;
}
#ifdef OPENVDB_USE_DELAYED_LOADING
// If this array is being read from a memory-mapped file, delay loading of its data
// until the data is actually accessed.
io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is.getInputStream());
const bool delayLoad = (mappedFile.get() != nullptr);
#endif
if (is.sizeOnly())
{
size_t compressedBytes(mCompressedBytes);
mCompressedBytes = 0; // if not set to zero, mPageHandle will attempt to destroy invalid memory
mFlags = static_cast<uint8_t>(mFlags & ~PARTIALREAD); // mark data read as having completed
assert(!mPageHandle);
mPageHandle = is.createHandle(compressedBytes);
return;
}
assert(mPageHandle);
tbb::spin_mutex::scoped_lock lock(mMutex);
this->deallocate();
#ifdef OPENVDB_USE_DELAYED_LOADING
this->setOutOfCore(delayLoad);
is.read(mPageHandle, std::streamsize(mPageHandle->size()), delayLoad);
#else
is.read(mPageHandle, std::streamsize(mPageHandle->size()), false);
#endif // OPENVDB_USE_DELAYED_LOADING
#ifdef OPENVDB_USE_DELAYED_LOADING
if (!delayLoad) {
#endif
std::unique_ptr<char[]> buffer = mPageHandle->read();
mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
mPageHandle.reset();
#ifdef OPENVDB_USE_DELAYED_LOADING
}
#endif
// clear page state
mUsePagedRead = 0;
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os) const
{
this->write(os, /*outputTransient=*/false);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os, bool outputTransient) const
{
this->writeMetadata(os, outputTransient, /*paged=*/false);
this->writeBuffers(os, outputTransient);
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::writeMetadata(std::ostream& os, bool outputTransient, bool paged) const
{
if (!outputTransient && this->isTransient()) return;
if (mFlags & PARTIALREAD) {
OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
}
uint8_t flags(mFlags);
uint8_t serializationFlags(0);
Index size(mSize);
Index stride(mStrideOrTotalSize);
bool strideOfOne(this->stride() == 1);
bool bloscCompression = io::getDataCompression(os) & io::COMPRESS_BLOSC;
// any compressed data needs to be loaded if out-of-core
if (bloscCompression) this->doLoad();
size_t compressedBytes = 0;
if (!strideOfOne)
{
serializationFlags |= WRITESTRIDED;
}
if (mIsUniform)
{
serializationFlags |= WRITEUNIFORM;
if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
}
else if (bloscCompression)
{
if (paged) serializationFlags |= WRITEPAGED;
else {
const char* charBuffer = reinterpret_cast<const char*>(this->data());
const size_t inBytes = this->arrayMemUsage();
compressedBytes = compression::bloscCompressedSize(charBuffer, inBytes);
}
}
Index64 bytes = /*flags*/ sizeof(Int16) + /*size*/ sizeof(Index);
bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
// write data
os.write(reinterpret_cast<const char*>(&bytes), sizeof(Index64));
os.write(reinterpret_cast<const char*>(&flags), sizeof(uint8_t));
os.write(reinterpret_cast<const char*>(&serializationFlags), sizeof(uint8_t));
os.write(reinterpret_cast<const char*>(&size), sizeof(Index));
// write strided
if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride), sizeof(Index));
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::writeBuffers(std::ostream& os, bool outputTransient) const
{
if (!outputTransient && this->isTransient()) return;
if (mFlags & PARTIALREAD) {
OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
}
this->doLoad();
if (this->isUniform()) {
os.write(reinterpret_cast<const char*>(this->data()), sizeof(StorageType));
}
else if (io::getDataCompression(os) & io::COMPRESS_BLOSC)
{
std::unique_ptr<char[]> compressedBuffer;
size_t compressedBytes = 0;
const char* charBuffer = reinterpret_cast<const char*>(this->data());
const size_t inBytes = this->arrayMemUsage();
compressedBuffer = compression::bloscCompress(charBuffer, inBytes, compressedBytes);
if (compressedBuffer) {
uint8_t bloscCompressed(1);
os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
}
else {
uint8_t bloscCompressed(0);
os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
os.write(reinterpret_cast<const char*>(this->data()), inBytes);
}
}
else
{
uint8_t bloscCompressed(0);
os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
os.write(reinterpret_cast<const char*>(this->data()), this->arrayMemUsage());
}
}
template<typename ValueType_, typename Codec_>
void
TypedAttributeArray<ValueType_, Codec_>::writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const
{
if (!outputTransient && this->isTransient()) return;
// paged compression only available when Blosc is enabled
bool bloscCompression = io::getDataCompression(os.getOutputStream()) & io::COMPRESS_BLOSC;
if (!bloscCompression) {
if (!os.sizeOnly()) this->writeBuffers(os.getOutputStream(), outputTransient);
return;
}
if (mFlags & PARTIALREAD) {
OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
}
this->doLoad();
os.write(reinterpret_cast<const char*>(this->data()), this->arrayMemUsage());
}
template<typename ValueType_, typename Codec_>
void
#if OPENVDB_ABI_VERSION_NUMBER >= 10
TypedAttributeArray<ValueType_, Codec_>::doLoadUnsafe() const
#else
TypedAttributeArray<ValueType_, Codec_>::doLoadUnsafe(const bool /*compression*/) const
#endif
{
if (!(this->isOutOfCore())) return;
// this function expects the mutex to already be locked
auto* self = const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
assert(self->mPageHandle);
assert(!(self->mFlags & PARTIALREAD));
std::unique_ptr<char[]> buffer = self->mPageHandle->read();
self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
self->mPageHandle.reset();
// clear all write and out-of-core flags
self->mOutOfCore = false;
}
template<typename ValueType_, typename Codec_>
AttributeArray::AccessorBasePtr
TypedAttributeArray<ValueType_, Codec_>::getAccessor() const
{
// use the faster 'unsafe' get and set methods as attribute handles
// ensure data is in-core when constructed
return AccessorBasePtr(new AttributeArray::Accessor<ValueType_>(
&TypedAttributeArray<ValueType_, Codec_>::getUnsafe,
&TypedAttributeArray<ValueType_, Codec_>::setUnsafe,
&TypedAttributeArray<ValueType_, Codec_>::collapse,
&TypedAttributeArray<ValueType_, Codec_>::fill));
}
template<typename ValueType_, typename Codec_>
bool
TypedAttributeArray<ValueType_, Codec_>::isEqual(const AttributeArray& other) const
{
const TypedAttributeArray<ValueType_, Codec_>* const otherT = dynamic_cast<const TypedAttributeArray<ValueType_, Codec_>* >(&other);
if(!otherT) return false;
if(this->mSize != otherT->mSize ||
this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
this->mIsUniform != otherT->mIsUniform ||
this->attributeType() != this->attributeType()) return false;
this->doLoad();
otherT->doLoad();
const StorageType *target = this->data(), *source = otherT->data();
if (!target && !source) return true;
if (!target || !source) return false;
Index n = this->mIsUniform ? 1 : mSize;
while (n && math::isExactlyEqual(*target++, *source++)) --n;
return n == 0;
}
template<typename ValueType_, typename Codec_>
char*
TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
{
return reinterpret_cast<char*>(this->data());
}
template<typename ValueType_, typename Codec_>
const char*
TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray() const
{
return reinterpret_cast<const char*>(this->data());
}
////////////////////////////////////////
/// Accessor to call unsafe get and set methods based on templated Codec and Value
template <typename CodecType, typename ValueType>
struct AccessorEval
{
using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
/// Getter that calls to TypedAttributeArray::getUnsafe()
/// @note Functor argument is provided but not required for the generic case
static ValueType get(GetterPtr /*functor*/, const AttributeArray* array, const Index n) {
return TypedAttributeArray<ValueType, CodecType>::getUnsafe(array, n);
}
/// Getter that calls to TypedAttributeArray::setUnsafe()
/// @note Functor argument is provided but not required for the generic case
static void set(SetterPtr /*functor*/, AttributeArray* array, const Index n, const ValueType& value) {
TypedAttributeArray<ValueType, CodecType>::setUnsafe(array, n, value);
}
};
/// Partial specialization when Codec is not known at compile-time to use the supplied functor instead
template <typename ValueType>
struct AccessorEval<UnknownCodec, ValueType>
{
using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
/// Getter that calls the supplied functor
static ValueType get(GetterPtr functor, const AttributeArray* array, const Index n) {
return (*functor)(array, n);
}
/// Setter that calls the supplied functor
static void set(SetterPtr functor, AttributeArray* array, const Index n, const ValueType& value) {
(*functor)(array, n, value);
}
};
////////////////////////////////////////
// AttributeHandle implementation
template <typename ValueType, typename CodecType>
typename AttributeHandle<ValueType, CodecType>::Ptr
AttributeHandle<ValueType, CodecType>::create(const AttributeArray& array, const bool collapseOnDestruction)
{
return typename AttributeHandle<ValueType, CodecType>::Ptr(
new AttributeHandle<ValueType, CodecType>(array, collapseOnDestruction));
}
template <typename ValueType, typename CodecType>
AttributeHandle<ValueType, CodecType>::AttributeHandle(const AttributeArray& array, const bool collapseOnDestruction)
: mArray(&array)
, mStrideOrTotalSize(array.hasConstantStride() ? array.stride() : 1)
, mSize(array.hasConstantStride() ? array.size() : array.dataSize())
, mCollapseOnDestruction(collapseOnDestruction && array.isStreaming())
{
if (!this->compatibleType<std::is_same<CodecType, UnknownCodec>::value>()) {
OPENVDB_THROW(TypeError, "Cannot bind handle due to incompatible type of AttributeArray.");
}
// load data if delay-loaded
mArray->loadData();
// bind getter and setter methods
AttributeArray::AccessorBasePtr accessor = mArray->getAccessor();
assert(accessor);
AttributeArray::Accessor<ValueType>* typedAccessor = static_cast<AttributeArray::Accessor<ValueType>*>(accessor.get());
mGetter = typedAccessor->mGetter;
mSetter = typedAccessor->mSetter;
mCollapser = typedAccessor->mCollapser;
mFiller = typedAccessor->mFiller;
}
template <typename ValueType, typename CodecType>
AttributeHandle<ValueType, CodecType>::~AttributeHandle()
{
// if enabled, attribute is collapsed on destruction of the handle to save memory
if (mCollapseOnDestruction) const_cast<AttributeArray*>(this->mArray)->collapse();
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, bool>::type
AttributeHandle<ValueType, CodecType>::compatibleType() const
{
// if codec is unknown, just check the value type
return mArray->hasValueType<ValueType>();
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, bool>::type
AttributeHandle<ValueType, CodecType>::compatibleType() const
{
// if the codec is known, check the value type and codec
return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
}
template <typename ValueType, typename CodecType>
const AttributeArray& AttributeHandle<ValueType, CodecType>::array() const
{
assert(mArray);
return *mArray;
}
template <typename ValueType, typename CodecType>
Index AttributeHandle<ValueType, CodecType>::index(Index n, Index m) const
{
Index index = n * mStrideOrTotalSize + m;
assert(index < (mSize * mStrideOrTotalSize));
return index;
}
template <typename ValueType, typename CodecType>
ValueType AttributeHandle<ValueType, CodecType>::get(Index n, Index m) const
{
return this->get<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m));
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, ValueType>::type
AttributeHandle<ValueType, CodecType>::get(Index index) const
{
// if the codec is unknown, use the getter functor
return (*mGetter)(mArray, index);
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, ValueType>::type
AttributeHandle<ValueType, CodecType>::get(Index index) const
{
// if the codec is known, call the method on the attribute array directly
return TypedAttributeArray<ValueType, CodecType>::getUnsafe(mArray, index);
}
template <typename ValueType, typename CodecType>
bool AttributeHandle<ValueType, CodecType>::isUniform() const
{
return mArray->isUniform();
}
template <typename ValueType, typename CodecType>
bool AttributeHandle<ValueType, CodecType>::hasConstantStride() const
{
return mArray->hasConstantStride();
}
////////////////////////////////////////
// AttributeWriteHandle implementation
template <typename ValueType, typename CodecType>
typename AttributeWriteHandle<ValueType, CodecType>::Ptr
AttributeWriteHandle<ValueType, CodecType>::create(AttributeArray& array, const bool expand)
{
return typename AttributeWriteHandle<ValueType, CodecType>::Ptr(
new AttributeWriteHandle<ValueType, CodecType>(array, expand));
}
template <typename ValueType, typename CodecType>
AttributeWriteHandle<ValueType, CodecType>::AttributeWriteHandle(AttributeArray& array, const bool expand)
: AttributeHandle<ValueType, CodecType>(array, /*collapseOnDestruction=*/false)
{
if (expand) array.expand();
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::set(Index n, const ValueType& value)
{
this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, 0), value);
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::set(Index n, Index m, const ValueType& value)
{
this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m), value);
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::expand(const bool fill)
{
const_cast<AttributeArray*>(this->mArray)->expand(fill);
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::collapse()
{
const_cast<AttributeArray*>(this->mArray)->collapse();
}
template <typename ValueType, typename CodecType>
bool AttributeWriteHandle<ValueType, CodecType>::compact()
{
return const_cast<AttributeArray*>(this->mArray)->compact();
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::collapse(const ValueType& uniformValue)
{
this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
}
template <typename ValueType, typename CodecType>
void AttributeWriteHandle<ValueType, CodecType>::fill(const ValueType& value)
{
this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<IsUnknownCodec, void>::type
AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
{
// if the codec is unknown, use the setter functor
(*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index, value);
}
template <typename ValueType, typename CodecType>
template <bool IsUnknownCodec>
typename std::enable_if<!IsUnknownCodec, void>::type
AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
{
// if the codec is known, call the method on the attribute array directly
TypedAttributeArray<ValueType, CodecType>::setUnsafe(const_cast<AttributeArray*>(this->mArray), index, value);
}
template <typename ValueType, typename CodecType>
AttributeArray& AttributeWriteHandle<ValueType, CodecType>::array()
{
assert(this->mArray);
return *const_cast<AttributeArray*>(this->mArray);
}
} // namespace points
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
Compression.h
value
ValueT value
Definition GridBuilder.h:1290
IndexIterator.h
Index Iterators.
Name.h
OPENVDB_API
#define OPENVDB_API
Definition Platform.h:251
OPENVDB_DEPRECATED_MESSAGE
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:125
QuantizedUnitVec.h
StreamCompression.h
Convenience wrappers to using Blosc and reading and writing of Paged data.
openvdb::v10_0::IndexError
Definition Exceptions.h:57
openvdb::v10_0::IoError
Definition Exceptions.h:58
openvdb::v10_0::Metadata
Base class for storing metadata information in a grid.
Definition Metadata.h:24
openvdb::v10_0::TypeError
Definition Exceptions.h:64
openvdb::v10_0::TypedMetadata
Templated metadata class to hold specific types.
Definition Metadata.h:122
openvdb::v10_0::TypedMetadata::value
T & value()
Return this metadata's value.
Definition Metadata.h:249
openvdb::v10_0::ValueError
Definition Exceptions.h:65
openvdb::v10_0::compression::PageHandle::Ptr
std::unique_ptr< PageHandle > Ptr
Definition StreamCompression.h:172
openvdb::v10_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::v10_0::compression::PagedInputStream::createHandle
PageHandle::Ptr createHandle(std::streamsize n)
Creates a PageHandle to access the next.
openvdb::v10_0::compression::PagedInputStream::sizeOnly
bool sizeOnly() const
Definition StreamCompression.h:217
openvdb::v10_0::compression::PagedInputStream::read
void read(PageHandle::Ptr &pageHandle, std::streamsize n, bool delayed=true)
Takes a pageHandle and updates the referenced page with the current stream pointer position and if de...
openvdb::v10_0::compression::PagedInputStream::getInputStream
std::istream & getInputStream()
Definition StreamCompression.h:220
openvdb::v10_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::v10_0::compression::PagedOutputStream::getOutputStream
std::ostream & getOutputStream()
Set and get the output stream.
Definition StreamCompression.h:257
openvdb::v10_0::compression::PagedOutputStream::sizeOnly
bool sizeOnly() const
Definition StreamCompression.h:254
openvdb::v10_0::compression::PagedOutputStream::write
PagedOutputStream & write(const char *str, std::streamsize n)
Writes the given.
openvdb::v10_0::math::QuantizedUnitVec::unpack
static Vec3s unpack(const uint16_t data)
Definition QuantizedUnitVec.h:86
openvdb::v10_0::math::QuantizedUnitVec::pack
static uint16_t pack(const Vec3< T > &vec)
Definition QuantizedUnitVec.h:48
openvdb::v10_0::math::Vec3
Definition Vec3.h:24
openvdb::v10_0::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition Vec3.h:85
openvdb::v10_0::math::Vec3::y
T & y()
Definition Vec3.h:86
openvdb::v10_0::math::Vec3::z
T & z()
Definition Vec3.h:87
openvdb::v10_0::points::AttributeArray::ScopedRegistryLock
Definition AttributeArray.h:119
openvdb::v10_0::points::AttributeArray::ScopedRegistryLock::ScopedRegistryLock
ScopedRegistryLock()
openvdb::v10_0::points::AttributeArray
Base class for storing attribute data.
Definition AttributeArray.h:93
openvdb::v10_0::points::AttributeArray::valueType
virtual Name valueType() const =0
Return the name of the value type of a single element in this array (e.g., "float" or "vec3d").
openvdb::v10_0::points::AttributeArray::constDataAsByteArray
const char * constDataAsByteArray() const
Indirect virtual function to retrieve the data buffer cast to a char byte array.
Definition AttributeArray.h:363
openvdb::v10_0::points::AttributeArray::AttributeArray
AttributeArray(const AttributeArray &rhs, const tbb::spin_mutex::scoped_lock &)
openvdb::v10_0::points::AttributeArray::setConstantStride
void setConstantStride(bool state)
Specify whether this attribute has a constant stride or not.
openvdb::v10_0::points::AttributeArray::create
static Ptr create(const NamePair &type, Index length, Index stride=1, bool constantStride=true, const Metadata *metadata=nullptr, const ScopedRegistryLock *lock=nullptr)
openvdb::v10_0::points::AttributeArray::isTransient
bool isTransient() const
Return true if this attribute is not serialized during stream output.
Definition AttributeArray.h:306
openvdb::v10_0::points::AttributeArray::SerializationFlag
SerializationFlag
Definition AttributeArray.h:109
openvdb::v10_0::points::AttributeArray::WRITESTRIDED
@ WRITESTRIDED
Definition AttributeArray.h:110
openvdb::v10_0::points::AttributeArray::WRITEUNIFORM
@ WRITEUNIFORM
data is marked as strided when written
Definition AttributeArray.h:111
openvdb::v10_0::points::AttributeArray::WRITEPAGED
@ WRITEPAGED
Definition AttributeArray.h:114
openvdb::v10_0::points::AttributeArray::WRITEMEMCOMPRESS
@ WRITEMEMCOMPRESS
data is marked as uniform when written
Definition AttributeArray.h:112
openvdb::v10_0::points::AttributeArray::operator=
AttributeArray & operator=(const AttributeArray &rhs)
openvdb::v10_0::points::AttributeArray::dataSize
virtual Index dataSize() const =0
openvdb::v10_0::points::AttributeArray::isUniform
virtual bool isUniform() const =0
Return true if this array is stored as a single uniform value.
openvdb::v10_0::points::AttributeArray::readBuffers
virtual void readBuffers(std::istream &)=0
Read attribute buffers from a stream.
openvdb::v10_0::points::AttributeArray::Ptr
std::shared_ptr< AttributeArray > Ptr
Definition AttributeArray.h:125
openvdb::v10_0::points::AttributeArray::~AttributeArray
virtual ~AttributeArray()
Definition AttributeArray.h:133
openvdb::v10_0::points::AttributeArray::mPageHandle
compression::PageHandle::Ptr mPageHandle
Definition AttributeArray.h:405
openvdb::v10_0::points::AttributeArray::Flag
Flag
Definition AttributeArray.h:101
openvdb::v10_0::points::AttributeArray::TRANSIENT
@ TRANSIENT
Definition AttributeArray.h:102
openvdb::v10_0::points::AttributeArray::PARTIALREAD
@ PARTIALREAD
streaming mode collapses attributes when first accessed
Definition AttributeArray.h:106
openvdb::v10_0::points::AttributeArray::HIDDEN
@ HIDDEN
by default not written to disk
Definition AttributeArray.h:103
openvdb::v10_0::points::AttributeArray::CONSTANTSTRIDE
@ CONSTANTSTRIDE
hidden from UIs or iterators
Definition AttributeArray.h:104
openvdb::v10_0::points::AttributeArray::STREAMING
@ STREAMING
stride size does not vary in the array
Definition AttributeArray.h:105
openvdb::v10_0::points::AttributeArray::AttributeArray
AttributeArray()
Definition AttributeArray.h:132
openvdb::v10_0::points::AttributeArray::stride
virtual Index stride() const =0
openvdb::v10_0::points::AttributeArray::isHidden
bool isHidden() const
Return true if this attribute is hidden (e.g., from UI or iterators).
Definition AttributeArray.h:299
openvdb::v10_0::points::AttributeArray::isType
bool isType() const
Return true if this attribute is of the same type as the template parameter.
Definition AttributeArray.h:224
openvdb::v10_0::points::AttributeArray::valueTypeIsQuaternion
virtual bool valueTypeIsQuaternion() const =0
Return true if the value type is a quaternion.
openvdb::v10_0::points::AttributeArray::valueTypeIsVector
virtual bool valueTypeIsVector() const =0
Return true if the value type is a vector.
openvdb::v10_0::points::AttributeArray::copyValuesUnsafe
void copyValuesUnsafe(const AttributeArray &sourceArray, const IterT &iter)
Copy values into this array from a source array to a target array as referenced by an iterator.
Definition AttributeArray.h:1088
openvdb::v10_0::points::AttributeArray::mFlags
uint8_t mFlags
Definition AttributeArray.h:400
openvdb::v10_0::points::AttributeArray::getAccessor
virtual AccessorBasePtr getAccessor() const =0
Obtain an Accessor that stores getter and setter functors.
openvdb::v10_0::points::AttributeArray::setStreaming
void setStreaming(bool state)
Specify whether this attribute is to be streamed off disk, in which case, the attributes are collapse...
openvdb::v10_0::points::AttributeArray::AttributeArray
AttributeArray(const AttributeArray &rhs)
openvdb::v10_0::points::AttributeArray::isDataLoaded
virtual bool isDataLoaded() const =0
Return true if all data has been loaded.
openvdb::v10_0::points::AttributeArray::flags
uint8_t flags() const
Retrieve the attribute array flags.
Definition AttributeArray.h:320
openvdb::v10_0::points::AttributeArray::hasValueType
bool hasValueType() const
Return true if this attribute has a value type the same as the template parameter.
Definition AttributeArray.h:228
openvdb::v10_0::points::AttributeArray::mOutOfCore
std::atomic< Index32 > mOutOfCore
Definition AttributeArray.h:402
openvdb::v10_0::points::AttributeArray::writeBuffers
virtual void writeBuffers(std::ostream &, bool outputTransient) const =0
openvdb::v10_0::points::AttributeArray::clearRegistry
static void clearRegistry(const ScopedRegistryLock *lock=nullptr)
Clear the attribute type registry.
openvdb::v10_0::points::AttributeArray::AccessorBasePtr
std::shared_ptr< AccessorBase > AccessorBasePtr
Definition AttributeArray.h:98
openvdb::v10_0::points::AttributeArray::size
virtual Index size() const =0
openvdb::v10_0::points::AttributeArray::setTransient
void setTransient(bool state)
Specify whether this attribute should only exist in memory and not be serialized during stream output...
openvdb::v10_0::points::AttributeArray::read
virtual void read(std::istream &)=0
Read attribute metadata and buffers from a stream.
openvdb::v10_0::points::AttributeArray::copyValues
void copyValues(const AttributeArray &sourceArray, const IterT &iter, bool compact=true)
Like copyValuesUnsafe(), but if compact is true, attempt to collapse this array.
Definition AttributeArray.h:1094
openvdb::v10_0::points::AttributeArray::setHidden
void setHidden(bool state)
Specify whether this attribute should be hidden (e.g., from UI or iterators).
openvdb::v10_0::points::AttributeArray::write
virtual void write(std::ostream &, bool outputTransient) const =0
openvdb::v10_0::points::AttributeArray::compact
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
openvdb::v10_0::points::AttributeArray::readPagedBuffers
virtual void readPagedBuffers(compression::PagedInputStream &)=0
Read attribute buffers from a paged stream.
openvdb::v10_0::points::AttributeArray::valueTypeIsClass
virtual bool valueTypeIsClass() const =0
Return true if the value type is a class (ie vector, matrix or quaternion return true).
openvdb::v10_0::points::AttributeArray::loadData
virtual void loadData() const =0
Ensures all data is in-core.
openvdb::v10_0::points::AttributeArray::mUsePagedRead
uint8_t mUsePagedRead
Definition AttributeArray.h:401
openvdb::v10_0::points::AttributeArray::valueTypeIsMatrix
virtual bool valueTypeIsMatrix() const =0
Return true if the value type is a matrix.
openvdb::v10_0::points::AttributeArray::operator==
bool operator==(const AttributeArray &other) const
openvdb::v10_0::points::AttributeArray::mMutex
tbb::spin_mutex mMutex
Definition AttributeArray.h:399
openvdb::v10_0::points::AttributeArray::operator!=
bool operator!=(const AttributeArray &other) const
Definition AttributeArray.h:359
openvdb::v10_0::points::AttributeArray::isStreaming
bool isStreaming() const
Return true if this attribute is in streaming mode.
Definition AttributeArray.h:314
openvdb::v10_0::points::AttributeArray::writeMetadata
virtual void writeMetadata(std::ostream &, bool outputTransient, bool paged) const =0
openvdb::v10_0::points::AttributeArray::operator=
AttributeArray & operator=(AttributeArray &&)=delete
openvdb::v10_0::points::AttributeArray::isRegistered
static bool isRegistered(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Return true if the given attribute type name is registered.
openvdb::v10_0::points::AttributeArray::FactoryMethod
Ptr(*)(Index, Index, bool, const Metadata *) FactoryMethod
Definition AttributeArray.h:128
openvdb::v10_0::points::AttributeArray::codecType
virtual Name codecType() const =0
Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
openvdb::v10_0::points::AttributeArray::memUsageIfLoaded
virtual size_t memUsageIfLoaded() const =0
openvdb::v10_0::points::AttributeArray::AttributeHandle
friend class AttributeHandle
Definition AttributeArray.h:130
openvdb::v10_0::points::AttributeArray::readMetadata
virtual void readMetadata(std::istream &)=0
Read attribute metadata from a stream.
openvdb::v10_0::points::AttributeArray::ConstPtr
std::shared_ptr< const AttributeArray > ConstPtr
Definition AttributeArray.h:126
openvdb::v10_0::points::AttributeArray::collapse
virtual void collapse()=0
Replace the existing array with a uniform zero value.
openvdb::v10_0::points::AttributeArray::writePagedBuffers
virtual void writePagedBuffers(compression::PagedOutputStream &, bool outputTransient) const =0
openvdb::v10_0::points::AttributeArray::storageTypeSize
virtual Index storageTypeSize() const =0
openvdb::v10_0::points::AttributeArray::write
virtual void write(std::ostream &) const =0
Write attribute metadata and buffers to a stream, don't write transient attributes.
openvdb::v10_0::points::AttributeArray::registerType
static void registerType(const NamePair &type, FactoryMethod, const ScopedRegistryLock *lock=nullptr)
Register a attribute type along with a factory function.
openvdb::v10_0::points::AttributeArray::copy
virtual AttributeArray::Ptr copy() const =0
Return a copy of this attribute.
openvdb::v10_0::points::AttributeArray::valueTypeSize
virtual Index valueTypeSize() const =0
openvdb::v10_0::points::AttributeArray::valueTypeIsFloatingPoint
virtual bool valueTypeIsFloatingPoint() const =0
Return true if the value type is floating point.
openvdb::v10_0::points::AttributeArray::unregisterType
static void unregisterType(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Remove a attribute type from the registry.
openvdb::v10_0::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition AttributeArray.h:317
openvdb::v10_0::points::AttributeArray::type
virtual const NamePair & type() const =0
Return the name of this attribute's type.
openvdb::v10_0::points::AttributeArray::mCompressedBytes
size_t mCompressedBytes
Definition AttributeArray.h:406
openvdb::v10_0::points::AttributeArray::mIsUniform
bool mIsUniform
Definition AttributeArray.h:398
openvdb::v10_0::points::AttributeArray::expand
virtual void expand(bool fill=true)=0
If this array is uniform, replace it with an array of length size().
openvdb::v10_0::points::AttributeArray::memUsage
virtual size_t memUsage() const =0
Return the number of bytes of memory used by this attribute.
openvdb::v10_0::points::AttributeArray::AttributeArray
AttributeArray(AttributeArray &&)=delete
openvdb::v10_0::points::AttributeHandle::~AttributeHandle
virtual ~AttributeHandle()
Definition AttributeArray.h:2151
openvdb::v10_0::points::AttributeHandle::size
Index size() const
Definition AttributeArray.h:858
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::ValuePtr
void(*)(AttributeArray *array, const ValueType &value) ValuePtr
Definition AttributeArray.h:845
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::mSetter
SetterPtr mSetter
Definition AttributeArray.h:873
openvdb::v10_0::points::AttributeHandle::stride
Index stride() const
Definition AttributeArray.h:857
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::Ptr
std::shared_ptr< Handle > Ptr
Definition AttributeArray.h:839
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::mGetter
GetterPtr mGetter
Definition AttributeArray.h:872
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition AttributeArray.h:844
openvdb::v10_0::points::AttributeHandle::create
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition AttributeArray.h:2116
openvdb::v10_0::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition AttributeArray.h:2123
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::mFiller
ValuePtr mFiller
Definition AttributeArray.h:875
openvdb::v10_0::points::AttributeHandle::get
ValueType get(Index n, Index m=0) const
Definition AttributeArray.h:2193
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition AttributeArray.h:843
openvdb::v10_0::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeHandle &)=default
openvdb::v10_0::points::AttributeHandle::Handle
AttributeHandle< ValueType, CodecType > Handle
Definition AttributeArray.h:838
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::mCollapser
ValuePtr mCollapser
Definition AttributeArray.h:874
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::array
const AttributeArray & array() const
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::mArray
const AttributeArray * mArray
Definition AttributeArray.h:870
openvdb::v10_0::points::AttributeHandle::isUniform
bool isUniform() const
Definition AttributeArray.h:2219
openvdb::v10_0::points::AttributeHandle< ValueType, CodecType >::UniquePtr
std::unique_ptr< Handle > UniquePtr
Definition AttributeArray.h:840
openvdb::v10_0::points::AttributeHandle::hasConstantStride
bool hasConstantStride() const
Definition AttributeArray.h:2225
openvdb::v10_0::points::AttributeHandle::operator=
AttributeHandle & operator=(const AttributeHandle &)=default
openvdb::v10_0::points::AttributeHandle::index
Index index(Index n, Index m) const
Definition AttributeArray.h:2185
openvdb::v10_0::points::AttributeWriteHandle::~AttributeWriteHandle
virtual ~AttributeWriteHandle()=default
openvdb::v10_0::points::AttributeWriteHandle::AttributeWriteHandle
AttributeWriteHandle(AttributeArray &array, const bool expand=true)
Definition AttributeArray.h:2243
openvdb::v10_0::points::AttributeWriteHandle< ValueType, CodecType >::Ptr
std::shared_ptr< Handle > Ptr
Definition AttributeArray.h:910
openvdb::v10_0::points::AttributeWriteHandle::compact
bool compact()
Compact the existing array to become uniform if all values are identical.
Definition AttributeArray.h:2274
openvdb::v10_0::points::AttributeWriteHandle::collapse
void collapse()
Replace the existing array with a uniform value (zero if none provided).
Definition AttributeArray.h:2268
openvdb::v10_0::points::AttributeWriteHandle::set
void set(Index n, const ValueType &value)
Definition AttributeArray.h:2250
openvdb::v10_0::points::AttributeWriteHandle< ValueType, CodecType >::expand
void expand(bool fill=true)
openvdb::v10_0::points::AttributeWriteHandle< ValueType, CodecType >::array
AttributeArray & array()
openvdb::v10_0::points::AttributeWriteHandle< ValueType, CodecType >::ScopedPtr
std::unique_ptr< Handle > ScopedPtr
Definition AttributeArray.h:911
openvdb::v10_0::points::AttributeWriteHandle::Handle
AttributeWriteHandle< ValueType, CodecType > Handle
Definition AttributeArray.h:909
openvdb::v10_0::points::AttributeWriteHandle::create
static Ptr create(AttributeArray &array, const bool expand=true)
Definition AttributeArray.h:2236
openvdb::v10_0::points::AttributeWriteHandle::set
void set(Index n, Index m, const ValueType &value)
Definition AttributeArray.h:2256
openvdb::v10_0::points::AttributeWriteHandle< ValueType, CodecType >::fill
void fill(const ValueType &value)
openvdb::v10_0::points::AttributeWriteHandle::collapse
void collapse(const ValueType &uniformValue)
Definition AttributeArray.h:2280
openvdb::v10_0::points::TypedAttributeArray
Typed class for storing attribute data.
Definition AttributeArray.h:545
openvdb::v10_0::points::TypedAttributeArray::valueTypeSize
Index valueTypeSize() const override
Return the size in bytes of the value type of a single element in this array.
Definition AttributeArray.h:635
openvdb::v10_0::points::TypedAttributeArray::write
void write(std::ostream &) const override
Write attribute data to a stream, don't write transient attributes.
Definition AttributeArray.h:1845
openvdb::v10_0::points::TypedAttributeArray::memUsageIfLoaded
size_t memUsageIfLoaded() const override
Definition AttributeArray.h:1398
openvdb::v10_0::points::TypedAttributeArray::getUnsafe
void getUnsafe(Index n, T &value) const
Return the value at index n (assumes in-core).
Definition AttributeArray.h:1431
openvdb::v10_0::points::TypedAttributeArray::getUnsafe
ValueType getUnsafe(Index n) const
Return the value at index n (assumes in-core).
Definition AttributeArray.h:1407
openvdb::v10_0::points::TypedAttributeArray::isUniform
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Definition AttributeArray.h:700
openvdb::v10_0::points::TypedAttributeArray::readBuffers
void readBuffers(std::istream &) override
Read attribute buffers from a stream.
Definition AttributeArray.h:1751
openvdb::v10_0::points::TypedAttributeArray::Ptr
std::shared_ptr< TypedAttributeArray > Ptr
Definition AttributeArray.h:547
openvdb::v10_0::points::TypedAttributeArray::getAccessor
AccessorBasePtr getAccessor() const override
Obtain an Accessor that stores getter and setter functors.
Definition AttributeArray.h:2015
openvdb::v10_0::points::TypedAttributeArray::write
void write(std::ostream &os, bool outputTransient) const override
Definition AttributeArray.h:1853
openvdb::v10_0::points::TypedAttributeArray::StorageType
typename Codec::template Storage< ValueType >::Type StorageType
Definition AttributeArray.h:552
openvdb::v10_0::points::TypedAttributeArray::memUsage
size_t memUsage() const override
Return the number of bytes of memory used by this attribute.
Definition AttributeArray.h:1390
openvdb::v10_0::points::TypedAttributeArray::ValueType
ValueType_ ValueType
Definition AttributeArray.h:550
openvdb::v10_0::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(Index n=1, Index strideOrTotalSize=1, bool constantStride=true, const ValueType &uniformValue=zeroVal< ValueType >())
Default constructor, always constructs a uniform attribute.
Definition AttributeArray.h:1133
openvdb::v10_0::points::TypedAttributeArray::isDataLoaded
bool isDataLoaded() const override
Return true if all data has been loaded.
Definition AttributeArray.h:1683
openvdb::v10_0::points::TypedAttributeArray::isOutOfCore
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
Definition AttributeArray.h:1643
openvdb::v10_0::points::TypedAttributeArray::ConstPtr
std::shared_ptr< const TypedAttributeArray > ConstPtr
Definition AttributeArray.h:548
openvdb::v10_0::points::TypedAttributeArray::valueTypeIsVector
bool valueTypeIsVector() const override
Return true if the value type is a vector.
Definition AttributeArray.h:1364
openvdb::v10_0::points::TypedAttributeArray< Index, StringCodec< false > >::validData
bool validData() const
Definition AttributeArray.h:783
openvdb::v10_0::points::TypedAttributeArray< Index, StringCodec< false > >::compact
bool compact() override
openvdb::v10_0::points::TypedAttributeArray::cast
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>.
Definition AttributeArray.h:1259
openvdb::v10_0::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(TypedAttributeArray &&)=delete
Move assignment operator disabled.
openvdb::v10_0::points::TypedAttributeArray::writeBuffers
void writeBuffers(std::ostream &os, bool outputTransient) const override
Definition AttributeArray.h:1921
openvdb::v10_0::points::TypedAttributeArray::copy
AttributeArray::Ptr copy() const override
Definition AttributeArray.h:1279
openvdb::v10_0::points::TypedAttributeArray::storageTypeSize
Index storageTypeSize() const override
Definition AttributeArray.h:639
openvdb::v10_0::points::TypedAttributeArray::valueTypeIsQuaternion
bool valueTypeIsQuaternion() const override
Return true if the value type is a quaternion.
Definition AttributeArray.h:1372
openvdb::v10_0::points::TypedAttributeArray::readPagedBuffers
void readPagedBuffers(compression::PagedInputStream &) override
Read attribute buffers from a paged stream.
Definition AttributeArray.h:1790
openvdb::v10_0::points::TypedAttributeArray::set
void set(Index n, const ValueType &value)
Set value at the given index n.
Definition AttributeArray.h:1471
openvdb::v10_0::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(const TypedAttributeArray &)
Definition AttributeArray.h:1183
openvdb::v10_0::points::TypedAttributeArray::registerType
static void registerType()
Register this attribute type along with a factory function.
Definition AttributeArray.h:1231
openvdb::v10_0::points::TypedAttributeArray::valueTypeIsFloatingPoint
bool valueTypeIsFloatingPoint() const override
Return true if the value type is floating point.
Definition AttributeArray.h:1335
openvdb::v10_0::points::TypedAttributeArray::writeMetadata
void writeMetadata(std::ostream &os, bool outputTransient, bool paged) const override
Definition AttributeArray.h:1862
openvdb::v10_0::points::TypedAttributeArray::unregisterType
static void unregisterType()
Remove this attribute type from the registry.
Definition AttributeArray.h:1239
openvdb::v10_0::points::TypedAttributeArray::data
const StorageType * data() const
Definition AttributeArray.h:780
openvdb::v10_0::points::TypedAttributeArray::loadData
void loadData() const override
Ensures all data is in-core.
Definition AttributeArray.h:1675
openvdb::v10_0::points::TypedAttributeArray::read
void read(std::istream &) override
Read attribute data from a stream.
Definition AttributeArray.h:1691
openvdb::v10_0::points::TypedAttributeArray::get
ValueType get(Index n) const
Return the value at index n.
Definition AttributeArray.h:1419
openvdb::v10_0::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(TypedAttributeArray &&)=delete
Move constructor disabled.
openvdb::v10_0::points::TypedAttributeArray::attributeType
static const NamePair & attributeType()
Return the name of this attribute's type (includes codec).
Definition AttributeArray.h:1210
openvdb::v10_0::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(const TypedAttributeArray &)
Definition AttributeArray.h:1161
openvdb::v10_0::points::TypedAttributeArray::fill
static void fill(AttributeArray *array, const ValueType &value)
Non-member equivalent to fill() that static_casts array to this TypedAttributeArray.
Definition AttributeArray.h:1609
openvdb::v10_0::points::TypedAttributeArray::collapse
static void collapse(AttributeArray *array, const ValueType &value)
Non-member equivalent to collapse() that static_casts array to this TypedAttributeArray.
Definition AttributeArray.h:1584
openvdb::v10_0::points::TypedAttributeArray::type
const NamePair & type() const override
Return the name of this attribute's type.
Definition AttributeArray.h:607
openvdb::v10_0::points::TypedAttributeArray::cast
static const TypedAttributeArray & cast(const AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>.
Definition AttributeArray.h:1269
openvdb::v10_0::points::TypedAttributeArray::valueTypeIsClass
bool valueTypeIsClass() const override
Return true if the value type is a class (ie vector, matrix or quaternion return true).
Definition AttributeArray.h:1355
openvdb::v10_0::points::TypedAttributeArray::size
Index size() const override
Return the number of elements in this array.
Definition AttributeArray.h:617
openvdb::v10_0::points::TypedAttributeArray::collapse
void collapse() override
Replace the existing array with a uniform zero value.
Definition AttributeArray.h:1562
openvdb::v10_0::points::TypedAttributeArray::dataSize
Index dataSize() const override
Return the size of the data in this array.
Definition AttributeArray.h:624
openvdb::v10_0::points::TypedAttributeArray::Codec
Codec_ Codec
Definition AttributeArray.h:551
openvdb::v10_0::points::TypedAttributeArray::~TypedAttributeArray
~TypedAttributeArray() override
Definition AttributeArray.h:581
openvdb::v10_0::points::TypedAttributeArray::expand
void expand(bool fill=true) override
Replace the single value storage with an array of length size().
Definition AttributeArray.h:1524
openvdb::v10_0::points::TypedAttributeArray::isRegistered
static bool isRegistered()
Return true if this attribute type is registered.
Definition AttributeArray.h:1223
openvdb::v10_0::points::TypedAttributeArray::valueTypeIsMatrix
bool valueTypeIsMatrix() const override
Return true if the value type is a matrix.
Definition AttributeArray.h:1381
openvdb::v10_0::points::TypedAttributeArray< Index, StringCodec< false > >::data
StorageType * data()
Definition AttributeArray.h:779
openvdb::v10_0::points::TypedAttributeArray::getUnsafe
static ValueType getUnsafe(const AttributeArray *array, const Index n)
Definition AttributeArray.h:1448
openvdb::v10_0::points::TypedAttributeArray::constData
const StorageType * constData() const
Return the raw data buffer.
Definition AttributeArray.h:772
openvdb::v10_0::points::TypedAttributeArray< Index, StringCodec< false > >::fill
void fill(const ValueType &value)
openvdb::v10_0::points::TypedAttributeArray::collapse
void collapse(const ValueType &uniformValue)
Replace the existing array with the given uniform value.
Definition AttributeArray.h:1570
openvdb::v10_0::points::TypedAttributeArray::set
void set(Index n, const T &value)
Set value at the given index n.
Definition AttributeArray.h:1493
openvdb::v10_0::points::TypedAttributeArray::stride
Index stride() const override
Definition AttributeArray.h:621
openvdb::v10_0::points::TypedAttributeArray::create
static Ptr create(Index n, Index strideOrTotalSize=1, bool constantStride=true, const Metadata *metadata=nullptr)
Return a new attribute array of the given length n and stride with uniform value zero.
Definition AttributeArray.h:1247
openvdb::v10_0::points::TypedAttributeArray::codecType
Name codecType() const override
Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
Definition AttributeArray.h:632
openvdb::v10_0::points::TypedAttributeArray::writePagedBuffers
void writePagedBuffers(compression::PagedOutputStream &os, bool outputTransient) const override
Definition AttributeArray.h:1963
openvdb::v10_0::points::TypedAttributeArray::valueType
Name valueType() const override
Return the name of the value type of a single element in this array (e.g., "float" or "vec3d").
Definition AttributeArray.h:629
openvdb::v10_0::points::TypedAttributeArray::setUnsafe
void setUnsafe(Index n, const T &value)
Set value at the given index n (assumes in-core).
Definition AttributeArray.h:1484
openvdb::v10_0::points::TypedAttributeArray::setUnsafe
void setUnsafe(Index n, const ValueType &value)
Set value at the given index n (assumes in-core).
Definition AttributeArray.h:1456
openvdb::v10_0::points::TypedAttributeArray::setUnsafe
static void setUnsafe(AttributeArray *array, const Index n, const ValueType &value)
Definition AttributeArray.h:1501
openvdb::v10_0::points::TypedAttributeArray::readMetadata
void readMetadata(std::istream &) override
Read attribute metadata from a stream.
Definition AttributeArray.h:1700
openvdb::v10_0::points::TypedAttributeArray::get
void get(Index n, T &value) const
Return the value at index n.
Definition AttributeArray.h:1440
io.h
logging.h
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition logging.h:256
openvdb::v10_0::compression
Definition StreamCompression.h:33
openvdb::v10_0::compression::bloscDecompress
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
openvdb::v10_0::compression::bloscCompressedSize
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
openvdb::v10_0::compression::bloscCompress
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
openvdb::v10_0::io::getDataCompression
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK,...
openvdb::v10_0::io::COMPRESS_BLOSC
@ COMPRESS_BLOSC
Definition Compression.h:56
openvdb::v10_0::math
Definition Types.h:28
openvdb::v10_0::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:443
openvdb::v10_0::math::half
internal::half half
Definition Types.h:29
openvdb::v10_0::points::attribute_traits
Definition AttributeArray.h:440
openvdb::v10_0::points::index
Definition IndexIterator.h:34
openvdb::v10_0::points
Definition AttributeArray.h:41
openvdb::v10_0::points::fixedPointToFloatingPoint
FloatT fixedPointToFloatingPoint(const IntegerT s)
Definition AttributeArray.h:61
openvdb::v10_0::points::sTypeName
std::unique_ptr< const NamePair > TypedAttributeArray< ValueType_, Codec_ >::sTypeName
Definition AttributeArray.h:1129
openvdb::v10_0::points::floatingPointToFixedPoint
IntegerT floatingPointToFixedPoint(const FloatT s)
Definition AttributeArray.h:50
openvdb::v10_0::Name
std::string Name
Definition Name.h:17
openvdb::v10_0::Index
Index32 Index
Definition Types.h:54
openvdb::v10_0::Int16
int16_t Int16
Definition Types.h:55
openvdb::v10_0::NamePair
std::pair< Name, Name > NamePair
Definition AttributeArray.h:39
openvdb::v10_0::zeroVal
T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
openvdb::v10_0::Index64
uint64_t Index64
Definition Types.h:53
openvdb::v10_0::typeNameAsString
const char * typeNameAsString()
Definition Types.h:477
openvdb
Definition Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Types.h
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::v10_0::VecTraits::IsVec
static const bool IsVec
Definition Types.h:206
openvdb::v10_0::VecTraits::ElementType
typename T::ValueType ElementType
Definition Types.h:208
openvdb::v10_0::points::AccessorEval< UnknownCodec, ValueType >::get
static ValueType get(GetterPtr functor, const AttributeArray *array, const Index n)
Getter that calls the supplied functor.
Definition AttributeArray.h:2099
openvdb::v10_0::points::AccessorEval< UnknownCodec, ValueType >::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition AttributeArray.h:2096
openvdb::v10_0::points::AccessorEval< UnknownCodec, ValueType >::set
static void set(SetterPtr functor, AttributeArray *array, const Index n, const ValueType &value)
Setter that calls the supplied functor.
Definition AttributeArray.h:2104
openvdb::v10_0::points::AccessorEval< UnknownCodec, ValueType >::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition AttributeArray.h:2095
openvdb::v10_0::points::AccessorEval
Accessor to call unsafe get and set methods based on templated Codec and Value.
Definition AttributeArray.h:2073
openvdb::v10_0::points::AccessorEval::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition AttributeArray.h:2075
openvdb::v10_0::points::AccessorEval::get
static ValueType get(GetterPtr, const AttributeArray *array, const Index n)
Definition AttributeArray.h:2079
openvdb::v10_0::points::AccessorEval::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition AttributeArray.h:2074
openvdb::v10_0::points::AccessorEval::set
static void set(SetterPtr, AttributeArray *array, const Index n, const ValueType &value)
Definition AttributeArray.h:2085
openvdb::v10_0::points::AttributeArray::AccessorBase
Accessor base class for AttributeArray storage where type is not available.
Definition AttributeArray.h:415
openvdb::v10_0::points::AttributeArray::AccessorBase::~AccessorBase
virtual ~AccessorBase()=default
openvdb::v10_0::points::AttributeArray::Accessor
Definition AttributeArray.h:421
openvdb::v10_0::points::AttributeArray::Accessor::mSetter
SetterPtr mSetter
Definition AttributeArray.h:430
openvdb::v10_0::points::AttributeArray::Accessor::mGetter
GetterPtr mGetter
Definition AttributeArray.h:429
openvdb::v10_0::points::AttributeArray::Accessor::ValuePtr
void(*)(AttributeArray *array, const T &value) ValuePtr
Definition AttributeArray.h:424
openvdb::v10_0::points::AttributeArray::Accessor::GetterPtr
T(*)(const AttributeArray *array, const Index n) GetterPtr
Definition AttributeArray.h:422
openvdb::v10_0::points::AttributeArray::Accessor::SetterPtr
void(*)(AttributeArray *array, const Index n, const T &value) SetterPtr
Definition AttributeArray.h:423
openvdb::v10_0::points::AttributeArray::Accessor::mFiller
ValuePtr mFiller
Definition AttributeArray.h:432
openvdb::v10_0::points::AttributeArray::Accessor::Accessor
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler)
Definition AttributeArray.h:426
openvdb::v10_0::points::AttributeArray::Accessor::mCollapser
ValuePtr mCollapser
Definition AttributeArray.h:431
openvdb::v10_0::points::FixedPointCodec::Storage
Definition AttributeArray.h:513
openvdb::v10_0::points::FixedPointCodec::Storage::Type
typename attribute_traits::UIntTypeTrait< OneByte, T >::Type Type
Definition AttributeArray.h:513
openvdb::v10_0::points::FixedPointCodec
Definition AttributeArray.h:511
openvdb::v10_0::points::FixedPointCodec::encode
static void encode(const ValueType &, StorageType &)
Definition AttributeArray.h:1004
openvdb::v10_0::points::FixedPointCodec::decode
static void decode(const StorageType &, ValueType &)
Definition AttributeArray.h:991
openvdb::v10_0::points::FixedPointCodec::name
static const char * name()
Definition AttributeArray.h:518
openvdb::v10_0::points::NullCodec::Storage
Definition AttributeArray.h:472
openvdb::v10_0::points::NullCodec::Storage::Type
T Type
Definition AttributeArray.h:472
openvdb::v10_0::points::NullCodec
Definition AttributeArray.h:470
openvdb::v10_0::points::NullCodec::encode
static void encode(const ValueType &, ValueType &)
Definition AttributeArray.h:966
openvdb::v10_0::points::NullCodec::name
static const char * name()
Definition AttributeArray.h:476
openvdb::v10_0::points::NullCodec::decode
static void decode(const ValueType &, ValueType &)
Definition AttributeArray.h:958
openvdb::v10_0::points::PositionRange
Definition AttributeArray.h:493
openvdb::v10_0::points::PositionRange::decode
static ValueType decode(const ValueType &value)
Definition AttributeArray.h:496
openvdb::v10_0::points::PositionRange::encode
static ValueType encode(const ValueType &value)
Definition AttributeArray.h:495
openvdb::v10_0::points::PositionRange::name
static const char * name()
Definition AttributeArray.h:494
openvdb::v10_0::points::StringCodec::name
static const char * name()
Definition AttributeArrayString.h:45
openvdb::v10_0::points::TruncateCodec::Storage
Definition AttributeArray.h:483
openvdb::v10_0::points::TruncateCodec::Storage::Type
typename attribute_traits::TruncateTrait< T >::Type Type
Definition AttributeArray.h:483
openvdb::v10_0::points::TruncateCodec
Definition AttributeArray.h:481
openvdb::v10_0::points::TruncateCodec::encode
static void encode(const ValueType &, StorageType &)
Definition AttributeArray.h:982
openvdb::v10_0::points::TruncateCodec::decode
static void decode(const StorageType &, ValueType &)
Definition AttributeArray.h:974
openvdb::v10_0::points::TruncateCodec::name
static const char * name()
Definition AttributeArray.h:487
openvdb::v10_0::points::UnitRange
Definition AttributeArray.h:502
openvdb::v10_0::points::UnitRange::decode
static ValueType decode(const ValueType &value)
Definition AttributeArray.h:505
openvdb::v10_0::points::UnitRange::encode
static ValueType encode(const ValueType &value)
Definition AttributeArray.h:504
openvdb::v10_0::points::UnitRange::name
static const char * name()
Definition AttributeArray.h:503
openvdb::v10_0::points::UnitVecCodec::Storage
Definition AttributeArray.h:530
openvdb::v10_0::points::UnitVecCodec::Storage::Type
StorageType Type
Definition AttributeArray.h:530
openvdb::v10_0::points::UnitVecCodec
Definition AttributeArray.h:526
openvdb::v10_0::points::UnitVecCodec::StorageType
uint16_t StorageType
Definition AttributeArray.h:527
openvdb::v10_0::points::UnitVecCodec::decode
static void decode(const StorageType &, math::Vec3< T > &)
Definition AttributeArray.h:1016
openvdb::v10_0::points::UnitVecCodec::encode
static void encode(const math::Vec3< T > &, StorageType &)
Definition AttributeArray.h:1024
openvdb::v10_0::points::UnitVecCodec::name
static const char * name()
Definition AttributeArray.h:534
openvdb::v10_0::points::UnknownCodec
Definition AttributeArray.h:466
openvdb::v10_0::points::attribute_traits::TruncateTrait< float >::Type
math::half Type
Definition AttributeArray.h:442
openvdb::v10_0::points::attribute_traits::TruncateTrait< int >::Type
short Type
Definition AttributeArray.h:443
openvdb::v10_0::points::attribute_traits::TruncateTrait< math::Vec3< T > >::Type
math::Vec3< typename TruncateTrait< T >::Type > Type
Definition AttributeArray.h:446
openvdb::v10_0::points::attribute_traits::TruncateTrait
Definition AttributeArray.h:441
openvdb::v10_0::points::attribute_traits::UIntTypeTrait< false, T >::Type
uint16_t Type
Definition AttributeArray.h:451
openvdb::v10_0::points::attribute_traits::UIntTypeTrait< false, math::Vec3< T > >::Type
math::Vec3< uint16_t > Type
Definition AttributeArray.h:456
openvdb::v10_0::points::attribute_traits::UIntTypeTrait< true, T >::Type
uint8_t Type
Definition AttributeArray.h:450
openvdb::v10_0::points::attribute_traits::UIntTypeTrait< true, math::Vec3< T > >::Type
math::Vec3< uint8_t > Type
Definition AttributeArray.h:453
openvdb::v10_0::points::attribute_traits::UIntTypeTrait
Definition AttributeArray.h:449
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