OpenVDB: AttributeArray.h Source File

OpenVDB 6.1.0

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