OpenVDB 13.0.1
Loading...
Searching...
No Matches
NodeMasks.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3//
4/// @author Ken Museth
5///
6/// @file NodeMasks.h
7
8#ifndef OPENVDB_UTIL_NODEMASKS_HAS_BEEN_INCLUDED
9#define OPENVDB_UTIL_NODEMASKS_HAS_BEEN_INCLUDED
10
11#include <algorithm> // for std::min()
12#include <cstring>
13#include <iostream>// for cout
14#include <openvdb/version.h>
15#include <openvdb/Platform.h>
16#include <openvdb/Types.h>
17#include <openvdb/util/Assert.h>
18//#include <strings.h> // for ffs
19
20
21namespace openvdb {
23namespace OPENVDB_VERSION_NAME {
24namespace util {
25
26/// Return the number of on bits in the given 8-bit value.
27inline Index32
29{
30#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
31 return __popcnt16(v);
32#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
33 return __builtin_popcount(v);
34#else
35 // Software Implementation - Simple LUT
36 static const Byte numBits[256] = {
37#define COUNTONB2(n) n, n+1, n+1, n+2
38#define COUNTONB4(n) COUNTONB2(n), COUNTONB2(n+1), COUNTONB2(n+1), COUNTONB2(n+2)
39#define COUNTONB6(n) COUNTONB4(n), COUNTONB4(n+1), COUNTONB4(n+1), COUNTONB4(n+2)
41 };
42 return numBits[v];
43#undef COUNTONB6
44#undef COUNTONB4
45#undef COUNTONB2
46#endif
47}
48
49/// Return the number of off bits in the given 8-bit value.
50inline Index32 CountOff(Byte v) { return CountOn(static_cast<Byte>(~v)); }
51
52/// Return the number of on bits in the given 32-bit value.
53inline Index32
55{
56 v = v - ((v >> 1) & 0x55555555U);
57 v = (v & 0x33333333U) + ((v >> 2) & 0x33333333U);
58 return (((v + (v >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24;
59}
60
61/// Return the number of off bits in the given 32-bit value.
62inline Index32 CountOff(Index32 v) { return CountOn(~v); }
63
64/// Return the number of on bits in the given 64-bit value.
65inline Index32
67{
68#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER) && defined(_M_X64)
69 v = __popcnt64(v);
70#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
71 v = __builtin_popcountll(v);
72#else
73 // Software Implementation
74 v = v - ((v >> 1) & UINT64_C(0x5555555555555555));
75 v = (v & UINT64_C(0x3333333333333333)) + ((v >> 2) & UINT64_C(0x3333333333333333));
76 v = (((v + (v >> 4)) & UINT64_C(0xF0F0F0F0F0F0F0F)) * UINT64_C(0x101010101010101)) >> 56;
77#endif
78 return static_cast<Index32>(v);
79}
80
81/// Return the number of off bits in the given 64-bit value.
82inline Index32 CountOff(Index64 v) { return CountOn(~v); }
83
84/// Return the least significant on bit of the given 8-bit value.
85inline Index32
87{
89#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
90 unsigned long index;
91 _BitScanForward(&index, static_cast<Index32>(v));
92 return static_cast<Index32>(index);
93#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
94 return __builtin_ctz(v);
95#else
96 // Software Implementation
97 static const Byte DeBruijn[8] = {0, 1, 6, 2, 7, 5, 4, 3};
98 return DeBruijn[Byte((v & -v) * 0x1DU) >> 5];
99#endif
100}
101
102/// Return the least significant on bit of the given 32-bit value.
103inline Index32
105{
107 //return ffs(v);
108 static const Byte DeBruijn[32] = {
109 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
110 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
111 };
112
113// disable unary minus on unsigned warning
114#if defined(_MSC_VER)
115#pragma warning(push)
116#pragma warning(disable:4146)
117#endif
118 return DeBruijn[Index32((v & -v) * 0x077CB531U) >> 27];
119#if defined(_MSC_VER)
120#pragma warning(pop)
121#endif
122}
123
124/// Return the least significant on bit of the given 64-bit value.
125inline Index32
127{
129#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
130 unsigned long index;
131 _BitScanForward64(&index, v);
132 return static_cast<Index32>(index);
133#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
134 return static_cast<Index32>(__builtin_ctzll(v));
135#else
136 // Software Implementation
137 static const Byte DeBruijn[64] = {
138 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
139 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
140 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
141 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
142 };
143
144
145// disable unary minus on unsigned warning
146#if defined(_MSC_VER)
147#pragma warning(push)
148#pragma warning(disable:4146)
149#endif
150 return DeBruijn[Index64((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
151#if defined(_MSC_VER)
152#pragma warning(pop)
153#endif
154
155#endif
156}
157
158/// Return the most significant on bit of the given 32-bit value.
159inline Index32
161{
162 static const Byte DeBruijn[32] = {
163 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
164 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
165 };
166 v |= v >> 1; // first round down to one less than a power of 2
167 v |= v >> 2;
168 v |= v >> 4;
169 v |= v >> 8;
170 v |= v >> 16;
171 return DeBruijn[Index32(v * 0x07C4ACDDU) >> 27];
172}
173
174
175////////////////////////////////////////
176
177
178/// Base class for the bit mask iterators
179template<typename NodeMask>
181{
182protected:
183 Index32 mPos; // bit position
184 const NodeMask* mParent; // this iterator can't change the parent_mask!
185
186public:
187 BaseMaskIterator(): mPos(NodeMask::SIZE), mParent(nullptr) {}
190 {
191 OPENVDB_ASSERT((parent == nullptr && pos == 0) || (parent != nullptr && pos <= NodeMask::SIZE));
192 }
193 bool operator==(const BaseMaskIterator &iter) const {return mPos == iter.mPos;}
194 bool operator!=(const BaseMaskIterator &iter) const {return mPos != iter.mPos;}
195 bool operator< (const BaseMaskIterator &iter) const {return mPos < iter.mPos;}
197 {
198 mPos = iter.mPos; mParent = iter.mParent; return *this;
199 }
200 Index32 offset() const { return mPos; }
201 Index32 pos() const { return mPos; }
202 bool test() const { OPENVDB_ASSERT(mPos <= NodeMask::SIZE); return (mPos != NodeMask::SIZE); }
203 operator bool() const { return this->test(); }
204}; // class BaseMaskIterator
205
206
207/// @note This happens to be a const-iterator!
208template <typename NodeMask>
209class OnMaskIterator: public BaseMaskIterator<NodeMask>
210{
211private:
212 using BaseType = BaseMaskIterator<NodeMask>;
213 using BaseType::mPos;//bit position;
214 using BaseType::mParent;//this iterator can't change the parent_mask!
215public:
216 OnMaskIterator() : BaseType() {}
217 OnMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
219 {
220 OPENVDB_ASSERT(mParent != nullptr);
221 mPos = mParent->findNextOn(mPos+1);
223 }
224 void increment(Index n) { while(n-- && this->next()) ; }
225 bool next()
226 {
227 this->increment();
228 return this->test();
229 }
230 bool operator*() const {return true;}
232 {
233 this->increment();
234 return *this;
235 }
236}; // class OnMaskIterator
237
238
239template <typename NodeMask>
240class OffMaskIterator: public BaseMaskIterator<NodeMask>
241{
242private:
243 using BaseType = BaseMaskIterator<NodeMask>;
244 using BaseType::mPos;//bit position;
245 using BaseType::mParent;//this iterator can't change the parent_mask!
246public:
247 OffMaskIterator() : BaseType() {}
248 OffMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
250 {
251 OPENVDB_ASSERT(mParent != nullptr);
252 mPos=mParent->findNextOff(mPos+1);
254 }
255 void increment(Index n) { while(n-- && this->next()) ; }
256 bool next()
257 {
258 this->increment();
259 return this->test();
260 }
261 bool operator*() const {return false;}
263 {
264 this->increment();
265 return *this;
266 }
267}; // class OffMaskIterator
268
269
270template <typename NodeMask>
271class DenseMaskIterator: public BaseMaskIterator<NodeMask>
272{
273private:
274 using BaseType = BaseMaskIterator<NodeMask>;
275 using BaseType::mPos;//bit position;
276 using BaseType::mParent;//this iterator can't change the parent_mask!
277
278public:
279 DenseMaskIterator() : BaseType() {}
280 DenseMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
282 {
283 OPENVDB_ASSERT(mParent != nullptr);
284 mPos += 1;//careful - the increment might go beyond the end
286 }
287 void increment(Index n) { while(n-- && this->next()) ; }
288 bool next()
289 {
290 this->increment();
291 return this->test();
292 }
293 bool operator*() const {return mParent->isOn(mPos);}
295 {
296 this->increment();
297 return *this;
298 }
299}; // class DenseMaskIterator
300
301
302/// @brief Bit mask for the internal and leaf nodes of VDB. This
303/// is a 64-bit implementation.
304///
305/// @note A template specialization for Log2Dim=1 and Log2Dim=2 are
306/// given below.
307template<Index Log2Dim>
309{
310public:
311 static_assert(Log2Dim > 2, "expected NodeMask template specialization, got base template");
312
313 static const Index32 LOG2DIM = Log2Dim;
314 static const Index32 DIM = 1<<Log2Dim;
315 static const Index32 SIZE = 1<<3*Log2Dim;
316 static const Index32 WORD_COUNT = SIZE >> 6;// 2^6=64
317 using Word = Index64;
318
319private:
320
321 // The bits are represented as a linear array of Words, and the
322 // size of a Word is 32 or 64 bits depending on the platform.
323 // The BIT_MASK is defined as the number of bits in a Word - 1
324 //static const Index32 BIT_MASK = sizeof(void*) == 8 ? 63 : 31;
325 //static const Index32 LOG2WORD = BIT_MASK == 63 ? 6 : 5;
326 //static const Index32 WORD_COUNT = SIZE >> LOG2WORD;
327 //using Word = boost::mpl::if_c<BIT_MASK == 63, Index64, Index32>::type;
328
329 Word mWords[WORD_COUNT];//only member data!
330
331public:
332 /// Default constructor sets all bits off
333 NodeMask() { this->setOff(); }
334 /// All bits are set to the specified state
335 NodeMask(bool on) { this->set(on); }
336 /// Copy constructor
337 NodeMask(const NodeMask &other) { *this = other; }
338 /// Destructor
340 /// Assignment operator
342 {
344 const Word* w2 = other.mWords;
345 for (Word* w1 = mWords; n--; ++w1, ++w2) *w1 = *w2;
346 return *this;
347 }
348
352
353 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
354 OnIterator endOn() const { return OnIterator(SIZE,this); }
355 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
356 OffIterator endOff() const { return OffIterator(SIZE,this); }
357 DenseIterator beginDense() const { return DenseIterator(0,this); }
358 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
359
360 bool operator == (const NodeMask &other) const
361 {
362 int n = WORD_COUNT;
363 for (const Word *w1=mWords, *w2=other.mWords; n-- && *w1++ == *w2++;) ;
364 return n == -1;
365 }
366
367 bool operator != (const NodeMask &other) const { return !(*this == other); }
368
369 //
370 // Bitwise logical operations
371 //
372
373 /// @brief Apply a functor to the words of the this and the other mask.
374 ///
375 /// @details An example that implements the "operator&=" method:
376 /// @code
377 /// struct Op { inline void operator()(W &w1, const W& w2) const { w1 &= w2; } };
378 /// @endcode
379 template<typename WordOp>
380 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
381 {
382 Word *w1 = mWords;
383 const Word *w2 = other.mWords;
384 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) op( *w1, *w2);
385 return *this;
386 }
387 template<typename WordOp>
388 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
389 {
390 Word *w1 = mWords;
391 const Word *w2 = other1.mWords, *w3 = other2.mWords;
392 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2, ++w3) op( *w1, *w2, *w3);
393 return *this;
394 }
395 template<typename WordOp>
396 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
397 const WordOp& op)
398 {
399 Word *w1 = mWords;
400 const Word *w2 = other1.mWords, *w3 = other2.mWords, *w4 = other3.mWords;
401 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2, ++w3, ++w4) op( *w1, *w2, *w3, *w4);
402 return *this;
403 }
404 /// @brief Bitwise intersection
405 const NodeMask& operator&=(const NodeMask& other)
406 {
407 Word *w1 = mWords;
408 const Word *w2 = other.mWords;
409 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= *w2;
410 return *this;
411 }
412 /// @brief Bitwise union
413 const NodeMask& operator|=(const NodeMask& other)
414 {
415 Word *w1 = mWords;
416 const Word *w2 = other.mWords;
417 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 |= *w2;
418 return *this;
419 }
420 /// @brief Bitwise difference
421 const NodeMask& operator-=(const NodeMask& other)
422 {
423 Word *w1 = mWords;
424 const Word *w2 = other.mWords;
425 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= ~*w2;
426 return *this;
427 }
428 /// @brief Bitwise XOR
429 const NodeMask& operator^=(const NodeMask& other)
430 {
431 Word *w1 = mWords;
432 const Word *w2 = other.mWords;
433 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 ^= *w2;
434 return *this;
435 }
436 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
437 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; return m; }
438 NodeMask operator|(const NodeMask& other) const { NodeMask m(*this); m |= other; return m; }
439 NodeMask operator^(const NodeMask& other) const { NodeMask m(*this); m ^= other; return m; }
440
441 /// Return the byte size of this NodeMask
442 static Index32 memUsage() { return static_cast<Index32>(WORD_COUNT*sizeof(Word)); }
443 /// Return the total number of on bits
445 {
446 Index32 sum = 0, n = WORD_COUNT;
447 for (const Word* w = mWords; n--; ++w) sum += CountOn(*w);
448 return sum;
449 }
450 /// Return the total number of on bits
451 Index32 countOff() const { return SIZE-this->countOn(); }
452 /// Set the <i>n</i>th bit on
453 void setOn(Index32 n) {
454 OPENVDB_ASSERT( (n >> 6) < WORD_COUNT );
455 mWords[n >> 6] |= Word(1) << (n & 63);
456 }
457 /// Set the <i>n</i>th bit off
458 void setOff(Index32 n) {
459 OPENVDB_ASSERT( (n >> 6) < WORD_COUNT );
460 mWords[n >> 6] &= ~(Word(1) << (n & 63));
461 }
462 /// Set the <i>n</i>th bit to the specified state
463 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
464 /// Set all bits to the specified state
465 void set(bool on)
466 {
467 const Word state = on ? ~Word(0) : Word(0);
469 for (Word* w = mWords; n--; ++w) *w = state;
470 }
471 /// Set all bits on
472 void setOn()
473 {
475 for (Word* w = mWords; n--; ++w) *w = ~Word(0);
476 }
477 /// Set all bits off
478 void setOff()
479 {
481 for (Word* w = mWords; n--; ++w) *w = Word(0);
482 }
483 /// Toggle the state of the <i>n</i>th bit
484 void toggle(Index32 n) {
485 OPENVDB_ASSERT( (n >> 6) < WORD_COUNT );
486 mWords[n >> 6] ^= Word(1) << (n & 63);
487 }
488 /// Toggle the state of all bits in the mask
489 void toggle()
490 {
492 for (Word* w = mWords; n--; ++w) *w = ~*w;
493 }
494 /// Set the first bit on
495 void setFirstOn() { this->setOn(0); }
496 /// Set the last bit on
497 void setLastOn() { this->setOn(SIZE-1); }
498 /// Set the first bit off
499 void setFirstOff() { this->setOff(0); }
500 /// Set the last bit off
501 void setLastOff() { this->setOff(SIZE-1); }
502 /// Return @c true if the <i>n</i>th bit is on
503 bool isOn(Index32 n) const
504 {
505 OPENVDB_ASSERT( (n >> 6) < WORD_COUNT );
506 return 0 != (mWords[n >> 6] & (Word(1) << (n & 63)));
507 }
508 /// Return @c true if the <i>n</i>th bit is off
509 bool isOff(Index32 n) const {return !this->isOn(n); }
510 /// Return @c true if all the bits are on
511 bool isOn() const
512 {
513 int n = WORD_COUNT;
514 for (const Word *w = mWords; n-- && *w++ == ~Word(0);) ;
515 return n == -1;
516 }
517 /// Return @c true if all the bits are off
518 bool isOff() const
519 {
520 int n = WORD_COUNT;
521 for (const Word *w = mWords; n-- && *w++ == Word(0);) ;
522 return n == -1;
523 }
524 /// Return @c true if bits are either all off OR all on.
525 /// @param isOn Takes on the values of all bits if the method
526 /// returns true - else it is undefined.
527 bool isConstant(bool &isOn) const
528 {
529 isOn = (mWords[0] == ~Word(0));//first word has all bits on
530 if ( !isOn && mWords[0] != Word(0)) return false;//early out
531 const Word *w = mWords + 1, *n = mWords + WORD_COUNT;
532 while( w<n && *w == mWords[0] ) ++w;
533 return w == n;
534 }
536 {
537 Index32 n = 0;
538 const Word* w = mWords;
539 for (; n<WORD_COUNT && !*w; ++w, ++n) ;
540 return n==WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(*w);
541 }
543 {
544 Index32 n = 0;
545 const Word* w = mWords;
546 for (; n<WORD_COUNT && !~*w; ++w, ++n) ;
547 return n==WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(~*w);
548 }
549
550 //@{
551 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
552 template<typename WordT>
553 WordT getWord(Index n) const
554 {
555 OPENVDB_ASSERT(n*8*sizeof(WordT) < SIZE);
556 return reinterpret_cast<const WordT*>(mWords)[n];
557 }
558 template<typename WordT>
559 WordT& getWord(Index n)
560 {
561 OPENVDB_ASSERT(n*8*sizeof(WordT) < SIZE);
562 return reinterpret_cast<WordT*>(mWords)[n];
563 }
564 //@}
565
566 void save(std::ostream& os) const
567 {
568 os.write(reinterpret_cast<const char*>(mWords), this->memUsage());
569 }
570 void load(std::istream& is) { is.read(reinterpret_cast<char*>(mWords), this->memUsage()); }
571 void seek(std::istream& is) const { is.seekg(this->memUsage(), std::ios_base::cur); }
572 /// @brief simple print method for debugging
573 void printInfo(std::ostream& os=std::cout) const
574 {
575 os << "NodeMask: Dim=" << DIM << " Log2Dim=" << Log2Dim
576 << " Bit count=" << SIZE << " word count=" << WORD_COUNT << std::endl;
577 }
578 void printBits(std::ostream& os=std::cout, Index32 max_out=80u) const
579 {
580 const Index32 n=(SIZE>max_out ? max_out : SIZE);
581 for (Index32 i=0; i < n; ++i) {
582 if ( !(i & 63) )
583 os << "||";
584 else if ( !(i%8) )
585 os << "|";
586 os << this->isOn(i);
587 }
588 os << "|" << std::endl;
589 }
590 void printAll(std::ostream& os=std::cout, Index32 max_out=80u) const
591 {
592 this->printInfo(os);
593 this->printBits(os, max_out);
594 }
595
597 {
598 Index32 n = start >> 6;//initiate
599 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
600 Index32 m = start & 63;
601 Word b = mWords[n];
602 if (b & (Word(1) << m)) return start;//simpel case: start is on
603 b &= ~Word(0) << m;// mask out lower bits
604 while(!b && ++n<WORD_COUNT) b = mWords[n];// find next none-zero word
605 return (!b ? SIZE : (n << 6) + FindLowestOn(b));//catch last word=0
606 }
607
609 {
610 Index32 n = start >> 6;//initiate
611 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
612 Index32 m = start & 63;
613 Word b = ~mWords[n];
614 if (b & (Word(1) << m)) return start;//simpel case: start is on
615 b &= ~Word(0) << m;// mask out lower bits
616 while(!b && ++n<WORD_COUNT) b = ~mWords[n];// find next none-zero word
617 return (!b ? SIZE : (n << 6) + FindLowestOn(b));//catch last word=0
618 }
619};// NodeMask
620
621
622/// @brief Template specialization of NodeMask for Log2Dim=1, i.e. 2^3 nodes
623template<>
624class NodeMask<1>
625{
626public:
627
628 static const Index32 LOG2DIM = 1;
629 static const Index32 DIM = 2;
630 static const Index32 SIZE = 8;
631 static const Index32 WORD_COUNT = 1;
632 using Word = Byte;
633
634private:
635
636 Byte mByte;//only member data!
637
638public:
639 /// Default constructor sets all bits off
640 NodeMask() : mByte(0x00U) {}
641 /// All bits are set to the specified state
642 NodeMask(bool on) : mByte(on ? 0xFFU : 0x00U) {}
643 /// Copy constructor
644 NodeMask(const NodeMask &other) : mByte(other.mByte) {}
645 /// Destructor
647 /// Assignment operator
648 void operator = (const NodeMask &other) { mByte = other.mByte; }
649
653
654 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
655 OnIterator endOn() const { return OnIterator(SIZE,this); }
656 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
657 OffIterator endOff() const { return OffIterator(SIZE,this); }
658 DenseIterator beginDense() const { return DenseIterator(0,this); }
659 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
660
661 bool operator == (const NodeMask &other) const { return mByte == other.mByte; }
662
663 bool operator != (const NodeMask &other) const {return mByte != other.mByte; }
664
665 //
666 // Bitwise logical operations
667 //
668
669 /// @brief Apply a functor to the words of the this and the other mask.
670 ///
671 /// @details An example that implements the "operator&=" method:
672 /// @code
673 /// struct Op { inline void operator()(Word &w1, const Word& w2) const { w1 &= w2; } };
674 /// @endcode
675 template<typename WordOp>
676 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
677 {
678 op(mByte, other.mByte);
679 return *this;
680 }
681 template<typename WordOp>
682 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
683 {
684 op(mByte, other1.mByte, other2.mByte);
685 return *this;
686 }
687 template<typename WordOp>
688 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
689 const WordOp& op)
690 {
691 op(mByte, other1.mByte, other2.mByte, other3.mByte);
692 return *this;
693 }
694 /// @brief Bitwise intersection
695 const NodeMask& operator&=(const NodeMask& other)
696 {
697 mByte &= other.mByte;
698 return *this;
699 }
700 /// @brief Bitwise union
701 const NodeMask& operator|=(const NodeMask& other)
702 {
703 mByte |= other.mByte;
704 return *this;
705 }
706 /// @brief Bitwise difference
707 const NodeMask& operator-=(const NodeMask& other)
708 {
709 mByte &= static_cast<Byte>(~other.mByte);
710 return *this;
711 }
712 /// @brief Bitwise XOR
713 const NodeMask& operator^=(const NodeMask& other)
714 {
715 mByte ^= other.mByte;
716 return *this;
717 }
718 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
719 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; return m; }
720 NodeMask operator|(const NodeMask& other) const { NodeMask m(*this); m |= other; return m; }
721 NodeMask operator^(const NodeMask& other) const { NodeMask m(*this); m ^= other; return m; }
722 /// Return the byte size of this NodeMask
723 static Index32 memUsage() { return 1; }
724 /// Return the total number of on bits
725 Index32 countOn() const { return CountOn(mByte); }
726 /// Return the total number of on bits
727 Index32 countOff() const { return CountOff(mByte); }
728 /// Set the <i>n</i>th bit on
729 void setOn(Index32 n) {
730 OPENVDB_ASSERT( n < 8 );
731 mByte = static_cast<Byte>(mByte | 0x01U << (n & 7));
732 }
733 /// Set the <i>n</i>th bit off
734 void setOff(Index32 n) {
735 OPENVDB_ASSERT( n < 8 );
736 mByte = static_cast<Byte>(mByte & ~(0x01U << (n & 7)));
737 }
738 /// Set the <i>n</i>th bit to the specified state
739 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
740 /// Set all bits to the specified state
741 void set(bool on) { mByte = on ? 0xFFU : 0x00U; }
742 /// Set all bits on
743 void setOn() { mByte = 0xFFU; }
744 /// Set all bits off
745 void setOff() { mByte = 0x00U; }
746 /// Toggle the state of the <i>n</i>th bit
747 void toggle(Index32 n) {
748 OPENVDB_ASSERT( n < 8 );
749 mByte = static_cast<Byte>(mByte ^ 0x01U << (n & 7));
750 }
751 /// Toggle the state of all bits in the mask
752 void toggle() { mByte = static_cast<Byte>(~mByte); }
753 /// Set the first bit on
754 void setFirstOn() { this->setOn(0); }
755 /// Set the last bit on
756 void setLastOn() { this->setOn(7); }
757 /// Set the first bit off
758 void setFirstOff() { this->setOff(0); }
759 /// Set the last bit off
760 void setLastOff() { this->setOff(7); }
761 /// Return true if the <i>n</i>th bit is on
762 bool isOn(Index32 n) const
763 {
764 OPENVDB_ASSERT( n < 8 );
765 return mByte & (0x01U << (n & 7));
766 }
767 /// Return true if the <i>n</i>th bit is off
768 bool isOff(Index32 n) const {return !this->isOn(n); }
769 /// Return true if all the bits are on
770 bool isOn() const { return mByte == 0xFFU; }
771 /// Return true if all the bits are off
772 bool isOff() const { return mByte == 0; }
773 /// Return @c true if bits are either all off OR all on.
774 /// @param isOn Takes on the values of all bits if the method
775 /// returns true - else it is undefined.
776 bool isConstant(bool &isOn) const
777 {
778 isOn = this->isOn();
779 return isOn || this->isOff();
780 }
781 Index32 findFirstOn() const { return mByte ? FindLowestOn(mByte) : 8; }
783 {
784 const Byte b = static_cast<Byte>(~mByte);
785 return b ? FindLowestOn(b) : 8;
786 }
787 /*
788 //@{
789 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
790 /// @note This version assumes WordT=Byte and n=0!
791 template<typename WordT>
792 WordT getWord(Index n) const
793 {
794 static_assert(sizeof(WordT) == sizeof(Byte), "expected word size to be one byte");
795 OPENVDB_ASSERT(n == 0);
796 return reinterpret_cast<WordT>(mByte);
797 }
798 template<typename WordT>
799 WordT& getWord(Index n)
800 {
801 static_assert(sizeof(WordT) == sizeof(Byte), "expected word size to be one byte");
802 OPENVDB_ASSERT(n == 0);
803 return reinterpret_cast<WordT&>(mByte);
804 }
805 //@}
806 */
807 void save(std::ostream& os) const { os.write(reinterpret_cast<const char*>(&mByte), 1); }
808 void load(std::istream& is) { is.read(reinterpret_cast<char*>(&mByte), 1); }
809 void seek(std::istream& is) const { is.seekg(1, std::ios_base::cur); }
810 /// @brief simple print method for debugging
811 void printInfo(std::ostream& os=std::cout) const
812 {
813 os << "NodeMask: Dim=2, Log2Dim=1, Bit count=8, Word count=1"<<std::endl;
814 }
815 void printBits(std::ostream& os=std::cout) const
816 {
817 os << "||";
818 for (Index32 i=0; i < 8; ++i) os << this->isOn(i);
819 os << "||" << std::endl;
820 }
821 void printAll(std::ostream& os=std::cout) const
822 {
823 this->printInfo(os);
824 this->printBits(os);
825 }
826
828 {
829 if (start>=8) return 8;
830 const Byte b = static_cast<Byte>(mByte & (0xFFU << start));
831 return b ? FindLowestOn(b) : 8;
832 }
833
835 {
836 if (start>=8) return 8;
837 const Byte b = static_cast<Byte>(~mByte & (0xFFU << start));
838 return b ? FindLowestOn(b) : 8;
839 }
840
841};// NodeMask<1>
842
843
844/// @brief Template specialization of NodeMask for Log2Dim=2, i.e. 4^3 nodes
845template<>
846class NodeMask<2>
847{
848public:
849
850 static const Index32 LOG2DIM = 2;
851 static const Index32 DIM = 4;
852 static const Index32 SIZE = 64;
853 static const Index32 WORD_COUNT = 1;
854 using Word = Index64;
855
856private:
857
858 Word mWord;//only member data!
859
860public:
861 /// Default constructor sets all bits off
862 NodeMask() : mWord(UINT64_C(0x00)) {}
863 /// All bits are set to the specified state
864 NodeMask(bool on) : mWord(on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00)) {}
865 /// Copy constructor
866 NodeMask(const NodeMask &other) : mWord(other.mWord) {}
867 /// Destructor
869 /// Assignment operator
870 void operator = (const NodeMask &other) { mWord = other.mWord; }
871
875
876 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
877 OnIterator endOn() const { return OnIterator(SIZE,this); }
878 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
879 OffIterator endOff() const { return OffIterator(SIZE,this); }
880 DenseIterator beginDense() const { return DenseIterator(0,this); }
881 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
882
883 bool operator == (const NodeMask &other) const { return mWord == other.mWord; }
884
885 bool operator != (const NodeMask &other) const {return mWord != other.mWord; }
886
887 //
888 // Bitwise logical operations
889 //
890
891 /// @brief Apply a functor to the words of the this and the other mask.
892 ///
893 /// @details An example that implements the "operator&=" method:
894 /// @code
895 /// struct Op { inline void operator()(Word &w1, const Word& w2) const { w1 &= w2; } };
896 /// @endcode
897 template<typename WordOp>
898 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
899 {
900 op(mWord, other.mWord);
901 return *this;
902 }
903 template<typename WordOp>
904 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
905 {
906 op(mWord, other1.mWord, other2.mWord);
907 return *this;
908 }
909 template<typename WordOp>
910 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
911 const WordOp& op)
912 {
913 op(mWord, other1.mWord, other2.mWord, other3.mWord);
914 return *this;
915 }
916 /// @brief Bitwise intersection
917 const NodeMask& operator&=(const NodeMask& other)
918 {
919 mWord &= other.mWord;
920 return *this;
921 }
922 /// @brief Bitwise union
923 const NodeMask& operator|=(const NodeMask& other)
924 {
925 mWord |= other.mWord;
926 return *this;
927 }
928 /// @brief Bitwise difference
929 const NodeMask& operator-=(const NodeMask& other)
930 {
931 mWord &= ~other.mWord;
932 return *this;
933 }
934 /// @brief Bitwise XOR
935 const NodeMask& operator^=(const NodeMask& other)
936 {
937 mWord ^= other.mWord;
938 return *this;
939 }
940 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
941 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; return m; }
942 NodeMask operator|(const NodeMask& other) const { NodeMask m(*this); m |= other; return m; }
943 NodeMask operator^(const NodeMask& other) const { NodeMask m(*this); m ^= other; return m; }
944 /// Return the byte size of this NodeMask
945 static Index32 memUsage() { return 8; }
946 /// Return the total number of on bits
947 Index32 countOn() const { return CountOn(mWord); }
948 /// Return the total number of on bits
949 Index32 countOff() const { return CountOff(mWord); }
950 /// Set the <i>n</i>th bit on
951 void setOn(Index32 n) {
952 OPENVDB_ASSERT( n < 64 );
953 mWord |= UINT64_C(0x01) << (n & 63);
954 }
955 /// Set the <i>n</i>th bit off
956 void setOff(Index32 n) {
957 OPENVDB_ASSERT( n < 64 );
958 mWord &= ~(UINT64_C(0x01) << (n & 63));
959 }
960 /// Set the <i>n</i>th bit to the specified state
961 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
962 /// Set all bits to the specified state
963 void set(bool on) { mWord = on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00); }
964 /// Set all bits on
965 void setOn() { mWord = UINT64_C(0xFFFFFFFFFFFFFFFF); }
966 /// Set all bits off
967 void setOff() { mWord = UINT64_C(0x00); }
968 /// Toggle the state of the <i>n</i>th bit
969 void toggle(Index32 n) {
970 OPENVDB_ASSERT( n < 64 );
971 mWord ^= UINT64_C(0x01) << (n & 63);
972 }
973 /// Toggle the state of all bits in the mask
974 void toggle() { mWord = ~mWord; }
975 /// Set the first bit on
976 void setFirstOn() { this->setOn(0); }
977 /// Set the last bit on
978 void setLastOn() { this->setOn(63); }
979 /// Set the first bit off
980 void setFirstOff() { this->setOff(0); }
981 /// Set the last bit off
982 void setLastOff() { this->setOff(63); }
983 /// Return true if the <i>n</i>th bit is on
984 bool isOn(Index32 n) const
985 {
986 OPENVDB_ASSERT( n < 64 );
987 return 0 != (mWord & (UINT64_C(0x01) << (n & 63)));
988 }
989 /// Return true if the <i>n</i>th bit is off
990 bool isOff(Index32 n) const {return !this->isOn(n); }
991 /// Return true if all the bits are on
992 bool isOn() const { return mWord == UINT64_C(0xFFFFFFFFFFFFFFFF); }
993 /// Return true if all the bits are off
994 bool isOff() const { return mWord == 0; }
995 /// Return @c true if bits are either all off OR all on.
996 /// @param isOn Takes on the values of all bits if the method
997 /// returns true - else it is undefined.
998 bool isConstant(bool &isOn) const
999 { isOn = this->isOn();
1000 return isOn || this->isOff();
1001 }
1002 Index32 findFirstOn() const { return mWord ? FindLowestOn(mWord) : 64; }
1004 {
1005 const Word w = ~mWord;
1006 return w ? FindLowestOn(w) : 64;
1007 }
1008 //@{
1009 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
1010 template<typename WordT>
1011 WordT getWord(Index n) const
1012 {
1013 OPENVDB_ASSERT(n*8*sizeof(WordT) < SIZE);
1014 return reinterpret_cast<const WordT*>(&mWord)[n];
1015 }
1016 template<typename WordT>
1017 WordT& getWord(Index n)
1018 {
1019 OPENVDB_ASSERT(n*8*sizeof(WordT) < SIZE);
1020 return reinterpret_cast<WordT*>(mWord)[n];
1021 }
1022 //@}
1023 void save(std::ostream& os) const { os.write(reinterpret_cast<const char*>(&mWord), 8); }
1024 void load(std::istream& is) { is.read(reinterpret_cast<char*>(&mWord), 8); }
1025 void seek(std::istream& is) const { is.seekg(8, std::ios_base::cur); }
1026 /// @brief simple print method for debugging
1027 void printInfo(std::ostream& os=std::cout) const
1028 {
1029 os << "NodeMask: Dim=4, Log2Dim=2, Bit count=64, Word count=1"<<std::endl;
1030 }
1031 void printBits(std::ostream& os=std::cout) const
1032 {
1033 os << "|";
1034 for (Index32 i=0; i < 64; ++i) {
1035 if ( !(i%8) ) os << "|";
1036 os << this->isOn(i);
1037 }
1038 os << "||" << std::endl;
1039 }
1040 void printAll(std::ostream& os=std::cout) const
1041 {
1042 this->printInfo(os);
1043 this->printBits(os);
1044 }
1045
1047 {
1048 if (start>=64) return 64;
1049 const Word w = mWord & (UINT64_C(0xFFFFFFFFFFFFFFFF) << start);
1050 return w ? FindLowestOn(w) : 64;
1051 }
1052
1054 {
1055 if (start>=64) return 64;
1056 const Word w = ~mWord & (UINT64_C(0xFFFFFFFFFFFFFFFF) << start);
1057 return w ? FindLowestOn(w) : 64;
1058 }
1059
1060};// NodeMask<2>
1061
1062
1063} // namespace util
1064} // namespace OPENVDB_VERSION_NAME
1065} // namespace openvdb
1066
1067#endif // OPENVDB_UTIL_NODEMASKS_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
#define COUNTONB6(n)
bool operator==(const BaseMaskIterator &iter) const
Definition NodeMasks.h:193
bool test() const
Definition NodeMasks.h:202
BaseMaskIterator(const BaseMaskIterator &)=default
bool operator!=(const BaseMaskIterator &iter) const
Definition NodeMasks.h:194
BaseMaskIterator()
Definition NodeMasks.h:187
Index32 mPos
Definition NodeMasks.h:183
Index32 pos() const
Definition NodeMasks.h:201
BaseMaskIterator(Index32 pos, const NodeMask *parent)
Definition NodeMasks.h:189
Index32 offset() const
Definition NodeMasks.h:200
const NodeMask * mParent
Definition NodeMasks.h:184
BaseMaskIterator & operator=(const BaseMaskIterator &iter)
Definition NodeMasks.h:196
Definition NodeMasks.h:272
DenseMaskIterator & operator++()
Definition NodeMasks.h:294
bool operator*() const
Definition NodeMasks.h:293
DenseMaskIterator()
Definition NodeMasks.h:279
DenseMaskIterator(Index32 pos, const NodeMask *parent)
Definition NodeMasks.h:280
bool next()
Definition NodeMasks.h:288
void increment(Index n)
Definition NodeMasks.h:287
void increment()
Definition NodeMasks.h:281
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition NodeMasks.h:713
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition NodeMasks.h:768
NodeMask operator|(const NodeMask &other) const
Definition NodeMasks.h:720
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition NodeMasks.h:695
Index32 countOn() const
Return the total number of on bits.
Definition NodeMasks.h:725
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition NodeMasks.h:707
void printAll(std::ostream &os=std::cout) const
Definition NodeMasks.h:821
OnIterator beginOn() const
Definition NodeMasks.h:654
NodeMask operator^(const NodeMask &other) const
Definition NodeMasks.h:721
DenseIterator endDense() const
Definition NodeMasks.h:659
DenseIterator beginDense() const
Definition NodeMasks.h:658
OffIterator beginOff() const
Definition NodeMasks.h:656
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition NodeMasks.h:739
void setOn()
Set all bits on.
Definition NodeMasks.h:743
DenseMaskIterator< NodeMask > DenseIterator
Definition NodeMasks.h:652
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition NodeMasks.h:762
void printBits(std::ostream &os=std::cout) const
Definition NodeMasks.h:815
bool isConstant(bool &isOn) const
Definition NodeMasks.h:776
static const Index32 WORD_COUNT
Definition NodeMasks.h:631
Index32 countOff() const
Return the total number of on bits.
Definition NodeMasks.h:727
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition NodeMasks.h:747
void setLastOff()
Set the last bit off.
Definition NodeMasks.h:760
NodeMask(bool on)
All bits are set to the specified state.
Definition NodeMasks.h:642
Index32 findNextOff(Index32 start) const
Definition NodeMasks.h:834
void seek(std::istream &is) const
Definition NodeMasks.h:809
void setFirstOff()
Set the first bit off.
Definition NodeMasks.h:758
OnMaskIterator< NodeMask > OnIterator
Definition NodeMasks.h:650
void set(bool on)
Set all bits to the specified state.
Definition NodeMasks.h:741
NodeMask operator!() const
Definition NodeMasks.h:718
static const Index32 SIZE
Definition NodeMasks.h:630
void setFirstOn()
Set the first bit on.
Definition NodeMasks.h:754
static const Index32 DIM
Definition NodeMasks.h:629
OnIterator endOn() const
Definition NodeMasks.h:655
void load(std::istream &is)
Definition NodeMasks.h:808
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition NodeMasks.h:701
void save(std::ostream &os) const
Definition NodeMasks.h:807
Index32 findFirstOff() const
Definition NodeMasks.h:782
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition NodeMasks.h:723
void setOff()
Set all bits off.
Definition NodeMasks.h:745
void setOff(Index32 n)
Set the nth bit off.
Definition NodeMasks.h:734
void setOn(Index32 n)
Set the nth bit on.
Definition NodeMasks.h:729
NodeMask operator&(const NodeMask &other) const
Definition NodeMasks.h:719
bool isOff() const
Return true if all the bits are off.
Definition NodeMasks.h:772
static const Index32 LOG2DIM
Definition NodeMasks.h:628
NodeMask()
Default constructor sets all bits off.
Definition NodeMasks.h:640
NodeMask(const NodeMask &other)
Copy constructor.
Definition NodeMasks.h:644
Byte Word
Definition NodeMasks.h:632
void toggle()
Toggle the state of all bits in the mask.
Definition NodeMasks.h:752
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition NodeMasks.h:811
OffMaskIterator< NodeMask > OffIterator
Definition NodeMasks.h:651
Index32 findNextOn(Index32 start) const
Definition NodeMasks.h:827
void setLastOn()
Set the last bit on.
Definition NodeMasks.h:756
~NodeMask()
Destructor.
Definition NodeMasks.h:646
OffIterator endOff() const
Definition NodeMasks.h:657
bool isOn() const
Return true if all the bits are on.
Definition NodeMasks.h:770
Index32 findFirstOn() const
Definition NodeMasks.h:781
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition NodeMasks.h:935
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition NodeMasks.h:990
NodeMask operator|(const NodeMask &other) const
Definition NodeMasks.h:942
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition NodeMasks.h:917
Index32 countOn() const
Return the total number of on bits.
Definition NodeMasks.h:947
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition NodeMasks.h:929
Index64 Word
Definition NodeMasks.h:854
void printAll(std::ostream &os=std::cout) const
Definition NodeMasks.h:1040
OnIterator beginOn() const
Definition NodeMasks.h:876
WordT & getWord(Index n)
Definition NodeMasks.h:1017
NodeMask operator^(const NodeMask &other) const
Definition NodeMasks.h:943
DenseIterator endDense() const
Definition NodeMasks.h:881
DenseIterator beginDense() const
Definition NodeMasks.h:880
OffIterator beginOff() const
Definition NodeMasks.h:878
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition NodeMasks.h:961
void setOn()
Set all bits on.
Definition NodeMasks.h:965
DenseMaskIterator< NodeMask > DenseIterator
Definition NodeMasks.h:874
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition NodeMasks.h:984
void printBits(std::ostream &os=std::cout) const
Definition NodeMasks.h:1031
bool isConstant(bool &isOn) const
Definition NodeMasks.h:998
static const Index32 WORD_COUNT
Definition NodeMasks.h:853
Index32 countOff() const
Return the total number of on bits.
Definition NodeMasks.h:949
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition NodeMasks.h:969
void setLastOff()
Set the last bit off.
Definition NodeMasks.h:982
NodeMask(bool on)
All bits are set to the specified state.
Definition NodeMasks.h:864
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition NodeMasks.h:1011
Index32 findNextOff(Index32 start) const
Definition NodeMasks.h:1053
void seek(std::istream &is) const
Definition NodeMasks.h:1025
void setFirstOff()
Set the first bit off.
Definition NodeMasks.h:980
OnMaskIterator< NodeMask > OnIterator
Definition NodeMasks.h:872
void set(bool on)
Set all bits to the specified state.
Definition NodeMasks.h:963
NodeMask operator!() const
Definition NodeMasks.h:940
static const Index32 SIZE
Definition NodeMasks.h:852
void setFirstOn()
Set the first bit on.
Definition NodeMasks.h:976
static const Index32 DIM
Definition NodeMasks.h:851
OnIterator endOn() const
Definition NodeMasks.h:877
void load(std::istream &is)
Definition NodeMasks.h:1024
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition NodeMasks.h:923
void save(std::ostream &os) const
Definition NodeMasks.h:1023
Index32 findFirstOff() const
Definition NodeMasks.h:1003
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition NodeMasks.h:945
void setOff()
Set all bits off.
Definition NodeMasks.h:967
void setOff(Index32 n)
Set the nth bit off.
Definition NodeMasks.h:956
void setOn(Index32 n)
Set the nth bit on.
Definition NodeMasks.h:951
NodeMask operator&(const NodeMask &other) const
Definition NodeMasks.h:941
bool isOff() const
Return true if all the bits are off.
Definition NodeMasks.h:994
static const Index32 LOG2DIM
Definition NodeMasks.h:850
NodeMask()
Default constructor sets all bits off.
Definition NodeMasks.h:862
NodeMask(const NodeMask &other)
Copy constructor.
Definition NodeMasks.h:866
void toggle()
Toggle the state of all bits in the mask.
Definition NodeMasks.h:974
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition NodeMasks.h:1027
OffMaskIterator< NodeMask > OffIterator
Definition NodeMasks.h:873
Index32 findNextOn(Index32 start) const
Definition NodeMasks.h:1046
void setLastOn()
Set the last bit on.
Definition NodeMasks.h:978
~NodeMask()
Destructor.
Definition NodeMasks.h:868
OffIterator endOff() const
Definition NodeMasks.h:879
bool isOn() const
Return true if all the bits are on.
Definition NodeMasks.h:992
Index32 findFirstOn() const
Definition NodeMasks.h:1002
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition NodeMasks.h:309
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition NodeMasks.h:429
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition NodeMasks.h:509
NodeMask operator|(const NodeMask &other) const
Definition NodeMasks.h:438
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition NodeMasks.h:405
Index32 countOn() const
Return the total number of on bits.
Definition NodeMasks.h:444
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition NodeMasks.h:421
Index64 Word
Definition NodeMasks.h:317
OnIterator beginOn() const
Definition NodeMasks.h:353
WordT & getWord(Index n)
Definition NodeMasks.h:559
NodeMask operator^(const NodeMask &other) const
Definition NodeMasks.h:439
DenseIterator endDense() const
Definition NodeMasks.h:358
DenseIterator beginDense() const
Definition NodeMasks.h:357
OffIterator beginOff() const
Definition NodeMasks.h:355
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition NodeMasks.h:463
void setOn()
Set all bits on.
Definition NodeMasks.h:472
DenseMaskIterator< NodeMask > DenseIterator
Definition NodeMasks.h:351
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition NodeMasks.h:503
bool isConstant(bool &isOn) const
Definition NodeMasks.h:527
static const Index32 WORD_COUNT
Definition NodeMasks.h:316
Index32 countOff() const
Return the total number of on bits.
Definition NodeMasks.h:451
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition NodeMasks.h:484
void setLastOff()
Set the last bit off.
Definition NodeMasks.h:501
NodeMask(bool on)
All bits are set to the specified state.
Definition NodeMasks.h:335
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition NodeMasks.h:553
Index32 findNextOff(Index32 start) const
Definition NodeMasks.h:608
void seek(std::istream &is) const
Definition NodeMasks.h:571
void setFirstOff()
Set the first bit off.
Definition NodeMasks.h:499
OnMaskIterator< NodeMask > OnIterator
Definition NodeMasks.h:349
void set(bool on)
Set all bits to the specified state.
Definition NodeMasks.h:465
NodeMask operator!() const
Definition NodeMasks.h:436
static const Index32 SIZE
Definition NodeMasks.h:315
void setFirstOn()
Set the first bit on.
Definition NodeMasks.h:495
static const Index32 DIM
Definition NodeMasks.h:314
OnIterator endOn() const
Definition NodeMasks.h:354
void load(std::istream &is)
Definition NodeMasks.h:570
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition NodeMasks.h:413
void save(std::ostream &os) const
Definition NodeMasks.h:566
Index32 findFirstOff() const
Definition NodeMasks.h:542
void printBits(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition NodeMasks.h:578
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition NodeMasks.h:442
void setOff()
Set all bits off.
Definition NodeMasks.h:478
void setOff(Index32 n)
Set the nth bit off.
Definition NodeMasks.h:458
void setOn(Index32 n)
Set the nth bit on.
Definition NodeMasks.h:453
NodeMask operator&(const NodeMask &other) const
Definition NodeMasks.h:437
bool isOff() const
Return true if all the bits are off.
Definition NodeMasks.h:518
NodeMask & operator=(const NodeMask &other)
Assignment operator.
Definition NodeMasks.h:341
static const Index32 LOG2DIM
Definition NodeMasks.h:313
NodeMask()
Default constructor sets all bits off.
Definition NodeMasks.h:333
NodeMask(const NodeMask &other)
Copy constructor.
Definition NodeMasks.h:337
void toggle()
Toggle the state of all bits in the mask.
Definition NodeMasks.h:489
void printAll(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition NodeMasks.h:590
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition NodeMasks.h:573
OffMaskIterator< NodeMask > OffIterator
Definition NodeMasks.h:350
Index32 findNextOn(Index32 start) const
Definition NodeMasks.h:596
void setLastOn()
Set the last bit on.
Definition NodeMasks.h:497
~NodeMask()
Destructor.
Definition NodeMasks.h:339
OffIterator endOff() const
Definition NodeMasks.h:356
bool isOn() const
Return true if all the bits are on.
Definition NodeMasks.h:511
Index32 findFirstOn() const
Definition NodeMasks.h:535
Definition NodeMasks.h:241
bool operator*() const
Definition NodeMasks.h:261
OffMaskIterator()
Definition NodeMasks.h:247
OffMaskIterator(Index32 pos, const NodeMask *parent)
Definition NodeMasks.h:248
bool next()
Definition NodeMasks.h:256
OffMaskIterator & operator++()
Definition NodeMasks.h:262
void increment(Index n)
Definition NodeMasks.h:255
void increment()
Definition NodeMasks.h:249
Definition NodeMasks.h:210
bool operator*() const
Definition NodeMasks.h:230
OnMaskIterator & operator++()
Definition NodeMasks.h:231
bool next()
Definition NodeMasks.h:225
OnMaskIterator(Index32 pos, const NodeMask *parent)
Definition NodeMasks.h:217
OnMaskIterator()
Definition NodeMasks.h:216
void increment(Index n)
Definition NodeMasks.h:224
void increment()
Definition NodeMasks.h:218
Index32 CountOff(Byte v)
Return the number of off bits in the given 8-bit value.
Definition NodeMasks.h:50
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition NodeMasks.h:160
Index32 FindLowestOn(Byte v)
Return the least significant on bit of the given 8-bit value.
Definition NodeMasks.h:86
Index32 CountOn(Byte v)
Return the number of on bits in the given 8-bit value.
Definition NodeMasks.h:28
Index32 Index
Definition Types.h:34
unsigned char Byte
Definition Types.h:39
uint32_t Index32
Definition Types.h:32
uint64_t Index64
Definition Types.h:33
Definition Exceptions.h:13
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284