OpenVDB: AttributeArray.h Source File

OpenVDB 7.1.0

AttributeArray.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
9
10 #ifndef OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
12
13 #include <openvdb/Types.h>
14 #include <openvdb/math/QuantizedUnitVec.h>
15 #include <openvdb/util/Name.h>
16 #include <openvdb/util/logging.h>
17 #include <openvdb/io/io.h> // MappedFile
18 #include <openvdb/io/Compression.h> // COMPRESS_BLOSC
19
20 #include "IndexIterator.h"
21 #include "StreamCompression.h"
22
23 #include <tbb/spin_mutex.h>
24 #include <tbb/atomic.h>
25
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 #include <type_traits>
30
31
32 class TestAttributeArray;
33
34 namespace openvdb {
35 OPENVDB_USE_VERSION_NAMESPACE
36 namespace OPENVDB_VERSION_NAME {
37
38
39 using NamePair = std::pair<Name, Name>;
40
41 namespace points {
42
43
45
46 // Utility methods
47
48 template <typename IntegerT, typename FloatT>
49 inline IntegerT
50 floatingPointToFixedPoint(const FloatT s)
51 {
52 static_assert(std::is_unsigned<IntegerT>::value, "IntegerT must be unsigned");
53 if (FloatT(0.0) > s) return std::numeric_limits<IntegerT>::min();
54 else if (FloatT(1.0) <= s) return std::numeric_limits<IntegerT>::max();
55 return IntegerT(s * FloatT(std::numeric_limits<IntegerT>::max()));
56 }
57
58
59 template <typename FloatT, typename IntegerT>
60 inline FloatT
61 fixedPointToFloatingPoint(const IntegerT s)
62 {
63 static_assert(std::is_unsigned<IntegerT>::value, "IntegerT must be unsigned");
64 return FloatT(s) / FloatT((std::numeric_limits<IntegerT>::max()));
65 }
66
67 template <typename IntegerVectorT, typename FloatT>
68 inline IntegerVectorT
69 floatingPointToFixedPoint(const math::Vec3<FloatT>& v)
70 {
71 return IntegerVectorT(
72 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.x()),
73 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.y()),
74 floatingPointToFixedPoint<typename IntegerVectorT::ValueType>(v.z()));
75 }
76
77 template <typename FloatVectorT, typename IntegerT>
78 inline FloatVectorT
79 fixedPointToFloatingPoint(const math::Vec3<IntegerT>& v)
80 {
81 return FloatVectorT(
82 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.x()),
83 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.y()),
84 fixedPointToFloatingPoint<typename FloatVectorT::ValueType>(v.z()));
85 }
86
87
89
90
92 class OPENVDB_API AttributeArray
93 {
94 protected:
95 struct AccessorBase;
96 template <typename T> struct Accessor;
97
98 using AccessorBasePtr = std::shared_ptr<AccessorBase>;
99
100 public:
101 enum Flag {
102 TRANSIENT = 0x1,
103 HIDDEN = 0x2,
104 CONSTANTSTRIDE = 0x8,
105 STREAMING = 0x10,
106 PARTIALREAD = 0x20
107 };
108
109 enum SerializationFlag {
110 WRITESTRIDED = 0x1,
111 WRITEUNIFORM = 0x2,
112 WRITEMEMCOMPRESS = 0x4,
113 WRITEPAGED = 0x8
115 };
116
117 // Scoped Lock wrapper class that locks the AttributeArray registry mutex
118 class OPENVDB_API ScopedRegistryLock
119 {
120 tbb::spin_mutex::scoped_lock lock;
121 public:
122 ScopedRegistryLock();
123 }; // class ScopedRegistryLock
124
125 using Ptr = std::shared_ptr<AttributeArray>;
126 using ConstPtr = std::shared_ptr<const AttributeArray>;
127
128 using FactoryMethod = Ptr (*)(Index, Index, bool, const Metadata*);
129
130 template <typename ValueType, typename CodecType> friend class AttributeHandle;
131
132 AttributeArray(): mPageHandle() { mOutOfCore = 0; }
133 virtual ~AttributeArray()
134 {
135 // if this AttributeArray has been partially read, zero the compressed bytes,
136 // so the page handle won't attempt to clean up invalid memory
137 if (mFlags & PARTIALREAD) mCompressedBytes = 0;
138 }
139 #if OPENVDB_ABI_VERSION_NUMBER >= 6
140 AttributeArray(const AttributeArray& rhs);
141 AttributeArray& operator=(const AttributeArray& rhs);
142 #else
143 AttributeArray(const AttributeArray&) = default;
144 AttributeArray& operator=(const AttributeArray&) = default;
145 #endif
146 AttributeArray(AttributeArray&&) = delete;
147 AttributeArray& operator=(AttributeArray&&) = delete;
148
150 virtual AttributeArray::Ptr copy() const = 0;
151
154 #ifndef _MSC_VER
155 OPENVDB_DEPRECATED
156 #endif
157 virtual AttributeArray::Ptr copyUncompressed() const = 0;
158
161 virtual Index size() const = 0;
162
165 virtual Index stride() const = 0;
166
169 virtual Index dataSize() const = 0;
170
171 #if OPENVDB_ABI_VERSION_NUMBER >= 6
172 virtual Name valueType() const = 0;
174
176 virtual Name codecType() const = 0;
177
180 virtual Index valueTypeSize() const = 0;
181
184 virtual Index storageTypeSize() const = 0;
185
187 virtual bool valueTypeIsFloatingPoint() const = 0;
188
190 virtual bool valueTypeIsClass() const = 0;
191
193 virtual bool valueTypeIsVector() const = 0;
194
196 virtual bool valueTypeIsQuaternion() const = 0;
197
199 virtual bool valueTypeIsMatrix() const = 0;
200 #endif
201
203 virtual size_t memUsage() const = 0;
204
208 static Ptr create(const NamePair& type, Index length, Index stride = 1,
209 bool constantStride = true,
210 const Metadata* metadata = nullptr,
211 const ScopedRegistryLock* lock = nullptr);
212
213 static OPENVDB_DEPRECATED Ptr create(const NamePair& type, Index length,
214 Index stride, bool constantStride, const ScopedRegistryLock* lock);
215
217 static bool isRegistered(const NamePair& type, const ScopedRegistryLock* lock = nullptr);
219 static void clearRegistry(const ScopedRegistryLock* lock = nullptr);
220
222 virtual const NamePair& type() const = 0;
224 template<typename AttributeArrayType>
225 bool isType() const { return this->type() == AttributeArrayType::attributeType(); }
226
228 template<typename ValueType>
229 bool hasValueType() const { return this->type().first == typeNameAsString<ValueType>(); }
230
233 #if OPENVDB_ABI_VERSION_NUMBER >= 6
234 // Windows does not allow base classes to be easily deprecated.
235 #ifndef _MSC_VER
236 OPENVDB_DEPRECATED
237 #endif
238 #endif
239 virtual void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) = 0;
240
241 #if OPENVDB_ABI_VERSION_NUMBER >= 6
242 template<typename IterT>
266 void copyValuesUnsafe(const AttributeArray& sourceArray, const IterT& iter);
270 template<typename IterT>
271 void copyValues(const AttributeArray& sourceArray, const IterT& iter, bool compact = true);
272 #endif
273
275 virtual bool isUniform() const = 0;
278 virtual void expand(bool fill = true) = 0;
280 virtual void collapse() = 0;
282 virtual bool compact() = 0;
283
285 // Windows does not allow base classes to be deprecated
286 #ifndef _MSC_VER
287 OPENVDB_DEPRECATED
288 #endif
289 virtual bool compress() = 0;
291 // Windows does not allow base classes to be deprecated
292 #ifndef _MSC_VER
293 OPENVDB_DEPRECATED
294 #endif
295 virtual bool decompress() = 0;
296
301 void setHidden(bool state);
303 bool isHidden() const { return bool(mFlags & HIDDEN); }
304
308 void setTransient(bool state);
310 bool isTransient() const { return bool(mFlags & TRANSIENT); }
311
316 void setStreaming(bool state);
318 bool isStreaming() const { return bool(mFlags & STREAMING); }
319
321 bool hasConstantStride() const { return bool(mFlags & CONSTANTSTRIDE); }
322
324 uint8_t flags() const { return mFlags; }
325
327 virtual void read(std::istream&) = 0;
330 virtual void write(std::ostream&, bool outputTransient) const = 0;
332 virtual void write(std::ostream&) const = 0;
333
335 virtual void readMetadata(std::istream&) = 0;
339 virtual void writeMetadata(std::ostream&, bool outputTransient, bool paged) const = 0;
340
342 virtual void readBuffers(std::istream&) = 0;
345 virtual void writeBuffers(std::ostream&, bool outputTransient) const = 0;
346
348 virtual void readPagedBuffers(compression::PagedInputStream&) = 0;
351 virtual void writePagedBuffers(compression::PagedOutputStream&, bool outputTransient) const = 0;
352
354 virtual void loadData() const = 0;
355
356 #if OPENVDB_ABI_VERSION_NUMBER >= 6
357 virtual bool isDataLoaded() const = 0;
359 #endif
360
364 bool operator==(const AttributeArray& other) const;
365 bool operator!=(const AttributeArray& other) const { return !this->operator==(other); }
366
367 private:
368 friend class ::TestAttributeArray;
369
372 virtual bool isEqual(const AttributeArray& other) const = 0;
373
374 #if OPENVDB_ABI_VERSION_NUMBER >= 6
375 virtual char* dataAsByteArray() = 0;
377 virtual const char* dataAsByteArray() const = 0;
378
380 template <typename IterT>
381 void doCopyValues(const AttributeArray& sourceArray, const IterT& iter,
382 bool rangeChecking = true);
383 #endif
384
385 protected:
386 #if OPENVDB_ABI_VERSION_NUMBER >= 7
387 AttributeArray(const AttributeArray& rhs, const tbb::spin_mutex::scoped_lock&);
388 #endif
389
391 void setConstantStride(bool state);
392
394 virtual AccessorBasePtr getAccessor() const = 0;
395
397 static void registerType(const NamePair& type, FactoryMethod,
398 const ScopedRegistryLock* lock = nullptr);
400 static void unregisterType(const NamePair& type,
401 const ScopedRegistryLock* lock = nullptr);
402
403 #if OPENVDB_ABI_VERSION_NUMBER < 6
404
405 size_t mCompressedBytes = 0;
406 uint8_t mFlags = 0;
407 uint8_t mUsePagedRead = 0;
408 tbb::atomic<Index32> mOutOfCore; // interpreted as bool
409 compression::PageHandle::Ptr mPageHandle;
410
411 #else // #if OPENVDB_ABI_VERSION_NUMBER < 6
412
413 bool mIsUniform = true;
414 mutable tbb::spin_mutex mMutex;
415 uint8_t mFlags = 0;
416 uint8_t mUsePagedRead = 0;
417 tbb::atomic<Index32> mOutOfCore; // interpreted as bool
419 union {
420 compression::PageHandle::Ptr mPageHandle;
421 size_t mCompressedBytes; // as of ABI=6, this data is packed together to save memory
422 };
423
424 #endif
425 }; // class AttributeArray
426
427
429
430
432 struct AttributeArray::AccessorBase { virtual ~AccessorBase() = default; };
433
436 template <typename T>
437 struct AttributeArray::Accessor : public AttributeArray::AccessorBase
438 {
439 using GetterPtr = T (*)(const AttributeArray* array, const Index n);
440 using SetterPtr = void (*)(AttributeArray* array, const Index n, const T& value);
441 using ValuePtr = void (*)(AttributeArray* array, const T& value);
442
443 Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler) :
444 mGetter(getter), mSetter(setter), mCollapser(collapser), mFiller(filler) { }
445
446 GetterPtr mGetter;
447 SetterPtr mSetter;
448 ValuePtr mCollapser;
449 ValuePtr mFiller;
450 }; // struct AttributeArray::Accessor
451
452
454
455
456 namespace attribute_traits
457 {
458 template <typename T> struct TruncateTrait { };
459 template <> struct TruncateTrait<float> { using Type = half; };
460 template <> struct TruncateTrait<int> { using Type = short; };
461
462 template <typename T> struct TruncateTrait<math::Vec3<T>> {
463 using Type = math::Vec3<typename TruncateTrait<T>::Type>;
464 };
465
466 template <bool OneByte, typename T> struct UIntTypeTrait { };
467 template<typename T> struct UIntTypeTrait</*OneByte=*/true, T> { using Type = uint8_t; };
468 template<typename T> struct UIntTypeTrait</*OneByte=*/false, T> { using Type = uint16_t; };
469 template<typename T> struct UIntTypeTrait</*OneByte=*/true, math::Vec3<T>> {
470 using Type = math::Vec3<uint8_t>;
471 };
472 template<typename T> struct UIntTypeTrait</*OneByte=*/false, math::Vec3<T>> {
473 using Type = math::Vec3<uint16_t>;
474 };
475 }
476
477
479
480
481 // Attribute codec schemes
482
483 struct UnknownCodec { };
484
485
486 struct NullCodec
487 {
488 template <typename T>
489 struct Storage { using Type = T; };
490
491 template<typename ValueType> static void decode(const ValueType&, ValueType&);
492 template<typename ValueType> static void encode(const ValueType&, ValueType&);
493 static const char* name() { return "null"; }
494 };
495
496
497 struct TruncateCodec
498 {
499 template <typename T>
500 struct Storage { using Type = typename attribute_traits::TruncateTrait<T>::Type; };
501
502 template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
503 template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
504 static const char* name() { return "trnc"; }
505 };
506
507
508 // Fixed-point codec range for voxel-space positions [-0.5,0.5]
509 struct PositionRange
510 {
511 static const char* name() { return "fxpt"; }
512 template <typename ValueType> static ValueType encode(const ValueType& value) { return value + ValueType(0.5); }
513 template <typename ValueType> static ValueType decode(const ValueType& value) { return value - ValueType(0.5); }
514 };
515
516
517 // Fixed-point codec range for unsigned values in the unit range [0.0,1.0]
518 struct UnitRange
519 {
520 static const char* name() { return "ufxpt"; }
521 template <typename ValueType> static ValueType encode(const ValueType& value) { return value; }
522 template <typename ValueType> static ValueType decode(const ValueType& value) { return value; }
523 };
524
525
526 template <bool OneByte, typename Range=PositionRange>
527 struct FixedPointCodec
528 {
529 template <typename T>
530 struct Storage { using Type = typename attribute_traits::UIntTypeTrait<OneByte, T>::Type; };
531
532 template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
533 template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
534
535 static const char* name() {
536 static const std::string Name = std::string(Range::name()) + (OneByte ? "8" : "16");
537 return Name.c_str();
538 }
539 };
540
541
542 struct UnitVecCodec
543 {
544 using StorageType = uint16_t;
545
546 template <typename T>
547 struct Storage { using Type = StorageType; };
548
549 template<typename T> static void decode(const StorageType&, math::Vec3<T>&);
550 template<typename T> static void encode(const math::Vec3<T>&, StorageType&);
551 static const char* name() { return "uvec"; }
552 };
553
554
556
557
559
560 template<typename ValueType_, typename Codec_ = NullCodec>
561 #if OPENVDB_ABI_VERSION_NUMBER >= 6 // for ABI=6, class is final to allow for de-virtualization
562 class TypedAttributeArray final: public AttributeArray
563 #else
564 class TypedAttributeArray: public AttributeArray
565 #endif
566 {
567 public:
568 using Ptr = std::shared_ptr<TypedAttributeArray>;
569 using ConstPtr = std::shared_ptr<const TypedAttributeArray>;
570
571 using ValueType = ValueType_;
572 using Codec = Codec_;
573 using StorageType = typename Codec::template Storage<ValueType>::Type;
574
576
578 explicit TypedAttributeArray(Index n = 1, Index strideOrTotalSize = 1, bool constantStride = true,
579 const ValueType& uniformValue = zeroVal<ValueType>());
580 #if OPENVDB_ABI_VERSION_NUMBER >= 7
581 TypedAttributeArray(const TypedAttributeArray&);
590 OPENVDB_DEPRECATED TypedAttributeArray(const TypedAttributeArray&, bool /*unused*/);
591 #else
592 TypedAttributeArray(const TypedAttributeArray&, bool uncompress = false);
596 #endif
597 TypedAttributeArray& operator=(const TypedAttributeArray&);
601 TypedAttributeArray(TypedAttributeArray&&) = delete;
603 TypedAttributeArray& operator=(TypedAttributeArray&&) = delete;
604
605 ~TypedAttributeArray() override { this->deallocate(); }
606
609 AttributeArray::Ptr copy() const override;
610
614 OPENVDB_DEPRECATED AttributeArray::Ptr copyUncompressed() const override;
615
617 static Ptr create(Index n, Index strideOrTotalSize = 1, bool constantStride = true,
618 const Metadata* metadata = nullptr);
619
621 static TypedAttributeArray& cast(AttributeArray& attributeArray);
622
624 static const TypedAttributeArray& cast(const AttributeArray& attributeArray);
625
627 static const NamePair& attributeType();
629 const NamePair& type() const override { return attributeType(); }
630
632 static bool isRegistered();
634 static void registerType();
636 static void unregisterType();
637
639 Index size() const override { return mSize; }
640
643 Index stride() const override { return hasConstantStride() ? mStrideOrTotalSize : 0; }
644
646 Index dataSize() const override {
647 return hasConstantStride() ? mSize * mStrideOrTotalSize : mStrideOrTotalSize;
648 }
649
650 #if OPENVDB_ABI_VERSION_NUMBER >= 6
651 Name valueType() const override { return typeNameAsString<ValueType>(); }
653
655 Name codecType() const override { return Codec::name(); }
656
658 Index valueTypeSize() const override { return sizeof(ValueType); }
659
662 Index storageTypeSize() const override { return sizeof(StorageType); }
663
665 bool valueTypeIsFloatingPoint() const override;
666
668 bool valueTypeIsClass() const override;
669
671 bool valueTypeIsVector() const override;
672
674 bool valueTypeIsQuaternion() const override;
675
677 bool valueTypeIsMatrix() const override;
678 #endif
679
681 size_t memUsage() const override;
682
684 ValueType getUnsafe(Index n) const;
686 ValueType get(Index n) const;
688 template<typename T> void getUnsafe(Index n, T& value) const;
690 template<typename T> void get(Index n, T& value) const;
691
694 static ValueType getUnsafe(const AttributeArray* array, const Index n);
695
697 void setUnsafe(Index n, const ValueType& value);
699 void set(Index n, const ValueType& value);
701 template<typename T> void setUnsafe(Index n, const T& value);
703 template<typename T> void set(Index n, const T& value);
704
707 static void setUnsafe(AttributeArray* array, const Index n, const ValueType& value);
708
710 #if OPENVDB_ABI_VERSION_NUMBER >= 6
711 OPENVDB_DEPRECATED
712 #endif
713 void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) override;
714
716 bool isUniform() const override { return mIsUniform; }
720 void expand(bool fill = true) override;
722 void collapse() override;
724 bool compact() override;
725
727 void collapse(const ValueType& uniformValue);
730 void fill(const ValueType& value);
731
733 static void collapse(AttributeArray* array, const ValueType& value);
735 static void fill(AttributeArray* array, const ValueType& value);
736
738 OPENVDB_DEPRECATED bool compress() override;
740 OPENVDB_DEPRECATED bool decompress() override;
741
743 void read(std::istream&) override;
747 void write(std::ostream& os, bool outputTransient) const override;
749 void write(std::ostream&) const override;
750
752 void readMetadata(std::istream&) override;
757 void writeMetadata(std::ostream& os, bool outputTransient, bool paged) const override;
758
760 void readBuffers(std::istream&) override;
764 void writeBuffers(std::ostream& os, bool outputTransient) const override;
765
767 void readPagedBuffers(compression::PagedInputStream&) override;
771 void writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const override;
772
774 inline bool isOutOfCore() const;
775
777 void loadData() const override;
778
779 #if OPENVDB_ABI_VERSION_NUMBER >= 6
780 bool isDataLoaded() const override;
782 #endif
783
784 protected:
785 AccessorBasePtr getAccessor() const override;
786
788 inline StorageType* data() { assert(validData()); return mData.get(); }
789 inline const StorageType* data() const { assert(validData()); return mData.get(); }
790
792 inline bool validData() const { return !(isOutOfCore() || (flags() & PARTIALREAD)); }
793
794 private:
795 friend class ::TestAttributeArray;
796
797 #if OPENVDB_ABI_VERSION_NUMBER >= 7
798 TypedAttributeArray(const TypedAttributeArray&, const tbb::spin_mutex::scoped_lock&);
799 #endif
800
802 inline void doLoad() const;
805 inline void doLoadUnsafe(const bool compression = true) const;
807 inline bool compressUnsafe();
808
810 inline void setOutOfCore(const bool);
811
813 bool isEqual(const AttributeArray& other) const override;
814
815 #if OPENVDB_ABI_VERSION_NUMBER >= 6
816 char* dataAsByteArray() override;
818 const char* dataAsByteArray() const override;
819 #endif
820
821 size_t arrayMemUsage() const;
822 void allocate();
823 void deallocate();
824
826 static AttributeArray::Ptr factory(Index n, Index strideOrTotalSize, bool constantStride,
827 const Metadata* metadata) {
828 return TypedAttributeArray::create(n, strideOrTotalSize, constantStride, metadata);
829 }
830
831 static std::unique_ptr<const NamePair> sTypeName;
832 std::unique_ptr<StorageType[]> mData;
833 Index mSize;
834 Index mStrideOrTotalSize;
835 #if OPENVDB_ABI_VERSION_NUMBER < 6 // as of ABI=6, this data lives in the base class to reduce memory
836 bool mIsUniform = true;
837 mutable tbb::spin_mutex mMutex;
838 #endif
839 }; // class TypedAttributeArray
840
841
843
844
847 template <typename ValueType, typename CodecType = UnknownCodec>
848 class AttributeHandle
849 {
850 public:
851 using Handle = AttributeHandle<ValueType, CodecType>;
852 using Ptr = std::shared_ptr<Handle>;
853 using UniquePtr = std::unique_ptr<Handle>;
854
855 protected:
856 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
857 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
858 using ValuePtr = void (*)(AttributeArray* array, const ValueType& value);
859
860 public:
861 static Ptr create(const AttributeArray& array, const bool collapseOnDestruction = true);
862
863 AttributeHandle(const AttributeArray& array, const bool collapseOnDestruction = true);
864
865 AttributeHandle(const AttributeHandle&) = default;
866 AttributeHandle& operator=(const AttributeHandle&) = default;
867
868 virtual ~AttributeHandle();
869
870 Index stride() const { return mStrideOrTotalSize; }
871 Index size() const { return mSize; }
872
873 bool isUniform() const;
874 bool hasConstantStride() const;
875
876 ValueType get(Index n, Index m = 0) const;
877
878 const AttributeArray& array() const;
879
880 protected:
881 Index index(Index n, Index m) const;
882
883 const AttributeArray* mArray;
884
885 GetterPtr mGetter;
886 SetterPtr mSetter;
887 ValuePtr mCollapser;
888 ValuePtr mFiller;
889
890 private:
891 friend class ::TestAttributeArray;
892
893 template <bool IsUnknownCodec>
894 typename std::enable_if<IsUnknownCodec, bool>::type compatibleType() const;
895
896 template <bool IsUnknownCodec>
897 typename std::enable_if<!IsUnknownCodec, bool>::type compatibleType() const;
898
899 template <bool IsUnknownCodec>
900 typename std::enable_if<IsUnknownCodec, ValueType>::type get(Index index) const;
901
902 template <bool IsUnknownCodec>
903 typename std::enable_if<!IsUnknownCodec, ValueType>::type get(Index index) const;
904
905 // local copy of AttributeArray (to preserve compression)
906 AttributeArray::Ptr mLocalArray;
907
908 Index mStrideOrTotalSize;
909 Index mSize;
910 bool mCollapseOnDestruction;
911 }; // class AttributeHandle
912
913
915
916
918 template <typename ValueType, typename CodecType = UnknownCodec>
919 class AttributeWriteHandle : public AttributeHandle<ValueType, CodecType>
920 {
921 public:
922 using Handle = AttributeWriteHandle<ValueType, CodecType>;
923 using Ptr = std::shared_ptr<Handle>;
924 using ScopedPtr = std::unique_ptr<Handle>;
925
926 static Ptr create(AttributeArray& array, const bool expand = true);
927
928 AttributeWriteHandle(AttributeArray& array, const bool expand = true);
929
930 virtual ~AttributeWriteHandle() = default;
931
934 void expand(bool fill = true);
935
937 void collapse();
938 void collapse(const ValueType& uniformValue);
939
941 bool compact();
942
945 void fill(const ValueType& value);
946
947 void set(Index n, const ValueType& value);
948 void set(Index n, Index m, const ValueType& value);
949
950 AttributeArray& array();
951
952 private:
953 friend class ::TestAttributeArray;
954
955 template <bool IsUnknownCodec>
956 typename std::enable_if<IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
957
958 template <bool IsUnknownCodec>
959 typename std::enable_if<!IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
960 }; // class AttributeWriteHandle
961
962
964
965
966 // Attribute codec implementation
967
968
969 template<typename ValueType>
970 inline void
971 NullCodec::decode(const ValueType& data, ValueType& val)
972 {
973 val = data;
974 }
975
976
977 template<typename ValueType>
978 inline void
979 NullCodec::encode(const ValueType& val, ValueType& data)
980 {
981 data = val;
982 }
983
984
985 template<typename StorageType, typename ValueType>
986 inline void
987 TruncateCodec::decode(const StorageType& data, ValueType& val)
988 {
989 val = static_cast<ValueType>(data);
990 }
991
992
993 template<typename StorageType, typename ValueType>
994 inline void
995 TruncateCodec::encode(const ValueType& val, StorageType& data)
996 {
997 data = static_cast<StorageType>(val);
998 }
999
1000
1001 template <bool OneByte, typename Range>
1002 template<typename StorageType, typename ValueType>
1003 inline void
1004 FixedPointCodec<OneByte, Range>::decode(const StorageType& data, ValueType& val)
1005 {
1006 val = fixedPointToFloatingPoint<ValueType>(data);
1007
1008 // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
1009
1010 val = Range::template decode<ValueType>(val);
1011 }
1012
1013
1014 template <bool OneByte, typename Range>
1015 template<typename StorageType, typename ValueType>
1016 inline void
1017 FixedPointCodec<OneByte, Range>::encode(const ValueType& val, StorageType& data)
1018 {
1019 // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
1020
1021 const ValueType newVal = Range::template encode<ValueType>(val);
1022
1023 data = floatingPointToFixedPoint<StorageType>(newVal);
1024 }
1025
1026
1027 template<typename T>
1028 inline void
1029 UnitVecCodec::decode(const StorageType& data, math::Vec3<T>& val)
1030 {
1031 val = math::QuantizedUnitVec::unpack(data);
1032 }
1033
1034
1035 template<typename T>
1036 inline void
1037 UnitVecCodec::encode(const math::Vec3<T>& val, StorageType& data)
1038 {
1039 data = math::QuantizedUnitVec::pack(val);
1040 }
1041
1042
1044
1045 // AttributeArray implementation
1046
1047 #if OPENVDB_ABI_VERSION_NUMBER >= 6
1048
1049 template <typename IterT>
1050 void AttributeArray::doCopyValues(const AttributeArray& sourceArray, const IterT& iter,
1051 bool rangeChecking/*=true*/)
1052 {
1053 // ensure both arrays have float-float or integer-integer value types
1054 assert(sourceArray.valueTypeIsFloatingPoint() == this->valueTypeIsFloatingPoint());
1055 // ensure both arrays have been loaded from disk (if delay-loaded)
1056 assert(sourceArray.isDataLoaded() && this->isDataLoaded());
1057 // ensure storage size * stride matches on both arrays
1058 assert(this->storageTypeSize()*this->stride() ==
1059 sourceArray.storageTypeSize()*sourceArray.stride());
1060
1061 const size_t bytes(sourceArray.storageTypeSize()*sourceArray.stride());
1062 const char* const sourceBuffer = sourceArray.dataAsByteArray();
1063 char* const targetBuffer = this->dataAsByteArray();
1064 assert(sourceBuffer && targetBuffer);
1065
1066 if (rangeChecking && this->isUniform()) {
1067 OPENVDB_THROW(IndexError, "Cannot copy array data as target array is uniform.");
1068 }
1069
1070 const bool sourceIsUniform = sourceArray.isUniform();
1071
1072 const Index sourceDataSize = rangeChecking ? sourceArray.dataSize() : 0;
1073 const Index targetDataSize = rangeChecking ? this->dataSize() : 0;
1074
1075 for (IterT it(iter); it; ++it) {
1076 const Index sourceIndex = sourceIsUniform ? 0 : it.sourceIndex();
1077 const Index targetIndex = it.targetIndex();
1078
1079 if (rangeChecking) {
1080 if (sourceIndex >= sourceDataSize) {
1081 OPENVDB_THROW(IndexError,
1082 "Cannot copy array data as source index exceeds size of source array.");
1083 }
1084 if (targetIndex >= targetDataSize) {
1085 OPENVDB_THROW(IndexError,
1086 "Cannot copy array data as target index exceeds size of target array.");
1087 }
1088 } else {
1089 // range-checking asserts
1090 assert(sourceIndex < sourceArray.dataSize());
1091 assert(targetIndex < this->dataSize());
1092 if (this->isUniform()) assert(targetIndex == Index(0));
1093 }
1094
1095 const size_t targetOffset(targetIndex * bytes);
1096 const size_t sourceOffset(sourceIndex * bytes);
1097
1098 std::memcpy(targetBuffer + targetOffset, sourceBuffer + sourceOffset, bytes);
1099 }
1100 }
1101
1102 template <typename IterT>
1103 void AttributeArray::copyValuesUnsafe(const AttributeArray& sourceArray, const IterT& iter)
1104 {
1105 this->doCopyValues(sourceArray, iter, /*range-checking=*/false);
1106 }
1107
1108 template <typename IterT>
1109 void AttributeArray::copyValues(const AttributeArray& sourceArray, const IterT& iter,
1110 bool compact/* = true*/)
1111 {
1112 const Index bytes = sourceArray.storageTypeSize();
1113 if (bytes != this->storageTypeSize()) {
1114 OPENVDB_THROW(TypeError, "Cannot copy array data due to mis-match in storage type sizes.");
1115 }
1116
1117 // ensure both arrays have been loaded from disk
1118 sourceArray.loadData();
1119 this->loadData();
1120
1121 // if the target array is uniform, expand it first
1122 this->expand();
1123
1124 // TODO: Acquire mutex locks for source and target arrays to ensure that
1125 // value copying is always thread-safe. Note that the unsafe method will be
1126 // faster, but can only be used if neither the source or target arrays are
1127 // modified during copying. Note that this will require a new private
1128 // virtual method with ABI=7 to access the mutex from the derived class.
1129
1130 this->doCopyValues(sourceArray, iter, true);
1131
1132 // attempt to compact target array
1133 if (compact) {
1134 this->compact();
1135 }
1136 }
1137 #endif
1138
1139
1141
1142 // TypedAttributeArray implementation
1143
1144 template<typename ValueType_, typename Codec_>
1145 std::unique_ptr<const NamePair> TypedAttributeArray<ValueType_, Codec_>::sTypeName;
1146
1147
1148 template<typename ValueType_, typename Codec_>
1149 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(
1150 Index n, Index strideOrTotalSize, bool constantStride, const ValueType& uniformValue)
1151 : AttributeArray()
1152 , mData(new StorageType[1])
1153 , mSize(n)
1154 , mStrideOrTotalSize(strideOrTotalSize)
1155 {
1156 if (constantStride) {
1157 this->setConstantStride(true);
1158 if (strideOrTotalSize == 0) {
1159 OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a constant stride requires that " \
1160 "stride to be at least one.")
1161 }
1162 }
1163 else {
1164 this->setConstantStride(false);
1165 if (mStrideOrTotalSize < n) {
1166 OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a non-constant stride must have " \
1167 "a total size of at least the number of elements in the array.")
1168 }
1169 }
1170 mSize = std::max(Index(1), mSize);
1171 mStrideOrTotalSize = std::max(Index(1), mStrideOrTotalSize);
1172 Codec::encode(uniformValue, this->data()[0]);
1173 }
1174
1175
1176 #if OPENVDB_ABI_VERSION_NUMBER >= 7
1177 template<typename ValueType_, typename Codec_>
1178 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs)
1179 : TypedAttributeArray(rhs, tbb::spin_mutex::scoped_lock(rhs.mMutex))
1180 {
1181 }
1182
1183
1184 template<typename ValueType_, typename Codec_>
1185 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs,
1186 const tbb::spin_mutex::scoped_lock& lock)
1187 : AttributeArray(rhs, lock)
1188 #else
1189 template<typename ValueType_, typename Codec_>
1190 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs, bool)
1191 : AttributeArray(rhs)
1192 #endif
1193 , mSize(rhs.mSize)
1194 , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
1195 #if OPENVDB_ABI_VERSION_NUMBER < 6
1196 , mIsUniform(rhs.mIsUniform)
1197 #endif
1198 {
1199 if (this->validData()) {
1200 this->allocate();
1201 std::memcpy(this->data(), rhs.data(), this->arrayMemUsage());
1202 }
1203 }
1204
1205
1206 template<typename ValueType_, typename Codec_>
1207 TypedAttributeArray<ValueType_, Codec_>&
1208 TypedAttributeArray<ValueType_, Codec_>::operator=(const TypedAttributeArray& rhs)
1209 {
1210 if (&rhs != this) {
1211 // lock both the source and target arrays to ensure thread-safety
1212 tbb::spin_mutex::scoped_lock lock(mMutex);
1213 tbb::spin_mutex::scoped_lock rhsLock(rhs.mMutex);
1214
1215 this->deallocate();
1216
1217 mFlags = rhs.mFlags;
1218 mUsePagedRead = rhs.mUsePagedRead;
1219 mSize = rhs.mSize;
1220 mStrideOrTotalSize = rhs.mStrideOrTotalSize;
1221 mIsUniform = rhs.mIsUniform;
1222
1223 if (this->validData()) {
1224 this->allocate();
1225 std::memcpy(this->newDataAsByteArray(), rhs.newDataAsByteArray(), this->arrayMemUsage());
1226 }
1227 }
1228 }
1229
1230
1231 template<typename ValueType_, typename Codec_>
1232 inline const NamePair&
1233 TypedAttributeArray<ValueType_, Codec_>::attributeType()
1234 {
1235 static std::once_flag once;
1236 std::call_once(once, []()
1237 {
1238 sTypeName.reset(new NamePair(typeNameAsString<ValueType>(), Codec::name()));
1239 });
1240 return *sTypeName;
1241 }
1242
1243
1244 template<typename ValueType_, typename Codec_>
1245 inline bool
1246 TypedAttributeArray<ValueType_, Codec_>::isRegistered()
1247 {
1248 return AttributeArray::isRegistered(TypedAttributeArray::attributeType());
1249 }
1250
1251
1252 template<typename ValueType_, typename Codec_>
1253 inline void
1254 TypedAttributeArray<ValueType_, Codec_>::registerType()
1255 {
1256 AttributeArray::registerType(TypedAttributeArray::attributeType(), TypedAttributeArray::factory);
1257 }
1258
1259
1260 template<typename ValueType_, typename Codec_>
1261 inline void
1262 TypedAttributeArray<ValueType_, Codec_>::unregisterType()
1263 {
1264 AttributeArray::unregisterType(TypedAttributeArray::attributeType());
1265 }
1266
1267
1268 template<typename ValueType_, typename Codec_>
1269 inline typename TypedAttributeArray<ValueType_, Codec_>::Ptr
1270 TypedAttributeArray<ValueType_, Codec_>::create(Index n, Index stride, bool constantStride,
1271 const Metadata* metadata)
1272 {
1273 const TypedMetadata<ValueType>* typedMetadata = metadata ?
1274 dynamic_cast<const TypedMetadata<ValueType>*>(metadata) : nullptr;
1275
1276 return Ptr(new TypedAttributeArray(n, stride, constantStride,
1277 typedMetadata ? typedMetadata->value() : zeroVal<ValueType>()));
1278 }
1279
1280 template<typename ValueType_, typename Codec_>
1281 inline TypedAttributeArray<ValueType_, Codec_>&
1282 TypedAttributeArray<ValueType_, Codec_>::cast(AttributeArray& attributeArray)
1283 {
1284 if (!attributeArray.isType<TypedAttributeArray>()) {
1285 OPENVDB_THROW(TypeError, "Invalid Attribute Type");
1286 }
1287 return static_cast<TypedAttributeArray&>(attributeArray);
1288 }
1289
1290 template<typename ValueType_, typename Codec_>
1291 inline const TypedAttributeArray<ValueType_, Codec_>&
1292 TypedAttributeArray<ValueType_, Codec_>::cast(const AttributeArray& attributeArray)
1293 {
1294 if (!attributeArray.isType<TypedAttributeArray>()) {
1295 OPENVDB_THROW(TypeError, "Invalid Attribute Type");
1296 }
1297 return static_cast<const TypedAttributeArray&>(attributeArray);
1298 }
1299
1300 template<typename ValueType_, typename Codec_>
1301 AttributeArray::Ptr
1302 TypedAttributeArray<ValueType_, Codec_>::copy() const
1303 {
1304 #if OPENVDB_ABI_VERSION_NUMBER < 7
1305 tbb::spin_mutex::scoped_lock lock(mMutex);
1306 #endif
1307 return AttributeArray::Ptr(new TypedAttributeArray<ValueType, Codec>(*this));
1308 }
1309
1310
1311 template<typename ValueType_, typename Codec_>
1312 AttributeArray::Ptr
1313 TypedAttributeArray<ValueType_, Codec_>::copyUncompressed() const
1314 {
1315 return this->copy();
1316 }
1317
1318
1319 template<typename ValueType_, typename Codec_>
1320 size_t
1321 TypedAttributeArray<ValueType_, Codec_>::arrayMemUsage() const
1322 {
1323 if (this->isOutOfCore()) return 0;
1324
1325 return (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType);
1326 }
1327
1328
1329 template<typename ValueType_, typename Codec_>
1330 void
1331 TypedAttributeArray<ValueType_, Codec_>::allocate()
1332 {
1333 assert(!mData);
1334 if (mIsUniform) {
1335 mData.reset(new StorageType[1]);
1336 }
1337 else {
1338 const size_t size(this->dataSize());
1339 assert(size > 0);
1340 mData.reset(new StorageType[size]);
1341 }
1342 }
1343
1344
1345 template<typename ValueType_, typename Codec_>
1346 void
1347 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1348 {
1349 // detach from file if delay-loaded
1350 if (this->isOutOfCore()) {
1351 this->setOutOfCore(false);
1352 this->mPageHandle.reset();
1353 }
1354 if (mData) mData.reset();
1355 }
1356
1357
1358 #if OPENVDB_ABI_VERSION_NUMBER >= 6
1359 template<typename ValueType_, typename Codec_>
1360 bool
1361 TypedAttributeArray<ValueType_, Codec_>::valueTypeIsFloatingPoint() const
1362 {
1363 // TODO: Update to use Traits that correctly handle matrices and quaternions.
1364
1365 if (std::is_same<ValueType, Quats>::value ||
1366 std::is_same<ValueType, Quatd>::value ||
1367 std::is_same<ValueType, Mat3s>::value ||
1368 std::is_same<ValueType, Mat3d>::value ||
1369 std::is_same<ValueType, Mat4s>::value ||
1370 std::is_same<ValueType, Mat4d>::value) return true;
1371
1372 using ElementT = typename VecTraits<ValueType>::ElementType;
1373
1374 // half is not defined as float point as expected, so explicitly handle it
1375 return std::is_floating_point<ElementT>::value || std::is_same<half, ElementT>::value;
1376 }
1377
1378
1379 template<typename ValueType_, typename Codec_>
1380 bool
1381 TypedAttributeArray<ValueType_, Codec_>::valueTypeIsClass() const
1382 {
1383 // half is not defined as a non-class type as expected, so explicitly exclude it
1384 return std::is_class<ValueType>::value && !std::is_same<half, ValueType>::value;
1385 }
1386
1387
1388 template<typename ValueType_, typename Codec_>
1389 bool
1390 TypedAttributeArray<ValueType_, Codec_>::valueTypeIsVector() const
1391 {
1392 return VecTraits<ValueType>::IsVec;
1393 }
1394
1395
1396 template<typename ValueType_, typename Codec_>
1397 bool
1398 TypedAttributeArray<ValueType_, Codec_>::valueTypeIsQuaternion() const
1399 {
1400 // TODO: improve performance by making this a compile-time check using type traits
1401 return !this->valueType().compare(0, 4, "quat");
1402 }
1403
1404
1405 template<typename ValueType_, typename Codec_>
1406 bool
1407 TypedAttributeArray<ValueType_, Codec_>::valueTypeIsMatrix() const
1408 {
1409 // TODO: improve performance by making this a compile-time check using type traits
1410 return !this->valueType().compare(0, 3, "mat");
1411 }
1412 #endif
1413
1414
1415 template<typename ValueType_, typename Codec_>
1416 size_t
1417 TypedAttributeArray<ValueType_, Codec_>::memUsage() const
1418 {
1419 return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1420 }
1421
1422
1423 template<typename ValueType_, typename Codec_>
1424 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1425 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n) const
1426 {
1427 assert(n < this->dataSize());
1428
1429 ValueType val;
1430 Codec::decode(/*in=*/this->data()[mIsUniform ? 0 : n], /*out=*/val);
1431 return val;
1432 }
1433
1434
1435 template<typename ValueType_, typename Codec_>
1436 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1437 TypedAttributeArray<ValueType_, Codec_>::get(Index n) const
1438 {
1439 if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1440 if (this->isOutOfCore()) this->doLoad();
1441
1442 return this->getUnsafe(n);
1443 }
1444
1445
1446 template<typename ValueType_, typename Codec_>
1447 template<typename T>
1448 void
1449 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n, T& val) const
1450 {
1451 val = static_cast<T>(this->getUnsafe(n));
1452 }
1453
1454
1455 template<typename ValueType_, typename Codec_>
1456 template<typename T>
1457 void
1458 TypedAttributeArray<ValueType_, Codec_>::get(Index n, T& val) const
1459 {
1460 val = static_cast<T>(this->get(n));
1461 }
1462
1463
1464 template<typename ValueType_, typename Codec_>
1465 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1466 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(const AttributeArray* array, const Index n)
1467 {
1468 return static_cast<const TypedAttributeArray<ValueType, Codec>*>(array)->getUnsafe(n);
1469 }
1470
1471
1472 template<typename ValueType_, typename Codec_>
1473 void
1474 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const ValueType& val)
1475 {
1476 assert(n < this->dataSize());
1477 assert(!this->isOutOfCore());
1478 assert(!this->isUniform());
1479
1480 // this unsafe method assumes the data is not uniform, however if it is, this redirects the index
1481 // to zero, which is marginally less efficient but ensures not writing to an illegal address
1482
1483 Codec::encode(/*in=*/val, /*out=*/this->data()[mIsUniform ? 0 : n]);
1484 }
1485
1486
1487 template<typename ValueType_, typename Codec_>
1488 void
1489 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const ValueType& val)
1490 {
1491 if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1492 if (this->isOutOfCore()) this->doLoad();
1493 if (this->isUniform()) this->expand();
1494
1495 this->setUnsafe(n, val);
1496 }
1497
1498
1499 template<typename ValueType_, typename Codec_>
1500 template<typename T>
1501 void
1502 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const T& val)
1503 {
1504 this->setUnsafe(n, static_cast<ValueType>(val));
1505 }
1506
1507
1508 template<typename ValueType_, typename Codec_>
1509 template<typename T>
1510 void
1511 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const T& val)
1512 {
1513 this->set(n, static_cast<ValueType>(val));
1514 }
1515
1516
1517 template<typename ValueType_, typename Codec_>
1518 void
1519 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(AttributeArray* array, const Index n, const ValueType& value)
1520 {
1521 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->setUnsafe(n, value);
1522 }
1523
1524
1525 template<typename ValueType_, typename Codec_>
1526 void
1527 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const AttributeArray& sourceArray, const Index sourceIndex)
1528 {
1529 const TypedAttributeArray& sourceTypedArray = static_cast<const TypedAttributeArray&>(sourceArray);
1530
1531 ValueType sourceValue;
1532 sourceTypedArray.get(sourceIndex, sourceValue);
1533
1534 this->set(n, sourceValue);
1535 }
1536
1537
1538 template<typename ValueType_, typename Codec_>
1539 void
1540 TypedAttributeArray<ValueType_, Codec_>::expand(bool fill)
1541 {
1542 if (!mIsUniform) return;
1543
1544 const StorageType val = this->data()[0];
1545
1546 {
1547 tbb::spin_mutex::scoped_lock lock(mMutex);
1548 this->deallocate();
1549 mIsUniform = false;
1550 this->allocate();
1551 }
1552
1553 if (fill) {
1554 for (Index i = 0; i < this->dataSize(); ++i) this->data()[i] = val;
1555 }
1556 }
1557
1558
1559 template<typename ValueType_, typename Codec_>
1560 bool
1561 TypedAttributeArray<ValueType_, Codec_>::compact()
1562 {
1563 if (mIsUniform) return true;
1564
1565 // compaction is not possible if any values are different
1566 const ValueType_ val = this->get(0);
1567 for (Index i = 1; i < this->dataSize(); i++) {
1568 if (!math::isExactlyEqual(this->get(i), val)) return false;
1569 }
1570
1571 this->collapse(this->get(0));
1572 return true;
1573 }
1574
1575
1576 template<typename ValueType_, typename Codec_>
1577 void
1578 TypedAttributeArray<ValueType_, Codec_>::collapse()
1579 {
1580 this->collapse(zeroVal<ValueType>());
1581 }
1582
1583
1584 template<typename ValueType_, typename Codec_>
1585 void
1586 TypedAttributeArray<ValueType_, Codec_>::collapse(const ValueType& uniformValue)
1587 {
1588 if (!mIsUniform) {
1589 tbb::spin_mutex::scoped_lock lock(mMutex);
1590 this->deallocate();
1591 mIsUniform = true;
1592 this->allocate();
1593 }
1594 Codec::encode(uniformValue, this->data()[0]);
1595 }
1596
1597
1598 template<typename ValueType_, typename Codec_>
1599 void
1600 TypedAttributeArray<ValueType_, Codec_>::collapse(AttributeArray* array, const ValueType& value)
1601 {
1602 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->collapse(value);
1603 }
1604
1605
1606 template<typename ValueType_, typename Codec_>
1607 void
1608 TypedAttributeArray<ValueType_, Codec_>::fill(const ValueType& value)
1609 {
1610 if (this->isOutOfCore()) {
1611 tbb::spin_mutex::scoped_lock lock(mMutex);
1612 this->deallocate();
1613 this->allocate();
1614 }
1615
1616 const Index size = mIsUniform ? 1 : this->dataSize();
1617 for (Index i = 0; i < size; ++i) {
1618 Codec::encode(value, this->data()[i]);
1619 }
1620 }
1621
1622
1623 template<typename ValueType_, typename Codec_>
1624 void
1625 TypedAttributeArray<ValueType_, Codec_>::fill(AttributeArray* array, const ValueType& value)
1626 {
1627 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->fill(value);
1628 }
1629
1630
1631 template<typename ValueType_, typename Codec_>
1632 inline bool
1633 TypedAttributeArray<ValueType_, Codec_>::compress()
1634 {
1635 return false;
1636 }
1637
1638
1639 template<typename ValueType_, typename Codec_>
1640 inline bool
1641 TypedAttributeArray<ValueType_, Codec_>::compressUnsafe()
1642 {
1643 return false;
1644 }
1645
1646
1647 template<typename ValueType_, typename Codec_>
1648 inline bool
1649 TypedAttributeArray<ValueType_, Codec_>::decompress()
1650 {
1651 return false;
1652 }
1653
1654
1655 template<typename ValueType_, typename Codec_>
1656 bool
1657 TypedAttributeArray<ValueType_, Codec_>::isOutOfCore() const
1658 {
1659 return mOutOfCore;
1660 }
1661
1662
1663 template<typename ValueType_, typename Codec_>
1664 void
1665 TypedAttributeArray<ValueType_, Codec_>::setOutOfCore(const bool b)
1666 {
1667 mOutOfCore = b;
1668 }
1669
1670
1671 template<typename ValueType_, typename Codec_>
1672 void
1673 TypedAttributeArray<ValueType_, Codec_>::doLoad() const
1674 {
1675 if (!(this->isOutOfCore())) return;
1676
1677 TypedAttributeArray<ValueType_, Codec_>* self =
1678 const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
1679
1680 // This lock will be contended at most once, after which this buffer
1681 // will no longer be out-of-core.
1682 tbb::spin_mutex::scoped_lock lock(self->mMutex);
1683 this->doLoadUnsafe();
1684 }
1685
1686
1687 template<typename ValueType_, typename Codec_>
1688 void
1689 TypedAttributeArray<ValueType_, Codec_>::loadData() const
1690 {
1691 this->doLoad();
1692 }
1693
1694
1695 #if OPENVDB_ABI_VERSION_NUMBER >= 6
1696 template<typename ValueType_, typename Codec_>
1697 bool
1698 TypedAttributeArray<ValueType_, Codec_>::isDataLoaded() const
1699 {
1700 return !this->isOutOfCore();
1701 }
1702 #endif
1703
1704
1705 template<typename ValueType_, typename Codec_>
1706 void
1707 TypedAttributeArray<ValueType_, Codec_>::read(std::istream& is)
1708 {
1709 this->readMetadata(is);
1710 this->readBuffers(is);
1711 }
1712
1713
1714 template<typename ValueType_, typename Codec_>
1715 void
1716 TypedAttributeArray<ValueType_, Codec_>::readMetadata(std::istream& is)
1717 {
1718 // read data
1719
1720 Index64 bytes = Index64(0);
1721 is.read(reinterpret_cast<char*>(&bytes), sizeof(Index64));
1722 bytes = bytes - /*flags*/sizeof(Int16) - /*size*/sizeof(Index);
1723
1724 uint8_t flags = uint8_t(0);
1725 is.read(reinterpret_cast<char*>(&flags), sizeof(uint8_t));
1726 mFlags = flags;
1727
1728 uint8_t serializationFlags = uint8_t(0);
1729 is.read(reinterpret_cast<char*>(&serializationFlags), sizeof(uint8_t));
1730
1731 Index size = Index(0);
1732 is.read(reinterpret_cast<char*>(&size), sizeof(Index));
1733 mSize = size;
1734
1735 // warn if an unknown flag has been set
1736 if (mFlags >= 0x20) {
1737 OPENVDB_LOG_WARN("Unknown attribute flags for VDB file format.");
1738 }
1739 // error if an unknown serialization flag has been set,
1740 // as this will adjust the layout of the data and corrupt the ability to read
1741 if (serializationFlags >= 0x10) {
1742 OPENVDB_THROW(IoError, "Unknown attribute serialization flags for VDB file format.");
1743 }
1744
1745 // set uniform, compressed and page read state
1746
1747 mIsUniform = serializationFlags & WRITEUNIFORM;
1748 mUsePagedRead = serializationFlags & WRITEPAGED;
1749 mCompressedBytes = bytes;
1750 mFlags |= PARTIALREAD; // mark data as having been partially read
1751
1752 // read strided value (set to 1 if array is not strided)
1753
1754 if (serializationFlags & WRITESTRIDED) {
1755 Index stride = Index(0);
1756 is.read(reinterpret_cast<char*>(&stride), sizeof(Index));
1757 mStrideOrTotalSize = stride;
1758 }
1759 else {
1760 mStrideOrTotalSize = 1;
1761 }
1762 }
1763
1764
1765 template<typename ValueType_, typename Codec_>
1766 void
1767 TypedAttributeArray<ValueType_, Codec_>::readBuffers(std::istream& is)
1768 {
1769 if (mUsePagedRead) {
1770 // use readBuffers(PagedInputStream&) for paged buffers
1771 OPENVDB_THROW(IoError, "Cannot read paged AttributeArray buffers.");
1772 }
1773
1774 tbb::spin_mutex::scoped_lock lock(mMutex);
1775
1776 this->deallocate();
1777
1778 uint8_t bloscCompressed(0);
1779 if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed), sizeof(uint8_t));
1780
1781 assert(mFlags & PARTIALREAD);
1782 std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
1783 is.read(buffer.get(), mCompressedBytes);
1784 mCompressedBytes = 0;
1785 mFlags = static_cast<uint8_t>(mFlags & ~PARTIALREAD); // mark data read as having completed
1786
1787 // compressed on-disk
1788
1789 if (bloscCompressed == uint8_t(1)) {
1790
1791 // decompress buffer
1792
1793 const size_t inBytes = this->dataSize() * sizeof(StorageType);
1794 std::unique_ptr<char[]> newBuffer = compression::bloscDecompress(buffer.get(), inBytes);
1795 if (newBuffer) buffer.reset(newBuffer.release());
1796 }
1797
1798 // set data to buffer
1799
1800 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1801 }
1802
1803
1804 template<typename ValueType_, typename Codec_>
1805 void
1806 TypedAttributeArray<ValueType_, Codec_>::readPagedBuffers(compression::PagedInputStream& is)
1807 {
1808 if (!mUsePagedRead) {
1809 if (!is.sizeOnly()) this->readBuffers(is.getInputStream());
1810 return;
1811 }
1812
1813 // If this array is being read from a memory-mapped file, delay loading of its data
1814 // until the data is actually accessed.
1815 io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is.getInputStream());
1816 const bool delayLoad = (mappedFile.get() != nullptr);
1817
1818 if (is.sizeOnly())
1819 {
1820 size_t compressedBytes(mCompressedBytes);
1821 mCompressedBytes = 0; // if not set to zero, mPageHandle will attempt to destroy invalid memory
1822 mFlags = static_cast<uint8_t>(mFlags & ~PARTIALREAD); // mark data read as having completed
1823 assert(!mPageHandle);
1824 mPageHandle = is.createHandle(compressedBytes);
1825 return;
1826 }
1827
1828 assert(mPageHandle);
1829
1830 tbb::spin_mutex::scoped_lock lock(mMutex);
1831
1832 this->deallocate();
1833
1834 this->setOutOfCore(delayLoad);
1835 is.read(mPageHandle, std::streamsize(mPageHandle->size()), delayLoad);
1836
1837 if (!delayLoad) {
1838 std::unique_ptr<char[]> buffer = mPageHandle->read();
1839 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1840 }
1841
1842 // clear page state
1843
1844 mUsePagedRead = 0;
1845 }
1846
1847
1848 template<typename ValueType_, typename Codec_>
1849 void
1850 TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os) const
1851 {
1852 this->write(os, /*outputTransient=*/false);
1853 }
1854
1855
1856 template<typename ValueType_, typename Codec_>
1857 void
1858 TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os, bool outputTransient) const
1859 {
1860 this->writeMetadata(os, outputTransient, /*paged=*/false);
1861 this->writeBuffers(os, outputTransient);
1862 }
1863
1864
1865 template<typename ValueType_, typename Codec_>
1866 void
1867 TypedAttributeArray<ValueType_, Codec_>::writeMetadata(std::ostream& os, bool outputTransient, bool paged) const
1868 {
1869 if (!outputTransient && this->isTransient()) return;
1870
1871 if (mFlags & PARTIALREAD) {
1872 OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
1873 }
1874
1875 uint8_t flags(mFlags);
1876 uint8_t serializationFlags(0);
1877 Index size(mSize);
1878 Index stride(mStrideOrTotalSize);
1879 bool strideOfOne(this->stride() == 1);
1880
1881 bool bloscCompression = io::getDataCompression(os) & io::COMPRESS_BLOSC;
1882
1883 // any compressed data needs to be loaded if out-of-core
1884 if (bloscCompression) this->doLoad();
1885
1886 size_t compressedBytes = 0;
1887
1888 if (!strideOfOne)
1889 {
1890 serializationFlags |= WRITESTRIDED;
1891 }
1892
1893 if (mIsUniform)
1894 {
1895 serializationFlags |= WRITEUNIFORM;
1896 if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1897 }
1898 else if (bloscCompression)
1899 {
1900 if (paged) serializationFlags |= WRITEPAGED;
1901 else {
1902 const char* charBuffer = reinterpret_cast<const char*>(this->data());
1903 const size_t inBytes = this->arrayMemUsage();
1904 compressedBytes = compression::bloscCompressedSize(charBuffer, inBytes);
1905 }
1906 }
1907
1908 Index64 bytes = /*flags*/ sizeof(Int16) + /*size*/ sizeof(Index);
1909
1910 bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1911
1912 // write data
1913
1914 os.write(reinterpret_cast<const char*>(&bytes), sizeof(Index64));
1915 os.write(reinterpret_cast<const char*>(&flags), sizeof(uint8_t));
1916 os.write(reinterpret_cast<const char*>(&serializationFlags), sizeof(uint8_t));
1917 os.write(reinterpret_cast<const char*>(&size), sizeof(Index));
1918
1919 // write strided
1920 if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride), sizeof(Index));
1921 }
1922
1923
1924 template<typename ValueType_, typename Codec_>
1925 void
1926 TypedAttributeArray<ValueType_, Codec_>::writeBuffers(std::ostream& os, bool outputTransient) const
1927 {
1928 if (!outputTransient && this->isTransient()) return;
1929
1930 if (mFlags & PARTIALREAD) {
1931 OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
1932 }
1933
1934 this->doLoad();
1935
1936 if (this->isUniform()) {
1937 os.write(reinterpret_cast<const char*>(this->data()), sizeof(StorageType));
1938 }
1939 else if (io::getDataCompression(os) & io::COMPRESS_BLOSC)
1940 {
1941 std::unique_ptr<char[]> compressedBuffer;
1942 size_t compressedBytes = 0;
1943 const char* charBuffer = reinterpret_cast<const char*>(this->data());
1944 const size_t inBytes = this->arrayMemUsage();
1945 compressedBuffer = compression::bloscCompress(charBuffer, inBytes, compressedBytes);
1946 if (compressedBuffer) {
1947 uint8_t bloscCompressed(1);
1948 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1949 os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1950 }
1951 else {
1952 uint8_t bloscCompressed(0);
1953 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1954 os.write(reinterpret_cast<const char*>(this->data()), inBytes);
1955 }
1956 }
1957 else
1958 {
1959 uint8_t bloscCompressed(0);
1960 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1961 os.write(reinterpret_cast<const char*>(this->data()), this->arrayMemUsage());
1962 }
1963 }
1964
1965
1966 template<typename ValueType_, typename Codec_>
1967 void
1968 TypedAttributeArray<ValueType_, Codec_>::writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const
1969 {
1970 if (!outputTransient && this->isTransient()) return;
1971
1972 // paged compression only available when Blosc is enabled
1973 bool bloscCompression = io::getDataCompression(os.getOutputStream()) & io::COMPRESS_BLOSC;
1974 if (!bloscCompression) {
1975 if (!os.sizeOnly()) this->writeBuffers(os.getOutputStream(), outputTransient);
1976 return;
1977 }
1978
1979 if (mFlags & PARTIALREAD) {
1980 OPENVDB_THROW(IoError, "Cannot write out a partially-read AttributeArray.");
1981 }
1982
1983 this->doLoad();
1984
1985 os.write(reinterpret_cast<const char*>(this->data()), this->arrayMemUsage());
1986 }
1987
1988
1989 template<typename ValueType_, typename Codec_>
1990 void
1991 TypedAttributeArray<ValueType_, Codec_>::doLoadUnsafe(const bool /*compression*/) const
1992 {
1993 if (!(this->isOutOfCore())) return;
1994
1995 // this function expects the mutex to already be locked
1996
1997 auto* self = const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
1998
1999 assert(self->mPageHandle);
2000 assert(!(self->mFlags & PARTIALREAD));
2001
2002 std::unique_ptr<char[]> buffer = self->mPageHandle->read();
2003
2004 self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
2005
2006 self->mPageHandle.reset();
2007
2008 // clear all write and out-of-core flags
2009
2010 self->mOutOfCore = false;
2011 }
2012
2013
2014 template<typename ValueType_, typename Codec_>
2015 AttributeArray::AccessorBasePtr
2016 TypedAttributeArray<ValueType_, Codec_>::getAccessor() const
2017 {
2018 // use the faster 'unsafe' get and set methods as attribute handles
2019 // ensure data is in-core when constructed
2020
2021 return AccessorBasePtr(new AttributeArray::Accessor<ValueType_>(
2022 &TypedAttributeArray<ValueType_, Codec_>::getUnsafe,
2023 &TypedAttributeArray<ValueType_, Codec_>::setUnsafe,
2024 &TypedAttributeArray<ValueType_, Codec_>::collapse,
2025 &TypedAttributeArray<ValueType_, Codec_>::fill));
2026 }
2027
2028
2029 template<typename ValueType_, typename Codec_>
2030 bool
2031 TypedAttributeArray<ValueType_, Codec_>::isEqual(const AttributeArray& other) const
2032 {
2033 const TypedAttributeArray<ValueType_, Codec_>* const otherT = dynamic_cast<const TypedAttributeArray<ValueType_, Codec_>* >(&other);
2034 if(!otherT) return false;
2035 if(this->mSize != otherT->mSize ||
2036 this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
2037 this->mIsUniform != otherT->mIsUniform ||
2038 this->attributeType() != this->attributeType()) return false;
2039
2040 this->doLoad();
2041 otherT->doLoad();
2042
2043 const StorageType *target = this->data(), *source = otherT->data();
2044 if (!target && !source) return true;
2045 if (!target || !source) return false;
2046 Index n = this->mIsUniform ? 1 : mSize;
2047 while (n && math::isExactlyEqual(*target++, *source++)) --n;
2048 return n == 0;
2049 }
2050
2051
2052 #if OPENVDB_ABI_VERSION_NUMBER >= 6
2053 template<typename ValueType_, typename Codec_>
2054 char*
2055 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray()
2056 {
2057 return reinterpret_cast<char*>(this->data());
2058 }
2059
2060
2061 template<typename ValueType_, typename Codec_>
2062 const char*
2063 TypedAttributeArray<ValueType_, Codec_>::dataAsByteArray() const
2064 {
2065 return reinterpret_cast<const char*>(this->data());
2066 }
2067 #endif
2068
2069
2071
2072
2074 template <typename CodecType, typename ValueType>
2075 struct AccessorEval
2076 {
2077 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
2078 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
2079
2082 static ValueType get(GetterPtr /*functor*/, const AttributeArray* array, const Index n) {
2083 return TypedAttributeArray<ValueType, CodecType>::getUnsafe(array, n);
2084 }
2085
2088 static void set(SetterPtr /*functor*/, AttributeArray* array, const Index n, const ValueType& value) {
2089 TypedAttributeArray<ValueType, CodecType>::setUnsafe(array, n, value);
2090 }
2091 };
2092
2093
2095 template <typename ValueType>
2096 struct AccessorEval<UnknownCodec, ValueType>
2097 {
2098 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
2099 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
2100
2102 static ValueType get(GetterPtr functor, const AttributeArray* array, const Index n) {
2103 return (*functor)(array, n);
2104 }
2105
2107 static void set(SetterPtr functor, AttributeArray* array, const Index n, const ValueType& value) {
2108 (*functor)(array, n, value);
2109 }
2110 };
2111
2112
2114
2115 // AttributeHandle implementation
2116
2117 template <typename ValueType, typename CodecType>
2118 typename AttributeHandle<ValueType, CodecType>::Ptr
2119 AttributeHandle<ValueType, CodecType>::create(const AttributeArray& array, const bool collapseOnDestruction)
2120 {
2121 return typename AttributeHandle<ValueType, CodecType>::Ptr(
2122 new AttributeHandle<ValueType, CodecType>(array, collapseOnDestruction));
2123 }
2124
2125 template <typename ValueType, typename CodecType>
2126 AttributeHandle<ValueType, CodecType>::AttributeHandle(const AttributeArray& array, const bool collapseOnDestruction)
2127 : mArray(&array)
2128 , mStrideOrTotalSize(array.hasConstantStride() ? array.stride() : 1)
2129 , mSize(array.hasConstantStride() ? array.size() : array.dataSize())
2130 , mCollapseOnDestruction(collapseOnDestruction && array.isStreaming())
2131 {
2132 if (!this->compatibleType<std::is_same<CodecType, UnknownCodec>::value>()) {
2133 OPENVDB_THROW(TypeError, "Cannot bind handle due to incompatible type of AttributeArray.");
2134 }
2135
2136 // load data if delay-loaded
2137
2138 mArray->loadData();
2139
2140 // bind getter and setter methods
2141
2142 AttributeArray::AccessorBasePtr accessor = mArray->getAccessor();
2143 assert(accessor);
2144
2145 AttributeArray::Accessor<ValueType>* typedAccessor = static_cast<AttributeArray::Accessor<ValueType>*>(accessor.get());
2146
2147 mGetter = typedAccessor->mGetter;
2148 mSetter = typedAccessor->mSetter;
2149 mCollapser = typedAccessor->mCollapser;
2150 mFiller = typedAccessor->mFiller;
2151 }
2152
2153 template <typename ValueType, typename CodecType>
2154 AttributeHandle<ValueType, CodecType>::~AttributeHandle()
2155 {
2156 // if enabled, attribute is collapsed on destruction of the handle to save memory
2157 if (mCollapseOnDestruction) const_cast<AttributeArray*>(this->mArray)->collapse();
2158 }
2159
2160 template <typename ValueType, typename CodecType>
2161 template <bool IsUnknownCodec>
2162 typename std::enable_if<IsUnknownCodec, bool>::type
2163 AttributeHandle<ValueType, CodecType>::compatibleType() const
2164 {
2165 // if codec is unknown, just check the value type
2166
2167 return mArray->hasValueType<ValueType>();
2168 }
2169
2170 template <typename ValueType, typename CodecType>
2171 template <bool IsUnknownCodec>
2172 typename std::enable_if<!IsUnknownCodec, bool>::type
2173 AttributeHandle<ValueType, CodecType>::compatibleType() const
2174 {
2175 // if the codec is known, check the value type and codec
2176
2177 return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
2178 }
2179
2180 template <typename ValueType, typename CodecType>
2181 const AttributeArray& AttributeHandle<ValueType, CodecType>::array() const
2182 {
2183 assert(mArray);
2184 return *mArray;
2185 }
2186
2187 template <typename ValueType, typename CodecType>
2188 Index AttributeHandle<ValueType, CodecType>::index(Index n, Index m) const
2189 {
2190 Index index = n * mStrideOrTotalSize + m;
2191 assert(index < (mSize * mStrideOrTotalSize));
2192 return index;
2193 }
2194
2195 template <typename ValueType, typename CodecType>
2196 ValueType AttributeHandle<ValueType, CodecType>::get(Index n, Index m) const
2197 {
2198 return this->get<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m));
2199 }
2200
2201 template <typename ValueType, typename CodecType>
2202 template <bool IsUnknownCodec>
2203 typename std::enable_if<IsUnknownCodec, ValueType>::type
2204 AttributeHandle<ValueType, CodecType>::get(Index index) const
2205 {
2206 // if the codec is unknown, use the getter functor
2207
2208 return (*mGetter)(mArray, index);
2209 }
2210
2211 template <typename ValueType, typename CodecType>
2212 template <bool IsUnknownCodec>
2213 typename std::enable_if<!IsUnknownCodec, ValueType>::type
2214 AttributeHandle<ValueType, CodecType>::get(Index index) const
2215 {
2216 // if the codec is known, call the method on the attribute array directly
2217
2218 return TypedAttributeArray<ValueType, CodecType>::getUnsafe(mArray, index);
2219 }
2220
2221 template <typename ValueType, typename CodecType>
2222 bool AttributeHandle<ValueType, CodecType>::isUniform() const
2223 {
2224 return mArray->isUniform();
2225 }
2226
2227 template <typename ValueType, typename CodecType>
2228 bool AttributeHandle<ValueType, CodecType>::hasConstantStride() const
2229 {
2230 return mArray->hasConstantStride();
2231 }
2232
2234
2235 // AttributeWriteHandle implementation
2236
2237 template <typename ValueType, typename CodecType>
2238 typename AttributeWriteHandle<ValueType, CodecType>::Ptr
2239 AttributeWriteHandle<ValueType, CodecType>::create(AttributeArray& array, const bool expand)
2240 {
2241 return typename AttributeWriteHandle<ValueType, CodecType>::Ptr(
2242 new AttributeWriteHandle<ValueType, CodecType>(array, expand));
2243 }
2244
2245 template <typename ValueType, typename CodecType>
2246 AttributeWriteHandle<ValueType, CodecType>::AttributeWriteHandle(AttributeArray& array, const bool expand)
2247 : AttributeHandle<ValueType, CodecType>(array, /*collapseOnDestruction=*/false)
2248 {
2249 if (expand) array.expand();
2250 }
2251
2252 template <typename ValueType, typename CodecType>
2253 void AttributeWriteHandle<ValueType, CodecType>::set(Index n, const ValueType& value)
2254 {
2255 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, 0), value);
2256 }
2257
2258 template <typename ValueType, typename CodecType>
2259 void AttributeWriteHandle<ValueType, CodecType>::set(Index n, Index m, const ValueType& value)
2260 {
2261 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m), value);
2262 }
2263
2264 template <typename ValueType, typename CodecType>
2265 void AttributeWriteHandle<ValueType, CodecType>::expand(const bool fill)
2266 {
2267 const_cast<AttributeArray*>(this->mArray)->expand(fill);
2268 }
2269
2270 template <typename ValueType, typename CodecType>
2271 void AttributeWriteHandle<ValueType, CodecType>::collapse()
2272 {
2273 const_cast<AttributeArray*>(this->mArray)->collapse();
2274 }
2275
2276 template <typename ValueType, typename CodecType>
2277 bool AttributeWriteHandle<ValueType, CodecType>::compact()
2278 {
2279 return const_cast<AttributeArray*>(this->mArray)->compact();
2280 }
2281
2282 template <typename ValueType, typename CodecType>
2283 void AttributeWriteHandle<ValueType, CodecType>::collapse(const ValueType& uniformValue)
2284 {
2285 this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2286 }
2287
2288 template <typename ValueType, typename CodecType>
2289 void AttributeWriteHandle<ValueType, CodecType>::fill(const ValueType& value)
2290 {
2291 this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2292 }
2293
2294 template <typename ValueType, typename CodecType>
2295 template <bool IsUnknownCodec>
2296 typename std::enable_if<IsUnknownCodec, void>::type
2297 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2298 {
2299 // if the codec is unknown, use the setter functor
2300
2301 (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index, value);
2302 }
2303
2304 template <typename ValueType, typename CodecType>
2305 template <bool IsUnknownCodec>
2306 typename std::enable_if<!IsUnknownCodec, void>::type
2307 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2308 {
2309 // if the codec is known, call the method on the attribute array directly
2310
2311 TypedAttributeArray<ValueType, CodecType>::setUnsafe(const_cast<AttributeArray*>(this->mArray), index, value);
2312 }
2313
2314 template <typename ValueType, typename CodecType>
2315 AttributeArray& AttributeWriteHandle<ValueType, CodecType>::array()
2316 {
2317 assert(this->mArray);
2318 return *const_cast<AttributeArray*>(this->mArray);
2319 }
2320
2321
2322 } // namespace points
2323 } // namespace OPENVDB_VERSION_NAME
2324 } // namespace openvdb
2325
2326 #endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
openvdb::v7_1::math::Vec3
Definition: Mat.h:170
openvdb::v7_1::compression::PagedOutputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:256
openvdb::v7_1::points::TypedAttributeArray::type
const NamePair & type() const override
Return the name of this attribute's type.
Definition: AttributeArray.h:629
openvdb::v7_1::points::AttributeArray::~AttributeArray
virtual ~AttributeArray()
Definition: AttributeArray.h:133
openvdb::v7_1::points::AttributeWriteHandle::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:923
openvdb::v7_1::points::TypedAttributeArray::getAccessor
AccessorBasePtr getAccessor() const override
Obtain an Accessor that stores getter and setter functors.
Definition: AttributeArray.h:2016
Compression.h
openvdb::v7_1::points::AttributeArray::create
static OPENVDB_DEPRECATED Ptr create(const NamePair &type, Index length, Index stride, bool constantStride, const ScopedRegistryLock *lock)
openvdb::v7_1::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:83
openvdb::v7_1::points::TypedAttributeArray::valueTypeIsQuaternion
bool valueTypeIsQuaternion() const override
Return true if the value type is a quaternion.
Definition: AttributeArray.h:1398
openvdb::v7_1::points::AttributeArray::operator=
AttributeArray & operator=(const AttributeArray &rhs)
openvdb::v7_1::points::AttributeArray::readPagedBuffers
virtual void readPagedBuffers(compression::PagedInputStream &)=0
Read attribute buffers from a paged stream.
openvdb::v7_1::points::TruncateCodec::Storage
Definition: AttributeArray.h:500
StreamCompression.h
Convenience wrappers to using Blosc and reading and writing of Paged data.
openvdb::v7_1::points::AttributeArray::stride
virtual Index stride() const =0
openvdb::v7_1::points::NullCodec::Storage
Definition: AttributeArray.h:489
openvdb::v7_1::points::AttributeHandle::mArray
const AttributeArray * mArray
Definition: AttributeArray.h:883
openvdb::v7_1::points::AttributeHandle::get
ValueType get(Index n, Index m=0) const
Definition: AttributeArray.h:2196
openvdb::v7_1::points::AttributeHandle< Index, openvdb::v7_1::points::StringCodec< false > >::GetterPtr
Index(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:856
openvdb::v7_1::points::AttributeHandle
Definition: AttributeArray.h:849
openvdb::v7_1::points::TypedAttributeArray::size
Index size() const override
Return the number of elements in this array.
Definition: AttributeArray.h:639
openvdb::v7_1::points::TypedAttributeArray::fill
void fill(const ValueType &value)
Fill the existing array with the given value.
Definition: AttributeArray.h:1608
openvdb::v7_1::points::AttributeArray::AttributeArray
AttributeArray(AttributeArray &&)=delete
openvdb::v7_1::points::TypedAttributeArray::setUnsafe
void setUnsafe(Index n, const ValueType &value)
Set value at the given index n (assumes in-core)
Definition: AttributeArray.h:1474
openvdb::v7_1::points::AttributeHandle::index
Index index(Index n, Index m) const
Definition: AttributeArray.h:2188
openvdb::v7_1::TypedMetadata
Templated metadata class to hold specific types.
Definition: Metadata.h:122
openvdb::v7_1::points::AttributeWriteHandle::AttributeWriteHandle
AttributeWriteHandle(AttributeArray &array, const bool expand=true)
Definition: AttributeArray.h:2246
openvdb::v7_1::points::TypedAttributeArray::create
static Ptr create(Index n, Index strideOrTotalSize=1, bool constantStride=true, const Metadata *metadata=nullptr)
Return a new attribute array of the given length n and stride with uniform value zero.
Definition: AttributeArray.h:1270
openvdb::v7_1::points::AttributeHandle< Index, openvdb::v7_1::points::StringCodec< false > >::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:852
openvdb::v7_1::points::AttributeArray::write
virtual void write(std::ostream &) const =0
Write attribute metadata and buffers to a stream, don't write transient attributes.
openvdb::v7_1::points::AttributeArray::readMetadata
virtual void readMetadata(std::istream &)=0
Read attribute metadata from a stream.
openvdb::v7_1::points::UnitVecCodec
Definition: AttributeArray.h:543
Types.h
openvdb::v7_1::points::AttributeArray::isHidden
bool isHidden() const
Return true if this attribute is hidden (e.g., from UI or iterators).
Definition: AttributeArray.h:303
openvdb::v7_1::points::AccessorEval< UnknownCodec, ValueType >::set
static void set(SetterPtr functor, AttributeArray *array, const Index n, const ValueType &value)
Setter that calls the supplied functor.
Definition: AttributeArray.h:2107
openvdb::v7_1::points::AttributeArray::AttributeArray
AttributeArray()
Definition: AttributeArray.h:132
openvdb::v7_1::points::TypedAttributeArray::valueTypeSize
Index valueTypeSize() const override
Return the size in bytes of the value type of a single element in this array.
Definition: AttributeArray.h:658
openvdb::v7_1::points::fixedPointToFloatingPoint
FloatVectorT fixedPointToFloatingPoint(const math::Vec3< IntegerT > &v)
Definition: AttributeArray.h:79
openvdb::v7_1::points::UnitRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:521
openvdb::v7_1::TypedMetadata::value
T & value()
Return this metadata's value.
Definition: Metadata.h:249
openvdb::v7_1::io::MappedFile::Ptr
SharedPtr< MappedFile > Ptr
Definition: io.h:136
openvdb::v7_1::points::AttributeArray::operator==
bool operator==(const AttributeArray &other) const
openvdb::v7_1::compression::PagedInputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:219
openvdb::v7_1::points::PositionRange
Definition: AttributeArray.h:510
openvdb::v7_1::points::AttributeHandle::isUniform
bool isUniform() const
Definition: AttributeArray.h:2222
openvdb::v7_1::points::AttributeArray::ConstPtr
std::shared_ptr< const AttributeArray > ConstPtr
Definition: AttributeArray.h:126
openvdb::v7_1::points::AttributeArray::getAccessor
virtual AccessorBasePtr getAccessor() const =0
Obtain an Accessor that stores getter and setter functors.
openvdb::v7_1::points::AttributeArray::valueTypeIsFloatingPoint
virtual bool valueTypeIsFloatingPoint() const =0
Return true if the value type is floating point.
openvdb::v7_1::math::operator==
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:471
openvdb::v7_1::points::attribute_traits::UIntTypeTrait< true, T >::Type
uint8_t Type
Definition: AttributeArray.h:467
openvdb::v7_1::Index
Index32 Index
Definition: Types.h:31
openvdb::v7_1::points::AttributeArray::setHidden
void setHidden(bool state)
Specify whether this attribute should be hidden (e.g., from UI or iterators).
openvdb::v7_1::points::OPENVDB_DEPRECATED
Index OPENVDB_DEPRECATED
Definition: AttributeArrayString.h:33
openvdb::v7_1::points::AttributeHandle::size
Index size() const
Definition: AttributeArray.h:871
openvdb::v7_1::Name
std::string Name
Definition: Name.h:17
openvdb::v7_1::points::AccessorEval< UnknownCodec, ValueType >::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:2098
openvdb::v7_1::points::AttributeArray::isRegistered
static bool isRegistered(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Return true if the given attribute type name is registered.
openvdb::v7_1::points::TypedAttributeArray::ValueType
ValueType_ ValueType
Definition: AttributeArray.h:571
QuantizedUnitVec.h
openvdb::v7_1::points::PositionRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:512
tbb
Definition: Coord.h:16
openvdb::v7_1::points::AttributeArray::dataSize
virtual Index dataSize() const =0
openvdb::v7_1::points::TypedAttributeArray::isUniform
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Definition: AttributeArray.h:716
openvdb::v7_1::points::AttributeWriteHandle::collapse
void collapse(const ValueType &uniformValue)
Definition: AttributeArray.h:2283
openvdb::v7_1::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:102
openvdb::v7_1::points::TypedAttributeArray::valueTypeIsVector
bool valueTypeIsVector() const override
Return true if the value type is a vector.
Definition: AttributeArray.h:1390
openvdb::v7_1::points::floatingPointToFixedPoint
IntegerVectorT floatingPointToFixedPoint(const math::Vec3< FloatT > &v)
Definition: AttributeArray.h:69
openvdb::v7_1::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(const TypedAttributeArray &)
Definition: AttributeArray.h:1208
openvdb::v7_1::points::TypedAttributeArray::registerType
static void registerType()
Register this attribute type along with a factory function.
Definition: AttributeArray.h:1254
openvdb::v7_1::points::AttributeArray::operator!=
bool operator!=(const AttributeArray &other) const
Definition: AttributeArray.h:365
openvdb::v7_1::points::TypedAttributeArray::unregisterType
static void unregisterType()
Remove this attribute type from the registry.
Definition: AttributeArray.h:1262
openvdb::v7_1::points::AttributeArray::Ptr
std::shared_ptr< AttributeArray > Ptr
Definition: AttributeArray.h:125
openvdb::v7_1::points::TypedAttributeArray::copyUncompressed
OPENVDB_DEPRECATED AttributeArray::Ptr copyUncompressed() const override
Definition: AttributeArray.h:1313
openvdb::v7_1::points::AttributeArray::writeBuffers
virtual void writeBuffers(std::ostream &, bool outputTransient) const =0
openvdb::v7_1::points::TypedAttributeArray::readBuffers
void readBuffers(std::istream &) override
Read attribute buffers from a stream.
Definition: AttributeArray.h:1767
openvdb::v7_1::points::AttributeWriteHandle
Write-able version of AttributeHandle.
Definition: AttributeArray.h:920
openvdb::v7_1::io::getDataCompression
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK,...
openvdb::v7_1::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition: AttributeArray.h:2126
openvdb::v7_1::Metadata
Base class for storing metadata information in a grid.
Definition: Metadata.h:24
openvdb::v7_1::points::UnitRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:522
openvdb::v7_1::points::AttributeArray::Accessor::SetterPtr
void(*)(AttributeArray *array, const Index n, const T &value) SetterPtr
Definition: AttributeArray.h:440
openvdb::v7_1::points::AttributeHandle::stride
Index stride() const
Definition: AttributeArray.h:870
openvdb::v7_1::points::PositionRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:513
openvdb::v7_1::VecTraits::ElementType
typename T::ValueType ElementType
Definition: Types.h:185
openvdb::v7_1::points::UnitVecCodec::Storage
Definition: AttributeArray.h:547
openvdb::v7_1::points::AttributeWriteHandle::set
void set(Index n, const ValueType &value)
Definition: AttributeArray.h:2253
openvdb::v7_1::points::AttributeHandle::array
const AttributeArray & array() const
Definition: AttributeArray.h:2181
openvdb::v7_1::Index64
uint64_t Index64
Definition: Types.h:30
openvdb::v7_1::points::AttributeArray::readBuffers
virtual void readBuffers(std::istream &)=0
Read attribute buffers from a stream.
Name.h
openvdb::v7_1::points::AttributeArray::FactoryMethod
Ptr(*)(Index, Index, bool, const Metadata *) FactoryMethod
Definition: AttributeArray.h:128
openvdb::v7_1::points::AttributeArray::Flag
Flag
Definition: AttributeArray.h:101
openvdb::v7_1::IoError
Definition: Exceptions.h:58
openvdb::v7_1::points::AttributeWriteHandle::fill
void fill(const ValueType &value)
Fill the existing array with the given value.
Definition: AttributeArray.h:2289
openvdb::v7_1::points::AttributeArray::clearRegistry
static void clearRegistry(const ScopedRegistryLock *lock=nullptr)
Clear the attribute type registry.
openvdb::v7_1::points::TypedAttributeArray::StorageType
typename Codec::template Storage< ValueType >::Type StorageType
Definition: AttributeArray.h:573
openvdb::v7_1::points::PositionRange::name
static const char * name()
Definition: AttributeArray.h:511
openvdb::v7_1::math::Vec3::y
T & y()
Definition: Vec3.h:84
openvdb::v7_1::points::TypedAttributeArray::~TypedAttributeArray
~TypedAttributeArray() override
Definition: AttributeArray.h:605
openvdb::v7_1::VecTraits
Definition: Types.h:182
openvdb::v7_1::points::attribute_traits::TruncateTrait< float >::Type
half Type
Definition: AttributeArray.h:459
openvdb::v7_1::points::UnitVecCodec::StorageType
uint16_t StorageType
Definition: AttributeArray.h:544
openvdb::v7_1::points::AttributeArray::mFlags
uint8_t mFlags
Definition: AttributeArray.h:415
openvdb::v7_1::points::TypedAttributeArray::getUnsafe
ValueType getUnsafe(Index n) const
Return the value at index n (assumes in-core)
Definition: AttributeArray.h:1425
openvdb::v7_1::compression::PageHandle::Ptr
std::unique_ptr< PageHandle > Ptr
Definition: StreamCompression.h:171
openvdb::v7_1::points::AttributeArray::setTransient
void setTransient(bool state)
Specify whether this attribute should only exist in memory and not be serialized during stream output...
openvdb::v7_1::points::TypedAttributeArray::loadData
void loadData() const override
Ensures all data is in-core.
Definition: AttributeArray.h:1689
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:230
openvdb::v7_1::points::AttributeArray::mIsUniform
bool mIsUniform
Definition: AttributeArray.h:413
openvdb::v7_1::points::TruncateCodec::name
static const char * name()
Definition: AttributeArray.h:504
openvdb::v7_1::points::AttributeHandle::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:888
openvdb::v7_1::points::AttributeArray::mMutex
tbb::spin_mutex mMutex
Definition: AttributeArray.h:414
openvdb::v7_1::points::AttributeArray::copy
virtual AttributeArray::Ptr copy() const =0
Return a copy of this attribute.
openvdb::v7_1::points::TypedAttributeArray::Codec
Codec_ Codec
Definition: AttributeArray.h:572
openvdb::v7_1::points::FixedPointCodec::Storage
Definition: AttributeArray.h:530
openvdb::v7_1::points::AttributeArray::mPageHandle
compression::PageHandle::Ptr mPageHandle
Definition: AttributeArray.h:420
openvdb::v7_1::points::FixedPointCodec
Definition: AttributeArray.h:528
openvdb::v7_1::points::AttributeArray::setStreaming
void setStreaming(bool state)
Specify whether this attribute is to be streamed off disk, in which case, the attributes are collapse...
openvdb::v7_1::points::UnitRange::name
static const char * name()
Definition: AttributeArray.h:520
openvdb::v7_1::points::TypedAttributeArray::memUsage
size_t memUsage() const override
Return the number of bytes of memory used by this attribute.
Definition: AttributeArray.h:1417
openvdb::v7_1::points::AttributeArray::read
virtual void read(std::istream &)=0
Read attribute metadata and buffers from a stream.
openvdb::v7_1::points::TypedAttributeArray::read
void read(std::istream &) override
Read attribute data from a stream.
Definition: AttributeArray.h:1707
openvdb::v7_1::points::TypedAttributeArray::TypedAttributeArray
OPENVDB_DEPRECATED TypedAttributeArray(const TypedAttributeArray &, bool)
openvdb::v7_1::points::AttributeArray::operator=
AttributeArray & operator=(AttributeArray &&)=delete
openvdb::v7_1::points::AttributeHandle::create
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition: AttributeArray.h:2119
openvdb::v7_1::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:408
openvdb::v7_1::points::AttributeArray::valueTypeIsVector
virtual bool valueTypeIsVector() const =0
Return true if the value type is a vector.
openvdb::v7_1::points::AttributeArray::compress
virtual OPENVDB_DEPRECATED bool compress()=0
openvdb::v7_1::points::UnitVecCodec::name
static const char * name()
Definition: AttributeArray.h:551
openvdb::v7_1::compression::bloscDecompress
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
openvdb::v7_1::points::AttributeArray::AccessorBase::~AccessorBase
virtual ~AccessorBase()=default
openvdb::v7_1::math::Vec3::z
T & z()
Definition: Vec3.h:85
openvdb::v7_1::points::AttributeArray::codecType
virtual Name codecType() const =0
Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
openvdb::v7_1::points::AttributeArray::isStreaming
bool isStreaming() const
Return true if this attribute is in streaming mode.
Definition: AttributeArray.h:318
openvdb::v7_1::points::AttributeArray::setConstantStride
void setConstantStride(bool state)
Specify whether this attribute has a constant stride or not.
openvdb::v7_1::points::TypedAttributeArray::isOutOfCore
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
Definition: AttributeArray.h:1657
openvdb::v7_1::compression::PagedOutputStream::getOutputStream
std::ostream & getOutputStream()
Set and get the output stream.
Definition: StreamCompression.h:259
openvdb::v7_1::points::TypedAttributeArray::get
ValueType get(Index n) const
Return the value at index n.
Definition: AttributeArray.h:1437
openvdb::v7_1::points::AttributeArray::copyUncompressed
virtual OPENVDB_DEPRECATED AttributeArray::Ptr copyUncompressed() const =0
openvdb::v7_1::points::NullCodec::Storage::Type
T Type
Definition: AttributeArray.h:489
openvdb::v7_1::Int16
int16_t Int16
Definition: Types.h:32
openvdb::v7_1::points::TypedAttributeArray
Typed class for storing attribute data.
Definition: AttributeArray.h:566
openvdb::v7_1::points::TypedAttributeArray::copy
AttributeArray::Ptr copy() const override
Definition: AttributeArray.h:1302
IndexIterator.h
Index Iterators.
openvdb::v7_1::points::AttributeArray::AttributeArray
AttributeArray(const AttributeArray &rhs)
openvdb::v7_1::points::TypedAttributeArray::collapse
void collapse() override
Replace the existing array with a uniform zero value.
Definition: AttributeArray.h:1578
openvdb::v7_1::points::TypedAttributeArray::writeMetadata
void writeMetadata(std::ostream &os, bool outputTransient, bool paged) const override
Definition: AttributeArray.h:1867
openvdb::v7_1::points::AccessorEval
Accessor to call unsafe get and set methods based on templated Codec and Value.
Definition: AttributeArray.h:2076
openvdb::v7_1::points::AttributeArray::compact
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
openvdb::v7_1::points::TypedAttributeArray::cast
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>
Definition: AttributeArray.h:1282
openvdb::v7_1::points::AccessorEval::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:2078
openvdb::v7_1::points::TypedAttributeArray::compress
OPENVDB_DEPRECATED bool compress() override
Compress the attribute array.
Definition: AttributeArray.h:1633
openvdb::v7_1::points::TypedAttributeArray::valueTypeIsMatrix
bool valueTypeIsMatrix() const override
Return true if the value type is a matrix.
Definition: AttributeArray.h:1407
openvdb::v7_1::points::TypedAttributeArray::storageTypeSize
Index storageTypeSize() const override
Definition: AttributeArray.h:662
openvdb::v7_1::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeHandle &)=default
openvdb::v7_1::points::AttributeArray::Accessor::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:448
openvdb::v7_1::points::attribute_traits::TruncateTrait
Definition: AttributeArray.h:458
openvdb::v7_1::points::NullCodec::name
static const char * name()
Definition: AttributeArray.h:493
openvdb::v7_1::points::AttributeArray::hasValueType
bool hasValueType() const
Return true if this attribute has a value type the same as the template parameter.
Definition: AttributeArray.h:229
openvdb::v7_1::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:321
openvdb::v7_1::points::AttributeHandle::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:887
openvdb::v7_1::points::AttributeArray::size
virtual Index size() const =0
openvdb::v7_1::compression::PagedInputStream::getInputStream
std::istream & getInputStream()
Definition: StreamCompression.h:222
openvdb::v7_1::points::TypedAttributeArray::expand
void expand(bool fill=true) override
Replace the single value storage with an array of length size().
Definition: AttributeArray.h:1540
openvdb::v7_1::points::AttributeHandle::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:885
openvdb::v7_1::points::UnitRange
Definition: AttributeArray.h:519
openvdb::v7_1::points::AttributeWriteHandle::compact
bool compact()
Compact the existing array to become uniform if all values are identical.
Definition: AttributeArray.h:2277
openvdb::v7_1::points::AttributeArray::Accessor::GetterPtr
T(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:439
openvdb::v7_1::points::AttributeArray::write
virtual void write(std::ostream &, bool outputTransient) const =0
openvdb::v7_1::points::AttributeWriteHandle::expand
void expand(bool fill=true)
If this array is uniform, replace it with an array of length size().
Definition: AttributeArray.h:2265
openvdb::v7_1::points::TypedAttributeArray::data
const StorageType * data() const
Definition: AttributeArray.h:789
openvdb::v7_1::points::AttributeWriteHandle::create
static Ptr create(AttributeArray &array, const bool expand=true)
Definition: AttributeArray.h:2239
openvdb::v7_1::points::AttributeArray::memUsage
virtual size_t memUsage() const =0
Return the number of bytes of memory used by this attribute.
openvdb::v7_1::points::UnitVecCodec::Storage::Type
StorageType Type
Definition: AttributeArray.h:547
openvdb::v7_1::points::AttributeWriteHandle< Index, openvdb::v7_1::points::StringCodec< false > >::ScopedPtr
std::unique_ptr< Handle > ScopedPtr
Definition: AttributeArray.h:924
openvdb::v7_1::points::AttributeArray::flags
uint8_t flags() const
Retrieve the attribute array flags.
Definition: AttributeArray.h:324
openvdb::v7_1::points::AttributeArray::decompress
virtual OPENVDB_DEPRECATED bool decompress()=0
openvdb::v7_1::points::AttributeArray::isType
bool isType() const
Return true if this attribute is of the same type as the template parameter.
Definition: AttributeArray.h:225
openvdb::v7_1::points::AttributeArray::ScopedRegistryLock::ScopedRegistryLock
ScopedRegistryLock()
openvdb::v7_1::points::AttributeWriteHandle::array
AttributeArray & array()
Definition: AttributeArray.h:2315
openvdb::v7_1::points::TypedAttributeArray::compact
bool compact() override
Compact the existing array to become uniform if all values are identical.
Definition: AttributeArray.h:1561
openvdb::v7_1::points::AttributeArray::mOutOfCore
tbb::atomic< Index32 > mOutOfCore
Definition: AttributeArray.h:417
openvdb::v7_1::compression::PagedInputStream::createHandle
PageHandle::Ptr createHandle(std::streamsize n)
Creates a PageHandle to access the next.
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:146
openvdb::v7_1::points::TypedAttributeArray::dataSize
Index dataSize() const override
Return the size of the data in this array.
Definition: AttributeArray.h:646
openvdb::v7_1::points::AccessorEval< UnknownCodec, ValueType >::get
static ValueType get(GetterPtr functor, const AttributeArray *array, const Index n)
Getter that calls the supplied functor.
Definition: AttributeArray.h:2102
openvdb::v7_1::points::AttributeArray::Accessor
Definition: AttributeArray.h:96
openvdb::v7_1::points::AttributeArray::writeMetadata
virtual void writeMetadata(std::ostream &, bool outputTransient, bool paged) const =0
openvdb::v7_1::points::TypedAttributeArray::writeBuffers
void writeBuffers(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1926
openvdb::v7_1::compression::PagedInputStream
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition: StreamCompression.h:209
openvdb::v7_1::points::FixedPointCodec::name
static const char * name()
Definition: AttributeArray.h:535
openvdb::v7_1::points::AttributeArray::registerType
static void registerType(const NamePair &type, FactoryMethod, const ScopedRegistryLock *lock=nullptr)
Register a attribute type along with a factory function.
openvdb::v7_1::points::AttributeArray::isUniform
virtual bool isUniform() const =0
Return true if this array is stored as a single uniform value.
openvdb::v7_1::points::AttributeArray::AccessorBase
Accessor base class for AttributeArray storage where type is not available.
Definition: AttributeArray.h:432
openvdb::v7_1::points::AttributeArray::loadData
virtual void loadData() const =0
Ensures all data is in-core.
openvdb::v7_1::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:93
openvdb::v7_1::points::AccessorEval::set
static void set(SetterPtr, AttributeArray *array, const Index n, const ValueType &value)
Definition: AttributeArray.h:2088
openvdb::v7_1::points::AttributeWriteHandle::collapse
void collapse()
Replace the existing array with a uniform value (zero if none provided).
Definition: AttributeArray.h:2271
openvdb::v7_1::points::attribute_traits::TruncateTrait< int >::Type
short Type
Definition: AttributeArray.h:460
openvdb::v7_1::points::AttributeArray::storageTypeSize
virtual Index storageTypeSize() const =0
openvdb::v7_1::points::TypedAttributeArray::isRegistered
static bool isRegistered()
Return true if this attribute type is registered.
Definition: AttributeArray.h:1246
openvdb::v7_1::points::AttributeArray::create
static Ptr create(const NamePair &type, Index length, Index stride=1, bool constantStride=true, const Metadata *metadata=nullptr, const ScopedRegistryLock *lock=nullptr)
openvdb::v7_1::points::TypedAttributeArray::valueTypeIsClass
bool valueTypeIsClass() const override
Return true if the value type is a class (ie vector, matrix or quaternion return true)
Definition: AttributeArray.h:1381
openvdb::v7_1::points::AttributeArray::valueTypeIsQuaternion
virtual bool valueTypeIsQuaternion() const =0
Return true if the value type is a quaternion.
openvdb::v7_1::points::TypedAttributeArray::valueTypeIsFloatingPoint
bool valueTypeIsFloatingPoint() const override
Return true if the value type is floating point.
Definition: AttributeArray.h:1361
openvdb::v7_1::points::TypedAttributeArray::Ptr
std::shared_ptr< TypedAttributeArray > Ptr
Definition: AttributeArray.h:568
openvdb::v7_1::points::AttributeWriteHandle::~AttributeWriteHandle
virtual ~AttributeWriteHandle()=default
openvdb::v7_1::points::TypedAttributeArray::stride
Index stride() const override
Definition: AttributeArray.h:643
openvdb::v7_1::points::AttributeArray::collapse
virtual void collapse()=0
Replace the existing array with a uniform zero value.
logging.h
io.h
openvdb::v7_1::points::TruncateCodec::Storage::Type
typename attribute_traits::TruncateTrait< T >::Type Type
Definition: AttributeArray.h:500
openvdb::v7_1::IndexError
Definition: Exceptions.h:57
openvdb::v7_1::points::AttributeArray::valueTypeSize
virtual Index valueTypeSize() const =0
openvdb::v7_1::points::AttributeWriteHandle::set
void set(Index n, Index m, const ValueType &value)
Definition: AttributeArray.h:2259
openvdb::v7_1::points::TruncateCodec
Definition: AttributeArray.h:498
openvdb::v7_1::points::AttributeArray::Accessor::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:447
openvdb::v7_1::points::TypedAttributeArray::validData
bool validData() const
Verify that data is not out-of-core or in a partially-read state.
Definition: AttributeArray.h:792
openvdb::v7_1::points::AttributeArray::type
virtual const NamePair & type() const =0
Return the name of this attribute's type.
openvdb::v7_1::io::getMappedFilePtr
OPENVDB_API SharedPtr< MappedFile > getMappedFilePtr(std::ios_base &)
Return a shared pointer to the memory-mapped file with which the given stream is associated,...
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:94
openvdb::v7_1::points::AttributeArray::isTransient
bool isTransient() const
Return true if this attribute is not serialized during stream output.
Definition: AttributeArray.h:310
openvdb::v7_1::points::AttributeHandle::~AttributeHandle
virtual ~AttributeHandle()
Definition: AttributeArray.h:2154
openvdb::v7_1::compression::bloscCompress
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
openvdb::v7_1::points::UnknownCodec
Definition: AttributeArray.h:483
openvdb::v7_1::points::AttributeArray::expand
virtual void expand(bool fill=true)=0
If this array is uniform, replace it with an array of length size().
openvdb::v7_1::points::AttributeArray::ScopedRegistryLock
Definition: AttributeArray.h:119
openvdb::v7_1::points::AttributeHandle< Index, openvdb::v7_1::points::StringCodec< false > >::UniquePtr
std::unique_ptr< Handle > UniquePtr
Definition: AttributeArray.h:853
openvdb::v7_1::points::AttributeArray::AttributeArray
AttributeArray(const AttributeArray &rhs, const tbb::spin_mutex::scoped_lock &)
openvdb::v7_1::points::AttributeArray::Accessor::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:446
openvdb::v7_1::points::AttributeArray::mCompressedBytes
size_t mCompressedBytes
Definition: AttributeArray.h:421
openvdb::v7_1::compression::PagedOutputStream::write
PagedOutputStream & write(const char *str, std::streamsize n)
Writes the given.
openvdb::v7_1::points::AttributeHandle< Index, openvdb::v7_1::points::StringCodec< false > >::SetterPtr
void(*)(AttributeArray *array, const Index n, const Index &value) SetterPtr
Definition: AttributeArray.h:857
openvdb::v7_1::points::TypedAttributeArray::attributeType
static const NamePair & attributeType()
Return the name of this attribute's type (includes codec)
Definition: AttributeArray.h:1233
openvdb::v7_1::io::COMPRESS_BLOSC
@ COMPRESS_BLOSC
Definition: Compression.h:56
openvdb::v7_1::points::AttributeHandle::hasConstantStride
bool hasConstantStride() const
Definition: AttributeArray.h:2228
openvdb::v7_1::points::attribute_traits::UIntTypeTrait
Definition: AttributeArray.h:466
openvdb::v7_1::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(TypedAttributeArray &&)=delete
Move assignment operator disabled.
openvdb::v7_1::NamePair
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:39
openvdb::v7_1::points::AttributeArray::Accessor::Accessor
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler)
Definition: AttributeArray.h:443
openvdb::v7_1::points::AttributeArray::valueTypeIsMatrix
virtual bool valueTypeIsMatrix() const =0
Return true if the value type is a matrix.
openvdb::v7_1::points::AttributeArray::Accessor::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:449
openvdb::v7_1::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(Index n=1, Index strideOrTotalSize=1, bool constantStride=true, const ValueType &uniformValue=zeroVal< ValueType >())
Default constructor, always constructs a uniform attribute.
Definition: AttributeArray.h:1149
openvdb::v7_1::ValueError
Definition: Exceptions.h:65
openvdb::v7_1::points::AttributeArray::SerializationFlag
SerializationFlag
Definition: AttributeArray.h:109
openvdb::v7_1::points::TypedAttributeArray::set
void set(Index n, const ValueType &value)
Set value at the given index n.
Definition: AttributeArray.h:1489
openvdb::v7_1::points::AccessorEval::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:2077
openvdb::v7_1::points::AttributeHandle::operator=
AttributeHandle & operator=(const AttributeHandle &)=default
openvdb::v7_1::points::FixedPointCodec::Storage::Type
typename attribute_traits::UIntTypeTrait< OneByte, T >::Type Type
Definition: AttributeArray.h:530
openvdb::v7_1::points::TypedAttributeArray::isDataLoaded
bool isDataLoaded() const override
Return true if all data has been loaded.
Definition: AttributeArray.h:1698
openvdb::v7_1::points::TypedAttributeArray::readPagedBuffers
void readPagedBuffers(compression::PagedInputStream &) override
Read attribute buffers from a paged stream.
Definition: AttributeArray.h:1806
openvdb
Definition: Exceptions.h:13
openvdb::v7_1::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(TypedAttributeArray &&)=delete
Move constructor disabled.
openvdb::v7_1::points::AttributeArray::Accessor::ValuePtr
void(*)(AttributeArray *array, const T &value) ValuePtr
Definition: AttributeArray.h:441
openvdb::v7_1::points::AttributeArray::writePagedBuffers
virtual void writePagedBuffers(compression::PagedOutputStream &, bool outputTransient) const =0
openvdb::v7_1::points::TypedAttributeArray::codecType
Name codecType() const override
Return the name of the codec used by this array (e.g., "trnc" or "fxpt").
Definition: AttributeArray.h:655
openvdb::v7_1::points::AttributeArray::isDataLoaded
virtual bool isDataLoaded() const =0
Return true if all data has been loaded.
openvdb::v7_1::points::AttributeArray::AccessorBasePtr
std::shared_ptr< AccessorBase > AccessorBasePtr
Definition: AttributeArray.h:98
openvdb::v7_1::points::AttributeHandle< Index, openvdb::v7_1::points::StringCodec< false > >::ValuePtr
void(*)(AttributeArray *array, const Index &value) ValuePtr
Definition: AttributeArray.h:858
openvdb::v7_1::points::AttributeHandle::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:886
openvdb::v7_1::points::TypedAttributeArray::data
StorageType * data()
Return the raw data buffer.
Definition: AttributeArray.h:788
openvdb::v7_1::points::attribute_traits::UIntTypeTrait< false, T >::Type
uint16_t Type
Definition: AttributeArray.h:468
openvdb::v7_1::points::AccessorEval::get
static ValueType get(GetterPtr, const AttributeArray *array, const Index n)
Definition: AttributeArray.h:2082
openvdb::v7_1::points::AttributeArray::mUsePagedRead
uint8_t mUsePagedRead
Definition: AttributeArray.h:416
openvdb::v7_1::points::TypedAttributeArray::readMetadata
void readMetadata(std::istream &) override
Read attribute metadata from a stream.
Definition: AttributeArray.h:1716
openvdb::v7_1::compression::PagedOutputStream
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition: StreamCompression.h:246
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
openvdb::v7_1::points::AccessorEval< UnknownCodec, ValueType >::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:2099
openvdb::v7_1::compression::PagedInputStream::read
void read(PageHandle::Ptr &pageHandle, std::streamsize n, bool delayed=true)
Takes a pageHandle and updates the referenced page with the current stream pointer position and if de...
openvdb::v7_1::compression::bloscCompressedSize
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
openvdb::v7_1::points::AttributeArray::unregisterType
static void unregisterType(const NamePair &type, const ScopedRegistryLock *lock=nullptr)
Remove a attribute type from the registry.
openvdb::v7_1::points::TypedAttributeArray::write
void write(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1858
openvdb::v7_1::points::AttributeArray::valueTypeIsClass
virtual bool valueTypeIsClass() const =0
Return true if the value type is a class (ie vector, matrix or quaternion return true)
openvdb::v7_1::points::NullCodec
Definition: AttributeArray.h:487
openvdb::v7_1::points::AttributeArray::set
virtual OPENVDB_DEPRECATED void set(const Index n, const AttributeArray &sourceArray, const Index sourceIndex)=0
Set value at given index n from sourceIndex of another sourceArray.
openvdb::v7_1::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:106
openvdb::v7_1::TypeError
Definition: Exceptions.h:64
openvdb::v7_1::points::TypedAttributeArray::decompress
OPENVDB_DEPRECATED bool decompress() override
Uncompress the attribute array.
Definition: AttributeArray.h:1649
openvdb::v7_1::points::TypedAttributeArray::writePagedBuffers
void writePagedBuffers(compression::PagedOutputStream &os, bool outputTransient) const override
Definition: AttributeArray.h:1968
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253