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