1/////////////////////////////////////////////////////////////////////////// 
2// 
3// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas 
4// Digital Ltd. LLC 
5//  
6// All rights reserved. 
7//  
8// Redistribution and use in source and binary forms, with or without 
9// modification, are permitted provided that the following conditions are 
10// met: 
11// * Redistributions of source code must retain the above copyright 
12// notice, this list of conditions and the following disclaimer. 
13// * Redistributions in binary form must reproduce the above 
14// copyright notice, this list of conditions and the following disclaimer 
15// in the documentation and/or other materials provided with the 
16// distribution. 
17// * Neither the name of Industrial Light & Magic nor the names of 
18// its contributors may be used to endorse or promote products derived 
19// from this software without specific prior written permission.  
20//  
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
32// 
33/////////////////////////////////////////////////////////////////////////// 
34 
35 
36#ifndef INCLUDED_IMATHBOX_H 
37#define INCLUDED_IMATHBOX_H 
38 
39//------------------------------------------------------------------- 
40// 
41// class Imath::Box<class T> 
42// -------------------------------- 
43// 
44// This class imposes the following requirements on its  
45// parameter class: 
46//  
47// 1) The class T must implement these operators: 
48// + - < > <= >= =  
49// with the signature (T,T) and the expected  
50// return values for a numeric type.  
51// 
52// 2) The class T must implement operator= 
53// with the signature (T,float and/or double) 
54// 
55// 3) The class T must have a constructor which takes 
56// a float (and/or double) for use in initializing the box. 
57// 
58// 4) The class T must have a function T::dimensions() 
59// which returns the number of dimensions in the class 
60// (since its assumed its a vector) -- preferably, this 
61// returns a constant expression. 
62// 
63//------------------------------------------------------------------- 
64 
65#include "ImathVec.h" 
66#include "ImathNamespace.h" 
67 
68IMATH_INTERNAL_NAMESPACE_HEADER_ENTER 
69 
70 
71template <class T>  
72class Box 
73
74 public
75 
76 //------------------------- 
77 // Data Members are public 
78 //------------------------- 
79 
80 T min
81 T max
82 
83 //----------------------------------------------------- 
84 // Constructors - an "empty" box is created by default 
85 //----------------------------------------------------- 
86 
87 Box ();  
88 Box (const T &point); 
89 Box (const T &minT, const T &maxT); 
90 
91 //-------------------- 
92 // Operators: ==, != 
93 //-------------------- 
94  
95 bool operator == (const Box<T> &src) const
96 bool operator != (const Box<T> &src) const
97 
98 //------------------ 
99 // Box manipulation 
100 //------------------ 
101 
102 void makeEmpty (); 
103 void extendBy (const T &point); 
104 void extendBy (const Box<T> &box); 
105 void makeInfinite ();  
106 
107 //--------------------------------------------------- 
108 // Query functions - these compute results each time 
109 //--------------------------------------------------- 
110 
111 T size () const
112 T center () const
113 bool intersects (const T &point) const
114 bool intersects (const Box<T> &box) const
115 
116 unsigned int majorAxis () const
117 
118 //---------------- 
119 // Classification 
120 //---------------- 
121 
122 bool isEmpty () const
123 bool hasVolume () const
124 bool isInfinite () const
125}; 
126 
127 
128//-------------------- 
129// Convenient typedefs 
130//-------------------- 
131 
132typedef Box <V2s> Box2s
133typedef Box <V2i> Box2i
134typedef Box <V2f> Box2f
135typedef Box <V2d> Box2d
136typedef Box <V3s> Box3s
137typedef Box <V3i> Box3i
138typedef Box <V3f> Box3f
139typedef Box <V3d> Box3d
140 
141 
142//---------------- 
143// Implementation 
144 
145 
146template <class T> 
147inline Box<T>::Box() 
148
149 makeEmpty(); 
150
151 
152 
153template <class T> 
154inline Box<T>::Box (const T &point
155
156 min = point
157 max = point
158
159 
160 
161template <class T> 
162inline Box<T>::Box (const T &minT, const T &maxT
163
164 min = minT
165 max = maxT
166
167 
168 
169template <class T> 
170inline bool 
171Box<T>::operator == (const Box<T> &src) const 
172
173 return (min == src.min && max == src.max); 
174
175 
176 
177template <class T> 
178inline bool 
179Box<T>::operator != (const Box<T> &src) const 
180
181 return (min != src.min || max != src.max); 
182
183 
184 
185template <class T> 
186inline void Box<T>::makeEmpty() 
187
188 min = T(T::baseTypeMax()); 
189 max = T(T::baseTypeMin()); 
190
191 
192template <class T> 
193inline void Box<T>::makeInfinite() 
194
195 min = T(T::baseTypeMin()); 
196 max = T(T::baseTypeMax()); 
197
198 
199 
200template <class T> 
201inline void 
202Box<T>::extendBy(const T &point
203
204 for (unsigned int i = 0; i < min.dimensions(); i++) 
205
206 if (point[i] < min[i]) 
207 min[i] = point[i]; 
208 
209 if (point[i] > max[i]) 
210 max[i] = point[i]; 
211
212
213 
214 
215template <class T> 
216inline void 
217Box<T>::extendBy(const Box<T> &box
218
219 for (unsigned int i = 0; i < min.dimensions(); i++) 
220
221 if (box.min[i] < min[i]) 
222 min[i] = box.min[i]; 
223 
224 if (box.max[i] > max[i]) 
225 max[i] = box.max[i]; 
226
227
228 
229 
230template <class T> 
231inline bool 
232Box<T>::intersects(const T &point) const 
233
234 for (unsigned int i = 0; i < min.dimensions(); i++) 
235
236 if (point[i] < min[i] || point[i] > max[i]) 
237 return false
238
239 
240 return true
241
242 
243 
244template <class T> 
245inline bool 
246Box<T>::intersects(const Box<T> &box) const 
247
248 for (unsigned int i = 0; i < min.dimensions(); i++) 
249
250 if (box.max[i] < min[i] || box.min[i] > max[i]) 
251 return false
252
253 
254 return true
255
256 
257 
258template <class T>  
259inline
260Box<T>::size() const  
261{  
262 if (isEmpty()) 
263 return T (0); 
264 
265 return max - min
266
267 
268 
269template <class T>  
270inline
271Box<T>::center() const  
272{  
273 return (max + min) / 2
274
275 
276 
277template <class T> 
278inline bool 
279Box<T>::isEmpty() const 
280
281 for (unsigned int i = 0; i < min.dimensions(); i++) 
282
283 if (max[i] < min[i]) 
284 return true
285
286 
287 return false
288
289 
290template <class T> 
291inline bool 
292Box<T>::isInfinite() const 
293
294 for (unsigned int i = 0; i < min.dimensions(); i++) 
295
296 if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax()) 
297 return false
298
299 
300 return true
301
302 
303 
304template <class T> 
305inline bool 
306Box<T>::hasVolume() const 
307
308 for (unsigned int i = 0; i < min.dimensions(); i++) 
309
310 if (max[i] <= min[i]) 
311 return false
312
313 
314 return true
315
316 
317 
318template<class T> 
319inline unsigned int 
320Box<T>::majorAxis() const 
321
322 unsigned int major = 0
323 T s = size(); 
324 
325 for (unsigned int i = 1; i < min.dimensions(); i++) 
326
327 if (s[i] > s[major]) 
328 major = i
329
330 
331 return major
332
333 
334//------------------------------------------------------------------- 
335// 
336// Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T> 
337// 
338//------------------------------------------------------------------- 
339 
340template <typename T> class Box
341 
342template <class T> 
343class Box<Vec2<T> > 
344
345 public
346 
347 //------------------------- 
348 // Data Members are public 
349 //------------------------- 
350 
351 Vec2<T> min
352 Vec2<T> max
353 
354 //----------------------------------------------------- 
355 // Constructors - an "empty" box is created by default 
356 //----------------------------------------------------- 
357 
358 Box();  
359 Box (const Vec2<T> &point); 
360 Box (const Vec2<T> &minT, const Vec2<T> &maxT); 
361 
362 //-------------------- 
363 // Operators: ==, != 
364 //-------------------- 
365 
366 bool operator == (const Box<Vec2<T> > &src) const
367 bool operator != (const Box<Vec2<T> > &src) const
368 
369 //------------------ 
370 // Box manipulation 
371 //------------------ 
372 
373 void makeEmpty(); 
374 void extendBy (const Vec2<T> &point); 
375 void extendBy (const Box<Vec2<T> > &box); 
376 void makeInfinite(); 
377 
378 //--------------------------------------------------- 
379 // Query functions - these compute results each time 
380 //--------------------------------------------------- 
381 
382 Vec2<T> size() const
383 Vec2<T> center() const
384 bool intersects (const Vec2<T> &point) const
385 bool intersects (const Box<Vec2<T> > &box) const
386 
387 unsigned int majorAxis() const
388 
389 //---------------- 
390 // Classification 
391 //---------------- 
392 
393 bool isEmpty() const
394 bool hasVolume() const
395 bool isInfinite() const
396}; 
397 
398 
399//---------------- 
400// Implementation 
401 
402template <class T> 
403inline Box<Vec2<T> >::Box() 
404
405 makeEmpty(); 
406
407 
408 
409template <class T> 
410inline Box<Vec2<T> >::Box (const Vec2<T> &point
411
412 min = point
413 max = point
414
415 
416 
417template <class T> 
418inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT
419
420 min = minT
421 max = maxT
422
423 
424 
425template <class T> 
426inline bool 
427Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const 
428
429 return (min == src.min && max == src.max); 
430
431 
432 
433template <class T> 
434inline bool 
435Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const 
436
437 return (min != src.min || max != src.max); 
438
439 
440 
441template <class T> 
442inline void Box<Vec2<T> >::makeEmpty() 
443
444 min = Vec2<T>(Vec2<T>::baseTypeMax()); 
445 max = Vec2<T>(Vec2<T>::baseTypeMin()); 
446
447 
448template <class T> 
449inline void Box<Vec2<T> >::makeInfinite() 
450
451 min = Vec2<T>(Vec2<T>::baseTypeMin()); 
452 max = Vec2<T>(Vec2<T>::baseTypeMax()); 
453
454 
455 
456template <class T> 
457inline void 
458Box<Vec2<T> >::extendBy (const Vec2<T> &point
459
460 if (point[0] < min[0]) 
461 min[0] = point[0]; 
462 
463 if (point[0] > max[0]) 
464 max[0] = point[0]; 
465 
466 if (point[1] < min[1]) 
467 min[1] = point[1]; 
468 
469 if (point[1] > max[1]) 
470 max[1] = point[1]; 
471
472 
473 
474template <class T> 
475inline void 
476Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box
477
478 if (box.min[0] < min[0]) 
479 min[0] = box.min[0]; 
480 
481 if (box.max[0] > max[0]) 
482 max[0] = box.max[0]; 
483 
484 if (box.min[1] < min[1]) 
485 min[1] = box.min[1]; 
486 
487 if (box.max[1] > max[1]) 
488 max[1] = box.max[1]; 
489
490 
491 
492template <class T> 
493inline bool 
494Box<Vec2<T> >::intersects (const Vec2<T> &point) const 
495
496 if (point[0] < min[0] || point[0] > max[0] || 
497 point[1] < min[1] || point[1] > max[1]) 
498 return false
499 
500 return true
501
502 
503 
504template <class T> 
505inline bool 
506Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const 
507
508 if (box.max[0] < min[0] || box.min[0] > max[0] || 
509 box.max[1] < min[1] || box.min[1] > max[1]) 
510 return false
511 
512 return true
513
514 
515 
516template <class T>  
517inline Vec2<T> 
518Box<Vec2<T> >::size() const  
519{  
520 if (isEmpty()) 
521 return Vec2<T> (0); 
522 
523 return max - min
524
525 
526 
527template <class T>  
528inline Vec2<T> 
529Box<Vec2<T> >::center() const  
530{  
531 return (max + min) / 2
532
533 
534 
535template <class T> 
536inline bool 
537Box<Vec2<T> >::isEmpty() const 
538
539 if (max[0] < min[0] || 
540 max[1] < min[1]) 
541 return true
542 
543 return false
544
545 
546template <class T> 
547inline bool 
548Box<Vec2<T> > ::isInfinite() const 
549
550 if (min[0] != limits<T>::min() || max[0] != limits<T>::max() || 
551 min[1] != limits<T>::min() || max[1] != limits<T>::max()) 
552 return false
553  
554 return true
555
556 
557 
558template <class T> 
559inline bool 
560Box<Vec2<T> >::hasVolume() const 
561
562 if (max[0] <= min[0] || 
563 max[1] <= min[1]) 
564 return false
565 
566 return true
567
568 
569 
570template <class T> 
571inline unsigned int 
572Box<Vec2<T> >::majorAxis() const 
573
574 unsigned int major = 0
575 Vec2<T> s = size(); 
576 
577 if (s[1] > s[major]) 
578 major = 1
579 
580 return major
581
582 
583 
584template <class T> 
585class Box<Vec3<T> > 
586
587 public
588 
589 //------------------------- 
590 // Data Members are public 
591 //------------------------- 
592 
593 Vec3<T> min
594 Vec3<T> max
595 
596 //----------------------------------------------------- 
597 // Constructors - an "empty" box is created by default 
598 //----------------------------------------------------- 
599 
600 Box();  
601 Box (const Vec3<T> &point); 
602 Box (const Vec3<T> &minT, const Vec3<T> &maxT); 
603 
604 //-------------------- 
605 // Operators: ==, != 
606 //-------------------- 
607 
608 bool operator == (const Box<Vec3<T> > &src) const
609 bool operator != (const Box<Vec3<T> > &src) const
610 
611 //------------------ 
612 // Box manipulation 
613 //------------------ 
614 
615 void makeEmpty(); 
616 void extendBy (const Vec3<T> &point); 
617 void extendBy (const Box<Vec3<T> > &box); 
618 void makeInfinite (); 
619 
620 //--------------------------------------------------- 
621 // Query functions - these compute results each time 
622 //--------------------------------------------------- 
623 
624 Vec3<T> size() const
625 Vec3<T> center() const
626 bool intersects (const Vec3<T> &point) const
627 bool intersects (const Box<Vec3<T> > &box) const
628 
629 unsigned int majorAxis() const
630 
631 //---------------- 
632 // Classification 
633 //---------------- 
634 
635 bool isEmpty() const
636 bool hasVolume() const
637 bool isInfinite() const
638}; 
639 
640 
641//---------------- 
642// Implementation 
643 
644 
645template <class T> 
646inline Box<Vec3<T> >::Box() 
647
648 makeEmpty(); 
649
650 
651 
652template <class T> 
653inline Box<Vec3<T> >::Box (const Vec3<T> &point
654
655 min = point
656 max = point
657
658 
659 
660template <class T> 
661inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT
662
663 min = minT
664 max = maxT
665
666 
667 
668template <class T> 
669inline bool 
670Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const 
671
672 return (min == src.min && max == src.max); 
673
674 
675 
676template <class T> 
677inline bool 
678Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const 
679
680 return (min != src.min || max != src.max); 
681
682 
683 
684template <class T> 
685inline void Box<Vec3<T> >::makeEmpty() 
686
687 min = Vec3<T>(Vec3<T>::baseTypeMax()); 
688 max = Vec3<T>(Vec3<T>::baseTypeMin()); 
689
690 
691template <class T> 
692inline void Box<Vec3<T> >::makeInfinite() 
693
694 min = Vec3<T>(Vec3<T>::baseTypeMin()); 
695 max = Vec3<T>(Vec3<T>::baseTypeMax()); 
696
697 
698 
699template <class T> 
700inline void 
701Box<Vec3<T> >::extendBy (const Vec3<T> &point
702
703 if (point[0] < min[0]) 
704 min[0] = point[0]; 
705 
706 if (point[0] > max[0]) 
707 max[0] = point[0]; 
708 
709 if (point[1] < min[1]) 
710 min[1] = point[1]; 
711 
712 if (point[1] > max[1]) 
713 max[1] = point[1]; 
714 
715 if (point[2] < min[2]) 
716 min[2] = point[2]; 
717 
718 if (point[2] > max[2]) 
719 max[2] = point[2]; 
720
721 
722 
723template <class T> 
724inline void 
725Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box
726
727 if (box.min[0] < min[0]) 
728 min[0] = box.min[0]; 
729 
730 if (box.max[0] > max[0]) 
731 max[0] = box.max[0]; 
732 
733 if (box.min[1] < min[1]) 
734 min[1] = box.min[1]; 
735 
736 if (box.max[1] > max[1]) 
737 max[1] = box.max[1]; 
738 
739 if (box.min[2] < min[2]) 
740 min[2] = box.min[2]; 
741 
742 if (box.max[2] > max[2]) 
743 max[2] = box.max[2]; 
744
745 
746 
747template <class T> 
748inline bool 
749Box<Vec3<T> >::intersects (const Vec3<T> &point) const 
750
751 if (point[0] < min[0] || point[0] > max[0] || 
752 point[1] < min[1] || point[1] > max[1] || 
753 point[2] < min[2] || point[2] > max[2]) 
754 return false
755 
756 return true
757
758 
759 
760template <class T> 
761inline bool 
762Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const 
763
764 if (box.max[0] < min[0] || box.min[0] > max[0] || 
765 box.max[1] < min[1] || box.min[1] > max[1] || 
766 box.max[2] < min[2] || box.min[2] > max[2]) 
767 return false
768 
769 return true
770
771 
772 
773template <class T>  
774inline Vec3<T> 
775Box<Vec3<T> >::size() const  
776{  
777 if (isEmpty()) 
778 return Vec3<T> (0); 
779 
780 return max - min
781
782 
783 
784template <class T>  
785inline Vec3<T> 
786Box<Vec3<T> >::center() const  
787{  
788 return (max + min) / 2
789
790 
791 
792template <class T> 
793inline bool 
794Box<Vec3<T> >::isEmpty() const 
795
796 if (max[0] < min[0] || 
797 max[1] < min[1] || 
798 max[2] < min[2]) 
799 return true
800 
801 return false
802
803 
804template <class T> 
805inline bool 
806Box<Vec3<T> >::isInfinite() const 
807
808 if (min[0] != limits<T>::min() || max[0] != limits<T>::max() || 
809 min[1] != limits<T>::min() || max[1] != limits<T>::max() || 
810 min[2] != limits<T>::min() || max[2] != limits<T>::max()) 
811 return false
812  
813 return true
814
815 
816 
817template <class T> 
818inline bool 
819Box<Vec3<T> >::hasVolume() const 
820
821 if (max[0] <= min[0] || 
822 max[1] <= min[1] || 
823 max[2] <= min[2]) 
824 return false
825 
826 return true
827
828 
829 
830template <class T> 
831inline unsigned int 
832Box<Vec3<T> >::majorAxis() const 
833
834 unsigned int major = 0
835 Vec3<T> s = size(); 
836 
837 if (s[1] > s[major]) 
838 major = 1
839 
840 if (s[2] > s[major]) 
841 major = 2
842 
843 return major
844
845 
846 
847IMATH_INTERNAL_NAMESPACE_HEADER_EXIT 
848 
849#endif // INCLUDED_IMATHBOX_H 
850