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