OpenVDB: openvdb/points/AttributeArray.h Source File

OpenVDB 9.1.0

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