HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BBox.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_BBOX_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
33 
34 #include "Math.h" // for math::isApproxEqual() and math::Tolerance()
35 #include "Vec3.h"
36 #include <algorithm> // for std::min(), std::max()
37 #include <cmath> // for std::abs()
38 #include <iostream>
39 #include <limits>
40 #include <type_traits>
41 
42 
43 namespace openvdb {
45 namespace OPENVDB_VERSION_NAME {
46 namespace math {
47 
48 /// @brief Axis-aligned bounding box
49 template<typename Vec3T>
50 class BBox
51 {
52 public:
53  using Vec3Type = Vec3T;
54  using ValueType = Vec3T;
55  using VectorType = Vec3T;
56  using ElementType = typename Vec3Type::ValueType;
57 
58  /// @brief The default constructor creates an invalid bounding box.
59  BBox();
60  /// @brief Construct a bounding box that exactly encloses the given
61  /// minimum and maximum points.
62  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax);
63  /// @brief Construct a bounding box that exactly encloses the given
64  /// minimum and maximum points.
65  /// @details If @a sorted is false, sort the points by their
66  /// @e x, @e y and @e z components.
67  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted);
68  /// @brief Contruct a cubical bounding box from a minimum coordinate
69  /// and an edge length.
70  /// @note Inclusive for integral <b>ElementType</b>s
71  BBox(const Vec3T& xyzMin, const ElementType& length);
72 
73  /// @brief Construct a bounding box that exactly encloses two points,
74  /// whose coordinates are given by an array of six values,
75  /// <i>x<sub>1</sub></i>, <i>y<sub>1</sub></i>, <i>z<sub>1</sub></i>,
76  /// <i>x<sub>2</sub></i>, <i>y<sub>2</sub></i> and <i>z<sub>2</sub></i>.
77  /// @details If @a sorted is false, sort the points by their
78  /// @e x, @e y and @e z components.
79  explicit BBox(const ElementType* xyz, bool sorted = true);
80 
81  BBox(const BBox&) = default;
82  BBox& operator=(const BBox&) = default;
83 
84  /// @brief Sort the mininum and maximum points of this bounding box
85  /// by their @e x, @e y and @e z components.
86  void sort();
87 
88  /// @brief Return a const reference to the minimum point of this bounding box.
89  const Vec3T& min() const { return mMin; }
90  /// @brief Return a const reference to the maximum point of this bounding box.
91  const Vec3T& max() const { return mMax; }
92  /// @brief Return a non-const reference to the minimum point of this bounding box.
93  Vec3T& min() { return mMin; }
94  /// @brief Return a non-const reference to the maximum point of this bounding box.
95  Vec3T& max() { return mMax; }
96 
97  /// @brief Return @c true if this bounding box is identical to the given bounding box.
98  bool operator==(const BBox& rhs) const;
99  /// @brief Return @c true if this bounding box differs from the given bounding box.
100  bool operator!=(const BBox& rhs) const { return !(*this == rhs); }
101 
102  /// @brief Return @c true if this bounding box is empty, i.e., it has no (positive) volume.
103  bool empty() const;
104  /// @brief Return @c true if this bounding box has (positive) volume.
105  bool hasVolume() const { return !this->empty(); }
106  /// @brief Return @c true if this bounding box has (positive) volume.
107  operator bool() const { return !this->empty(); }
108 
109  /// @brief Return @c true if all components of the minimum point are less than
110  /// or equal to the corresponding components of the maximum point.
111  /// @details This is equivalent to testing whether this bounding box has nonnegative volume.
112  /// @note For floating-point <b>ElementType</b>s a tolerance is used for this test.
113  bool isSorted() const;
114 
115  /// @brief Return the center point of this bounding box.
116  Vec3d getCenter() const;
117 
118  /// @brief Return the extents of this bounding box, i.e., the length along each axis.
119  /// @note Inclusive for integral <b>ElementType</b>s
120  Vec3T extents() const;
121  /// @brief Return the index (0, 1 or 2) of the longest axis.
122  size_t maxExtent() const { return MaxIndex(mMax - mMin); }
123  /// @brief Return the index (0, 1 or 2) of the shortest axis.
124  size_t minExtent() const { return MinIndex(mMax - mMin); }
125 
126  /// @brief Return the volume enclosed by this bounding box.
127  ElementType volume() const { Vec3T e = this->extents(); return e[0] * e[1] * e[2]; }
128 
129  /// @brief Return @c true if the given point is inside this bounding box.
130  bool isInside(const Vec3T& xyz) const;
131  /// @brief Return @c true if the given bounding box is inside this bounding box.
132  bool isInside(const BBox&) const;
133  /// @brief Return @c true if the given bounding box overlaps with this bounding box.
134  bool hasOverlap(const BBox&) const;
135  /// @brief Return @c true if the given bounding box overlaps with this bounding box.
136  bool intersects(const BBox& other) const { return hasOverlap(other); }
137 
138  /// @brief Pad this bounding box.
139  void expand(ElementType padding);
140  /// @brief Expand this bounding box to enclose the given point.
141  void expand(const Vec3T& xyz);
142  /// @brief Union this bounding box with the given bounding box.
143  void expand(const BBox&);
144  /// @brief Union this bounding box with the cubical bounding box with
145  /// minimum point @a xyzMin and the given edge length.
146  /// @note Inclusive for integral <b>ElementType</b>s
147  void expand(const Vec3T& xyzMin, const ElementType& length);
148 
149  /// @brief Translate this bounding box by
150  /// (<i>t<sub>x</sub></i>, <i>t<sub>y</sub></i>, <i>t<sub>z</sub></i>).
151  void translate(const Vec3T& t);
152 
153  /// @brief Apply a map to this bounding box.
154  template<typename MapType>
155  BBox applyMap(const MapType& map) const;
156  /// @brief Apply the inverse of a map to this bounding box
157  template<typename MapType>
158  BBox applyInverseMap(const MapType& map) const;
159 
160  /// @brief Unserialize this bounding box from the given stream.
161  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
162  /// @brief Serialize this bounding box to the given stream.
163  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
164 
165 private:
166  Vec3T mMin, mMax;
167 }; // class BBox
168 
169 
170 ////////////////////////////////////////
171 
172 
173 template<typename Vec3T>
174 inline
176  mMin( std::numeric_limits<ElementType>::max()),
177  mMax(-std::numeric_limits<ElementType>::max())
178 {
179 }
180 
181 template<typename Vec3T>
182 inline
183 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax):
184  mMin(xyzMin), mMax(xyzMax)
185 {
186 }
187 
188 template<typename Vec3T>
189 inline
190 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted):
191  mMin(xyzMin), mMax(xyzMax)
192 {
193  if (!sorted) this->sort();
194 }
195 
196 template<typename Vec3T>
197 inline
198 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length):
199  mMin(xyzMin), mMax(xyzMin)
200 {
201  // min and max are inclusive for integral ElementType
203  mMax[0] += size;
204  mMax[1] += size;
205  mMax[2] += size;
206 }
207 
208 template<typename Vec3T>
209 inline
210 BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted):
211  mMin(xyz[0], xyz[1], xyz[2]),
212  mMax(xyz[3], xyz[4], xyz[5])
213 {
214  if (!sorted) this->sort();
215 }
216 
217 
218 ////////////////////////////////////////
219 
220 
221 template<typename Vec3T>
222 inline bool
224 {
226  // min and max are inclusive for integral ElementType
227  return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
228  }
229  return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2];
230 }
231 
232 
233 template<typename Vec3T>
234 inline bool
235 BBox<Vec3T>::operator==(const BBox& rhs) const
236 {
238  return mMin == rhs.min() && mMax == rhs.max();
239  } else {
240  return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max());
241  }
242 }
243 
244 
245 template<typename Vec3T>
246 inline void
248 {
249  Vec3T tMin(mMin), tMax(mMax);
250  for (int i = 0; i < 3; ++i) {
251  mMin[i] = std::min(tMin[i], tMax[i]);
252  mMax[i] = std::max(tMin[i], tMax[i]);
253  }
254 }
255 
256 
257 template<typename Vec3T>
258 inline bool
260 {
262  return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
263  } else {
265  return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
266  }
267 }
268 
269 
270 template<typename Vec3T>
271 inline Vec3d
273 {
274  return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
275 }
276 
277 
278 template<typename Vec3T>
279 inline Vec3T
281 {
283  return (mMax - mMin) + Vec3T(1, 1, 1);
284  } else {
285  return (mMax - mMin);
286  }
287 }
288 
289 ////////////////////////////////////////
290 
291 
292 template<typename Vec3T>
293 inline bool
294 BBox<Vec3T>::isInside(const Vec3T& xyz) const
295 {
297  return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
298  xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
299  xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
300  } else {
302  return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
303  xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
304  xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
305  }
306 }
307 
308 
309 template<typename Vec3T>
310 inline bool
312 {
314  return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
315  b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
316  b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
317  } else {
319  return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
320  (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
321  (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
322  }
323 }
324 
325 
326 template<typename Vec3T>
327 inline bool
329 {
331  return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
332  mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
333  mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
334  } else {
336  return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
337  mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
338  mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
339  }
340 }
341 
342 
343 ////////////////////////////////////////
344 
345 
346 template<typename Vec3T>
347 inline void
349 {
350  dx = std::abs(dx);
351  for (int i = 0; i < 3; ++i) {
352  mMin[i] -= dx;
353  mMax[i] += dx;
354  }
355 }
356 
357 
358 template<typename Vec3T>
359 inline void
360 BBox<Vec3T>::expand(const Vec3T& xyz)
361 {
362  for (int i = 0; i < 3; ++i) {
363  mMin[i] = std::min(mMin[i], xyz[i]);
364  mMax[i] = std::max(mMax[i], xyz[i]);
365  }
366 }
367 
368 
369 template<typename Vec3T>
370 inline void
372 {
373  for (int i = 0; i < 3; ++i) {
374  mMin[i] = std::min(mMin[i], b.min()[i]);
375  mMax[i] = std::max(mMax[i], b.max()[i]);
376  }
377 }
378 
379 template<typename Vec3T>
380 inline void
381 BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length)
382 {
384  for (int i = 0; i < 3; ++i) {
385  mMin[i] = std::min(mMin[i], xyzMin[i]);
386  mMax[i] = std::max(mMax[i], xyzMin[i] + size);
387  }
388 }
389 
390 
391 template<typename Vec3T>
392 inline void
393 BBox<Vec3T>::translate(const Vec3T& dx)
394 {
395  mMin += dx;
396  mMax += dx;
397 }
398 
399 template<typename Vec3T>
400 template<typename MapType>
401 inline BBox<Vec3T>
402 BBox<Vec3T>::applyMap(const MapType& map) const
403 {
404  using Vec3R = Vec3<double>;
405  BBox<Vec3T> bbox;
406  bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMin[2])));
407  bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMax[2])));
408  bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMin[2])));
409  bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMin[2])));
410  bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMin[2])));
411  bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMax[2])));
412  bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMax[2])));
413  bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMax[2])));
414  return bbox;
415 }
416 
417 template<typename Vec3T>
418 template<typename MapType>
419 inline BBox<Vec3T>
420 BBox<Vec3T>::applyInverseMap(const MapType& map) const
421 {
422  using Vec3R = Vec3<double>;
423  BBox<Vec3T> bbox;
424  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMin[2])));
425  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMax[2])));
426  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMin[2])));
427  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMin[2])));
428  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMin[2])));
429  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMax[2])));
430  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMax[2])));
431  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMax[2])));
432  return bbox;
433 }
434 
435 ////////////////////////////////////////
436 
437 
438 template<typename Vec3T>
439 inline std::ostream&
440 operator<<(std::ostream& os, const BBox<Vec3T>& b)
441 {
442  os << b.min() << " -> " << b.max();
443  return os;
444 }
445 
446 } // namespace math
447 } // namespace OPENVDB_VERSION_NAME
448 } // namespace openvdb
449 
450 #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
451 
452 // Copyright (c) 2012-2018 DreamWorks Animation LLC
453 // All rights reserved. This software is distributed under the
454 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: BBox.h:124
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:911
void translate(const Vec3T &t)
Translate this bounding box by (tx, ty, tz).
Definition: BBox.h:393
Vec3T & max()
Return a non-const reference to the maximum point of this bounding box.
Definition: BBox.h:95
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:189
void expand(ElementType padding)
Pad this bounding box.
Definition: BBox.h:348
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: BBox.h:122
png_uint_32 i
Definition: png.h:2877
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:161
GLsizeiptr size
Definition: glcorearb.h:663
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: BBox.h:163
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:890
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER T abs(T a)
Definition: ImathFun.h:55
const Vec3T & min() const
Return a const reference to the minimum point of this bounding box.
Definition: BBox.h:89
BBox applyMap(const MapType &map) const
Apply a map to this bounding box.
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
BBox applyInverseMap(const MapType &map) const
Apply the inverse of a map to this bounding box.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool operator!=(const BBox &rhs) const
Return true if this bounding box differs from the given bounding box.
Definition: BBox.h:100
bool empty() const
Return true if this bounding box is empty, i.e., it has no (positive) volume.
Definition: BBox.h:223
typename Vec3Type::ValueType ElementType
Definition: BBox.h:56
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
const Vec3T & max() const
Return a const reference to the maximum point of this bounding box.
Definition: BBox.h:91
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:358
Vec3T extents() const
Return the extents of this bounding box, i.e., the length along each axis.
Definition: BBox.h:280
GLsizei const GLfloat * value
Definition: glcorearb.h:823
Axis-aligned bounding box.
Definition: BBox.h:50
BBox()
The default constructor creates an invalid bounding box.
Definition: BBox.h:175
BBox & operator=(const BBox &)=default
bool intersects(const BBox &other) const
Return true if the given bounding box overlaps with this bounding box.
Definition: BBox.h:136
bool operator==(const BBox &rhs) const
Return true if this bounding box is identical to the given bounding box.
Definition: BBox.h:235
ElementType volume() const
Return the volume enclosed by this bounding box.
Definition: BBox.h:127
Vec3d getCenter() const
Return the center point of this bounding box.
Definition: BBox.h:272
Vec3T & min()
Return a non-const reference to the minimum point of this bounding box.
Definition: BBox.h:93
bool hasOverlap(const BBox &) const
Return true if the given bounding box overlaps with this bounding box.
Definition: BBox.h:328
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
bool isSorted() const
Return true if all components of the minimum point are less than or equal to the corresponding compon...
Definition: BBox.h:259
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:135
void sort()
Sort the mininum and maximum points of this bounding box by their x, y and z components.
Definition: BBox.h:247
bool hasVolume() const
Return true if this bounding box has (positive) volume.
Definition: BBox.h:105
bool isInside(const Vec3T &xyz) const
Return true if the given point is inside this bounding box.
Definition: BBox.h:294
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794