OpenVDB: BBox.h Source File

OpenVDB 3.2.0

BBox.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 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 {
41 OPENVDB_USE_VERSION_NAMESPACE
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 template<typename MapType>
158 BBox applyMap(const MapType& map) const;
159
161 template<typename MapType>
162 BBox applyInverseMap(const MapType& map) const;
163
165 void read(std::istream& is) { mMin.read(is); mMax.read(is); }
166
168 void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
169
170 private:
171 Vec3T mMin, mMax;
172 }; // class BBox
173
174
176
177
178 template<typename Vec3T>
179 inline
180 BBox<Vec3T>::BBox():
181 mMin( std::numeric_limits<ElementType>::max()),
182 mMax(-std::numeric_limits<ElementType>::max())
183 {
184 }
185
186 template<typename Vec3T>
187 inline
188 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax):
189 mMin(xyzMin), mMax(xyzMax)
190 {
191 }
192
193 template<typename Vec3T>
194 inline
195 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted):
196 mMin(xyzMin), mMax(xyzMax)
197 {
198 if (!sorted) this->sort();
199 }
200
201 template<typename Vec3T>
202 inline
203 BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length):
204 mMin(xyzMin), mMax(xyzMin)
205 {
206 // min and max are inclusive for integral ElementType
207 const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
208 mMax[0] += size;
209 mMax[1] += size;
210 mMax[2] += size;
211 }
212
213 template<typename Vec3T>
214 inline
215 BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted):
216 mMin(xyz[0], xyz[1], xyz[2]),
217 mMax(xyz[3], xyz[4], xyz[5])
218 {
219 if (!sorted) this->sort();
220 }
221
222
223 template<typename Vec3T>
224 inline
225 BBox<Vec3T>::BBox(const BBox& other):
226 mMin(other.mMin), mMax(other.mMax)
227 {
228 }
229
230
232
233
234 template<typename Vec3T>
235 inline bool
236 BBox<Vec3T>::empty() const
237 {
238 if (boost::is_integral<ElementType>::value) {
239 // min and max are inclusive for integral ElementType
240 return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]);
241 }
242 return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2];
243 }
244
245
246 template<typename Vec3T>
247 inline bool
248 BBox<Vec3T>::operator==(const BBox& rhs) const
249 {
250 if (boost::is_integral<ElementType>::value) {
251 return mMin == rhs.min() && mMax == rhs.max();
252 } else {
253 return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max());
254 }
255 }
256
257
258 template<typename Vec3T>
259 inline void
260 BBox<Vec3T>::sort()
261 {
262 Vec3T tMin(mMin), tMax(mMax);
263 for (int i = 0; i < 3; ++i) {
264 mMin[i] = std::min(tMin[i], tMax[i]);
265 mMax[i] = std::max(tMin[i], tMax[i]);
266 }
267 }
268
269
270 template<typename Vec3T>
271 inline bool
272 BBox<Vec3T>::isSorted() const
273 {
274 if (boost::is_integral<ElementType>::value) {
275 return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
276 } else {
277 ElementType t = math::Tolerance<ElementType>::value();
278 return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
279 }
280 }
281
282
283 template<typename Vec3T>
284 inline Vec3d
285 BBox<Vec3T>::getCenter() const
286 {
287 return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
288 }
289
290
291 template<typename Vec3T>
292 inline Vec3T
293 BBox<Vec3T>::extents() const
294 {
295 if (boost::is_integral<ElementType>::value) {
296 return (mMax - mMin) + Vec3T(1, 1, 1);
297 } else {
298 return (mMax - mMin);
299 }
300 }
301
303
304
305 template<typename Vec3T>
306 inline bool
307 BBox<Vec3T>::isInside(const Vec3T& xyz) const
308 {
309 if (boost::is_integral<ElementType>::value) {
310 return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
311 xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
312 xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
313 } else {
314 ElementType t = math::Tolerance<ElementType>::value();
315 return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
316 xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
317 xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
318 }
319 }
320
321
322 template<typename Vec3T>
323 inline bool
324 BBox<Vec3T>::isInside(const BBox& b) const
325 {
326 if (boost::is_integral<ElementType>::value) {
327 return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
328 b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
329 b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
330 } else {
331 ElementType t = math::Tolerance<ElementType>::value();
332 return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
333 (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
334 (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
335 }
336 }
337
338
339 template<typename Vec3T>
340 inline bool
341 BBox<Vec3T>::hasOverlap(const BBox& b) const
342 {
343 if (boost::is_integral<ElementType>::value) {
344 return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
345 mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
346 mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
347 } else {
348 ElementType t = math::Tolerance<ElementType>::value();
349 return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
350 mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
351 mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
352 }
353 }
354
355
357
358
359 template<typename Vec3T>
360 inline void
361 BBox<Vec3T>::expand(ElementType dx)
362 {
363 dx = std::abs(dx);
364 for (int i = 0; i < 3; ++i) {
365 mMin[i] -= dx;
366 mMax[i] += dx;
367 }
368 }
369
370
371 template<typename Vec3T>
372 inline void
373 BBox<Vec3T>::expand(const Vec3T& xyz)
374 {
375 for (int i = 0; i < 3; ++i) {
376 mMin[i] = std::min(mMin[i], xyz[i]);
377 mMax[i] = std::max(mMax[i], xyz[i]);
378 }
379 }
380
381
382 template<typename Vec3T>
383 inline void
384 BBox<Vec3T>::expand(const BBox& b)
385 {
386 for (int i = 0; i < 3; ++i) {
387 mMin[i] = std::min(mMin[i], b.min()[i]);
388 mMax[i] = std::max(mMax[i], b.max()[i]);
389 }
390 }
391
392 template<typename Vec3T>
393 inline void
394 BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length)
395 {
396 const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
397 for (int i = 0; i < 3; ++i) {
398 mMin[i] = std::min(mMin[i], xyzMin[i]);
399 mMax[i] = std::max(mMax[i], xyzMin[i] + size);
400 }
401 }
402
403
404 template<typename Vec3T>
405 inline void
406 BBox<Vec3T>::translate(const Vec3T& dx)
407 {
408 mMin += dx;
409 mMax += dx;
410 }
411
412 template<typename Vec3T>
413 template<typename MapType>
414 inline BBox<Vec3T>
415 BBox<Vec3T>::applyMap(const MapType& map) const
416 {
417 typedef Vec3<double> Vec3R;
418 BBox<Vec3T> bbox;
419 bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMin[2])));
420 bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMax[2])));
421 bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMin[2])));
422 bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMin[2])));
423 bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMin[2])));
424 bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMax[2])));
425 bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMax[2])));
426 bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMax[2])));
427 return bbox;
428 }
429
430 template<typename Vec3T>
431 template<typename MapType>
432 inline BBox<Vec3T>
433 BBox<Vec3T>::applyInverseMap(const MapType& map) const
434 {
435 typedef Vec3<double> Vec3R;
436 BBox<Vec3T> bbox;
437 bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMin[2])));
438 bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMax[2])));
439 bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMin[2])));
440 bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMin[2])));
441 bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMin[2])));
442 bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMax[2])));
443 bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMax[2])));
444 bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMax[2])));
445 return bbox;
446 }
447
449
450
451 template<typename Vec3T>
452 inline std::ostream&
453 operator<<(std::ostream& os, const BBox<Vec3T>& b)
454 {
455 os << b.min() << " -> " << b.max();
456 return os;
457 }
458
459 } // namespace math
460 } // namespace OPENVDB_VERSION_NAME
461 } // namespace openvdb
462
463 #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
464
465 // Copyright (c) 2012-2016 DreamWorks Animation LLC
466 // All rights reserved. This software is distributed under the
467 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v3_2_0::math::BBox::max
Vec3T & max()
Return a non-const reference to the maximum point of the BBox.
Definition: BBox.h:90
Vec3.h
openvdb::v3_2_0::math::BBox::write
void write(std::ostream &os) const
Serialize this bounding box to the given stream.
Definition: BBox.h:168
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v3_2_0::math::BBox::hasVolume
bool hasVolume() const
Return true if the BBox has a (positive) volume.
Definition: BBox.h:103
openvdb::v3_2_0::math::Vec3< double >
openvdb::v3_2_0::math::BBox::minExtent
size_t minExtent() const
Return the index (0, 1 or 2) of the shortest axis.
Definition: BBox.h:129
openvdb::v3_2_0::tools::composite::max
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
openvdb::v3_2_0::math::BBox
Axis-aligned bounding box.
Definition: BBox.h:47
openvdb::v3_2_0::math::BBox::volume
ElementType volume() const
Return the volume spanned by this BBox.
Definition: BBox.h:123
openvdb::v3_2_0::math::isApproxEqual
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
openvdb::v3_2_0::math::BBox::ValueType
Vec3T ValueType
Definition: BBox.h:51
openvdb::v3_2_0::math::BBox::maxExtent
size_t maxExtent() const
Return the index (0, 1 or 2) of the longest axis.
Definition: BBox.h:126
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
Definition: version.h:43
openvdb::v3_2_0::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:651
openvdb::v3_2_0::math::BBox::ElementType
Vec3Type::ValueType ElementType
Definition: BBox.h:53
openvdb::v3_2_0::math::Vec3< double >::ValueType
double ValueType
Definition: Vec3.h:51
openvdb::v3_2_0::math::BBox::expand
void expand(ElementType padding)
Pad this bounding box.
Definition: BBox.h:361
openvdb::v3_2_0::math::BBox::operator!=
bool operator!=(const BBox &rhs) const
Return true if the two BBox&#39;es are not identical.
Definition: BBox.h:96
openvdb
Definition: Exceptions.h:39
openvdb::v3_2_0::math::Tolerance
Tolerance for floating-point comparison.
Definition: Math.h:125
openvdb::v3_2_0::math::BBox::min
const Vec3T & min() const
Return a const reference to the minimum point of the BBox.
Definition: BBox.h:81
openvdb::v3_2_0::math::BBox::max
const Vec3T & max() const
Return a const reference to the maximum point of the BBox.
Definition: BBox.h:84
openvdb::v3_2_0::math::operator==
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:450
openvdb::v3_2_0::math::MaxIndex
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:911
openvdb::v3_2_0::math::BBox::read
void read(std::istream &is)
Unserialize this bounding box from the given stream.
Definition: BBox.h:165
openvdb::v3_2_0::Vec3R
math::Vec3< Real > Vec3R
Definition: Types.h:76
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
openvdb::v3_2_0::math::BBox::min
Vec3T & min()
Return a non-const reference to the minimum point of the BBox.
Definition: BBox.h:87
openvdb::v3_2_0::math::BBox::Vec3Type
Vec3T Vec3Type
Definition: BBox.h:50
openvdb::v3_2_0::math::BBox::VectorType
Vec3T VectorType
Definition: BBox.h:52
openvdb::v3_2_0::math::MinIndex
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:890
openvdb::v3_2_0::tools::composite::min
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128