OpenVDB: LeafBuffer.h Source File

OpenVDB 8.0.0

LeafBuffer.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #ifndef OPENVDB_TREE_LEAFBUFFER_HAS_BEEN_INCLUDED
5 #define OPENVDB_TREE_LEAFBUFFER_HAS_BEEN_INCLUDED
6
7 #include <openvdb/Types.h>
8 #include <openvdb/io/Compression.h> // for io::readCompressedValues(), etc
9 #include <openvdb/util/NodeMasks.h>
10 #include <tbb/atomic.h>
11 #include <tbb/spin_mutex.h>
12 #include <algorithm> // for std::swap
13 #include <cstddef> // for offsetof()
14 #include <iostream>
15 #include <memory>
16 #include <type_traits>
17
18
19 class TestLeaf;
20
21 namespace openvdb {
22 OPENVDB_USE_VERSION_NAMESPACE
23 namespace OPENVDB_VERSION_NAME {
24 namespace tree {
25
26 namespace internal {
27
39 template<typename T>
40 struct LeafBufferFlags
41 {
43 using type = tbb::atomic<Index32>;
44 static constexpr bool IsAtomic = true;
45 };
46
47 } // namespace internal
48
49
52 template<typename T, Index Log2Dim>
53 class LeafBuffer
54 {
55 public:
56 using ValueType = T;
57 using StorageType = ValueType;
58 using NodeMaskType = util::NodeMask<Log2Dim>;
59 static const Index SIZE = 1 << 3 * Log2Dim;
60
61 struct FileInfo
62 {
63 FileInfo(): bufpos(0) , maskpos(0) {}
64 std::streamoff bufpos;
65 std::streamoff maskpos;
66 io::MappedFile::Ptr mapping;
67 SharedPtr<io::StreamMetadata> meta;
68 };
69
71 inline LeafBuffer(): mData(new ValueType[SIZE]) { mOutOfCore = 0; }
73 explicit inline LeafBuffer(const ValueType&);
75 inline LeafBuffer(const LeafBuffer&);
77 LeafBuffer(PartialCreate, const ValueType&): mData(nullptr) { mOutOfCore = 0; }
79 inline ~LeafBuffer();
80
82 bool isOutOfCore() const { return bool(mOutOfCore); }
84 bool empty() const { return !mData || this->isOutOfCore(); }
86 bool allocate() { if (mData == nullptr) mData = new ValueType[SIZE]; return true; }
87
89 inline void fill(const ValueType&);
90
92 const ValueType& getValue(Index i) const { return this->at(i); }
94 const ValueType& operator[](Index i) const { return this->at(i); }
96 inline void setValue(Index i, const ValueType&);
97
99 inline LeafBuffer& operator=(const LeafBuffer&);
100
103 inline bool operator==(const LeafBuffer&) const;
106 inline bool operator!=(const LeafBuffer& other) const { return !(other == *this); }
107
109 inline void swap(LeafBuffer&);
110
112 inline Index memUsage() const;
114 static Index size() { return SIZE; }
115
119 const ValueType* data() const;
123 ValueType* data();
124
125 private:
127 inline const ValueType& at(Index i) const;
128
134 ValueType& operator[](Index i) { return const_cast<ValueType&>(this->at(i)); }
135
136 bool deallocate();
137
138 inline void setOutOfCore(bool b) { mOutOfCore = b; }
139 // To facilitate inlining in the common case in which the buffer is in-core,
140 // the loading logic is split into a separate function, doLoad().
141 inline void loadValues() const { if (this->isOutOfCore()) this->doLoad(); }
142 inline void doLoad() const;
143 inline bool detachFromFile();
144
145 using FlagsType = typename internal::LeafBufferFlags<ValueType>::type;
146
147 union {
148 ValueType* mData;
149 FileInfo* mFileInfo;
150 };
151 FlagsType mOutOfCore; // interpreted as bool; extra bits reserved for future use
152 tbb::spin_mutex mMutex; // 1 byte
153 //int8_t mReserved[3]; // padding for alignment
154
155 static const ValueType sZero;
156
157 friend class ::TestLeaf;
158 // Allow the parent LeafNode to access this buffer's data pointer.
159 template<typename, Index> friend class LeafNode;
160 }; // class LeafBuffer
161
162
164
165
166 template<typename T, Index Log2Dim>
167 const T LeafBuffer<T, Log2Dim>::sZero = zeroVal<T>();
168
169
170 template<typename T, Index Log2Dim>
171 inline
172 LeafBuffer<T, Log2Dim>::LeafBuffer(const ValueType& val)
173 : mData(new ValueType[SIZE])
174 {
175 mOutOfCore = 0;
176 this->fill(val);
177 }
178
179
180 template<typename T, Index Log2Dim>
181 inline
182 LeafBuffer<T, Log2Dim>::~LeafBuffer()
183 {
184 if (this->isOutOfCore()) {
185 this->detachFromFile();
186 } else {
187 this->deallocate();
188 }
189 }
190
191
192 template<typename T, Index Log2Dim>
193 inline
194 LeafBuffer<T, Log2Dim>::LeafBuffer(const LeafBuffer& other)
195 : mData(nullptr)
196 , mOutOfCore(other.mOutOfCore)
197 {
198 if (other.isOutOfCore()) {
199 mFileInfo = new FileInfo(*other.mFileInfo);
200 } else if (other.mData != nullptr) {
201 this->allocate();
202 ValueType* target = mData;
203 const ValueType* source = other.mData;
204 Index n = SIZE;
205 while (n--) *target++ = *source++;
206 }
207 }
208
209
210 template<typename T, Index Log2Dim>
211 inline void
212 LeafBuffer<T, Log2Dim>::setValue(Index i, const ValueType& val)
213 {
214 assert(i < SIZE);
215 this->loadValues();
216 if (mData) mData[i] = val;
217 }
218
219
220 template<typename T, Index Log2Dim>
221 inline LeafBuffer<T, Log2Dim>&
222 LeafBuffer<T, Log2Dim>::operator=(const LeafBuffer& other)
223 {
224 if (&other != this) {
225 if (this->isOutOfCore()) {
226 this->detachFromFile();
227 } else {
228 if (other.isOutOfCore()) this->deallocate();
229 }
230 if (other.isOutOfCore()) {
231 mOutOfCore = other.mOutOfCore;
232 mFileInfo = new FileInfo(*other.mFileInfo);
233 } else if (other.mData != nullptr) {
234 this->allocate();
235 ValueType* target = mData;
236 const ValueType* source = other.mData;
237 Index n = SIZE;
238 while (n--) *target++ = *source++;
239 }
240 }
241 return *this;
242 }
243
244
245 template<typename T, Index Log2Dim>
246 inline void
247 LeafBuffer<T, Log2Dim>::fill(const ValueType& val)
248 {
249 this->detachFromFile();
250 if (mData != nullptr) {
251 ValueType* target = mData;
252 Index n = SIZE;
253 while (n--) *target++ = val;
254 }
255 }
256
257
258 template<typename T, Index Log2Dim>
259 inline bool
260 LeafBuffer<T, Log2Dim>::operator==(const LeafBuffer& other) const
261 {
262 this->loadValues();
263 other.loadValues();
264 const ValueType *target = mData, *source = other.mData;
265 if (!target && !source) return true;
266 if (!target || !source) return false;
267 Index n = SIZE;
268 while (n && math::isExactlyEqual(*target++, *source++)) --n;
269 return n == 0;
270 }
271
272
273 template<typename T, Index Log2Dim>
274 inline void
275 LeafBuffer<T, Log2Dim>::swap(LeafBuffer& other)
276 {
277 std::swap(mData, other.mData);
278 std::swap(mOutOfCore, other.mOutOfCore);
279 }
280
281
282 template<typename T, Index Log2Dim>
283 inline Index
284 LeafBuffer<T, Log2Dim>::memUsage() const
285 {
286 size_t n = sizeof(*this);
287 if (this->isOutOfCore()) n += sizeof(FileInfo);
288 else if (mData) n += SIZE * sizeof(ValueType);
289 return static_cast<Index>(n);
290 }
291
292
293 template<typename T, Index Log2Dim>
294 inline const typename LeafBuffer<T, Log2Dim>::ValueType*
295 LeafBuffer<T, Log2Dim>::data() const
296 {
297 this->loadValues();
298 if (mData == nullptr) {
299 LeafBuffer* self = const_cast<LeafBuffer*>(this);
300 // This lock will be contended at most once.
301 tbb::spin_mutex::scoped_lock lock(self->mMutex);
302 if (mData == nullptr) self->mData = new ValueType[SIZE];
303 }
304 return mData;
305 }
306
307 template<typename T, Index Log2Dim>
308 inline typename LeafBuffer<T, Log2Dim>::ValueType*
309 LeafBuffer<T, Log2Dim>::data()
310 {
311 this->loadValues();
312 if (mData == nullptr) {
313 // This lock will be contended at most once.
314 tbb::spin_mutex::scoped_lock lock(mMutex);
315 if (mData == nullptr) mData = new ValueType[SIZE];
316 }
317 return mData;
318 }
319
320
321 template<typename T, Index Log2Dim>
322 inline const typename LeafBuffer<T, Log2Dim>::ValueType&
323 LeafBuffer<T, Log2Dim>::at(Index i) const
324 {
325 assert(i < SIZE);
326 this->loadValues();
327 // We can't use the ternary operator here, otherwise Visual C++ returns
328 // a reference to a temporary.
329 if (mData) return mData[i]; else return sZero;
330 }
331
332
333 template<typename T, Index Log2Dim>
334 inline bool
335 LeafBuffer<T, Log2Dim>::deallocate()
336 {
337 if (mData != nullptr && !this->isOutOfCore()) {
338 delete[] mData;
339 mData = nullptr;
340 return true;
341 }
342 return false;
343 }
344
345
346 template<typename T, Index Log2Dim>
347 inline void
348 LeafBuffer<T, Log2Dim>::doLoad() const
349 {
350 if (!this->isOutOfCore()) return;
351
352 LeafBuffer<T, Log2Dim>* self = const_cast<LeafBuffer<T, Log2Dim>*>(this);
353
354 // This lock will be contended at most once, after which this buffer
355 // will no longer be out-of-core.
356 tbb::spin_mutex::scoped_lock lock(self->mMutex);
357 if (!this->isOutOfCore()) return;
358
359 std::unique_ptr<FileInfo> info(self->mFileInfo);
360 assert(info.get() != nullptr);
361 assert(info->mapping.get() != nullptr);
362 assert(info->meta.get() != nullptr);
363
365 self->mData = nullptr;
366 self->allocate();
367
368 SharedPtr<std::streambuf> buf = info->mapping->createBuffer();
369 std::istream is(buf.get());
370
371 io::setStreamMetadataPtr(is, info->meta, /*transfer=*/true);
372
373 NodeMaskType mask;
374 is.seekg(info->maskpos);
375 mask.load(is);
376
377 is.seekg(info->bufpos);
378 io::readCompressedValues(is, self->mData, SIZE, mask, io::getHalfFloat(is));
379
380 self->setOutOfCore(false);
381 }
382
383
384 template<typename T, Index Log2Dim>
385 inline bool
386 LeafBuffer<T, Log2Dim>::detachFromFile()
387 {
388 if (this->isOutOfCore()) {
389 delete mFileInfo;
390 mFileInfo = nullptr;
391 this->setOutOfCore(false);
392 return true;
393 }
394 return false;
395 }
396
397
399
400
401 // Partial specialization for bool ValueType
402 template<Index Log2Dim>
403 class LeafBuffer<bool, Log2Dim>
404 {
405 public:
406 using NodeMaskType = util::NodeMask<Log2Dim>;
407 using WordType = typename NodeMaskType::Word;
408 using ValueType = bool;
409 using StorageType = WordType;
410
411 static const Index WORD_COUNT = NodeMaskType::WORD_COUNT;
412 static const Index SIZE = 1 << 3 * Log2Dim;
413
414 // These static declarations must be on separate lines to avoid VC9 compiler errors.
415 static const bool sOn;
416 static const bool sOff;
417
418 LeafBuffer() {}
419 LeafBuffer(bool on): mData(on) {}
420 LeafBuffer(const NodeMaskType& other): mData(other) {}
421 LeafBuffer(const LeafBuffer& other): mData(other.mData) {}
422 ~LeafBuffer() {}
423 void fill(bool val) { mData.set(val); }
424 LeafBuffer& operator=(const LeafBuffer& b) { if (&b != this) { mData=b.mData; } return *this; }
425
426 const bool& getValue(Index i) const
427 {
428 assert(i < SIZE);
429 // We can't use the ternary operator here, otherwise Visual C++ returns
430 // a reference to a temporary.
431 if (mData.isOn(i)) return sOn; else return sOff;
432 }
433 const bool& operator[](Index i) const { return this->getValue(i); }
434
435 bool operator==(const LeafBuffer& other) const { return mData == other.mData; }
436 bool operator!=(const LeafBuffer& other) const { return mData != other.mData; }
437
438 void setValue(Index i, bool val) { assert(i < SIZE); mData.set(i, val); }
439
440 void swap(LeafBuffer& other) { if (&other != this) std::swap(mData, other.mData); }
441
442 Index memUsage() const { return sizeof(*this); }
443 static Index size() { return SIZE; }
444
447 WordType* data() { return &(mData.template getWord<WordType>(0)); }
450 const WordType* data() const { return const_cast<LeafBuffer*>(this)->data(); }
451
452 private:
453 // Allow the parent LeafNode to access this buffer's data.
454 template<typename, Index> friend class LeafNode;
455
456 NodeMaskType mData;
457 }; // class LeafBuffer
458
459
464 template<Index Log2Dim> const bool LeafBuffer<bool, Log2Dim>::sOn = true;
465 template<Index Log2Dim> const bool LeafBuffer<bool, Log2Dim>::sOff = false;
466
467 } // namespace tree
468 } // namespace OPENVDB_VERSION_NAME
469 } // namespace openvdb
470
471 #endif // OPENVDB_TREE_LEAFBUFFER_HAS_BEEN_INCLUDED
Types.h
openvdb::v8_2::tree::LeafBuffer::swap
void swap(LeafBuffer &)
Exchange this buffer's values with the other buffer's values.
Definition: LeafBuffer.h:275
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::swap
void swap(LeafBuffer &other)
Definition: LeafBuffer.h:440
Compression.h
openvdb::v8_2::tree::LeafBuffer::FileInfo::mapping
io::MappedFile::Ptr mapping
Definition: LeafBuffer.h:66
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::data
const WordType * data() const
Return a const pointer to the C-style array of words encoding the bits.
Definition: LeafBuffer.h:450
openvdb::v8_2::tree::LeafBuffer::LeafBuffer
LeafBuffer(PartialCreate, const ValueType &)
Construct a buffer but don't allocate memory for the full array of values.
Definition: LeafBuffer.h:77
openvdb::v8_2::tree::LeafBuffer::FileInfo::maskpos
std::streamoff maskpos
Definition: LeafBuffer.h:65
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::data
WordType * data()
Return a pointer to the C-style array of words encoding the bits.
Definition: LeafBuffer.h:447
openvdb::v8_2::tree::LeafBuffer< ValueType, Log2Dim >::ValueType
ValueType ValueType
Definition: LeafBuffer.h:56
openvdb::v8_2::tree::LeafBuffer::FileInfo::FileInfo
FileInfo()
Definition: LeafBuffer.h:63
openvdb::v8_2::tree::LeafBuffer::LeafBuffer
LeafBuffer(const ValueType &)
Construct a buffer populated with the specified value.
Definition: LeafBuffer.h:172
openvdb::v8_2::tree::LeafBuffer::data
const ValueType * data() const
Return a const pointer to the array of voxel values.
Definition: LeafBuffer.h:295
NodeMasks.h
openvdb::v8_2::tree::LeafBuffer::LeafBuffer
LeafBuffer()
Default constructor.
Definition: LeafBuffer.h:71
openvdb::v8_2::tree::LeafBuffer::mFileInfo
FileInfo * mFileInfo
Definition: LeafBuffer.h:149
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::operator==
bool operator==(const LeafBuffer &other) const
Definition: LeafBuffer.h:435
openvdb::v8_2::tree::LeafBuffer::operator!=
bool operator!=(const LeafBuffer &other) const
Return true if the contents of the other buffer are not exactly equal to the contents of this buffer.
Definition: LeafBuffer.h:106
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer()
Definition: LeafBuffer.h:418
openvdb::v8_2::Index
Index32 Index
Definition: openvdb/Types.h:32
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::WordType
typename NodeMaskType::Word WordType
Definition: LeafBuffer.h:407
openvdb::v8_2::tree::LeafBuffer::mData
ValueType * mData
Definition: LeafBuffer.h:148
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::operator[]
const bool & operator[](Index i) const
Definition: LeafBuffer.h:433
openvdb::v8_2::tree::LeafBuffer::operator==
bool operator==(const LeafBuffer &) const
Return true if the contents of the other buffer exactly equal the contents of this buffer.
Definition: LeafBuffer.h:260
openvdb::v8_2::tree::LeafBuffer< ValueType, Log2Dim >::StorageType
ValueType StorageType
Definition: LeafBuffer.h:57
openvdb::v8_2::tree::LeafBuffer::empty
bool empty() const
Return true if memory for this buffer has not yet been allocated.
Definition: LeafBuffer.h:84
openvdb::v8_2::util::NodeMask
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition: NodeMasks.h:308
openvdb::v8_2::tree::LeafBuffer::operator=
LeafBuffer & operator=(const LeafBuffer &)
Copy the other buffer's values into this buffer.
Definition: LeafBuffer.h:222
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::StorageType
WordType StorageType
Definition: LeafBuffer.h:409
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::~LeafBuffer
~LeafBuffer()
Definition: LeafBuffer.h:422
openvdb::v8_2::tree::LeafBuffer::FileInfo::bufpos
std::streamoff bufpos
Definition: LeafBuffer.h:64
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::setValue
void setValue(Index i, bool val)
Definition: LeafBuffer.h:438
openvdb::v8_2::tree::LeafBuffer
Array of fixed size 23Log2Dim that stores the voxel values of a LeafNode.
Definition: LeafBuffer.h:54
openvdb::v8_2::util::NodeMask::Word
Index64 Word
Definition: NodeMasks.h:316
openvdb::v8_2::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
openvdb::v8_2::tree::LeafBuffer::LeafBuffer
LeafBuffer(const LeafBuffer &)
Copy constructor.
Definition: LeafBuffer.h:194
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::fill
void fill(bool val)
Definition: LeafBuffer.h:423
openvdb::v8_2::tree::LeafBuffer::allocate
bool allocate()
Allocate memory for this buffer if it has not already been allocated.
Definition: LeafBuffer.h:86
openvdb::v8_2::tree::LeafBuffer::~LeafBuffer
~LeafBuffer()
Destructor.
Definition: LeafBuffer.h:182
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(const NodeMaskType &other)
Definition: LeafBuffer.h:420
openvdb::v8_2::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:92
openvdb::v8_2::tree::LeafBuffer::getValue
const ValueType & getValue(Index i) const
Return a const reference to the i'th element of this buffer.
Definition: LeafBuffer.h:92
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(const LeafBuffer &other)
Definition: LeafBuffer.h:421
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::sOff
static const bool sOff
Definition: LeafBuffer.h:416
openvdb::v8_2::tree::LeafBuffer::SIZE
static const Index SIZE
Definition: LeafBuffer.h:59
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(bool on)
Definition: LeafBuffer.h:419
openvdb::v8_2::tree::LeafBuffer::fill
void fill(const ValueType &)
Populate this buffer with a constant value.
Definition: LeafBuffer.h:247
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::size
static Index size()
Definition: LeafBuffer.h:443
openvdb::v8_2::tree::LeafBuffer::isOutOfCore
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
Definition: LeafBuffer.h:82
openvdb::v8_2::tree::LeafBuffer::operator[]
const ValueType & operator[](Index i) const
Return a const reference to the i'th element of this buffer.
Definition: LeafBuffer.h:94
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153
openvdb::v8_2::util::NodeMask::WORD_COUNT
static const Index32 WORD_COUNT
Definition: NodeMasks.h:315
openvdb::v8_2::tree::internal::LeafBufferFlags< ValueType >::type
tbb::atomic< Index32 > type
The type of LeafBuffer::mOutOfCore.
Definition: LeafBuffer.h:43
openvdb::v8_2::tree::LeafBuffer::size
static Index size()
Return the number of values contained in this buffer.
Definition: LeafBuffer.h:114
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::ValueType
bool ValueType
Definition: LeafBuffer.h:408
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::sOn
static const bool sOn
Definition: LeafBuffer.h:415
openvdb::v8_2::io::getHalfFloat
OPENVDB_API bool getHalfFloat(std::ios_base &)
Return true if floating-point values should be quantized to 16 bits when writing to the given stream ...
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::getValue
const bool & getValue(Index i) const
Definition: LeafBuffer.h:426
openvdb::v8_2::tree::LeafBuffer::memUsage
Index memUsage() const
Return the memory footprint of this buffer in bytes.
Definition: LeafBuffer.h:284
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::operator!=
bool operator!=(const LeafBuffer &other) const
Definition: LeafBuffer.h:436
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::memUsage
Index memUsage() const
Definition: LeafBuffer.h:442
openvdb::v8_2::tree::LeafBuffer::FileInfo::meta
SharedPtr< io::StreamMetadata > meta
Definition: LeafBuffer.h:67
openvdb::v8_2::tree::LeafBuffer::setValue
void setValue(Index i, const ValueType &)
Set the i'th value of this buffer to the specified value.
Definition: LeafBuffer.h:212
openvdb::v8_2::io::readCompressedValues
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:465
openvdb::v8_2::tree::LeafBuffer< bool, Log2Dim >::operator=
LeafBuffer & operator=(const LeafBuffer &b)
Definition: LeafBuffer.h:424
openvdb::v8_2::tree::LeafNode
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim....
Definition: LeafNode.h:38
openvdb
Definition: openvdb/Exceptions.h:13
openvdb::v8_2::io::MappedFile::Ptr
SharedPtr< MappedFile > Ptr
Definition: io.h:136
openvdb::v8_2::tree::LeafBuffer::FileInfo
Definition: LeafBuffer.h:62
openvdb::v8_2::io::setStreamMetadataPtr
OPENVDB_API void setStreamMetadataPtr(std::ios_base &, SharedPtr< StreamMetadata > &, bool transfer=true)
Associate the given stream with (a shared pointer to) an object that stores metadata (file format,...
openvdb::v8_2::tree::LeafBuffer::data
ValueType * data()
Return a pointer to the array of voxel values.
Definition: LeafBuffer.h:309
openvdb::v8_2::tree::internal::LeafBufferFlags
Definition: LeafBuffer.h:41
openvdb::v8_2::PartialCreate
Tag dispatch class that distinguishes constructors during file input.
Definition: openvdb/Types.h:548