OpenVDB  2.0.0
BBox.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 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 //
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 <boost/type_traits/is_integral.hpp>
39 
40 namespace openvdb {
42 namespace OPENVDB_VERSION_NAME {
43 namespace math {
44 
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 
56  BBox();
57 
59  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax);
60 
63  BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted);
64 
68  BBox(const Vec3T& xyzMin, const ElementType& length);
69 
72  explicit BBox(const ElementType* xyz, bool sorted = true);
73 
75  BBox(const BBox& other);
76 
78  void sort();
79 
81  const Vec3T& min() const { return mMin; }
82 
84  const Vec3T& max() const { return mMax; }
85 
87  Vec3T& min() { return mMin; }
88 
90  Vec3T& max() { return mMax; }
91 
93  bool operator==(const BBox& rhs) const;
94 
96  bool operator!=(const BBox& rhs) const { return !(*this == rhs); }
97 
100  bool empty() const;
101 
103  bool hasVolume() const { return !this->empty(); }
104 
106  operator bool() const { return !this->empty(); }
107 
111  bool isSorted() const;
112 
114  Vec3d getCenter() const;
115 
120  Vec3T extents() const;
121 
123  ElementType volume() const { Vec3T e = this->extents(); return e[0] * e[1] * e[2]; }
124 
126  size_t maxExtent() const { return MaxIndex(mMax - mMin); }
127 
129  size_t minExtent() const { return MinIndex(mMax - mMin); }
130 
132  bool isInside(const Vec3T& xyz) const;
133 
135  bool isInside(const BBox&) const;
136 
138  bool hasOverlap(const BBox&) const;
139 
141  void expand(ElementType padding);
142 
144  void expand(const Vec3T& xyz);
145 
147  void expand(const BBox&);
148  // @brief Union this bbox with the cubical bbox defined from xyzMin and
149  // length
151  void expand(const Vec3T& xyzMin, const ElementType& length);
152 
154  void translate(const Vec3T& t);
155 
157  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
158 
160  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
161 
162 private:
163  Vec3T mMin, mMax;
164 }; // class BBox
165 
166 
168 
169 
170 template<typename Vec3T>
171 inline
173  mMin( std::numeric_limits<ElementType>::max()),
174  mMax(-std::numeric_limits<ElementType>::max())
175 {
176 }
177 
178 template<typename Vec3T>
179 inline
180 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax):
181  mMin(xyzMin), mMax(xyzMax)
182 {
183 }
184 
185 template<typename Vec3T>
186 inline
187 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted):
188  mMin(xyzMin), mMax(xyzMax)
189 {
190  if (!sorted) this->sort();
191 }
192 
193 template<typename Vec3T>
194 inline
195 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length):
196  mMin(xyzMin), mMax(xyzMin)
197 {
198  // min and max are inclusive for integral ElementType
199  const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
200  mMax[0] += size;
201  mMax[1] += size;
202  mMax[2] += size;
203 }
204 
205 template<typename Vec3T>
206 inline
207 BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted):
208  mMin(xyz[0], xyz[1], xyz[2]),
209  mMax(xyz[3], xyz[4], xyz[5])
210 {
211  if (!sorted) this->sort();
212 }
213 
214 
215 template<typename Vec3T>
216 inline
217 BBox<Vec3T>::BBox(const BBox& other):
218  mMin(other.mMin), mMax(other.mMax)
219 {
220 }
221 
222 
224 
225 
226 template<typename Vec3T>
227 inline bool
229 {
230  if (boost::is_integral<ElementType>::value) {
231  // min and max are inclusive for integral ElementType
232  return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
233  }
234  return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2];
235 }
236 
237 
238 template<typename Vec3T>
239 inline bool
240 BBox<Vec3T>::operator==(const BBox& rhs) const
241 {
242  if (boost::is_integral<ElementType>::value) {
243  return mMin == rhs.min() && mMax == rhs.max();
244  } else {
245  return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max());
246  }
247 }
248 
249 
250 template<typename Vec3T>
251 inline void
253 {
254  Vec3T tMin(mMin), tMax(mMax);
255  for (size_t i = 0; i < 3; ++i) {
256  mMin[i] = std::min(tMin[i], tMax[i]);
257  mMax[i] = std::max(tMin[i], tMax[i]);
258  }
259 }
260 
261 
262 template<typename Vec3T>
263 inline bool
265 {
266  if (boost::is_integral<ElementType>::value) {
267  return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
268  } else {
270  return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
271  }
272 }
273 
274 
275 template<typename Vec3T>
276 inline Vec3d
278 {
279  return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
280 }
281 
282 
283 template<typename Vec3T>
284 inline Vec3T
286 {
287  if (boost::is_integral<ElementType>::value) {
288  return (mMax - mMin) + Vec3T(1, 1, 1);
289  } else {
290  return (mMax - mMin);
291  }
292 }
293 
295 
296 
297 template<typename Vec3T>
298 inline bool
299 BBox<Vec3T>::isInside(const Vec3T& xyz) const
300 {
301  if (boost::is_integral<ElementType>::value) {
302  return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
303  xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
304  xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
305  } else {
307  return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
308  xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
309  xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
310  }
311 }
312 
313 
314 template<typename Vec3T>
315 inline bool
317 {
318  if (boost::is_integral<ElementType>::value) {
319  return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
320  b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
321  b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
322  } else {
324  return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
325  (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
326  (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
327  }
328 }
329 
330 
331 template<typename Vec3T>
332 inline bool
334 {
335  if (boost::is_integral<ElementType>::value) {
336  return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
337  mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
338  mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
339  } else {
341  return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
342  mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
343  mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
344  }
345 }
346 
347 
349 
350 
351 template<typename Vec3T>
352 inline void
354 {
355  dx = std::abs(dx);
356  for (size_t i = 0; i < 3; ++i) {
357  mMin[i] -= dx;
358  mMax[i] += dx;
359  }
360 }
361 
362 
363 template<typename Vec3T>
364 inline void
365 BBox<Vec3T>::expand(const Vec3T& xyz)
366 {
367  for (size_t i = 0; i < 3; ++i) {
368  mMin[i] = std::min(mMin[i], xyz[i]);
369  mMax[i] = std::max(mMax[i], xyz[i]);
370  }
371 }
372 
373 
374 template<typename Vec3T>
375 inline void
377 {
378  for (size_t i = 0; i < 3; ++i) {
379  mMin[i] = std::min(mMin[i], b.min()[i]);
380  mMax[i] = std::max(mMax[i], b.max()[i]);
381  }
382 }
383 
384 template<typename Vec3T>
385 inline void
386 BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length)
387 {
388  const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
389  for (size_t i = 0; i < 3; ++i) {
390  mMin[i] = std::min(mMin[i], xyzMin[i]);
391  mMax[i] = std::max(mMax[i], xyzMin[i] + size);
392  }
393 }
394 
395 
396 template<typename Vec3T>
397 inline void
398 BBox<Vec3T>::translate(const Vec3T& dx)
399 {
400  mMin += dx;
401  mMax += dx;
402 }
403 
404 
406 
407 
408 template<typename Vec3T>
409 inline std::ostream&
410 operator<<(std::ostream& os, const BBox<Vec3T>& b)
411 {
412  os << b.min() << " -> " << b.max();
413  return os;
414 }
415 
416 } // namespace math
417 } // namespace OPENVDB_VERSION_NAME
418 } // namespace openvdb
419 
420 #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
421 
422 // Copyright (c) 2012-2013 DreamWorks Animation LLC
423 // All rights reserved. This software is distributed under the
424 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Vec3T & min()
Return a non-const reference to the minimum point of the BBox.
Definition: BBox.h:87
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
BBox()
Default constructor creates an invalid BBox.
Definition: BBox.h:172
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:285
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool isSorted() const
Return true if the all components of mMin &lt;= mMax, i.e. the volume is not negative.
Definition: BBox.h:264
Vec3T & max()
Return a non-const reference to the maximum point of the BBox.
Definition: BBox.h:90
ElementType volume() const
Return the volume spanned by this BBox.
Definition: BBox.h:123
Vec3d getCenter() const
Return the center point of the BBox.
Definition: BBox.h:277
bool hasOverlap(const BBox &) const
Return true if the given bounding box overlaps with this bounding box.
Definition: BBox.h:333
Axis-aligned bounding box.
Definition: BBox.h:47
bool isInside(const Vec3T &xyz) const
Return true if point (x, y, z) is inside this bounding box.
Definition: BBox.h:299
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:430
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: BBox.h:126
Vec3Type::ValueType ElementType
Definition: BBox.h:53
bool hasVolume() const
Return true if the BBox has a (positive) volume.
Definition: BBox.h:103
void translate(const Vec3T &t)
Translate this bounding box by .
Definition: BBox.h:398
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: BBox.h:160
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:814
double ValueType
Definition: Vec3.h:51
#define OPENVDB_VERSION_NAME
Definition: version.h:45
static T value()
Definition: Math.h:116
Vec3T ValueType
Definition: BBox.h:51
void expand(ElementType padding)
Pad this bounding box.
Definition: BBox.h:353
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: BBox.h:129
void sort()
Sort the min/max by x,y,z component.
Definition: BBox.h:252
Vec3< double > Vec3d
Definition: Vec3.h:605
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:796
bool operator!=(const BBox &rhs) const
Return true if the two BBox&#39;es are not identical.
Definition: BBox.h:96
const Vec3T & min() const
Return a const reference to the minimum point of the BBox.
Definition: BBox.h:81
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:157
bool empty() const
Return true if the BBox is empty, i.e. has no (positive) volume.
Definition: BBox.h:228
Vec3T Vec3Type
Definition: BBox.h:50
Vec3T VectorType
Definition: BBox.h:52
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
bool isApproxEqual(const Hermite &lhs, const Hermite &rhs)
Definition: Hermite.h:470
const Vec3T & max() const
Return a const reference to the maximum point of the BBox.
Definition: BBox.h:84
bool operator==(const BBox &rhs) const
Return true if the two BBox&#39;es are identical.
Definition: BBox.h:240