OpenVDB: openvdb/points/AttributeArray.h Source File

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