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);
299 bool isHidden()
const {
return bool(mFlags & HIDDEN); }
304 void setTransient(
bool state);
312 void setStreaming(
bool state);
320 uint8_t
flags()
const {
return mFlags; }
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>
474 template<
typename ValueType>
static void decode(
const ValueType&, ValueType&);
475 template<
typename ValueType>
static void encode(
const ValueType&, ValueType&);
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"; }
495 template <
typename ValueType>
static ValueType
encode(
const ValueType&
value) {
return value + ValueType(0.5); }
496 template <
typename ValueType>
static ValueType
decode(
const ValueType&
value) {
return value - ValueType(0.5); }
503 static const char*
name() {
return "ufxpt"; }
504 template <
typename ValueType>
static ValueType
encode(
const ValueType&
value) {
return value; }
505 template <
typename ValueType>
static ValueType
decode(
const ValueType&
value) {
return value; }
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;
770 #if OPENVDB_ABI_VERSION_NUMBER >= 9
786 friend class ::TestAttributeArray;
791 inline void doLoad()
const;
793 #if OPENVDB_ABI_VERSION_NUMBER >= 10
794 inline void doLoadUnsafe()
const;
797 inline void doLoadUnsafe(
const bool compression =
true)
const;
799 inline bool compressUnsafe();
803 inline void setOutOfCore(
const bool);
809 char* dataAsByteArray()
override;
810 const char* dataAsByteArray()
const override;
812 size_t arrayMemUsage()
const;
822 std::unique_ptr<StorageType[]> mData;
824 Index mStrideOrTotalSize;
833 template <
typename ValueType,
typename CodecType = UnknownCodec>
838 using Ptr = std::shared_ptr<Handle>;
877 friend class ::TestAttributeArray;
879 template <
bool IsUnknownCodec>
882 template <
bool IsUnknownCodec>
885 template <
bool IsUnknownCodec>
888 template <
bool IsUnknownCodec>
894 Index mStrideOrTotalSize;
896 bool mCollapseOnDestruction;
904 template <
typename ValueType,
typename CodecType = UnknownCodec>
909 using Ptr = std::shared_ptr<Handle>;
924 void collapse(
const ValueType& uniformValue);
939 friend class ::TestAttributeArray;
941 template <
bool IsUnknownCodec>
944 template <
bool IsUnknownCodec>
955 template<
typename ValueType>
963 template<
typename ValueType>
971 template<
typename StorageType,
typename ValueType>
975 val =
static_cast<ValueType
>(
data);
979 template<
typename StorageType,
typename ValueType>
983 data =
static_cast<StorageType
>(
val);
987 template <
bool OneByte,
typename Range>
988 template<
typename StorageType,
typename ValueType>
992 val = fixedPointToFloatingPoint<ValueType>(
data);
996 val = Range::template decode<ValueType>(
val);
1000 template <
bool OneByte,
typename Range>
1001 template<
typename StorageType,
typename ValueType>
1007 const ValueType newVal = Range::template encode<ValueType>(
val);
1009 data = floatingPointToFixedPoint<StorageType>(newVal);
1013 template<
typename T>
1021 template<
typename T>
1033 template <
typename IterT>
1034 void AttributeArray::doCopyValues(
const AttributeArray& sourceArray,
const IterT& iter,
1046 const char*
const sourceBuffer = sourceArray.dataAsByteArray();
1047 char*
const targetBuffer = this->dataAsByteArray();
1048 assert(sourceBuffer && targetBuffer);
1050 if (rangeChecking && this->
isUniform()) {
1051 OPENVDB_THROW(IndexError,
"Cannot copy array data as target array is uniform.");
1054 const bool sourceIsUniform = sourceArray.
isUniform();
1056 const Index sourceDataSize = rangeChecking ? sourceArray.
dataSize() : 0;
1057 const Index targetDataSize = rangeChecking ? this->
dataSize() : 0;
1059 for (IterT it(iter); it; ++it) {
1060 const Index sourceIndex = sourceIsUniform ? 0 : it.sourceIndex();
1061 const Index targetIndex = it.targetIndex();
1063 if (rangeChecking) {
1064 if (sourceIndex >= sourceDataSize) {
1066 "Cannot copy array data as source index exceeds size of source array.");
1068 if (targetIndex >= targetDataSize) {
1070 "Cannot copy array data as target index exceeds size of target array.");
1074 assert(sourceIndex < sourceArray.
dataSize());
1075 assert(targetIndex < this->
dataSize());
1079 const size_t targetOffset(targetIndex *
bytes);
1080 const size_t sourceOffset(sourceIndex *
bytes);
1082 std::memcpy(targetBuffer + targetOffset, sourceBuffer + sourceOffset,
bytes);
1086 template <
typename IterT>
1089 this->doCopyValues(sourceArray, iter,
false);
1092 template <
typename IterT>
1098 OPENVDB_THROW(TypeError,
"Cannot copy array data due to mis-match in storage type sizes.");
1114 this->doCopyValues(sourceArray, iter,
true);
1128 template<
typename ValueType_,
typename Codec_>
1134 , mStrideOrTotalSize(strideOrTotalSize)
1136 if (constantStride) {
1138 if (strideOrTotalSize == 0) {
1139 OPENVDB_THROW(ValueError,
"Creating a TypedAttributeArray with a constant stride requires that " \
1140 "stride to be at least one.")
1145 if (mStrideOrTotalSize < n) {
1146 OPENVDB_THROW(ValueError,
"Creating a TypedAttributeArray with a non-constant stride must have " \
1147 "a total size of at least the number of elements in the array.")
1151 mStrideOrTotalSize =
std::max(
Index(1), mStrideOrTotalSize);
1152 Codec::encode(uniformValue, this->
data()[0]);
1156 template<
typename ValueType_,
typename Codec_>
1158 : TypedAttributeArray(rhs, tbb::
spin_mutex::scoped_lock(rhs.mMutex))
1163 template<
typename ValueType_,
typename Codec_>
1165 const tbb::spin_mutex::scoped_lock& lock)
1168 , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
1172 std::memcpy(static_cast<void*>(this->
data()), rhs.
data(), this->arrayMemUsage());
1177 template<
typename ValueType_,
typename Codec_>
1178 TypedAttributeArray<ValueType_, Codec_>&
1183 tbb::spin_mutex::scoped_lock lock(mMutex);
1184 tbb::spin_mutex::scoped_lock rhsLock(rhs.
mMutex);
1191 mStrideOrTotalSize = rhs.mStrideOrTotalSize;
1194 if (this->validData()) {
1196 std::memcpy(static_cast<void*>(this->
data()), rhs.
data(), this->arrayMemUsage());
1204 template<
typename ValueType_,
typename Codec_>
1215 template<
typename ValueType_,
typename Codec_>
1223 template<
typename ValueType_,
typename Codec_>
1231 template<
typename ValueType_,
typename Codec_>
1239 template<
typename ValueType_,
typename Codec_>
1247 return Ptr(
new TypedAttributeArray(n, stride, constantStride,
1248 typedMetadata ? typedMetadata->
value() : zeroVal<ValueType>()));
1251 template<
typename ValueType_,
typename Codec_>
1255 if (!attributeArray.
isType<TypedAttributeArray>()) {
1258 return static_cast<TypedAttributeArray&
>(attributeArray);
1261 template<
typename ValueType_,
typename Codec_>
1265 if (!attributeArray.
isType<TypedAttributeArray>()) {
1268 return static_cast<const TypedAttributeArray&
>(attributeArray);
1271 template<
typename ValueType_,
typename Codec_>
1279 #if OPENVDB_ABI_VERSION_NUMBER < 10
1280 template<
typename ValueType_,
typename Codec_>
1284 return this->
copy();
1288 template<
typename ValueType_,
typename Codec_>
1292 if (this->isOutOfCore())
return 0;
1294 return (mIsUniform ? 1 : this->dataSize()) *
sizeof(StorageType);
1298 template<
typename ValueType_,
typename Codec_>
1300 TypedAttributeArray<ValueType_, Codec_>::allocate()
1304 mData.reset(
new StorageType[1]);
1307 const size_t size(this->dataSize());
1309 mData.reset(
new StorageType[
size]);
1314 template<
typename ValueType_,
typename Codec_>
1316 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1319 if (this->isOutOfCore()) {
1320 this->setOutOfCore(
false);
1321 this->mPageHandle.reset();
1323 if (mData) mData.reset();
1327 template<
typename ValueType_,
typename Codec_>
1347 template<
typename ValueType_,
typename Codec_>
1356 template<
typename ValueType_,
typename Codec_>
1364 template<
typename ValueType_,
typename Codec_>
1369 return !this->valueType().compare(0, 4,
"quat");
1373 template<
typename ValueType_,
typename Codec_>
1378 return !this->valueType().compare(0, 3,
"mat");
1382 template<
typename ValueType_,
typename Codec_>
1386 return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1389 #if OPENVDB_ABI_VERSION_NUMBER >= 10
1390 template<
typename ValueType_,
typename Codec_>
1394 return sizeof(*this) + (mIsUniform ? 1 : this->dataSize()) *
sizeof(StorageType);
1399 template<
typename ValueType_,
typename Codec_>
1400 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1406 Codec::decode(this->
data()[mIsUniform ? 0 : n], val);
1411 template<
typename ValueType_,
typename Codec_>
1415 if (n >= this->dataSize())
OPENVDB_THROW(IndexError,
"Out-of-range access.");
1416 if (this->isOutOfCore()) this->doLoad();
1418 return this->getUnsafe(n);
1422 template<
typename ValueType_,
typename Codec_>
1423 template<
typename T>
1427 val =
static_cast<T>(this->getUnsafe(n));
1431 template<
typename ValueType_,
typename Codec_>
1432 template<
typename T>
1436 val =
static_cast<T>(this->
get(
n));
1440 template<
typename ValueType_,
typename Codec_>
1448 template<
typename ValueType_,
typename Codec_>
1453 assert(!this->isOutOfCore());
1454 assert(!this->isUniform());
1459 Codec::encode(val, this->
data()[mIsUniform ? 0 : n]);
1463 template<
typename ValueType_,
typename Codec_>
1467 if (n >= this->dataSize())
OPENVDB_THROW(IndexError,
"Out-of-range access.");
1468 if (this->isOutOfCore()) this->doLoad();
1469 if (this->isUniform()) this->expand();
1471 this->setUnsafe(n, val);
1475 template<
typename ValueType_,
typename Codec_>
1476 template<
typename T>
1480 this->setUnsafe(n, static_cast<ValueType>(val));
1484 template<
typename ValueType_,
typename Codec_>
1485 template<
typename T>
1489 this->set(n, static_cast<ValueType>(val));
1493 template<
typename ValueType_,
typename Codec_>
1501 #if OPENVDB_ABI_VERSION_NUMBER < 10
1502 template<
typename ValueType_,
typename Codec_>
1506 const TypedAttributeArray& sourceTypedArray =
static_cast<const TypedAttributeArray&
>(sourceArray);
1509 sourceTypedArray.
get(sourceIndex, sourceValue);
1511 this->set(n, sourceValue);
1516 template<
typename ValueType_,
typename Codec_>
1520 if (!mIsUniform)
return;
1525 tbb::spin_mutex::scoped_lock lock(mMutex);
1532 for (
Index i = 0; i < this->dataSize(); ++i) this->
data()[i] =
val;
1537 template<
typename ValueType_,
typename Codec_>
1541 if (mIsUniform)
return true;
1544 const ValueType_
val = this->
get(0);
1545 for (
Index i = 1; i < this->dataSize(); i++) {
1549 this->collapse(this->
get(0));
1554 template<
typename ValueType_,
typename Codec_>
1558 this->collapse(zeroVal<ValueType>());
1562 template<
typename ValueType_,
typename Codec_>
1567 tbb::spin_mutex::scoped_lock lock(mMutex);
1572 Codec::encode(uniformValue, this->
data()[0]);
1576 template<
typename ValueType_,
typename Codec_>
1584 template<
typename ValueType_,
typename Codec_>
1588 if (this->isOutOfCore()) {
1589 tbb::spin_mutex::scoped_lock lock(mMutex);
1594 const Index size = mIsUniform ? 1 : this->dataSize();
1596 Codec::encode(value, this->
data()[i]);
1601 template<
typename ValueType_,
typename Codec_>
1609 #if OPENVDB_ABI_VERSION_NUMBER < 10
1610 template<
typename ValueType_,
typename Codec_>
1618 template<
typename ValueType_,
typename Codec_>
1626 template<
typename ValueType_,
typename Codec_>
1635 template<
typename ValueType_,
typename Codec_>
1643 template<
typename ValueType_,
typename Codec_>
1651 template<
typename ValueType_,
typename Codec_>
1653 TypedAttributeArray<ValueType_, Codec_>::doLoad()
const
1655 if (!(this->isOutOfCore()))
return;
1657 TypedAttributeArray<ValueType_, Codec_>*
self =
1658 const_cast<TypedAttributeArray<ValueType_, Codec_>*
>(
this);
1662 tbb::spin_mutex::scoped_lock lock(self->mMutex);
1663 this->doLoadUnsafe();
1667 template<
typename ValueType_,
typename Codec_>
1675 template<
typename ValueType_,
typename Codec_>
1679 return !this->isOutOfCore();
1683 template<
typename ValueType_,
typename Codec_>
1687 this->readMetadata(is);
1688 this->readBuffers(is);
1692 template<
typename ValueType_,
typename Codec_>
1699 is.read(reinterpret_cast<char*>(&bytes),
sizeof(
Index64));
1700 bytes = bytes -
sizeof(
Int16) -
sizeof(
Index);
1702 uint8_t
flags = uint8_t(0);
1703 is.read(reinterpret_cast<char*>(&flags),
sizeof(uint8_t));
1706 uint8_t serializationFlags = uint8_t(0);
1707 is.read(reinterpret_cast<char*>(&serializationFlags),
sizeof(uint8_t));
1710 is.read(reinterpret_cast<char*>(&size),
sizeof(
Index));
1714 if (mFlags >= 0x20) {
1719 if (serializationFlags >= 0x10) {
1720 OPENVDB_THROW(IoError,
"Unknown attribute serialization flags for VDB file format.");
1725 mIsUniform = serializationFlags & WRITEUNIFORM;
1726 mUsePagedRead = serializationFlags & WRITEPAGED;
1727 mCompressedBytes = bytes;
1728 mFlags |= PARTIALREAD;
1732 if (serializationFlags & WRITESTRIDED) {
1734 is.read(reinterpret_cast<char*>(&stride),
sizeof(
Index));
1735 mStrideOrTotalSize =
stride;
1738 mStrideOrTotalSize = 1;
1743 template<
typename ValueType_,
typename Codec_>
1747 if (mUsePagedRead) {
1749 OPENVDB_THROW(IoError,
"Cannot read paged AttributeArray buffers.");
1752 tbb::spin_mutex::scoped_lock lock(mMutex);
1756 uint8_t bloscCompressed(0);
1757 if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed),
sizeof(uint8_t));
1759 assert(mFlags & PARTIALREAD);
1760 std::unique_ptr<char[]>
buffer(
new char[mCompressedBytes]);
1761 is.read(buffer.get(), mCompressedBytes);
1762 mCompressedBytes = 0;
1763 mFlags =
static_cast<uint8_t
>(mFlags & ~PARTIALREAD);
1767 if (bloscCompressed == uint8_t(1)) {
1771 const size_t inBytes = this->dataSize() *
sizeof(
StorageType);
1773 if (newBuffer) buffer.reset(newBuffer.release());
1778 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1782 template<
typename ValueType_,
typename Codec_>
1786 if (!mUsePagedRead) {
1791 #ifdef OPENVDB_USE_DELAYED_LOADING
1794 io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is.
getInputStream());
1795 const bool delayLoad = (mappedFile.get() !=
nullptr);
1800 size_t compressedBytes(mCompressedBytes);
1801 mCompressedBytes = 0;
1802 mFlags =
static_cast<uint8_t
>(mFlags & ~PARTIALREAD);
1803 assert(!mPageHandle);
1808 assert(mPageHandle);
1810 tbb::spin_mutex::scoped_lock lock(mMutex);
1814 #ifdef OPENVDB_USE_DELAYED_LOADING
1815 this->setOutOfCore(delayLoad);
1816 is.
read(mPageHandle, std::streamsize(mPageHandle->size()), delayLoad);
1818 is.
read(mPageHandle, std::streamsize(mPageHandle->size()),
false);
1819 #endif // OPENVDB_USE_DELAYED_LOADING
1821 #ifdef OPENVDB_USE_DELAYED_LOADING
1824 std::unique_ptr<char[]>
buffer = mPageHandle->read();
1825 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1826 mPageHandle.reset();
1827 #ifdef OPENVDB_USE_DELAYED_LOADING
1837 template<
typename ValueType_,
typename Codec_>
1841 this->
write(os,
false);
1845 template<
typename ValueType_,
typename Codec_>
1849 this->writeMetadata(os, outputTransient,
false);
1850 this->writeBuffers(os, outputTransient);
1854 template<
typename ValueType_,
typename Codec_>
1858 if (!outputTransient && this->isTransient())
return;
1860 if (mFlags & PARTIALREAD) {
1861 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1864 uint8_t
flags(mFlags);
1865 uint8_t serializationFlags(0);
1868 bool strideOfOne(this->
stride() == 1);
1873 if (bloscCompression) this->doLoad();
1875 size_t compressedBytes = 0;
1879 serializationFlags |= WRITESTRIDED;
1884 serializationFlags |= WRITEUNIFORM;
1885 if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1887 else if (bloscCompression)
1889 if (paged) serializationFlags |= WRITEPAGED;
1891 const char* charBuffer =
reinterpret_cast<const char*
>(this->
data());
1892 const size_t inBytes = this->arrayMemUsage();
1899 bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1903 os.write(reinterpret_cast<const char*>(&bytes),
sizeof(
Index64));
1904 os.write(reinterpret_cast<const char*>(&flags),
sizeof(uint8_t));
1905 os.write(reinterpret_cast<const char*>(&serializationFlags),
sizeof(uint8_t));
1906 os.write(reinterpret_cast<const char*>(&size),
sizeof(
Index));
1909 if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride),
sizeof(
Index));
1913 template<
typename ValueType_,
typename Codec_>
1917 if (!outputTransient && this->isTransient())
return;
1919 if (mFlags & PARTIALREAD) {
1920 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1925 if (this->isUniform()) {
1926 os.write(reinterpret_cast<const char*>(this->
data()),
sizeof(
StorageType));
1930 std::unique_ptr<char[]> compressedBuffer;
1931 size_t compressedBytes = 0;
1932 const char* charBuffer =
reinterpret_cast<const char*
>(this->
data());
1933 const size_t inBytes = this->arrayMemUsage();
1935 if (compressedBuffer) {
1936 uint8_t bloscCompressed(1);
1937 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1938 os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1941 uint8_t bloscCompressed(0);
1942 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1943 os.write(reinterpret_cast<const char*>(this->
data()), inBytes);
1948 uint8_t bloscCompressed(0);
1949 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1950 os.write(reinterpret_cast<const char*>(this->
data()), this->arrayMemUsage());
1955 template<
typename ValueType_,
typename Codec_>
1959 if (!outputTransient && this->isTransient())
return;
1963 if (!bloscCompression) {
1968 if (mFlags & PARTIALREAD) {
1969 OPENVDB_THROW(IoError,
"Cannot write out a partially-read AttributeArray.");
1974 os.
write(reinterpret_cast<const char*>(this->
data()), this->arrayMemUsage());
1978 template<
typename ValueType_,
typename Codec_>
1980 #if OPENVDB_ABI_VERSION_NUMBER >= 10
1986 if (!(this->isOutOfCore()))
return;
1992 assert(self->mPageHandle);
1993 assert(!(self->mFlags & PARTIALREAD));
1995 std::unique_ptr<char[]>
buffer =
self->mPageHandle->read();
1997 self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1999 self->mPageHandle.reset();
2003 self->mOutOfCore =
false;
2007 template<
typename ValueType_,
typename Codec_>
2022 template<
typename ValueType_,
typename Codec_>
2027 if(!otherT)
return false;
2028 if(this->mSize != otherT->mSize ||
2029 this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
2031 this->attributeType() != this->attributeType())
return false;
2037 if (!target && !
source)
return true;
2038 if (!target || !
source)
return false;
2039 Index n = this->mIsUniform ? 1 : mSize;
2045 template<
typename ValueType_,
typename Codec_>
2047 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
2049 return reinterpret_cast<char*
>(this->
data());
2053 template<
typename ValueType_,
typename Codec_>
2055 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
const
2057 return reinterpret_cast<const char*
>(this->
data());
2065 template <
typename CodecType,
typename ValueType>
2086 template <
typename ValueType>
2094 return (*functor)(array,
n);
2099 (*functor)(array,
n,
value);
2108 template <
typename ValueType,
typename CodecType>
2109 typename AttributeHandle<ValueType, CodecType>::Ptr
2116 template <
typename ValueType,
typename CodecType>
2119 , mStrideOrTotalSize(array.hasConstantStride() ? array.
stride() : 1)
2120 , mSize(array.hasConstantStride() ? array.
size() : array.dataSize())
2121 , mCollapseOnDestruction(collapseOnDestruction && array.isStreaming())
2124 OPENVDB_THROW(TypeError,
"Cannot bind handle due to incompatible type of AttributeArray.");
2144 template <
typename ValueType,
typename CodecType>
2148 if (mCollapseOnDestruction)
const_cast<AttributeArray*
>(this->mArray)->collapse();
2151 template <
typename ValueType,
typename CodecType>
2152 template <
bool IsUnknownCodec>
2158 return mArray->hasValueType<ValueType>();
2161 template <
typename ValueType,
typename CodecType>
2162 template <
bool IsUnknownCodec>
2164 AttributeHandle<ValueType, CodecType>::compatibleType()
const
2168 return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
2171 template <
typename ValueType,
typename CodecType>
2178 template <
typename ValueType,
typename CodecType>
2182 assert(index < (mSize * mStrideOrTotalSize));
2186 template <
typename ValueType,
typename CodecType>
2192 template <
typename ValueType,
typename CodecType>
2193 template <
bool IsUnknownCodec>
2199 return (*mGetter)(mArray, index);
2202 template <
typename ValueType,
typename CodecType>
2203 template <
bool IsUnknownCodec>
2212 template <
typename ValueType,
typename CodecType>
2215 return mArray->isUniform();
2218 template <
typename ValueType,
typename CodecType>
2221 return mArray->hasConstantStride();
2228 template <
typename ValueType,
typename CodecType>
2236 template <
typename ValueType,
typename CodecType>
2240 if (expand) array.
expand();
2243 template <
typename ValueType,
typename CodecType>
2249 template <
typename ValueType,
typename CodecType>
2255 template <
typename ValueType,
typename CodecType>
2261 template <
typename ValueType,
typename CodecType>
2267 template <
typename ValueType,
typename CodecType>
2273 template <
typename ValueType,
typename CodecType>
2276 this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2279 template <
typename ValueType,
typename CodecType>
2282 this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2285 template <
typename ValueType,
typename CodecType>
2286 template <
bool IsUnknownCodec>
2292 (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index,
value);
2295 template <
typename ValueType,
typename CodecType>
2296 template <
bool IsUnknownCodec>
2305 template <
typename ValueType,
typename CodecType>
2308 assert(this->mArray);
2317 #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().
void read(T &in, bool &v)
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
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
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;.
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.
void write(T &out, bool v)
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