OpenVDB: LeafBuffer.h Source File

OpenVDB 8.1.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/spin_mutex.h>
11 #include <algorithm> // for std::swap
12 #include <atomic>
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
29 template<typename T, Index Log2Dim>
30 class LeafBuffer
31 {
32 public:
33 using ValueType = T;
34 using StorageType = ValueType;
35 using NodeMaskType = util::NodeMask<Log2Dim>;
36 static const Index SIZE = 1 << 3 * Log2Dim;
37
38 struct FileInfo
39 {
40 FileInfo(): bufpos(0) , maskpos(0) {}
41 std::streamoff bufpos;
42 std::streamoff maskpos;
43 io::MappedFile::Ptr mapping;
44 SharedPtr<io::StreamMetadata> meta;
45 };
46
48 inline LeafBuffer(): mData(new ValueType[SIZE]) { mOutOfCore = 0; }
50 explicit inline LeafBuffer(const ValueType&);
52 inline LeafBuffer(const LeafBuffer&);
54 LeafBuffer(PartialCreate, const ValueType&): mData(nullptr) { mOutOfCore = 0; }
56 inline ~LeafBuffer();
57
59 bool isOutOfCore() const { return bool(mOutOfCore); }
61 bool empty() const { return !mData || this->isOutOfCore(); }
63 bool allocate() { if (mData == nullptr) mData = new ValueType[SIZE]; return true; }
64
66 inline void fill(const ValueType&);
67
69 const ValueType& getValue(Index i) const { return this->at(i); }
71 const ValueType& operator[](Index i) const { return this->at(i); }
73 inline void setValue(Index i, const ValueType&);
74
76 inline LeafBuffer& operator=(const LeafBuffer&);
77
80 inline bool operator==(const LeafBuffer&) const;
83 inline bool operator!=(const LeafBuffer& other) const { return !(other == *this); }
84
86 inline void swap(LeafBuffer&);
87
89 inline Index memUsage() const;
91 static Index size() { return SIZE; }
92
96 const ValueType* data() const;
100 ValueType* data();
101
102 private:
104 inline const ValueType& at(Index i) const;
105
111 ValueType& operator[](Index i) { return const_cast<ValueType&>(this->at(i)); }
112
113 bool deallocate();
114
115 inline void setOutOfCore(bool b) { mOutOfCore = b; }
116 // To facilitate inlining in the common case in which the buffer is in-core,
117 // the loading logic is split into a separate function, doLoad().
118 inline void loadValues() const { if (this->isOutOfCore()) this->doLoad(); }
119 inline void doLoad() const;
120 inline bool detachFromFile();
121
122 using FlagsType = std::atomic<Index32>;
123
124 union {
125 ValueType* mData;
126 FileInfo* mFileInfo;
127 };
128 FlagsType mOutOfCore; // interpreted as bool; extra bits reserved for future use
129 tbb::spin_mutex mMutex; // 1 byte
130 //int8_t mReserved[3]; // padding for alignment
131
132 static const ValueType sZero;
133
134 friend class ::TestLeaf;
135 // Allow the parent LeafNode to access this buffer's data pointer.
136 template<typename, Index> friend class LeafNode;
137 }; // class LeafBuffer
138
139
141
142
143 template<typename T, Index Log2Dim>
144 const T LeafBuffer<T, Log2Dim>::sZero = zeroVal<T>();
145
146
147 template<typename T, Index Log2Dim>
148 inline
149 LeafBuffer<T, Log2Dim>::LeafBuffer(const ValueType& val)
150 : mData(new ValueType[SIZE])
151 {
152 mOutOfCore = 0;
153 this->fill(val);
154 }
155
156
157 template<typename T, Index Log2Dim>
158 inline
159 LeafBuffer<T, Log2Dim>::~LeafBuffer()
160 {
161 if (this->isOutOfCore()) {
162 this->detachFromFile();
163 } else {
164 this->deallocate();
165 }
166 }
167
168
169 template<typename T, Index Log2Dim>
170 inline
171 LeafBuffer<T, Log2Dim>::LeafBuffer(const LeafBuffer& other)
172 : mData(nullptr)
173 , mOutOfCore(other.mOutOfCore.load())
174 {
175 if (other.isOutOfCore()) {
176 mFileInfo = new FileInfo(*other.mFileInfo);
177 } else if (other.mData != nullptr) {
178 this->allocate();
179 ValueType* target = mData;
180 const ValueType* source = other.mData;
181 Index n = SIZE;
182 while (n--) *target++ = *source++;
183 }
184 }
185
186
187 template<typename T, Index Log2Dim>
188 inline void
189 LeafBuffer<T, Log2Dim>::setValue(Index i, const ValueType& val)
190 {
191 assert(i < SIZE);
192 this->loadValues();
193 if (mData) mData[i] = val;
194 }
195
196
197 template<typename T, Index Log2Dim>
198 inline LeafBuffer<T, Log2Dim>&
199 LeafBuffer<T, Log2Dim>::operator=(const LeafBuffer& other)
200 {
201 if (&other != this) {
202 if (this->isOutOfCore()) {
203 this->detachFromFile();
204 } else {
205 if (other.isOutOfCore()) this->deallocate();
206 }
207 if (other.isOutOfCore()) {
208 mOutOfCore.store(other.mOutOfCore.load(std::memory_order_acquire),
209 std::memory_order_release);
210 mFileInfo = new FileInfo(*other.mFileInfo);
211 } else if (other.mData != nullptr) {
212 this->allocate();
213 ValueType* target = mData;
214 const ValueType* source = other.mData;
215 Index n = SIZE;
216 while (n--) *target++ = *source++;
217 }
218 }
219 return *this;
220 }
221
222
223 template<typename T, Index Log2Dim>
224 inline void
225 LeafBuffer<T, Log2Dim>::fill(const ValueType& val)
226 {
227 this->detachFromFile();
228 if (mData != nullptr) {
229 ValueType* target = mData;
230 Index n = SIZE;
231 while (n--) *target++ = val;
232 }
233 }
234
235
236 template<typename T, Index Log2Dim>
237 inline bool
238 LeafBuffer<T, Log2Dim>::operator==(const LeafBuffer& other) const
239 {
240 this->loadValues();
241 other.loadValues();
242 const ValueType *target = mData, *source = other.mData;
243 if (!target && !source) return true;
244 if (!target || !source) return false;
245 Index n = SIZE;
246 while (n && math::isExactlyEqual(*target++, *source++)) --n;
247 return n == 0;
248 }
249
250
251 template<typename T, Index Log2Dim>
252 inline void
253 LeafBuffer<T, Log2Dim>::swap(LeafBuffer& other)
254 {
255 std::swap(mData, other.mData);
256
257 // Two atomics can't be swapped because it would require hardware support:
258 // https://en.wikipedia.org/wiki/Double_compare-and-swap
259 // Note that there's a window in which other.mOutOfCore could be written
260 // between our load from it and our store to it.
261 auto tmp = other.mOutOfCore.load(std::memory_order_acquire);
262 tmp = mOutOfCore.exchange(std::move(tmp));
263 other.mOutOfCore.store(std::move(tmp), std::memory_order_release);
264 }
265
266
267 template<typename T, Index Log2Dim>
268 inline Index
269 LeafBuffer<T, Log2Dim>::memUsage() const
270 {
271 size_t n = sizeof(*this);
272 if (this->isOutOfCore()) n += sizeof(FileInfo);
273 else if (mData) n += SIZE * sizeof(ValueType);
274 return static_cast<Index>(n);
275 }
276
277
278 template<typename T, Index Log2Dim>
279 inline const typename LeafBuffer<T, Log2Dim>::ValueType*
280 LeafBuffer<T, Log2Dim>::data() const
281 {
282 this->loadValues();
283 if (mData == nullptr) {
284 LeafBuffer* self = const_cast<LeafBuffer*>(this);
285 // This lock will be contended at most once.
286 tbb::spin_mutex::scoped_lock lock(self->mMutex);
287 if (mData == nullptr) self->mData = new ValueType[SIZE];
288 }
289 return mData;
290 }
291
292 template<typename T, Index Log2Dim>
293 inline typename LeafBuffer<T, Log2Dim>::ValueType*
294 LeafBuffer<T, Log2Dim>::data()
295 {
296 this->loadValues();
297 if (mData == nullptr) {
298 // This lock will be contended at most once.
299 tbb::spin_mutex::scoped_lock lock(mMutex);
300 if (mData == nullptr) mData = new ValueType[SIZE];
301 }
302 return mData;
303 }
304
305
306 template<typename T, Index Log2Dim>
307 inline const typename LeafBuffer<T, Log2Dim>::ValueType&
308 LeafBuffer<T, Log2Dim>::at(Index i) const
309 {
310 assert(i < SIZE);
311 this->loadValues();
312 // We can't use the ternary operator here, otherwise Visual C++ returns
313 // a reference to a temporary.
314 if (mData) return mData[i]; else return sZero;
315 }
316
317
318 template<typename T, Index Log2Dim>
319 inline bool
320 LeafBuffer<T, Log2Dim>::deallocate()
321 {
322 if (mData != nullptr && !this->isOutOfCore()) {
323 delete[] mData;
324 mData = nullptr;
325 return true;
326 }
327 return false;
328 }
329
330
331 template<typename T, Index Log2Dim>
332 inline void
333 LeafBuffer<T, Log2Dim>::doLoad() const
334 {
335 if (!this->isOutOfCore()) return;
336
337 LeafBuffer<T, Log2Dim>* self = const_cast<LeafBuffer<T, Log2Dim>*>(this);
338
339 // This lock will be contended at most once, after which this buffer
340 // will no longer be out-of-core.
341 tbb::spin_mutex::scoped_lock lock(self->mMutex);
342 if (!this->isOutOfCore()) return;
343
344 std::unique_ptr<FileInfo> info(self->mFileInfo);
345 assert(info.get() != nullptr);
346 assert(info->mapping.get() != nullptr);
347 assert(info->meta.get() != nullptr);
348
350 self->mData = nullptr;
351 self->allocate();
352
353 SharedPtr<std::streambuf> buf = info->mapping->createBuffer();
354 std::istream is(buf.get());
355
356 io::setStreamMetadataPtr(is, info->meta, /*transfer=*/true);
357
358 NodeMaskType mask;
359 is.seekg(info->maskpos);
360 mask.load(is);
361
362 is.seekg(info->bufpos);
363 io::readCompressedValues(is, self->mData, SIZE, mask, io::getHalfFloat(is));
364
365 self->setOutOfCore(false);
366 }
367
368
369 template<typename T, Index Log2Dim>
370 inline bool
371 LeafBuffer<T, Log2Dim>::detachFromFile()
372 {
373 if (this->isOutOfCore()) {
374 delete mFileInfo;
375 mFileInfo = nullptr;
376 this->setOutOfCore(false);
377 return true;
378 }
379 return false;
380 }
381
382
384
385
386 // Partial specialization for bool ValueType
387 template<Index Log2Dim>
388 class LeafBuffer<bool, Log2Dim>
389 {
390 public:
391 using NodeMaskType = util::NodeMask<Log2Dim>;
392 using WordType = typename NodeMaskType::Word;
393 using ValueType = bool;
394 using StorageType = WordType;
395
396 static const Index WORD_COUNT = NodeMaskType::WORD_COUNT;
397 static const Index SIZE = 1 << 3 * Log2Dim;
398
399 // These static declarations must be on separate lines to avoid VC9 compiler errors.
400 static const bool sOn;
401 static const bool sOff;
402
403 LeafBuffer() {}
404 LeafBuffer(bool on): mData(on) {}
405 LeafBuffer(const NodeMaskType& other): mData(other) {}
406 LeafBuffer(const LeafBuffer& other): mData(other.mData) {}
407 ~LeafBuffer() {}
408 void fill(bool val) { mData.set(val); }
409 LeafBuffer& operator=(const LeafBuffer& b) { if (&b != this) { mData=b.mData; } return *this; }
410
411 const bool& getValue(Index i) const
412 {
413 assert(i < SIZE);
414 // We can't use the ternary operator here, otherwise Visual C++ returns
415 // a reference to a temporary.
416 if (mData.isOn(i)) return sOn; else return sOff;
417 }
418 const bool& operator[](Index i) const { return this->getValue(i); }
419
420 bool operator==(const LeafBuffer& other) const { return mData == other.mData; }
421 bool operator!=(const LeafBuffer& other) const { return mData != other.mData; }
422
423 void setValue(Index i, bool val) { assert(i < SIZE); mData.set(i, val); }
424
425 void swap(LeafBuffer& other) { if (&other != this) std::swap(mData, other.mData); }
426
427 Index memUsage() const { return sizeof(*this); }
428 static Index size() { return SIZE; }
429
432 WordType* data() { return &(mData.template getWord<WordType>(0)); }
435 const WordType* data() const { return const_cast<LeafBuffer*>(this)->data(); }
436
437 private:
438 // Allow the parent LeafNode to access this buffer's data.
439 template<typename, Index> friend class LeafNode;
440
441 NodeMaskType mData;
442 }; // class LeafBuffer
443
444
449 template<Index Log2Dim> const bool LeafBuffer<bool, Log2Dim>::sOn = true;
450 template<Index Log2Dim> const bool LeafBuffer<bool, Log2Dim>::sOff = false;
451
452 } // namespace tree
453 } // namespace OPENVDB_VERSION_NAME
454 } // namespace openvdb
455
456 #endif // OPENVDB_TREE_LEAFBUFFER_HAS_BEEN_INCLUDED
Compression.h
NodeMasks.h
openvdb::v8_1::PartialCreate
Tag dispatch class that distinguishes constructors during file input.
Definition: openvdb/Types.h:566
openvdb::v8_1::io::MappedFile::Ptr
SharedPtr< MappedFile > Ptr
Definition: io.h:136
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(const NodeMaskType &other)
Definition: LeafBuffer.h:405
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::~LeafBuffer
~LeafBuffer()
Definition: LeafBuffer.h:407
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::StorageType
WordType StorageType
Definition: LeafBuffer.h:394
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::operator!=
bool operator!=(const LeafBuffer &other) const
Definition: LeafBuffer.h:421
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::operator=
LeafBuffer & operator=(const LeafBuffer &b)
Definition: LeafBuffer.h:409
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::sOff
static const bool sOff
Definition: LeafBuffer.h:401
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::WordType
typename NodeMaskType::Word WordType
Definition: LeafBuffer.h:392
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::memUsage
Index memUsage() const
Definition: LeafBuffer.h:427
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::data
WordType * data()
Return a pointer to the C-style array of words encoding the bits.
Definition: LeafBuffer.h:432
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::swap
void swap(LeafBuffer &other)
Definition: LeafBuffer.h:425
openvdb::v8_1::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:435
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::operator==
bool operator==(const LeafBuffer &other) const
Definition: LeafBuffer.h:420
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::ValueType
bool ValueType
Definition: LeafBuffer.h:393
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(const LeafBuffer &other)
Definition: LeafBuffer.h:406
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::getValue
const bool & getValue(Index i) const
Definition: LeafBuffer.h:411
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer(bool on)
Definition: LeafBuffer.h:404
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::fill
void fill(bool val)
Definition: LeafBuffer.h:408
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::size
static Index size()
Definition: LeafBuffer.h:428
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::sOn
static const bool sOn
Definition: LeafBuffer.h:400
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::LeafBuffer
LeafBuffer()
Definition: LeafBuffer.h:403
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::operator[]
const bool & operator[](Index i) const
Definition: LeafBuffer.h:418
openvdb::v8_1::tree::LeafBuffer< bool, Log2Dim >::setValue
void setValue(Index i, bool val)
Definition: LeafBuffer.h:423
openvdb::v8_1::tree::LeafBuffer
Array of fixed size 23Log2Dim that stores the voxel values of a LeafNode.
Definition: LeafBuffer.h:31
openvdb::v8_1::tree::LeafBuffer::operator=
LeafBuffer & operator=(const LeafBuffer &)
Copy the other buffer's values into this buffer.
Definition: LeafBuffer.h:199
openvdb::v8_1::tree::LeafBuffer::~LeafBuffer
~LeafBuffer()
Destructor.
Definition: LeafBuffer.h:159
openvdb::v8_1::tree::LeafBuffer::LeafBuffer
LeafBuffer(PartialCreate, const ValueType &)
Construct a buffer but don't allocate memory for the full array of values.
Definition: LeafBuffer.h:54
openvdb::v8_1::tree::LeafBuffer::StorageType
ValueType StorageType
Definition: LeafBuffer.h:34
openvdb::v8_1::tree::LeafBuffer::LeafBuffer
LeafBuffer(const ValueType &)
Construct a buffer populated with the specified value.
Definition: LeafBuffer.h:149
openvdb::v8_1::tree::LeafBuffer::LeafBuffer
LeafBuffer(const LeafBuffer &)
Copy constructor.
Definition: LeafBuffer.h:171
openvdb::v8_1::tree::LeafBuffer::fill
void fill(const ValueType &)
Populate this buffer with a constant value.
Definition: LeafBuffer.h:225
openvdb::v8_1::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:83
openvdb::v8_1::tree::LeafBuffer::swap
void swap(LeafBuffer &)
Exchange this buffer's values with the other buffer's values.
Definition: LeafBuffer.h:253
openvdb::v8_1::tree::LeafBuffer::isOutOfCore
bool isOutOfCore() const
Return true if this buffer's values have not yet been read from disk.
Definition: LeafBuffer.h:59
openvdb::v8_1::tree::LeafBuffer::operator[]
const ValueType & operator[](Index i) const
Return a const reference to the i'th element of this buffer.
Definition: LeafBuffer.h:71
openvdb::v8_1::tree::LeafBuffer::memUsage
Index memUsage() const
Return the memory footprint of this buffer in bytes.
Definition: LeafBuffer.h:269
openvdb::v8_1::tree::LeafBuffer::mData
ValueType * mData
Definition: LeafBuffer.h:125
openvdb::v8_1::tree::LeafBuffer::mFileInfo
FileInfo * mFileInfo
Definition: LeafBuffer.h:126
openvdb::v8_1::tree::LeafBuffer::empty
bool empty() const
Return true if memory for this buffer has not yet been allocated.
Definition: LeafBuffer.h:61
openvdb::v8_1::tree::LeafBuffer::getValue
const ValueType & getValue(Index i) const
Return a const reference to the i'th element of this buffer.
Definition: LeafBuffer.h:69
openvdb::v8_1::tree::LeafBuffer::setValue
void setValue(Index i, const ValueType &)
Set the i'th value of this buffer to the specified value.
Definition: LeafBuffer.h:189
openvdb::v8_1::tree::LeafBuffer::size
static Index size()
Return the number of values contained in this buffer.
Definition: LeafBuffer.h:91
openvdb::v8_1::tree::LeafBuffer::data
const ValueType * data() const
Return a const pointer to the array of voxel values.
Definition: LeafBuffer.h:280
openvdb::v8_1::tree::LeafBuffer::SIZE
static const Index SIZE
Definition: LeafBuffer.h:36
openvdb::v8_1::tree::LeafBuffer::data
ValueType * data()
Return a pointer to the array of voxel values.
Definition: LeafBuffer.h:294
openvdb::v8_1::tree::LeafBuffer::allocate
bool allocate()
Allocate memory for this buffer if it has not already been allocated.
Definition: LeafBuffer.h:63
openvdb::v8_1::tree::LeafBuffer::LeafBuffer
LeafBuffer()
Default constructor.
Definition: LeafBuffer.h:48
openvdb::v8_1::tree::LeafBuffer::ValueType
T ValueType
Definition: LeafBuffer.h:33
openvdb::v8_1::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:238
openvdb::v8_1::tree::LeafNode
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim....
Definition: LeafNode.h:38
openvdb::v8_1::util::NodeMask
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition: NodeMasks.h:308
openvdb::v8_1::util::NodeMask::Word
Index64 Word
Definition: NodeMasks.h:316
openvdb::v8_1::util::NodeMask::WORD_COUNT
static const Index32 WORD_COUNT
Definition: NodeMasks.h:315
openvdb::v8_1::io::readCompressedValues
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:465
openvdb::v8_1::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_1::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::v8_1::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
openvdb::v8_1::Index
Index32 Index
Definition: openvdb/Types.h:50
openvdb::v8_1::SharedPtr
std::shared_ptr< T > SharedPtr
Definition: openvdb/Types.h:110
openvdb
Definition: openvdb/Exceptions.h:13
Types.h
openvdb::v8_1::tree::LeafBuffer::FileInfo
Definition: LeafBuffer.h:39
openvdb::v8_1::tree::LeafBuffer::FileInfo::FileInfo
FileInfo()
Definition: LeafBuffer.h:40
openvdb::v8_1::tree::LeafBuffer::FileInfo::meta
SharedPtr< io::StreamMetadata > meta
Definition: LeafBuffer.h:44
openvdb::v8_1::tree::LeafBuffer::FileInfo::bufpos
std::streamoff bufpos
Definition: LeafBuffer.h:41
openvdb::v8_1::tree::LeafBuffer::FileInfo::mapping
io::MappedFile::Ptr mapping
Definition: LeafBuffer.h:43
openvdb::v8_1::tree::LeafBuffer::FileInfo::maskpos
std::streamoff maskpos
Definition: LeafBuffer.h:42
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:178