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