HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Coord.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 #ifndef OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
33 
34 #include <algorithm> // for std::min(), std::max()
35 #include <array> // for std::array
36 #include <iostream>
37 #include <limits>
38 #include <openvdb/Platform.h>
39 #include "Math.h"
40 #include "Vec3.h"
41 
42 namespace tbb { class split; } // forward declaration
43 
44 
45 namespace openvdb {
47 namespace OPENVDB_VERSION_NAME {
48 namespace math {
49 
50 /// @brief Signed (x, y, z) 32-bit integer coordinates
51 class Coord
52 {
53 public:
54  using Int32 = int32_t;
55  using Index32 = uint32_t;
56  using Vec3i = Vec3<Int32>;
58 
59  using ValueType = Int32;
60  using Limits = std::numeric_limits<ValueType>;
61 
62  Coord(): mVec{{0, 0, 0}} {}
63  explicit Coord(Int32 xyz): mVec{{xyz, xyz, xyz}} {}
64  Coord(Int32 x, Int32 y, Int32 z): mVec{{x, y, z}} {}
65  explicit Coord(const Vec3i& v): mVec{{v[0], v[1], v[2]}} {}
66  explicit Coord(const Vec3I& v): mVec{{Int32(v[0]), Int32(v[1]), Int32(v[2])}} {}
67  explicit Coord(const Int32* v): mVec{{v[0], v[1], v[2]}} {}
68 
69  /// @brief Return the smallest possible coordinate
70  static Coord min() { return Coord(Limits::min()); }
71 
72  /// @brief Return the largest possible coordinate
73  static Coord max() { return Coord(Limits::max()); }
74 
75  /// @brief Return @a xyz rounded to the closest integer coordinates
76  /// (cell centered conversion).
77  template<typename T> static Coord round(const Vec3<T>& xyz)
78  {
79  return Coord(Int32(Round(xyz[0])), Int32(Round(xyz[1])), Int32(Round(xyz[2])));
80  }
81  /// @brief Return the largest integer coordinates that are not greater
82  /// than @a xyz (node centered conversion).
83  template<typename T> static Coord floor(const Vec3<T>& xyz)
84  {
85  return Coord(Int32(Floor(xyz[0])), Int32(Floor(xyz[1])), Int32(Floor(xyz[2])));
86  }
87 
88  /// @brief Return the largest integer coordinates that are not greater
89  /// than @a xyz+1 (node centered conversion).
90  template<typename T> static Coord ceil(const Vec3<T>& xyz)
91  {
92  return Coord(Int32(Ceil(xyz[0])), Int32(Ceil(xyz[1])), Int32(Ceil(xyz[2])));
93  }
94 
95  /// @brief Reset all three coordinates with the specified arguments
96  Coord& reset(Int32 x, Int32 y, Int32 z)
97  {
98  mVec[0] = x;
99  mVec[1] = y;
100  mVec[2] = z;
101  return *this;
102  }
103  /// @brief Reset all three coordinates with the same specified argument
104  Coord& reset(Int32 xyz) { return this->reset(xyz, xyz, xyz); }
105 
106  Coord& setX(Int32 x) { mVec[0] = x; return *this; }
107  Coord& setY(Int32 y) { mVec[1] = y; return *this; }
108  Coord& setZ(Int32 z) { mVec[2] = z; return *this; }
109 
110  Coord& offset(Int32 dx, Int32 dy, Int32 dz)
111  {
112  mVec[0] += dx;
113  mVec[1] += dy;
114  mVec[2] += dz;
115  return *this;
116  }
117  Coord& offset(Int32 n) { return this->offset(n, n, n); }
118  Coord offsetBy(Int32 dx, Int32 dy, Int32 dz) const
119  {
120  return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
121  }
122  Coord offsetBy(Int32 n) const { return offsetBy(n, n, n); }
123 
124  Coord& operator+=(const Coord& rhs)
125  {
126  mVec[0] += rhs[0];
127  mVec[1] += rhs[1];
128  mVec[2] += rhs[2];
129  return *this;
130  }
131  Coord& operator-=(const Coord& rhs)
132  {
133  mVec[0] -= rhs[0];
134  mVec[1] -= rhs[1];
135  mVec[2] -= rhs[2];
136  return *this;
137  }
138  Coord operator+(const Coord& rhs) const
139  {
140  return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]);
141  }
142  Coord operator-(const Coord& rhs) const
143  {
144  return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]);
145  }
146  Coord operator-() const { return Coord(-mVec[0], -mVec[1], -mVec[2]); }
147 
148  Coord operator>> (size_t n) const { return Coord(mVec[0]>>n, mVec[1]>>n, mVec[2]>>n); }
149  Coord operator<< (size_t n) const { return Coord(mVec[0]<<n, mVec[1]<<n, mVec[2]<<n); }
150  Coord& operator<<=(size_t n) { mVec[0]<<=n; mVec[1]<<=n; mVec[2]<<=n; return *this; }
151  Coord& operator>>=(size_t n) { mVec[0]>>=n; mVec[1]>>=n; mVec[2]>>=n; return *this; }
152  Coord operator& (Int32 n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
153  Coord operator| (Int32 n) const { return Coord(mVec[0] | n, mVec[1] | n, mVec[2] | n); }
154  Coord& operator&= (Int32 n) { mVec[0]&=n; mVec[1]&=n; mVec[2]&=n; return *this; }
155  Coord& operator|= (Int32 n) { mVec[0]|=n; mVec[1]|=n; mVec[2]|=n; return *this; }
156 
157  Int32 x() const { return mVec[0]; }
158  Int32 y() const { return mVec[1]; }
159  Int32 z() const { return mVec[2]; }
160  Int32 operator[](size_t i) const { assert(i < 3); return mVec[i]; }
161  Int32& x() { return mVec[0]; }
162  Int32& y() { return mVec[1]; }
163  Int32& z() { return mVec[2]; }
164  Int32& operator[](size_t i) { assert(i < 3); return mVec[i]; }
165 
166  const Int32* data() const { return mVec.data(); }
167  Int32* data() { return mVec.data(); }
168  const Int32* asPointer() const { return mVec.data(); }
169  Int32* asPointer() { return mVec.data(); }
170  Vec3d asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
171  Vec3s asVec3s() const { return Vec3s(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
172  Vec3i asVec3i() const { return Vec3i(mVec.data()); }
173  Vec3I asVec3I() const { return Vec3I(Index32(mVec[0]), Index32(mVec[1]), Index32(mVec[2])); }
174  void asXYZ(Int32& x, Int32& y, Int32& z) const { x = mVec[0]; y = mVec[1]; z = mVec[2]; }
175 
176  bool operator==(const Coord& rhs) const
177  {
178  return (mVec[0] == rhs.mVec[0] && mVec[1] == rhs.mVec[1] && mVec[2] == rhs.mVec[2]);
179  }
180  bool operator!=(const Coord& rhs) const { return !(*this == rhs); }
181 
182  /// Lexicographic less than
183  bool operator<(const Coord& rhs) const
184  {
185  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
186  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
187  : this->z() < rhs.z() ? true : false;
188  }
189  /// Lexicographic less than or equal to
190  bool operator<=(const Coord& rhs) const
191  {
192  return this->x() < rhs.x() ? true : this->x() > rhs.x() ? false
193  : this->y() < rhs.y() ? true : this->y() > rhs.y() ? false
194  : this->z() <=rhs.z() ? true : false;
195  }
196  /// Lexicographic greater than
197  bool operator>(const Coord& rhs) const { return !(*this <= rhs); }
198  /// Lexicographic greater than or equal to
199  bool operator>=(const Coord& rhs) const { return !(*this < rhs); }
200 
201  /// Perform a component-wise minimum with the other Coord.
202  void minComponent(const Coord& other)
203  {
204  mVec[0] = std::min(mVec[0], other.mVec[0]);
205  mVec[1] = std::min(mVec[1], other.mVec[1]);
206  mVec[2] = std::min(mVec[2], other.mVec[2]);
207  }
208 
209  /// Perform a component-wise maximum with the other Coord.
210  void maxComponent(const Coord& other)
211  {
212  mVec[0] = std::max(mVec[0], other.mVec[0]);
213  mVec[1] = std::max(mVec[1], other.mVec[1]);
214  mVec[2] = std::max(mVec[2], other.mVec[2]);
215  }
216 
217  /// Return the component-wise minimum of the two Coords.
218  static inline Coord minComponent(const Coord& lhs, const Coord& rhs)
219  {
220  return Coord(std::min(lhs.x(), rhs.x()),
221  std::min(lhs.y(), rhs.y()),
222  std::min(lhs.z(), rhs.z()));
223  }
224 
225  /// Return the component-wise maximum of the two Coords.
226  static inline Coord maxComponent(const Coord& lhs, const Coord& rhs)
227  {
228  return Coord(std::max(lhs.x(), rhs.x()),
229  std::max(lhs.y(), rhs.y()),
230  std::max(lhs.z(), rhs.z()));
231  }
232 
233  /// Return true if any of the components of @a a are smaller than the
234  /// corresponding components of @a b.
235  static inline bool lessThan(const Coord& a, const Coord& b)
236  {
237  return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
238  }
239 
240  /// @brief Return the index (0, 1 or 2) with the smallest value.
241  size_t minIndex() const { return MinIndex(mVec); }
242 
243  /// @brief Return the index (0, 1 or 2) with the largest value.
244  size_t maxIndex() const { return MaxIndex(mVec); }
245 
246  void read(std::istream& is) { is.read(reinterpret_cast<char*>(mVec.data()), sizeof(mVec)); }
247  void write(std::ostream& os) const
248  {
249  os.write(reinterpret_cast<const char*>(mVec.data()), sizeof(mVec));
250  }
251 
252 private:
253  std::array<Int32, 3> mVec;
254 }; // class Coord
255 
256 
257 ////////////////////////////////////////
258 
259 
260 /// @brief Axis-aligned bounding box of signed integer coordinates
261 /// @note The range of the integer coordinates, [min, max], is inclusive.
262 /// Thus, a bounding box with min = max is not empty but rather encloses
263 /// a single coordinate.
265 {
266 public:
267  using Index64 = uint64_t;
269 
270  /// @brief Iterator over the Coord domain covered by a CoordBBox
271  /// @note If ZYXOrder is @c true, @e z is the fastest-moving coordinate,
272  /// otherwise the traversal is in XYZ order (i.e., @e x is fastest-moving).
273  template<bool ZYXOrder>
274  class Iterator
275  {
276  public:
277  /// @brief C-tor from a bounding box
278  Iterator(const CoordBBox& b): mPos(b.min()), mMin(b.min()), mMax(b.max()) {}
279  /// @brief Increment the iterator to point to the next coordinate.
280  /// @details Iteration stops one past the maximum coordinate
281  /// along the axis determined by the template parameter.
282  Iterator& operator++() { ZYXOrder ? next<2,1,0>() : next<0,1,2>(); return *this; }
283  /// @brief Return @c true if the iterator still points to a valid coordinate.
284  operator bool() const { return ZYXOrder ? (mPos[0] <= mMax[0]) : (mPos[2] <= mMax[2]); }
285  /// @brief Return a const reference to the coordinate currently pointed to.
286  const Coord& operator*() const { return mPos; }
287  /// Return @c true if this iterator and the given iterator point to the same coordinate.
288  bool operator==(const Iterator& other) const
289  {
290  return ((mPos == other.mPos) && (mMin == other.mMin) && (mMax == other.mMax));
291  }
292  /// Return @c true if this iterator and the given iterator point to different coordinates.
293  bool operator!=(const Iterator& other) const { return !(*this == other); }
294  private:
295  template<size_t a, size_t b, size_t c>
296  void next()
297  {
298  if (mPos[a] < mMax[a]) { ++mPos[a]; } // this is the most common case
299  else if (mPos[b] < mMax[b]) { mPos[a] = mMin[a]; ++mPos[b]; }
300  else if (mPos[c] <= mMax[c]) { mPos[a] = mMin[a]; mPos[b] = mMin[b]; ++mPos[c]; }
301  }
302  Coord mPos, mMin, mMax;
303  friend class CoordBBox; // for CoordBBox::end()
304  };// CoordBBox::Iterator
305 
306  using ZYXIterator = Iterator</*ZYX=*/true>;
307  using XYZIterator = Iterator</*ZYX=*/false>;
308 
309  /// @brief The default constructor produces an empty bounding box.
310  CoordBBox(): mMin(Coord::max()), mMax(Coord::min()) {}
311  /// @brief Construct a bounding box with the given @a min and @a max bounds.
312  CoordBBox(const Coord& min, const Coord& max): mMin(min), mMax(max) {}
313  /// @brief Construct from individual components of the min and max bounds.
315  ValueType xMax, ValueType yMax, ValueType zMax)
316  : mMin(xMin, yMin, zMin), mMax(xMax, yMax, zMax)
317  {
318  }
319  /// @brief Splitting constructor for use in TBB ranges
320  /// @note The other bounding box is assumed to be divisible.
321  CoordBBox(CoordBBox& other, const tbb::split&): mMin(other.mMin), mMax(other.mMax)
322  {
323  assert(this->is_divisible());
324  const size_t n = this->maxExtent();
325  mMax[n] = (mMin[n] + mMax[n]) >> 1;
326  other.mMin[n] = mMax[n] + 1;
327  }
328 
330  {
331  return CoordBBox(min, min.offsetBy(dim - 1));
332  }
333 
334  /// Return an "infinite" bounding box, as defined by the Coord value range.
335  static CoordBBox inf() { return CoordBBox(Coord::min(), Coord::max()); }
336 
337  const Coord& min() const { return mMin; }
338  const Coord& max() const { return mMax; }
339 
340  Coord& min() { return mMin; }
341  Coord& max() { return mMax; }
342 
343  void reset() { mMin = Coord::max(); mMax = Coord::min(); }
344  void reset(const Coord& min, const Coord& max) { mMin = min; mMax = max; }
345  void resetToCube(const Coord& min, ValueType dim) { mMin = min; mMax = min.offsetBy(dim - 1); }
346 
347  /// @brief Return the minimum coordinate.
348  /// @note The start coordinate is inclusive.
349  Coord getStart() const { return mMin; }
350  /// @brief Return the maximum coordinate plus one.
351  /// @note This end coordinate is exclusive.
352  Coord getEnd() const { return mMax.offsetBy(1); }
353 
354  /// @brief Return a ZYX-order iterator that points to the minimum coordinate.
355  ZYXIterator begin() const { return ZYXIterator{*this}; }
356  /// @brief Return a ZYX-order iterator that points to the minimum coordinate.
357  ZYXIterator beginZYX() const { return ZYXIterator{*this}; }
358  /// @brief Return an XYZ-order iterator that points to the minimum coordinate.
359  XYZIterator beginXYZ() const { return XYZIterator{*this}; }
360 
361  /// @brief Return a ZYX-order iterator that points past the maximum coordinate.
362  ZYXIterator end() const { ZYXIterator it{*this}; it.mPos[0] = mMax[0] + 1; return it; }
363  /// @brief Return a ZYX-order iterator that points past the maximum coordinate.
364  ZYXIterator endZYX() const { return end(); }
365  /// @brief Return an XYZ-order iterator that points past the maximum coordinate.
366  XYZIterator endXYZ() const { XYZIterator it{*this}; it.mPos[2] = mMax[2] + 1; return it; }
367 
368  bool operator==(const CoordBBox& rhs) const { return mMin == rhs.mMin && mMax == rhs.mMax; }
369  bool operator!=(const CoordBBox& rhs) const { return !(*this == rhs); }
370 
371  /// @brief Return @c true if this bounding box is empty (i.e., encloses no coordinates).
372  bool empty() const { return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]); }
373  /// Return @c true if this bounding box is nonempty (i.e., encloses at least one coordinate).
374  operator bool() const { return !this->empty(); }
375  /// Return @c true if this bounding box is nonempty (i.e., encloses at least one coordinate).
376  bool hasVolume() const { return !this->empty(); }
377 
378  /// Return the floating-point position of the center of this bounding box.
379  Vec3d getCenter() const { return 0.5 * Vec3d((mMin + mMax).asPointer()); }
380 
381  /// @brief Return the dimensions of the coordinates spanned by this bounding box.
382  /// @note Since coordinates are inclusive, a bounding box with min = max
383  /// has dimensions of (1, 1, 1).
384  Coord dim() const { return mMax.offsetBy(1) - mMin; }
385  /// @todo deprecate - use dim instead
386  Coord extents() const { return this->dim(); }
387  /// @brief Return the integer volume of coordinates spanned by this bounding box.
388  /// @note Since coordinates are inclusive, a bounding box with min = max has volume one.
389  Index64 volume() const
390  {
391  const Coord d = this->dim();
392  return Index64(d[0]) * Index64(d[1]) * Index64(d[2]);
393  }
394  /// Return @c true if this bounding box can be subdivided [mainly for use by TBB].
395  bool is_divisible() const { return mMin[0]<mMax[0] && mMin[1]<mMax[1] && mMin[2]<mMax[2]; }
396 
397  /// @brief Return the index (0, 1 or 2) of the shortest axis.
398  size_t minExtent() const { return this->dim().minIndex(); }
399 
400  /// @brief Return the index (0, 1 or 2) of the longest axis.
401  size_t maxExtent() const { return this->dim().maxIndex(); }
402 
403  /// Return @c true if point (x, y, z) is inside this bounding box.
404  bool isInside(const Coord& xyz) const
405  {
406  return !(Coord::lessThan(xyz,mMin) || Coord::lessThan(mMax,xyz));
407  }
408 
409  /// Return @c true if the given bounding box is inside this bounding box.
410  bool isInside(const CoordBBox& b) const
411  {
412  return !(Coord::lessThan(b.mMin,mMin) || Coord::lessThan(mMax,b.mMax));
413  }
414 
415  /// Return @c true if the given bounding box overlaps with this bounding box.
416  bool hasOverlap(const CoordBBox& b) const
417  {
418  return !(Coord::lessThan(mMax,b.mMin) || Coord::lessThan(b.mMax,mMin));
419  }
420 
421  /// Pad this bounding box with the specified padding.
422  void expand(ValueType padding)
423  {
424  mMin.offset(-padding);
425  mMax.offset( padding);
426  }
427 
428  /// Return a new instance that is expanded by the specified padding.
429  CoordBBox expandBy(ValueType padding) const
430  {
431  return CoordBBox(mMin.offsetBy(-padding),mMax.offsetBy(padding));
432  }
433 
434  /// Expand this bounding box to enclose point (x, y, z).
435  void expand(const Coord& xyz)
436  {
437  mMin.minComponent(xyz);
438  mMax.maxComponent(xyz);
439  }
440 
441  /// Union this bounding box with the given bounding box.
442  void expand(const CoordBBox& bbox)
443  {
444  mMin.minComponent(bbox.min());
445  mMax.maxComponent(bbox.max());
446  }
447  /// Intersect this bounding box with the given bounding box.
448  void intersect(const CoordBBox& bbox)
449  {
450  mMin.maxComponent(bbox.min());
451  mMax.minComponent(bbox.max());
452  }
453  /// @brief Union this bounding box with the cubical bounding box
454  /// of the given size and with the given minimum coordinates.
456  {
457  mMin.minComponent(min);
458  mMax.maxComponent(min.offsetBy(dim-1));
459  }
460  /// Translate this bounding box by
461  /// (<i>t<sub>x</sub></i>, <i>t<sub>y</sub></i>, <i>t<sub>z</sub></i>).
462  void translate(const Coord& t) { mMin += t; mMax += t; }
463 
464  /// @brief Populates an array with the eight corner points of this bounding box.
465  /// @details The ordering of the corner points is lexicographic.
466  /// @warning It is assumed that the pointer can be incremented at
467  /// least seven times, i.e. has storage for eight Coord elements!
468  void getCornerPoints(Coord *p) const
469  {
470  assert(p != nullptr);
471  p->reset(mMin.x(), mMin.y(), mMin.z()); ++p;
472  p->reset(mMin.x(), mMin.y(), mMax.z()); ++p;
473  p->reset(mMin.x(), mMax.y(), mMin.z()); ++p;
474  p->reset(mMin.x(), mMax.y(), mMax.z()); ++p;
475  p->reset(mMax.x(), mMin.y(), mMin.z()); ++p;
476  p->reset(mMax.x(), mMin.y(), mMax.z()); ++p;
477  p->reset(mMax.x(), mMax.y(), mMin.z()); ++p;
478  p->reset(mMax.x(), mMax.y(), mMax.z());
479  }
480 
481  //@{
482  /// @brief Bit-wise operations performed on both the min and max members
483  CoordBBox operator>> (size_t n) const { return CoordBBox(mMin>>n, mMax>>n); }
484  CoordBBox operator<< (size_t n) const { return CoordBBox(mMin<<n, mMax<<n); }
485  CoordBBox& operator<<=(size_t n) { mMin <<= n; mMax <<= n; return *this; }
486  CoordBBox& operator>>=(size_t n) { mMin >>= n; mMax >>= n; return *this; }
487  CoordBBox operator& (Coord::Int32 n) const { return CoordBBox(mMin & n, mMax & n); }
488  CoordBBox operator| (Coord::Int32 n) const { return CoordBBox(mMin | n, mMax | n); }
489  CoordBBox& operator&= (Coord::Int32 n) { mMin &= n; mMax &= n; return *this; }
490  CoordBBox& operator|= (Coord::Int32 n) { mMin |= n; mMax |= n; return *this; }
491  //@}
492 
493  /// Unserialize this bounding box from the given stream.
494  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
495  /// Serialize this bounding box to the given stream.
496  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
497 
498 private:
499  Coord mMin, mMax;
500 }; // class CoordBBox
501 
502 
503 ////////////////////////////////////////
504 
505 
506 inline std::ostream& operator<<(std::ostream& os, const Coord& xyz)
507 {
508  os << xyz.asVec3i(); return os;
509 }
510 
511 
512 inline Coord
513 Abs(const Coord& xyz)
514 {
515  return Coord(Abs(xyz[0]), Abs(xyz[1]), Abs(xyz[2]));
516 }
517 
518 
519 //@{
520 /// Allow a Coord to be added to or subtracted from a Vec3.
521 template<typename T>
523 operator+(const Vec3<T>& v0, const Coord& v1)
524 {
526  result[0] += v1[0];
527  result[1] += v1[1];
528  result[2] += v1[2];
529  return result;
530 }
531 
532 template<typename T>
534 operator+(const Coord& v1, const Vec3<T>& v0)
535 {
537  result[0] += v1[0];
538  result[1] += v1[1];
539  result[2] += v1[2];
540  return result;
541 }
542 //@}
543 
544 
545 //@{
546 /// Allow a Coord to be subtracted from a Vec3.
547 template <typename T>
549 operator-(const Vec3<T>& v0, const Coord& v1)
550 {
552  result[0] -= v1[0];
553  result[1] -= v1[1];
554  result[2] -= v1[2];
555  return result;
556 }
557 
558 template <typename T>
560 operator-(const Coord& v1, const Vec3<T>& v0)
561 {
563  result[0] -= v1[0];
564  result[1] -= v1[1];
565  result[2] -= v1[2];
566  return -result;
567 }
568 //@}
569 
570 inline std::ostream&
571 operator<<(std::ostream& os, const CoordBBox& b)
572 {
573  os << b.min() << " -> " << b.max();
574  return os;
575 }
576 
577 } // namespace math
578 } // namespace OPENVDB_VERSION_NAME
579 } // namespace openvdb
580 
581 #endif // OPENVDB_MATH_COORD_HAS_BEEN_INCLUDED
582 
583 // Copyright (c) 2012-2018 DreamWorks Animation LLC
584 // All rights reserved. This software is distributed under the
585 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:530
void expand(const CoordBBox &bbox)
Union this bounding box with the given bounding box.
Definition: Coord.h:442
CoordBBox & operator<<=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:485
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:810
bool operator==(const Iterator &other) const
Return true if this iterator and the given iterator point to the same coordinate. ...
Definition: Coord.h:288
Coord getEnd() const
Return the maximum coordinate plus one.
Definition: Coord.h:352
Vec3d getCenter() const
Return the floating-point position of the center of this bounding box.
Definition: Coord.h:379
void expand(const Coord &xyz)
Expand this bounding box to enclose point (x, y, z).
Definition: Coord.h:435
static CoordBBox createCube(const Coord &min, ValueType dim)
Definition: Coord.h:329
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:911
const GLdouble * v
Definition: glcorearb.h:836
HALF_EXPORT std::istream & operator>>(std::istream &is, half &h)
Coord dim() const
Return the dimensions of the coordinates spanned by this bounding box.
Definition: Coord.h:384
bool hasVolume() const
Return true if this bounding box is nonempty (i.e., encloses at least one coordinate).
Definition: Coord.h:376
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:549
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
void intersect(const CoordBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition: Coord.h:448
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
void getCornerPoints(Coord *p) const
Populates an array with the eight corner points of this bounding box.
Definition: Coord.h:468
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:189
CoordBBox operator|(Coord::Int32 n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:488
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: Coord.h:398
GLint y
Definition: glcorearb.h:102
Iterator over the Coord domain covered by a CoordBBox.
Definition: Coord.h:274
bool empty() const
Return true if this bounding box is empty (i.e., encloses no coordinates).
Definition: Coord.h:372
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
void read(T &in, bool &v)
Definition: ImfXdr.h:611
png_uint_32 i
Definition: png.h:2877
std::numeric_limits< ValueType > Limits
Definition: Coord.h:60
void reset(const Coord &min, const Coord &max)
Definition: Coord.h:344
void resetToCube(const Coord &min, ValueType dim)
Definition: Coord.h:345
CoordBBox expandBy(ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition: Coord.h:429
CoordBBox()
The default constructor produces an empty bounding box.
Definition: Coord.h:310
bool operator!=(const Iterator &other) const
Return true if this iterator and the given iterator point to different coordinates.
Definition: Coord.h:293
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:455
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:335
ZYXIterator begin() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:355
GLdouble n
Definition: glcorearb.h:2007
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:890
bool operator==(const CoordBBox &rhs) const
Definition: Coord.h:368
bool hasOverlap(const CoordBBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition: Coord.h:416
CoordBBox operator&(Coord::Int32 n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:487
Coord Abs(const Coord &xyz)
Definition: Coord.h:513
CoordBBox & operator&=(Coord::Int32 n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:489
Index64 volume() const
Return the integer volume of coordinates spanned by this bounding box.
Definition: Coord.h:389
bool operator<=(const TfRefPtr< T > &p, std::nullptr_t)
Definition: refPtr.h:1223
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:773
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
CoordBBox(const Coord &min, const Coord &max)
Construct a bounding box with the given min and max bounds.
Definition: Coord.h:312
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:494
GLintptr offset
Definition: glcorearb.h:664
Iterator(const CoordBBox &b)
C-tor from a bounding box.
Definition: Coord.h:278
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: Coord.h:496
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:264
CoordBBox operator<<(size_t n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:484
bool is_divisible() const
Return true if this bounding box can be subdivided [mainly for use by TBB].
Definition: Coord.h:395
GLboolean * data
Definition: glcorearb.h:130
bool isInside(const Coord &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: Coord.h:404
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: Coord.h:401
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:219
Coord getStart() const
Return the minimum coordinate.
Definition: Coord.h:349
void expand(ValueType padding)
Pad this bounding box with the specified padding.
Definition: Coord.h:422
int floor(T x)
Definition: ImathFun.h:150
GLfloat v0
Definition: glcorearb.h:815
Iterator & operator++()
Increment the iterator to point to the next coordinate.
Definition: Coord.h:282
CoordBBox & operator>>=(size_t n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:486
ZYXIterator end() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:362
bool operator!=(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Inequality operator, does exact floating point comparisons.
Definition: Vec3.h:496
CoordBBox operator>>(size_t n) const
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:483
XYZIterator beginXYZ() const
Return an XYZ-order iterator that points to the minimum coordinate.
Definition: Coord.h:359
XYZIterator endXYZ() const
Return an XYZ-order iterator that points past the maximum coordinate.
Definition: Coord.h:366
ZYXIterator beginZYX() const
Return a ZYX-order iterator that points to the minimum coordinate.
Definition: Coord.h:357
bool operator!=(const CoordBBox &rhs) const
Definition: Coord.h:369
GLint GLenum GLint x
Definition: glcorearb.h:408
GLfloat GLfloat v1
Definition: glcorearb.h:816
Vec2< T > maxComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise maximum of the two vectors.
Definition: Vec2.h:539
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:523
int Floor(float x)
Return the floor of x.
Definition: Math.h:802
bool operator>=(const TfRefPtr< T > &p, std::nullptr_t)
Definition: refPtr.h:1245
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:314
int ceil(T x)
Definition: ImathFun.h:158
bool isInside(const CoordBBox &b) const
Return true if the given bounding box is inside this bounding box.
Definition: Coord.h:410
void write(T &out, bool v)
Definition: ImfXdr.h:332
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:135
ZYXIterator endZYX() const
Return a ZYX-order iterator that points past the maximum coordinate.
Definition: Coord.h:364
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:488
CoordBBox & operator|=(Coord::Int32 n)
Bit-wise operations performed on both the min and max members.
Definition: Coord.h:490
CoordBBox(CoordBBox &other, const tbb::split &)
Splitting constructor for use in TBB ranges.
Definition: Coord.h:321
const Coord & operator*() const
Return a const reference to the coordinate currently pointed to.
Definition: Coord.h:286
std::ostream & operator<<(std::ostream &os, const BBox< Vec3T > &b)
Definition: BBox.h:440
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:207