OpenVDB  1.1.0
BBox.h
Go to the documentation of this file.
1 
2 //
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 isApproxEqual() and 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<class _VectorType>
47 class BBox
48 {
49 public:
50  typedef _VectorType VectorType;
51  typedef _VectorType ValueType;
52  typedef typename _VectorType::ValueType ElementType;
53 
54  BBox();
55  BBox(const VectorType& xyzMin, const VectorType& xyzMax);
56  BBox(const VectorType& xyzMin, const VectorType& xyzMax, bool sorted);
60  BBox(const VectorType& xyzMin, const ElementType& length);
61  explicit BBox(const ElementType* xyz, bool sorted = true);
62  BBox(const BBox& other);
63 
64  void sort();
65 
66  const VectorType& min() const { return mMin; }
67  const VectorType& max() const { return mMax; }
68 
69  VectorType& min() { return mMin; }
70  VectorType& max() { return mMax; }
71 
72  bool operator==(const BBox& rhs) const;
73  bool operator!=(const BBox& rhs) const { return !(*this == rhs); }
74 
75  bool empty() const;
76  bool hasVolume() const { return !empty(); }
77  operator bool() const { return !empty(); }
78 
79  bool isSorted() const;
80 
81  Vec3d getCenter() const;
82 
84  VectorType extents() const;
85 
86  ElementType volume() const { VectorType e = extents(); return e[0] * e[1] * e[2]; }
87 
89  size_t maxExtent() const;
90 
92  bool isInside(const VectorType& xyz) const;
93 
95  bool isInside(const BBox&) const;
96 
98  bool hasOverlap(const BBox&) const;
99 
101  void expand(ElementType padding);
103  void expand(const VectorType& xyz);
105  void expand(const BBox&);
106  // @brief Union this bbox with the cubical bbox defined from xyzMin and
107  // length
109  void expand(const VectorType& xyzMin, const ElementType& length);
111  void translate(const VectorType& t);
112 
114  void read(std::istream& is) { mMin.read(is); mMax.read(is); }
116  void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
117 
118 private:
119  VectorType mMin, mMax;
120 }; // class BBox
121 
122 
124 
125 
126 template<class VectorType>
127 inline
129  mMin(ElementType(0), ElementType(0), ElementType(0)),
130  mMax(ElementType(0), ElementType(0), ElementType(0))
131 {
132 }
133 
134 template<class VectorType>
135 inline
136 BBox<VectorType>::BBox(const VectorType& xyzMin, const VectorType& xyzMax):
137  mMin(xyzMin), mMax(xyzMax)
138 {
139 }
140 
141 template<class VectorType>
142 inline
143 BBox<VectorType>::BBox(const VectorType& xyzMin, const VectorType& xyzMax, bool sorted):
144  mMin(xyzMin), mMax(xyzMax)
145 {
146  if (!sorted) this->sort();
147 }
148 
149 template<class VectorType>
150 inline
151 BBox<VectorType>::BBox(const VectorType& xyzMin, const ElementType& length):
152  mMin(xyzMin), mMax(xyzMin)
153 {
154  // min and max are inclusive for integral ElementType
155  const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
156  mMax[0] += size;
157  mMax[1] += size;
158  mMax[2] += size;
159 }
160 
161 template<class VectorType>
162 inline
163 BBox<VectorType>::BBox(const ElementType* xyz, bool sorted):
164  mMin(xyz[0], xyz[1], xyz[2]),
165  mMax(xyz[3], xyz[4], xyz[5])
166 {
167  if (!sorted) this->sort();
168 }
169 
170 
171 template<class VectorType>
172 inline
174  mMin(other.mMin), mMax(other.mMax)
175 {
176 }
177 
178 
180 
181 
182 template<class VectorType>
183 inline bool
185 {
186  if (boost::is_integral<ElementType>::value) {
187  // min and max are inclusive for integral ElementType
188  return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
189  }
190  return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2];
191 }
192 
193 
194 template<class VectorType>
195 inline bool
197 {
198  if (boost::is_integral<ElementType>::value) {
199  return mMin == rhs.min() && mMax == rhs.max();
200  } else {
201  return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max());
202  }
203 }
204 
205 
206 template<class VectorType>
207 inline void
209 {
210  VectorType tMin(mMin), tMax(mMax);
211  for (size_t i = 0; i < 3; ++i) {
212  mMin[i] = std::min(tMin[i], tMax[i]);
213  mMax[i] = std::max(tMin[i], tMax[i]);
214  }
215 }
216 
217 
218 template<class VectorType>
219 inline bool
221 {
222  if (boost::is_integral<ElementType>::value) {
223  return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
224  } else {
226  return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
227  }
228 }
229 
230 
231 template<class VectorType>
232 inline Vec3d
234 {
235  return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
236 }
237 
238 
239 template<class VectorType>
240 inline VectorType
242 {
243  if (boost::is_integral<ElementType>::value) {
244  return (mMax - mMin) + VectorType(1, 1, 1);
245  } else {
246  return (mMax - mMin);
247  }
248 }
249 
250 
251 template<class VectorType>
252 inline size_t
254 {
255  VectorType e = extents();
256  if (e[0] > e[1] && e[0] > e[2]) return 0;
257  else if (e[1] > e[2]) return 1;
258  return 2;
259 }
260 
261 
263 
264 
265 template<class VectorType>
266 inline bool
268 {
269  if (boost::is_integral<ElementType>::value) {
270  return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
271  xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
272  xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
273  } else {
275  return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
276  xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
277  xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
278  }
279 }
280 
281 
282 template<class VectorType>
283 inline bool
285 {
286  if (boost::is_integral<ElementType>::value) {
287  return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
288  b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
289  b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
290  } else {
292  return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
293  (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
294  (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
295  }
296 }
297 
298 
299 template<class VectorType>
300 inline bool
302 {
303  if (boost::is_integral<ElementType>::value) {
304  return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
305  mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
306  mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
307  } else {
309  return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
310  mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
311  mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
312  }
313 }
314 
315 
317 
318 
319 template<class VectorType>
320 inline void
322 {
323  dx = std::abs(dx);
324  for (size_t i = 0; i < 3; ++i) {
325  mMin[i] -= dx;
326  mMax[i] += dx;
327  }
328 }
329 
330 
331 template<class VectorType>
332 inline void
334 {
335  for (size_t i = 0; i < 3; ++i) {
336  mMin[i] = std::min(mMin[i], xyz[i]);
337  mMax[i] = std::max(mMax[i], xyz[i]);
338  }
339 }
340 
341 
342 template<class VectorType>
343 inline void
345 {
346  for (size_t i = 0; i < 3; ++i) {
347  mMin[i] = std::min(mMin[i], b.min()[i]);
348  mMax[i] = std::max(mMax[i], b.max()[i]);
349  }
350 }
351 
352 template<class VectorType>
353 inline void
354 BBox<VectorType>::expand(const VectorType& xyzMin, const ElementType& length)
355 {
356  const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
357  for (size_t i = 0; i < 3; ++i) {
358  mMin[i] = std::min(mMin[i], xyzMin[i]);
359  mMax[i] = std::max(mMax[i], xyzMin[i] + size);
360  }
361 }
362 
363 
364 template<class VectorType>
365 inline void
367 {
368  mMin += dx;
369  mMax += dx;
370 }
371 
372 
374 
375 
376 template<class VectorType>
377 inline std::ostream&
378 operator<<(std::ostream& os, const BBox<VectorType>& b)
379 {
380  os << b.min() << " -> " << b.max();
381  return os;
382 }
383 
384 } // namespace math
385 } // namespace OPENVDB_VERSION_NAME
386 } // namespace openvdb
387 
388 #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
389 
390 // Copyright (c) 2012-2013 DreamWorks Animation LLC
391 // All rights reserved. This software is distributed under the
392 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )