OpenVDB  5.2.0
AttributeArray.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
36 
37 #ifndef OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/Types.h>
41 #include <openvdb/math/QuantizedUnitVec.h>
42 #include <openvdb/util/Name.h>
43 #include <openvdb/util/logging.h>
44 #include <openvdb/io/io.h> // MappedFile
45 #include <openvdb/io/Compression.h> // COMPRESS_BLOSC
46 
47 #include "IndexIterator.h"
48 #include "StreamCompression.h"
49 
50 #include <tbb/spin_mutex.h>
51 #include <tbb/atomic.h>
52 
53 #include <memory>
54 #include <string>
55 #include <type_traits>
56 
57 
58 class TestAttributeArray;
59 
60 namespace openvdb {
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  const AttributeArray& array() const;
675 
676 protected:
677  Index index(Index n, Index m) const;
678 
680 
685 
686 private:
687  friend class ::TestAttributeArray;
688 
689  template <bool IsUnknownCodec>
690  typename std::enable_if<IsUnknownCodec, bool>::type compatibleType() const;
691 
692  template <bool IsUnknownCodec>
693  typename std::enable_if<!IsUnknownCodec, bool>::type compatibleType() const;
694 
695  template <bool IsUnknownCodec>
696  typename std::enable_if<IsUnknownCodec, ValueType>::type get(Index index) const;
697 
698  template <bool IsUnknownCodec>
699  typename std::enable_if<!IsUnknownCodec, ValueType>::type get(Index index) const;
700 
701  // local copy of AttributeArray (to preserve compression)
702  AttributeArray::Ptr mLocalArray;
703 
704  Index mStrideOrTotalSize;
705  Index mSize;
706  bool mCollapseOnDestruction;
707 }; // class AttributeHandle
708 
709 
711 
712 
714 template <typename ValueType, typename CodecType = UnknownCodec>
715 class AttributeWriteHandle : public AttributeHandle<ValueType, CodecType>
716 {
717 public:
719  using Ptr = std::shared_ptr<Handle>;
720  using ScopedPtr = std::unique_ptr<Handle>;
721 
722  static Ptr create(AttributeArray& array, const bool expand = true);
723 
724  AttributeWriteHandle(AttributeArray& array, const bool expand = true);
725 
726  virtual ~AttributeWriteHandle() = default;
727 
730  void expand(bool fill = true);
731 
733  void collapse();
734  void collapse(const ValueType& uniformValue);
735 
737  bool compact();
738 
741  void fill(const ValueType& value);
742 
743  void set(Index n, const ValueType& value);
744  void set(Index n, Index m, const ValueType& value);
745 
746  AttributeArray& array();
747 
748 private:
749  friend class ::TestAttributeArray;
750 
751  template <bool IsUnknownCodec>
752  typename std::enable_if<IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
753 
754  template <bool IsUnknownCodec>
755  typename std::enable_if<!IsUnknownCodec, void>::type set(Index index, const ValueType& value) const;
756 }; // class AttributeWriteHandle
757 
758 
760 
761 
762 // Attribute codec implementation
763 
764 
765 template<typename ValueType>
766 inline void
767 NullCodec::decode(const ValueType& data, ValueType& val)
768 {
769  val = data;
770 }
771 
772 
773 template<typename ValueType>
774 inline void
775 NullCodec::encode(const ValueType& val, ValueType& data)
776 {
777  data = val;
778 }
779 
780 
781 template<typename StorageType, typename ValueType>
782 inline void
783 TruncateCodec::decode(const StorageType& data, ValueType& val)
784 {
785  val = static_cast<ValueType>(data);
786 }
787 
788 
789 template<typename StorageType, typename ValueType>
790 inline void
791 TruncateCodec::encode(const ValueType& val, StorageType& data)
792 {
793  data = static_cast<StorageType>(val);
794 }
795 
796 
797 template <bool OneByte, typename Range>
798 template<typename StorageType, typename ValueType>
799 inline void
800 FixedPointCodec<OneByte, Range>::decode(const StorageType& data, ValueType& val)
801 {
802  val = fixedPointToFloatingPoint<ValueType>(data);
803 
804  // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
805 
806  val = Range::template decode<ValueType>(val);
807 }
808 
809 
810 template <bool OneByte, typename Range>
811 template<typename StorageType, typename ValueType>
812 inline void
813 FixedPointCodec<OneByte, Range>::encode(const ValueType& val, StorageType& data)
814 {
815  // shift value range to be -0.5 => 0.5 (as this is most commonly used for position)
816 
817  const ValueType newVal = Range::template encode<ValueType>(val);
818 
819  data = floatingPointToFixedPoint<StorageType>(newVal);
820 }
821 
822 
823 template<typename T>
824 inline void
825 UnitVecCodec::decode(const StorageType& data, math::Vec3<T>& val)
826 {
827  val = math::QuantizedUnitVec::unpack(data);
828 }
829 
830 
831 template<typename T>
832 inline void
833 UnitVecCodec::encode(const math::Vec3<T>& val, StorageType& data)
834 {
835  data = math::QuantizedUnitVec::pack(val);
836 }
837 
838 
840 
841 // TypedAttributeArray implementation
842 
843 template<typename ValueType_, typename Codec_>
844 tbb::atomic<const NamePair*> TypedAttributeArray<ValueType_, Codec_>::sTypeName;
845 
846 
847 template<typename ValueType_, typename Codec_>
849  Index n, Index strideOrTotalSize, bool constantStride, const ValueType& uniformValue)
850  : mData(new StorageType[1])
851  , mSize(n)
852  , mStrideOrTotalSize(strideOrTotalSize)
853  , mIsUniform(true)
854 {
855  if (constantStride) {
856  this->setConstantStride(true);
857  if (strideOrTotalSize == 0) {
858  OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a constant stride requires that " \
859  "stride to be at least one.")
860  }
861  }
862  else {
863  this->setConstantStride(false);
864  if (mStrideOrTotalSize < n) {
865  OPENVDB_THROW(ValueError, "Creating a TypedAttributeArray with a non-constant stride must have " \
866  "a total size of at least the number of elements in the array.")
867  }
868  }
869  mSize = std::max(Index(1), mSize);
870  mStrideOrTotalSize = std::max(Index(1), mStrideOrTotalSize);
871  Codec::encode(uniformValue, mData.get()[0]);
872 }
873 
874 
875 template<typename ValueType_, typename Codec_>
877  : AttributeArray(rhs)
878  , mSize(rhs.mSize)
879  , mStrideOrTotalSize(rhs.mStrideOrTotalSize)
880  , mIsUniform(rhs.mIsUniform)
881 {
882  // disable uncompress if data is not compressed
883 
884  if (!this->isCompressed()) uncompress = false;
885 
886  if (this->isOutOfCore()) {
887  // do nothing
888  } else if (mIsUniform) {
889  this->allocate();
890  mData.get()[0] = rhs.mData.get()[0];
891  } else if (this->isCompressed()) {
892  std::unique_ptr<char[]> buffer;
893  if (uncompress) {
894  const char* charBuffer = reinterpret_cast<const char*>(rhs.mData.get());
895  size_t uncompressedBytes = compression::bloscUncompressedSize(charBuffer);
896  buffer = compression::bloscDecompress(charBuffer, uncompressedBytes);
897  }
898  if (buffer) {
899  mCompressedBytes = 0;
900  } else {
901  // decompression wasn't requested or failed so deep copy instead
902  buffer.reset(new char[mCompressedBytes]);
903  std::memcpy(buffer.get(), rhs.mData.get(), mCompressedBytes);
904  }
905  assert(buffer);
906  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
907  } else {
908  this->allocate();
909  std::memcpy(mData.get(), rhs.mData.get(), this->arrayMemUsage());
910  }
911 }
912 
913 
914 template<typename ValueType_, typename Codec_>
917 {
918  if (&rhs != this) {
919  tbb::spin_mutex::scoped_lock lock(mMutex);
920 
921  this->deallocate();
922 
923  mFlags = rhs.mFlags;
924  mSerializationFlags = rhs.mSerializationFlags;
925  mCompressedBytes = rhs.mCompressedBytes;
926  mSize = rhs.mSize;
927  mStrideOrTotalSize = rhs.mStrideOrTotalSize;
928  mIsUniform = rhs.mIsUniform;
929 
930  if (rhs.isOutOfCore()) {
931  mPageHandle = rhs.mPageHandle;
932  } else if (mIsUniform) {
933  this->allocate();
934  mData.get()[0] = rhs.mData.get()[0];
935  } else if (this->isCompressed()) {
936  std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
937  std::memcpy(buffer.get(), rhs.mData.get(), mCompressedBytes);
938  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
939  } else {
940  this->allocate();
941  std::memcpy(mData.get(), rhs.mData.get(), arrayMemUsage());
942  }
943  }
944 }
945 
946 
947 template<typename ValueType_, typename Codec_>
948 inline const NamePair&
950 {
951  if (sTypeName == nullptr) {
952  NamePair* s = new NamePair(typeNameAsString<ValueType>(), Codec::name());
953  if (sTypeName.compare_and_swap(s, nullptr) != nullptr) delete s;
954  }
955  return *sTypeName;
956 }
957 
958 
959 template<typename ValueType_, typename Codec_>
960 inline bool
962 {
964 }
965 
966 
967 template<typename ValueType_, typename Codec_>
968 inline void
970 {
971  AttributeArray::registerType(TypedAttributeArray::attributeType(), TypedAttributeArray::factory);
972 }
973 
974 
975 template<typename ValueType_, typename Codec_>
976 inline void
978 {
980 }
981 
982 
983 template<typename ValueType_, typename Codec_>
986 {
987  return Ptr(new TypedAttributeArray(n, stride, constantStride));
988 }
989 
990 template<typename ValueType_, typename Codec_>
993 {
994  if (!attributeArray.isType<TypedAttributeArray>()) {
995  OPENVDB_THROW(TypeError, "Invalid Attribute Type");
996  }
997  return static_cast<TypedAttributeArray&>(attributeArray);
998 }
999 
1000 template<typename ValueType_, typename Codec_>
1003 {
1004  if (!attributeArray.isType<TypedAttributeArray>()) {
1005  OPENVDB_THROW(TypeError, "Invalid Attribute Type");
1006  }
1007  return static_cast<const TypedAttributeArray&>(attributeArray);
1008 }
1009 
1010 template<typename ValueType_, typename Codec_>
1013 {
1015 }
1016 
1017 
1018 template<typename ValueType_, typename Codec_>
1021 {
1022  return AttributeArray::Ptr(new TypedAttributeArray<ValueType, Codec>(*this, /*decompress = */true));
1023 }
1024 
1025 
1026 template<typename ValueType_, typename Codec_>
1027 size_t
1029 {
1030  if (this->isOutOfCore()) return 0;
1031  if (this->isCompressed()) return mCompressedBytes;
1032 
1033  return (mIsUniform ? 1 : this->dataSize()) * sizeof(StorageType);
1034 }
1035 
1036 
1037 template<typename ValueType_, typename Codec_>
1038 void
1039 TypedAttributeArray<ValueType_, Codec_>::allocate()
1040 {
1041  assert(!mData);
1042  if (mIsUniform) {
1043  mData.reset(new StorageType[1]);
1044  }
1045  else {
1046  const size_t size(this->dataSize());
1047  assert(size > 0);
1048  mData.reset(new StorageType[size]);
1049  }
1050 }
1051 
1052 
1053 template<typename ValueType_, typename Codec_>
1054 void
1055 TypedAttributeArray<ValueType_, Codec_>::deallocate()
1056 {
1057  // detach from file if delay-loaded
1058  if (this->isOutOfCore()) {
1059  this->setOutOfCore(false);
1060  this->mPageHandle.reset();
1061  }
1062  if (mData) mData.reset();
1063 }
1064 
1065 
1066 template<typename ValueType_, typename Codec_>
1067 size_t
1069 {
1070  return sizeof(*this) + (bool(mData) ? this->arrayMemUsage() : 0);
1071 }
1072 
1073 
1074 template<typename ValueType_, typename Codec_>
1077 {
1078  assert(n < this->dataSize());
1079  assert(!this->isOutOfCore());
1080  assert(!this->isCompressed());
1081 
1082  ValueType val;
1083  Codec::decode(/*in=*/mData.get()[mIsUniform ? 0 : n], /*out=*/val);
1084  return val;
1085 }
1086 
1087 
1088 template<typename ValueType_, typename Codec_>
1091 {
1092  if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1093  if (this->isOutOfCore()) this->doLoad();
1094  if (this->isCompressed()) const_cast<TypedAttributeArray*>(this)->decompress();
1095 
1096  return this->getUnsafe(n);
1097 }
1098 
1099 
1100 template<typename ValueType_, typename Codec_>
1101 template<typename T>
1102 void
1104 {
1105  val = static_cast<T>(this->getUnsafe(n));
1106 }
1107 
1108 
1109 template<typename ValueType_, typename Codec_>
1110 template<typename T>
1111 void
1113 {
1114  val = static_cast<T>(this->get(n));
1115 }
1116 
1117 
1118 template<typename ValueType_, typename Codec_>
1121 {
1122  return static_cast<const TypedAttributeArray<ValueType, Codec>*>(array)->getUnsafe(n);
1123 }
1124 
1125 
1126 template<typename ValueType_, typename Codec_>
1127 void
1129 {
1130  assert(n < this->dataSize());
1131  assert(!this->isOutOfCore());
1132  assert(!this->isCompressed());
1133  assert(!this->isUniform());
1134 
1135  // this unsafe method assumes the data is not uniform, however if it is, this redirects the index
1136  // to zero, which is marginally less efficient but ensures not writing to an illegal address
1137 
1138  Codec::encode(/*in=*/val, /*out=*/mData.get()[mIsUniform ? 0 : n]);
1139 }
1140 
1141 
1142 template<typename ValueType_, typename Codec_>
1143 void
1145 {
1146  if (n >= this->dataSize()) OPENVDB_THROW(IndexError, "Out-of-range access.");
1147  if (this->isOutOfCore()) this->doLoad();
1148  if (this->isCompressed()) this->decompress();
1149  if (this->isUniform()) this->expand();
1150 
1151  this->setUnsafe(n, val);
1152 }
1153 
1154 
1155 template<typename ValueType_, typename Codec_>
1156 template<typename T>
1157 void
1159 {
1160  this->setUnsafe(n, static_cast<ValueType>(val));
1161 }
1162 
1163 
1164 template<typename ValueType_, typename Codec_>
1165 template<typename T>
1166 void
1168 {
1169  this->set(n, static_cast<ValueType>(val));
1170 }
1171 
1172 
1173 template<typename ValueType_, typename Codec_>
1174 void
1176 {
1177  static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->setUnsafe(n, value);
1178 }
1179 
1180 
1181 template<typename ValueType_, typename Codec_>
1182 void
1184 {
1185  const TypedAttributeArray& sourceTypedArray = static_cast<const TypedAttributeArray&>(sourceArray);
1186 
1187  ValueType sourceValue;
1188  sourceTypedArray.get(sourceIndex, sourceValue);
1189 
1190  this->set(n, sourceValue);
1191 }
1192 
1193 
1194 template<typename ValueType_, typename Codec_>
1195 void
1197 {
1198  if (!mIsUniform) return;
1199 
1200  const StorageType val = mData.get()[0];
1201 
1202  {
1203  tbb::spin_mutex::scoped_lock lock(mMutex);
1204  this->deallocate();
1205  mIsUniform = false;
1206  this->allocate();
1207  }
1208 
1209  mCompressedBytes = 0;
1210 
1211  if (fill) {
1212  for (Index i = 0; i < this->dataSize(); ++i) mData.get()[i] = val;
1213  }
1214 }
1215 
1216 
1217 template<typename ValueType_, typename Codec_>
1218 bool
1220 {
1221  if (mIsUniform) return true;
1222 
1223  // compaction is not possible if any values are different
1224  const ValueType_ val = this->get(0);
1225  for (Index i = 1; i < this->dataSize(); i++) {
1226  if (!math::isExactlyEqual(this->get(i), val)) return false;
1227  }
1228 
1229  this->collapse(this->get(0));
1230  return true;
1231 }
1232 
1233 
1234 template<typename ValueType_, typename Codec_>
1235 void
1237 {
1238  this->collapse(zeroVal<ValueType>());
1239 }
1240 
1241 
1242 template<typename ValueType_, typename Codec_>
1243 void
1245 {
1246  if (!mIsUniform) {
1247  tbb::spin_mutex::scoped_lock lock(mMutex);
1248  this->deallocate();
1249  mIsUniform = true;
1250  this->allocate();
1251  }
1252  Codec::encode(uniformValue, mData.get()[0]);
1253 }
1254 
1255 
1256 template<typename ValueType_, typename Codec_>
1257 void
1259 {
1260  static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->collapse(value);
1261 }
1262 
1263 
1264 template<typename ValueType_, typename Codec_>
1265 void
1267 {
1268  if (this->isOutOfCore()) {
1269  tbb::spin_mutex::scoped_lock lock(mMutex);
1270  this->deallocate();
1271  this->allocate();
1272  }
1273 
1274  const Index size = mIsUniform ? 1 : this->dataSize();
1275  for (Index i = 0; i < size; ++i) {
1276  Codec::encode(value, mData.get()[i]);
1277  }
1278 }
1279 
1280 
1281 template<typename ValueType_, typename Codec_>
1282 void
1284 {
1285  static_cast<TypedAttributeArray<ValueType, Codec>*>(array)->fill(value);
1286 }
1287 
1288 
1289 template<typename ValueType_, typename Codec_>
1290 inline bool
1292 {
1293  if (!compression::bloscCanCompress()) return false;
1294 
1295  if (!mIsUniform && !this->isCompressed()) {
1296 
1297  tbb::spin_mutex::scoped_lock lock(mMutex);
1298 
1299  this->doLoadUnsafe(/*compression=*/false);
1300 
1301  if (this->isCompressed()) return true;
1302 
1303  return this->compressUnsafe();
1304  }
1305 
1306  return false;
1307 }
1308 
1309 
1310 template<typename ValueType_, typename Codec_>
1311 inline bool
1313 {
1314  if (!compression::bloscCanCompress()) return false;
1315  if (mIsUniform) return false;
1316 
1317  // assumes mutex is locked and data is not out-of-core
1318 
1319  const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1320  const size_t inBytes = writeCompress ? mCompressedBytes : this->arrayMemUsage();
1321 
1322  if (inBytes > 0) {
1323  size_t outBytes;
1324  const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1325  std::unique_ptr<char[]> buffer = compression::bloscCompress(charBuffer, inBytes, outBytes);
1326  if (buffer) {
1327  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1328  mCompressedBytes = outBytes;
1329  return true;
1330  }
1331  }
1332 
1333  return false;
1334 }
1335 
1336 
1337 template<typename ValueType_, typename Codec_>
1338 inline bool
1340 {
1341  tbb::spin_mutex::scoped_lock lock(mMutex);
1342 
1343  const bool writeCompress = (mSerializationFlags & WRITEMEMCOMPRESS);
1344 
1345  if (writeCompress) {
1346  this->doLoadUnsafe(/*compression=*/false);
1347  return true;
1348  }
1349 
1350  if (this->isCompressed()) {
1351  this->doLoadUnsafe();
1352  const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1353  size_t uncompressedBytes = compression::bloscUncompressedSize(charBuffer);
1354  std::unique_ptr<char[]> buffer = compression::bloscDecompress(charBuffer, uncompressedBytes);
1355  if (buffer) {
1356  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1357  mCompressedBytes = 0;
1358  return true;
1359  }
1360  }
1361 
1362  return false;
1363 }
1364 
1365 
1366 template<typename ValueType_, typename Codec_>
1367 bool
1369 {
1370 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1371  return mOutOfCore;
1372 #else
1373  return (mFlags & OUTOFCORE);
1374 #endif
1375 }
1376 
1377 
1378 template<typename ValueType_, typename Codec_>
1379 void
1381 {
1382 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1383  mOutOfCore = b;
1384 #else
1385  if (b) mFlags = static_cast<uint8_t>(mFlags | OUTOFCORE);
1386  else mFlags = static_cast<uint8_t>(mFlags & ~OUTOFCORE);
1387 #endif
1388 }
1389 
1390 
1391 template<typename ValueType_, typename Codec_>
1392 void
1393 TypedAttributeArray<ValueType_, Codec_>::doLoad() const
1394 {
1395  if (!(this->isOutOfCore())) return;
1396 
1397  TypedAttributeArray<ValueType_, Codec_>* self =
1398  const_cast<TypedAttributeArray<ValueType_, Codec_>*>(this);
1399 
1400  // This lock will be contended at most once, after which this buffer
1401  // will no longer be out-of-core.
1402  tbb::spin_mutex::scoped_lock lock(self->mMutex);
1403  this->doLoadUnsafe();
1404 }
1405 
1406 
1407 template<typename ValueType_, typename Codec_>
1408 void
1410 {
1411  this->doLoad();
1412 }
1413 
1414 
1415 template<typename ValueType_, typename Codec_>
1416 void
1418 {
1419  this->readMetadata(is);
1420  this->readBuffers(is);
1421 }
1422 
1423 
1424 template<typename ValueType_, typename Codec_>
1425 void
1427 {
1428  // read data
1429 
1430  Index64 bytes = Index64(0);
1431  is.read(reinterpret_cast<char*>(&bytes), sizeof(Index64));
1432  bytes = bytes - /*flags*/sizeof(Int16) - /*size*/sizeof(Index);
1433 
1434  uint8_t flags = uint8_t(0);
1435  is.read(reinterpret_cast<char*>(&flags), sizeof(uint8_t));
1436  mFlags = flags;
1437 
1438  uint8_t serializationFlags = uint8_t(0);
1439  is.read(reinterpret_cast<char*>(&serializationFlags), sizeof(uint8_t));
1440  mSerializationFlags = serializationFlags;
1441 
1442  Index size = Index(0);
1443  is.read(reinterpret_cast<char*>(&size), sizeof(Index));
1444  mSize = size;
1445 
1446  // warn if an unknown flag has been set
1447  if (mFlags >= 0x20) {
1448  OPENVDB_LOG_WARN("Unknown attribute flags for VDB file format.");
1449  }
1450  // error if an unknown serialization flag has been set,
1451  // as this will adjust the layout of the data and corrupt the ability to read
1452  if (mSerializationFlags >= 0x10) {
1453  OPENVDB_THROW(IoError, "Unknown attribute serialization flags for VDB file format.");
1454  }
1455 
1456  // read uniform and compressed state
1457 
1458  mIsUniform = mSerializationFlags & WRITEUNIFORM;
1459  mCompressedBytes = bytes;
1460 
1461  // read strided value (set to 1 if array is not strided)
1462 
1463  if (mSerializationFlags & WRITESTRIDED) {
1464  Index stride = Index(0);
1465  is.read(reinterpret_cast<char*>(&stride), sizeof(Index));
1466  mStrideOrTotalSize = stride;
1467  }
1468  else {
1469  mStrideOrTotalSize = 1;
1470  }
1471 }
1472 
1473 
1474 template<typename ValueType_, typename Codec_>
1475 void
1477 {
1478  if ((mSerializationFlags & WRITEPAGED)) {
1479  // use readBuffers(PagedInputStream&) for paged buffers
1480  OPENVDB_THROW(IoError, "Cannot read paged AttributeArray buffers.");
1481  }
1482 
1483  tbb::spin_mutex::scoped_lock lock(mMutex);
1484 
1485  this->deallocate();
1486 
1487  uint8_t bloscCompressed(0);
1488  if (!mIsUniform) is.read(reinterpret_cast<char*>(&bloscCompressed), sizeof(uint8_t));
1489 
1490  std::unique_ptr<char[]> buffer(new char[mCompressedBytes]);
1491  is.read(buffer.get(), mCompressedBytes);
1492 
1493  if (mIsUniform) {
1494  // zero compressed bytes as uniform values are not compressed in memory
1495  mCompressedBytes = Index64(0);
1496  }
1497  else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1498  // zero compressed bytes if not compressed in memory
1499  mCompressedBytes = Index64(0);
1500  }
1501 
1502  // compressed on-disk
1503 
1504  if (bloscCompressed == uint8_t(1)) {
1505 
1506  // decompress buffer
1507 
1508  const size_t inBytes = this->dataSize() * sizeof(StorageType);
1509  std::unique_ptr<char[]> newBuffer = compression::bloscDecompress(buffer.get(), inBytes);
1510  if (newBuffer) buffer.reset(newBuffer.release());
1511  }
1512 
1513  // set data to buffer
1514 
1515  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1516 
1517  // clear all write flags
1518 
1519  if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1520  else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1521 }
1522 
1523 
1524 template<typename ValueType_, typename Codec_>
1525 void
1527 {
1528  if (!(mSerializationFlags & WRITEPAGED)) {
1529  if (!is.sizeOnly()) this->readBuffers(is.getInputStream());
1530  return;
1531  }
1532 
1533  // If this array is being read from a memory-mapped file, delay loading of its data
1534  // until the data is actually accessed.
1536  const bool delayLoad = (mappedFile.get() != nullptr);
1537 
1538  if (is.sizeOnly())
1539  {
1540  mPageHandle = is.createHandle(mCompressedBytes);
1541  return;
1542  }
1543 
1544  assert(mPageHandle);
1545 
1546  tbb::spin_mutex::scoped_lock lock(mMutex);
1547 
1548  this->deallocate();
1549 
1550  this->setOutOfCore(delayLoad);
1551  is.read(mPageHandle, mCompressedBytes, delayLoad);
1552 
1553  if (!delayLoad) {
1554  std::unique_ptr<char[]> buffer = mPageHandle->read();
1555  mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1556  }
1557 
1558  // zero compressed bytes as not compressed in memory
1559 
1560  if (mIsUniform) {
1561  // zero compressed bytes as uniform values are not compressed in memory
1562  mCompressedBytes = Index64(0);
1563  }
1564  else if (!(mSerializationFlags & WRITEMEMCOMPRESS)) {
1565  mCompressedBytes = Index64(0);
1566  }
1567 
1568  // clear all write flags
1569 
1570  if (mIsUniform) mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1571  else mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEPAGED);
1572 }
1573 
1574 
1575 template<typename ValueType_, typename Codec_>
1576 void
1578 {
1579  this->write(os, /*outputTransient=*/false);
1580 }
1581 
1582 
1583 template<typename ValueType_, typename Codec_>
1584 void
1585 TypedAttributeArray<ValueType_, Codec_>::write(std::ostream& os, bool outputTransient) const
1586 {
1587  this->writeMetadata(os, outputTransient, /*paged=*/false);
1588  this->writeBuffers(os, outputTransient);
1589 }
1590 
1591 
1592 template<typename ValueType_, typename Codec_>
1593 void
1594 TypedAttributeArray<ValueType_, Codec_>::writeMetadata(std::ostream& os, bool outputTransient, bool paged) const
1595 {
1596  if (!outputTransient && this->isTransient()) return;
1597 
1598 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1599  uint8_t flags(mFlags);
1600 #else
1601  uint8_t flags(mFlags & uint8_t(~OUTOFCORE));
1602 #endif
1603  uint8_t serializationFlags(0);
1604  Index size(mSize);
1605  Index stride(mStrideOrTotalSize);
1606  bool strideOfOne(this->stride() == 1);
1607 
1608  bool bloscCompression = io::getDataCompression(os) & io::COMPRESS_BLOSC;
1609 
1610  // any compressed data needs to be loaded if out-of-core
1611  if (bloscCompression || this->isCompressed()) this->doLoad();
1612 
1613  size_t compressedBytes = 0;
1614 
1615  if (!strideOfOne)
1616  {
1617  serializationFlags |= WRITESTRIDED;
1618  }
1619 
1620  if (mIsUniform)
1621  {
1622  serializationFlags |= WRITEUNIFORM;
1623  if (bloscCompression && paged) serializationFlags |= WRITEPAGED;
1624  }
1625  else if (bloscCompression && paged)
1626  {
1627  serializationFlags |= WRITEPAGED;
1628  if (this->isCompressed()) {
1629  serializationFlags |= WRITEMEMCOMPRESS;
1630  const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1631  compressedBytes = compression::bloscUncompressedSize(charBuffer);
1632  }
1633  }
1634  else if (this->isCompressed())
1635  {
1636  serializationFlags |= WRITEMEMCOMPRESS;
1637  compressedBytes = mCompressedBytes;
1638  }
1639  else if (bloscCompression)
1640  {
1641  const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1642  const size_t inBytes = this->arrayMemUsage();
1643  compressedBytes = compression::bloscCompressedSize(charBuffer, inBytes);
1644  }
1645 
1646  Index64 bytes = /*flags*/ sizeof(Int16) + /*size*/ sizeof(Index);
1647 
1648  bytes += (compressedBytes > 0) ? compressedBytes : this->arrayMemUsage();
1649 
1650  // write data
1651 
1652  os.write(reinterpret_cast<const char*>(&bytes), sizeof(Index64));
1653  os.write(reinterpret_cast<const char*>(&flags), sizeof(uint8_t));
1654  os.write(reinterpret_cast<const char*>(&serializationFlags), sizeof(uint8_t));
1655  os.write(reinterpret_cast<const char*>(&size), sizeof(Index));
1656 
1657  // write strided
1658  if (!strideOfOne) os.write(reinterpret_cast<const char*>(&stride), sizeof(Index));
1659 }
1660 
1661 
1662 template<typename ValueType_, typename Codec_>
1663 void
1664 TypedAttributeArray<ValueType_, Codec_>::writeBuffers(std::ostream& os, bool outputTransient) const
1665 {
1666  if (!outputTransient && this->isTransient()) return;
1667 
1668  this->doLoad();
1669 
1670  if (this->isUniform()) {
1671  os.write(reinterpret_cast<const char*>(mData.get()), sizeof(StorageType));
1672  }
1673  else if (this->isCompressed())
1674  {
1675  uint8_t bloscCompressed(0);
1676  os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1677  os.write(reinterpret_cast<const char*>(mData.get()), mCompressedBytes);
1678  }
1680  {
1681  std::unique_ptr<char[]> compressedBuffer;
1682  size_t compressedBytes = 0;
1683  const char* charBuffer = reinterpret_cast<const char*>(mData.get());
1684  const size_t inBytes = this->arrayMemUsage();
1685  compressedBuffer = compression::bloscCompress(charBuffer, inBytes, compressedBytes);
1686  if (compressedBuffer) {
1687  uint8_t bloscCompressed(1);
1688  os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1689  os.write(reinterpret_cast<const char*>(compressedBuffer.get()), compressedBytes);
1690  }
1691  else {
1692  uint8_t bloscCompressed(0);
1693  os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1694  os.write(reinterpret_cast<const char*>(mData.get()), inBytes);
1695  }
1696  }
1697  else
1698  {
1699  uint8_t bloscCompressed(0);
1700  os.write(reinterpret_cast<const char*>(&bloscCompressed), sizeof(uint8_t));
1701  os.write(reinterpret_cast<const char*>(mData.get()), this->arrayMemUsage());
1702  }
1703 }
1704 
1705 
1706 template<typename ValueType_, typename Codec_>
1707 void
1709 {
1710  if (!outputTransient && this->isTransient()) return;
1711 
1712  // paged compression only available when Blosc is enabled
1713  bool bloscCompression = io::getDataCompression(os.getOutputStream()) & io::COMPRESS_BLOSC;
1714  if (!bloscCompression) {
1715  if (!os.sizeOnly()) this->writeBuffers(os.getOutputStream(), outputTransient);
1716  return;
1717  }
1718 
1719  this->doLoad();
1720 
1721  const char* buffer;
1722  size_t bytes;
1723 
1724  std::unique_ptr<char[]> uncompressedBuffer;
1725  if (this->isCompressed()) {
1726  // paged streams require uncompressed buffers, so locally decompress
1727 
1728  const char* charBuffer = reinterpret_cast<const char*>(this->mData.get());
1729  bytes = compression::bloscUncompressedSize(charBuffer);
1730  uncompressedBuffer = compression::bloscDecompress(charBuffer, bytes);
1731  buffer = reinterpret_cast<const char*>(uncompressedBuffer.get());
1732  }
1733  else {
1734  buffer = reinterpret_cast<const char*>(mData.get());
1735  bytes = this->arrayMemUsage();
1736  }
1737 
1738  os.write(buffer, bytes);
1739 }
1740 
1741 
1742 template<typename ValueType_, typename Codec_>
1743 void
1744 TypedAttributeArray<ValueType_, Codec_>::doLoadUnsafe(const bool compression) const
1745 {
1746  if (!(this->isOutOfCore())) return;
1747 
1748  // this function expects the mutex to already be locked
1749 
1751 
1752  assert(self->mPageHandle);
1753 
1754  std::unique_ptr<char[]> buffer = self->mPageHandle->read();
1755 
1756  self->mData.reset(reinterpret_cast<StorageType*>(buffer.release()));
1757 
1758  self->mPageHandle.reset();
1759 
1760  // if data was compressed prior to being written to disk, re-compress
1761 
1762  if (self->mSerializationFlags & WRITEMEMCOMPRESS) {
1763  if (compression) self->compressUnsafe();
1764  else self->mCompressedBytes = 0;
1765  }
1766 
1767  // clear all write and out-of-core flags
1768 
1769 #if OPENVDB_ABI_VERSION_NUMBER >= 5
1770  self->mOutOfCore = false;
1771 #else
1772  self->mFlags &= uint8_t(~OUTOFCORE);
1773 #endif
1774  self->mSerializationFlags &= uint8_t(~WRITEUNIFORM & ~WRITEMEMCOMPRESS & ~WRITEPAGED);
1775 }
1776 
1777 
1778 template<typename ValueType_, typename Codec_>
1781 {
1782  // use the faster 'unsafe' get and set methods as attribute handles
1783  // ensure data is uncompressed and in-core when constructed
1784 
1790 }
1791 
1792 
1793 template<typename ValueType_, typename Codec_>
1794 bool
1796 {
1797  const TypedAttributeArray<ValueType_, Codec_>* const otherT = dynamic_cast<const TypedAttributeArray<ValueType_, Codec_>* >(&other);
1798  if(!otherT) return false;
1799  if(this->mSize != otherT->mSize ||
1800  this->mStrideOrTotalSize != otherT->mStrideOrTotalSize ||
1801  this->mIsUniform != otherT->mIsUniform ||
1802  *this->sTypeName != *otherT->sTypeName) return false;
1803 
1804  this->doLoad();
1805  otherT->doLoad();
1806 
1807  const StorageType *target = this->mData.get(), *source = otherT->mData.get();
1808  if (!target && !source) return true;
1809  if (!target || !source) return false;
1810  Index n = this->mIsUniform ? 1 : mSize;
1811  while (n && math::isExactlyEqual(*target++, *source++)) --n;
1812  return n == 0;
1813 }
1814 
1816 
1817 
1819 template <typename CodecType, typename ValueType>
1821 {
1822  using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
1823  using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
1824 
1827  static ValueType get(GetterPtr /*functor*/, const AttributeArray* array, const Index n) {
1829  }
1830 
1833  static void set(SetterPtr /*functor*/, AttributeArray* array, const Index n, const ValueType& value) {
1835  }
1836 };
1837 
1838 
1840 template <typename ValueType>
1841 struct AccessorEval<UnknownCodec, ValueType>
1842 {
1843  using GetterPtr = ValueType (*)(const AttributeArray* array, const Index n);
1844  using SetterPtr = void (*)(AttributeArray* array, const Index n, const ValueType& value);
1845 
1847  static ValueType get(GetterPtr functor, const AttributeArray* array, const Index n) {
1848  return (*functor)(array, n);
1849  }
1850 
1852  static void set(SetterPtr functor, AttributeArray* array, const Index n, const ValueType& value) {
1853  (*functor)(array, n, value);
1854  }
1855 };
1856 
1857 
1859 
1860 // AttributeHandle implementation
1861 
1862 template <typename ValueType, typename CodecType>
1864 AttributeHandle<ValueType, CodecType>::create(const AttributeArray& array, const bool preserveCompression)
1865 {
1867  new AttributeHandle<ValueType, CodecType>(array, preserveCompression));
1868 }
1869 
1870 template <typename ValueType, typename CodecType>
1871 AttributeHandle<ValueType, CodecType>::AttributeHandle(const AttributeArray& array, const bool preserveCompression)
1872  : mArray(&array)
1873  , mStrideOrTotalSize(array.hasConstantStride() ? array.stride() : 1)
1874  , mSize(array.hasConstantStride() ? array.size() : array.dataSize())
1875  , mCollapseOnDestruction(preserveCompression && array.isStreaming())
1876 {
1877  if (!this->compatibleType<std::is_same<CodecType, UnknownCodec>::value>()) {
1878  OPENVDB_THROW(TypeError, "Cannot bind handle due to incompatible type of AttributeArray.");
1879  }
1880 
1881  // load data if delay-loaded
1882 
1883  mArray->loadData();
1884 
1885  // if array is compressed and preserve compression is true, copy and decompress
1886  // into a local copy that is destroyed with handle to maintain thread-safety
1887 
1888  if (array.isCompressed())
1889  {
1890  if (preserveCompression && !array.isStreaming()) {
1891  mLocalArray = array.copyUncompressed();
1892  mLocalArray->decompress();
1893  mArray = mLocalArray.get();
1894  }
1895  else {
1896  const_cast<AttributeArray*>(mArray)->decompress();
1897  }
1898  }
1899 
1900  // bind getter and setter methods
1901 
1902  AttributeArray::AccessorBasePtr accessor = mArray->getAccessor();
1903  assert(accessor);
1904 
1905  AttributeArray::Accessor<ValueType>* typedAccessor = static_cast<AttributeArray::Accessor<ValueType>*>(accessor.get());
1906 
1907  mGetter = typedAccessor->mGetter;
1908  mSetter = typedAccessor->mSetter;
1909  mCollapser = typedAccessor->mCollapser;
1910  mFiller = typedAccessor->mFiller;
1911 }
1912 
1913 template <typename ValueType, typename CodecType>
1915 {
1916  // if enabled, attribute is collapsed on destruction of the handle to save memory
1917  if (mCollapseOnDestruction) const_cast<AttributeArray*>(this->mArray)->collapse();
1918 }
1919 
1920 template <typename ValueType, typename CodecType>
1921 template <bool IsUnknownCodec>
1922 typename std::enable_if<IsUnknownCodec, bool>::type
1924 {
1925  // if codec is unknown, just check the value type
1926 
1927  return mArray->hasValueType<ValueType>();
1928 }
1929 
1930 template <typename ValueType, typename CodecType>
1931 template <bool IsUnknownCodec>
1932 typename std::enable_if<!IsUnknownCodec, bool>::type
1933 AttributeHandle<ValueType, CodecType>::compatibleType() const
1934 {
1935  // if the codec is known, check the value type and codec
1936 
1937  return mArray->isType<TypedAttributeArray<ValueType, CodecType>>();
1938 }
1939 
1940 template <typename ValueType, typename CodecType>
1942 {
1943  assert(mArray);
1944  return *mArray;
1945 }
1946 
1947 template <typename ValueType, typename CodecType>
1949 {
1950  Index index = n * mStrideOrTotalSize + m;
1951  assert(index < (mSize * mStrideOrTotalSize));
1952  return index;
1953 }
1954 
1955 template <typename ValueType, typename CodecType>
1957 {
1958  return this->get<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m));
1959 }
1960 
1961 template <typename ValueType, typename CodecType>
1962 template <bool IsUnknownCodec>
1963 typename std::enable_if<IsUnknownCodec, ValueType>::type
1965 {
1966  // if the codec is unknown, use the getter functor
1967 
1968  return (*mGetter)(mArray, index);
1969 }
1970 
1971 template <typename ValueType, typename CodecType>
1972 template <bool IsUnknownCodec>
1973 typename std::enable_if<!IsUnknownCodec, ValueType>::type
1974 AttributeHandle<ValueType, CodecType>::get(Index index) const
1975 {
1976  // if the codec is known, call the method on the attribute array directly
1977 
1978  return TypedAttributeArray<ValueType, CodecType>::getUnsafe(mArray, index);
1979 }
1980 
1981 template <typename ValueType, typename CodecType>
1983 {
1984  return mArray->isUniform();
1985 }
1986 
1987 template <typename ValueType, typename CodecType>
1989 {
1990  return mArray->hasConstantStride();
1991 }
1992 
1994 
1995 // AttributeWriteHandle implementation
1996 
1997 template <typename ValueType, typename CodecType>
2000 {
2002  new AttributeWriteHandle<ValueType, CodecType>(array, expand));
2003 }
2004 
2005 template <typename ValueType, typename CodecType>
2007  : AttributeHandle<ValueType, CodecType>(array, /*preserveCompression = */ false)
2008 {
2009  if (expand) array.expand();
2010 }
2011 
2012 template <typename ValueType, typename CodecType>
2014 {
2015  this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, 0), value);
2016 }
2017 
2018 template <typename ValueType, typename CodecType>
2020 {
2021  this->set<std::is_same<CodecType, UnknownCodec>::value>(this->index(n, m), value);
2022 }
2023 
2024 template <typename ValueType, typename CodecType>
2026 {
2027  const_cast<AttributeArray*>(this->mArray)->expand(fill);
2028 }
2029 
2030 template <typename ValueType, typename CodecType>
2032 {
2033  const_cast<AttributeArray*>(this->mArray)->collapse();
2034 }
2035 
2036 template <typename ValueType, typename CodecType>
2038 {
2039  return const_cast<AttributeArray*>(this->mArray)->compact();
2040 }
2041 
2042 template <typename ValueType, typename CodecType>
2043 void AttributeWriteHandle<ValueType, CodecType>::collapse(const ValueType& uniformValue)
2044 {
2045  this->mCollapser(const_cast<AttributeArray*>(this->mArray), uniformValue);
2046 }
2047 
2048 template <typename ValueType, typename CodecType>
2050 {
2051  this->mFiller(const_cast<AttributeArray*>(this->mArray), value);
2052 }
2053 
2054 template <typename ValueType, typename CodecType>
2055 template <bool IsUnknownCodec>
2056 typename std::enable_if<IsUnknownCodec, void>::type
2057 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2058 {
2059  // if the codec is unknown, use the setter functor
2060 
2061  (*this->mSetter)(const_cast<AttributeArray*>(this->mArray), index, value);
2062 }
2063 
2064 template <typename ValueType, typename CodecType>
2065 template <bool IsUnknownCodec>
2066 typename std::enable_if<!IsUnknownCodec, void>::type
2067 AttributeWriteHandle<ValueType, CodecType>::set(Index index, const ValueType& value) const
2068 {
2069  // if the codec is known, call the method on the attribute array directly
2070 
2071  TypedAttributeArray<ValueType, CodecType>::setUnsafe(const_cast<AttributeArray*>(this->mArray), index, value);
2072 }
2073 
2074 template <typename ValueType, typename CodecType>
2076 {
2077  assert(this->mArray);
2078  return *const_cast<AttributeArray*>(this->mArray);
2079 }
2080 
2081 
2082 } // namespace points
2083 } // namespace OPENVDB_VERSION_NAME
2084 } // namespace openvdb
2085 
2086 #endif // OPENVDB_POINTS_ATTRIBUTE_ARRAY_HAS_BEEN_INCLUDED
2087 
2088 // Copyright (c) 2012-2018 DreamWorks Animation LLC
2089 // All rights reserved. This software is distributed under the
2090 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v5_2::compression::PagedOutputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:273
openvdb::v5_2::IoError
Definition: Exceptions.h:85
openvdb::v5_2::compression::bloscCompressedSize
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
openvdb::v5_2::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
openvdb::v5_2::points::AttributeArray::isHidden
bool isHidden() const
Return true if this attribute is hidden (e.g., from UI or iterators).
Definition: AttributeArray.h:218
openvdb::v5_2::points::AttributeArray::unregisterType
static void unregisterType(const NamePair &type)
Remove a attribute type from the registry.
openvdb::v5_2::points::TruncateCodec::Storage::Type
typename attribute_traits::TruncateTrait< T >::Type Type
Definition: AttributeArray.h:381
openvdb::v5_2::points::AttributeArray::AccessorBasePtr
std::shared_ptr< AccessorBase > AccessorBasePtr
Definition: AttributeArray.h:124
StreamCompression.h
Convenience wrappers to using Blosc and reading and writing of Paged data.
openvdb::v5_2::points::AccessorEval< UnknownCodec, ValueType >::set
static void set(SetterPtr functor, AttributeArray *array, const Index n, const ValueType &value)
Setter that calls the supplied functor.
Definition: AttributeArray.h:1852
openvdb::v5_2::points::TypedAttributeArray::writeBuffers
void writeBuffers(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1664
openvdb::v5_2::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:395
openvdb::v5_2::points::TypedAttributeArray::isUniform
bool isUniform() const override
Return true if this array is stored as a single uniform value.
Definition: AttributeArray.h:539
openvdb::v5_2::points::TypedAttributeArray::create
static Ptr create(Index n, Index strideOrTotalSize=1, bool constantStride=true)
Return a new attribute array of the given length n and stride with uniform value zero.
Definition: AttributeArray.h:985
openvdb::v5_2::points::TypedAttributeArray
Typed class for storing attribute data.
Definition: AttributeArray.h:441
openvdb::v5_2::points::TypedAttributeArray::writeMetadata
void writeMetadata(std::ostream &os, bool outputTransient, bool paged) const override
Definition: AttributeArray.h:1594
openvdb::v5_2::points::AccessorEval::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:1822
openvdb::v5_2::points::UnitRange
Definition: AttributeArray.h:399
openvdb::v5_2::points::TypedAttributeArray::readBuffers
void readBuffers(std::istream &) override
Read attribute buffers from a stream.
Definition: AttributeArray.h:1476
openvdb::v5_2::NamePair
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:65
openvdb::v5_2::points::NullCodec::name
static const char * name()
Definition: AttributeArray.h:374
openvdb::v5_2::compression::PagedInputStream
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition: StreamCompression.h:225
openvdb::v5_2::points::AttributeWriteHandle::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:719
openvdb::v5_2::compression::PagedOutputStream
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition: StreamCompression.h:262
openvdb::v5_2::points::AttributeHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::SetterPtr
void(*)(AttributeArray *array, const Index n, const StringIndexType &value) SetterPtr
Definition: AttributeArray.h:653
openvdb::v5_2::points::AttributeArray::FactoryMethod
Ptr(*)(Index, Index, bool) FactoryMethod
Definition: AttributeArray.h:145
openvdb::v5_2::math::Vec3::x
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:110
openvdb::v5_2::points::UnitRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:403
openvdb::v5_2::points::AttributeHandle::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:682
openvdb::v5_2::points::TypedAttributeArray::write
void write(std::ostream &os, bool outputTransient) const override
Definition: AttributeArray.h:1585
openvdb::v5_2::points::TypedAttributeArray::get
ValueType get(Index n) const
Return the value at index n.
Definition: AttributeArray.h:1090
openvdb::v5_2::points::AttributeArray::Accessor::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:330
openvdb::v5_2::compression::bloscCanCompress
OPENVDB_API bool bloscCanCompress()
Returns true if compression is available.
openvdb::v5_2::points::UnitVecCodec::Storage::Type
StorageType Type
Definition: AttributeArray.h:428
openvdb::v5_2::points::attribute_traits::UIntTypeTrait< true, T >::Type
uint8_t Type
Definition: AttributeArray.h:348
openvdb::v5_2::points::TypedAttributeArray::memUsage
size_t memUsage() const override
Return the number of bytes of memory used by this attribute.
Definition: AttributeArray.h:1068
openvdb::v5_2::points::TypedAttributeArray::read
void read(std::istream &) override
Read attribute data from a stream.
Definition: AttributeArray.h:1417
openvdb::v5_2::points::TypedAttributeArray::compress
bool compress() override
Compress the attribute array.
Definition: AttributeArray.h:1291
openvdb::v5_2::points::AttributeArray::Accessor::SetterPtr
void(*)(AttributeArray *array, const Index n, const T &value) SetterPtr
Definition: AttributeArray.h:321
openvdb::v5_2::compression::bloscCompress
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
openvdb::v5_2::Int16
int16_t Int16
Definition: Types.h:62
openvdb::v5_2::compression::bloscDecompress
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
openvdb::v5_2::points::TypedAttributeArray::readMetadata
void readMetadata(std::istream &) override
Read attribute metadata from a stream.
Definition: AttributeArray.h:1426
openvdb::v5_2::points::TypedAttributeArray::TypedAttributeArray
TypedAttributeArray(Index n=1, Index strideOrTotalSize=1, bool constantStride=true, const ValueType &uniformValue=zeroVal< ValueType >())
Default constructor, always constructs a uniform attribute.
Definition: AttributeArray.h:848
openvdb::v5_2::points::TypedAttributeArray::set
void set(Index n, const ValueType &value)
Set value at the given index n.
Definition: AttributeArray.h:1144
openvdb::v5_2::points::TypedAttributeArray::~TypedAttributeArray
virtual ~TypedAttributeArray()
Definition: AttributeArray.h:465
openvdb::v5_2::points::AttributeArray::Flag
Flag
Definition: AttributeArray.h:127
openvdb::v5_2::points::fixedPointToFloatingPoint
FloatVectorT fixedPointToFloatingPoint(const math::Vec3< IntegerT > &v)
Definition: AttributeArray.h:105
openvdb::v5_2::points::AttributeArray::ConstPtr
std::shared_ptr< const AttributeArray > ConstPtr
Definition: AttributeArray.h:143
openvdb::v5_2::points::AttributeArray::isCompressed
bool isCompressed() const
Return true if this array is compressed.
Definition: AttributeArray.h:206
openvdb::v5_2::compression::PagedOutputStream::getOutputStream
std::ostream & getOutputStream()
Set and get the output stream.
Definition: StreamCompression.h:276
openvdb::v5_2::points::AttributeArray::mFlags
uint8_t mFlags
Definition: AttributeArray.h:297
openvdb::v5_2::points::AttributeHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::ValuePtr
void(*)(AttributeArray *array, const StringIndexType &value) ValuePtr
Definition: AttributeArray.h:654
openvdb::v5_2::points::TruncateCodec
Definition: AttributeArray.h:378
openvdb::v5_2::points::TypedAttributeArray::readPagedBuffers
void readPagedBuffers(compression::PagedInputStream &) override
Read attribute buffers from a paged stream.
Definition: AttributeArray.h:1526
openvdb::v5_2::points::AttributeArray::mSerializationFlags
uint8_t mSerializationFlags
Definition: AttributeArray.h:298
openvdb::v5_2::points::TypedAttributeArray::writePagedBuffers
void writePagedBuffers(compression::PagedOutputStream &os, bool outputTransient) const override
Definition: AttributeArray.h:1708
openvdb::v5_2::points::AttributeArray::operator!=
bool operator!=(const AttributeArray &other) const
Definition: AttributeArray.h:275
openvdb::v5_2::points::TypedAttributeArray::collapse
void collapse() override
Replace the existing array with a uniform zero value.
Definition: AttributeArray.h:1236
openvdb::v5_2::points::AttributeHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::Ptr
std::shared_ptr< Handle > Ptr
Definition: AttributeArray.h:648
openvdb::v5_2::points::AttributeArray::Ptr
std::shared_ptr< AttributeArray > Ptr
Definition: AttributeArray.h:142
openvdb::v5_2::points::AccessorEval::set
static void set(SetterPtr, AttributeArray *array, const Index n, const ValueType &value)
Definition: AttributeArray.h:1833
openvdb::v5_2::points::TypedAttributeArray::cast
static TypedAttributeArray & cast(AttributeArray &attributeArray)
Cast an AttributeArray to TypedAttributeArray<T>
Definition: AttributeArray.h:992
openvdb::v5_2::points::TypedAttributeArray::attributeType
static const NamePair & attributeType()
Return the name of this attribute's type (includes codec)
Definition: AttributeArray.h:949
openvdb::v5_2::points::AttributeArray::setConstantStride
void setConstantStride(bool state)
Specify whether this attribute has a constant stride or not.
openvdb::v5_2::points::AttributeArray
Base class for storing attribute data.
Definition: AttributeArray.h:118
openvdb::v5_2::points::TruncateCodec::name
static const char * name()
Definition: AttributeArray.h:385
openvdb::v5_2::points::attribute_traits::TruncateTrait< int >::Type
short Type
Definition: AttributeArray.h:341
OPENVDB_API
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
openvdb::v5_2::points::AccessorEval
Accessor to call unsafe get and set methods based on templated Codec and Value.
Definition: AttributeArray.h:1820
openvdb::v5_2::points::FixedPointCodec::name
static const char * name()
Definition: AttributeArray.h:416
openvdb::v5_2::TypeError
Definition: Exceptions.h:91
openvdb::v5_2::points::TypedAttributeArray::copyUncompressed
AttributeArray::Ptr copyUncompressed() const override
Return an uncompressed copy of this attribute (will just return a copy if not compressed).
Definition: AttributeArray.h:1020
openvdb::v5_2::points::UnitVecCodec::name
static const char * name()
Definition: AttributeArray.h:432
openvdb::v5_2::points::AttributeHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::GetterPtr
StringIndexType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:652
openvdb::v5_2::points::AttributeHandle::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:681
openvdb::v5_2::points::TypedAttributeArray::Ptr
std::shared_ptr< TypedAttributeArray > Ptr
Definition: AttributeArray.h:444
openvdb::v5_2::points::TypedAttributeArray::getAccessor
AccessorBasePtr getAccessor() const override
Obtain an Accessor that stores getter and setter functors.
Definition: AttributeArray.h:1780
openvdb::v5_2::points::UnitRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:402
openvdb::v5_2::points::AttributeArray::hasValueType
bool hasValueType() const
Return true if this attribute has a value type the same as the template parameter.
Definition: AttributeArray.h:190
openvdb::v5_2::points::TypedAttributeArray::dataSize
Index dataSize() const override
Return the size of the data in this array.
Definition: AttributeArray.h:502
openvdb::v5_2::points::AccessorEval::get
static ValueType get(GetterPtr, const AttributeArray *array, const Index n)
Definition: AttributeArray.h:1827
openvdb::v5_2::points::AttributeHandle
Definition: AttributeArray.h:644
openvdb::v5_2::points::AttributeWriteHandle::expand
void expand(bool fill=true)
If this array is uniform, replace it with an array of length size().
Definition: AttributeArray.h:2025
openvdb::v5_2::points::attribute_traits::UIntTypeTrait< false, T >::Type
uint16_t Type
Definition: AttributeArray.h:349
openvdb::v5_2::points::AttributeArray::mPageHandle
compression::PageHandle::Ptr mPageHandle
used for out-of-core, paged reading
Definition: AttributeArray.h:305
openvdb::v5_2::points::AttributeHandle::hasConstantStride
bool hasConstantStride() const
Definition: AttributeArray.h:1988
IndexIterator.h
Index Iterators.
openvdb::v5_2::points::PositionRange
Definition: AttributeArray.h:390
openvdb::v5_2::points::AttributeArray::isType
bool isType() const
Return true if this attribute is of the same type as the template parameter.
Definition: AttributeArray.h:186
openvdb::v5_2::points::AccessorEval< UnknownCodec, ValueType >::GetterPtr
ValueType(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:1843
openvdb::v5_2::points::PositionRange::decode
static ValueType decode(const ValueType &value)
Definition: AttributeArray.h:394
openvdb::v5_2::math::Vec3::z
T & z()
Definition: Vec3.h:112
openvdb::v5_2::points::AccessorEval< UnknownCodec, ValueType >::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:1844
openvdb::v5_2::points::AttributeArray::isStreaming
bool isStreaming() const
Return true if this attribute is in streaming mode.
Definition: AttributeArray.h:233
openvdb::v5_2::points::TypedAttributeArray::Codec
Codec_ Codec
Definition: AttributeArray.h:448
openvdb::v5_2::points::AttributeWriteHandle::collapse
void collapse()
Replace the existing array with a uniform value (zero if none provided).
Definition: AttributeArray.h:2031
openvdb::v5_2::points::TypedAttributeArray::registerType
static void registerType()
Register this attribute type along with a factory function.
Definition: AttributeArray.h:969
openvdb::v5_2::points::AttributeHandle::stride
Index stride() const
Definition: AttributeArray.h:666
openvdb::v5_2::points::AttributeArray::Accessor::ValuePtr
void(*)(AttributeArray *array, const T &value) ValuePtr
Definition: AttributeArray.h:322
openvdb::v5_2::points::AttributeArray::registerType
static void registerType(const NamePair &type, FactoryMethod)
Register a attribute type along with a factory function.
openvdb::v5_2::points::AttributeHandle::mArray
const AttributeArray * mArray
Definition: AttributeArray.h:679
openvdb::v5_2::points::TypedAttributeArray::unregisterType
static void unregisterType()
Remove this attribute type from the registry.
Definition: AttributeArray.h:977
openvdb::v5_2::points::AttributeHandle::mFiller
ValuePtr mFiller
Definition: AttributeArray.h:684
openvdb::v5_2::points::AttributeArray::copyUncompressed
virtual AttributeArray::Ptr copyUncompressed() const =0
Return an uncompressed copy of this attribute (will return a copy if not compressed).
openvdb::v5_2::points::attribute_traits::UIntTypeTrait
Definition: AttributeArray.h:347
openvdb::v5_2::compression::PagedInputStream::getInputStream
std::istream & getInputStream()
Definition: StreamCompression.h:239
openvdb::v5_2::points::AttributeArray::isRegistered
static bool isRegistered(const NamePair &type)
Return true if the given attribute type name is registered.
openvdb::v5_2::points::TruncateCodec::Storage
Definition: AttributeArray.h:381
openvdb::v5_2::points::UnknownCodec
Definition: AttributeArray.h:364
openvdb::v5_2::points::NullCodec::Storage::Type
T Type
Definition: AttributeArray.h:370
openvdb::v5_2::Index
Index32 Index
Definition: Types.h:61
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v5_2::math::Vec3::y
T & y()
Definition: Vec3.h:111
openvdb::v5_2::points::AccessorEval< UnknownCodec, ValueType >::get
static ValueType get(GetterPtr functor, const AttributeArray *array, const Index n)
Getter that calls the supplied functor.
Definition: AttributeArray.h:1847
openvdb::v5_2::math::Vec3
Definition: Mat.h:197
openvdb::v5_2::IndexError
Definition: Exceptions.h:84
openvdb::v5_2::points::TypedAttributeArray::isOutOfCore
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
Definition: AttributeArray.h:1368
openvdb::v5_2::points::AttributeArray::Accessor::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:329
openvdb::v5_2::points::AttributeArray::hasConstantStride
bool hasConstantStride() const
Return true if this attribute has a constant stride.
Definition: AttributeArray.h:236
openvdb::v5_2::points::NullCodec::Storage
Definition: AttributeArray.h:370
openvdb::v5_2::points::TypedAttributeArray::size
Index size() const override
Return the number of elements in this array.
Definition: AttributeArray.h:495
openvdb::v5_2::points::AttributeHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::UniquePtr
std::unique_ptr< Handle > UniquePtr
Definition: AttributeArray.h:649
openvdb::v5_2::points::TypedAttributeArray::copy
AttributeArray::Ptr copy() const override
Return a copy of this attribute.
Definition: AttributeArray.h:1012
openvdb::v5_2::points::AttributeArray::isTransient
bool isTransient() const
Return true if this attribute is not serialized during stream output.
Definition: AttributeArray.h:225
openvdb::v5_2::points::AttributeWriteHandle::compact
bool compact()
Compact the existing array to become uniform if all values are identical.
Definition: AttributeArray.h:2037
openvdb::v5_2::points::TypedAttributeArray::decompress
bool decompress() override
Uncompress the attribute array.
Definition: AttributeArray.h:1339
openvdb::v5_2::points::FixedPointCodec
Definition: AttributeArray.h:408
openvdb::v5_2::io::getDataCompression
OPENVDB_API uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK,...
openvdb::v5_2::points::TypedAttributeArray::type
const NamePair & type() const override
Return the name of this attribute's type.
Definition: AttributeArray.h:485
openvdb::v5_2::points::TypedAttributeArray::StorageType
typename Codec::template Storage< ValueType >::Type StorageType
Definition: AttributeArray.h:449
openvdb::v5_2::points::AttributeArray::expand
virtual void expand(bool fill=true)=0
If this array is uniform, replace it with an array of length size().
openvdb::v5_2::Index64
uint64_t Index64
Definition: Types.h:60
openvdb::v5_2::points::floatingPointToFixedPoint
IntegerVectorT floatingPointToFixedPoint(const math::Vec3< FloatT > &v)
Definition: AttributeArray.h:95
openvdb::v5_2::io::COMPRESS_BLOSC
Definition: Compression.h:81
openvdb::v5_2::points::AttributeWriteHandle< StringIndexType, openvdb::v5_2::points::StringCodec< false > >::ScopedPtr
std::unique_ptr< Handle > ScopedPtr
Definition: AttributeArray.h:720
openvdb::v5_2::points::AttributeArray::flags
uint8_t flags() const
Retrieve the attribute array flags.
Definition: AttributeArray.h:239
openvdb::v5_2::points::AttributeArray::mCompressedBytes
size_t mCompressedBytes
Definition: AttributeArray.h:296
openvdb::v5_2::points::AttributeArray::Accessor::Accessor
Accessor(GetterPtr getter, SetterPtr setter, ValuePtr collapser, ValuePtr filler)
Definition: AttributeArray.h:324
openvdb::v5_2::points::TypedAttributeArray::loadData
void loadData() const override
Ensures all data is in-core.
Definition: AttributeArray.h:1409
openvdb::v5_2::points::NullCodec
Definition: AttributeArray.h:367
openvdb::v5_2::ValueError
Definition: Exceptions.h:92
openvdb::v5_2::points::AttributeWriteHandle
Write-able version of AttributeHandle.
Definition: AttributeArray.h:715
openvdb::v5_2::compression::PagedInputStream::sizeOnly
bool sizeOnly() const
Definition: StreamCompression.h:236
openvdb::v5_2::compression::PagedInputStream::createHandle
PageHandle::Ptr createHandle(std::streamsize n)
Creates a PageHandle to access the next.
openvdb::v5_2::points::UnitVecCodec::StorageType
uint16_t StorageType
Definition: AttributeArray.h:425
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v5_2::Name
std::string Name
Definition: Name.h:44
openvdb::v5_2::points::attribute_traits::TruncateTrait< float >::Type
half Type
Definition: AttributeArray.h:340
openvdb::v5_2::points::TypedAttributeArray::ValueType
ValueType_ ValueType
Definition: AttributeArray.h:447
openvdb::v5_2::points::attribute_traits::TruncateTrait
Definition: AttributeArray.h:339
openvdb::v5_2::points::PositionRange::encode
static ValueType encode(const ValueType &value)
Definition: AttributeArray.h:393
openvdb::v5_2::points::AccessorEval::SetterPtr
void(*)(AttributeArray *array, const Index n, const ValueType &value) SetterPtr
Definition: AttributeArray.h:1823
openvdb::v5_2::points::AttributeHandle::isUniform
bool isUniform() const
Definition: AttributeArray.h:1982
openvdb::v5_2::compression::bloscUncompressedSize
OPENVDB_API size_t bloscUncompressedSize(const char *buffer)
Retrieves the uncompressed size of buffer when uncompressed.
openvdb::v5_2::points::UnitRange::name
static const char * name()
Definition: AttributeArray.h:401
openvdb::v5_2::points::TypedAttributeArray::operator=
TypedAttributeArray & operator=(const TypedAttributeArray &)
Deep copy assignment operator.
Definition: AttributeArray.h:916
openvdb::v5_2::points::FixedPointCodec::Storage::Type
typename attribute_traits::UIntTypeTrait< OneByte, T >::Type Type
Definition: AttributeArray.h:411
openvdb
Definition: Exceptions.h:40
openvdb::v5_2::points::TypedAttributeArray::isRegistered
static bool isRegistered()
Return true if this attribute type is registered.
Definition: AttributeArray.h:961
openvdb::v5_2::points::TypedAttributeArray::fill
void fill(const ValueType &value)
Fill the existing array with the given value.
Definition: AttributeArray.h:1266
openvdb::v5_2::points::TypedAttributeArray::setUnsafe
void setUnsafe(Index n, const ValueType &value)
Set value at the given index n (assumes uncompressed and in-core)
Definition: AttributeArray.h:1128
openvdb::v5_2::points::AttributeArray::Accessor::mSetter
SetterPtr mSetter
Definition: AttributeArray.h:328
openvdb::v5_2::compression::PagedInputStream::read
void read(PageHandle::Ptr &pageHandle, std::streamsize n, bool delayed=true)
Takes a pageHandle and updates the referenced page with the current stream pointer position and if de...
openvdb::v5_2::points::AttributeArray::Accessor::GetterPtr
T(*)(const AttributeArray *array, const Index n) GetterPtr
Definition: AttributeArray.h:320
openvdb::v5_2::points::PositionRange::name
static const char * name()
Definition: AttributeArray.h:392
openvdb::v5_2::points::AttributeHandle::size
Index size() const
Definition: AttributeArray.h:667
openvdb::v5_2::points::TypedAttributeArray::compact
bool compact() override
Compact the existing array to become uniform if all values are identical.
Definition: AttributeArray.h:1219
openvdb::v5_2::points::TypedAttributeArray::stride
Index stride() const override
Definition: AttributeArray.h:499
openvdb::v5_2::points::AttributeArray::Accessor::mGetter
GetterPtr mGetter
Definition: AttributeArray.h:327
openvdb::v5_2::points::TypedAttributeArray::getUnsafe
ValueType getUnsafe(Index n) const
Return the value at index n (assumes uncompressed and in-core)
Definition: AttributeArray.h:1076
openvdb::v5_2::points::FixedPointCodec::Storage
Definition: AttributeArray.h:411
openvdb::v5_2::math::operator==
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
openvdb::v5_2::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
openvdb::v5_2::compression::PageHandle::Ptr
std::shared_ptr< PageHandle > Ptr
Definition: StreamCompression.h:197
openvdb::v5_2::points::AttributeHandle::mCollapser
ValuePtr mCollapser
Definition: AttributeArray.h:683
openvdb::v5_2::points::UnitVecCodec::Storage
Definition: AttributeArray.h:428
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
openvdb::v5_2::io::getMappedFilePtr
OPENVDB_API SharedPtr< MappedFile > getMappedFilePtr(std::ios_base &)
Return a shared pointer to the memory-mapped file with which the given stream is associated,...
openvdb::v5_2::points::AttributeArray::SerializationFlag
SerializationFlag
Definition: AttributeArray.h:135
openvdb::v5_2::points::AttributeHandle::create
static Ptr create(const AttributeArray &array, const bool preserveCompression=true)
Definition: AttributeArray.h:1864
openvdb::v5_2::points::AttributeHandle::AttributeHandle
AttributeHandle(const AttributeArray &array, const bool preserveCompression=true)
Definition: AttributeArray.h:1871
openvdb::v5_2::points::TypedAttributeArray::expand
void expand(bool fill=true) override
Replace the single value storage with an array of length size().
Definition: AttributeArray.h:1196
openvdb::v5_2::points::UnitVecCodec
Definition: AttributeArray.h:423
openvdb::v5_2::io::MappedFile::Ptr
SharedPtr< MappedFile > Ptr
Definition: io.h:152
openvdb::v5_2::points::AttributeArray::Accessor
Definition: AttributeArray.h:122
openvdb::v5_2::points::AttributeArray::AccessorBase
Accessor base class for AttributeArray storage where type is not available.
Definition: AttributeArray.h:313
openvdb::v5_2::compression::PagedOutputStream::write
PagedOutputStream & write(const char *str, std::streamsize n)
Writes the given.
OPENVDB_LOG_WARN
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:280