OpenVDB: AttributeArray.h Source File

OpenVDB 4.0.2

AttributeArray.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 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 };
134
135 enum SerializationFlag {
136 WRITESTRIDED = 0x1,
137 WRITEUNIFORM = 0x2,
138 WRITEMEMCOMPRESS = 0x4,
139 WRITEPAGED = 0x8
140 };
141
142 using Ptr = std::shared_ptr<AttributeArray>;
143 using ConstPtr = std::shared_ptr<const AttributeArray>;
144
145 using FactoryMethod = Ptr (*)(Index, Index, bool);
146
147 template <typename ValueType, typename CodecType> friend class AttributeHandle;
148
149 AttributeArray() = default;
150 AttributeArray(const AttributeArray&) = default;
151 AttributeArray& operator=(const AttributeArray&) = default;
152 virtual ~AttributeArray() = default;
153
155 virtual AttributeArray::Ptr copy() const = 0;
156
158 virtual AttributeArray::Ptr copyUncompressed() const = 0;
159
162 virtual Index size() const = 0;
163
166 virtual Index stride() const = 0;
167
170 virtual Index dataSize() const = 0;
171
173 virtual size_t memUsage() const = 0;
174
176 static Ptr create(const NamePair& type, Index length, Index stride = 1, bool constantStride = true);
178 static bool isRegistered(const NamePair& type);
180 static void clearRegistry();
181
183 virtual const NamePair& type() const = 0;
185 template<typename AttributeArrayType>
186 bool isType() const { return this->type() == AttributeArrayType::attributeType(); }
187
189 template<typename ValueType>
190 bool hasValueType() const { return this->type().first == typeNameAsString<ValueType>(); }
191
193 virtual void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) = 0;
194
196 virtual bool isUniform() const = 0;
199 virtual void expand(bool fill = true) = 0;
201 virtual void collapse() = 0;
203 virtual bool compact() = 0;
204
206 bool isCompressed() const { return mCompressedBytes != 0; }
208 virtual bool compress() = 0;
210 virtual bool decompress() = 0;
211
216 void setHidden(bool state);
218 bool isHidden() const { return bool(mFlags & HIDDEN); }
219
223 void setTransient(bool state);
225 bool isTransient() const { return bool(mFlags & TRANSIENT); }
226
231 void setStreaming(bool state);
233 bool isStreaming() const { return bool(mFlags & STREAMING); }
234
236 bool hasConstantStride() const { return bool(mFlags & CONSTANTSTRIDE); }
237
239 uint8_t flags() const { return mFlags; }
240
242 virtual void read(std::istream&) = 0;
245 virtual void write(std::ostream&, bool outputTransient) const = 0;
247 virtual void write(std::ostream&) const = 0;
248
250 virtual void readMetadata(std::istream&) = 0;
254 virtual void writeMetadata(std::ostream&, bool outputTransient, bool paged) const = 0;
255
257 virtual void readBuffers(std::istream&) = 0;
260 virtual void writeBuffers(std::ostream&, bool outputTransient) const = 0;
261
263 virtual void readPagedBuffers(compression::PagedInputStream&) = 0;
266 virtual void writePagedBuffers(compression::PagedOutputStream&, bool outputTransient) const = 0;
267
269 virtual void loadData() const = 0;
270
274 bool operator==(const AttributeArray& other) const;
275 bool operator!=(const AttributeArray& other) const { return !this->operator==(other); }
276
277 private:
278 friend class ::TestAttributeArray;
279
282 virtual bool isEqual(const AttributeArray& other) const = 0;
283
284 protected:
286 void setConstantStride(bool state);
287
289 virtual AccessorBasePtr getAccessor() const = 0;
290
292 static void registerType(const NamePair& type, FactoryMethod);
294 static void unregisterType(const NamePair& type);
295
296 size_t mCompressedBytes = 0;
297 uint8_t mFlags = 0;
298 uint8_t mSerializationFlags = 0;
299
301 compression::PageHandle::Ptr mPageHandle;
302 }; // class AttributeArray
303
304
306
307
309 struct AttributeArray::AccessorBase { virtual ~AccessorBase() = default; };
310
313 template <typename T>
314 struct AttributeArray::Accessor : public AttributeArray::AccessorBase
315 {
316 using GetterPtr = T (*)(const AttributeArray* array, const Index n);
317 using SetterPtr = void (*)(AttributeArray* array, const Index n, const T& value);
318 using ValuePtr = void (*)(AttributeArray* array, const T& value);
319
320 Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler) :
321 mGetter(getter), mSetter(setter), mCollapser(collapser), mFiller(filler) { }
322
323 GetterPtr mGetter;
324 SetterPtr mSetter;
325 ValuePtr mCollapser;
326 ValuePtr mFiller;
327 }; // struct AttributeArray::Accessor
328
329
331
332
333 namespace attribute_traits
334 {
335 template <typename T> struct TruncateTrait { };
336 template <> struct TruncateTrait<float> { using Type = half; };
337 template <> struct TruncateTrait<int> { using Type = short; };
338
339 template <typename T> struct TruncateTrait<math::Vec3<T>> {
340 using Type = math::Vec3<typename TruncateTrait<T>::Type>;
341 };
342
343 template <bool OneByte, typename T> struct UIntTypeTrait { };
344 template<typename T> struct UIntTypeTrait</*OneByte=*/true, T> { using Type = uint8_t; };
345 template<typename T> struct UIntTypeTrait</*OneByte=*/false, T> { using Type = uint16_t; };
346 template<typename T> struct UIntTypeTrait</*OneByte=*/true, math::Vec3<T>> {
347 using Type = math::Vec3<uint8_t>;
348 };
349 template<typename T> struct UIntTypeTrait</*OneByte=*/false, math::Vec3<T>> {
350 using Type = math::Vec3<uint16_t>;
351 };
352 }
353
354
356
357
358 // Attribute codec schemes
359
360 struct UnknownCodec { };
361
362
363 struct NullCodec
364 {
365 template <typename T>
366 struct Storage { using Type = T; };
367
368 template<typename ValueType> static void decode(const ValueType&, ValueType&);
369 template<typename ValueType> static void encode(const ValueType&, ValueType&);
370 static const char* name() { return "null"; }
371 };
372
373
374 struct TruncateCodec
375 {
376 template <typename T>
377 struct Storage { using Type = typename attribute_traits::TruncateTrait<T>::Type; };
378
379 template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
380 template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
381 static const char* name() { return "trnc"; }
382 };
383
384
385 // Fixed-point codec range for voxel-space positions [-0.5,0.5]
386 struct PositionRange
387 {
388 static const char* name() { return "fxpt"; }
389 template <typename ValueType> static ValueType encode(const ValueType& value) { return value + ValueType(0.5); }
390 template <typename ValueType> static ValueType decode(const ValueType& value) { return value - ValueType(0.5); }
391 };
392
393
394 // Fixed-point codec range for unsigned values in the unit range [0.0,1.0]
395 struct UnitRange
396 {
397 static const char* name() { return "ufxpt"; }
398 template <typename ValueType> static ValueType encode(const ValueType& value) { return value; }
399 template <typename ValueType> static ValueType decode(const ValueType& value) { return value; }
400 };
401
402
403 template <bool OneByte, typename Range=PositionRange>
404 struct FixedPointCodec
405 {
406 template <typename T>
407 struct Storage { using Type = typename attribute_traits::UIntTypeTrait<OneByte, T>::Type; };
408
409 template<typename StorageType, typename ValueType> static void decode(const StorageType&, ValueType&);
410 template<typename StorageType, typename ValueType> static void encode(const ValueType&, StorageType&);
411
412 static const char* name() {
413 static const std::string Name = std::string(Range::name()) + (OneByte ? "8" : "16");
414 return Name.c_str();
415 }
416 };
417
418
419 struct UnitVecCodec
420 {
421 using StorageType = uint16_t;
422
423 template <typename T>
424 struct Storage { using Type = StorageType; };
425
426 template<typename T> static void decode(const StorageType&, math::Vec3<T>&);
427 template<typename T> static void encode(const math::Vec3<T>&, StorageType&);
428 static const char* name() { return "uvec"; }
429 };
430
431
433
434
436 template<typename ValueType_, typename Codec_ = NullCodec>
437 class TypedAttributeArray: public AttributeArray
438 {
439 public:
440 using Ptr = std::shared_ptr<TypedAttributeArray>;
441 using ConstPtr = std::shared_ptr<const TypedAttributeArray>;
442
443 using ValueType = ValueType_;
444 using Codec = Codec_;
445 using StorageType = typename Codec::template Storage<ValueType>::Type;
446
448
450 explicit TypedAttributeArray(Index n = 1, Index strideOrTotalSize = 1, bool constantStride = true,
451 const ValueType& uniformValue = zeroVal<ValueType>());
453 TypedAttributeArray(const TypedAttributeArray&, bool uncompress = false);
455 TypedAttributeArray& operator=(const TypedAttributeArray&);
457 TypedAttributeArray(TypedAttributeArray&&) = delete;
459 TypedAttributeArray& operator=(TypedAttributeArray&&) = delete;
460
461 virtual ~TypedAttributeArray() { this->deallocate(); }
462
464 AttributeArray::Ptr copy() const override;
465
467 AttributeArray::Ptr copyUncompressed() const override;
468
470 static Ptr create(Index n, Index strideOrTotalSize = 1, bool constantStride = true);
471
473 static TypedAttributeArray& cast(AttributeArray& attributeArray);
474
476 static const TypedAttributeArray& cast(const AttributeArray& attributeArray);
477
479 static const NamePair& attributeType();
481 const NamePair& type() const override { return attributeType(); }
482
484 static bool isRegistered();
486 static void registerType();
488 static void unregisterType();
489
491 Index size() const override { return mSize; }
492
495 Index stride() const override { return hasConstantStride() ? mStrideOrTotalSize : 0; }
496
498 Index dataSize() const override {
499 return hasConstantStride() ? mSize * mStrideOrTotalSize : mStrideOrTotalSize;
500 }
501
503 size_t memUsage() const override;
504
506 ValueType getUnsafe(Index n) const;
508 ValueType get(Index n) const;
510 template<typename T> void getUnsafe(Index n, T& value) const;
512 template<typename T> void get(Index n, T& value) const;
513
516 static ValueType getUnsafe(const AttributeArray* array, const Index n);
517
519 void setUnsafe(Index n, const ValueType& value);
521 void set(Index n, const ValueType& value);
523 template<typename T> void setUnsafe(Index n, const T& value);
525 template<typename T> void set(Index n, const T& value);
526
529 static void setUnsafe(AttributeArray* array, const Index n, const ValueType& value);
530
532 void set(const Index n, const AttributeArray& sourceArray, const Index sourceIndex) override;
533
535 bool isUniform() const override { return mIsUniform; }
539 void expand(bool fill = true) override;
541 void collapse() override;
543 bool compact() override;
544
546 void collapse(const ValueType& uniformValue);
549 void fill(const ValueType& value);
550
552 static void collapse(AttributeArray* array, const ValueType& value);
554 static void fill(AttributeArray* array, const ValueType& value);
555
557 bool compress() override;
559 bool decompress() override;
560
562 void read(std::istream&) override;
566 void write(std::ostream& os, bool outputTransient) const override;
568 void write(std::ostream&) const override;
569
571 void readMetadata(std::istream&) override;
576 void writeMetadata(std::ostream& os, bool outputTransient, bool paged) const override;
577
579 void readBuffers(std::istream&) override;
583 void writeBuffers(std::ostream& os, bool outputTransient) const override;
584
586 void readPagedBuffers(compression::PagedInputStream&) override;
590 void writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const override;
591
593 inline bool isOutOfCore() const;
594
596 void loadData() const override;
597
598 protected:
599 AccessorBasePtr getAccessor() const override;
600
601 private:
603 inline void doLoad() const;
606 inline void doLoadUnsafe(const bool compression = true) const;
608 inline bool compressUnsafe();
609
611 inline void setOutOfCore(const bool);
612
614 bool isEqual(const AttributeArray& other) const override;
615
616 size_t arrayMemUsage() const;
617 void allocate();
618 void deallocate();
619
621 static AttributeArray::Ptr factory(Index n, Index strideOrTotalSize, bool constantStride) {
622 return TypedAttributeArray::create(n, strideOrTotalSize, constantStride);
623 }
624
625 static tbb::atomic<const NamePair*> sTypeName;
626 std::unique_ptr<StorageType[]> mData;
627 Index mSize;
628 Index mStrideOrTotalSize;
629 bool mIsUniform = false;
630 tbb::spin_mutex mMutex;
631 }; // class TypedAttributeArray
632
633
635
636
639 template <typename ValueType, typename CodecType = UnknownCodec>
640 class AttributeHandle
641 {
642 public:
643 using Handle = AttributeHandle<ValueType, CodecType>;
644 using Ptr = std::shared_ptr<Handle>;
645 using UniquePtr = std::unique_ptr<Handle>;
646
647 protected:
648 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
649 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
650 using ValuePtr = void (*)(AttributeArray* array, const ValueType& value);
651
652 public:
653 static Ptr create(const AttributeArray& array, const bool preserveCompression = true);
654
655 AttributeHandle(const AttributeArray& array, const bool preserveCompression = true);
656
657 AttributeHandle(const AttributeHandle&) = default;
658 AttributeHandle& operator=(const AttributeHandle&) = default;
659
660 virtual ~AttributeHandle();
661
662 Index stride() const { return mStrideOrTotalSize; }
663 Index size() const { return mSize; }
664
665 bool isUniform() const;
666 bool hasConstantStride() const;
667
668 ValueType get(Index n, Index m = 0) const;
669
670 protected:
671 Index index(Index n, Index m) const;
672
673 const AttributeArray* mArray;
674
675 GetterPtr mGetter;
676 SetterPtr mSetter;
677 ValuePtr mCollapser;
678 ValuePtr mFiller;
679
680 private:
681 friend class ::TestAttributeArray;
682
683 template <bool IsUnknownCodec>
684 typename std::enable_if<IsUnknownCodec, bool>::type compatibleType() const;
685
686 template <bool IsUnknownCodec>
687 typename std::enable_if<!IsUnknownCodec, bool>::type compatibleType() const;
688
689 template <bool IsUnknownCodec>
690 typename std::enable_if<IsUnknownCodec, ValueType>::type get(Index index) const;
691
692 template <bool IsUnknownCodec>
693 typename std::enable_if<!IsUnknownCodec, ValueType>::type get(Index index) const;
694
695 // local copy of AttributeArray (to preserve compression)
696 AttributeArray::Ptr mLocalArray;
697
698 Index mStrideOrTotalSize;
699 Index mSize;
700 bool mCollapseOnDestruction;
701 }; // class AttributeHandle
702
703
705
706
708 template <typename ValueType, typename CodecType = UnknownCodec>
709 class AttributeWriteHandle : public AttributeHandle<ValueType, CodecType>
710 {
711 public:
712 using Handle = AttributeWriteHandle<ValueType, CodecType>;
713 using Ptr = std::shared_ptr<Handle>;
714 using ScopedPtr = std::unique_ptr<Handle>;
715
716 static Ptr create(AttributeArray& array, const bool expand = true);
717
718 AttributeWriteHandle(AttributeArray& array, const bool expand = true);
719
720 virtual ~AttributeWriteHandle() = default;
721
724 void expand(bool fill = true);
725
727 void collapse();
728 void collapse(const ValueType& uniformValue);
729
731 bool compact();
732
735 void fill(const ValueType& value);
736
737 void set(Index n, const ValueType& value);
738 void set(Index n, Index m, const ValueType& value);
739
740 private:
741 friend class ::TestAttributeArray;
742
743 template <bool IsUnknownCodec>
744 typename std::enable_if<IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
745
746 template <bool IsUnknownCodec>
747 typename std::enable_if<!IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
748 }; // class AttributeWriteHandle
749
750
752
753
754 // Attribute codec implementation
755
756
757 template<typename ValueType>
758 inline void
759 NullCodec::decode(const ValueType& data, ValueType& val)
760 {
761 val = data;
762 }
763
764
765 template<typename ValueType>
766 inline void
767 NullCodec::encode(const ValueType& val, ValueType& data)
768 {
769 data = val;
770 }
771
772
773 template<typename StorageType, typename ValueType>
774 inline void
775 TruncateCodec::decode(const StorageType& data, ValueType& val)
776 {
777 val = static_cast<ValueType>(data);
778 }
779
780
781 template<typename StorageType, typename ValueType>
782 inline void
783 TruncateCodec::encode(const ValueType& val, StorageType& data)
784 {
785 data = static_cast<StorageType>(val);
786 }
787
788
789 template <bool OneByte, typename Range>
790 template<typename StorageType, typename ValueType>
791 inline void
792 FixedPointCodec<OneByte, Range>::decode(const StorageType& data, ValueType& val)
793 {
794 val = fixedPointToFloatingPoint<ValueType>(data);
795
796 // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
797
798 val = Range::template decode<ValueType>(val);
799 }
800
801
802 template <bool OneByte, typename Range>
803 template<typename StorageType, typename ValueType>
804 inline void
805 FixedPointCodec<OneByte, Range>::encode(const ValueType& val, StorageType& data)
806 {
807 // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
808
809 const ValueType newVal = Range::template encode<ValueType>(val);
810
811 data = floatingPointToFixedPoint<StorageType>(newVal);
812 }
813
814
815 template<typename T>
816 inline void
817 UnitVecCodec::decode(const StorageType& data, math::Vec3<T>& val)
818 {
819 val = math::QuantizedUnitVec::unpack(data);
820 }
821
822
823 template<typename T>
824 inline void
825 UnitVecCodec::encode(const math::Vec3<T>& val, StorageType& data)
826 {
827 data = math::QuantizedUnitVec::pack(val);
828 }
829
830
832
833 // TypedAttributeArray implementation
834
835 template<typename ValueType_, typename Codec_>
836 tbb::atomic<const NamePair*> TypedAttributeArray<ValueType_, Codec_>::sTypeName;
837
838
839 template<typename ValueType_, typename Codec_>
840 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(
841 Index n, Index strideOrTotalSize, bool constantStride, const ValueType& uniformValue)
842 : mData(new StorageType[1])
843 , mSize(n)
844 , mStrideOrTotalSize(strideOrTotalSize)
845 , mIsUniform(true)
846 {
847 if (constantStride) {
848 this->setConstantStride(true);
849 if (strideOrTotalSize == 0) {
850 OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a constant stride requires that " \
851 "stride to be at least one.")
852 }
853 }
854 else {
855 this->setConstantStride(false);
856 if (mStrideOrTotalSize < n) {
857 OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a non-constant stride must have " \
858 "a total size of at least the number of elements in the array.")
859 }
860 }
861 mSize = std::max(Index(1), mSize);
862 mStrideOrTotalSize = std::max(Index(1), mStrideOrTotalSize);
863 Codec::encode(uniformValue, mData.get()[0]);
864 }
865
866
867 template<typename ValueType_, typename Codec_>
868 TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray(const TypedAttributeArray& rhs, bool uncompress)
869 : AttributeArray(rhs)
870 , mSize(rhs.mSize)
871 , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
872 , mIsUniform(rhs.mIsUniform)
873 {
874 // disable uncompress if data is not compressed
875
876 if (!this->isCompressed()) uncompress = false;
877
878 if (this->isOutOfCore()) {
879 // do nothing
880 } else if (mIsUniform) {
881 this->allocate();
882 mData.get()[0] = rhs.mData.get()[0];
883 } else if (this->isCompressed()) {
884 std::unique_ptr<char[]> buffer;
885 if (uncompress) {
886 const char* charBuffer = reinterpret_cast<const char*>(rhs.mData.get());
887 size_t uncompressedBytes = compression::bloscUncompressedSize(charBuffer);
888 buffer = compression::bloscDecompress(charBuffer, uncompressedBytes);
889 }
890 if (buffer) {
891 mCompressedBytes = 0;
892 } else {
893 // decompression wasn't requested or failed so deep copy instead
894 buffer.reset(new char[mCompressedBytes]);
895 std::memcpy(buffer.get(), rhs.mData.get(), mCompressedBytes);
896 }
897 assert(buffer);
898 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
899 } else {
900 this->allocate();
901 std::memcpy(mData.get(), rhs.mData.get(), this->arrayMemUsage());
902 }
903 }
904
905
906 template<typename ValueType_, typename Codec_>
907 typename TypedAttributeArray<ValueType_, Codec_>::TypedAttributeArray&
908 TypedAttributeArray<ValueType_, Codec_>::operator=(const TypedAttributeArray& rhs)
909 {
910 if (&rhs != this) {
911 tbb::spin_mutex::scoped_lock lock(mMutex);
912
913 this->deallocate();
914
915 mFlags = rhs.mFlags;
916 mSerializationFlags = rhs.mSerializationFlags;
917 mCompressedBytes = rhs.mCompressedBytes;
918 mSize = rhs.mSize;
919 mStrideOrTotalSize = rhs.mStrideOrTotalSize;
920 mIsUniform = rhs.mIsUniform;
921
922 if (rhs.isOutOfCore()) {
923 mPageHandle = rhs.mPageHandle;
924 } else if (mIsUniform) {
925 this->allocate();
926 mData.get()[0] = rhs.mData.get()[0];
927 } else if (this->isCompressed()) {
928 std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
929 std::memcpy(buffer.get(), rhs.mData.get(), mCompressedBytes);
930 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
931 } else {
932 this->allocate();
933 std::memcpy(mData.get(), rhs.mData.get(), arrayMemUsage());
934 }
935 }
936 }
937
938
939 template<typename ValueType_, typename Codec_>
940 inline const NamePair&
941 TypedAttributeArray<ValueType_, Codec_>::attributeType()
942 {
943 if (sTypeName == nullptr) {
944 NamePair* s = new NamePair(typeNameAsString<ValueType>(), Codec::name());
945 if (sTypeName.compare_and_swap(s, nullptr) != nullptr) delete s;
946 }
947 return *sTypeName;
948 }
949
950
951 template<typename ValueType_, typename Codec_>
952 inline bool
953 TypedAttributeArray<ValueType_, Codec_>::isRegistered()
954 {
955 return AttributeArray::isRegistered(TypedAttributeArray::attributeType());
956 }
957
958
959 template<typename ValueType_, typename Codec_>
960 inline void
961 TypedAttributeArray<ValueType_, Codec_>::registerType()
962 {
963 AttributeArray::registerType(TypedAttributeArray::attributeType(), TypedAttributeArray::factory);
964 }
965
966
967 template<typename ValueType_, typename Codec_>
968 inline void
969 TypedAttributeArray<ValueType_, Codec_>::unregisterType()
970 {
971 AttributeArray::unregisterType(TypedAttributeArray::attributeType());
972 }
973
974
975 template<typename ValueType_, typename Codec_>
976 inline typename TypedAttributeArray<ValueType_, Codec_>::Ptr
977 TypedAttributeArray<ValueType_, Codec_>::create(Index n, Index stride, bool constantStride)
978 {
979 return Ptr(new TypedAttributeArray(n, stride, constantStride));
980 }
981
982 template<typename ValueType_, typename Codec_>
983 inline TypedAttributeArray<ValueType_, Codec_>&
984 TypedAttributeArray<ValueType_, Codec_>::cast(AttributeArray& attributeArray)
985 {
986 if (!attributeArray.isType<TypedAttributeArray>()) {
987 OPENVDB_THROW(TypeError, "Invalid Attribute Type");
988 }
989 return static_cast<TypedAttributeArray&>(attributeArray);
990 }
991
992 template<typename ValueType_, typename Codec_>
993 inline const TypedAttributeArray<ValueType_, Codec_>&
994 TypedAttributeArray<ValueType_, Codec_>::cast(const AttributeArray& attributeArray)
995 {
996 if (!attributeArray.isType<TypedAttributeArray>()) {
997 OPENVDB_THROW(TypeError, "Invalid Attribute Type");
998 }
999 return static_cast<const TypedAttributeArray&>(attributeArray);
1000 }
1001
1002 template<typename ValueType_, typename Codec_>
1003 AttributeArray::Ptr
1004 TypedAttributeArray<ValueType_, Codec_>::copy() const
1005 {
1006 return AttributeArray::Ptr(new TypedAttributeArray<ValueType, Codec>(*this));
1007 }
1008
1009
1010 template<typename ValueType_, typename Codec_>
1011 AttributeArray::Ptr
1012 TypedAttributeArray<ValueType_, Codec_>::copyUncompressed() const
1013 {
1014 return AttributeArray::Ptr(new TypedAttributeArray<ValueType, Codec>(*this, /*decompress = */true));
1015 }
1016
1017
1018 template<typename ValueType_, typename Codec_>
1019 size_t
1020 TypedAttributeArray<ValueType_, Codec_>::arrayMemUsage() const
1021 {
1022 if (this->isOutOfCore()) return 0;
1023 if (this->isCompressed()) return mCompressedBytes;
1024
1025 return (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType);
1026 }
1027
1028
1029 template<typename ValueType_, typename Codec_>
1030 void
1031 TypedAttributeArray<ValueType_, Codec_>::allocate()
1032 {
1033 assert(!mData);
1034 if (mIsUniform) {
1035 mData.reset(new StorageType[1]);
1036 }
1037 else {
1038 const size_t size(this->dataSize());
1039 assert(size > 0);
1040 mData.reset(new StorageType[size]);
1041 }
1042 }
1043
1044
1045 template<typename ValueType_, typename Codec_>
1046 void
1047 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1048 {
1049 // detach from file if delay-loaded
1050 if (this->isOutOfCore()) {
1051 this->setOutOfCore(false);
1052 this->mPageHandle.reset();
1053 }
1054 if (mData) mData.reset();
1055 }
1056
1057
1058 template<typename ValueType_, typename Codec_>
1059 size_t
1060 TypedAttributeArray<ValueType_, Codec_>::memUsage() const
1061 {
1062 return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1063 }
1064
1065
1066 template<typename ValueType_, typename Codec_>
1067 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1068 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n) const
1069 {
1070 assert(n < this->dataSize());
1071 assert(!this->isOutOfCore());
1072 assert(!this->isCompressed());
1073
1074 ValueType val;
1075 Codec::decode(/*in=*/mData.get()[mIsUniform ? 0 : n], /*out=*/val);
1076 return val;
1077 }
1078
1079
1080 template<typename ValueType_, typename Codec_>
1081 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1082 TypedAttributeArray<ValueType_, Codec_>::get(Index n) const
1083 {
1084 if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1085 if (this->isOutOfCore()) this->doLoad();
1086 if (this->isCompressed()) const_cast<TypedAttributeArray*>(this)->decompress();
1087
1088 return this->getUnsafe(n);
1089 }
1090
1091
1092 template<typename ValueType_, typename Codec_>
1093 template<typename T>
1094 void
1095 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(Index n, T& val) const
1096 {
1097 val = static_cast<T>(this->getUnsafe(n));
1098 }
1099
1100
1101 template<typename ValueType_, typename Codec_>
1102 template<typename T>
1103 void
1104 TypedAttributeArray<ValueType_, Codec_>::get(Index n, T& val) const
1105 {
1106 val = static_cast<T>(this->get(n));
1107 }
1108
1109
1110 template<typename ValueType_, typename Codec_>
1111 typename TypedAttributeArray<ValueType_, Codec_>::ValueType
1112 TypedAttributeArray<ValueType_, Codec_>::getUnsafe(const AttributeArray* array, const Index n)
1113 {
1114 return static_cast<const TypedAttributeArray<ValueType, Codec>*>(array)->getUnsafe(n);
1115 }
1116
1117
1118 template<typename ValueType_, typename Codec_>
1119 void
1120 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const ValueType& val)
1121 {
1122 assert(n < this->dataSize());
1123 assert(!this->isOutOfCore());
1124 assert(!this->isCompressed());
1125 assert(!this->isUniform());
1126
1127 // this unsafe method assumes the data is not uniform, however if it is, this redirects the index
1128 // to zero, which is marginally less efficient but ensures not writing to an illegal address
1129
1130 Codec::encode(/*in=*/val, /*out=*/mData.get()[mIsUniform ? 0 : n]);
1131 }
1132
1133
1134 template<typename ValueType_, typename Codec_>
1135 void
1136 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const ValueType& val)
1137 {
1138 if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1139 if (this->isOutOfCore()) this->doLoad();
1140 if (this->isCompressed()) this->decompress();
1141 if (this->isUniform()) this->expand();
1142
1143 this->setUnsafe(n, val);
1144 }
1145
1146
1147 template<typename ValueType_, typename Codec_>
1148 template<typename T>
1149 void
1150 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(Index n, const T& val)
1151 {
1152 this->setUnsafe(n, static_cast<ValueType>(val));
1153 }
1154
1155
1156 template<typename ValueType_, typename Codec_>
1157 template<typename T>
1158 void
1159 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const T& val)
1160 {
1161 this->set(n, static_cast<ValueType>(val));
1162 }
1163
1164
1165 template<typename ValueType_, typename Codec_>
1166 void
1167 TypedAttributeArray<ValueType_, Codec_>::setUnsafe(AttributeArray* array, const Index n, const ValueType& value)
1168 {
1169 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->setUnsafe(n, value);
1170 }
1171
1172
1173 template<typename ValueType_, typename Codec_>
1174 void
1175 TypedAttributeArray<ValueType_, Codec_>::set(Index n, const AttributeArray& sourceArray, const Index sourceIndex)
1176 {
1177 const TypedAttributeArray& sourceTypedArray = static_cast<const TypedAttributeArray&>(sourceArray);
1178
1179 ValueType sourceValue;
1180 sourceTypedArray.get(sourceIndex, sourceValue);
1181
1182 this->set(n, sourceValue);
1183 }
1184
1185
1186 template<typename ValueType_, typename Codec_>
1187 void
1188 TypedAttributeArray<ValueType_, Codec_>::expand(bool fill)
1189 {
1190 if (!mIsUniform) return;
1191
1192 const StorageType val = mData.get()[0];
1193
1194 {
1195 tbb::spin_mutex::scoped_lock lock(mMutex);
1196 this->deallocate();
1197 mIsUniform = false;
1198 this->allocate();
1199 }
1200
1201 mCompressedBytes = 0;
1202
1203 if (fill) {
1204 for (Index i = 0; i < this->dataSize(); ++i) mData.get()[i] = val;
1205 }
1206 }
1207
1208
1209 template<typename ValueType_, typename Codec_>
1210 bool
1211 TypedAttributeArray<ValueType_, Codec_>::compact()
1212 {
1213 if (mIsUniform) return true;
1214
1215 // compaction is not possible if any values are different
1216 const ValueType_ val = this->get(0);
1217 for (Index i = 1; i < this->dataSize(); i++) {
1218 if (!math::isExactlyEqual(this->get(i), val)) return false;
1219 }
1220
1221 this->collapse(this->get(0));
1222 return true;
1223 }
1224
1225
1226 template<typename ValueType_, typename Codec_>
1227 void
1228 TypedAttributeArray<ValueType_, Codec_>::collapse()
1229 {
1230 this->collapse(zeroVal<ValueType>());
1231 }
1232
1233
1234 template<typename ValueType_, typename Codec_>
1235 void
1236 TypedAttributeArray<ValueType_, Codec_>::collapse(const ValueType& uniformValue)
1237 {
1238 if (!mIsUniform) {
1239 tbb::spin_mutex::scoped_lock lock(mMutex);
1240 this->deallocate();
1241 mIsUniform = true;
1242 this->allocate();
1243 }
1244 Codec::encode(uniformValue, mData.get()[0]);
1245 }
1246
1247
1248 template<typename ValueType_, typename Codec_>
1249 void
1250 TypedAttributeArray<ValueType_, Codec_>::collapse(AttributeArray* array, const ValueType& value)
1251 {
1252 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->collapse(value);
1253 }
1254
1255
1256 template<typename ValueType_, typename Codec_>
1257 void
1258 TypedAttributeArray<ValueType_, Codec_>::fill(const ValueType& value)
1259 {
1260 if (this->isOutOfCore()) {
1261 tbb::spin_mutex::scoped_lock lock(mMutex);
1262 this->deallocate();
1263 this->allocate();
1264 }
1265
1266 const Index size = mIsUniform ? 1 : this->dataSize();
1267 for (Index i = 0; i < size; ++i) {
1268 Codec::encode(value, mData.get()[i]);
1269 }
1270 }
1271
1272
1273 template<typename ValueType_, typename Codec_>
1274 void
1275 TypedAttributeArray<ValueType_, Codec_>::fill(AttributeArray* array, const ValueType& value)
1276 {
1277 static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->fill(value);
1278 }
1279
1280
1281 template<typename ValueType_, typename Codec_>
1282 inline bool
1283 TypedAttributeArray<ValueType_, Codec_>::compress()
1284 {
1285 if (!compression::bloscCanCompress()) return false;
1286
1287 if (!mIsUniform && !this->isCompressed()) {
1288
1289 tbb::spin_mutex::scoped_lock lock(mMutex);
1290
1291 this->doLoadUnsafe(/*compression=*/false);
1292
1293 if (this->isCompressed()) return true;
1294
1295 return this->compressUnsafe();
1296 }
1297
1298 return false;
1299 }
1300
1301
1302 template<typename ValueType_, typename Codec_>
1303 inline bool
1304 TypedAttributeArray<ValueType_, Codec_>::compressUnsafe()
1305 {
1306 if (!compression::bloscCanCompress()) return false;
1307 if (mIsUniform) return false;
1308
1309 // assumes mutex is locked and data is not out-of-core
1310
1311 const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1312 const size_t inBytes = writeCompress ? mCompressedBytes : this->arrayMemUsage();
1313
1314 if (inBytes > 0) {
1315 size_t outBytes;
1316 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1317 std::unique_ptr<char[]> buffer = compression::bloscCompress(charBuffer, inBytes, outBytes);
1318 if (buffer) {
1319 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1320 mCompressedBytes = outBytes;
1321 return true;
1322 }
1323 }
1324
1325 return false;
1326 }
1327
1328
1329 template<typename ValueType_, typename Codec_>
1330 inline bool
1331 TypedAttributeArray<ValueType_, Codec_>::decompress()
1332 {
1333 tbb::spin_mutex::scoped_lock lock(mMutex);
1334
1335 const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1336
1337 if (writeCompress) {
1338 this->doLoadUnsafe(/*compression=*/false);
1339 return true;
1340 }
1341
1342 if (this->isCompressed()) {
1343 this->doLoadUnsafe();
1344 const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1345 size_t uncompressedBytes = compression::bloscUncompressedSize(charBuffer);
1346 std::unique_ptr<char[]> buffer = compression::bloscDecompress(charBuffer, uncompressedBytes);
1347 if (buffer) {
1348 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1349 mCompressedBytes = 0;
1350 return true;
1351 }
1352 }
1353
1354 return false;
1355 }
1356
1357
1358 template<typename ValueType_, typename Codec_>
1359 bool
1360 TypedAttributeArray<ValueType_, Codec_>::isOutOfCore() const
1361 {
1362 return (mFlags & OUTOFCORE);
1363 }
1364
1365
1366 template<typename ValueType_, typename Codec_>
1367 void
1368 TypedAttributeArray<ValueType_, Codec_>::setOutOfCore(const bool b)
1369 {
1370 if (b) mFlags = static_cast<uint8_t>(mFlags | OUTOFCORE);
1371 else mFlags = static_cast<uint8_t>(mFlags & ~OUTOFCORE);
1372 }
1373
1374
1375 template<typename ValueType_, typename Codec_>
1376 void
1377 TypedAttributeArray<ValueType_, Codec_>::doLoad() const
1378 {
1379 if (!(this->isOutOfCore())) return;
1380
1381 TypedAttributeArray<ValueType_, Codec_>* self =
1382 const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
1383
1384 // This lock will be contended at most once, after which this buffer
1385 // will no longer be out-of-core.
1386 tbb::spin_mutex::scoped_lock lock(self->mMutex);
1387 this->doLoadUnsafe();
1388 }
1389
1390
1391 template<typename ValueType_, typename Codec_>
1392 void
1393 TypedAttributeArray<ValueType_, Codec_>::loadData() const
1394 {
1395 this->doLoad();
1396 }
1397
1398
1399 template<typename ValueType_, typename Codec_>
1400 void
1401 TypedAttributeArray<ValueType_, Codec_>::read(std::istream& is)
1402 {
1403 this->readMetadata(is);
1404 this->readBuffers(is);
1405 }
1406
1407
1408 template<typename ValueType_, typename Codec_>
1409 void
1410 TypedAttributeArray<ValueType_, Codec_>::readMetadata(std::istream& is)
1411 {
1412 // read data
1413
1414 Index64 bytes = Index64(0);
1415 is.read(reinterpret_cast<char*>(&bytes), sizeof(Index64));
1416 bytes = bytes - /*flags*/sizeof(Int16) - /*size*/sizeof(Index);
1417
1418 uint8_t flags = uint8_t(0);
1419 is.read(reinterpret_cast<char*>(&flags), sizeof(uint8_t));
1420 mFlags = flags;
1421
1422 uint8_t serializationFlags = uint8_t(0);
1423 is.read(reinterpret_cast<char*>(&serializationFlags), sizeof(uint8_t));
1424 mSerializationFlags = serializationFlags;
1425
1426 Index size = Index(0);
1427 is.read(reinterpret_cast<char*>(&size), sizeof(Index));
1428 mSize = size;
1429
1430 // warn if an unknown flag has been set
1431 if (mFlags >= 0x20) {
1432 OPENVDB_LOG_WARN("Unknown attribute flags for VDB file format.");
1433 }
1434 // error if an unknown serialization flag has been set,
1435 // as this will adjust the layout of the data and corrupt the ability to read
1436 if (mSerializationFlags >= 0x10) {
1437 OPENVDB_THROW(IoError, "Unknown attribute serialization flags for VDB file format.");
1438 }
1439
1440 // read uniform and compressed state
1441
1442 mIsUniform = mSerializationFlags & WRITEUNIFORM;
1443 mCompressedBytes = bytes;
1444
1445 // read strided value (set to 1 if array is not strided)
1446
1447 if (mSerializationFlags & WRITESTRIDED) {
1448 Index stride = Index(0);
1449 is.read(reinterpret_cast<char*>(&stride), sizeof(Index));
1450 mStrideOrTotalSize = stride;
1451 }
1452 else {
1453 mStrideOrTotalSize = 1;
1454 }
1455 }
1456
1457
1458 template<typename ValueType_, typename Codec_>
1459 void
1460 TypedAttributeArray<ValueType_, Codec_>::readBuffers(std::istream& is)
1461 {
1462 if ((mSerializationFlags & WRITEPAGED)) {
1463 // use readBuffers(PagedInputStream&) for paged buffers
1464 OPENVDB_THROW(IoError, "Cannot read paged AttributeArray buffers.");
1465 }
1466
1467 tbb::spin_mutex::scoped_lock lock(mMutex);
1468
1469 this->deallocate();
1470
1471 uint8_t bloscCompressed(0);
1472 if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed), sizeof(uint8_t));
1473
1474 std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
1475 is.read(buffer.get(), mCompressedBytes);
1476
1477 if (mIsUniform) {
1478 // zero compressed bytes as uniform values are not compressed in memory
1479 mCompressedBytes = Index64(0);
1480 }
1481 else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1482 // zero compressed bytes if not compressed in memory
1483 mCompressedBytes = Index64(0);
1484 }
1485
1486 // compressed on-disk
1487
1488 if (bloscCompressed == uint8_t(1)) {
1489
1490 // decompress buffer
1491
1492 const size_t inBytes = this->dataSize() * sizeof(StorageType);
1493 std::unique_ptr<char[]> newBuffer = compression::bloscDecompress(buffer.get(), inBytes);
1494 if (newBuffer) buffer.reset(newBuffer.release());
1495 }
1496
1497 // set data to buffer
1498
1499 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1500
1501 // clear all write flags
1502
1503 if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1504 else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1505 }
1506
1507
1508 template<typename ValueType_, typename Codec_>
1509 void
1510 TypedAttributeArray<ValueType_, Codec_>::readPagedBuffers(compression::PagedInputStream& is)
1511 {
1512 if (!(mSerializationFlags & WRITEPAGED)) {
1513 if (!is.sizeOnly()) this->readBuffers(is.getInputStream());
1514 return;
1515 }
1516
1517 // If this array is being read from a memory-mapped file, delay loading of its data
1518 // until the data is actually accessed.
1519 io::MappedFile::Ptr mappedFile = io::getMappedFilePtr(is.getInputStream());
1520 const bool delayLoad = (mappedFile.get() != nullptr);
1521
1522 if (is.sizeOnly())
1523 {
1524 mPageHandle = is.createHandle(mCompressedBytes);
1525 return;
1526 }
1527
1528 assert(mPageHandle);
1529
1530 tbb::spin_mutex::scoped_lock lock(mMutex);
1531
1532 this->deallocate();
1533
1534 this->setOutOfCore(delayLoad);
1535 is.read(mPageHandle, mCompressedBytes, delayLoad);
1536
1537 if (!delayLoad) {
1538 std::unique_ptr<char[]> buffer = mPageHandle->read();
1539 mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1540 }
1541
1542 // zero compressed bytes as not compressed in memory
1543
1544 if (mIsUniform) {
1545 // zero compressed bytes as uniform values are not compressed in memory
1546 mCompressedBytes = Index64(0);
1547 }
1548 else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1549 mCompressedBytes = Index64(0);
1550 }
1551
1552 // clear all write flags
1553
1554 if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1555 else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1556 }
1557
1558
1559 template<typename ValueType_, typename Codec_>
1560 void
1561 TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os) const
1562 {
1563 this->write(os, /*outputTransient=*/false);
1564 }
1565
1566
1567 template<typename ValueType_, typename Codec_>
1568 void
1569 TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os, bool outputTransient) const
1570 {
1571 this->writeMetadata(os, outputTransient, /*paged=*/false);
1572 this->writeBuffers(os, outputTransient);
1573 }
1574
1575
1576 template<typename ValueType_, typename Codec_>
1577 void
1578 TypedAttributeArray<ValueType_, Codec_>::writeMetadata(std::ostream& os, bool outputTransient, bool paged) const
1579 {
1580 if (!outputTransient && this->isTransient()) return;
1581
1582 uint8_t flags(mFlags & uint8_t(~OUTOFCORE));
1583 uint8_t serializationFlags(0);
1584 Index size(mSize);
1585 Index stride(mStrideOrTotalSize);
1586 bool strideOfOne(this->stride() == 1);
1587
1588 bool bloscCompression = io::getDataCompression(os) & io::COMPRESS_BLOSC;
1589
1590 // any compressed data needs to be loaded if out-of-core
1591 if (bloscCompression || this->isCompressed()) this->doLoad();
1592
1593 size_t compressedBytes = 0;
1594
1595 if (!strideOfOne)
1596 {
1597 serializationFlags |= WRITESTRIDED;
1598 }
1599
1600 if (mIsUniform)
1601 {
1602 serializationFlags |= WRITEUNIFORM;
1603 if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1604 }
1605 else if (bloscCompression && paged)
1606 {
1607 serializationFlags |= WRITEPAGED;
1608 if (this->isCompressed()) {
1609 serializationFlags |= WRITEMEMCOMPRESS;
1610 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1611 compressedBytes = compression::bloscUncompressedSize(charBuffer);
1612 }
1613 }
1614 else if (this->isCompressed())
1615 {
1616 serializationFlags |= WRITEMEMCOMPRESS;
1617 compressedBytes = mCompressedBytes;
1618 }
1619 else if (bloscCompression)
1620 {
1621 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1622 const size_t inBytes = this->arrayMemUsage();
1623 compressedBytes = compression::bloscCompressedSize(charBuffer, inBytes);
1624 }
1625
1626 Index64 bytes = /*flags*/ sizeof(Int16) + /*size*/ sizeof(Index);
1627
1628 bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1629
1630 // write data
1631
1632 os.write(reinterpret_cast<const char*>(&bytes), sizeof(Index64));
1633 os.write(reinterpret_cast<const char*>(&flags), sizeof(uint8_t));
1634 os.write(reinterpret_cast<const char*>(&serializationFlags), sizeof(uint8_t));
1635 os.write(reinterpret_cast<const char*>(&size), sizeof(Index));
1636
1637 // write strided
1638 if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride), sizeof(Index));
1639 }
1640
1641
1642 template<typename ValueType_, typename Codec_>
1643 void
1644 TypedAttributeArray<ValueType_, Codec_>::writeBuffers(std::ostream& os, bool outputTransient) const
1645 {
1646 if (!outputTransient && this->isTransient()) return;
1647
1648 this->doLoad();
1649
1650 if (this->isUniform()) {
1651 os.write(reinterpret_cast<const char*>(mData.get()), sizeof(StorageType));
1652 }
1653 else if (this->isCompressed())
1654 {
1655 uint8_t bloscCompressed(0);
1656 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1657 os.write(reinterpret_cast<const char*>(mData.get()), mCompressedBytes);
1658 }
1659 else if (io::getDataCompression(os) & io::COMPRESS_BLOSC)
1660 {
1661 std::unique_ptr<char[]> compressedBuffer;
1662 size_t compressedBytes = 0;
1663 const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1664 const size_t inBytes = this->arrayMemUsage();
1665 compressedBuffer = compression::bloscCompress(charBuffer, inBytes, compressedBytes);
1666 if (compressedBuffer) {
1667 uint8_t bloscCompressed(1);
1668 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1669 os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1670 }
1671 else {
1672 uint8_t bloscCompressed(0);
1673 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1674 os.write(reinterpret_cast<const char*>(mData.get()), inBytes);
1675 }
1676 }
1677 else
1678 {
1679 uint8_t bloscCompressed(0);
1680 os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1681 os.write(reinterpret_cast<const char*>(mData.get()), this->arrayMemUsage());
1682 }
1683 }
1684
1685
1686 template<typename ValueType_, typename Codec_>
1687 void
1688 TypedAttributeArray<ValueType_, Codec_>::writePagedBuffers(compression::PagedOutputStream& os, bool outputTransient) const
1689 {
1690 if (!outputTransient && this->isTransient()) return;
1691
1692 // paged compression only available when Blosc is enabled
1693 bool bloscCompression = io::getDataCompression(os.getOutputStream()) & io::COMPRESS_BLOSC;
1694 if (!bloscCompression) {
1695 if (!os.sizeOnly()) this->writeBuffers(os.getOutputStream(), outputTransient);
1696 return;
1697 }
1698
1699 this->doLoad();
1700
1701 const char* buffer;
1702 size_t bytes;
1703
1704 std::unique_ptr<char[]> uncompressedBuffer;
1705 if (this->isCompressed()) {
1706 // paged streams require uncompressed buffers, so locally decompress
1707
1708 const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1709 bytes = compression::bloscUncompressedSize(charBuffer);
1710 uncompressedBuffer = compression::bloscDecompress(charBuffer, bytes);
1711 buffer = reinterpret_cast<const char*>(uncompressedBuffer.get());
1712 }
1713 else {
1714 buffer = reinterpret_cast<const char*>(mData.get());
1715 bytes = this->arrayMemUsage();
1716 }
1717
1718 os.write(buffer, bytes);
1719 }
1720
1721
1722 template<typename ValueType_, typename Codec_>
1723 void
1724 TypedAttributeArray<ValueType_, Codec_>::doLoadUnsafe(const bool compression) const
1725 {
1726 if (!(this->isOutOfCore())) return;
1727
1728 // this function expects the mutex to already be locked
1729
1730 TypedAttributeArray<ValueType_, Codec_>* self = const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
1731
1732 assert(self->mPageHandle);
1733
1734 std::unique_ptr<char[]> buffer = self->mPageHandle->read();
1735
1736 self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1737
1738 self->mPageHandle.reset();
1739
1740 // if data was compressed prior to being written to disk, re-compress
1741
1742 if (self->mSerializationFlags & WRITEMEMCOMPRESS) {
1743 if (compression) self->compressUnsafe();
1744 else self->mCompressedBytes = 0;
1745 }
1746
1747 // clear all write and out-of-core flags
1748
1749 self->mFlags &= uint8_t(~OUTOFCORE);
1750 self->mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1751 }
1752
1753
1754 template<typename ValueType_, typename Codec_>
1755 AttributeArray::AccessorBasePtr
1756 TypedAttributeArray<ValueType_, Codec_>::getAccessor() const
1757 {
1758 // use the faster 'unsafe' get and set methods as attribute handles
1759 // ensure data is uncompressed and in-core when constructed
1760
1761 return AccessorBasePtr(new AttributeArray::Accessor<ValueType_>(
1762 &TypedAttributeArray<ValueType_, Codec_>::getUnsafe,
1763 &TypedAttributeArray<ValueType_, Codec_>::setUnsafe,
1764 &TypedAttributeArray<ValueType_, Codec_>::collapse,
1765 &TypedAttributeArray<ValueType_, Codec_>::fill));
1766 }
1767
1768
1769 template<typename ValueType_, typename Codec_>
1770 bool
1771 TypedAttributeArray<ValueType_, Codec_>::isEqual(const AttributeArray& other) const
1772 {
1773 const TypedAttributeArray<ValueType_, Codec_>* const otherT = dynamic_cast<const TypedAttributeArray<ValueType_, Codec_>* >(&other);
1774 if(!otherT) return false;
1775 if(this->mSize != otherT->mSize ||
1776 this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
1777 this->mIsUniform != otherT->mIsUniform ||
1778 *this->sTypeName != *otherT->sTypeName) return false;
1779
1780 this->doLoad();
1781 otherT->doLoad();
1782
1783 const StorageType *target = this->mData.get(), *source = otherT->mData.get();
1784 if (!target && !source) return true;
1785 if (!target || !source) return false;
1786 Index n = this->mIsUniform ? 1 : mSize;
1787 while (n && math::isExactlyEqual(*target++, *source++)) --n;
1788 return n == 0;
1789 }
1790
1792
1793
1795 template <typename CodecType, typename ValueType>
1796 struct AccessorEval
1797 {
1798 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
1799 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
1800
1803 static ValueType get(GetterPtr /*functor*/, const AttributeArray* array, const Index n) {
1804 return TypedAttributeArray<ValueType, CodecType>::getUnsafe(array, n);
1805 }
1806
1809 static void set(SetterPtr /*functor*/, AttributeArray* array, const Index n, const ValueType& value) {
1810 TypedAttributeArray<ValueType, CodecType>::setUnsafe(array, n, value);
1811 }
1812 };
1813
1814
1816 template <typename ValueType>
1817 struct AccessorEval<UnknownCodec, ValueType>
1818 {
1819 using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
1820 using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
1821
1823 static ValueType get(GetterPtr functor, const AttributeArray* array, const Index n) {
1824 return (*functor)(array, n);
1825 }
1826
1828 static void set(SetterPtr functor, AttributeArray* array, const Index n, const ValueType& value) {
1829 (*functor)(array, n, value);
1830 }
1831 };
1832
1833
1835
1836 // AttributeHandle implementation
1837
1838 template <typename ValueType, typename CodecType>
1839 typename AttributeHandle<ValueType, CodecType>::Ptr
1840 AttributeHandle<ValueType, CodecType>::create(const AttributeArray& array, const bool preserveCompression)
1841 {
1842 return typename AttributeHandle<ValueType, CodecType>::Ptr(
1843 new AttributeHandle<ValueType, CodecType>(array, preserveCompression));
1844 }
1845
1846 template <typename ValueType, typename CodecType>
1847 AttributeHandle<ValueType, CodecType>::AttributeHandle(const AttributeArray& array, const bool preserveCompression)
1848 : mArray(&array)
1849 , mStrideOrTotalSize(array.hasConstantStride() ? array.stride() : 1)
1850 , mSize(array.hasConstantStride() ? array.size() : array.dataSize())
1851 , mCollapseOnDestruction(preserveCompression && array.isStreaming())
1852 {
1853 if (!this->compatibleType<std::is_same<CodecType, UnknownCodec>::value>()) {
1854 OPENVDB_THROW(TypeError, "Cannot bind handle due to incompatible type of AttributeArray.");
1855 }
1856
1857 // load data if delay-loaded
1858
1859 mArray->loadData();
1860
1861 // if array is compressed and preserve compression is true, copy and decompress
1862 // into a local copy that is destroyed with handle to maintain thread-safety
1863
1864 if (array.isCompressed())
1865 {
1866 if (preserveCompression && !array.isStreaming()) {
1867 mLocalArray = array.copyUncompressed();
1868 mLocalArray->decompress();
1869 mArray = mLocalArray.get();
1870 }
1871 else {
1872 const_cast<AttributeArray*>(mArray)->decompress();
1873 }
1874 }
1875
1876 // bind getter and setter methods
1877
1878 AttributeArray::AccessorBasePtr accessor = mArray->getAccessor();
1879 assert(accessor);
1880
1881 AttributeArray::Accessor<ValueType>* typedAccessor = static_cast<AttributeArray::Accessor<ValueType>*>(accessor.get());
1882
1883 mGetter = typedAccessor->mGetter;
1884 mSetter = typedAccessor->mSetter;
1885 mCollapser = typedAccessor->mCollapser;
1886 mFiller = typedAccessor->mFiller;
1887 }
1888
1889 template <typename ValueType, typename CodecType>
1890 AttributeHandle<ValueType, CodecType>::~AttributeHandle()
1891 {
1892 // if enabled, attribute is collapsed on destruction of the handle to save memory
1893 if (mCollapseOnDestruction) const_cast<AttributeArray*>(this->mArray)->collapse();
1894 }
1895
1896 template <typename ValueType, typename CodecType>
1897 template <bool IsUnknownCodec>
1898 typename std::enable_if<IsUnknownCodec, bool>::type
1899 AttributeHandle<ValueType, CodecType>::compatibleType() const
1900 {
1901 // if codec is unknown, just check the value type
1902
1903 return mArray->hasValueType<ValueType>();
1904 }
1905
1906 template <typename ValueType, typename CodecType>
1907 template <bool IsUnknownCodec>
1908 typename std::enable_if<!IsUnknownCodec, bool>::type
1909 AttributeHandle<ValueType, CodecType>::compatibleType() const
1910 {
1911 // if the codec is known, check the value type and codec
1912
1913 return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
1914 }
1915
1916 template <typename ValueType, typename CodecType>
1917 Index AttributeHandle<ValueType, CodecType>::index(Index n, Index m) const
1918 {
1919 Index index = n * mStrideOrTotalSize + m;
1920 assert(index < (mSize * mStrideOrTotalSize));
1921 return index;
1922 }
1923
1924 template <typename ValueType, typename CodecType>
1925 ValueType AttributeHandle<ValueType, CodecType>::get(Index n, Index m) const
1926 {
1927 return this->get<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m));
1928 }
1929
1930 template <typename ValueType, typename CodecType>
1931 template <bool IsUnknownCodec>
1932 typename std::enable_if<IsUnknownCodec, ValueType>::type
1933 AttributeHandle<ValueType, CodecType>::get(Index index) const
1934 {
1935 // if the codec is unknown, use the getter functor
1936
1937 return (*mGetter)(mArray, index);
1938 }
1939
1940 template <typename ValueType, typename CodecType>
1941 template <bool IsUnknownCodec>
1942 typename std::enable_if<!IsUnknownCodec, ValueType>::type
1943 AttributeHandle<ValueType, CodecType>::get(Index index) const
1944 {
1945 // if the codec is known, call the method on the attribute array directly
1946
1947 return TypedAttributeArray<ValueType, CodecType>::getUnsafe(mArray, index);
1948 }
1949
1950 template <typename ValueType, typename CodecType>
1951 bool AttributeHandle<ValueType, CodecType>::isUniform() const
1952 {
1953 return mArray->isUniform();
1954 }
1955
1956 template <typename ValueType, typename CodecType>
1957 bool AttributeHandle<ValueType, CodecType>::hasConstantStride() const
1958 {
1959 return mArray->hasConstantStride();
1960 }
1961
1963
1964 // AttributeWriteHandle implementation
1965
1966 template <typename ValueType, typename CodecType>
1967 typename AttributeWriteHandle<ValueType, CodecType>::Ptr
1968 AttributeWriteHandle<ValueType, CodecType>::create(AttributeArray& array, const bool expand)
1969 {
1970 return typename AttributeWriteHandle<ValueType, CodecType>::Ptr(
1971 new AttributeWriteHandle<ValueType, CodecType>(array, expand));
1972 }
1973
1974 template <typename ValueType, typename CodecType>
1975 AttributeWriteHandle<ValueType, CodecType>::AttributeWriteHandle(AttributeArray& array, const bool expand)
1976 : AttributeHandle<ValueType, CodecType>(array, /*preserveCompression = */ false)
1977 {
1978 if (expand) array.expand();
1979 }
1980
1981 template <typename ValueType, typename CodecType>
1982 void AttributeWriteHandle<ValueType, CodecType>::set(Index n, const ValueType& value)
1983 {
1984 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, 0), value);
1985 }
1986
1987 template <typename ValueType, typename CodecType>
1988 void AttributeWriteHandle<ValueType, CodecType>::set(Index n, Index m, const ValueType& value)
1989 {
1990 this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m), value);
1991 }
1992
1993 template <typename ValueType, typename CodecType>
1994 void AttributeWriteHandle<ValueType, CodecType>::expand(const bool fill)
1995 {
1996 const_cast<AttributeArray*>(this->mArray)->expand(fill);
1997 }
1998
1999 template <typename ValueType, typename CodecType>
2000 void AttributeWriteHandle<ValueType, CodecType>::collapse()
2001 {
2002 const_cast<AttributeArray*>(this->mArray)->collapse();
2003 }
2004
2005 template <typename ValueType, typename CodecType>
2006 bool AttributeWriteHandle<ValueType, CodecType>::compact()
2007 {
2008 return const_cast<AttributeArray*>(this->mArray)->compact();
2009 }
2010
2011 template <typename ValueType, typename CodecType>
2012 void AttributeWriteHandle<ValueType, CodecType>::collapse(const ValueType& uniformValue)
2013 {
2014 this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2015 }
2016
2017 template <typename ValueType, typename CodecType>
2018 void AttributeWriteHandle<ValueType, CodecType>::fill(const ValueType& value)
2019 {
2020 this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2021 }
2022
2023 template <typename ValueType, typename CodecType>
2024 template <bool IsUnknownCodec>
2025 typename std::enable_if<IsUnknownCodec, void>::type
2026 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2027 {
2028 // if the codec is unknown, use the setter functor
2029
2030 (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index, value);
2031 }
2032
2033 template <typename ValueType, typename CodecType>
2034 template <bool IsUnknownCodec>
2035 typename std::enable_if<!IsUnknownCodec, void>::type
2036 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2037 {
2038 // if the codec is known, call the method on the attribute array directly
2039
2040 TypedAttributeArray<ValueType, CodecType>::setUnsafe(const_cast<AttributeArray*>(this->mArray), index, value);
2041 }
2042
2043
2044 } // namespace points
2045 } // namespace OPENVDB_VERSION_NAME
2046 } // namespace openvdb
2047
2048 #endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
2049
2050 // Copyright (c) 2012-2017 DreamWorks Animation LLC
2051 // All rights reserved. This software is distributed under the
2052 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v4_0_2::points::NullCodec
Definition: AttributeArray.h:363
openvdb::v4_0_2::points::TypedAttributeArray::ValueType
ValueType_ ValueType
Definition: AttributeArray.h:443
openvdb::v4_0_2::points::TypedAttributeArray::copy
AttributeArray::Ptr copy() const override
Return a copy of this attribute.
Definition: AttributeArray.h:1004
openvdb::v4_0_2::points::AttributeArray::Accessor::GetterPtr
T(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:316
openvdb::v4_0_2::points::TruncateCodec::Storage::Type
typename attribute_traits::TruncateTrait< T >::Type Type
Definition: AttributeArray.h:377
openvdb::v4_0_2::points::AttributeWriteHandle::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:713
openvdb::v4_0_2::compression::PagedOutputStream::write
PagedOutputStream & write(const char *str, std::streamsize n)
Writes the given.
openvdb::v4_0_2::points::fixedPointToFloatingPoint
FloatVectorT fixedPointToFloatingPoint(const math::Vec3< IntegerT > &v)
Definition: AttributeArray.h:105
openvdb::v4_0_2::points::AccessorEval::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:1799
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
openvdb::v4_0_2::compression::PagedInputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:236
openvdb::v4_0_2::points::AttributeArray::isStreaming
bool isStreaming() const
Return true if this attribute is in streaming mode.
Definition: AttributeArray.h:233
Types.h
openvdb::v4_0_2::points::TypedAttributeArray::stride
Index stride() const override
Definition: AttributeArray.h:495
openvdb::v4_0_2::io::getDataCompression
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK, etc.) specifying whether and how input data is compressed or output data should be compressed.
openvdb::v4_0_2::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(const TypedAttributeArray &)
Deep copy assignment operator.
Definition: AttributeArray.h:908
openvdb::v4_0_2::compression::bloscDecompress
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
Compression.h
openvdb::v4_0_2::points::attribute_traits::TruncateTrait
Definition: AttributeArray.h:335
openvdb::v4_0_2::io::COMPRESS_BLOSC
Definition: Compression.h:81
openvdb::v4_0_2::points::TypedAttributeArray::registerType
static void registerType()
Register this attribute type along with a factory function.
Definition: AttributeArray.h:961
openvdb::v4_0_2::points::AttributeArray::isTransient
bool isTransient() const
Return true if this attribute is not serialized during stream output.
Definition: AttributeArray.h:225
QuantizedUnitVec.h
openvdb::v4_0_2::IoError
Definition: Exceptions.h:85
openvdb::v4_0_2::points::AttributeArray::hasValueType
bool hasValueType() const
Return true if this attribute has a value type the same as the template parameter.
Definition: AttributeArray.h:190
openvdb::v4_0_2::points::TypedAttributeArray::collapse
void collapse() override
Replace the existing array with a uniform zero value.
Definition: AttributeArray.h:1228
openvdb::v4_0_2::points::AttributeArray::Accessor
Definition: AttributeArray.h:122
openvdb::v4_0_2::points::AttributeHandle::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:678
openvdb::v4_0_2::points::attribute_traits::UIntTypeTrait< false, T >::Type
uint16_t Type
Definition: AttributeArray.h:345
openvdb::v4_0_2::points::AttributeHandle::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:676
openvdb::v4_0_2::points::TypedAttributeArray::cast
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>
Definition: AttributeArray.h:984
openvdb::v4_0_2::points::AttributeArray::operator!=
bool operator!=(const AttributeArray &other) const
Definition: AttributeArray.h:275
openvdb::v4_0_2::points::TypedAttributeArray::writeMetadata
void writeMetadata(std::ostream &os, bool outputTransient, bool paged) const override
Definition: AttributeArray.h:1578
openvdb::v4_0_2::points::AttributeArray::Flag
Flag
Definition: AttributeArray.h:127
openvdb::v4_0_2::points::TypedAttributeArray::compact
bool compact() override
Compact the existing array to become uniform if all values are identical.
Definition: AttributeArray.h:1211
openvdb::v4_0_2::points::AttributeHandle::stride
Index stride() const
Definition: AttributeArray.h:662
openvdb::v4_0_2::points::UnitVecCodec::StorageType
uint16_t StorageType
Definition: AttributeArray.h:421
openvdb::v4_0_2::compression::PageHandle::Ptr
std::shared_ptr< PageHandle > Ptr
Definition: StreamCompression.h:197
openvdb::v4_0_2::math::Vec3::z
T & z()
Definition: Vec3.h:111
openvdb::v4_0_2::points::AttributeHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::ValuePtr
void(*)(AttributeArray *array, const StringIndexType &value) ValuePtr
Definition: AttributeArray.h:650
openvdb::v4_0_2::points::UnitVecCodec::Storage::Type
StorageType Type
Definition: AttributeArray.h:424
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
openvdb::v4_0_2::points::AttributeArray::Accessor::ValuePtr
void(*)(AttributeArray *array, const T &value) ValuePtr
Definition: AttributeArray.h:318
openvdb::v4_0_2::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:391
openvdb::v4_0_2::points::UnitRange
Definition: AttributeArray.h:395
openvdb::v4_0_2::points::AttributeArray::mCompressedBytes
size_t mCompressedBytes
Definition: AttributeArray.h:296
openvdb::v4_0_2::points::UnknownCodec
Definition: AttributeArray.h:360
openvdb::v4_0_2::points::AttributeHandle::mArray
const AttributeArray * mArray
Definition: AttributeArray.h:673
i
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
openvdb::v4_0_2::points::FixedPointCodec::Storage
Definition: AttributeArray.h:407
openvdb::v4_0_2::compression::bloscUncompressedSize
OPENVDB_API size_t bloscUncompressedSize(const char *buffer)
Retrieves the uncompressed size of buffer when uncompressed.
openvdb::v4_0_2::compression::bloscCompress
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
openvdb::v4_0_2::points::AttributeArray::expand
virtual void expand(bool fill=true)=0
If this array is uniform, replace it with an array of length size().
openvdb::v4_0_2::points::AttributeArray::mPageHandle
compression::PageHandle::Ptr mPageHandle
used for out-of-core, paged reading
Definition: AttributeArray.h:301
openvdb::v4_0_2::points::AttributeArray::flags
uint8_t flags() const
Retrieve the attribute array flags.
Definition: AttributeArray.h:239
openvdb::v4_0_2::compression::bloscCompressedSize
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
openvdb::v4_0_2::points::TypedAttributeArray::copyUncompressed
AttributeArray::Ptr copyUncompressed() const override
Return an uncompressed copy of this attribute (will just return a copy if not compressed).
Definition: AttributeArray.h:1012
openvdb::v4_0_2::compression::PagedInputStream::read
void read(PageHandle::Ptr &pageHandle, std::streamsize n, bool delayed=true)
Takes a pageHandle and updates the referenced page with the current stream pointer position and if de...
openvdb::v4_0_2::points::AttributeArray::SerializationFlag
SerializationFlag
Definition: AttributeArray.h:135
openvdb::v4_0_2::points::floatingPointToFixedPoint
IntegerVectorT floatingPointToFixedPoint(const math::Vec3< FloatT > &v)
Definition: AttributeArray.h:95
data
T * data
Definition: LeafBuffer.h:71
openvdb::v4_0_2::points::AccessorEval
Accessor to call unsafe get and set methods based on templated Codec and Value.
Definition: AttributeArray.h:1796
openvdb::v4_0_2::points::TypedAttributeArray::size
Index size() const override
Return the number of elements in this array.
Definition: AttributeArray.h:491
openvdb::v4_0_2::points::TypedAttributeArray::loadData
void loadData() const override
Ensures all data is in-core.
Definition: AttributeArray.h:1393
openvdb::v4_0_2::points::AttributeArray::WRITESTRIDED
Definition: AttributeArray.h:136
openvdb::v4_0_2::points::AttributeWriteHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::ScopedPtr
std::unique_ptr< Handle > ScopedPtr
Definition: AttributeArray.h:714
openvdb::v4_0_2::points::AttributeArray::unregisterType
static void unregisterType(const NamePair &type)
Remove a attribute type from the registry.
openvdb::v4_0_2::points::FixedPointCodec::Storage::Type
typename attribute_traits::UIntTypeTrait< OneByte, T >::Type Type
Definition: AttributeArray.h:407
openvdb::v4_0_2::Index
Index32 Index
Definition: Types.h:57
openvdb::v4_0_2::math::Vec3
Definition: Mat.h:195
io.h
openvdb::v4_0_2::points::PositionRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:389
openvdb::v4_0_2::points::AttributeArray::isCompressed
bool isCompressed() const
Return true if this array is compressed.
Definition: AttributeArray.h:206
openvdb::v4_0_2::points::TypedAttributeArray::unregisterType
static void unregisterType()
Remove this attribute type from the registry.
Definition: AttributeArray.h:969
openvdb::v4_0_2::points::AttributeArray::isRegistered
static bool isRegistered(const NamePair &type)
Return true if the given attribute type name is registered.
logging.h
openvdb::v4_0_2::points::TypedAttributeArray::compress
bool compress() override
Compress the attribute array.
Definition: AttributeArray.h:1283
openvdb::v4_0_2::points::AttributeArray::AccessorBase
Accessor base class for AttributeArray storage where type is not available.
Definition: AttributeArray.h:309
openvdb::v4_0_2::points::TypedAttributeArray::read
void read(std::istream &) override
Read attribute data from a stream.
Definition: AttributeArray.h:1401
openvdb::v4_0_2::points::TypedAttributeArray::~TypedAttributeArray
virtual ~TypedAttributeArray()
Definition: AttributeArray.h:461
openvdb::v4_0_2::points::attribute_traits::TruncateTrait< float >::Type
half Type
Definition: AttributeArray.h:336
openvdb::v4_0_2::points::TypedAttributeArray::getUnsafe
ValueType getUnsafe(Index n) const
Return the value at index n (assumes uncompressed and in-core)
Definition: AttributeArray.h:1068
openvdb::v4_0_2::points::AttributeArray::Accessor::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:325
openvdb::v4_0_2::compression::PagedInputStream::getInputStream
std::istream & getInputStream()
Definition: StreamCompression.h:239
openvdb::v4_0_2::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:1120
openvdb::v4_0_2::points::TypedAttributeArray::getAccessor
AccessorBasePtr getAccessor() const override
Obtain an Accessor that stores getter and setter functors.
Definition: AttributeArray.h:1756
openvdb::v4_0_2::compression::PagedOutputStream::getOutputStream
std::ostream & getOutputStream()
Set and get the output stream.
Definition: StreamCompression.h:276
openvdb::v4_0_2::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
openvdb::v4_0_2::points::TypedAttributeArray::dataSize
Index dataSize() const override
Return the size of the data in this array.
Definition: AttributeArray.h:498
openvdb::v4_0_2::points::AttributeHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::UniquePtr
std::unique_ptr< Handle > UniquePtr
Definition: AttributeArray.h:645
openvdb::v4_0_2::points::AttributeHandle::create
static Ptr create(const AttributeArray &array, const bool preserveCompression=true)
Definition: AttributeArray.h:1840
openvdb::v4_0_2::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
openvdb::v4_0_2::points::AttributeHandle::hasConstantStride
bool hasConstantStride() const
Definition: AttributeArray.h:1957
openvdb::v4_0_2::Index64
uint64_t Index64
Definition: Types.h:56
StreamCompression.h
Convenience wrappers to using Blosc and reading and writing of Paged data.
openvdb::v4_0_2::points::attribute_traits::UIntTypeTrait< true, T >::Type
uint8_t Type
Definition: AttributeArray.h:344
openvdb::v4_0_2::points::TypedAttributeArray::attributeType
static const NamePair & attributeType()
Return the name of this attribute&#39;s type (includes codec)
Definition: AttributeArray.h:941
openvdb::v4_0_2::Name
std::string Name
Definition: Name.h:44
openvdb::v4_0_2::points::AttributeArray::Accessor::SetterPtr
void(*)(AttributeArray *array, const Index n, const T &value) SetterPtr
Definition: AttributeArray.h:317
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v4_0_2::points::TypedAttributeArray::write
void write(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1569
openvdb::v4_0_2::points::TypedAttributeArray::isUniform
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Definition: AttributeArray.h:535
openvdb::v4_0_2::Int16
int16_t Int16
Definition: Types.h:58
openvdb::v4_0_2::points::AttributeArray::copyUncompressed
virtual AttributeArray::Ptr copyUncompressed() const =0
Return an uncompressed copy of this attribute (will return a copy if not compressed).
openvdb::v4_0_2::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeArray &array, const bool preserveCompression=true)
Definition: AttributeArray.h:1847
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form &#39;someVar << "some text" << ...&#39;.
Definition: logging.h:279
openvdb::v4_0_2::compression::PagedOutputStream
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition: StreamCompression.h:262
openvdb::v4_0_2::points::AttributeHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::GetterPtr
StringIndexType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:648
openvdb::v4_0_2::points::AttributeHandle::size
Index size() const
Definition: AttributeArray.h:663
openvdb::v4_0_2::points::AttributeArray::ConstPtr
std::shared_ptr< const AttributeArray > ConstPtr
Definition: AttributeArray.h:143
openvdb::v4_0_2::compression::bloscCanCompress
OPENVDB_API bool bloscCanCompress()
Returns true if compression is available.
openvdb::v4_0_2::points::attribute_traits::UIntTypeTrait
Definition: AttributeArray.h:343
openvdb::v4_0_2::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:236
openvdb::v4_0_2::points::TypedAttributeArray::fill
void fill(const ValueType &value)
Fill the existing array with the given value.
Definition: AttributeArray.h:1258
openvdb::v4_0_2::points::TruncateCodec::Storage
Definition: AttributeArray.h:377
openvdb::v4_0_2::compression::PagedOutputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:273
openvdb
Definition: Exceptions.h:39
openvdb::v4_0_2::points::TypedAttributeArray::writePagedBuffers
void writePagedBuffers(compression::PagedOutputStream &os, bool outputTransient) const override
Definition: AttributeArray.h:1688
openvdb::v4_0_2::math::operator==
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:487
openvdb::v4_0_2::points::NullCodec::Storage
Definition: AttributeArray.h:366
openvdb::v4_0_2::points::PositionRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:390
openvdb::v4_0_2::points::UnitVecCodec::Storage
Definition: AttributeArray.h:424
openvdb::v4_0_2::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:109
openvdb::v4_0_2::points::TypedAttributeArray
Typed class for storing attribute data.
Definition: AttributeArray.h:437
openvdb::v4_0_2::points::AttributeArray::AccessorBasePtr
std::shared_ptr< AccessorBase > AccessorBasePtr
Definition: AttributeArray.h:124
IndexIterator.h
Index Iterators.
openvdb::v4_0_2::math::Vec3::y
T & y()
Definition: Vec3.h:110
openvdb::v4_0_2::points::attribute_traits::TruncateTrait< int >::Type
short Type
Definition: AttributeArray.h:337
openvdb::v4_0_2::points::AttributeArray::isHidden
bool isHidden() const
Return true if this attribute is hidden (e.g., from UI or iterators).
Definition: AttributeArray.h:218
openvdb::v4_0_2::points::FixedPointCodec::name
static const char * name()
Definition: AttributeArray.h:412
openvdb::v4_0_2::points::AttributeArray::getAccessor
virtual AccessorBasePtr getAccessor() const =0
Obtain an Accessor that stores getter and setter functors.
openvdb::v4_0_2::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(Index n=1, Index strideOrTotalSize=1, bool constantStride=true, const ValueType &uniformValue=zeroVal< ValueType >())
Default constructor, always constructs a uniform attribute.
Definition: AttributeArray.h:840
openvdb::v4_0_2::points::AttributeArray::WRITEMEMCOMPRESS
data is marked as uniform when written
Definition: AttributeArray.h:138
openvdb::v4_0_2::points::TypedAttributeArray::set
void set(Index n, const ValueType &value)
Set value at the given index n.
Definition: AttributeArray.h:1136
openvdb::v4_0_2::points::TypedAttributeArray::readBuffers
void readBuffers(std::istream &) override
Read attribute buffers from a stream.
Definition: AttributeArray.h:1460
openvdb::v4_0_2::points::AccessorEval< UnknownCodec, ValueType >::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:1820
openvdb::v4_0_2::points::AttributeHandle::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:675
openvdb::v4_0_2::points::AttributeArray::mSerializationFlags
uint8_t mSerializationFlags
Definition: AttributeArray.h:298
openvdb::v4_0_2::points::AttributeHandle
Definition: AttributeArray.h:640
openvdb::v4_0_2::ValueError
Definition: Exceptions.h:92
openvdb::v4_0_2::io::MappedFile::Ptr
SharedPtr< MappedFile > Ptr
Definition: io.h:152
openvdb::v4_0_2::points::AttributeArray::Ptr
std::shared_ptr< AttributeArray > Ptr
Definition: AttributeArray.h:142
openvdb::v4_0_2::points::TypedAttributeArray::get
ValueType get(Index n) const
Return the value at index n.
Definition: AttributeArray.h:1082
openvdb::v4_0_2::points::AttributeArray::registerType
static void registerType(const NamePair &type, FactoryMethod)
Register a attribute type along with a factory function.
openvdb::v4_0_2::points::AttributeHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::SetterPtr
void(*)(AttributeArray *array, const Index n, const StringIndexType &value) SetterPtr
Definition: AttributeArray.h:649
openvdb::v4_0_2::points::UnitVecCodec::name
static const char * name()
Definition: AttributeArray.h:428
openvdb::v4_0_2::points::AttributeArray::WRITEPAGED
data is marked as compressed in-memory when written
Definition: AttributeArray.h:139
openvdb::v4_0_2::points::TypedAttributeArray::expand
void expand(bool fill=true) override
Replace the single value storage with an array of length size().
Definition: AttributeArray.h:1188
openvdb::v4_0_2::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:977
openvdb::v4_0_2::points::AccessorEval< UnknownCodec, ValueType >::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:1819
openvdb::v4_0_2::points::AttributeHandle::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:677
openvdb::v4_0_2::points::AttributeHandle< StringIndexType, openvdb::v4_0_2::points::StringCodec< false > >::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:644
openvdb::v4_0_2::points::AttributeArray::FactoryMethod
Ptr(*)(Index, Index, bool) FactoryMethod
Definition: AttributeArray.h:145
openvdb::v4_0_2::points::UnitRange::name
static const char * name()
Definition: AttributeArray.h:397
openvdb::v4_0_2::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:118
openvdb::v4_0_2::points::AttributeArray::Accessor::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:324
openvdb::v4_0_2::points::AttributeArray::mFlags
uint8_t mFlags
Definition: AttributeArray.h:297
openvdb::v4_0_2::points::TypedAttributeArray::decompress
bool decompress() override
Uncompress the attribute array.
Definition: AttributeArray.h:1331
openvdb::v4_0_2::points::TypedAttributeArray::readPagedBuffers
void readPagedBuffers(compression::PagedInputStream &) override
Read attribute buffers from a paged stream.
Definition: AttributeArray.h:1510
openvdb::v4_0_2::points::TypedAttributeArray::isOutOfCore
bool isOutOfCore() const
Return true if this buffer&#39;s values have not yet been read from disk.
Definition: AttributeArray.h:1360
openvdb::v4_0_2::IndexError
Definition: Exceptions.h:84
openvdb::v4_0_2::points::TypedAttributeArray::type
const NamePair & type() const override
Return the name of this attribute&#39;s type.
Definition: AttributeArray.h:481
openvdb::v4_0_2::compression::PagedInputStream::createHandle
PageHandle::Ptr createHandle(std::streamsize n)
Creates a PageHandle to access the next.
openvdb::v4_0_2::TypeError
Definition: Exceptions.h:91
openvdb::v4_0_2::points::AccessorEval::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:1798
openvdb::v4_0_2::points::UnitRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:399
openvdb::v4_0_2::compression::PagedInputStream
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition: StreamCompression.h:225
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v4_0_2::points::TypedAttributeArray::isRegistered
static bool isRegistered()
Return true if this attribute type is registered.
Definition: AttributeArray.h:953
openvdb::v4_0_2::NamePair
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:65
openvdb::v4_0_2::points::AttributeArray::WRITEUNIFORM
data is marked as strided when written
Definition: AttributeArray.h:137
openvdb::v4_0_2::points::PositionRange
Definition: AttributeArray.h:386
openvdb::v4_0_2::points::TruncateCodec
Definition: AttributeArray.h:374
openvdb::v4_0_2::points::NullCodec::Storage::Type
T Type
Definition: AttributeArray.h:366
openvdb::v4_0_2::points::AttributeHandle::isUniform
bool isUniform() const
Definition: AttributeArray.h:1951
openvdb::v4_0_2::points::FixedPointCodec
Definition: AttributeArray.h:404
openvdb::v4_0_2::points::AttributeArray::setConstantStride
void setConstantStride(bool state)
Specify whether this attribute has a constant stride or not.
openvdb::v4_0_2::points::AttributeArray::isType
bool isType() const
Return true if this attribute is of the same type as the template parameter.
Definition: AttributeArray.h:186
openvdb::v4_0_2::points::NullCodec::name
static const char * name()
Definition: AttributeArray.h:370
size
static constexpr size_t size
The size of a LeafBuffer when LeafBuffer::mOutOfCore is atomic.
Definition: LeafBuffer.h:85
openvdb::v4_0_2::points::UnitRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:398
openvdb::v4_0_2::points::PositionRange::name
static const char * name()
Definition: AttributeArray.h:388
openvdb::v4_0_2::points::AttributeArray::Accessor::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:326
openvdb::v4_0_2::points::TypedAttributeArray::memUsage
size_t memUsage() const override
Return the number of bytes of memory used by this attribute.
Definition: AttributeArray.h:1060
openvdb::v4_0_2::points::UnitVecCodec
Definition: AttributeArray.h:419
openvdb::v4_0_2::points::AttributeArray::OUTOFCORE
hidden from UIs or iterators
Definition: AttributeArray.h:130
openvdb::v4_0_2::points::TypedAttributeArray::Codec
Codec_ Codec
Definition: AttributeArray.h:444
openvdb::v4_0_2::points::AttributeArray::Accessor::Accessor
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler)
Definition: AttributeArray.h:320
openvdb::v4_0_2::points::TypedAttributeArray::StorageType
typename Codec::template Storage< ValueType >::Type StorageType
Definition: AttributeArray.h:445
openvdb::v4_0_2::points::TypedAttributeArray::Ptr
std::shared_ptr< TypedAttributeArray > Ptr
Definition: AttributeArray.h:440
openvdb::v4_0_2::points::AttributeWriteHandle
Write-able version of AttributeHandle.
Definition: AttributeArray.h:709
Name.h
openvdb::v4_0_2::points::TruncateCodec::name
static const char * name()
Definition: AttributeArray.h:381
openvdb::v4_0_2::points::TypedAttributeArray::readMetadata
void readMetadata(std::istream &) override
Read attribute metadata from a stream.
Definition: AttributeArray.h:1410
openvdb::v4_0_2::points::AttributeArray::Accessor::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:323
openvdb::v4_0_2::points::TypedAttributeArray::writeBuffers
void writeBuffers(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1644
openvdb::v4_0_2::io::getMappedFilePtr
OPENVDB_API SharedPtr< MappedFile > getMappedFilePtr(std::ios_base &)
Return a shared pointer to the memory-mapped file with which the given stream is associated, or a null pointer if the stream is not associated with a memory-mapped file.