10 #ifndef OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
23 #include <tbb/spin_mutex.h>
29 #include <type_traits>
32 class TestAttributeArray;
48 template <
typename IntegerT,
typename FloatT>
59 template <
typename FloatT,
typename IntegerT>
67 template <
typename IntegerVectorT,
typename FloatT>
71 return IntegerVectorT(
72 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
x()),
73 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
y()),
74 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
z()));
77 template <
typename FloatVectorT,
typename IntegerT>
82 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
x()),
83 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
y()),
84 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
z()));
104 CONSTANTSTRIDE = 0x8,
112 WRITEMEMCOMPRESS = 0x4,
120 tbb::spin_mutex::scoped_lock lock;
125 using Ptr = std::shared_ptr<AttributeArray>;
126 using ConstPtr = std::shared_ptr<const AttributeArray>;
137 if (
mFlags & PARTIALREAD) mCompressedBytes = 0;
147 #if OPENVDB_ABI_VERSION_NUMBER < 10
165 virtual Index dataSize()
const = 0;
168 virtual Name valueType()
const = 0;
171 virtual Name codecType()
const = 0;
175 virtual Index valueTypeSize()
const = 0;
179 virtual Index storageTypeSize()
const = 0;
182 virtual bool valueTypeIsFloatingPoint()
const = 0;
185 virtual bool valueTypeIsClass()
const = 0;
188 virtual bool valueTypeIsVector()
const = 0;
191 virtual bool valueTypeIsQuaternion()
const = 0;
194 virtual bool valueTypeIsMatrix()
const = 0;
197 virtual size_t memUsage()
const = 0;
199 #if OPENVDB_ABI_VERSION_NUMBER >= 10
211 bool constantStride =
true,
213 const ScopedRegistryLock* lock =
nullptr);
216 static bool isRegistered(
const NamePair&
type,
const ScopedRegistryLock* lock =
nullptr);
218 static void clearRegistry(
const ScopedRegistryLock* lock =
nullptr);
223 template<
typename AttributeArrayType>
224 bool isType()
const {
return this->
type() == AttributeArrayType::attributeType(); }
227 template<
typename ValueType>
230 #if OPENVDB_ABI_VERSION_NUMBER < 10
262 template<
typename IterT>
263 void copyValuesUnsafe(
const AttributeArray& sourceArray,
const IterT& iter);
267 template<
typename IterT>
268 void copyValues(
const AttributeArray& sourceArray,
const IterT& iter,
bool compact =
true);
271 virtual bool isUniform()
const = 0;
274 virtual void expand(
bool fill =
true) = 0;
276 virtual void collapse() = 0;
278 virtual bool compact() = 0;
280 #if OPENVDB_ABI_VERSION_NUMBER < 10
285 virtual bool compress() = 0;
290 virtual bool decompress() = 0;
297 void setHidden(
bool state);
304 void setTransient(
bool state);
312 void setStreaming(
bool state);
323 virtual void read(std::istream&) = 0;
326 virtual void write(std::ostream&,
bool outputTransient)
const = 0;
328 virtual void write(std::ostream&)
const = 0;
331 virtual void readMetadata(std::istream&) = 0;
335 virtual void writeMetadata(std::ostream&,
bool outputTransient,
bool paged)
const = 0;
338 virtual void readBuffers(std::istream&) = 0;
341 virtual void writeBuffers(std::ostream&,
bool outputTransient)
const = 0;
350 virtual void loadData()
const = 0;
353 virtual bool isDataLoaded()
const = 0;
361 #if OPENVDB_ABI_VERSION_NUMBER >= 9
363 const char* constDataAsByteArray()
const {
return this->dataAsByteArray(); }
367 friend class ::TestAttributeArray;
374 virtual char* dataAsByteArray() = 0;
375 virtual const char* dataAsByteArray()
const = 0;
378 template <
typename IterT>
379 void doCopyValues(
const AttributeArray& sourceArray,
const IterT& iter,
380 bool rangeChecking =
true);
386 void setConstantStride(
bool state);
398 bool mIsUniform =
true;
401 uint8_t mUsePagedRead = 0;
419 template <
typename T>
439 namespace attribute_traits
471 template <
typename T>
476 static const char*
name() {
return "null"; }
482 template <
typename T>
485 template<
typename StorageType,
typename ValueType>
static void decode(
const StorageType&,
ValueType&);
486 template<
typename StorageType,
typename ValueType>
static void encode(
const ValueType&, StorageType&);
487 static const char*
name() {
return "trnc"; }
494 static const char*
name() {
return "fxpt"; }
503 static const char*
name() {
return "ufxpt"; }
509 template <
bool OneByte,
typename Range=PositionRange>
512 template <
typename T>
515 template<
typename StorageType,
typename ValueType>
static void decode(
const StorageType&,
ValueType&);
516 template<
typename StorageType,
typename ValueType>
static void encode(
const ValueType&, StorageType&);
529 template <
typename T>
534 static const char*
name() {
return "uvec"; }
543 template<
typename ValueType_,
typename Codec_ = NullCodec>
547 using Ptr = std::shared_ptr<TypedAttributeArray>;
548 using ConstPtr = std::shared_ptr<const TypedAttributeArray>;
558 const ValueType& uniformValue = zeroVal<ValueType>());
567 #if OPENVDB_ABI_VERSION_NUMBER < 10
575 TypedAttributeArray&
operator=(
const TypedAttributeArray&);
579 TypedAttributeArray&
operator=(TypedAttributeArray&&) =
delete;
587 #if OPENVDB_ABI_VERSION_NUMBER < 10
596 const Metadata* metadata =
nullptr);
659 #if OPENVDB_ABI_VERSION_NUMBER >= 10
693 #if OPENVDB_ABI_VERSION_NUMBER < 10
721 #if OPENVDB_ABI_VERSION_NUMBER < 10
731 void read(std::istream&)
override;
735 void write(std::ostream& os,
bool outputTransient)
const override;
737 void write(std::ostream&)
const override;
745 void writeMetadata(std::ostream& os,
bool outputTransient,
bool paged)
const override;
752 void writeBuffers(std::ostream& os,
bool outputTransient)
const override;
784 friend class ::TestAttributeArray;
789 inline void doLoad()
const;
791 #if OPENVDB_ABI_VERSION_NUMBER >= 10
792 inline void doLoadUnsafe()
const;
795 inline void doLoadUnsafe(
const bool compression =
true)
const;
797 inline bool compressUnsafe();
801 inline void setOutOfCore(
const bool);
807 char* dataAsByteArray()
override;
808 const char* dataAsByteArray()
const override;
810 size_t arrayMemUsage()
const;
820 std::unique_ptr<StorageType[]> mData;
822 Index mStrideOrTotalSize;
831 template <
typename ValueType,
typename CodecType = UnknownCodec>
836 using Ptr = std::shared_ptr<Handle>;
875 friend class ::TestAttributeArray;
877 template <
bool IsUnknownCodec>
880 template <
bool IsUnknownCodec>
883 template <
bool IsUnknownCodec>
886 template <
bool IsUnknownCodec>
892 Index mStrideOrTotalSize;
894 bool mCollapseOnDestruction;
902 template <
typename ValueType,
typename CodecType = UnknownCodec>
907 using Ptr = std::shared_ptr<Handle>;
937 friend class ::TestAttributeArray;
939 template <
bool IsUnknownCodec>
942 template <
bool IsUnknownCodec>
953 template<
typename ValueType>
961 template<
typename ValueType>
969 template<
typename StorageType,
typename ValueType>
977 template<
typename StorageType,
typename ValueType>
981 data =
static_cast<StorageType
>(
val);
985 template <
bool OneByte,
typename Range>
986 template<
typename StorageType,
typename ValueType>
990 val = fixedPointToFloatingPoint<ValueType>(
data);
994 val = Range::template decode<ValueType>(
val);
998 template <
bool OneByte,
typename Range>
999 template<
typename StorageType,
typename ValueType>
1005 const ValueType newVal = Range::template encode<ValueType>(
val);
1007 data = floatingPointToFixedPoint<StorageType>(newVal);
1011 template<
typename T>
1019 template<
typename T>
1031 template <
typename IterT>
1032 void AttributeArray::doCopyValues(
const AttributeArray& sourceArray,
const IterT& iter,
1044 const char*
const sourceBuffer = sourceArray.dataAsByteArray();
1045 char*
const targetBuffer = this->dataAsByteArray();
1046 assert(sourceBuffer && targetBuffer);
1048 if (rangeChecking && this->
isUniform()) {
1049 OPENVDB_THROW(IndexError,
"Cannot copy array data as target array is uniform.");
1052 const bool sourceIsUniform = sourceArray.
isUniform();
1054 const Index sourceDataSize = rangeChecking ? sourceArray.
dataSize() : 0;
1055 const Index targetDataSize = rangeChecking ? this->
dataSize() : 0;
1057 for (IterT it(iter); it; ++it) {
1058 const Index sourceIndex = sourceIsUniform ? 0 : it.sourceIndex();
1059 const Index targetIndex = it.targetIndex();
1061 if (rangeChecking) {
1062 if (sourceIndex >= sourceDataSize) {
1064 "Cannot copy array data as source index exceeds size of source array.");
1066 if (targetIndex >= targetDataSize) {
1068 "Cannot copy array data as target index exceeds size of target array.");
1072 assert(sourceIndex < sourceArray.
dataSize());
1073 assert(targetIndex < this->
dataSize());
1077 const size_t targetOffset(targetIndex *
bytes);
1078 const size_t sourceOffset(sourceIndex *
bytes);
1080 std::memcpy(targetBuffer + targetOffset, sourceBuffer + sourceOffset,
bytes);
1084 template <
typename IterT>
1087 this->doCopyValues(sourceArray, iter,
false);
1090 template <
typename IterT>
1096 OPENVDB_THROW(TypeError,
"Cannot copy array data due to mis-match in storage type sizes.");
1112 this->doCopyValues(sourceArray, iter,
true);
1126 template<
typename ValueType_,
typename Codec_>
1132 , mStrideOrTotalSize(strideOrTotalSize)
1134 if (constantStride) {
1136 if (strideOrTotalSize == 0) {
1137 OPENVDB_THROW(ValueError,
"Creating a TypedAttributeArray with a constant stride requires that " \
1138 "stride to be at least one.")
1143 if (mStrideOrTotalSize < n) {
1144 OPENVDB_THROW(ValueError,
"Creating a TypedAttributeArray with a non-constant stride must have " \
1145 "a total size of at least the number of elements in the array.")
1149 mStrideOrTotalSize =
std::max(
Index(1), mStrideOrTotalSize);
1150 Codec::encode(uniformValue, this->
data()[0]);
1154 template<
typename ValueType_,
typename Codec_>
1156 : TypedAttributeArray(rhs, tbb::
spin_mutex::scoped_lock(rhs.mMutex))
1161 template<
typename ValueType_,
typename Codec_>
1163 const tbb::spin_mutex::scoped_lock& lock)
1166 , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
1170 std::memcpy(static_cast<void*>(this->
data()), rhs.
data(), this->arrayMemUsage());
1175 template<
typename ValueType_,
typename Codec_>
1176 TypedAttributeArray<ValueType_, Codec_>&
1181 tbb::spin_mutex::scoped_lock lock(mMutex);
1182 tbb::spin_mutex::scoped_lock rhsLock(rhs.
mMutex);
1189 mStrideOrTotalSize = rhs.mStrideOrTotalSize;
1192 if (this->validData()) {
1194 std::memcpy(static_cast<void*>(this->
data()), rhs.
data(), this->arrayMemUsage());
1202 template<
typename ValueType_,
typename Codec_>
1213 template<
typename ValueType_,
typename Codec_>
1221 template<
typename ValueType_,
typename Codec_>
1229 template<
typename ValueType_,
typename Codec_>
1237 template<
typename ValueType_,
typename Codec_>
1245 return Ptr(
new TypedAttributeArray(n, stride, constantStride,
1246 typedMetadata ? typedMetadata->
value() : zeroVal<ValueType>()));
1249 template<
typename ValueType_,
typename Codec_>
1253 if (!attributeArray.
isType<TypedAttributeArray>()) {
1256 return static_cast<TypedAttributeArray&
>(attributeArray);
1259 template<
typename ValueType_,
typename Codec_>
1263 if (!attributeArray.
isType<TypedAttributeArray>()) {
1266 return static_cast<const TypedAttributeArray&
>(attributeArray);
1269 template<
typename ValueType_,
typename Codec_>
1277 #if OPENVDB_ABI_VERSION_NUMBER < 10
1278 template<
typename ValueType_,
typename Codec_>
1282 return this->
copy();
1286 template<
typename ValueType_,
typename Codec_>
1290 if (this->isOutOfCore())
return 0;
1292 return (mIsUniform ? 1 : this->dataSize()) *
sizeof(StorageType);
1296 template<
typename ValueType_,
typename Codec_>
1298 TypedAttributeArray<ValueType_, Codec_>::allocate()
1302 mData.reset(
new StorageType[1]);
1305 const size_t size(this->dataSize());
1307 mData.reset(
new StorageType[
size]);
1312 template<
typename ValueType_,
typename Codec_>
1314 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1317 if (this->isOutOfCore()) {
1318 this->setOutOfCore(
false);
1319 this->mPageHandle.reset();
1321 if (mData) mData.reset();
1325 template<
typename ValueType_,
typename Codec_>
1345 template<
typename ValueType_,
typename Codec_>
1354 template<
typename ValueType_,
typename Codec_>
1362 template<
typename ValueType_,
typename Codec_>
1367 return !this->valueType().compare(0, 4,
"quat");
1371 template<
typename ValueType_,
typename Codec_>
1376 return !this->valueType().compare(0, 3,
"mat");
1380 template<
typename ValueType_,
typename Codec_>
1384 return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1387 #if OPENVDB_ABI_VERSION_NUMBER >= 10
1388 template<
typename ValueType_,
typename Codec_>
1392 return sizeof(*this) + (mIsUniform ? 1 : this->dataSize()) *
sizeof(StorageType);
1397 template<
typename ValueType_,
typename Codec_>
1404 Codec::decode(this->
data()[mIsUniform ? 0 : n], val);
1409 template<
typename ValueType_,
typename Codec_>
1413 if (n >= this->dataSize())
OPENVDB_THROW(IndexError,
"Out-of-range access.");
1414 if (this->isOutOfCore()) this->doLoad();
1416 return this->getUnsafe(n);
1420 template<
typename ValueType_,
typename Codec_>
1421 template<
typename T>
1425 val =
static_cast<T>(this->getUnsafe(n));
1429 template<
typename ValueType_,
typename Codec_>
1430 template<
typename T>
1434 val =
static_cast<T>(this->
get(
n));
1438 template<
typename ValueType_,
typename Codec_>
1446 template<
typename ValueType_,
typename Codec_>
1451 assert(!this->isOutOfCore());
1452 assert(!this->isUniform());
1457 Codec::encode(val, this->
data()[mIsUniform ? 0 : n]);
1461 template<
typename ValueType_,
typename Codec_>
1465 if (n >= this->dataSize())
OPENVDB_THROW(IndexError,
"Out-of-range access.");
1466 if (this->isOutOfCore()) this->doLoad();
1467 if (this->isUniform()) this->expand();
1469 this->setUnsafe(n, val);
1473 template<
typename ValueType_,
typename Codec_>
1474 template<
typename T>
1478 this->setUnsafe(n, static_cast<ValueType>(val));
1482 template<
typename ValueType_,
typename Codec_>
1483 template<
typename T>
1487 this->set(n, static_cast<ValueType>(val));
1491 template<
typename ValueType_,
typename Codec_>
1499 #if OPENVDB_ABI_VERSION_NUMBER < 10
1500 template<
typename ValueType_,
typename Codec_>
1504 const TypedAttributeArray& sourceTypedArray =
static_cast<const TypedAttributeArray&
>(sourceArray);
1507 sourceTypedArray.
get(sourceIndex, sourceValue);
1509 this->set(n, sourceValue);
1514 template<
typename ValueType_,
typename Codec_>
1518 if (!mIsUniform)
return;
1523 tbb::spin_mutex::scoped_lock lock(mMutex);
1530 for (
Index i = 0; i < this->dataSize(); ++i) this->
data()[i] =
val;
1535 template<
typename ValueType_,
typename Codec_>
1539 if (mIsUniform)
return true;
1542 const ValueType_
val = this->
get(0);
1543 for (
Index i = 1; i < this->dataSize(); i++) {
1547 this->collapse(this->
get(0));
1552 template<
typename ValueType_,
typename Codec_>
1556 this->collapse(zeroVal<ValueType>());
1560 template<
typename ValueType_,
typename Codec_>
1565 tbb::spin_mutex::scoped_lock lock(mMutex);
1570 Codec::encode(uniformValue, this->
data()[0]);
1574 template<
typename ValueType_,
typename Codec_>
1582 template<
typename ValueType_,
typename Codec_>
1586 if (this->isOutOfCore()) {
1587 tbb::spin_mutex::scoped_lock lock(mMutex);
1592 const Index size = mIsUniform ? 1 : this->dataSize();
1594 Codec::encode(value, this->
data()[i]);
1599 template<
typename ValueType_,
typename Codec_>
1607 #if OPENVDB_ABI_VERSION_NUMBER < 10
1608 template<
typename ValueType_,
typename Codec_>
1616 template<
typename ValueType_,
typename Codec_>
1624 template<
typename ValueType_,
typename Codec_>
1633 template<
typename ValueType_,
typename Codec_>
1641 template<
typename ValueType_,
typename Codec_>
1649 template<
typename ValueType_,
typename Codec_>
1651 TypedAttributeArray<ValueType_, Codec_>::doLoad()
const
1653 if (!(this->isOutOfCore()))
return;
1655 TypedAttributeArray<ValueType_, Codec_>*
self =
1656 const_cast<TypedAttributeArray<ValueType_, Codec_>*
>(
this);
1660 tbb::spin_mutex::scoped_lock lock(self->mMutex);
1661 this->doLoadUnsafe();
1665 template<
typename ValueType_,
typename Codec_>
1673 template<
typename ValueType_,
typename Codec_>
1677 return !this->isOutOfCore();
1681 template<
typename ValueType_,
typename Codec_>
1685 this->readMetadata(is);
1686 this->readBuffers(is);
1690 template<
typename ValueType_,
typename Codec_>
1697 is.read(reinterpret_cast<char*>(&bytes),
sizeof(
Index64));
1698 bytes = bytes -
sizeof(
Int16) -
sizeof(
Index);
1700 uint8_t
flags = uint8_t(0);
1701 is.read(reinterpret_cast<char*>(&flags),
sizeof(uint8_t));
1704 uint8_t serializationFlags = uint8_t(0);
1705 is.read(reinterpret_cast<char*>(&serializationFlags),
sizeof(uint8_t));
1708 is.read(reinterpret_cast<char*>(&size),
sizeof(
Index));
1717 if (serializationFlags >= 0x10) {
1718 OPENVDB_THROW(IoError,
"Unknown attribute serialization flags for VDB file format.");
1723 mIsUniform = serializationFlags & WRITEUNIFORM;
1724 mUsePagedRead = serializationFlags & WRITEPAGED;
1725 mCompressedBytes = bytes;
1730 if (serializationFlags & WRITESTRIDED) {
1732 is.read(reinterpret_cast<char*>(&stride),
sizeof(
Index));
1733 mStrideOrTotalSize =
stride;
1736 mStrideOrTotalSize = 1;
1741 template<
typename ValueType_,
typename Codec_>
1745 if (mUsePagedRead) {
1747 OPENVDB_THROW(IoError,
"Cannot read paged AttributeArray buffers.");
1750 tbb::spin_mutex::scoped_lock lock(mMutex);
1754 uint8_t bloscCompressed(0);
1755 if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed),
sizeof(uint8_t));
1757 assert(
mFlags & PARTIALREAD);
1758 std::unique_ptr<char[]>
buffer(
new char[mCompressedBytes]);
1759 is.read(buffer.get(), mCompressedBytes);
1760 mCompressedBytes = 0;
1765 if (bloscCompressed == uint8_t(1)) {
1769 const size_t inBytes = this->dataSize() *
sizeof(
StorageType);
1771 if (newBuffer) buffer.reset(newBuffer.release());
1776 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1780 template<
typename ValueType_,
typename Codec_>
1784 if (!mUsePagedRead) {
1789 #ifdef OPENVDB_USE_DELAYED_LOADING
1792 io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is.
getInputStream());
1793 const bool delayLoad = (mappedFile.get() !=
nullptr);
1798 size_t compressedBytes(mCompressedBytes);
1799 mCompressedBytes = 0;
1801 assert(!mPageHandle);
1806 assert(mPageHandle);
1808 tbb::spin_mutex::scoped_lock lock(mMutex);
1812 #ifdef OPENVDB_USE_DELAYED_LOADING
1813 this->setOutOfCore(delayLoad);
1814 is.
read(mPageHandle, std::streamsize(mPageHandle->size()), delayLoad);
1816 is.
read(mPageHandle, std::streamsize(mPageHandle->size()),
false);
1817 #endif // OPENVDB_USE_DELAYED_LOADING
1819 #ifdef OPENVDB_USE_DELAYED_LOADING
1822 std::unique_ptr<char[]>
buffer = mPageHandle->read();
1823 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1824 mPageHandle.reset();
1825 #ifdef OPENVDB_USE_DELAYED_LOADING
1835 template<
typename ValueType_,
typename Codec_>
1839 this->write(os,
false);
1843 template<
typename ValueType_,
typename Codec_>
1847 this->writeMetadata(os, outputTransient,
false);
1848 this->writeBuffers(os, outputTransient);
1852 template<
typename ValueType_,
typename Codec_>
1856 if (!outputTransient && this->isTransient())
return;
1858 if (
mFlags & PARTIALREAD) {
1859 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1863 uint8_t serializationFlags(0);
1865 Index strideOrTotalSize(mStrideOrTotalSize);
1866 bool strideOfOne(this->
stride() == 1);
1871 if (bloscCompression) this->doLoad();
1873 size_t compressedBytes = 0;
1877 serializationFlags |= WRITESTRIDED;
1882 serializationFlags |= WRITEUNIFORM;
1883 if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1885 else if (bloscCompression)
1887 if (paged) serializationFlags |= WRITEPAGED;
1889 const char* charBuffer =
reinterpret_cast<const char*
>(this->
data());
1890 const size_t inBytes = this->arrayMemUsage();
1897 bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1901 os.write(reinterpret_cast<const char*>(&bytes),
sizeof(
Index64));
1902 os.write(reinterpret_cast<const char*>(&flags),
sizeof(uint8_t));
1903 os.write(reinterpret_cast<const char*>(&serializationFlags),
sizeof(uint8_t));
1904 os.write(reinterpret_cast<const char*>(&size),
sizeof(
Index));
1907 if (!strideOfOne) os.write(reinterpret_cast<const char*>(&strideOrTotalSize),
sizeof(
Index));
1911 template<
typename ValueType_,
typename Codec_>
1915 if (!outputTransient && this->isTransient())
return;
1917 if (
mFlags & PARTIALREAD) {
1918 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1923 if (this->isUniform()) {
1924 os.write(reinterpret_cast<const char*>(this->
data()),
sizeof(
StorageType));
1928 std::unique_ptr<char[]> compressedBuffer;
1929 size_t compressedBytes = 0;
1930 const char* charBuffer =
reinterpret_cast<const char*
>(this->
data());
1931 const size_t inBytes = this->arrayMemUsage();
1933 if (compressedBuffer) {
1934 uint8_t bloscCompressed(1);
1935 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1936 os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1939 uint8_t bloscCompressed(0);
1940 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1941 os.write(reinterpret_cast<const char*>(this->
data()), inBytes);
1946 uint8_t bloscCompressed(0);
1947 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1948 os.write(reinterpret_cast<const char*>(this->
data()), this->arrayMemUsage());
1953 template<
typename ValueType_,
typename Codec_>
1957 if (!outputTransient && this->isTransient())
return;
1961 if (!bloscCompression) {
1966 if (
mFlags & PARTIALREAD) {
1967 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1972 os.
write(reinterpret_cast<const char*>(this->
data()), this->arrayMemUsage());
1976 template<
typename ValueType_,
typename Codec_>
1978 #if OPENVDB_ABI_VERSION_NUMBER >= 10
1984 if (!(this->isOutOfCore()))
return;
1990 assert(self->mPageHandle);
1991 assert(!(self->mFlags & PARTIALREAD));
1993 std::unique_ptr<char[]>
buffer =
self->mPageHandle->read();
1995 self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1997 self->mPageHandle.reset();
2001 self->mOutOfCore =
false;
2005 template<
typename ValueType_,
typename Codec_>
2020 template<
typename ValueType_,
typename Codec_>
2025 if(!otherT)
return false;
2026 if(this->mSize != otherT->mSize ||
2027 this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
2029 this->attributeType() != this->attributeType())
return false;
2035 if (!target && !
source)
return true;
2036 if (!target || !
source)
return false;
2037 Index n = this->mIsUniform ? 1 : mSize;
2043 template<
typename ValueType_,
typename Codec_>
2045 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
2047 return reinterpret_cast<char*
>(this->
data());
2051 template<
typename ValueType_,
typename Codec_>
2053 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
const
2055 return reinterpret_cast<const char*
>(this->
data());
2063 template <
typename CodecType,
typename ValueType>
2084 template <
typename ValueType>
2092 return (*functor)(array,
n);
2097 (*functor)(array,
n,
value);
2106 template <
typename ValueType,
typename CodecType>
2107 typename AttributeHandle<ValueType, CodecType>::Ptr
2114 template <
typename ValueType,
typename CodecType>
2117 , mStrideOrTotalSize(array.hasConstantStride() ? array.
stride() : 1)
2118 , mSize(array.hasConstantStride() ? array.
size() : array.dataSize())
2119 , mCollapseOnDestruction(collapseOnDestruction && array.isStreaming())
2122 OPENVDB_THROW(TypeError,
"Cannot bind handle due to incompatible type of AttributeArray.");
2142 template <
typename ValueType,
typename CodecType>
2146 if (mCollapseOnDestruction)
const_cast<AttributeArray*
>(this->mArray)->collapse();
2149 template <
typename ValueType,
typename CodecType>
2150 template <
bool IsUnknownCodec>
2156 return mArray->hasValueType<
ValueType>();
2159 template <
typename ValueType,
typename CodecType>
2160 template <
bool IsUnknownCodec>
2162 AttributeHandle<ValueType, CodecType>::compatibleType()
const
2166 return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
2169 template <
typename ValueType,
typename CodecType>
2176 template <
typename ValueType,
typename CodecType>
2180 assert(index < (mSize * mStrideOrTotalSize));
2184 template <
typename ValueType,
typename CodecType>
2190 template <
typename ValueType,
typename CodecType>
2191 template <
bool IsUnknownCodec>
2197 return (*mGetter)(mArray, index);
2200 template <
typename ValueType,
typename CodecType>
2201 template <
bool IsUnknownCodec>
2210 template <
typename ValueType,
typename CodecType>
2213 return mArray->isUniform();
2216 template <
typename ValueType,
typename CodecType>
2219 return mArray->hasConstantStride();
2226 template <
typename ValueType,
typename CodecType>
2234 template <
typename ValueType,
typename CodecType>
2238 if (expand) array.
expand();
2241 template <
typename ValueType,
typename CodecType>
2247 template <
typename ValueType,
typename CodecType>
2253 template <
typename ValueType,
typename CodecType>
2259 template <
typename ValueType,
typename CodecType>
2265 template <
typename ValueType,
typename CodecType>
2271 template <
typename ValueType,
typename CodecType>
2274 this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2277 template <
typename ValueType,
typename CodecType>
2280 this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2283 template <
typename ValueType,
typename CodecType>
2284 template <
bool IsUnknownCodec>
2290 (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index,
value);
2293 template <
typename ValueType,
typename CodecType>
2294 template <
bool IsUnknownCodec>
2303 template <
typename ValueType,
typename CodecType>
2306 assert(this->mArray);
2315 #endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
bool isUniform() const override
Return true if this array is stored as a single uniform value.
void readBuffers(std::istream &) override
Read attribute buffers from a stream.
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
static void unregisterType()
Remove this attribute type from the registry.
std::unique_ptr< Handle > UniquePtr
ValueType getUnsafe(Index n) const
Return the value at index n (assumes in-core)
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
void loadData() const override
Ensures all data is in-core.
virtual void expand(bool fill=true)=0
If this array is uniform, replace it with an array of length size().
~TypedAttributeArray() override
virtual Index storageTypeSize() const =0
std::unique_ptr< PageHandle > Ptr
GLdouble GLdouble GLint GLint const GLdouble * points
size_t memUsage() const override
Return the number of bytes of memory used by this attribute.
Index stride() const override
Write-able version of AttributeHandle.
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
bool isHidden() const
Return true if this attribute is hidden (e.g., from UI or iterators).
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
std::unique_ptr< Handle > ScopedPtr
bool hasConstantStride() const
virtual Index stride() const =0
bool isStreaming() const
Return true if this attribute is in streaming mode.
static const char * name()
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
bool compact()
Compact the existing array to become uniform if all values are identical.
PagedOutputStream & write(const char *str, std::streamsize n)
Writes the given.
typename T::ValueType ElementType
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>
typename attribute_traits::TruncateTrait< T >::Type Type
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
std::shared_ptr< AccessorBase > AccessorBasePtr
static void decode(const StorageType &, ValueType &)
virtual ~AttributeHandle()
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK, etc.) specifying whether and how input data is compressed or output data should be compressed.
void collapse() override
Replace the existing array with a uniform zero value.
bool valueTypeIsFloatingPoint() const override
Return true if the value type is floating point.
static void registerType(const NamePair &type, FactoryMethod, const ScopedRegistryLock *lock=nullptr)
Register a attribute type along with a factory function.
#define OPENVDB_LOG_WARN(mesg)
IntegerT floatingPointToFixedPoint(const FloatT s)
void(*)(AttributeArray *array, const Index n, const T &value) SetterPtr
ValueType get(Index n) const
Return the value at index n.
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
GLuint GLsizei GLsizei * length
#define OPENVDB_USE_VERSION_NAMESPACE
static ValueType encode(const ValueType &value)
StorageType * data()
Return the raw data buffer.
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
**But if you need a or simply need to know when the task has note that the like this
bool hasConstantStride() const
Return true if this attribute has a constant stride.
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
bool compact() override
Compact the existing array to become uniform if all values are identical.
bool valueTypeIsMatrix() const override
Return true if the value type is a matrix.
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
static void encode(const ValueType &, StorageType &)
void expand(bool fill=true)
If this array is uniform, replace it with an array of length size().
static const char * name()
void copyValues(const AttributeArray &sourceArray, const IterT &iter, bool compact=true)
Like copyValuesUnsafe(), but if compact is true, attempt to collapse this array.
const AttributeArray * mArray
std::ostream & getOutputStream()
Set and get the output stream.
const NamePair & type() const override
Return the name of this attribute's type.
static void encode(const math::Vec3< T > &, StorageType &)
void collapse()
Replace the existing array with a uniform value (zero if none provided).
void(*)(AttributeArray *array, const Index n, const Index &value) SetterPtr
TypedAttributeArray & operator=(const TypedAttributeArray &)
static Ptr create(AttributeArray &array, const bool expand=true)
static void decode(const StorageType &, ValueType &)
void(*)(AttributeArray *array, const Index &value) ValuePtr
AttributeArray::Ptr copy() const override
TypedAttributeArray(Index n=1, Index strideOrTotalSize=1, bool constantStride=true, const ValueType &uniformValue=zeroVal< ValueType >())
Default constructor, always constructs a uniform attribute.
typename attribute_traits::UIntTypeTrait< OneByte, T >::Type Type
std::shared_ptr< Handle > Ptr
static const char * name()
void(*)(AttributeArray *array, const T &value) ValuePtr
static const char * name()
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
void setConstantStride(bool state)
Specify whether this attribute has a constant stride or not.
bool operator!=(const AttributeArray &other) const
virtual Index dataSize() const =0
Base class for storing attribute data.
AttributeWriteHandle(AttributeArray &array, const bool expand=true)
const StorageType * data() const
void writeBuffers(std::ostream &os, bool outputTransient) const override
IMATH_NAMESPACE::V2f float
Index storageTypeSize() const override
FloatT fixedPointToFloatingPoint(const IntegerT s)
Index size() const override
Return the number of elements in this array.
virtual bool valueTypeIsFloatingPoint() const =0
Return true if the value type is floating point.
AttributeHandle(const AttributeArray &array, const bool collapseOnDestruction=true)
static void unregisterType(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Remove a attribute type from the registry.
Accessor to call unsafe get and set methods based on templated Codec and Value.
static uint16_t pack(const Vec3< T > &vec)
Index index(Index n, Index m) const
virtual AccessorBasePtr getAccessor() const =0
Obtain an Accessor that stores getter and setter functors.
virtual void loadData() const =0
Ensures all data is in-core.
static const NamePair & attributeType()
Return the name of this attribute's type (includes codec)
GLsizei GLsizei GLchar * source
GLint GLenum GLboolean GLsizei stride
const StorageType * constData() const
Return the raw data buffer.
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
void readMetadata(std::istream &) override
Read attribute metadata from a stream.
Index valueTypeSize() const override
Return the size in bytes of the value type of a single element in this array.
std::shared_ptr< AttributeArray > Ptr
static bool isRegistered(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Return true if the given attribute type name is registered.
std::shared_ptr< Handle > Ptr
Convenience wrappers to using Blosc and reading and writing of Paged data.
void readPagedBuffers(compression::PagedInputStream &) override
Read attribute buffers from a paged stream.
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...
AttributeArray::Ptr copyUncompressed() const override
virtual bool isUniform() const =0
Return true if this array is stored as a single uniform value.
std::istream & getInputStream()
GLuint const GLchar * name
std::pair< Name, Name > NamePair
void writeMetadata(std::ostream &os, bool outputTransient, bool paged) const override
bool isTransient() const
Return true if this attribute is not serialized during stream output.
static ValueType encode(const ValueType &value)
GLboolean GLboolean GLboolean b
bool hasValueType() const
Return true if this attribute has a value type the same as the template parameter.
Name codecType() const override
Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
static ValueType decode(const ValueType &value)
std::shared_ptr< const AttributeArray > ConstPtr
bool compress() override
Compress the attribute array.
static bool isRegistered()
Return true if this attribute type is registered.
virtual bool isDataLoaded() const =0
Return true if all data has been loaded.
AttributeHandle & operator=(const AttributeHandle &)=default
static ValueType decode(const ValueType &value)
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
PageHandle::Ptr createHandle(std::streamsize n)
Creates a PageHandle to access the next.
virtual ~AttributeArray()
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
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.
static void decode(const StorageType &, math::Vec3< T > &)
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...
void writePagedBuffers(compression::PagedOutputStream &os, bool outputTransient) const override
uint8_t flags() const
Retrieve the attribute array flags.
Name valueType() const override
Return the name of the value type of a single element in this array (e.g., "float" or "vec3d")...
const AttributeArray & array() const
void set(Index n, const ValueType &value)
Set value at the given index n.
Typed class for storing attribute data.
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
LeafData & operator=(const LeafData &)=delete
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
bool isDataLoaded() const override
Return true if all data has been loaded.
void fill(const ValueType &value)
Fill the existing array with the given value.
virtual ~AccessorBase()=default
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void write(std::ostream &os, bool outputTransient) const override
AccessorBasePtr getAccessor() const override
Obtain an Accessor that stores getter and setter functors.
static const char * name()
static const char * name()
std::shared_ptr< TypedAttributeArray > Ptr
bool valueTypeIsVector() const override
Return true if the value type is a vector.
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
typename Codec::template Storage< ValueType >::Type StorageType
void set(Index n, const ValueType &value)
void read(std::istream &) override
Read attribute data from a stream.
static void set(SetterPtr functor, AttributeArray *array, const Index n, const ValueType &value)
Setter that calls the supplied functor.
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
static void encode(const ValueType &, StorageType &)
static Vec3s unpack(const uint16_t data)
Accessor base class for AttributeArray storage where type is not available.
Ptr(*)(Index, Index, bool, const Metadata *) FactoryMethod
static void decode(const ValueType &, ValueType &)
compression::PageHandle::Ptr mPageHandle
T(*)(const AttributeArray *array, const Index n) GetterPtr
bool valueTypeIsQuaternion() const override
Return true if the value type is a quaternion.
static void set(SetterPtr, AttributeArray *array, const Index n, const ValueType &value)
streaming mode collapses attributes when first accessed
void setUnsafe(Index n, const ValueType &value)
Set value at the given index n (assumes in-core)
void fill(const ValueType &value)
Fill the existing array with the given value.
bool isType() const
Return true if this attribute is of the same type as the template parameter.
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.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
static void registerType()
Register this attribute type along with a factory function.
bool valueTypeIsClass() const override
Return true if the value type is a class (ie vector, matrix or quaternion return true) ...
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler)
void expand(bool fill=true) override
Replace the single value storage with an array of length size().
bool decompress() override
Uncompress the attribute array.
bool validData() const
Verify that data is not out-of-core or in a partially-read state.
ValueType get(Index n, Index m=0) const
static void encode(const ValueType &, ValueType &)
Index dataSize() const override
Return the size of the data in this array.
Index(*)(const AttributeArray *array, const Index n) GetterPtr
#define OPENVDB_THROW(exception, message)
std::atomic< Index32 > mOutOfCore
virtual ~AttributeWriteHandle()=default