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