HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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.
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
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:504
void expand(const CoordBBox &bbox)
Union this bounding box with the given bounding box.
Definition: Coord.h:440
CoordBBox & operator<<=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:489
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:856
bool operator==(const Iterator &other) const
Return true if this iterator and the given iterator point to the same coordinate. ...
Definition: Coord.h:274
Coord getEnd() const
Return the maximum coordinate plus one.
Definition: Coord.h:338
OIIO_FORCEINLINE const vint4 & operator>>=(vint4 &a, const unsigned int bits)
Definition: simd.h:4532
Vec3d getCenter() const
Return the floating-point position of the center of this bounding box.
Definition: Coord.h:377
Definition: ImathVec.h:32
void expand(const Coord &xyz)
Expand this bounding box to enclose point (x, y, z).
Definition: Coord.h:433
IMATH_HOSTDEVICE constexpr int floor(T x) IMATH_NOEXCEPT
Definition: ImathFun.h:112
void translate(const Coord &t)
Translate this bounding box by (tx, ty, tz).
Definition: Coord.h:460
GLboolean * data
Definition: glcorearb.h:131
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:315
const GLdouble * v
Definition: glcorearb.h:837
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:947
openvdb::math::Coord Coord
Definition: Coord.h:594
Coord dim() const
Return the dimensions of the coordinates spanned by this bounding box.
Definition: Coord.h:382
bool hasVolume() const
Return true if this bounding box is nonempty (i.e., encloses at least one coordinate).
Definition: Coord.h:374
Vec3< typename promote< T, Coord::ValueType >::type > operator-(const Vec3< T > &v0, const Coord &v1)
Allow a Coord to be subtracted from a Vec3.
Definition: Coord.h:553
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:446
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
void getCornerPoints(Coord *p) const
Populates an array with the eight corner points of this bounding box.
Definition: Coord.h:472
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:239
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
CoordBBox operator|(Coord::Int32 n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:492
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: Coord.h:396
GLint y
Definition: glcorearb.h:103
Iterator over the Coord domain covered by a CoordBBox.
Definition: Coord.h:260
**But if you need a result
Definition: thread.h:613
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:358
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:24
std::enable_if< UT_EnableBitMask< T >::enable, T & >::type operator&=(T &lhs, T rhs)
Definition: UT_EnumHelper.h:57
void read(T &in, bool &v)
Definition: ImfXdr.h:502
std::numeric_limits< ValueType > Limits
Definition: Coord.h:33
OIIO_FORCEINLINE vbool4 operator>=(const vint4 &a, const vint4 &b)
Definition: simd.h:4577
void moveMax(const Coord &max)
Move this bounding box to the specified max.
Definition: Coord.h:466
void reset(const Coord &min, const Coord &max)
Definition: Coord.h:330
void resetToCube(const Coord &min, ValueType dim)
Definition: Coord.h:331
CoordBBox expandBy(ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition: Coord.h:427
CoordBBox()
The default constructor produces an empty bounding box.
Definition: Coord.h:296
bool operator!=(const Iterator &other) const
Return true if this iterator and the given iterator point to different coordinates.
Definition: Coord.h:279
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
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:321
ZYXIterator begin() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:341
GLdouble n
Definition: glcorearb.h:2008
OIIO_FORCEINLINE vbool4 operator<=(const vint4 &a, const vint4 &b)
Definition: simd.h:4581
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:931
GLintptr offset
Definition: glcorearb.h:665
bool operator==(const CoordBBox &rhs) const
Definition: Coord.h:354
GLboolean reset
Definition: glad.h:5138
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:414
CoordBBox operator&(Coord::Int32 n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:491
Coord Abs(const Coord &xyz)
Definition: Coord.h:517
OIIO_FORCEINLINE const vint4 & operator+=(vint4 &a, const vint4 &b)
Definition: simd.h:4369
CoordBBox & operator&=(Coord::Int32 n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:493
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:387
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
CoordBBox(const Coord &min, const Coord &max)
Construct a bounding box with the given min and max bounds.
Definition: Coord.h:298
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: Coord.h:498
Iterator(const CoordBBox &b)
C-tor from a bounding box.
Definition: Coord.h:264
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: Coord.h:500
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:250
CoordBBox operator<<(size_t n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:488
bool is_divisible() const
Return true if this bounding box can be subdivided [mainly for use by TBB].
Definition: Coord.h:393
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:402
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: Coord.h:399
OIIO_FORCEINLINE vint4 operator>>(const vint4 &a, const unsigned int bits)
Definition: simd.h:4524
vfloat4 round(const vfloat4 &a)
Definition: simd.h:7436
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:186
Coord getStart() const
Return the minimum coordinate.
Definition: Coord.h:335
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:420
GLdouble t
Definition: glad.h:2397
GLfloat v0
Definition: glcorearb.h:816
Iterator & operator++()
Increment the iterator to point to the next coordinate.
Definition: Coord.h:268
std::size_t operator()(const Coord &ijk) const noexcept
Definition: Coord.h:597
CoordBBox & operator>>=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:490
ZYXIterator end() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:348
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:481
IMATH_HOSTDEVICE constexpr int ceil(T x) IMATH_NOEXCEPT
Definition: ImathFun.h:119
CoordBBox operator>>(size_t n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:487
XYZIterator beginXYZ() const
Return an XYZ-order iterator that points to the minimum coordinate.
Definition: Coord.h:345
OIIO_FORCEINLINE const vint4 & operator<<=(vint4 &a, const unsigned int bits)
Definition: simd.h:4519
XYZIterator endXYZ() const
Return an XYZ-order iterator that points past the maximum coordinate.
Definition: Coord.h:352
void moveMin(const Coord &min)
Move this bounding box to the specified min.
Definition: Coord.h:463
ZYXIterator beginZYX() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:343
bool operator!=(const CoordBBox &rhs) const
Definition: Coord.h:355
GLfloat GLfloat v1
Definition: glcorearb.h:817
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Vec2< T > maxComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise maximum of the two vectors.
Definition: Vec2.h:513
OIIO_FORCEINLINE const vint4 & operator-=(vint4 &a, const vint4 &b)
Definition: simd.h:4392
Vec3< typename promote< T, typename Coord::ValueType >::type > operator+(const Vec3< T > &v0, const Coord &v1)
Allow a Coord to be added to or subtracted from a Vec3.
Definition: Coord.h:527
int Floor(float x)
Return the floor of x.
Definition: Math.h:848
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
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
bool isInside(const CoordBBox &b) const
Return true if the given bounding box is inside this bounding box.
Definition: Coord.h:408
void write(T &out, bool v)
Definition: ImfXdr.h:287
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:119
ZYXIterator endZYX() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:350
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:473
CoordBBox & operator|=(Coord::Int32 n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:494
CoordBBox(CoordBBox &other, const tbb::split &)
Splitting constructor for use in TBB ranges.
Definition: Coord.h:307
const Coord & operator*() const
Return a const reference to the coordinate currently pointed to.
Definition: Coord.h:272
std::enable_if< UT_EnableBitMask< T >::enable, T & >::type operator|=(T &lhs, T rhs)
Definition: UT_EnumHelper.h:37
std::ostream & operator<<(std::ostream &os, const BBox< Vec3T > &b)
Definition: BBox.h:413
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:174