OpenVDB: AttributeArray.h Source File

OpenVDB 8.1.0

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