HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BBox.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2017 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 <ostream>
37 #include <algorithm> // for min/max
38 #include <hboost/type_traits/is_integral.hpp>
39 
40 namespace openvdb {
42 namespace OPENVDB_VERSION_NAME {
43 namespace math {
44 
45 /// @brief Axis-aligned bounding box
46 template<typename Vec3T>
47 class BBox
48 {
49 public:
50  typedef Vec3T Vec3Type;
51  typedef Vec3T ValueType;
52  typedef Vec3T VectorType;
53  typedef typename Vec3Type::ValueType ElementType;
54 
55  /// @brief Default constructor creates an invalid BBox
56  BBox();
57 
58  /// @brief Constructor based on a minimum and maximum point.
59  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax);
60 
61  /// @brief Constructor based on a minimum and maximum point.
62  /// If sorted is false the points will be sorted by x,y,z component.
63  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted);
64 
65  /// @brief Contruct a cubical BBox from a minimum coordinate and a
66  /// single edge length.
67  /// @note inclusive for integral <tt>ElementType</tt>s
68  BBox(const Vec3T& xyzMin, const ElementType& length);
69 
70  /// @brief Constructor based on a raw array of six points. If
71  /// sorted is false the points will be sorted by x,y,z component.
72  explicit BBox(const ElementType* xyz, bool sorted = true);
73 
74  /// @brief Copy constructor
75  BBox(const BBox&) = default;
76 
77  /// @brief Assignment operator
78  BBox& operator=(const BBox&) = default;
79 
80  /// @brief Sort the min/max by x,y,z component.
81  void sort();
82 
83  /// @brief Return a const reference to the minimum point of the BBox
84  const Vec3T& min() const { return mMin; }
85 
86  /// @brief Return a const reference to the maximum point of the BBox
87  const Vec3T& max() const { return mMax; }
88 
89  /// @brief Return a non-const reference to the minimum point of the BBox
90  Vec3T& min() { return mMin; }
91 
92  /// @brief Return a non-const reference to the maximum point of the BBox
93  Vec3T& max() { return mMax; }
94 
95  /// @brief Return true if the two BBox'es are identical
96  bool operator==(const BBox& rhs) const;
97 
98  /// @brief Return true if the two BBox'es are not identical
99  bool operator!=(const BBox& rhs) const { return !(*this == rhs); }
100 
101  /// @brief Return true if the BBox is empty, i.e. has no
102  /// (positive) volume.
103  bool empty() const;
104 
105  /// @brief Return true if the BBox has a (positive) volume.
106  bool hasVolume() const { return !this->empty(); }
107 
108  /// @brief Return true if the BBox is valid, i.e. as a (positive) volume.
109  operator bool() const { return !this->empty(); }
110 
111  /// @brief Return true if the all components of mMin <= mMax,
112  /// i.e. the volume is not negative.
113  /// @note For floating point values a tolerance is used for this test.
114  bool isSorted() const;
115 
116  /// @brief Return the center point of the BBox
117  Vec3d getCenter() const;
118 
119  /// @brief Returns the extents of the BBox, i.e. the length per axis
120  /// for floating points values or number of grids per axis points
121  /// integral values.
122  /// @note inclusive for integral <tt>ElementType</tt>s
123  Vec3T extents() const;
124 
125  /// @brief Return the volume spanned by this BBox.
126  ElementType volume() const { Vec3T e = this->extents(); return e[0] * e[1] * e[2]; }
127 
128  /// Return the index (0, 1 or 2) of the longest axis.
129  size_t maxExtent() const { return MaxIndex(mMax - mMin); }
130 
131  /// Return the index (0, 1 or 2) of the shortest axis.
132  size_t minExtent() const { return MinIndex(mMax - mMin); }
133 
134  /// Return @c true if point (x, y, z) is inside this bounding box.
135  bool isInside(const Vec3T& xyz) const;
136 
137  /// Return @c true if the given bounding box is inside this bounding box.
138  bool isInside(const BBox&) const;
139 
140  /// Return @c true if the given bounding box overlaps with this bounding box.
141  bool hasOverlap(const BBox&) const;
142 
143  /// Pad this bounding box.
144  void expand(ElementType padding);
145 
146  /// Expand this bounding box to enclose point (x, y, z).
147  void expand(const Vec3T& xyz);
148 
149  /// Union this bounding box with the given bounding box.
150  void expand(const BBox&);
151  // @brief Union this bbox with the cubical bbox defined from xyzMin and
152  // length
153  /// @note inclusive for integral <tt>ElementType</tt>s
154  void expand(const Vec3T& xyzMin, const ElementType& length);
155 
156  /// Translate this bounding box by \f$(t_x, t_y, t_z)\f$.
157  void translate(const Vec3T& t);
158 
159  /// Apply a map to this bounding box
160  template<typename MapType>
161  BBox applyMap(const MapType& map) const;
162 
163  /// Apply the inverse of a map to this bounding box
164  template<typename MapType>
165  BBox applyInverseMap(const MapType& map) const;
166 
167  /// Unserialize this bounding box from the given stream.
168  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
169 
170  /// Serialize this bounding box to the given stream.
171  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
172 
173 private:
174  Vec3T mMin, mMax;
175 }; // class BBox
176 
177 
178 ////////////////////////////////////////
179 
180 
181 template<typename Vec3T>
182 inline
184  mMin( std::numeric_limits<ElementType>::max()),
185  mMax(-std::numeric_limits<ElementType>::max())
186 {
187 }
188 
189 template<typename Vec3T>
190 inline
191 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax):
192  mMin(xyzMin), mMax(xyzMax)
193 {
194 }
195 
196 template<typename Vec3T>
197 inline
198 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted):
199  mMin(xyzMin), mMax(xyzMax)
200 {
201  if (!sorted) this->sort();
202 }
203 
204 template<typename Vec3T>
205 inline
206 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length):
207  mMin(xyzMin), mMax(xyzMin)
208 {
209  // min and max are inclusive for integral ElementType
211  mMax[0] += size;
212  mMax[1] += size;
213  mMax[2] += size;
214 }
215 
216 template<typename Vec3T>
217 inline
218 BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted):
219  mMin(xyz[0], xyz[1], xyz[2]),
220  mMax(xyz[3], xyz[4], xyz[5])
221 {
222  if (!sorted) this->sort();
223 }
224 
225 
226 ////////////////////////////////////////
227 
228 
229 template<typename Vec3T>
230 inline bool
232 {
234  // min and max are inclusive for integral ElementType
235  return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
236  }
237  return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2];
238 }
239 
240 
241 template<typename Vec3T>
242 inline bool
243 BBox<Vec3T>::operator==(const BBox& rhs) const
244 {
246  return mMin == rhs.min() && mMax == rhs.max();
247  } else {
248  return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max());
249  }
250 }
251 
252 
253 template<typename Vec3T>
254 inline void
256 {
257  Vec3T tMin(mMin), tMax(mMax);
258  for (int i = 0; i < 3; ++i) {
259  mMin[i] = std::min(tMin[i], tMax[i]);
260  mMax[i] = std::max(tMin[i], tMax[i]);
261  }
262 }
263 
264 
265 template<typename Vec3T>
266 inline bool
268 {
270  return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
271  } else {
273  return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
274  }
275 }
276 
277 
278 template<typename Vec3T>
279 inline Vec3d
281 {
282  return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
283 }
284 
285 
286 template<typename Vec3T>
287 inline Vec3T
289 {
291  return (mMax - mMin) + Vec3T(1, 1, 1);
292  } else {
293  return (mMax - mMin);
294  }
295 }
296 
297 ////////////////////////////////////////
298 
299 
300 template<typename Vec3T>
301 inline bool
302 BBox<Vec3T>::isInside(const Vec3T& xyz) const
303 {
305  return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
306  xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
307  xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
308  } else {
310  return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
311  xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
312  xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
313  }
314 }
315 
316 
317 template<typename Vec3T>
318 inline bool
320 {
322  return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
323  b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
324  b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
325  } else {
327  return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
328  (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
329  (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
330  }
331 }
332 
333 
334 template<typename Vec3T>
335 inline bool
337 {
339  return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
340  mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
341  mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
342  } else {
344  return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
345  mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
346  mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
347  }
348 }
349 
350 
351 ////////////////////////////////////////
352 
353 
354 template<typename Vec3T>
355 inline void
357 {
358  dx = std::abs(dx);
359  for (int i = 0; i < 3; ++i) {
360  mMin[i] -= dx;
361  mMax[i] += dx;
362  }
363 }
364 
365 
366 template<typename Vec3T>
367 inline void
368 BBox<Vec3T>::expand(const Vec3T& xyz)
369 {
370  for (int i = 0; i < 3; ++i) {
371  mMin[i] = std::min(mMin[i], xyz[i]);
372  mMax[i] = std::max(mMax[i], xyz[i]);
373  }
374 }
375 
376 
377 template<typename Vec3T>
378 inline void
380 {
381  for (int i = 0; i < 3; ++i) {
382  mMin[i] = std::min(mMin[i], b.min()[i]);
383  mMax[i] = std::max(mMax[i], b.max()[i]);
384  }
385 }
386 
387 template<typename Vec3T>
388 inline void
389 BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length)
390 {
392  for (int i = 0; i < 3; ++i) {
393  mMin[i] = std::min(mMin[i], xyzMin[i]);
394  mMax[i] = std::max(mMax[i], xyzMin[i] + size);
395  }
396 }
397 
398 
399 template<typename Vec3T>
400 inline void
401 BBox<Vec3T>::translate(const Vec3T& dx)
402 {
403  mMin += dx;
404  mMax += dx;
405 }
406 
407 template<typename Vec3T>
408 template<typename MapType>
409 inline BBox<Vec3T>
410 BBox<Vec3T>::applyMap(const MapType& map) const
411 {
412  typedef Vec3<double> Vec3R;
413  BBox<Vec3T> bbox;
414  bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMin[2])));
415  bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMax[2])));
416  bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMin[2])));
417  bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMin[2])));
418  bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMin[2])));
419  bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMax[2])));
420  bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMax[2])));
421  bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMax[2])));
422  return bbox;
423 }
424 
425 template<typename Vec3T>
426 template<typename MapType>
427 inline BBox<Vec3T>
428 BBox<Vec3T>::applyInverseMap(const MapType& map) const
429 {
430  typedef Vec3<double> Vec3R;
431  BBox<Vec3T> bbox;
432  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMin[2])));
433  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMax[2])));
434  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMin[2])));
435  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMin[2])));
436  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMin[2])));
437  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMax[2])));
438  bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMax[2])));
439  bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMax[2])));
440  return bbox;
441 }
442 
443 ////////////////////////////////////////
444 
445 
446 template<typename Vec3T>
447 inline std::ostream&
448 operator<<(std::ostream& os, const BBox<Vec3T>& b)
449 {
450  os << b.min() << " -> " << b.max();
451  return os;
452 }
453 
454 } // namespace math
455 } // namespace OPENVDB_VERSION_NAME
456 } // namespace openvdb
457 
458 #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
459 
460 // Copyright (c) 2012-2017 DreamWorks Animation LLC
461 // All rights reserved. This software is distributed under the
462 // 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:132
math::Vec3< Real > Vec3R
Definition: Types.h:75
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128
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 .
Definition: BBox.h:401
Vec3T & max()
Return a non-const reference to the maximum point of the BBox.
Definition: BBox.h:93
void expand(ElementType padding)
Pad this bounding box.
Definition: BBox.h:356
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: BBox.h:129
png_uint_32 i
Definition: png.h:2877
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:168
GLsizeiptr size
Definition: glcorearb.h:663
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: BBox.h:171
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 the BBox.
Definition: BBox.h:84
BBox applyMap(const MapType &map) const
Apply a map to this bounding box.
#define OPENVDB_VERSION_NAME
Definition: version.h:43
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 the two BBox'es are not identical.
Definition: BBox.h:99
bool empty() const
Return true if the BBox is empty, i.e. has no (positive) volume.
Definition: BBox.h:231
Vec3Type::ValueType ElementType
Definition: BBox.h:53
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
const Vec3T & max() const
Return a const reference to the maximum point of the BBox.
Definition: BBox.h:87
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:370
Vec3T extents() const
Returns the extents of the BBox, i.e. the length per axis for floating points values or number of gri...
Definition: BBox.h:288
GLsizei const GLfloat * value
Definition: glcorearb.h:823
Axis-aligned bounding box.
Definition: BBox.h:47
BBox()
Default constructor creates an invalid BBox.
Definition: BBox.h:183
BBox & operator=(const BBox &)=default
Assignment operator.
bool operator==(const BBox &rhs) const
Return true if the two BBox'es are identical.
Definition: BBox.h:243
ElementType volume() const
Return the volume spanned by this BBox.
Definition: BBox.h:126
Vec3d getCenter() const
Return the center point of the BBox.
Definition: BBox.h:280
Vec3T & min()
Return a non-const reference to the minimum point of the BBox.
Definition: BBox.h:90
bool hasOverlap(const BBox &) const
Return true if the given bounding box overlaps with this bounding box.
Definition: BBox.h:336
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
bool isSorted() const
Return true if the all components of mMin <= mMax, i.e. the volume is not negative.
Definition: BBox.h:267
void sort()
Sort the min/max by x,y,z component.
Definition: BBox.h:255
bool hasVolume() const
Return true if the BBox has a (positive) volume.
Definition: BBox.h:106
bool isInside(const Vec3T &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: BBox.h:302
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794