37 #ifndef OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
40 #include <openvdb/Types.h>
41 #include <openvdb/math/QuantizedUnitVec.h>
42 #include <openvdb/util/Name.h>
43 #include <openvdb/util/logging.h>
44 #include <openvdb/io/io.h>
45 #include <openvdb/io/Compression.h>
50 #include <tbb/spin_mutex.h>
51 #include <tbb/atomic.h>
55 #include <type_traits>
58 class TestAttributeArray;
74 template <
typename IntegerT,
typename FloatT>
78 static_assert(std::is_unsigned<IntegerT>::value,
"IntegerT must be unsigned");
85 template <
typename FloatT,
typename IntegerT>
89 static_assert(std::is_unsigned<IntegerT>::value,
"IntegerT must be unsigned");
93 template <
typename IntegerVectorT,
typename FloatT>
97 return IntegerVectorT(
98 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
x()),
99 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
y()),
100 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.
z()));
103 template <
typename FloatVectorT,
typename IntegerT>
108 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
x()),
109 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
y()),
110 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.
z()));
131 CONSTANTSTRIDE = 0x8,
138 WRITEMEMCOMPRESS = 0x4,
142 using Ptr = std::shared_ptr<AttributeArray>;
143 using ConstPtr = std::shared_ptr<const AttributeArray>;
162 virtual Index size()
const = 0;
166 virtual Index stride()
const = 0;
170 virtual Index dataSize()
const = 0;
173 virtual size_t memUsage()
const = 0;
178 static bool isRegistered(
const NamePair& type);
180 static void clearRegistry();
183 virtual const NamePair& type()
const = 0;
185 template<
typename AttributeArrayType>
186 bool isType()
const {
return this->type() == AttributeArrayType::attributeType(); }
189 template<
typename ValueType>
190 bool hasValueType()
const {
return this->type().first == typeNameAsString<ValueType>(); }
196 virtual bool isUniform()
const = 0;
199 virtual void expand(
bool fill =
true) = 0;
201 virtual void collapse() = 0;
203 virtual bool compact() = 0;
208 virtual bool compress() = 0;
210 virtual bool decompress() = 0;
216 void setHidden(
bool state);
218 bool isHidden()
const {
return bool(mFlags & HIDDEN); }
223 void setTransient(
bool state);
231 void setStreaming(
bool state);
239 uint8_t
flags()
const {
return mFlags; }
242 virtual void read(std::istream&) = 0;
245 virtual void write(std::ostream&,
bool outputTransient)
const = 0;
247 virtual void write(std::ostream&)
const = 0;
250 virtual void readMetadata(std::istream&) = 0;
254 virtual void writeMetadata(std::ostream&,
bool outputTransient,
bool paged)
const = 0;
257 virtual void readBuffers(std::istream&) = 0;
260 virtual void writeBuffers(std::ostream&,
bool outputTransient)
const = 0;
269 virtual void loadData()
const = 0;
278 friend class ::TestAttributeArray;
286 void setConstantStride(
bool state);
294 static void unregisterType(
const NamePair& type);
296 size_t mCompressedBytes = 0;
298 uint8_t mSerializationFlags = 0;
300 #if OPENVDB_ABI_VERSION_NUMBER >= 5
301 tbb::atomic<Index32> mOutOfCore = 0;
317 template <
typename T>
325 mGetter(getter), mSetter(setter), mCollapser(collapser), mFiller(filler) { }
337 namespace attribute_traits
369 template <
typename T>
372 template<
typename ValueType>
static void decode(
const ValueType&, ValueType&);
373 template<
typename ValueType>
static void encode(
const ValueType&, ValueType&);
374 static const char*
name() {
return "null"; }
380 template <
typename T>
383 template<
typename StorageType,
typename ValueType>
static void decode(
const StorageType&, ValueType&);
384 template<
typename StorageType,
typename ValueType>
static void encode(
const ValueType&, StorageType&);
385 static const char*
name() {
return "trnc"; }
392 static const char*
name() {
return "fxpt"; }
393 template <
typename ValueType>
static ValueType
encode(
const ValueType& value) {
return value + ValueType(0.5); }
394 template <
typename ValueType>
static ValueType
decode(
const ValueType& value) {
return value - ValueType(0.5); }
401 static const char*
name() {
return "ufxpt"; }
402 template <
typename ValueType>
static ValueType
encode(
const ValueType& value) {
return value; }
403 template <
typename ValueType>
static ValueType
decode(
const ValueType& value) {
return value; }
407 template <
bool OneByte,
typename Range=PositionRange>
410 template <
typename T>
413 template<
typename StorageType,
typename ValueType>
static void decode(
const StorageType&, ValueType&);
414 template<
typename StorageType,
typename ValueType>
static void encode(
const ValueType&, StorageType&);
417 static const std::string
Name = std::string(Range::name()) + (OneByte ?
"8" :
"16");
427 template <
typename T>
432 static const char*
name() {
return "uvec"; }
440 template<
typename ValueType_,
typename Codec_ = NullCodec>
444 using Ptr = std::shared_ptr<TypedAttributeArray>;
445 using ConstPtr = std::shared_ptr<const TypedAttributeArray>;
449 using StorageType =
typename Codec::template Storage<ValueType>::Type;
455 const ValueType& uniformValue = zeroVal<ValueType>());
474 static Ptr create(
Index n,
Index strideOrTotalSize = 1,
bool constantStride =
true);
483 static const NamePair& attributeType();
488 static bool isRegistered();
490 static void registerType();
492 static void unregisterType();
499 Index stride()
const override {
return hasConstantStride() ? mStrideOrTotalSize : 0; }
503 return hasConstantStride() ? mSize * mStrideOrTotalSize : mStrideOrTotalSize;
507 size_t memUsage()
const override;
510 ValueType getUnsafe(
Index n)
const;
512 ValueType get(
Index n)
const;
514 template<
typename T>
void getUnsafe(
Index n, T& value)
const;
516 template<
typename T>
void get(
Index n, T& value)
const;
523 void setUnsafe(
Index n,
const ValueType& value);
525 void set(
Index n,
const ValueType& value);
527 template<
typename T>
void setUnsafe(
Index n,
const T& value);
529 template<
typename T>
void set(
Index n,
const T& value);
543 void expand(
bool fill =
true)
override;
545 void collapse()
override;
547 bool compact()
override;
550 void collapse(
const ValueType& uniformValue);
553 void fill(
const ValueType& value);
556 static void collapse(
AttributeArray* array,
const ValueType& value);
561 bool compress()
override;
563 bool decompress()
override;
566 void read(std::istream&)
override;
570 void write(std::ostream& os,
bool outputTransient)
const override;
572 void write(std::ostream&)
const override;
575 void readMetadata(std::istream&)
override;
580 void writeMetadata(std::ostream& os,
bool outputTransient,
bool paged)
const override;
583 void readBuffers(std::istream&)
override;
587 void writeBuffers(std::ostream& os,
bool outputTransient)
const override;
597 inline bool isOutOfCore()
const;
600 void loadData()
const override;
603 AccessorBasePtr getAccessor()
const override;
607 inline void doLoad()
const;
610 inline void doLoadUnsafe(
const bool compression =
true)
const;
612 inline bool compressUnsafe();
615 inline void setOutOfCore(
const bool);
620 size_t arrayMemUsage()
const;
626 return TypedAttributeArray::create(n, strideOrTotalSize, constantStride);
629 static tbb::atomic<const NamePair*> sTypeName;
630 std::unique_ptr<StorageType[]> mData;
632 Index mStrideOrTotalSize;
633 bool mIsUniform =
false;
634 tbb::spin_mutex mMutex;
643 template <
typename ValueType,
typename CodecType = UnknownCodec>
648 using Ptr = std::shared_ptr<Handle>;
657 static Ptr create(
const AttributeArray& array,
const bool preserveCompression =
true);
669 bool isUniform()
const;
670 bool hasConstantStride()
const;
687 friend class ::TestAttributeArray;
689 template <
bool IsUnknownCodec>
690 typename std::enable_if<IsUnknownCodec, bool>::type compatibleType()
const;
692 template <
bool IsUnknownCodec>
693 typename std::enable_if<!IsUnknownCodec, bool>::type compatibleType()
const;
695 template <
bool IsUnknownCodec>
696 typename std::enable_if<IsUnknownCodec, ValueType>::type get(
Index index)
const;
698 template <
bool IsUnknownCodec>
699 typename std::enable_if<!IsUnknownCodec, ValueType>::type get(
Index index)
const;
704 Index mStrideOrTotalSize;
706 bool mCollapseOnDestruction;
714 template <
typename ValueType,
typename CodecType = UnknownCodec>
719 using Ptr = std::shared_ptr<Handle>;
730 void expand(
bool fill =
true);
734 void collapse(
const ValueType& uniformValue);
741 void fill(
const ValueType& value);
743 void set(
Index n,
const ValueType& value);
744 void set(
Index n,
Index m,
const ValueType& value);
749 friend class ::TestAttributeArray;
751 template <
bool IsUnknownCodec>
752 typename std::enable_if<IsUnknownCodec, void>::type set(
Index index,
const ValueType& value)
const;
754 template <
bool IsUnknownCodec>
755 typename std::enable_if<!IsUnknownCodec, void>::type set(
Index index,
const ValueType& value)
const;
765 template<
typename ValueType>
767 NullCodec::decode(
const ValueType& data, ValueType& val)
773 template<
typename ValueType>
775 NullCodec::encode(
const ValueType& val, ValueType& data)
781 template<
typename StorageType,
typename ValueType>
783 TruncateCodec::decode(
const StorageType& data, ValueType& val)
785 val = static_cast<ValueType>(data);
789 template<
typename StorageType,
typename ValueType>
791 TruncateCodec::encode(
const ValueType& val, StorageType& data)
793 data = static_cast<StorageType>(val);
797 template <
bool OneByte,
typename Range>
798 template<
typename StorageType,
typename ValueType>
802 val = fixedPointToFloatingPoint<ValueType>(data);
806 val = Range::template decode<ValueType>(val);
810 template <
bool OneByte,
typename Range>
811 template<
typename StorageType,
typename ValueType>
817 const ValueType newVal = Range::template encode<ValueType>(val);
819 data = floatingPointToFixedPoint<StorageType>(newVal);
827 val = math::QuantizedUnitVec::unpack(data);
835 data = math::QuantizedUnitVec::pack(val);
843 template<
typename ValueType_,
typename Codec_>
847 template<
typename ValueType_,
typename Codec_>
852 , mStrideOrTotalSize(strideOrTotalSize)
855 if (constantStride) {
857 if (strideOrTotalSize == 0) {
859 "stride to be at least one.")
864 if (mStrideOrTotalSize < n) {
866 "a total size of at least the number of elements in the array.")
871 Codec::encode(uniformValue, mData.get()[0]);
875 template<
typename ValueType_,
typename Codec_>
879 , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
880 , mIsUniform(rhs.mIsUniform)
888 }
else if (mIsUniform) {
890 mData.get()[0] = rhs.mData.get()[0];
892 std::unique_ptr<char[]> buffer;
894 const char* charBuffer = reinterpret_cast<const char*>(rhs.mData.get());
906 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
909 std::memcpy(mData.get(), rhs.mData.get(), this->arrayMemUsage());
914 template<
typename ValueType_,
typename Codec_>
919 tbb::spin_mutex::scoped_lock lock(mMutex);
927 mStrideOrTotalSize = rhs.mStrideOrTotalSize;
928 mIsUniform = rhs.mIsUniform;
932 }
else if (mIsUniform) {
934 mData.get()[0] = rhs.mData.get()[0];
935 }
else if (this->isCompressed()) {
936 std::unique_ptr<char[]> buffer(
new char[mCompressedBytes]);
937 std::memcpy(buffer.get(), rhs.mData.get(), mCompressedBytes);
938 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
941 std::memcpy(mData.get(), rhs.mData.get(), arrayMemUsage());
947 template<
typename ValueType_,
typename Codec_>
951 if (sTypeName ==
nullptr) {
953 if (sTypeName.compare_and_swap(s,
nullptr) !=
nullptr)
delete s;
959 template<
typename ValueType_,
typename Codec_>
967 template<
typename ValueType_,
typename Codec_>
975 template<
typename ValueType_,
typename Codec_>
983 template<
typename ValueType_,
typename Codec_>
990 template<
typename ValueType_,
typename Codec_>
997 return static_cast<TypedAttributeArray&>(attributeArray);
1000 template<
typename ValueType_,
typename Codec_>
1007 return static_cast<const TypedAttributeArray&>(attributeArray);
1010 template<
typename ValueType_,
typename Codec_>
1018 template<
typename ValueType_,
typename Codec_>
1026 template<
typename ValueType_,
typename Codec_>
1030 if (this->isOutOfCore())
return 0;
1031 if (this->isCompressed())
return mCompressedBytes;
1033 return (mIsUniform ? 1 : this->dataSize()) *
sizeof(StorageType);
1037 template<
typename ValueType_,
typename Codec_>
1039 TypedAttributeArray<ValueType_, Codec_>::allocate()
1043 mData.reset(
new StorageType[1]);
1046 const size_t size(this->dataSize());
1048 mData.reset(
new StorageType[size]);
1053 template<
typename ValueType_,
typename Codec_>
1055 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1058 if (this->isOutOfCore()) {
1059 this->setOutOfCore(
false);
1060 this->mPageHandle.reset();
1062 if (mData) mData.reset();
1066 template<
typename ValueType_,
typename Codec_>
1070 return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1074 template<
typename ValueType_,
typename Codec_>
1078 assert(n < this->dataSize());
1079 assert(!this->isOutOfCore());
1080 assert(!this->isCompressed());
1083 Codec::decode(mData.get()[mIsUniform ? 0 : n], val);
1088 template<
typename ValueType_,
typename Codec_>
1093 if (this->isOutOfCore()) this->doLoad();
1094 if (this->isCompressed()) const_cast<TypedAttributeArray*>(
this)->decompress();
1096 return this->getUnsafe(n);
1100 template<
typename ValueType_,
typename Codec_>
1101 template<
typename T>
1105 val = static_cast<T>(this->getUnsafe(n));
1109 template<
typename ValueType_,
typename Codec_>
1110 template<
typename T>
1114 val = static_cast<T>(this->get(n));
1118 template<
typename ValueType_,
typename Codec_>
1126 template<
typename ValueType_,
typename Codec_>
1130 assert(n < this->dataSize());
1131 assert(!this->isOutOfCore());
1132 assert(!this->isCompressed());
1133 assert(!this->isUniform());
1138 Codec::encode(val, mData.get()[mIsUniform ? 0 : n]);
1142 template<
typename ValueType_,
typename Codec_>
1147 if (this->isOutOfCore()) this->doLoad();
1148 if (this->isCompressed()) this->decompress();
1149 if (this->isUniform()) this->expand();
1151 this->setUnsafe(n, val);
1155 template<
typename ValueType_,
typename Codec_>
1156 template<
typename T>
1160 this->setUnsafe(n, static_cast<ValueType>(val));
1164 template<
typename ValueType_,
typename Codec_>
1165 template<
typename T>
1169 this->set(n, static_cast<ValueType>(val));
1173 template<
typename ValueType_,
typename Codec_>
1181 template<
typename ValueType_,
typename Codec_>
1185 const TypedAttributeArray& sourceTypedArray = static_cast<const TypedAttributeArray&>(sourceArray);
1188 sourceTypedArray.
get(sourceIndex, sourceValue);
1190 this->set(n, sourceValue);
1194 template<
typename ValueType_,
typename Codec_>
1198 if (!mIsUniform)
return;
1203 tbb::spin_mutex::scoped_lock lock(mMutex);
1209 mCompressedBytes = 0;
1212 for (
Index i = 0; i < this->dataSize(); ++i) mData.get()[i] = val;
1217 template<
typename ValueType_,
typename Codec_>
1221 if (mIsUniform)
return true;
1224 const ValueType_ val = this->get(0);
1225 for (
Index i = 1; i < this->dataSize(); i++) {
1229 this->collapse(this->get(0));
1234 template<
typename ValueType_,
typename Codec_>
1238 this->collapse(zeroVal<ValueType>());
1242 template<
typename ValueType_,
typename Codec_>
1247 tbb::spin_mutex::scoped_lock lock(mMutex);
1252 Codec::encode(uniformValue, mData.get()[0]);
1256 template<
typename ValueType_,
typename Codec_>
1264 template<
typename ValueType_,
typename Codec_>
1268 if (this->isOutOfCore()) {
1269 tbb::spin_mutex::scoped_lock lock(mMutex);
1274 const Index size = mIsUniform ? 1 : this->dataSize();
1275 for (
Index i = 0; i < size; ++i) {
1276 Codec::encode(value, mData.get()[i]);
1281 template<
typename ValueType_,
typename Codec_>
1289 template<
typename ValueType_,
typename Codec_>
1295 if (!mIsUniform && !this->isCompressed()) {
1297 tbb::spin_mutex::scoped_lock lock(mMutex);
1299 this->doLoadUnsafe(
false);
1301 if (this->isCompressed())
return true;
1303 return this->compressUnsafe();
1310 template<
typename ValueType_,
typename Codec_>
1315 if (mIsUniform)
return false;
1319 const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1320 const size_t inBytes = writeCompress ? mCompressedBytes : this->arrayMemUsage();
1324 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1327 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1328 mCompressedBytes = outBytes;
1337 template<
typename ValueType_,
typename Codec_>
1341 tbb::spin_mutex::scoped_lock lock(mMutex);
1343 const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1345 if (writeCompress) {
1346 this->doLoadUnsafe(
false);
1350 if (this->isCompressed()) {
1351 this->doLoadUnsafe();
1352 const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1356 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1357 mCompressedBytes = 0;
1366 template<
typename ValueType_,
typename Codec_>
1370 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1373 return (mFlags & OUTOFCORE);
1378 template<
typename ValueType_,
typename Codec_>
1382 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1385 if (b) mFlags = static_cast<uint8_t>(mFlags | OUTOFCORE);
1386 else mFlags = static_cast<uint8_t>(mFlags & ~OUTOFCORE);
1391 template<
typename ValueType_,
typename Codec_>
1393 TypedAttributeArray<ValueType_, Codec_>::doLoad()
const
1395 if (!(this->isOutOfCore()))
return;
1397 TypedAttributeArray<ValueType_, Codec_>*
self =
1398 const_cast<TypedAttributeArray<ValueType_, Codec_>*
>(
this);
1402 tbb::spin_mutex::scoped_lock lock(self->mMutex);
1403 this->doLoadUnsafe();
1407 template<
typename ValueType_,
typename Codec_>
1415 template<
typename ValueType_,
typename Codec_>
1419 this->readMetadata(is);
1420 this->readBuffers(is);
1424 template<
typename ValueType_,
typename Codec_>
1431 is.read(reinterpret_cast<char*>(&bytes),
sizeof(
Index64));
1432 bytes = bytes -
sizeof(
Int16) -
sizeof(
Index);
1434 uint8_t flags = uint8_t(0);
1435 is.read(reinterpret_cast<char*>(&flags),
sizeof(uint8_t));
1438 uint8_t serializationFlags = uint8_t(0);
1439 is.read(reinterpret_cast<char*>(&serializationFlags),
sizeof(uint8_t));
1440 mSerializationFlags = serializationFlags;
1443 is.read(reinterpret_cast<char*>(&size),
sizeof(
Index));
1447 if (mFlags >= 0x20) {
1452 if (mSerializationFlags >= 0x10) {
1458 mIsUniform = mSerializationFlags & WRITEUNIFORM;
1459 mCompressedBytes = bytes;
1463 if (mSerializationFlags & WRITESTRIDED) {
1465 is.read(reinterpret_cast<char*>(&stride),
sizeof(
Index));
1466 mStrideOrTotalSize = stride;
1469 mStrideOrTotalSize = 1;
1474 template<
typename ValueType_,
typename Codec_>
1478 if ((mSerializationFlags & WRITEPAGED)) {
1483 tbb::spin_mutex::scoped_lock lock(mMutex);
1487 uint8_t bloscCompressed(0);
1488 if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed),
sizeof(uint8_t));
1490 std::unique_ptr<char[]> buffer(
new char[mCompressedBytes]);
1491 is.read(buffer.get(), mCompressedBytes);
1495 mCompressedBytes =
Index64(0);
1497 else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1499 mCompressedBytes =
Index64(0);
1504 if (bloscCompressed == uint8_t(1)) {
1508 const size_t inBytes = this->dataSize() *
sizeof(
StorageType);
1510 if (newBuffer) buffer.reset(newBuffer.release());
1515 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1519 if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1520 else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1524 template<
typename ValueType_,
typename Codec_>
1528 if (!(mSerializationFlags & WRITEPAGED)) {
1536 const bool delayLoad = (mappedFile.get() !=
nullptr);
1544 assert(mPageHandle);
1546 tbb::spin_mutex::scoped_lock lock(mMutex);
1550 this->setOutOfCore(delayLoad);
1551 is.
read(mPageHandle, mCompressedBytes, delayLoad);
1554 std::unique_ptr<char[]> buffer = mPageHandle->read();
1555 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1562 mCompressedBytes =
Index64(0);
1564 else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1565 mCompressedBytes =
Index64(0);
1570 if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1571 else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1575 template<
typename ValueType_,
typename Codec_>
1579 this->write(os,
false);
1583 template<
typename ValueType_,
typename Codec_>
1587 this->writeMetadata(os, outputTransient,
false);
1588 this->writeBuffers(os, outputTransient);
1592 template<
typename ValueType_,
typename Codec_>
1596 if (!outputTransient && this->isTransient())
return;
1598 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1599 uint8_t flags(mFlags);
1601 uint8_t flags(mFlags & uint8_t(~OUTOFCORE));
1603 uint8_t serializationFlags(0);
1605 Index stride(mStrideOrTotalSize);
1606 bool strideOfOne(this->stride() == 1);
1611 if (bloscCompression || this->isCompressed()) this->doLoad();
1613 size_t compressedBytes = 0;
1617 serializationFlags |= WRITESTRIDED;
1622 serializationFlags |= WRITEUNIFORM;
1623 if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1625 else if (bloscCompression && paged)
1627 serializationFlags |= WRITEPAGED;
1628 if (this->isCompressed()) {
1629 serializationFlags |= WRITEMEMCOMPRESS;
1630 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1634 else if (this->isCompressed())
1636 serializationFlags |= WRITEMEMCOMPRESS;
1637 compressedBytes = mCompressedBytes;
1639 else if (bloscCompression)
1641 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1642 const size_t inBytes = this->arrayMemUsage();
1648 bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1652 os.write(reinterpret_cast<const char*>(&bytes),
sizeof(
Index64));
1653 os.write(reinterpret_cast<const char*>(&flags),
sizeof(uint8_t));
1654 os.write(reinterpret_cast<const char*>(&serializationFlags),
sizeof(uint8_t));
1655 os.write(reinterpret_cast<const char*>(&size),
sizeof(
Index));
1658 if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride),
sizeof(
Index));
1662 template<
typename ValueType_,
typename Codec_>
1666 if (!outputTransient && this->isTransient())
return;
1670 if (this->isUniform()) {
1671 os.write(reinterpret_cast<const char*>(mData.get()),
sizeof(
StorageType));
1673 else if (this->isCompressed())
1675 uint8_t bloscCompressed(0);
1676 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1677 os.write(reinterpret_cast<const char*>(mData.get()), mCompressedBytes);
1681 std::unique_ptr<char[]> compressedBuffer;
1682 size_t compressedBytes = 0;
1683 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1684 const size_t inBytes = this->arrayMemUsage();
1686 if (compressedBuffer) {
1687 uint8_t bloscCompressed(1);
1688 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1689 os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1692 uint8_t bloscCompressed(0);
1693 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1694 os.write(reinterpret_cast<const char*>(mData.get()), inBytes);
1699 uint8_t bloscCompressed(0);
1700 os.write(reinterpret_cast<const char*>(&bloscCompressed),
sizeof(uint8_t));
1701 os.write(reinterpret_cast<const char*>(mData.get()), this->arrayMemUsage());
1706 template<
typename ValueType_,
typename Codec_>
1710 if (!outputTransient && this->isTransient())
return;
1714 if (!bloscCompression) {
1724 std::unique_ptr<char[]> uncompressedBuffer;
1725 if (this->isCompressed()) {
1728 const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1731 buffer = reinterpret_cast<const char*>(uncompressedBuffer.get());
1734 buffer = reinterpret_cast<const char*>(mData.get());
1735 bytes = this->arrayMemUsage();
1738 os.
write(buffer, bytes);
1742 template<
typename ValueType_,
typename Codec_>
1746 if (!(this->isOutOfCore()))
return;
1752 assert(self->mPageHandle);
1754 std::unique_ptr<char[]> buffer =
self->mPageHandle->read();
1756 self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1758 self->mPageHandle.reset();
1762 if (self->mSerializationFlags & WRITEMEMCOMPRESS) {
1763 if (compression)
self->compressUnsafe();
1764 else self->mCompressedBytes = 0;
1769 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1770 self->mOutOfCore =
false;
1772 self->mFlags &= uint8_t(~OUTOFCORE);
1774 self->mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1778 template<
typename ValueType_,
typename Codec_>
1793 template<
typename ValueType_,
typename Codec_>
1798 if(!otherT)
return false;
1799 if(this->mSize != otherT->mSize ||
1800 this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
1801 this->mIsUniform != otherT->mIsUniform ||
1802 *this->sTypeName != *otherT->sTypeName)
return false;
1807 const StorageType *target = this->mData.get(), *source = otherT->mData.get();
1808 if (!target && !source)
return true;
1809 if (!target || !source)
return false;
1810 Index n = this->mIsUniform ? 1 : mSize;
1819 template <
typename CodecType,
typename ValueType>
1840 template <
typename ValueType>
1848 return (*functor)(array, n);
1853 (*functor)(array, n, value);
1862 template <
typename ValueType,
typename CodecType>
1870 template <
typename ValueType,
typename CodecType>
1873 , mStrideOrTotalSize(array.hasConstantStride() ? array.stride() : 1)
1874 , mSize(array.hasConstantStride() ? array.size() : array.dataSize())
1875 , mCollapseOnDestruction(preserveCompression && array.isStreaming())
1877 if (!this->compatibleType<std::is_same<CodecType, UnknownCodec>::value>()) {
1890 if (preserveCompression && !array.
isStreaming()) {
1892 mLocalArray->decompress();
1893 mArray = mLocalArray.get();
1896 const_cast<AttributeArray*>(mArray)->decompress();
1907 mGetter = typedAccessor->
mGetter;
1908 mSetter = typedAccessor->
mSetter;
1910 mFiller = typedAccessor->
mFiller;
1913 template <
typename ValueType,
typename CodecType>
1917 if (mCollapseOnDestruction) const_cast<AttributeArray*>(this->mArray)->collapse();
1920 template <
typename ValueType,
typename CodecType>
1921 template <
bool IsUnknownCodec>
1922 typename std::enable_if<IsUnknownCodec, bool>::type
1927 return mArray->hasValueType<ValueType>();
1930 template <
typename ValueType,
typename CodecType>
1931 template <
bool IsUnknownCodec>
1932 typename std::enable_if<!IsUnknownCodec, bool>::type
1933 AttributeHandle<ValueType, CodecType>::compatibleType()
const
1937 return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
1940 template <
typename ValueType,
typename CodecType>
1947 template <
typename ValueType,
typename CodecType>
1950 Index index = n * mStrideOrTotalSize + m;
1951 assert(index < (mSize * mStrideOrTotalSize));
1955 template <
typename ValueType,
typename CodecType>
1958 return this->get<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m));
1961 template <
typename ValueType,
typename CodecType>
1962 template <
bool IsUnknownCodec>
1963 typename std::enable_if<IsUnknownCodec, ValueType>::type
1968 return (*mGetter)(mArray, index);
1971 template <
typename ValueType,
typename CodecType>
1972 template <
bool IsUnknownCodec>
1973 typename std::enable_if<!IsUnknownCodec, ValueType>::type
1974 AttributeHandle<ValueType, CodecType>::get(
Index index)
const
1978 return TypedAttributeArray<ValueType, CodecType>::getUnsafe(mArray, index);
1981 template <
typename ValueType,
typename CodecType>
1987 template <
typename ValueType,
typename CodecType>
1997 template <
typename ValueType,
typename CodecType>
2005 template <
typename ValueType,
typename CodecType>
2009 if (expand) array.
expand();
2012 template <
typename ValueType,
typename CodecType>
2015 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, 0), value);
2018 template <
typename ValueType,
typename CodecType>
2021 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m), value);
2024 template <
typename ValueType,
typename CodecType>
2027 const_cast<AttributeArray*>(this->mArray)->
expand(fill);
2030 template <
typename ValueType,
typename CodecType>
2033 const_cast<AttributeArray*>(this->mArray)->
collapse();
2036 template <
typename ValueType,
typename CodecType>
2039 return const_cast<AttributeArray*>(this->mArray)->
compact();
2042 template <
typename ValueType,
typename CodecType>
2045 this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2048 template <
typename ValueType,
typename CodecType>
2051 this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2054 template <
typename ValueType,
typename CodecType>
2055 template <
bool IsUnknownCodec>
2056 typename std::enable_if<IsUnknownCodec, void>::type
2061 (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index, value);
2064 template <
typename ValueType,
typename CodecType>
2065 template <
bool IsUnknownCodec>
2066 typename std::enable_if<!IsUnknownCodec, void>::type
2067 AttributeWriteHandle<ValueType, CodecType>::set(
Index index,
const ValueType& value)
const
2071 TypedAttributeArray<ValueType, CodecType>::setUnsafe(const_cast<AttributeArray*>(this->mArray), index, value);
2074 template <
typename ValueType,
typename CodecType>
2077 assert(this->mArray);
2078 return *const_cast<AttributeArray*>(this->mArray);
2086 #endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED