OpenVDB: AttributeArray.h Source File

OpenVDB 6.0.0

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