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