OpenVDB  11.0.0
Coord.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #ifndef OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
5 #define OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
6 
7 #include <functional>// for std::hash
8 #include <algorithm> // for std::min(), std::max()
9 #include <array> // for std::array
10 #include <iostream>
11 #include <limits>
12 #include <openvdb/Platform.h>
13 #include "Math.h"
14 #include "Vec3.h"
15 
16 #include <tbb/blocked_range.h> // for tbb::split
17 
18 namespace openvdb {
20 namespace OPENVDB_VERSION_NAME {
21 namespace math {
22 
23 /// @brief Signed (x, y, z) 32-bit integer coordinates
24 class Coord
25 {
26 public:
27  using Int32 = int32_t;
28  using Index32 = uint32_t;
29  using Vec3i = Vec3<Int32>;
31 
32  using ValueType = Int32;
33  using Limits = std::numeric_limits<ValueType>;
34 
35  Coord(): mVec{{0, 0, 0}} {}
36  constexpr explicit Coord(Int32 xyz): mVec{{xyz, xyz, xyz}} {}
37  constexpr Coord(Int32 x, Int32 y, Int32 z): mVec{{x, y, z}} {}
38  explicit Coord(const Vec3i& v): mVec{{v[0], v[1], v[2]}} {}
39  explicit Coord(const Vec3I& v): mVec{{Int32(v[0]), Int32(v[1]), Int32(v[2])}} {}
40  explicit Coord(const Int32* v): mVec{{v[0], v[1], v[2]}} {}
41 
42  /// @brief Return the smallest possible coordinate
43  static Coord min() { return Coord(Limits::min()); }
44 
45  /// @brief Return the largest possible coordinate
46  static Coord max() { return Coord(Limits::max()); }
47 
48  /// @brief Return @a xyz rounded to the closest integer coordinates
49  /// (cell centered conversion).
50  template<typename T> static Coord round(const Vec3<T>& xyz)
51  {
52  return Coord(Int32(Round(xyz[0])), Int32(Round(xyz[1])), Int32(Round(xyz[2])));
53  }
54  /// @brief Return the largest integer coordinates that are not greater
55  /// than @a xyz (node centered conversion).
56  template<typename T> static Coord floor(const Vec3<T>& xyz)
57  {
58  return Coord(Int32(Floor(xyz[0])), Int32(Floor(xyz[1])), Int32(Floor(xyz[2])));
59  }
60 
61  /// @brief Return the largest integer coordinates that are not greater
62  /// than @a xyz+1 (node centered conversion).
63  template<typename T> static Coord ceil(const Vec3<T>& xyz)
64  {
65  return Coord(Int32(Ceil(xyz[0])), Int32(Ceil(xyz[1])), Int32(Ceil(xyz[2])));
66  }
67 
68  /// @brief Reset all three coordinates with the specified arguments
70  {
71  mVec[0] = x;
72  mVec[1] = y;
73  mVec[2] = z;
74  return *this;
75  }
76  /// @brief Reset all three coordinates with the same specified argument
77  Coord& reset(Int32 xyz) { return this->reset(xyz, xyz, xyz); }
78 
79  Coord& setX(Int32 x) { mVec[0] = x; return *this; }
80  Coord& setY(Int32 y) { mVec[1] = y; return *this; }
81  Coord& setZ(Int32 z) { mVec[2] = z; return *this; }
82 
83  Coord& offset(Int32 dx, Int32 dy, Int32 dz)
84  {
85  mVec[0] += dx;
86  mVec[1] += dy;
87  mVec[2] += dz;
88  return *this;
89  }
90  Coord& offset(Int32 n) { return this->offset(n, n, n); }
91  Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
92  {
93  return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
94  }
95  Coord offsetBy(Int32 n) const { return offsetBy(n, n, n); }
96 
97  Coord& operator+=(const Coord& rhs)
98  {
99  mVec[0] += rhs[0];
100  mVec[1] += rhs[1];
101  mVec[2] += rhs[2];
102  return *this;
103  }
104  Coord& operator-=(const Coord& rhs)
105  {
106  mVec[0] -= rhs[0];
107  mVec[1] -= rhs[1];
108  mVec[2] -= rhs[2];
109  return *this;
110  }
111  Coord operator+(const Coord& rhs) const
112  {
113  return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]);
114  }
115  Coord operator-(const Coord& rhs) const
116  {
117  return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]);
118  }
119  Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
120 
121  Coord operator>> (size_t n) const { return Coord(mVec[0]>>n, mVec[1]>>n, mVec[2]>>n); }
122  Coord operator<< (size_t n) const { return Coord(mVec[0]<<n, mVec[1]<<n, mVec[2]<<n); }
123  Coord& operator<<=(size_t n) { mVec[0]<<=n; mVec[1]<<=n; mVec[2]<<=n; return *this; }
124  Coord& operator>>=(size_t n) { mVec[0]>>=n; mVec[1]>>=n; mVec[2]>>=n; return *this; }
125  Coord operator& (Int32 n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
126  Coord operator| (Int32 n) const { return Coord(mVec[0] | n, mVec[1] | n, mVec[2] | n); }
127  Coord& operator&= (Int32 n) { mVec[0]&=n; mVec[1]&=n; mVec[2]&=n; return *this; }
128  Coord& operator|= (Int32 n) { mVec[0]|=n; mVec[1]|=n; mVec[2]|=n; return *this; }
129 
130  Int32 x() const { return mVec[0]; }
131  Int32 y() const { return mVec[1]; }
132  Int32 z() const { return mVec[2]; }
133  Int32 operator[](size_t i) const { assert(i < 3); return mVec[i]; }
134  Int32& x() { return mVec[0]; }
135  Int32& y() { return mVec[1]; }
136  Int32& z() { return mVec[2]; }
137  Int32& operator[](size_t i) { assert(i < 3); return mVec[i]; }
138 
139  const Int32* data() const { return mVec.data(); }
140  Int32* data() { return mVec.data(); }
141  const Int32* asPointer() const { return mVec.data(); }
142  Int32* asPointer() { return mVec.data(); }
143  Vec3d asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
144  Vec3s asVec3s() const { return Vec3s(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
145  Vec3i asVec3i() const { return Vec3i(mVec.data()); }
146  Vec3I asVec3I() const { return Vec3I(Index32(mVec[0]), Index32(mVec[1]), Index32(mVec[2])); }
147  void asXYZ(Int32& x, Int32& y, Int32& z) const { x = mVec[0]; y = mVec[1]; z = mVec[2]; }
148 
149  bool operator==(const Coord& rhs) const
150  {
151  return (mVec[0] == rhs.mVec[0] && mVec[1] == rhs.mVec[1] && mVec[2] == rhs.mVec[2]);
152  }
153  bool operator!=(const Coord& rhs) const { return !(*this == rhs); }
154 
155  /// Lexicographic less than
156  bool operator<(const Coord& rhs) const
157  {
158  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
159  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
160  : this->z() < rhs.z() ? true : false;
161  }
162  /// Lexicographic less than or equal to
163  bool operator<=(const Coord& rhs) const
164  {
165  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
166  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
167  : this->z() <=rhs.z() ? true : false;
168  }
169  /// Lexicographic greater than
170  bool operator>(const Coord& rhs) const { return !(*this <= rhs); }
171  /// Lexicographic greater than or equal to
172  bool operator>=(const Coord& rhs) const { return !(*this < rhs); }
173 
174  /// Perform a component-wise minimum with the other Coord.
175  void minComponent(const Coord& other)
176  {
177  mVec[0] = std::min(mVec[0], other.mVec[0]);
178  mVec[1] = std::min(mVec[1], other.mVec[1]);
179  mVec[2] = std::min(mVec[2], other.mVec[2]);
180  }
181 
182  /// Perform a component-wise maximum with the other Coord.
183  void maxComponent(const Coord& other)
184  {
185  mVec[0] = std::max(mVec[0], other.mVec[0]);
186  mVec[1] = std::max(mVec[1], other.mVec[1]);
187  mVec[2] = std::max(mVec[2], other.mVec[2]);
188  }
189 
190  /// Return the component-wise minimum of the two Coords.
191  static inline Coord minComponent(const Coord& lhs, const Coord& rhs)
192  {
193  return Coord(std::min(lhs.x(), rhs.x()),
194  std::min(lhs.y(), rhs.y()),
195  std::min(lhs.z(), rhs.z()));
196  }
197 
198  /// Return the component-wise maximum of the two Coords.
199  static inline Coord maxComponent(const Coord& lhs, const Coord& rhs)
200  {
201  return Coord(std::max(lhs.x(), rhs.x()),
202  std::max(lhs.y(), rhs.y()),
203  std::max(lhs.z(), rhs.z()));
204  }
205 
206  /// Return true if any of the components of @a a are smaller than the
207  /// corresponding components of @a b.
208  static inline bool lessThan(const Coord& a, const Coord& b)
209  {
210  return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
211  }
212 
213  /// @brief Return the index (0, 1 or 2) with the smallest value.
214  size_t minIndex() const { return MinIndex(mVec); }
215 
216  /// @brief Return the index (0, 1 or 2) with the largest value.
217  size_t maxIndex() const { return MaxIndex(mVec); }
218 
219  void read(std::istream& is) { is.read(reinterpret_cast<char*>(mVec.data()), sizeof(mVec)); }
220  void write(std::ostream& os) const
221  {
222  os.write(reinterpret_cast<const char*>(mVec.data()), sizeof(mVec));
223  }
224 
225  /// @brief Return a hash value for this coordinate
226  /// @note Log2N is the binary logarithm of the hash table size.
227  /// @details The hash function is originally taken from the SIGGRAPH paper:
228  /// "VDB: High-resolution sparse volumes with dynamic topology"
229  /// and the prime numbers are modified based on the ACM Transactions on Graphics paper:
230  /// "Real-time 3D reconstruction at scale using voxel hashing"
231  template<int Log2N = 20>
232  size_t hash() const
233  {
234  const uint32_t* vec = reinterpret_cast<const uint32_t*>(mVec.data());
235  return ((1<<Log2N)-1) & (vec[0]*73856093 ^ vec[1]*19349669 ^ vec[2]*83492791);
236  }
237 
238 private:
239  std::array<Int32, 3> mVec;
240 }; // class Coord
241 
242 
243 ////////////////////////////////////////
244 
245 
246 /// @brief Axis-aligned bounding box of signed integer coordinates
247 /// @note The range of the integer coordinates, [min, max], is inclusive.
248 /// Thus, a bounding box with min = max is not empty but rather encloses
249 /// a single coordinate.
251 {
252 public:
253  using Index64 = uint64_t;
255 
256  /// @brief Iterator over the Coord domain covered by a CoordBBox
257  /// @note If ZYXOrder is @c true, @e z is the fastest-moving coordinate,
258  /// otherwise the traversal is in XYZ order (i.e., @e x is fastest-moving).
259  template<bool ZYXOrder>
260  class Iterator
261  {
262  public:
263  /// @brief C-tor from a bounding box
264  Iterator(const CoordBBox& b): mPos(b.min()), mMin(b.min()), mMax(b.max()) {}
265  /// @brief Increment the iterator to point to the next coordinate.
266  /// @details Iteration stops one past the maximum coordinate
267  /// along the axis determined by the template parameter.
268  Iterator& operator++() { ZYXOrder ? next<2,1,0>() : next<0,1,2>(); return *this; }
269  /// @brief Return @c true if the iterator still points to a valid coordinate.
270  operator bool() const { return ZYXOrder ? (mPos[0] <= mMax[0]) : (mPos[2] <= mMax[2]); }
271  /// @brief Return a const reference to the coordinate currently pointed to.
272  const Coord& operator*() const { return mPos; }
273  /// Return @c true if this iterator and the given iterator point to the same coordinate.
274  bool operator==(const Iterator& other) const
275  {
276  return ((mPos == other.mPos) && (mMin == other.mMin) && (mMax == other.mMax));
277  }
278  /// Return @c true if this iterator and the given iterator point to different coordinates.
279  bool operator!=(const Iterator& other) const { return !(*this == other); }
280  private:
281  template<size_t a, size_t b, size_t c>
282  void next()
283  {
284  if (mPos[a] < mMax[a]) { ++mPos[a]; } // this is the most common case
285  else if (mPos[b] < mMax[b]) { mPos[a] = mMin[a]; ++mPos[b]; }
286  else if (mPos[c] <= mMax[c]) { mPos[a] = mMin[a]; mPos[b] = mMin[b]; ++mPos[c]; }
287  }
288  Coord mPos, mMin, mMax;
289  friend class CoordBBox; // for CoordBBox::end()
290  };// CoordBBox::Iterator
291 
292  using ZYXIterator = Iterator</*ZYX=*/true>;
293  using XYZIterator = Iterator</*ZYX=*/false>;
294 
295  /// @brief The default constructor produces an empty bounding box.
296  CoordBBox(): mMin(Coord::max()), mMax(Coord::min()) {}
297  /// @brief Construct a bounding box with the given @a min and @a max bounds.
298  CoordBBox(const Coord& min, const Coord& max): mMin(min), mMax(max) {}
299  /// @brief Construct from individual components of the min and max bounds.
301  ValueType xMax, ValueType yMax, ValueType zMax)
302  : mMin(xMin, yMin, zMin), mMax(xMax, yMax, zMax)
303  {
304  }
305  /// @brief Splitting constructor for use in TBB ranges
306  /// @note The other bounding box is assumed to be divisible.
307  CoordBBox(CoordBBox& other, const tbb::split&): mMin(other.mMin), mMax(other.mMax)
308  {
309  assert(this->is_divisible());
310  const size_t n = this->maxExtent();
311  mMax[n] = (mMin[n] + mMax[n]) >> 1;
312  other.mMin[n] = mMax[n] + 1;
313  }
314 
315  static CoordBBox createCube(const Coord& min, ValueType dim)
316  {
317  return CoordBBox(min, min.offsetBy(dim - 1));
318  }
319 
320  /// Return an "infinite" bounding box, as defined by the Coord value range.
321  static CoordBBox inf() { return CoordBBox(Coord::min(), Coord::max()); }
322 
323  const Coord& min() const { return mMin; }
324  const Coord& max() const { return mMax; }
325 
326  Coord& min() { return mMin; }
327  Coord& max() { return mMax; }
328 
329  void reset() { mMin = Coord::max(); mMax = Coord::min(); }
330  void reset(const Coord& min, const Coord& max) { mMin = min; mMax = max; }
331  void resetToCube(const Coord& min, ValueType dim) { mMin = min; mMax = min.offsetBy(dim - 1); }
332 
333  /// @brief Return the minimum coordinate.
334  /// @note The start coordinate is inclusive.
335  Coord getStart() const { return mMin; }
336  /// @brief Return the maximum coordinate plus one.
337  /// @note This end coordinate is exclusive.
338  Coord getEnd() const { return mMax.offsetBy(1); }
339 
340  /// @brief Return a ZYX-order iterator that points to the minimum coordinate.
341  ZYXIterator begin() const { return ZYXIterator{*this}; }
342  /// @brief Return a ZYX-order iterator that points to the minimum coordinate.
343  ZYXIterator beginZYX() const { return ZYXIterator{*this}; }
344  /// @brief Return an XYZ-order iterator that points to the minimum coordinate.
345  XYZIterator beginXYZ() const { return XYZIterator{*this}; }
346 
347  /// @brief Return a ZYX-order iterator that points past the maximum coordinate.
348  ZYXIterator end() const { ZYXIterator it{*this}; it.mPos[0] = mMax[0] + 1; return it; }
349  /// @brief Return a ZYX-order iterator that points past the maximum coordinate.
350  ZYXIterator endZYX() const { return end(); }
351  /// @brief Return an XYZ-order iterator that points past the maximum coordinate.
352  XYZIterator endXYZ() const { XYZIterator it{*this}; it.mPos[2] = mMax[2] + 1; return it; }
353 
354  bool operator==(const CoordBBox& rhs) const { return mMin == rhs.mMin && mMax == rhs.mMax; }
355  bool operator!=(const CoordBBox& rhs) const { return !(*this == rhs); }
356 
357  /// @brief Return @c true if this bounding box is empty (i.e., encloses no coordinates).
358  bool empty() const
359  {
360 #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
361  #pragma GCC diagnostic push
362  #pragma GCC diagnostic ignored "-Wstrict-overflow"
363 #endif
364  return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
365 #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
366  #pragma GCC diagnostic pop
367 #endif
368  }
369  /// @brief Return @c true if this bounding box is nonempty
370  /// (i.e., encloses at least one coordinate).
371  operator bool() const { return !this->empty(); }
372  /// @brief Return @c true if this bounding box is nonempty
373  /// (i.e., encloses at least one coordinate).
374  bool hasVolume() const { return !this->empty(); }
375 
376  /// @brief Return the floating-point position of the center of this bounding box.
377  Vec3d getCenter() const { return 0.5 * Vec3d((mMin + mMax).asPointer()); }
378 
379  /// @brief Return the dimensions of the coordinates spanned by this bounding box.
380  /// @note Since coordinates are inclusive, a bounding box with min = max
381  /// has dimensions of (1, 1, 1).
382  Coord dim() const { return empty() ? Coord(0) : (mMax.offsetBy(1) - mMin); }
383  /// @todo deprecate - use dim instead
384  Coord extents() const { return this->dim(); }
385  /// @brief Return the integer volume of coordinates spanned by this bounding box.
386  /// @note Since coordinates are inclusive, a bounding box with min = max has volume one.
387  Index64 volume() const
388  {
389  const Coord d = this->dim();
390  return Index64(d[0]) * Index64(d[1]) * Index64(d[2]);
391  }
392  /// @brief Return @c true if this bounding box can be subdivided [mainly for use by TBB].
393  bool is_divisible() const { return mMin[0]<mMax[0] && mMin[1]<mMax[1] && mMin[2]<mMax[2]; }
394 
395  /// @brief Return the index (0, 1 or 2) of the shortest axis.
396  size_t minExtent() const { return this->dim().minIndex(); }
397 
398  /// @brief Return the index (0, 1 or 2) of the longest axis.
399  size_t maxExtent() const { return this->dim().maxIndex(); }
400 
401  /// @brief Return @c true if point (x, y, z) is inside this bounding box.
402  bool isInside(const Coord& xyz) const
403  {
404  return !(Coord::lessThan(xyz,mMin) || Coord::lessThan(mMax,xyz));
405  }
406 
407  /// @brief Return @c true if the given bounding box is inside this bounding box.
408  bool isInside(const CoordBBox& b) const
409  {
410  return !(Coord::lessThan(b.mMin,mMin) || Coord::lessThan(mMax,b.mMax));
411  }
412 
413  /// @brief Return @c true if the given bounding box overlaps with this bounding box.
414  bool hasOverlap(const CoordBBox& b) const
415  {
416  return !(Coord::lessThan(mMax,b.mMin) || Coord::lessThan(b.mMax,mMin));
417  }
418 
419  /// @brief Pad this bounding box with the specified padding.
420  void expand(ValueType padding)
421  {
422  mMin.offset(-padding);
423  mMax.offset( padding);
424  }
425 
426  /// @brief Return a new instance that is expanded by the specified padding.
427  CoordBBox expandBy(ValueType padding) const
428  {
429  return CoordBBox(mMin.offsetBy(-padding),mMax.offsetBy(padding));
430  }
431 
432  /// @brief Expand this bounding box to enclose point (x, y, z).
433  void expand(const Coord& xyz)
434  {
435  mMin.minComponent(xyz);
436  mMax.maxComponent(xyz);
437  }
438 
439  /// @brief Union this bounding box with the given bounding box.
440  void expand(const CoordBBox& bbox)
441  {
442  mMin.minComponent(bbox.min());
443  mMax.maxComponent(bbox.max());
444  }
445  /// @brief Intersect this bounding box with the given bounding box.
446  void intersect(const CoordBBox& bbox)
447  {
448  mMin.maxComponent(bbox.min());
449  mMax.minComponent(bbox.max());
450  }
451  /// @brief Union this bounding box with the cubical bounding box
452  /// of the given size and with the given minimum coordinates.
453  void expand(const Coord& min, Coord::ValueType dim)
454  {
455  mMin.minComponent(min);
456  mMax.maxComponent(min.offsetBy(dim-1));
457  }
458  /// @brief Translate this bounding box by
459  /// (<i>t<sub>x</sub></i>, <i>t<sub>y</sub></i>, <i>t<sub>z</sub></i>).
460  void translate(const Coord& t) { mMin += t; mMax += t; }
461 
462  /// @brief Move this bounding box to the specified min
463  void moveMin(const Coord& min) { mMax += min - mMin; mMin = min; }
464 
465  /// @brief Move this bounding box to the specified max
466  void moveMax(const Coord& max) { mMin += max - mMax; mMax = max; }
467 
468  /// @brief Populates an array with the eight corner points of this bounding box.
469  /// @details The ordering of the corner points is lexicographic.
470  /// @warning It is assumed that the pointer can be incremented at
471  /// least seven times, i.e. has storage for eight Coord elements!
472  void getCornerPoints(Coord *p) const
473  {
474  assert(p != nullptr);
475  p->reset(mMin.x(), mMin.y(), mMin.z()); ++p;
476  p->reset(mMin.x(), mMin.y(), mMax.z()); ++p;
477  p->reset(mMin.x(), mMax.y(), mMin.z()); ++p;
478  p->reset(mMin.x(), mMax.y(), mMax.z()); ++p;
479  p->reset(mMax.x(), mMin.y(), mMin.z()); ++p;
480  p->reset(mMax.x(), mMin.y(), mMax.z()); ++p;
481  p->reset(mMax.x(), mMax.y(), mMin.z()); ++p;
482  p->reset(mMax.x(), mMax.y(), mMax.z());
483  }
484 
485  //@{
486  /// @brief Bit-wise operations performed on both the min and max members
487  CoordBBox operator>> (size_t n) const { return CoordBBox(mMin>>n, mMax>>n); }
488  CoordBBox operator<< (size_t n) const { return CoordBBox(mMin<<n, mMax<<n); }
489  CoordBBox& operator<<=(size_t n) { mMin <<= n; mMax <<= n; return *this; }
490  CoordBBox& operator>>=(size_t n) { mMin >>= n; mMax >>= n; return *this; }
491  CoordBBox operator& (Coord::Int32 n) const { return CoordBBox(mMin & n, mMax & n); }
492  CoordBBox operator| (Coord::Int32 n) const { return CoordBBox(mMin | n, mMax | n); }
493  CoordBBox& operator&= (Coord::Int32 n) { mMin &= n; mMax &= n; return *this; }
494  CoordBBox& operator|= (Coord::Int32 n) { mMin |= n; mMax |= n; return *this; }
495  //@}
496 
497  /// @brief Unserialize this bounding box from the given stream.
498  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
499  /// @brief Serialize this bounding box to the given stream.
500  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
501 
502 private:
503  Coord mMin, mMax;
504 }; // class CoordBBox
505 
506 
507 ////////////////////////////////////////
508 
509 
510 inline std::ostream& operator<<(std::ostream& os, const Coord& xyz)
511 {
512  os << xyz.asVec3i(); return os;
513 }
514 
515 
516 inline Coord
517 Abs(const Coord& xyz)
518 {
519  return Coord(Abs(xyz[0]), Abs(xyz[1]), Abs(xyz[2]));
520 }
521 
522 
523 //@{
524 /// Allow a Coord to be added to or subtracted from a Vec3.
525 template<typename T>
527 operator+(const Vec3<T>& v0, const Coord& v1)
528 {
530  result[0] += v1[0];
531  result[1] += v1[1];
532  result[2] += v1[2];
533  return result;
534 }
535 
536 template<typename T>
538 operator+(const Coord& v1, const Vec3<T>& v0)
539 {
541  result[0] += v1[0];
542  result[1] += v1[1];
543  result[2] += v1[2];
544  return result;
545 }
546 //@}
547 
548 
549 //@{
550 /// Allow a Coord to be subtracted from a Vec3.
551 template <typename T>
553 operator-(const Vec3<T>& v0, const Coord& v1)
554 {
556  result[0] -= v1[0];
557  result[1] -= v1[1];
558  result[2] -= v1[2];
559  return result;
560 }
561 
562 template <typename T>
564 operator-(const Coord& v1, const Vec3<T>& v0)
565 {
567  result[0] -= v1[0];
568  result[1] -= v1[1];
569  result[2] -= v1[2];
570  return -result;
571 }
572 //@}
573 
574 inline std::ostream&
575 operator<<(std::ostream& os, const CoordBBox& b)
576 {
577  os << b.min() << " -> " << b.max();
578  return os;
579 }
580 
581 } // namespace math
582 } // namespace OPENVDB_VERSION_NAME
583 } // namespace openvdb
584 
585 ////////////////////////////////////////
586 
587 // template specialization of std::hash with Coord, which
588 // allows for Coord to be used as the key in std::unordered_map
589 namespace std {// injected in namespace std
590 
591 template<>
592 struct hash<openvdb::math::Coord>
593 {
594  using Coord = openvdb::math::Coord;
596  using result_type = std::size_t;
597  std::size_t operator()(const Coord& ijk) const noexcept { return ijk.Coord::hash<>(); }
598 };// std::hash<openvdb::math::Coord>
599 
600 }// namespace std
601 
602 #endif // OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
size_t maxIndex() const
Return the index (0, 1 or 2) with the largest value.
Definition: Coord.h:217
bool operator!=(const Iterator &other) const
Return true if this iterator and the given iterator point to different coordinates.
Definition: Coord.h:279
Coord::ValueType ValueType
Definition: Coord.h:254
size_t hash() const
Return a hash value for this coordinate.
Definition: Coord.h:232
CoordBBox()
The default constructor produces an empty bounding box.
Definition: Coord.h:296
const Int32 * data() const
Definition: Coord.h:139
math::Vec3< Index32 > Vec3I
Definition: Types.h:73
void getCornerPoints(Coord *p) const
Populates an array with the eight corner points of this bounding box.
Definition: Coord.h:472
Vec3s asVec3s() const
Definition: Coord.h:144
void reset()
Definition: Coord.h:329
bool operator>=(const Coord &rhs) const
Lexicographic greater than or equal to.
Definition: Coord.h:172
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:46
void maxComponent(const Coord &other)
Perform a component-wise maximum with the other Coord.
Definition: Coord.h:183
Int32 z() const
Definition: Coord.h:132
Int32 ValueType
Definition: Coord.h:32
CoordBBox(ValueType xMin, ValueType yMin, ValueType zMin, ValueType xMax, ValueType yMax, ValueType zMax)
Construct from individual components of the min and max bounds.
Definition: Coord.h:300
Coord extents() const
Definition: Coord.h:384
bool operator!=(const Coord &rhs) const
Definition: Coord.h:153
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition: Coord.h:460
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool hasVolume() const
Return true if this bounding box is nonempty (i.e., encloses at least one coordinate).
Definition: Coord.h:374
Int32 x() const
Definition: Coord.h:130
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: Coord.h:500
Int32 y() const
Definition: Coord.h:131
Coord & offset(Int32 n)
Definition: Coord.h:90
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:250
int Floor(float x)
Return the floor of x.
Definition: Math.h:848
Int32 & operator[](size_t i)
Definition: Coord.h:137
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:24
Vec3d asVec3d() const
Definition: Coord.h:143
Iterator(const CoordBBox &b)
C-tor from a bounding box.
Definition: Coord.h:264
ZYXIterator beginZYX() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:343
Coord operator+(const Coord &rhs) const
Definition: Coord.h:111
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:420
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: Coord.h:396
Vec3d getCenter() const
Return the floating-point position of the center of this bounding box.
Definition: Coord.h:377
bool operator==(const Coord &rhs) const
Definition: Coord.h:149
Definition: Coord.h:589
Vec3< typename promote< T, typename Coord::ValueType >::type > operator+(const Coord &v1, const Vec3< T > &v0)
Allow a Coord to be added to or subtracted from a Vec3.
Definition: Coord.h:538
Coord argument_type
Definition: Coord.h:595
Definition: Mat.h:165
Coord offsetBy(Int32 n) const
Definition: Coord.h:95
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:321
XYZIterator endXYZ() const
Return an XYZ-order iterator that points past the maximum coordinate.
Definition: Coord.h:352
static Coord minComponent(const Coord &lhs, const Coord &rhs)
Return the component-wise minimum of the two Coords.
Definition: Coord.h:191
bool operator==(const Iterator &other) const
Return true if this iterator and the given iterator point to the same coordinate. ...
Definition: Coord.h:274
CoordBBox expandBy(ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition: Coord.h:427
Coord Abs(const Coord &xyz)
Definition: Coord.h:517
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:856
void moveMin(const Coord &min)
Move this bounding box to the specified min.
Definition: Coord.h:463
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:402
BBox< Coord > CoordBBox
Definition: NanoVDB.h:2535
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:414
bool isInside(const CoordBBox &b) const
Return true if the given bounding box is inside this bounding box.
Definition: Coord.h:408
const Coord & min() const
Definition: Coord.h:323
Vec3< double > Vec3d
Definition: Vec3.h:664
uint64_t Index64
Definition: Types.h:53
Coord & operator+=(const Coord &rhs)
Definition: Coord.h:97
Coord(const Int32 *v)
Definition: Coord.h:40
void expand(const Coord &xyz)
Expand this bounding box to enclose point (x, y, z).
Definition: Coord.h:433
Coord & min()
Definition: Coord.h:326
Coord & operator<<=(size_t n)
Definition: Coord.h:123
Int32 & x()
Definition: Coord.h:134
OPENVDB_API std::istream & operator>>(std::istream &is, half &h)
Input h from is.
ZYXIterator end() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:348
void read(std::istream &is)
Definition: Coord.h:219
Vec3< float > Vec3s
Definition: Vec3.h:663
Int32 operator[](size_t i) const
Definition: Coord.h:133
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: Coord.h:399
Coord & reset(Int32 xyz)
Reset all three coordinates with the same specified argument.
Definition: Coord.h:77
const Int32 * asPointer() const
Definition: Coord.h:141
Coord & setY(Int32 y)
Definition: Coord.h:80
std::size_t result_type
Definition: Coord.h:596
Coord dim() const
Return the dimensions of the coordinates spanned by this bounding box.
Definition: Coord.h:382
Coord & operator>>=(size_t n)
Definition: Coord.h:124
ZYXIterator begin() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:341
std::numeric_limits< ValueType > Limits
Definition: Coord.h:33
Coord & reset(Int32 x, Int32 y, Int32 z)
Reset all three coordinates with the specified arguments.
Definition: Coord.h:69
Vec3I asVec3I() const
Definition: Coord.h:146
static Coord floor(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion)...
Definition: Coord.h:56
Iterator & operator++()
Increment the iterator to point to the next coordinate.
Definition: Coord.h:268
Definition: Exceptions.h:13
bool operator<=(const Coord &rhs) const
Lexicographic less than or equal to.
Definition: Coord.h:163
bool operator<(const Coord &rhs) const
Lexicographic less than.
Definition: Coord.h:156
Coord & offset(Int32 dx, Int32 dy, Int32 dz)
Definition: Coord.h:83
static bool lessThan(const Coord &a, const Coord &b)
Definition: Coord.h:208
constexpr Coord(Int32 x, Int32 y, Int32 z)
Definition: Coord.h:37
Coord & max()
Definition: Coord.h:327
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
Coord & operator-=(const Coord &rhs)
Definition: Coord.h:104
CoordBBox & operator<<=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:489
static Coord maxComponent(const Coord &lhs, const Coord &rhs)
Return the component-wise maximum of the two Coords.
Definition: Coord.h:199
void asXYZ(Int32 &x, Int32 &y, Int32 &z) const
Definition: Coord.h:147
void reset(const Coord &min, const Coord &max)
Definition: Coord.h:330
Coord getEnd() const
Return the maximum coordinate plus one.
Definition: Coord.h:338
Coord & setZ(Int32 z)
Definition: Coord.h:81
bool operator>(const Coord &rhs) const
Lexicographic greater than.
Definition: Coord.h:170
__hostdev__ uint32_t hash(uint32_t x)
Definition: common.h:14
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: Coord.h:498
Int32 * asPointer()
Definition: Coord.h:142
Coord()
Definition: Coord.h:35
Coord getStart() const
Return the minimum coordinate.
Definition: Coord.h:335
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:446
Int32 & z()
Definition: Coord.h:136
constexpr Coord(Int32 xyz)
Definition: Coord.h:36
Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
Definition: Coord.h:91
CoordBBox & operator>>=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:490
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:358
ZYXIterator endZYX() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:350
Coord & setX(Int32 x)
Definition: Coord.h:79
static Coord min()
Return the smallest possible coordinate.
Definition: Coord.h:43
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:387
uint64_t Index64
Definition: Coord.h:253
Iterator over the Coord domain covered by a CoordBBox.
Definition: Coord.h:260
const Coord & max() const
Definition: Coord.h:324
openvdb::math::Coord Coord
Definition: Coord.h:594
Coord(const Vec3i &v)
Definition: Coord.h:38
uint32_t Index32
Definition: Coord.h:28
Int32 & y()
Definition: Coord.h:135
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:175
size_t minIndex() const
Return the index (0, 1 or 2) with the smallest value.
Definition: Coord.h:214
Int32 * data()
Definition: Coord.h:140
std::ostream & operator<<(std::ostream &os, const CoordBBox &b)
Definition: Coord.h:575
void expand(const Coord &min, Coord::ValueType dim)
Union this bounding box with the cubical bounding box of the given size and with the given minimum co...
Definition: Coord.h:453
Vec3< typename promote< T, Coord::ValueType >::type > operator-(const Coord &v1, const Vec3< T > &v0)
Allow a Coord to be subtracted from a Vec3.
Definition: Coord.h:564
CoordBBox(CoordBBox &other, const tbb::split &)
Splitting constructor for use in TBB ranges.
Definition: Coord.h:307
Vec3i asVec3i() const
Definition: Coord.h:145
const Coord & operator*() const
Return a const reference to the coordinate currently pointed to.
Definition: Coord.h:272
int32_t Int32
Definition: Coord.h:27
Coord operator-() const
Definition: Coord.h:119
void expand(const CoordBBox &bbox)
Union this bounding box with the given bounding box.
Definition: Coord.h:440
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:947
bool operator!=(const CoordBBox &rhs) const
Definition: Coord.h:355
Coord(const Vec3I &v)
Definition: Coord.h:39
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:110
void moveMax(const Coord &max)
Move this bounding box to the specified max.
Definition: Coord.h:466
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
void split(ContainerT &out, const std::string &in, const char delim)
Definition: Name.h:43
void write(std::ostream &os) const
Definition: Coord.h:220
Vec3< int32_t > Vec3i
Definition: Vec3.h:661
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:315
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:931
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:106
static Coord ceil(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz+1 (node centered conversion)...
Definition: Coord.h:63
std::size_t operator()(const Coord &ijk) const noexcept
Definition: Coord.h:597
bool operator==(const CoordBBox &rhs) const
Definition: Coord.h:354
bool is_divisible() const
Return true if this bounding box can be subdivided [mainly for use by TBB].
Definition: Coord.h:393
uint32_t Index32
Definition: Types.h:52
Coord operator-(const Coord &rhs) const
Definition: Coord.h:115
CoordBBox(const Coord &min, const Coord &max)
Construct a bounding box with the given min and max bounds.
Definition: Coord.h:298
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212
void resetToCube(const Coord &min, ValueType dim)
Definition: Coord.h:331
static Coord round(const Vec3< T > &xyz)
Return xyz rounded to the closest integer coordinates (cell centered conversion). ...
Definition: Coord.h:50
XYZIterator beginXYZ() const
Return an XYZ-order iterator that points to the minimum coordinate.
Definition: Coord.h:345