OpenVDB: AttributeArray.h Source File

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