OpenVDB: AttributeArray.h Source File

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