OpenVDB: openvdb/util/NodeMasks.h Source File

OpenVDB 10.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: MPL-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 <cassert>
13#include <cstring>
14#include <iostream>// for cout
15#include <openvdb/Platform.h>
16#include <openvdb/Types.h>
17//#include <strings.h> // for ffs
18
19
20namespace openvdb {
21 OPENVDB_USE_VERSION_NAMESPACE
22namespace OPENVDB_VERSION_NAME {
23namespace util {
24
25/// Return the number of on bits in the given 8-bit value.
26inline Index32
27CountOn(Byte v)
28{
29#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
30 return __popcnt16(v);
31#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
32 return __builtin_popcount(v);
33#else
34 // Software Implementation - Simple LUT
35 static const Byte numBits[256] = {
36#define COUNTONB2(n) n, n+1, n+1, n+2
37#define COUNTONB4(n) COUNTONB2(n), COUNTONB2(n+1), COUNTONB2(n+1), COUNTONB2(n+2)
38#define COUNTONB6(n) COUNTONB4(n), COUNTONB4(n+1), COUNTONB4(n+1), COUNTONB4(n+2)
39 COUNTONB6(0), COUNTONB6(1), COUNTONB6(1), COUNTONB6(2)
40 };
41 return numBits[v];
42#undef COUNTONB6
43#undef COUNTONB4
44#undef COUNTONB2
45#endif
46}
47
48/// Return the number of off bits in the given 8-bit value.
49 inline Index32 CountOff(Byte v) { return CountOn(static_cast<Byte>(~v)); }
50
51/// Return the number of on bits in the given 32-bit value.
52inline Index32
53 CountOn(Index32 v)
54{
55 v = v - ((v >> 1) & 0x55555555U);
56 v = (v & 0x33333333U) + ((v >> 2) & 0x33333333U);
57 return (((v + (v >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24;
58}
59
60/// Return the number of off bits in the given 32-bit value.
61 inline Index32 CountOff(Index32 v) { return CountOn(~v); }
62
63/// Return the number of on bits in the given 64-bit value.
64inline Index32
65 CountOn(Index64 v)
66{
67#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER) && defined(_M_X64)
68 v = __popcnt64(v);
69#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
70 v = __builtin_popcountll(v);
71#else
72 // Software Implementation
73 v = v - ((v >> 1) & UINT64_C(0x5555555555555555));
74 v = (v & UINT64_C(0x3333333333333333)) + ((v >> 2) & UINT64_C(0x3333333333333333));
75 v = (((v + (v >> 4)) & UINT64_C(0xF0F0F0F0F0F0F0F)) * UINT64_C(0x101010101010101)) >> 56;
76#endif
77 return static_cast<Index32>(v);
78}
79
80/// Return the number of off bits in the given 64-bit value.
81 inline Index32 CountOff(Index64 v) { return CountOn(~v); }
82
83/// Return the least significant on bit of the given 8-bit value.
84inline Index32
85FindLowestOn(Byte v)
86{
87 assert(v);
88#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
89 unsigned long index;
90 _BitScanForward(&index, static_cast<Index32>(v));
91 return static_cast<Index32>(index);
92#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
93 return __builtin_ctz(v);
94#else
95 // Software Implementation
96 static const Byte DeBruijn[8] = {0, 1, 6, 2, 7, 5, 4, 3};
97 return DeBruijn[Byte((v & -v) * 0x1DU) >> 5];
98#endif
99}
100
101/// Return the least significant on bit of the given 32-bit value.
102inline Index32
103 FindLowestOn(Index32 v)
104{
105 assert(v);
106 //return ffs(v);
107 static const Byte DeBruijn[32] = {
108 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
109 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
110 };
111
112// disable unary minus on unsigned warning
113#if defined(_MSC_VER)
114#pragma warning(push)
115#pragma warning(disable:4146)
116#endif
117 return DeBruijn[Index32((v & -v) * 0x077CB531U) >> 27];
118#if defined(_MSC_VER)
119#pragma warning(pop)
120#endif
121}
122
123/// Return the least significant on bit of the given 64-bit value.
124inline Index32
125 FindLowestOn(Index64 v)
126{
127 assert(v);
128#if defined(OPENVDB_USE_SSE42) && defined(_MSC_VER)
129 unsigned long index;
130 _BitScanForward64(&index, v);
131 return static_cast<Index32>(index);
132#elif defined(OPENVDB_USE_SSE42) && (defined(__GNUC__) || defined(__clang__))
133 return static_cast<Index32>(__builtin_ctzll(v));
134#else
135 // Software Implementation
136 static const Byte DeBruijn[64] = {
137 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
138 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
139 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
140 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
141 };
142
143
144// disable unary minus on unsigned warning
145#if defined(_MSC_VER)
146#pragma warning(push)
147#pragma warning(disable:4146)
148#endif
149 return DeBruijn[Index64((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
150#if defined(_MSC_VER)
151#pragma warning(pop)
152#endif
153
154#endif
155}
156
157/// Return the most significant on bit of the given 32-bit value.
158inline Index32
159FindHighestOn(Index32 v)
160{
161 static const Byte DeBruijn[32] = {
162 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
163 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
164 };
165 v |= v >> 1; // first round down to one less than a power of 2
166 v |= v >> 2;
167 v |= v >> 4;
168 v |= v >> 8;
169 v |= v >> 16;
170 return DeBruijn[Index32(v * 0x07C4ACDDU) >> 27];
171}
172
173
174////////////////////////////////////////
175
176
177/// Base class for the bit mask iterators
178template<typename NodeMask>
179 class BaseMaskIterator
180{
181protected:
182 Index32 mPos; // bit position
183 const NodeMask* mParent; // this iterator can't change the parent_mask!
184
185public:
186 BaseMaskIterator(): mPos(NodeMask::SIZE), mParent(nullptr) {}
187 BaseMaskIterator(const BaseMaskIterator&) = default;
188 BaseMaskIterator(Index32 pos, const NodeMask* parent): mPos(pos), mParent(parent)
189 {
190 assert((parent == nullptr && pos == 0) || (parent != nullptr && pos <= NodeMask::SIZE));
191 }
192 bool operator==(const BaseMaskIterator &iter) const {return mPos == iter.mPos;}
193 bool operator!=(const BaseMaskIterator &iter) const {return mPos != iter.mPos;}
194 bool operator< (const BaseMaskIterator &iter) const {return mPos < iter.mPos;}
195 BaseMaskIterator& operator=(const BaseMaskIterator& iter)
196 {
197 mPos = iter.mPos; mParent = iter.mParent; return *this;
198 }
199 Index32 offset() const { return mPos; }
200 Index32 pos() const { return mPos; }
201 bool test() const { assert(mPos <= NodeMask::SIZE); return (mPos != NodeMask::SIZE); }
202 operator bool() const { return this->test(); }
203}; // class BaseMaskIterator
204
205
206/// @note This happens to be a const-iterator!
207template <typename NodeMask>
208 class OnMaskIterator: public BaseMaskIterator<NodeMask>
209{
210private:
211 using BaseType = BaseMaskIterator<NodeMask>;
212 using BaseType::mPos;//bit position;
213 using BaseType::mParent;//this iterator can't change the parent_mask!
214public:
215 OnMaskIterator() : BaseType() {}
216 OnMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
217 void increment()
218 {
219 assert(mParent != nullptr);
220 mPos = mParent->findNextOn(mPos+1);
221 assert(mPos <= NodeMask::SIZE);
222 }
223 void increment(Index n) { while(n-- && this->next()) ; }
224 bool next()
225 {
226 this->increment();
227 return this->test();
228 }
229 bool operator*() const {return true;}
230 OnMaskIterator& operator++()
231 {
232 this->increment();
233 return *this;
234 }
235}; // class OnMaskIterator
236
237
238template <typename NodeMask>
239 class OffMaskIterator: public BaseMaskIterator<NodeMask>
240{
241private:
242 using BaseType = BaseMaskIterator<NodeMask>;
243 using BaseType::mPos;//bit position;
244 using BaseType::mParent;//this iterator can't change the parent_mask!
245public:
246 OffMaskIterator() : BaseType() {}
247 OffMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
248 void increment()
249 {
250 assert(mParent != nullptr);
251 mPos=mParent->findNextOff(mPos+1);
252 assert(mPos <= NodeMask::SIZE);
253 }
254 void increment(Index n) { while(n-- && this->next()) ; }
255 bool next()
256 {
257 this->increment();
258 return this->test();
259 }
260 bool operator*() const {return false;}
261 OffMaskIterator& operator++()
262 {
263 this->increment();
264 return *this;
265 }
266}; // class OffMaskIterator
267
268
269template <typename NodeMask>
270 class DenseMaskIterator: public BaseMaskIterator<NodeMask>
271{
272private:
273 using BaseType = BaseMaskIterator<NodeMask>;
274 using BaseType::mPos;//bit position;
275 using BaseType::mParent;//this iterator can't change the parent_mask!
276
277public:
278 DenseMaskIterator() : BaseType() {}
279 DenseMaskIterator(Index32 pos,const NodeMask *parent) : BaseType(pos,parent) {}
280 void increment()
281 {
282 assert(mParent != nullptr);
283 mPos += 1;//careful - the increment might go beyond the end
284 assert(mPos<= NodeMask::SIZE);
285 }
286 void increment(Index n) { while(n-- && this->next()) ; }
287 bool next()
288 {
289 this->increment();
290 return this->test();
291 }
292 bool operator*() const {return mParent->isOn(mPos);}
293 DenseMaskIterator& operator++()
294 {
295 this->increment();
296 return *this;
297 }
298}; // class DenseMaskIterator
299
300
301/// @brief Bit mask for the internal and leaf nodes of VDB. This
302/// is a 64-bit implementation.
303///
304/// @note A template specialization for Log2Dim=1 and Log2Dim=2 are
305/// given below.
306template<Index Log2Dim>
307 class NodeMask
308{
309public:
310 static_assert(Log2Dim > 2, "expected NodeMask template specialization, got base template");
311
312 static const Index32 LOG2DIM = Log2Dim;
313 static const Index32 DIM = 1<<Log2Dim;
314 static const Index32 SIZE = 1<<3*Log2Dim;
315 static const Index32 WORD_COUNT = SIZE >> 6;// 2^6=64
316 using Word = Index64;
317
318private:
319
320 // The bits are represented as a linear array of Words, and the
321 // size of a Word is 32 or 64 bits depending on the platform.
322 // The BIT_MASK is defined as the number of bits in a Word - 1
323 //static const Index32 BIT_MASK = sizeof(void*) == 8 ? 63 : 31;
324 //static const Index32 LOG2WORD = BIT_MASK == 63 ? 6 : 5;
325 //static const Index32 WORD_COUNT = SIZE >> LOG2WORD;
326 //using Word = boost::mpl::if_c<BIT_MASK == 63, Index64, Index32>::type;
327
328 Word mWords[WORD_COUNT];//only member data!
329
330public:
331 /// Default constructor sets all bits off
332 NodeMask() { this->setOff(); }
333 /// All bits are set to the specified state
334 NodeMask(bool on) { this->set(on); }
335 /// Copy constructor
336 NodeMask(const NodeMask &other) { *this = other; }
337 /// Destructor
338 ~NodeMask() {}
339 /// Assignment operator
340 NodeMask& operator=(const NodeMask& other)
341 {
342 Index32 n = WORD_COUNT;
343 const Word* w2 = other.mWords;
344 for (Word* w1 = mWords; n--; ++w1, ++w2) *w1 = *w2;
345 return *this;
346 }
347
348 using OnIterator = OnMaskIterator<NodeMask>;
349 using OffIterator = OffMaskIterator<NodeMask>;
350 using DenseIterator = DenseMaskIterator<NodeMask>;
351
352 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
353 OnIterator endOn() const { return OnIterator(SIZE,this); }
354 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
355 OffIterator endOff() const { return OffIterator(SIZE,this); }
356 DenseIterator beginDense() const { return DenseIterator(0,this); }
357 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
358
359 bool operator == (const NodeMask &other) const
360 {
361 int n = WORD_COUNT;
362 for (const Word *w1=mWords, *w2=other.mWords; n-- && *w1++ == *w2++;) ;
363 return n == -1;
364 }
365
366 bool operator != (const NodeMask &other) const { return !(*this == other); }
367
368 //
369 // Bitwise logical operations
370 //
371
372 /// @brief Apply a functor to the words of the this and the other mask.
373 ///
374 /// @details An example that implements the "operator&=" method:
375 /// @code
376 /// struct Op { inline void operator()(W &w1, const W& w2) const { w1 &= w2; } };
377 /// @endcode
378 template<typename WordOp>
379 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
380 {
381 Word *w1 = mWords;
382 const Word *w2 = other.mWords;
383 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) op( *w1, *w2);
384 return *this;
385 }
386 template<typename WordOp>
387 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
388 {
389 Word *w1 = mWords;
390 const Word *w2 = other1.mWords, *w3 = other2.mWords;
391 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2, ++w3) op( *w1, *w2, *w3);
392 return *this;
393 }
394 template<typename WordOp>
395 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
396 const WordOp& op)
397 {
398 Word *w1 = mWords;
399 const Word *w2 = other1.mWords, *w3 = other2.mWords, *w4 = other3.mWords;
400 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2, ++w3, ++w4) op( *w1, *w2, *w3, *w4);
401 return *this;
402 }
403 /// @brief Bitwise intersection
404 const NodeMask& operator&=(const NodeMask& other)
405 {
406 Word *w1 = mWords;
407 const Word *w2 = other.mWords;
408 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= *w2;
409 return *this;
410 }
411 /// @brief Bitwise union
412 const NodeMask& operator|=(const NodeMask& other)
413 {
414 Word *w1 = mWords;
415 const Word *w2 = other.mWords;
416 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 |= *w2;
417 return *this;
418 }
419 /// @brief Bitwise difference
420 const NodeMask& operator-=(const NodeMask& other)
421 {
422 Word *w1 = mWords;
423 const Word *w2 = other.mWords;
424 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= ~*w2;
425 return *this;
426 }
427 /// @brief Bitwise XOR
428 const NodeMask& operator^=(const NodeMask& other)
429 {
430 Word *w1 = mWords;
431 const Word *w2 = other.mWords;
432 for (Index32 n = WORD_COUNT; n--; ++w1, ++w2) *w1 ^= *w2;
433 return *this;
434 }
435 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
436 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; 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
440 /// Return the byte size of this NodeMask
441 static Index32 memUsage() { return static_cast<Index32>(WORD_COUNT*sizeof(Word)); }
442 /// Return the total number of on bits
443 Index32 countOn() const
444 {
445 Index32 sum = 0, n = WORD_COUNT;
446 for (const Word* w = mWords; n--; ++w) sum += CountOn(*w);
447 return sum;
448 }
449 /// Return the total number of on bits
450 Index32 countOff() const { return SIZE-this->countOn(); }
451 /// Set the <i>n</i>th bit on
452 void setOn(Index32 n) {
453 assert( (n >> 6) < WORD_COUNT );
454 mWords[n >> 6] |= Word(1) << (n & 63);
455 }
456 /// Set the <i>n</i>th bit off
457 void setOff(Index32 n) {
458 assert( (n >> 6) < WORD_COUNT );
459 mWords[n >> 6] &= ~(Word(1) << (n & 63));
460 }
461 /// Set the <i>n</i>th bit to the specified state
462 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
463 /// Set all bits to the specified state
464 void set(bool on)
465 {
466 const Word state = on ? ~Word(0) : Word(0);
467 Index32 n = WORD_COUNT;
468 for (Word* w = mWords; n--; ++w) *w = state;
469 }
470 /// Set all bits on
471 void setOn()
472 {
473 Index32 n = WORD_COUNT;
474 for (Word* w = mWords; n--; ++w) *w = ~Word(0);
475 }
476 /// Set all bits off
477 void setOff()
478 {
479 Index32 n = WORD_COUNT;
480 for (Word* w = mWords; n--; ++w) *w = Word(0);
481 }
482 /// Toggle the state of the <i>n</i>th bit
483 void toggle(Index32 n) {
484 assert( (n >> 6) < WORD_COUNT );
485 mWords[n >> 6] ^= Word(1) << (n & 63);
486 }
487 /// Toggle the state of all bits in the mask
488 void toggle()
489 {
490 Index32 n = WORD_COUNT;
491 for (Word* w = mWords; n--; ++w) *w = ~*w;
492 }
493 /// Set the first bit on
494 void setFirstOn() { this->setOn(0); }
495 /// Set the last bit on
496 void setLastOn() { this->setOn(SIZE-1); }
497 /// Set the first bit off
498 void setFirstOff() { this->setOff(0); }
499 /// Set the last bit off
500 void setLastOff() { this->setOff(SIZE-1); }
501 /// Return @c true if the <i>n</i>th bit is on
502 bool isOn(Index32 n) const
503 {
504 assert( (n >> 6) < WORD_COUNT );
505 return 0 != (mWords[n >> 6] & (Word(1) << (n & 63)));
506 }
507 /// Return @c true if the <i>n</i>th bit is off
508 bool isOff(Index32 n) const {return !this->isOn(n); }
509 /// Return @c true if all the bits are on
510 bool isOn() const
511 {
512 int n = WORD_COUNT;
513 for (const Word *w = mWords; n-- && *w++ == ~Word(0);) ;
514 return n == -1;
515 }
516 /// Return @c true if all the bits are off
517 bool isOff() const
518 {
519 int n = WORD_COUNT;
520 for (const Word *w = mWords; n-- && *w++ == Word(0);) ;
521 return n == -1;
522 }
523 /// Return @c true if bits are either all off OR all on.
524 /// @param isOn Takes on the values of all bits if the method
525 /// returns true - else it is undefined.
526 bool isConstant(bool &isOn) const
527 {
528 isOn = (mWords[0] == ~Word(0));//first word has all bits on
529 if ( !isOn && mWords[0] != Word(0)) return false;//early out
530 const Word *w = mWords + 1, *n = mWords + WORD_COUNT;
531 while( w<n && *w == mWords[0] ) ++w;
532 return w == n;
533 }
534 Index32 findFirstOn() const
535 {
536 Index32 n = 0;
537 const Word* w = mWords;
538 for (; n<WORD_COUNT && !*w; ++w, ++n) ;
539 return n==WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(*w);
540 }
541 Index32 findFirstOff() const
542 {
543 Index32 n = 0;
544 const Word* w = mWords;
545 for (; n<WORD_COUNT && !~*w; ++w, ++n) ;
546 return n==WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(~*w);
547 }
548
549 //@{
550 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
551 template<typename WordT>
552 WordT getWord(Index n) const
553 {
554 assert(n*8*sizeof(WordT) < SIZE);
555 return reinterpret_cast<const WordT*>(mWords)[n];
556 }
557 template<typename WordT>
558 WordT& getWord(Index n)
559 {
560 assert(n*8*sizeof(WordT) < SIZE);
561 return reinterpret_cast<WordT*>(mWords)[n];
562 }
563 //@}
564
565 void save(std::ostream& os) const
566 {
567 os.write(reinterpret_cast<const char*>(mWords), this->memUsage());
568 }
569 void load(std::istream& is) { is.read(reinterpret_cast<char*>(mWords), this->memUsage()); }
570 void seek(std::istream& is) const { is.seekg(this->memUsage(), std::ios_base::cur); }
571 /// @brief simple print method for debugging
572 void printInfo(std::ostream& os=std::cout) const
573 {
574 os << "NodeMask: Dim=" << DIM << " Log2Dim=" << Log2Dim
575 << " Bit count=" << SIZE << " word count=" << WORD_COUNT << std::endl;
576 }
577 void printBits(std::ostream& os=std::cout, Index32 max_out=80u) const
578 {
579 const Index32 n=(SIZE>max_out ? max_out : SIZE);
580 for (Index32 i=0; i < n; ++i) {
581 if ( !(i & 63) )
582 os << "||";
583 else if ( !(i%8) )
584 os << "|";
585 os << this->isOn(i);
586 }
587 os << "|" << std::endl;
588 }
589 void printAll(std::ostream& os=std::cout, Index32 max_out=80u) const
590 {
591 this->printInfo(os);
592 this->printBits(os, max_out);
593 }
594
595 Index32 findNextOn(Index32 start) const
596 {
597 Index32 n = start >> 6;//initiate
598 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
599 Index32 m = start & 63;
600 Word b = mWords[n];
601 if (b & (Word(1) << m)) return start;//simpel case: start is on
602 b &= ~Word(0) << m;// mask out lower bits
603 while(!b && ++n<WORD_COUNT) b = mWords[n];// find next none-zero word
604 return (!b ? SIZE : (n << 6) + FindLowestOn(b));//catch last word=0
605 }
606
607 Index32 findNextOff(Index32 start) const
608 {
609 Index32 n = start >> 6;//initiate
610 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
611 Index32 m = start & 63;
612 Word b = ~mWords[n];
613 if (b & (Word(1) << m)) return start;//simpel case: start is on
614 b &= ~Word(0) << m;// mask out lower bits
615 while(!b && ++n<WORD_COUNT) b = ~mWords[n];// find next none-zero word
616 return (!b ? SIZE : (n << 6) + FindLowestOn(b));//catch last word=0
617 }
618};// NodeMask
619
620
621/// @brief Template specialization of NodeMask for Log2Dim=1, i.e. 2^3 nodes
622template<>
623 class NodeMask<1>
624{
625public:
626
627 static const Index32 LOG2DIM = 1;
628 static const Index32 DIM = 2;
629 static const Index32 SIZE = 8;
630 static const Index32 WORD_COUNT = 1;
631 using Word = Byte;
632
633private:
634
635 Byte mByte;//only member data!
636
637public:
638 /// Default constructor sets all bits off
639 NodeMask() : mByte(0x00U) {}
640 /// All bits are set to the specified state
641 NodeMask(bool on) : mByte(on ? 0xFFU : 0x00U) {}
642 /// Copy constructor
643 NodeMask(const NodeMask &other) : mByte(other.mByte) {}
644 /// Destructor
645 ~NodeMask() {}
646 /// Assignment operator
647 void operator = (const NodeMask &other) { mByte = other.mByte; }
648
649 using OnIterator = OnMaskIterator<NodeMask>;
650 using OffIterator = OffMaskIterator<NodeMask>;
651 using DenseIterator = DenseMaskIterator<NodeMask>;
652
653 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
654 OnIterator endOn() const { return OnIterator(SIZE,this); }
655 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
656 OffIterator endOff() const { return OffIterator(SIZE,this); }
657 DenseIterator beginDense() const { return DenseIterator(0,this); }
658 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
659
660 bool operator == (const NodeMask &other) const { return mByte == other.mByte; }
661
662 bool operator != (const NodeMask &other) const {return mByte != other.mByte; }
663
664 //
665 // Bitwise logical operations
666 //
667
668 /// @brief Apply a functor to the words of the this and the other mask.
669 ///
670 /// @details An example that implements the "operator&=" method:
671 /// @code
672 /// struct Op { inline void operator()(Word &w1, const Word& w2) const { w1 &= w2; } };
673 /// @endcode
674 template<typename WordOp>
675 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
676 {
677 op(mByte, other.mByte);
678 return *this;
679 }
680 template<typename WordOp>
681 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
682 {
683 op(mByte, other1.mByte, other2.mByte);
684 return *this;
685 }
686 template<typename WordOp>
687 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
688 const WordOp& op)
689 {
690 op(mByte, other1.mByte, other2.mByte, other3.mByte);
691 return *this;
692 }
693 /// @brief Bitwise intersection
694 const NodeMask& operator&=(const NodeMask& other)
695 {
696 mByte &= other.mByte;
697 return *this;
698 }
699 /// @brief Bitwise union
700 const NodeMask& operator|=(const NodeMask& other)
701 {
702 mByte |= other.mByte;
703 return *this;
704 }
705 /// @brief Bitwise difference
706 const NodeMask& operator-=(const NodeMask& other)
707 {
708 mByte &= static_cast<Byte>(~other.mByte);
709 return *this;
710 }
711 /// @brief Bitwise XOR
712 const NodeMask& operator^=(const NodeMask& other)
713 {
714 mByte ^= other.mByte;
715 return *this;
716 }
717 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
718 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; 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 /// Return the byte size of this NodeMask
722 static Index32 memUsage() { return 1; }
723 /// Return the total number of on bits
724 Index32 countOn() const { return CountOn(mByte); }
725 /// Return the total number of on bits
726 Index32 countOff() const { return CountOff(mByte); }
727 /// Set the <i>n</i>th bit on
728 void setOn(Index32 n) {
729 assert( n < 8 );
730 mByte = static_cast<Byte>(mByte | 0x01U << (n & 7));
731 }
732 /// Set the <i>n</i>th bit off
733 void setOff(Index32 n) {
734 assert( n < 8 );
735 mByte = static_cast<Byte>(mByte & ~(0x01U << (n & 7)));
736 }
737 /// Set the <i>n</i>th bit to the specified state
738 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
739 /// Set all bits to the specified state
740 void set(bool on) { mByte = on ? 0xFFU : 0x00U; }
741 /// Set all bits on
742 void setOn() { mByte = 0xFFU; }
743 /// Set all bits off
744 void setOff() { mByte = 0x00U; }
745 /// Toggle the state of the <i>n</i>th bit
746 void toggle(Index32 n) {
747 assert( n < 8 );
748 mByte = static_cast<Byte>(mByte ^ 0x01U << (n & 7));
749 }
750 /// Toggle the state of all bits in the mask
751 void toggle() { mByte = static_cast<Byte>(~mByte); }
752 /// Set the first bit on
753 void setFirstOn() { this->setOn(0); }
754 /// Set the last bit on
755 void setLastOn() { this->setOn(7); }
756 /// Set the first bit off
757 void setFirstOff() { this->setOff(0); }
758 /// Set the last bit off
759 void setLastOff() { this->setOff(7); }
760 /// Return true if the <i>n</i>th bit is on
761 bool isOn(Index32 n) const
762 {
763 assert( n < 8 );
764 return mByte & (0x01U << (n & 7));
765 }
766 /// Return true if the <i>n</i>th bit is off
767 bool isOff(Index32 n) const {return !this->isOn(n); }
768 /// Return true if all the bits are on
769 bool isOn() const { return mByte == 0xFFU; }
770 /// Return true if all the bits are off
771 bool isOff() const { return mByte == 0; }
772 /// Return @c true if bits are either all off OR all on.
773 /// @param isOn Takes on the values of all bits if the method
774 /// returns true - else it is undefined.
775 bool isConstant(bool &isOn) const
776 {
777 isOn = this->isOn();
778 return isOn || this->isOff();
779 }
780 Index32 findFirstOn() const { return mByte ? FindLowestOn(mByte) : 8; }
781 Index32 findFirstOff() const
782 {
783 const Byte b = static_cast<Byte>(~mByte);
784 return b ? FindLowestOn(b) : 8;
785 }
786 /*
787 //@{
788 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
789 /// @note This version assumes WordT=Byte and n=0!
790 template<typename WordT>
791 WordT getWord(Index n) const
792 {
793 static_assert(sizeof(WordT) == sizeof(Byte), "expected word size to be one byte");
794 assert(n == 0);
795 return reinterpret_cast<WordT>(mByte);
796 }
797 template<typename WordT>
798 WordT& getWord(Index n)
799 {
800 static_assert(sizeof(WordT) == sizeof(Byte), "expected word size to be one byte");
801 assert(n == 0);
802 return reinterpret_cast<WordT&>(mByte);
803 }
804 //@}
805 */
806 void save(std::ostream& os) const { os.write(reinterpret_cast<const char*>(&mByte), 1); }
807 void load(std::istream& is) { is.read(reinterpret_cast<char*>(&mByte), 1); }
808 void seek(std::istream& is) const { is.seekg(1, std::ios_base::cur); }
809 /// @brief simple print method for debugging
810 void printInfo(std::ostream& os=std::cout) const
811 {
812 os << "NodeMask: Dim=2, Log2Dim=1, Bit count=8, Word count=1"<<std::endl;
813 }
814 void printBits(std::ostream& os=std::cout) const
815 {
816 os << "||";
817 for (Index32 i=0; i < 8; ++i) os << this->isOn(i);
818 os << "||" << std::endl;
819 }
820 void printAll(std::ostream& os=std::cout) const
821 {
822 this->printInfo(os);
823 this->printBits(os);
824 }
825
826 Index32 findNextOn(Index32 start) const
827 {
828 if (start>=8) return 8;
829 const Byte b = static_cast<Byte>(mByte & (0xFFU << start));
830 return b ? FindLowestOn(b) : 8;
831 }
832
833 Index32 findNextOff(Index32 start) const
834 {
835 if (start>=8) return 8;
836 const Byte b = static_cast<Byte>(~mByte & (0xFFU << start));
837 return b ? FindLowestOn(b) : 8;
838 }
839
840};// NodeMask<1>
841
842
843/// @brief Template specialization of NodeMask for Log2Dim=2, i.e. 4^3 nodes
844template<>
845 class NodeMask<2>
846{
847public:
848
849 static const Index32 LOG2DIM = 2;
850 static const Index32 DIM = 4;
851 static const Index32 SIZE = 64;
852 static const Index32 WORD_COUNT = 1;
853 using Word = Index64;
854
855private:
856
857 Word mWord;//only member data!
858
859public:
860 /// Default constructor sets all bits off
861 NodeMask() : mWord(UINT64_C(0x00)) {}
862 /// All bits are set to the specified state
863 NodeMask(bool on) : mWord(on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00)) {}
864 /// Copy constructor
865 NodeMask(const NodeMask &other) : mWord(other.mWord) {}
866 /// Destructor
867 ~NodeMask() {}
868 /// Assignment operator
869 void operator = (const NodeMask &other) { mWord = other.mWord; }
870
871 using OnIterator = OnMaskIterator<NodeMask>;
872 using OffIterator = OffMaskIterator<NodeMask>;
873 using DenseIterator = DenseMaskIterator<NodeMask>;
874
875 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
876 OnIterator endOn() const { return OnIterator(SIZE,this); }
877 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
878 OffIterator endOff() const { return OffIterator(SIZE,this); }
879 DenseIterator beginDense() const { return DenseIterator(0,this); }
880 DenseIterator endDense() const { return DenseIterator(SIZE,this); }
881
882 bool operator == (const NodeMask &other) const { return mWord == other.mWord; }
883
884 bool operator != (const NodeMask &other) const {return mWord != other.mWord; }
885
886 //
887 // Bitwise logical operations
888 //
889
890 /// @brief Apply a functor to the words of the this and the other mask.
891 ///
892 /// @details An example that implements the "operator&=" method:
893 /// @code
894 /// struct Op { inline void operator()(Word &w1, const Word& w2) const { w1 &= w2; } };
895 /// @endcode
896 template<typename WordOp>
897 const NodeMask& foreach(const NodeMask& other, const WordOp& op)
898 {
899 op(mWord, other.mWord);
900 return *this;
901 }
902 template<typename WordOp>
903 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const WordOp& op)
904 {
905 op(mWord, other1.mWord, other2.mWord);
906 return *this;
907 }
908 template<typename WordOp>
909 const NodeMask& foreach(const NodeMask& other1, const NodeMask& other2, const NodeMask& other3,
910 const WordOp& op)
911 {
912 op(mWord, other1.mWord, other2.mWord, other3.mWord);
913 return *this;
914 }
915 /// @brief Bitwise intersection
916 const NodeMask& operator&=(const NodeMask& other)
917 {
918 mWord &= other.mWord;
919 return *this;
920 }
921 /// @brief Bitwise union
922 const NodeMask& operator|=(const NodeMask& other)
923 {
924 mWord |= other.mWord;
925 return *this;
926 }
927 /// @brief Bitwise difference
928 const NodeMask& operator-=(const NodeMask& other)
929 {
930 mWord &= ~other.mWord;
931 return *this;
932 }
933 /// @brief Bitwise XOR
934 const NodeMask& operator^=(const NodeMask& other)
935 {
936 mWord ^= other.mWord;
937 return *this;
938 }
939 NodeMask operator!() const { NodeMask m(*this); m.toggle(); return m; }
940 NodeMask operator&(const NodeMask& other) const { NodeMask m(*this); m &= other; 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 /// Return the byte size of this NodeMask
944 static Index32 memUsage() { return 8; }
945 /// Return the total number of on bits
946 Index32 countOn() const { return CountOn(mWord); }
947 /// Return the total number of on bits
948 Index32 countOff() const { return CountOff(mWord); }
949 /// Set the <i>n</i>th bit on
950 void setOn(Index32 n) {
951 assert( n < 64 );
952 mWord |= UINT64_C(0x01) << (n & 63);
953 }
954 /// Set the <i>n</i>th bit off
955 void setOff(Index32 n) {
956 assert( n < 64 );
957 mWord &= ~(UINT64_C(0x01) << (n & 63));
958 }
959 /// Set the <i>n</i>th bit to the specified state
960 void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
961 /// Set all bits to the specified state
962 void set(bool on) { mWord = on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00); }
963 /// Set all bits on
964 void setOn() { mWord = UINT64_C(0xFFFFFFFFFFFFFFFF); }
965 /// Set all bits off
966 void setOff() { mWord = UINT64_C(0x00); }
967 /// Toggle the state of the <i>n</i>th bit
968 void toggle(Index32 n) {
969 assert( n < 64 );
970 mWord ^= UINT64_C(0x01) << (n & 63);
971 }
972 /// Toggle the state of all bits in the mask
973 void toggle() { mWord = ~mWord; }
974 /// Set the first bit on
975 void setFirstOn() { this->setOn(0); }
976 /// Set the last bit on
977 void setLastOn() { this->setOn(63); }
978 /// Set the first bit off
979 void setFirstOff() { this->setOff(0); }
980 /// Set the last bit off
981 void setLastOff() { this->setOff(63); }
982 /// Return true if the <i>n</i>th bit is on
983 bool isOn(Index32 n) const
984 {
985 assert( n < 64 );
986 return 0 != (mWord & (UINT64_C(0x01) << (n & 63)));
987 }
988 /// Return true if the <i>n</i>th bit is off
989 bool isOff(Index32 n) const {return !this->isOn(n); }
990 /// Return true if all the bits are on
991 bool isOn() const { return mWord == UINT64_C(0xFFFFFFFFFFFFFFFF); }
992 /// Return true if all the bits are off
993 bool isOff() const { return mWord == 0; }
994 /// Return @c true if bits are either all off OR all on.
995 /// @param isOn Takes on the values of all bits if the method
996 /// returns true - else it is undefined.
997 bool isConstant(bool &isOn) const
998 { isOn = this->isOn();
999 return isOn || this->isOff();
1000 }
1001 Index32 findFirstOn() const { return mWord ? FindLowestOn(mWord) : 64; }
1002 Index32 findFirstOff() const
1003 {
1004 const Word w = ~mWord;
1005 return w ? FindLowestOn(w) : 64;
1006 }
1007 //@{
1008 /// Return the <i>n</i>th word of the bit mask, for a word of arbitrary size.
1009 template<typename WordT>
1010 WordT getWord(Index n) const
1011 {
1012 assert(n*8*sizeof(WordT) < SIZE);
1013 return reinterpret_cast<const WordT*>(&mWord)[n];
1014 }
1015 template<typename WordT>
1016 WordT& getWord(Index n)
1017 {
1018 assert(n*8*sizeof(WordT) < SIZE);
1019 return reinterpret_cast<WordT*>(mWord)[n];
1020 }
1021 //@}
1022 void save(std::ostream& os) const { os.write(reinterpret_cast<const char*>(&mWord), 8); }
1023 void load(std::istream& is) { is.read(reinterpret_cast<char*>(&mWord), 8); }
1024 void seek(std::istream& is) const { is.seekg(8, std::ios_base::cur); }
1025 /// @brief simple print method for debugging
1026 void printInfo(std::ostream& os=std::cout) const
1027 {
1028 os << "NodeMask: Dim=4, Log2Dim=2, Bit count=64, Word count=1"<<std::endl;
1029 }
1030 void printBits(std::ostream& os=std::cout) const
1031 {
1032 os << "|";
1033 for (Index32 i=0; i < 64; ++i) {
1034 if ( !(i%8) ) os << "|";
1035 os << this->isOn(i);
1036 }
1037 os << "||" << std::endl;
1038 }
1039 void printAll(std::ostream& os=std::cout) const
1040 {
1041 this->printInfo(os);
1042 this->printBits(os);
1043 }
1044
1045 Index32 findNextOn(Index32 start) const
1046 {
1047 if (start>=64) return 64;
1048 const Word w = mWord & (UINT64_C(0xFFFFFFFFFFFFFFFF) << start);
1049 return w ? FindLowestOn(w) : 64;
1050 }
1051
1052 Index32 findNextOff(Index32 start) const
1053 {
1054 if (start>=64) return 64;
1055 const Word w = ~mWord & (UINT64_C(0xFFFFFFFFFFFFFFFF) << start);
1056 return w ? FindLowestOn(w) : 64;
1057 }
1058
1059};// NodeMask<2>
1060
1061
1062// Unlike NodeMask above this RootNodeMask has a run-time defined size.
1063// It is only included for backward compatibility and will likely be
1064// deprecated in the future!
1065// This class is 32-bit specefic, hence the use if Index32 vs Index!
1066 class RootNodeMask
1067{
1068protected:
1069 Index32 mBitSize, mIntSize;
1070 Index32 *mBits;
1071
1072public:
1073 RootNodeMask(): mBitSize(0), mIntSize(0), mBits(nullptr) {}
1074 RootNodeMask(Index32 bit_size):
1075 mBitSize(bit_size), mIntSize(((bit_size-1)>>5)+1), mBits(new Index32[mIntSize])
1076 {
1077 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=0x00000000;
1078 }
1079 RootNodeMask(const RootNodeMask& B):
1080 mBitSize(B.mBitSize), mIntSize(B.mIntSize), mBits(new Index32[mIntSize])
1081 {
1082 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=B.mBits[i];
1083 }
1084 ~RootNodeMask() {delete [] mBits;}
1085
1086 void init(Index32 bit_size) {
1087 mBitSize = bit_size;
1088 mIntSize =((bit_size-1)>>5)+1;
1089 delete [] mBits;
1090 mBits = new Index32[mIntSize];
1091 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=0x00000000;
1092 }
1093
1094 Index getBitSize() const {return mBitSize;}
1095
1096 Index getIntSize() const {return mIntSize;}
1097
1098 RootNodeMask& operator=(const RootNodeMask& B) {
1099 if (mBitSize!=B.mBitSize) {
1100 mBitSize=B.mBitSize;
1101 mIntSize=B.mIntSize;
1102 delete [] mBits;
1103 mBits = new Index32[mIntSize];
1104 }
1105 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=B.mBits[i];
1106 return *this;
1107 }
1108
1109 class BaseIterator
1110 {
1111 protected:
1112 Index32 mPos;//bit position
1113 Index32 mBitSize;
1114 const RootNodeMask* mParent;//this iterator can't change the parent_mask!
1115 public:
1116 BaseIterator() : mPos(0), mBitSize(0), mParent(nullptr) {}
1117 BaseIterator(const BaseIterator&) = default;
1118 BaseIterator(Index32 pos, const RootNodeMask* parent):
1119 mPos(pos), mBitSize(parent->getBitSize()), mParent(parent) { assert(pos <= mBitSize); }
1120 bool operator==(const BaseIterator &iter) const {return mPos == iter.mPos;}
1121 bool operator!=(const BaseIterator &iter) const {return mPos != iter.mPos;}
1122 bool operator< (const BaseIterator &iter) const {return mPos < iter.mPos;}
1123 BaseIterator& operator=(const BaseIterator& iter) {
1124 mPos = iter.mPos;
1125 mBitSize = iter.mBitSize;
1126 mParent = iter.mParent;
1127 return *this;
1128 }
1129
1130 Index32 offset() const {return mPos;}
1131
1132 Index32 pos() const {return mPos;}
1133
1134 bool test() const {
1135 assert(mPos <= mBitSize);
1136 return (mPos != mBitSize);
1137 }
1138
1139 operator bool() const {return this->test();}
1140 }; // class BaseIterator
1141
1142 /// @note This happens to be a const-iterator!
1143 class OnIterator: public BaseIterator
1144 {
1145 protected:
1146 using BaseIterator::mPos;//bit position;
1147 using BaseIterator::mBitSize;//bit size;
1148 using BaseIterator::mParent;//this iterator can't change the parent_mask!
1149 public:
1150 OnIterator() : BaseIterator() {}
1151 OnIterator(Index32 pos,const RootNodeMask *parent) : BaseIterator(pos,parent) {}
1152 void increment() {
1153 assert(mParent != nullptr);
1154 mPos=mParent->findNextOn(mPos+1);
1155 assert(mPos <= mBitSize);
1156 }
1157 void increment(Index n) {
1158 for (Index i=0; i<n && this->next(); ++i) {}
1159 }
1160 bool next() {
1161 this->increment();
1162 return this->test();
1163 }
1164 bool operator*() const {return true;}
1165 OnIterator& operator++() {
1166 this->increment();
1167 return *this;
1168 }
1169 }; // class OnIterator
1170
1171 class OffIterator: public BaseIterator
1172 {
1173 protected:
1174 using BaseIterator::mPos;//bit position;
1175 using BaseIterator::mBitSize;//bit size;
1176 using BaseIterator::mParent;//this iterator can't change the parent_mask!
1177 public:
1178 OffIterator() : BaseIterator() {}
1179 OffIterator(Index32 pos,const RootNodeMask *parent) : BaseIterator(pos,parent) {}
1180 void increment() {
1181 assert(mParent != nullptr);
1182 mPos=mParent->findNextOff(mPos+1);
1183 assert(mPos <= mBitSize);
1184 }
1185 void increment(Index n) {
1186 for (Index i=0; i<n && this->next(); ++i) {}
1187 }
1188 bool next() {
1189 this->increment();
1190 return this->test();
1191 }
1192 bool operator*() const {return true;}
1193 OffIterator& operator++() {
1194 this->increment();
1195 return *this;
1196 }
1197 }; // class OffIterator
1198
1199 class DenseIterator: public BaseIterator
1200 {
1201 protected:
1202 using BaseIterator::mPos;//bit position;
1203 using BaseIterator::mBitSize;//bit size;
1204 using BaseIterator::mParent;//this iterator can't change the parent_mask!
1205 public:
1206 DenseIterator() : BaseIterator() {}
1207 DenseIterator(Index32 pos,const RootNodeMask *parent) : BaseIterator(pos,parent) {}
1208 void increment() {
1209 assert(mParent != nullptr);
1210 mPos += 1;//carefull - the increament might go beyond the end
1211 assert(mPos<= mBitSize);
1212 }
1213 void increment(Index n) {
1214 for (Index i=0; i<n && this->next(); ++i) {}
1215 }
1216 bool next() {
1217 this->increment();
1218 return this->test();
1219 }
1220 bool operator*() const {return mParent->isOn(mPos);}
1221 DenseIterator& operator++() {
1222 this->increment();
1223 return *this;
1224 }
1225 }; // class DenseIterator
1226
1227 OnIterator beginOn() const { return OnIterator(this->findFirstOn(),this); }
1228 OnIterator endOn() const { return OnIterator(mBitSize,this); }
1229 OffIterator beginOff() const { return OffIterator(this->findFirstOff(),this); }
1230 OffIterator endOff() const { return OffIterator(mBitSize,this); }
1231 DenseIterator beginDense() const { return DenseIterator(0,this); }
1232 DenseIterator endDense() const { return DenseIterator(mBitSize,this); }
1233
1234 bool operator == (const RootNodeMask &B) const {
1235 if (mBitSize != B.mBitSize) return false;
1236 for (Index32 i=0; i<mIntSize; ++i) if (mBits[i] != B.mBits[i]) return false;
1237 return true;
1238 }
1239
1240 bool operator != (const RootNodeMask &B) const {
1241 if (mBitSize != B.mBitSize) return true;
1242 for (Index32 i=0; i<mIntSize; ++i) if (mBits[i] != B.mBits[i]) return true;
1243 return false;
1244 }
1245
1246 //
1247 // Bitwise logical operations
1248 //
1249 RootNodeMask operator!() const { RootNodeMask m = *this; m.toggle(); return m; }
1250 const RootNodeMask& operator&=(const RootNodeMask& other) {
1251 assert(mIntSize == other.mIntSize);
1252 for (Index32 i = 0, N = std::min(mIntSize, other.mIntSize); i < N; ++i) {
1253 mBits[i] &= other.mBits[i];
1254 }
1255 for (Index32 i = other.mIntSize; i < mIntSize; ++i) mBits[i] = 0x00000000;
1256 return *this;
1257 }
1258 const RootNodeMask& operator|=(const RootNodeMask& other) {
1259 assert(mIntSize == other.mIntSize);
1260 for (Index32 i = 0, N = std::min(mIntSize, other.mIntSize); i < N; ++i) {
1261 mBits[i] |= other.mBits[i];
1262 }
1263 return *this;
1264 }
1265 const RootNodeMask& operator^=(const RootNodeMask& other) {
1266 assert(mIntSize == other.mIntSize);
1267 for (Index32 i = 0, N = std::min(mIntSize, other.mIntSize); i < N; ++i) {
1268 mBits[i] ^= other.mBits[i];
1269 }
1270 return *this;
1271 }
1272 RootNodeMask operator&(const RootNodeMask& other) const {
1273 RootNodeMask m(*this); m &= other; return m;
1274 }
1275 RootNodeMask operator|(const RootNodeMask& other) const {
1276 RootNodeMask m(*this); m |= other; return m;
1277 }
1278 RootNodeMask operator^(const RootNodeMask& other) const {
1279 RootNodeMask m(*this); m ^= other; return m;
1280 }
1281
1282
1283 Index32 getMemUsage() const {
1284 return static_cast<Index32>(mIntSize*sizeof(Index32) + sizeof(*this));
1285 }
1286
1287 Index32 countOn() const {
1288 assert(mBits);
1289 Index32 n=0;
1290 for (Index32 i=0; i< mIntSize; ++i) n += CountOn(mBits[i]);
1291 return n;
1292 }
1293
1294 Index32 countOff() const { return mBitSize-this->countOn(); }
1295
1296 void setOn(Index32 i) {
1297 assert(mBits);
1298 assert( (i>>5) < mIntSize);
1299 mBits[i>>5] |= 1<<(i&31);
1300 }
1301
1302 void setOff(Index32 i) {
1303 assert(mBits);
1304 assert( (i>>5) < mIntSize);
1305 mBits[i>>5] &= ~(1<<(i&31));
1306 }
1307
1308 void set(Index32 i, bool On) { On ? this->setOn(i) : this->setOff(i); }
1309
1310 void setOn() {
1311 assert(mBits);
1312 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=0xFFFFFFFF;
1313 }
1314 void setOff() {
1315 assert(mBits);
1316 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=0x00000000;
1317 }
1318 void toggle(Index32 i) {
1319 assert(mBits);
1320 assert( (i>>5) < mIntSize);
1321 mBits[i>>5] ^= 1<<(i&31);
1322 }
1323 void toggle() {
1324 assert(mBits);
1325 for (Index32 i=0; i<mIntSize; ++i) mBits[i]=~mBits[i];
1326 }
1327 void setFirstOn() { this->setOn(0); }
1328 void setLastOn() { this->setOn(mBitSize-1); }
1329 void setFirstOff() { this->setOff(0); }
1330 void setLastOff() { this->setOff(mBitSize-1); }
1331 bool isOn(Index32 i) const {
1332 assert(mBits);
1333 assert( (i>>5) < mIntSize);
1334 return ( mBits[i >> 5] & (1<<(i&31)) );
1335 }
1336 bool isOff(Index32 i) const {
1337 assert(mBits);
1338 assert( (i>>5) < mIntSize);
1339 return ( ~mBits[i >> 5] & (1<<(i&31)) );
1340 }
1341
1342 bool isOn() const {
1343 if (!mBits) return false;//undefined is off
1344 for (Index32 i=0; i<mIntSize; ++i) if (mBits[i] != 0xFFFFFFFF) return false;
1345 return true;
1346 }
1347
1348 bool isOff() const {
1349 if (!mBits) return true;//undefined is off
1350 for (Index32 i=0; i<mIntSize; ++i) if (mBits[i] != 0) return false;
1351 return true;
1352 }
1353
1354 Index32 findFirstOn() const {
1355 assert(mBits);
1356 Index32 i=0;
1357 while(!mBits[i]) if (++i == mIntSize) return mBitSize;//reached end
1358 return 32*i + FindLowestOn(mBits[i]);
1359 }
1360
1361 Index32 findFirstOff() const {
1362 assert(mBits);
1363 Index32 i=0;
1364 while(!(~mBits[i])) if (++i == mIntSize) return mBitSize;//reached end
1365 return 32*i + FindLowestOn(~mBits[i]);
1366 }
1367
1368 void save(std::ostream& os) const {
1369 assert(mBits);
1370 os.write(reinterpret_cast<const char*>(mBits), mIntSize * sizeof(Index32));
1371 }
1372 void load(std::istream& is) {
1373 assert(mBits);
1374 is.read(reinterpret_cast<char*>(mBits), mIntSize * sizeof(Index32));
1375 }
1376 void seek(std::istream& is) const {
1377 assert(mBits);
1378 is.seekg(mIntSize * sizeof(Index32), std::ios_base::cur);
1379 }
1380 /// @brief simple print method for debugging
1381 void printInfo(std::ostream& os=std::cout) const {
1382 os << "RootNodeMask: Bit-size="<<mBitSize<<" Int-size="<<mIntSize<<std::endl;
1383 }
1384
1385 void printBits(std::ostream& os=std::cout, Index32 max_out=80u) const {
1386 const Index32 n=(mBitSize>max_out?max_out:mBitSize);
1387 for (Index32 i=0; i < n; ++i) {
1388 if ( !(i&31) )
1389 os << "||";
1390 else if ( !(i%8) )
1391 os << "|";
1392 os << this->isOn(i);
1393 }
1394 os << "|" << std::endl;
1395 }
1396
1397 void printAll(std::ostream& os=std::cout, Index32 max_out=80u) const {
1398 this->printInfo(os);
1399 this->printBits(os,max_out);
1400 }
1401
1402 Index32 findNextOn(Index32 start) const {
1403 assert(mBits);
1404 Index32 n = start >> 5, m = start & 31;//initiate
1405 if (n>=mIntSize) return mBitSize; // check for out of bounds
1406 Index32 b = mBits[n];
1407 if (b & (1<<m)) return start;//simple case
1408 b &= 0xFFFFFFFF << m;// mask lower bits
1409 while(!b && ++n<mIntSize) b = mBits[n];// find next nonzero int
1410 return (!b ? mBitSize : 32*n + FindLowestOn(b));//catch last-int=0
1411 }
1412
1413 Index32 findNextOff(Index32 start) const {
1414 assert(mBits);
1415 Index32 n = start >> 5, m = start & 31;//initiate
1416 if (n>=mIntSize) return mBitSize; // check for out of bounds
1417 Index32 b = ~mBits[n];
1418 if (b & (1<<m)) return start;//simple case
1419 b &= 0xFFFFFFFF<<m;// mask lower bits
1420 while(!b && ++n<mIntSize) b = ~mBits[n];// find next nonzero int
1421 return (!b ? mBitSize : 32*n + FindLowestOn(b));//catch last-int=0
1422 }
1423
1424 Index32 memUsage() const {
1425 assert(mBits);
1426 return static_cast<Index32>(sizeof(Index32*)+(2+mIntSize)*sizeof(Index32));//in bytes
1427 }
1428}; // class RootNodeMask
1429
1430} // namespace util
1431} // namespace OPENVDB_VERSION_NAME
1432} // namespace openvdb
1433
1434#endif // OPENVDB_UTIL_NODEMASKS_HAS_BEEN_INCLUDED
COUNTONB6
#define COUNTONB6(n)
Platform.h
openvdb::v10_0::util::BaseMaskIterator
Base class for the bit mask iterators.
Definition: NodeMasks.h:180
openvdb::v10_0::util::BaseMaskIterator::operator==
bool operator==(const BaseMaskIterator &iter) const
Definition: NodeMasks.h:192
openvdb::v10_0::util::BaseMaskIterator::test
bool test() const
Definition: NodeMasks.h:201
openvdb::v10_0::util::BaseMaskIterator::BaseMaskIterator
BaseMaskIterator(const BaseMaskIterator &)=default
openvdb::v10_0::util::BaseMaskIterator::operator!=
bool operator!=(const BaseMaskIterator &iter) const
Definition: NodeMasks.h:193
openvdb::v10_0::util::BaseMaskIterator::BaseMaskIterator
BaseMaskIterator()
Definition: NodeMasks.h:186
openvdb::v10_0::util::BaseMaskIterator::mPos
Index32 mPos
Definition: NodeMasks.h:182
openvdb::v10_0::util::BaseMaskIterator::pos
Index32 pos() const
Definition: NodeMasks.h:200
openvdb::v10_0::util::BaseMaskIterator::BaseMaskIterator
BaseMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:188
openvdb::v10_0::util::BaseMaskIterator::offset
Index32 offset() const
Definition: NodeMasks.h:199
openvdb::v10_0::util::BaseMaskIterator::mParent
const NodeMask * mParent
Definition: NodeMasks.h:183
openvdb::v10_0::util::BaseMaskIterator::operator=
BaseMaskIterator & operator=(const BaseMaskIterator &iter)
Definition: NodeMasks.h:195
openvdb::v10_0::util::DenseMaskIterator
Definition: NodeMasks.h:271
openvdb::v10_0::util::DenseMaskIterator::operator++
DenseMaskIterator & operator++()
Definition: NodeMasks.h:293
openvdb::v10_0::util::DenseMaskIterator::operator*
bool operator*() const
Definition: NodeMasks.h:292
openvdb::v10_0::util::DenseMaskIterator::DenseMaskIterator
DenseMaskIterator()
Definition: NodeMasks.h:278
openvdb::v10_0::util::DenseMaskIterator::DenseMaskIterator
DenseMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:279
openvdb::v10_0::util::DenseMaskIterator::next
bool next()
Definition: NodeMasks.h:287
openvdb::v10_0::util::DenseMaskIterator::increment
void increment(Index n)
Definition: NodeMasks.h:286
openvdb::v10_0::util::DenseMaskIterator::increment
void increment()
Definition: NodeMasks.h:280
openvdb::v10_0::util::NodeMask< 1 >::operator^=
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:712
openvdb::v10_0::util::NodeMask< 1 >::isOff
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:767
openvdb::v10_0::util::NodeMask< 1 >::operator|
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:719
openvdb::v10_0::util::NodeMask< 1 >::operator&=
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:694
openvdb::v10_0::util::NodeMask< 1 >::countOn
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:724
openvdb::v10_0::util::NodeMask< 1 >::operator-=
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:706
openvdb::v10_0::util::NodeMask< 1 >::printAll
void printAll(std::ostream &os=std::cout) const
Definition: NodeMasks.h:820
openvdb::v10_0::util::NodeMask< 1 >::beginOn
OnIterator beginOn() const
Definition: NodeMasks.h:653
openvdb::v10_0::util::NodeMask< 1 >::operator^
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:720
openvdb::v10_0::util::NodeMask< 1 >::endDense
DenseIterator endDense() const
Definition: NodeMasks.h:658
openvdb::v10_0::util::NodeMask< 1 >::beginDense
DenseIterator beginDense() const
Definition: NodeMasks.h:657
openvdb::v10_0::util::NodeMask< 1 >::beginOff
OffIterator beginOff() const
Definition: NodeMasks.h:655
openvdb::v10_0::util::NodeMask< 1 >::set
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:738
openvdb::v10_0::util::NodeMask< 1 >::setOn
void setOn()
Set all bits on.
Definition: NodeMasks.h:742
openvdb::v10_0::util::NodeMask< 1 >::isOn
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:761
openvdb::v10_0::util::NodeMask< 1 >::printBits
void printBits(std::ostream &os=std::cout) const
Definition: NodeMasks.h:814
openvdb::v10_0::util::NodeMask< 1 >::isConstant
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:775
openvdb::v10_0::util::NodeMask< 1 >::countOff
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:726
openvdb::v10_0::util::NodeMask< 1 >::toggle
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:746
openvdb::v10_0::util::NodeMask< 1 >::setLastOff
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:759
openvdb::v10_0::util::NodeMask< 1 >::NodeMask
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:641
openvdb::v10_0::util::NodeMask< 1 >::findNextOff
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:833
openvdb::v10_0::util::NodeMask< 1 >::seek
void seek(std::istream &is) const
Definition: NodeMasks.h:808
openvdb::v10_0::util::NodeMask< 1 >::setFirstOff
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:757
openvdb::v10_0::util::NodeMask< 1 >::set
void set(bool on)
Set all bits to the specified state.
Definition: NodeMasks.h:740
openvdb::v10_0::util::NodeMask< 1 >::operator!
NodeMask operator!() const
Definition: NodeMasks.h:717
openvdb::v10_0::util::NodeMask< 1 >::setFirstOn
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:753
openvdb::v10_0::util::NodeMask< 1 >::endOn
OnIterator endOn() const
Definition: NodeMasks.h:654
openvdb::v10_0::util::NodeMask< 1 >::load
void load(std::istream &is)
Definition: NodeMasks.h:807
openvdb::v10_0::util::NodeMask< 1 >::operator|=
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:700
openvdb::v10_0::util::NodeMask< 1 >::save
void save(std::ostream &os) const
Definition: NodeMasks.h:806
openvdb::v10_0::util::NodeMask< 1 >::findFirstOff
Index32 findFirstOff() const
Definition: NodeMasks.h:781
openvdb::v10_0::util::NodeMask< 1 >::memUsage
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:722
openvdb::v10_0::util::NodeMask< 1 >::setOff
void setOff()
Set all bits off.
Definition: NodeMasks.h:744
openvdb::v10_0::util::NodeMask< 1 >::setOff
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:733
openvdb::v10_0::util::NodeMask< 1 >::setOn
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:728
openvdb::v10_0::util::NodeMask< 1 >::operator&
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:718
openvdb::v10_0::util::NodeMask< 1 >::isOff
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:771
openvdb::v10_0::util::NodeMask< 1 >::NodeMask
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:639
openvdb::v10_0::util::NodeMask< 1 >::NodeMask
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:643
openvdb::v10_0::util::NodeMask< 1 >::Word
Byte Word
Definition: NodeMasks.h:631
openvdb::v10_0::util::NodeMask< 1 >::toggle
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:751
openvdb::v10_0::util::NodeMask< 1 >::printInfo
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:810
openvdb::v10_0::util::NodeMask< 1 >::findNextOn
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:826
openvdb::v10_0::util::NodeMask< 1 >::setLastOn
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:755
openvdb::v10_0::util::NodeMask< 1 >::~NodeMask
~NodeMask()
Destructor.
Definition: NodeMasks.h:645
openvdb::v10_0::util::NodeMask< 1 >::endOff
OffIterator endOff() const
Definition: NodeMasks.h:656
openvdb::v10_0::util::NodeMask< 1 >::isOn
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:769
openvdb::v10_0::util::NodeMask< 1 >::findFirstOn
Index32 findFirstOn() const
Definition: NodeMasks.h:780
openvdb::v10_0::util::NodeMask< 2 >::operator^=
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:934
openvdb::v10_0::util::NodeMask< 2 >::isOff
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:989
openvdb::v10_0::util::NodeMask< 2 >::operator|
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:941
openvdb::v10_0::util::NodeMask< 2 >::operator&=
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:916
openvdb::v10_0::util::NodeMask< 2 >::countOn
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:946
openvdb::v10_0::util::NodeMask< 2 >::operator-=
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:928
openvdb::v10_0::util::NodeMask< 2 >::Word
Index64 Word
Definition: NodeMasks.h:853
openvdb::v10_0::util::NodeMask< 2 >::printAll
void printAll(std::ostream &os=std::cout) const
Definition: NodeMasks.h:1039
openvdb::v10_0::util::NodeMask< 2 >::beginOn
OnIterator beginOn() const
Definition: NodeMasks.h:875
openvdb::v10_0::util::NodeMask< 2 >::getWord
WordT & getWord(Index n)
Definition: NodeMasks.h:1016
openvdb::v10_0::util::NodeMask< 2 >::operator^
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:942
openvdb::v10_0::util::NodeMask< 2 >::endDense
DenseIterator endDense() const
Definition: NodeMasks.h:880
openvdb::v10_0::util::NodeMask< 2 >::beginDense
DenseIterator beginDense() const
Definition: NodeMasks.h:879
openvdb::v10_0::util::NodeMask< 2 >::beginOff
OffIterator beginOff() const
Definition: NodeMasks.h:877
openvdb::v10_0::util::NodeMask< 2 >::set
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:960
openvdb::v10_0::util::NodeMask< 2 >::setOn
void setOn()
Set all bits on.
Definition: NodeMasks.h:964
openvdb::v10_0::util::NodeMask< 2 >::isOn
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:983
openvdb::v10_0::util::NodeMask< 2 >::printBits
void printBits(std::ostream &os=std::cout) const
Definition: NodeMasks.h:1030
openvdb::v10_0::util::NodeMask< 2 >::isConstant
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:997
openvdb::v10_0::util::NodeMask< 2 >::countOff
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:948
openvdb::v10_0::util::NodeMask< 2 >::toggle
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:968
openvdb::v10_0::util::NodeMask< 2 >::setLastOff
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:981
openvdb::v10_0::util::NodeMask< 2 >::NodeMask
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:863
openvdb::v10_0::util::NodeMask< 2 >::getWord
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:1010
openvdb::v10_0::util::NodeMask< 2 >::findNextOff
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:1052
openvdb::v10_0::util::NodeMask< 2 >::seek
void seek(std::istream &is) const
Definition: NodeMasks.h:1024
openvdb::v10_0::util::NodeMask< 2 >::setFirstOff
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:979
openvdb::v10_0::util::NodeMask< 2 >::set
void set(bool on)
Set all bits to the specified state.
Definition: NodeMasks.h:962
openvdb::v10_0::util::NodeMask< 2 >::operator!
NodeMask operator!() const
Definition: NodeMasks.h:939
openvdb::v10_0::util::NodeMask< 2 >::setFirstOn
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:975
openvdb::v10_0::util::NodeMask< 2 >::endOn
OnIterator endOn() const
Definition: NodeMasks.h:876
openvdb::v10_0::util::NodeMask< 2 >::load
void load(std::istream &is)
Definition: NodeMasks.h:1023
openvdb::v10_0::util::NodeMask< 2 >::operator|=
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:922
openvdb::v10_0::util::NodeMask< 2 >::save
void save(std::ostream &os) const
Definition: NodeMasks.h:1022
openvdb::v10_0::util::NodeMask< 2 >::findFirstOff
Index32 findFirstOff() const
Definition: NodeMasks.h:1002
openvdb::v10_0::util::NodeMask< 2 >::memUsage
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:944
openvdb::v10_0::util::NodeMask< 2 >::setOff
void setOff()
Set all bits off.
Definition: NodeMasks.h:966
openvdb::v10_0::util::NodeMask< 2 >::setOff
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:955
openvdb::v10_0::util::NodeMask< 2 >::setOn
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:950
openvdb::v10_0::util::NodeMask< 2 >::operator&
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:940
openvdb::v10_0::util::NodeMask< 2 >::isOff
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:993
openvdb::v10_0::util::NodeMask< 2 >::NodeMask
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:861
openvdb::v10_0::util::NodeMask< 2 >::NodeMask
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:865
openvdb::v10_0::util::NodeMask< 2 >::toggle
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:973
openvdb::v10_0::util::NodeMask< 2 >::printInfo
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:1026
openvdb::v10_0::util::NodeMask< 2 >::findNextOn
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:1045
openvdb::v10_0::util::NodeMask< 2 >::setLastOn
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:977
openvdb::v10_0::util::NodeMask< 2 >::~NodeMask
~NodeMask()
Destructor.
Definition: NodeMasks.h:867
openvdb::v10_0::util::NodeMask< 2 >::endOff
OffIterator endOff() const
Definition: NodeMasks.h:878
openvdb::v10_0::util::NodeMask< 2 >::isOn
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:991
openvdb::v10_0::util::NodeMask< 2 >::findFirstOn
Index32 findFirstOn() const
Definition: NodeMasks.h:1001
openvdb::v10_0::util::NodeMask
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation.
Definition: NodeMasks.h:308
openvdb::v10_0::util::NodeMask::operator^=
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:428
openvdb::v10_0::util::NodeMask::isOff
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:508
openvdb::v10_0::util::NodeMask::operator|
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:437
openvdb::v10_0::util::NodeMask::operator&=
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:404
openvdb::v10_0::util::NodeMask::countOn
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:443
openvdb::v10_0::util::NodeMask::operator-=
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:420
openvdb::v10_0::util::NodeMask::Word
Index64 Word
Definition: NodeMasks.h:316
openvdb::v10_0::util::NodeMask::beginOn
OnIterator beginOn() const
Definition: NodeMasks.h:352
openvdb::v10_0::util::NodeMask::getWord
WordT & getWord(Index n)
Definition: NodeMasks.h:558
openvdb::v10_0::util::NodeMask::operator^
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:438
openvdb::v10_0::util::NodeMask::endDense
DenseIterator endDense() const
Definition: NodeMasks.h:357
openvdb::v10_0::util::NodeMask::beginDense
DenseIterator beginDense() const
Definition: NodeMasks.h:356
openvdb::v10_0::util::NodeMask::beginOff
OffIterator beginOff() const
Definition: NodeMasks.h:354
openvdb::v10_0::util::NodeMask::set
void set(Index32 n, bool On)
Set the nth bit to the specified state.
Definition: NodeMasks.h:462
openvdb::v10_0::util::NodeMask::setOn
void setOn()
Set all bits on.
Definition: NodeMasks.h:471
openvdb::v10_0::util::NodeMask::isOn
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:502
openvdb::v10_0::util::NodeMask::isConstant
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:526
openvdb::v10_0::util::NodeMask::countOff
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:450
openvdb::v10_0::util::NodeMask::toggle
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
openvdb::v10_0::util::NodeMask::setLastOff
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:500
openvdb::v10_0::util::NodeMask::NodeMask
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:334
openvdb::v10_0::util::NodeMask::getWord
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:552
openvdb::v10_0::util::NodeMask::findNextOff
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:607
openvdb::v10_0::util::NodeMask::seek
void seek(std::istream &is) const
Definition: NodeMasks.h:570
openvdb::v10_0::util::NodeMask::setFirstOff
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:498
openvdb::v10_0::util::NodeMask::set
void set(bool on)
Set all bits to the specified state.
Definition: NodeMasks.h:464
openvdb::v10_0::util::NodeMask::operator!
NodeMask operator!() const
Definition: NodeMasks.h:435
openvdb::v10_0::util::NodeMask::setFirstOn
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:494
openvdb::v10_0::util::NodeMask::endOn
OnIterator endOn() const
Definition: NodeMasks.h:353
openvdb::v10_0::util::NodeMask::load
void load(std::istream &is)
Definition: NodeMasks.h:569
openvdb::v10_0::util::NodeMask::operator|=
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:412
openvdb::v10_0::util::NodeMask::save
void save(std::ostream &os) const
Definition: NodeMasks.h:565
openvdb::v10_0::util::NodeMask::findFirstOff
Index32 findFirstOff() const
Definition: NodeMasks.h:541
openvdb::v10_0::util::NodeMask::printBits
void printBits(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:577
openvdb::v10_0::util::NodeMask::memUsage
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:441
openvdb::v10_0::util::NodeMask::setOff
void setOff()
Set all bits off.
Definition: NodeMasks.h:477
openvdb::v10_0::util::NodeMask::setOff
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
openvdb::v10_0::util::NodeMask::setOn
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
openvdb::v10_0::util::NodeMask::operator&
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:436
openvdb::v10_0::util::NodeMask::isOff
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:517
openvdb::v10_0::util::NodeMask::operator=
NodeMask & operator=(const NodeMask &other)
Assignment operator.
Definition: NodeMasks.h:340
openvdb::v10_0::util::NodeMask::NodeMask
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:332
openvdb::v10_0::util::NodeMask::NodeMask
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:336
openvdb::v10_0::util::NodeMask::toggle
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:488
openvdb::v10_0::util::NodeMask::printAll
void printAll(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:589
openvdb::v10_0::util::NodeMask::printInfo
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:572
openvdb::v10_0::util::NodeMask::findNextOn
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:595
openvdb::v10_0::util::NodeMask::setLastOn
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:496
openvdb::v10_0::util::NodeMask::~NodeMask
~NodeMask()
Destructor.
Definition: NodeMasks.h:338
openvdb::v10_0::util::NodeMask::endOff
OffIterator endOff() const
Definition: NodeMasks.h:355
openvdb::v10_0::util::NodeMask::isOn
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:510
openvdb::v10_0::util::NodeMask::findFirstOn
Index32 findFirstOn() const
Definition: NodeMasks.h:534
openvdb::v10_0::util::OffMaskIterator
Definition: NodeMasks.h:240
openvdb::v10_0::util::OffMaskIterator::operator*
bool operator*() const
Definition: NodeMasks.h:260
openvdb::v10_0::util::OffMaskIterator::OffMaskIterator
OffMaskIterator()
Definition: NodeMasks.h:246
openvdb::v10_0::util::OffMaskIterator::OffMaskIterator
OffMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:247
openvdb::v10_0::util::OffMaskIterator::next
bool next()
Definition: NodeMasks.h:255
openvdb::v10_0::util::OffMaskIterator::operator++
OffMaskIterator & operator++()
Definition: NodeMasks.h:261
openvdb::v10_0::util::OffMaskIterator::increment
void increment(Index n)
Definition: NodeMasks.h:254
openvdb::v10_0::util::OffMaskIterator::increment
void increment()
Definition: NodeMasks.h:248
openvdb::v10_0::util::OnMaskIterator
Definition: NodeMasks.h:209
openvdb::v10_0::util::OnMaskIterator::operator*
bool operator*() const
Definition: NodeMasks.h:229
openvdb::v10_0::util::OnMaskIterator::operator++
OnMaskIterator & operator++()
Definition: NodeMasks.h:230
openvdb::v10_0::util::OnMaskIterator::next
bool next()
Definition: NodeMasks.h:224
openvdb::v10_0::util::OnMaskIterator::OnMaskIterator
OnMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:216
openvdb::v10_0::util::OnMaskIterator::OnMaskIterator
OnMaskIterator()
Definition: NodeMasks.h:215
openvdb::v10_0::util::OnMaskIterator::increment
void increment(Index n)
Definition: NodeMasks.h:223
openvdb::v10_0::util::OnMaskIterator::increment
void increment()
Definition: NodeMasks.h:217
openvdb::v10_0::util::RootNodeMask::BaseIterator
Definition: NodeMasks.h:1110
openvdb::v10_0::util::RootNodeMask::BaseIterator::mParent
const RootNodeMask * mParent
Definition: NodeMasks.h:1114
openvdb::v10_0::util::RootNodeMask::BaseIterator::test
bool test() const
Definition: NodeMasks.h:1134
openvdb::v10_0::util::RootNodeMask::BaseIterator::mBitSize
Index32 mBitSize
Definition: NodeMasks.h:1113
openvdb::v10_0::util::RootNodeMask::BaseIterator::operator==
bool operator==(const BaseIterator &iter) const
Definition: NodeMasks.h:1120
openvdb::v10_0::util::RootNodeMask::BaseIterator::BaseIterator
BaseIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1118
openvdb::v10_0::util::RootNodeMask::BaseIterator::BaseIterator
BaseIterator()
Definition: NodeMasks.h:1116
openvdb::v10_0::util::RootNodeMask::BaseIterator::mPos
Index32 mPos
Definition: NodeMasks.h:1112
openvdb::v10_0::util::RootNodeMask::BaseIterator::pos
Index32 pos() const
Definition: NodeMasks.h:1132
openvdb::v10_0::util::RootNodeMask::BaseIterator::operator=
BaseIterator & operator=(const BaseIterator &iter)
Definition: NodeMasks.h:1123
openvdb::v10_0::util::RootNodeMask::BaseIterator::offset
Index32 offset() const
Definition: NodeMasks.h:1130
openvdb::v10_0::util::RootNodeMask::BaseIterator::operator!=
bool operator!=(const BaseIterator &iter) const
Definition: NodeMasks.h:1121
openvdb::v10_0::util::RootNodeMask::BaseIterator::BaseIterator
BaseIterator(const BaseIterator &)=default
openvdb::v10_0::util::RootNodeMask::DenseIterator
Definition: NodeMasks.h:1200
openvdb::v10_0::util::RootNodeMask::DenseIterator::DenseIterator
DenseIterator()
Definition: NodeMasks.h:1206
openvdb::v10_0::util::RootNodeMask::DenseIterator::operator++
DenseIterator & operator++()
Definition: NodeMasks.h:1221
openvdb::v10_0::util::RootNodeMask::DenseIterator::DenseIterator
DenseIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1207
openvdb::v10_0::util::RootNodeMask::DenseIterator::operator*
bool operator*() const
Definition: NodeMasks.h:1220
openvdb::v10_0::util::RootNodeMask::DenseIterator::next
bool next()
Definition: NodeMasks.h:1216
openvdb::v10_0::util::RootNodeMask::DenseIterator::increment
void increment(Index n)
Definition: NodeMasks.h:1213
openvdb::v10_0::util::RootNodeMask::DenseIterator::increment
void increment()
Definition: NodeMasks.h:1208
openvdb::v10_0::util::RootNodeMask::OffIterator
Definition: NodeMasks.h:1172
openvdb::v10_0::util::RootNodeMask::OffIterator::operator*
bool operator*() const
Definition: NodeMasks.h:1192
openvdb::v10_0::util::RootNodeMask::OffIterator::OffIterator
OffIterator()
Definition: NodeMasks.h:1178
openvdb::v10_0::util::RootNodeMask::OffIterator::OffIterator
OffIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1179
openvdb::v10_0::util::RootNodeMask::OffIterator::operator++
OffIterator & operator++()
Definition: NodeMasks.h:1193
openvdb::v10_0::util::RootNodeMask::OffIterator::next
bool next()
Definition: NodeMasks.h:1188
openvdb::v10_0::util::RootNodeMask::OffIterator::increment
void increment(Index n)
Definition: NodeMasks.h:1185
openvdb::v10_0::util::RootNodeMask::OffIterator::increment
void increment()
Definition: NodeMasks.h:1180
openvdb::v10_0::util::RootNodeMask::OnIterator
Definition: NodeMasks.h:1144
openvdb::v10_0::util::RootNodeMask::OnIterator::OnIterator
OnIterator()
Definition: NodeMasks.h:1150
openvdb::v10_0::util::RootNodeMask::OnIterator::operator*
bool operator*() const
Definition: NodeMasks.h:1164
openvdb::v10_0::util::RootNodeMask::OnIterator::next
bool next()
Definition: NodeMasks.h:1160
openvdb::v10_0::util::RootNodeMask::OnIterator::OnIterator
OnIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1151
openvdb::v10_0::util::RootNodeMask::OnIterator::operator++
OnIterator & operator++()
Definition: NodeMasks.h:1165
openvdb::v10_0::util::RootNodeMask::OnIterator::increment
void increment(Index n)
Definition: NodeMasks.h:1157
openvdb::v10_0::util::RootNodeMask::OnIterator::increment
void increment()
Definition: NodeMasks.h:1152
openvdb::v10_0::util::RootNodeMask
Definition: NodeMasks.h:1067
openvdb::v10_0::util::RootNodeMask::mBits
Index32 * mBits
Definition: NodeMasks.h:1070
openvdb::v10_0::util::RootNodeMask::~RootNodeMask
~RootNodeMask()
Definition: NodeMasks.h:1084
openvdb::v10_0::util::RootNodeMask::RootNodeMask
RootNodeMask()
Definition: NodeMasks.h:1073
openvdb::v10_0::util::RootNodeMask::countOn
Index32 countOn() const
Definition: NodeMasks.h:1287
openvdb::v10_0::util::RootNodeMask::getBitSize
Index getBitSize() const
Definition: NodeMasks.h:1094
openvdb::v10_0::util::RootNodeMask::beginOn
OnIterator beginOn() const
Definition: NodeMasks.h:1227
openvdb::v10_0::util::RootNodeMask::operator&=
const RootNodeMask & operator&=(const RootNodeMask &other)
Definition: NodeMasks.h:1250
openvdb::v10_0::util::RootNodeMask::operator&
RootNodeMask operator&(const RootNodeMask &other) const
Definition: NodeMasks.h:1272
openvdb::v10_0::util::RootNodeMask::set
void set(Index32 i, bool On)
Definition: NodeMasks.h:1308
openvdb::v10_0::util::RootNodeMask::endDense
DenseIterator endDense() const
Definition: NodeMasks.h:1232
openvdb::v10_0::util::RootNodeMask::operator|
RootNodeMask operator|(const RootNodeMask &other) const
Definition: NodeMasks.h:1275
openvdb::v10_0::util::RootNodeMask::beginDense
DenseIterator beginDense() const
Definition: NodeMasks.h:1231
openvdb::v10_0::util::RootNodeMask::beginOff
OffIterator beginOff() const
Definition: NodeMasks.h:1229
openvdb::v10_0::util::RootNodeMask::setOn
void setOn()
Definition: NodeMasks.h:1310
openvdb::v10_0::util::RootNodeMask::isOff
bool isOff(Index32 i) const
Definition: NodeMasks.h:1336
openvdb::v10_0::util::RootNodeMask::countOff
Index32 countOff() const
Definition: NodeMasks.h:1294
openvdb::v10_0::util::RootNodeMask::setLastOff
void setLastOff()
Definition: NodeMasks.h:1330
openvdb::v10_0::util::RootNodeMask::RootNodeMask
RootNodeMask(const RootNodeMask &B)
Definition: NodeMasks.h:1079
openvdb::v10_0::util::RootNodeMask::mBitSize
Index32 mBitSize
Definition: NodeMasks.h:1069
openvdb::v10_0::util::RootNodeMask::findNextOff
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:1413
openvdb::v10_0::util::RootNodeMask::setOff
void setOff(Index32 i)
Definition: NodeMasks.h:1302
openvdb::v10_0::util::RootNodeMask::seek
void seek(std::istream &is) const
Definition: NodeMasks.h:1376
openvdb::v10_0::util::RootNodeMask::setOn
void setOn(Index32 i)
Definition: NodeMasks.h:1296
openvdb::v10_0::util::RootNodeMask::mIntSize
Index32 mIntSize
Definition: NodeMasks.h:1069
openvdb::v10_0::util::RootNodeMask::setFirstOff
void setFirstOff()
Definition: NodeMasks.h:1329
openvdb::v10_0::util::RootNodeMask::isOn
bool isOn(Index32 i) const
Definition: NodeMasks.h:1331
openvdb::v10_0::util::RootNodeMask::getIntSize
Index getIntSize() const
Definition: NodeMasks.h:1096
openvdb::v10_0::util::RootNodeMask::setFirstOn
void setFirstOn()
Definition: NodeMasks.h:1327
openvdb::v10_0::util::RootNodeMask::endOn
OnIterator endOn() const
Definition: NodeMasks.h:1228
openvdb::v10_0::util::RootNodeMask::load
void load(std::istream &is)
Definition: NodeMasks.h:1372
openvdb::v10_0::util::RootNodeMask::operator!
RootNodeMask operator!() const
Definition: NodeMasks.h:1249
openvdb::v10_0::util::RootNodeMask::save
void save(std::ostream &os) const
Definition: NodeMasks.h:1368
openvdb::v10_0::util::RootNodeMask::findFirstOff
Index32 findFirstOff() const
Definition: NodeMasks.h:1361
openvdb::v10_0::util::RootNodeMask::operator^=
const RootNodeMask & operator^=(const RootNodeMask &other)
Definition: NodeMasks.h:1265
openvdb::v10_0::util::RootNodeMask::printBits
void printBits(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:1385
openvdb::v10_0::util::RootNodeMask::setOff
void setOff()
Definition: NodeMasks.h:1314
openvdb::v10_0::util::RootNodeMask::init
void init(Index32 bit_size)
Definition: NodeMasks.h:1086
openvdb::v10_0::util::RootNodeMask::memUsage
Index32 memUsage() const
Definition: NodeMasks.h:1424
openvdb::v10_0::util::RootNodeMask::getMemUsage
Index32 getMemUsage() const
Definition: NodeMasks.h:1283
openvdb::v10_0::util::RootNodeMask::isOff
bool isOff() const
Definition: NodeMasks.h:1348
openvdb::v10_0::util::RootNodeMask::operator=
RootNodeMask & operator=(const RootNodeMask &B)
Definition: NodeMasks.h:1098
openvdb::v10_0::util::RootNodeMask::toggle
void toggle(Index32 i)
Definition: NodeMasks.h:1318
openvdb::v10_0::util::RootNodeMask::operator^
RootNodeMask operator^(const RootNodeMask &other) const
Definition: NodeMasks.h:1278
openvdb::v10_0::util::RootNodeMask::toggle
void toggle()
Definition: NodeMasks.h:1323
openvdb::v10_0::util::RootNodeMask::RootNodeMask
RootNodeMask(Index32 bit_size)
Definition: NodeMasks.h:1074
openvdb::v10_0::util::RootNodeMask::printAll
void printAll(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:1397
openvdb::v10_0::util::RootNodeMask::printInfo
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:1381
openvdb::v10_0::util::RootNodeMask::operator|=
const RootNodeMask & operator|=(const RootNodeMask &other)
Definition: NodeMasks.h:1258
openvdb::v10_0::util::RootNodeMask::findNextOn
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:1402
openvdb::v10_0::util::RootNodeMask::setLastOn
void setLastOn()
Definition: NodeMasks.h:1328
openvdb::v10_0::util::RootNodeMask::endOff
OffIterator endOff() const
Definition: NodeMasks.h:1230
openvdb::v10_0::util::RootNodeMask::isOn
bool isOn() const
Definition: NodeMasks.h:1342
openvdb::v10_0::util::RootNodeMask::findFirstOn
Index32 findFirstOn() const
Definition: NodeMasks.h:1354
openvdb::v10_0::util::CountOff
Index32 CountOff(Byte v)
Return the number of off bits in the given 8-bit value.
Definition: NodeMasks.h:49
openvdb::v10_0::util::FindHighestOn
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:159
openvdb::v10_0::util::FindLowestOn
Index32 FindLowestOn(Byte v)
Return the least significant on bit of the given 8-bit value.
Definition: NodeMasks.h:85
openvdb::v10_0::util::CountOn
Index32 CountOn(Byte v)
Return the number of on bits in the given 8-bit value.
Definition: NodeMasks.h:27
openvdb::v10_0::Index
Index32 Index
Definition: Types.h:54
openvdb::v10_0::Byte
unsigned char Byte
Definition: Types.h:59
openvdb::v10_0::Index32
uint32_t Index32
Definition: Types.h:52
openvdb::v10_0::Index64
uint64_t Index64
Definition: Types.h:53
openvdb
Definition: Exceptions.h:13
Types.h
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212