OpenVDB 11.0.0

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