OpenVDB  8.1.1
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 <strings.h> // for ffs
18 
19 
20 namespace openvdb {
22 namespace OPENVDB_VERSION_NAME {
23 namespace util {
24 
26 inline Index32
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 
49 inline Index32 CountOff(Byte v) { return CountOn(static_cast<Byte>(~v)); }
50 
52 inline Index32
54 {
55  v = v - ((v >> 1) & 0x55555555U);
56  v = (v & 0x33333333U) + ((v >> 2) & 0x33333333U);
57  return (((v + (v >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24;
58 }
59 
61 inline Index32 CountOff(Index32 v) { return CountOn(~v); }
62 
64 inline Index32
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 
81 inline Index32 CountOff(Index64 v) { return CountOn(~v); }
82 
84 inline Index32
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 
102 inline Index32
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 
124 inline Index32
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 
158 inline Index32
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 
175 
176 
178 template<typename NodeMask>
180 {
181 protected:
182  Index32 mPos; // bit position
183  const NodeMask* mParent; // this iterator can't change the parent_mask!
184 
185 public:
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;}
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 
207 template <typename NodeMask>
208 class OnMaskIterator: public BaseMaskIterator<NodeMask>
209 {
210 private:
212  using BaseType::mPos;//bit position;
213  using BaseType::mParent;//this iterator can't change the parent_mask!
214 public:
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;}
231  {
232  this->increment();
233  return *this;
234  }
235 }; // class OnMaskIterator
236 
237 
238 template <typename NodeMask>
239 class OffMaskIterator: public BaseMaskIterator<NodeMask>
240 {
241 private:
243  using BaseType::mPos;//bit position;
244  using BaseType::mParent;//this iterator can't change the parent_mask!
245 public:
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;}
262  {
263  this->increment();
264  return *this;
265  }
266 }; // class OffMaskIterator
267 
268 
269 template <typename NodeMask>
270 class DenseMaskIterator: public BaseMaskIterator<NodeMask>
271 {
272 private:
274  using BaseType::mPos;//bit position;
275  using BaseType::mParent;//this iterator can't change the parent_mask!
276 
277 public:
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);}
294  {
295  this->increment();
296  return *this;
297  }
298 }; // class DenseMaskIterator
299 
300 
306 template<Index Log2Dim>
307 class NodeMask
308 {
309 public:
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 
318 private:
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 
330 public:
332  NodeMask() { this->setOff(); }
334  NodeMask(bool on) { this->set(on); }
336  NodeMask(const NodeMask &other) { *this = other; }
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 
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 
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  }
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  }
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  }
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  }
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 
441  static Index32 memUsage() { return static_cast<Index32>(WORD_COUNT*sizeof(Word)); }
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  }
450  Index32 countOff() const { return SIZE-this->countOn(); }
452  void setOn(Index32 n) {
453  assert( (n >> 6) < WORD_COUNT );
454  mWords[n >> 6] |= Word(1) << (n & 63);
455  }
457  void setOff(Index32 n) {
458  assert( (n >> 6) < WORD_COUNT );
459  mWords[n >> 6] &= ~(Word(1) << (n & 63));
460  }
462  void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
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  }
471  void setOn()
472  {
473  Index32 n = WORD_COUNT;
474  for (Word* w = mWords; n--; ++w) *w = ~Word(0);
475  }
477  void setOff()
478  {
479  Index32 n = WORD_COUNT;
480  for (Word* w = mWords; n--; ++w) *w = Word(0);
481  }
483  void toggle(Index32 n) {
484  assert( (n >> 6) < WORD_COUNT );
485  mWords[n >> 6] ^= Word(1) << (n & 63);
486  }
488  void toggle()
489  {
490  Index32 n = WORD_COUNT;
491  for (Word* w = mWords; n--; ++w) *w = ~*w;
492  }
494  void setFirstOn() { this->setOn(0); }
496  void setLastOn() { this->setOn(SIZE-1); }
498  void setFirstOff() { this->setOff(0); }
500  void setLastOff() { this->setOff(SIZE-1); }
502  bool isOn(Index32 n) const
503  {
504  assert( (n >> 6) < WORD_COUNT );
505  return 0 != (mWords[n >> 6] & (Word(1) << (n & 63)));
506  }
508  bool isOff(Index32 n) const {return !this->isOn(n); }
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  }
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  }
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  }
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  }
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 
550  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  }
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); }
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 
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 
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 
622 template<>
623 class NodeMask<1>
624 {
625 public:
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 
633 private:
634 
635  Byte mByte;//only member data!
636 
637 public:
639  NodeMask() : mByte(0x00U) {}
641  NodeMask(bool on) : mByte(on ? 0xFFU : 0x00U) {}
643  NodeMask(const NodeMask &other) : mByte(other.mByte) {}
647  void operator = (const NodeMask &other) { mByte = other.mByte; }
648 
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 
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  }
694  const NodeMask& operator&=(const NodeMask& other)
695  {
696  mByte &= other.mByte;
697  return *this;
698  }
700  const NodeMask& operator|=(const NodeMask& other)
701  {
702  mByte |= other.mByte;
703  return *this;
704  }
706  const NodeMask& operator-=(const NodeMask& other)
707  {
708  mByte &= static_cast<Byte>(~other.mByte);
709  return *this;
710  }
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; }
722  static Index32 memUsage() { return 1; }
724  Index32 countOn() const { return CountOn(mByte); }
726  Index32 countOff() const { return CountOff(mByte); }
728  void setOn(Index32 n) {
729  assert( n < 8 );
730  mByte = static_cast<Byte>(mByte | 0x01U << (n & 7));
731  }
733  void setOff(Index32 n) {
734  assert( n < 8 );
735  mByte = static_cast<Byte>(mByte & ~(0x01U << (n & 7)));
736  }
738  void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
740  void set(bool on) { mByte = on ? 0xFFU : 0x00U; }
742  void setOn() { mByte = 0xFFU; }
744  void setOff() { mByte = 0x00U; }
746  void toggle(Index32 n) {
747  assert( n < 8 );
748  mByte = static_cast<Byte>(mByte ^ 0x01U << (n & 7));
749  }
751  void toggle() { mByte = static_cast<Byte>(~mByte); }
753  void setFirstOn() { this->setOn(0); }
755  void setLastOn() { this->setOn(7); }
757  void setFirstOff() { this->setOff(0); }
759  void setLastOff() { this->setOff(7); }
761  bool isOn(Index32 n) const
762  {
763  assert( n < 8 );
764  return mByte & (0x01U << (n & 7));
765  }
767  bool isOff(Index32 n) const {return !this->isOn(n); }
769  bool isOn() const { return mByte == 0xFFU; }
771  bool isOff() const { return mByte == 0; }
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; }
782  {
783  const Byte b = static_cast<Byte>(~mByte);
784  return b ? FindLowestOn(b) : 8;
785  }
786  /*
788  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  }
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); }
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 
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 
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 
844 template<>
845 class NodeMask<2>
846 {
847 public:
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 
855 private:
856 
857  Word mWord;//only member data!
858 
859 public:
861  NodeMask() : mWord(UINT64_C(0x00)) {}
863  NodeMask(bool on) : mWord(on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00)) {}
865  NodeMask(const NodeMask &other) : mWord(other.mWord) {}
869  void operator = (const NodeMask &other) { mWord = other.mWord; }
870 
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 
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  }
916  const NodeMask& operator&=(const NodeMask& other)
917  {
918  mWord &= other.mWord;
919  return *this;
920  }
922  const NodeMask& operator|=(const NodeMask& other)
923  {
924  mWord |= other.mWord;
925  return *this;
926  }
928  const NodeMask& operator-=(const NodeMask& other)
929  {
930  mWord &= ~other.mWord;
931  return *this;
932  }
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; }
944  static Index32 memUsage() { return 8; }
946  Index32 countOn() const { return CountOn(mWord); }
948  Index32 countOff() const { return CountOff(mWord); }
950  void setOn(Index32 n) {
951  assert( n < 64 );
952  mWord |= UINT64_C(0x01) << (n & 63);
953  }
955  void setOff(Index32 n) {
956  assert( n < 64 );
957  mWord &= ~(UINT64_C(0x01) << (n & 63));
958  }
960  void set(Index32 n, bool On) { On ? this->setOn(n) : this->setOff(n); }
962  void set(bool on) { mWord = on ? UINT64_C(0xFFFFFFFFFFFFFFFF) : UINT64_C(0x00); }
964  void setOn() { mWord = UINT64_C(0xFFFFFFFFFFFFFFFF); }
966  void setOff() { mWord = UINT64_C(0x00); }
968  void toggle(Index32 n) {
969  assert( n < 64 );
970  mWord ^= UINT64_C(0x01) << (n & 63);
971  }
973  void toggle() { mWord = ~mWord; }
975  void setFirstOn() { this->setOn(0); }
977  void setLastOn() { this->setOn(63); }
979  void setFirstOff() { this->setOff(0); }
981  void setLastOff() { this->setOff(63); }
983  bool isOn(Index32 n) const
984  {
985  assert( n < 64 );
986  return 0 != (mWord & (UINT64_C(0x01) << (n & 63)));
987  }
989  bool isOff(Index32 n) const {return !this->isOn(n); }
991  bool isOn() const { return mWord == UINT64_C(0xFFFFFFFFFFFFFFFF); }
993  bool isOff() const { return mWord == 0; }
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; }
1003  {
1004  const Word w = ~mWord;
1005  return w ? FindLowestOn(w) : 64;
1006  }
1008  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  }
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); }
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 
1046  {
1047  if (start>=64) return 64;
1048  const Word w = mWord & (UINT64_C(0xFFFFFFFFFFFFFFFF) << start);
1049  return w ? FindLowestOn(w) : 64;
1050  }
1051 
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!
1067 {
1068 protected:
1069  Index32 mBitSize, mIntSize;
1071 
1072 public:
1073  RootNodeMask(): mBitSize(0), mIntSize(0), mBits(nullptr) {}
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  }
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 
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 
1110  {
1111  protected:
1112  Index32 mPos;//bit position
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;}
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 
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:
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;}
1166  this->increment();
1167  return *this;
1168  }
1169  }; // class OnIterator
1170 
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:
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;}
1194  this->increment();
1195  return *this;
1196  }
1197  }; // class OffIterator
1198 
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:
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);}
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 
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 
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 
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  }
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
void increment()
Definition: NodeMasks.h:1152
bool operator*() const
Definition: NodeMasks.h:1220
void printAll(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:589
DenseMaskIterator()
Definition: NodeMasks.h:278
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:457
DenseMaskIterator & operator++()
Definition: NodeMasks.h:293
OnIterator endOn() const
Definition: NodeMasks.h:1228
Index32 findFirstOff() const
Definition: NodeMasks.h:1002
Index32 offset() const
Definition: NodeMasks.h:199
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:993
OffIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1179
void load(std::istream &is)
Definition: NodeMasks.h:807
~RootNodeMask()
Definition: NodeMasks.h:1084
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:485
DenseIterator endDense() const
Definition: NodeMasks.h:1232
void increment()
Definition: NodeMasks.h:280
~NodeMask()
Destructor.
Definition: NodeMasks.h:867
BaseMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:188
uint32_t Index32
Definition: openvdb/Types.h:48
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:436
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:755
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:975
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:861
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:712
Index32 pos() const
Definition: NodeMasks.h:200
NodeMask operator!() const
Definition: NodeMasks.h:717
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:940
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:508
bool next()
Definition: NodeMasks.h:1188
void setOn()
Set all bits on.
Definition: NodeMasks.h:742
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:428
void setFirstOff()
Definition: NodeMasks.h:1329
Index32 * mBits
Definition: NodeMasks.h:1070
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:641
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:973
OffMaskIterator & operator++()
Definition: NodeMasks.h:261
Index32 findFirstOff() const
Definition: NodeMasks.h:781
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
OffIterator beginOff() const
Definition: NodeMasks.h:877
const NodeMask & operator^=(const NodeMask &other)
Bitwise XOR.
Definition: NodeMasks.h:934
NodeMask & operator=(const NodeMask &other)
Assignment operator.
Definition: NodeMasks.h:340
OffIterator endOff() const
Definition: NodeMasks.h:355
OffIterator beginOff() const
Definition: NodeMasks.h:655
bool operator*() const
Definition: NodeMasks.h:1164
bool operator!=(const BaseMaskIterator &iter) const
Definition: NodeMasks.h:193
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:552
RootNodeMask operator&(const RootNodeMask &other) const
Definition: NodeMasks.h:1272
void setOff(Index32 i)
Definition: NodeMasks.h:1302
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:332
BaseIterator & operator=(const BaseIterator &iter)
Definition: NodeMasks.h:1123
DenseMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:279
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:643
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:751
void toggle()
Toggle the state of all bits in the mask.
Definition: NodeMasks.h:488
void increment()
Definition: NodeMasks.h:1180
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:863
OPENVDB_API void printBits(std::ostream &os, half h)
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:979
WordT & getWord(Index n)
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:1016
OnIterator endOn() const
Definition: NodeMasks.h:353
bool isOn() const
Definition: NodeMasks.h:1342
Index32 findFirstOn() const
Definition: NodeMasks.h:534
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:977
void setOff()
Set all bits off.
Definition: NodeMasks.h:477
WordT getWord(Index n) const
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:1010
DenseIterator()
Definition: NodeMasks.h:1206
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:437
RootNodeMask & operator=(const RootNodeMask &B)
Definition: NodeMasks.h:1098
Byte Word
Definition: NodeMasks.h:631
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:759
Index64 Word
Definition: NodeMasks.h:853
bool operator*() const
Definition: NodeMasks.h:292
void setOff()
Set all bits off.
Definition: NodeMasks.h:744
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:572
BaseMaskIterator & operator=(const BaseMaskIterator &iter)
Definition: NodeMasks.h:195
void increment(Index n)
Definition: NodeMasks.h:223
void printAll(std::ostream &os=std::cout) const
Definition: NodeMasks.h:820
OffIterator()
Definition: NodeMasks.h:1178
OffMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:247
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:1052
OffIterator & operator++()
Definition: NodeMasks.h:1193
bool next()
Definition: NodeMasks.h:255
void setOn()
Set all bits on.
Definition: NodeMasks.h:964
void printBits(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:1385
Definition: NodeMasks.h:208
RootNodeMask(const RootNodeMask &B)
Definition: NodeMasks.h:1079
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:981
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:502
void setOn()
Definition: NodeMasks.h:1310
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:733
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:404
OnMaskIterator()
Definition: NodeMasks.h:215
bool operator*() const
Definition: NodeMasks.h:1192
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:991
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:775
bool operator!=(const BaseIterator &iter) const
Definition: NodeMasks.h:1121
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:865
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:706
OnIterator endOn() const
Definition: NodeMasks.h:654
BaseIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1118
BaseIterator()
Definition: NodeMasks.h:1116
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:983
Index32 findFirstOn() const
Definition: NodeMasks.h:780
void setLastOn()
Definition: NodeMasks.h:1328
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:722
void increment()
Definition: NodeMasks.h:248
void seek(std::istream &is) const
Definition: NodeMasks.h:1024
OffMaskIterator()
Definition: NodeMasks.h:246
void setLastOff()
Set the last bit off.
Definition: NodeMasks.h:500
Definition: NodeMasks.h:1066
OffIterator beginOff() const
Definition: NodeMasks.h:1229
bool operator*() const
Definition: NodeMasks.h:260
OnIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1151
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:719
bool isOn(Index32 n) const
Return true if the nth bit is on.
Definition: NodeMasks.h:761
void printAll(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:1397
DenseIterator endDense() const
Definition: NodeMasks.h:658
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:724
Index32 Index
Definition: openvdb/Types.h:50
Index getBitSize() const
Definition: NodeMasks.h:1094
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:700
RootNodeMask(Index32 bit_size)
Definition: NodeMasks.h:1074
NodeMask operator!() const
Definition: NodeMasks.h:435
void save(std::ostream &os) const
Definition: NodeMasks.h:1022
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:753
Index32 pos() const
Definition: NodeMasks.h:1132
bool next()
Definition: NodeMasks.h:1216
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:950
Index32 countOff() const
Definition: NodeMasks.h:1294
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:968
OffIterator endOff() const
Definition: NodeMasks.h:878
void setFirstOn()
Definition: NodeMasks.h:1327
RootNodeMask operator!() const
Definition: NodeMasks.h:1249
void printAll(std::ostream &os=std::cout) const
Definition: NodeMasks.h:1039
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:767
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:438
bool next()
Definition: NodeMasks.h:287
Base class for the bit mask iterators.
Definition: NodeMasks.h:179
void setOn(Index32 i)
Definition: NodeMasks.h:1296
Index64 Word
Definition: NodeMasks.h:316
void toggle(Index32 i)
Definition: NodeMasks.h:1318
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:189
void load(std::istream &is)
Definition: NodeMasks.h:1372
void increment()
Definition: NodeMasks.h:217
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:450
OffIterator beginOff() const
Definition: NodeMasks.h:354
Index getIntSize() const
Definition: NodeMasks.h:1096
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:1026
Index32 mBitSize
Definition: NodeMasks.h:1113
BaseMaskIterator()
Definition: NodeMasks.h:186
Index32 findFirstOff() const
Definition: NodeMasks.h:1361
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:510
bool operator==(const BaseMaskIterator &iter) const
Definition: NodeMasks.h:192
const RootNodeMask * mParent
Definition: NodeMasks.h:1114
bool isOff(Index32 n) const
Return true if the nth bit is off.
Definition: NodeMasks.h:989
void load(std::istream &is)
Definition: NodeMasks.h:1023
NodeMask operator|(const NodeMask &other) const
Definition: NodeMasks.h:941
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:517
Definition: openvdb/Exceptions.h:13
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:443
DenseIterator endDense() const
Definition: NodeMasks.h:880
void setLastOff()
Definition: NodeMasks.h:1330
NodeMask(const NodeMask &other)
Copy constructor.
Definition: NodeMasks.h:336
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:694
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:942
OnIterator beginOn() const
Definition: NodeMasks.h:352
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:1381
void load(std::istream &is)
Definition: NodeMasks.h:569
uint64_t Index64
Definition: openvdb/Types.h:49
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:944
NodeMask operator!() const
Definition: NodeMasks.h:939
Index32 mBitSize
Definition: NodeMasks.h:1069
Definition: NodeMasks.h:270
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:483
DenseIterator beginDense() const
Definition: NodeMasks.h:879
const RootNodeMask & operator&=(const RootNodeMask &other)
Definition: NodeMasks.h:1250
OnIterator beginOn() const
Definition: NodeMasks.h:875
NodeMask operator^(const NodeMask &other) const
Definition: NodeMasks.h:720
DenseIterator(Index32 pos, const RootNodeMask *parent)
Definition: NodeMasks.h:1207
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:948
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:420
bool isOn(Index32 i) const
Definition: NodeMasks.h:1331
void save(std::ostream &os) const
Definition: NodeMasks.h:565
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:833
bool operator*() const
Definition: NodeMasks.h:229
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:498
Index32 CountOff(Index64 v)
Return the number of off bits in the given 64-bit value.
Definition: NodeMasks.h:81
Index32 countOff() const
Return the total number of on bits.
Definition: NodeMasks.h:726
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:595
Index32 getMemUsage() const
Definition: NodeMasks.h:1283
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:1402
Index32 CountOn(Index64 v)
Return the number of on bits in the given 64-bit value.
Definition: NodeMasks.h:65
Index32 findFirstOn() const
Definition: NodeMasks.h:1354
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:826
RootNodeMask operator^(const RootNodeMask &other) const
Definition: NodeMasks.h:1278
void setOff()
Definition: NodeMasks.h:1314
void setOn()
Set all bits on.
Definition: NodeMasks.h:471
Index32 FindLowestOn(Index64 v)
Return the least significant on bit of the given 64-bit value.
Definition: NodeMasks.h:125
void increment(Index n)
Definition: NodeMasks.h:286
bool isOn() const
Return true if all the bits are on.
Definition: NodeMasks.h:769
void toggle(Index32 n)
Toggle the state of the nth bit.
Definition: NodeMasks.h:746
OnMaskIterator & operator++()
Definition: NodeMasks.h:230
Index32 countOn() const
Definition: NodeMasks.h:1287
bool next()
Definition: NodeMasks.h:1160
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:728
bool isOff() const
Definition: NodeMasks.h:1348
const RootNodeMask & operator|=(const RootNodeMask &other)
Definition: NodeMasks.h:1258
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:922
~NodeMask()
Destructor.
Definition: NodeMasks.h:645
OnMaskIterator(Index32 pos, const NodeMask *parent)
Definition: NodeMasks.h:216
OnIterator endOn() const
Definition: NodeMasks.h:876
OnIterator beginOn() const
Definition: NodeMasks.h:653
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:477
NodeMask()
Default constructor sets all bits off.
Definition: NodeMasks.h:639
NodeMask(bool on)
All bits are set to the specified state.
Definition: NodeMasks.h:334
const NodeMask & operator-=(const NodeMask &other)
Bitwise difference.
Definition: NodeMasks.h:928
void init(Index32 bit_size)
Definition: NodeMasks.h:1086
const NodeMask & operator|=(const NodeMask &other)
Bitwise union.
Definition: NodeMasks.h:412
OnIterator & operator++()
Definition: NodeMasks.h:1165
void setOn(Index32 n)
Set the nth bit on.
Definition: NodeMasks.h:452
DenseIterator endDense() const
Definition: NodeMasks.h:357
DenseIterator beginDense() const
Definition: NodeMasks.h:657
DenseIterator beginDense() const
Definition: NodeMasks.h:356
OffIterator endOff() const
Definition: NodeMasks.h:656
bool operator==(const BaseIterator &iter) const
Definition: NodeMasks.h:1120
void increment(Index n)
Definition: NodeMasks.h:1213
Index32 findFirstOff() const
Definition: NodeMasks.h:541
WordT & getWord(Index n)
Return the nth word of the bit mask, for a word of arbitrary size.
Definition: NodeMasks.h:558
~NodeMask()
Destructor.
Definition: NodeMasks.h:338
RootNodeMask()
Definition: NodeMasks.h:1073
void setOff(Index32 n)
Set the nth bit off.
Definition: NodeMasks.h:955
Definition: NodeMasks.h:239
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:233
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:997
bool test() const
Definition: NodeMasks.h:201
void seek(std::istream &is) const
Definition: NodeMasks.h:1376
void setFirstOn()
Set the first bit on.
Definition: NodeMasks.h:494
void increment(Index n)
Definition: NodeMasks.h:1157
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:607
Index32 offset() const
Definition: NodeMasks.h:1130
void increment(Index n)
Definition: NodeMasks.h:1185
void toggle()
Definition: NodeMasks.h:1323
void setOff()
Set all bits off.
Definition: NodeMasks.h:966
const NodeMask * mParent
Definition: NodeMasks.h:183
Index32 memUsage() const
Definition: NodeMasks.h:1424
RootNodeMask operator|(const RootNodeMask &other) const
Definition: NodeMasks.h:1275
static Index32 memUsage()
Return the byte size of this NodeMask.
Definition: NodeMasks.h:441
void save(std::ostream &os) const
Definition: NodeMasks.h:1368
void increment(Index n)
Definition: NodeMasks.h:254
bool isOff() const
Return true if all the bits are off.
Definition: NodeMasks.h:771
Index32 findFirstOn() const
Definition: NodeMasks.h:1001
bool isConstant(bool &isOn) const
Definition: NodeMasks.h:526
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:103
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
DenseIterator & operator++()
Definition: NodeMasks.h:1221
void setFirstOff()
Set the first bit off.
Definition: NodeMasks.h:757
Index32 mIntSize
Definition: NodeMasks.h:1069
void printInfo(std::ostream &os=std::cout) const
simple print method for debugging
Definition: NodeMasks.h:810
bool next()
Definition: NodeMasks.h:224
Index32 findNextOn(Index32 start) const
Definition: NodeMasks.h:1045
void increment()
Definition: NodeMasks.h:1208
void printBits(std::ostream &os=std::cout) const
Definition: NodeMasks.h:1030
OffIterator endOff() const
Definition: NodeMasks.h:1230
OnIterator()
Definition: NodeMasks.h:1150
Index32 countOn() const
Return the total number of on bits.
Definition: NodeMasks.h:946
NodeMask operator&(const NodeMask &other) const
Definition: NodeMasks.h:718
Index32 findNextOff(Index32 start) const
Definition: NodeMasks.h:1413
void printBits(std::ostream &os=std::cout, Index32 max_out=80u) const
Definition: NodeMasks.h:577
void seek(std::istream &is) const
Definition: NodeMasks.h:808
void seek(std::istream &is) const
Definition: NodeMasks.h:570
Index32 FindHighestOn(Index32 v)
Return the most significant on bit of the given 32-bit value.
Definition: NodeMasks.h:159
void save(std::ostream &os) const
Definition: NodeMasks.h:806
const RootNodeMask & operator^=(const RootNodeMask &other)
Definition: NodeMasks.h:1265
Index32 mPos
Definition: NodeMasks.h:1112
bool test() const
Definition: NodeMasks.h:1134
bool isOff(Index32 i) const
Definition: NodeMasks.h:1336
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178
#define COUNTONB6(n)
void printBits(std::ostream &os=std::cout) const
Definition: NodeMasks.h:814
Index32 mPos
Definition: NodeMasks.h:182
unsigned char Byte
Definition: openvdb/Types.h:55
OnIterator beginOn() const
Definition: NodeMasks.h:1227
DenseIterator beginDense() const
Definition: NodeMasks.h:1231
const NodeMask & operator&=(const NodeMask &other)
Bitwise intersection.
Definition: NodeMasks.h:916
void setLastOn()
Set the last bit on.
Definition: NodeMasks.h:496