/src/FreeImage/Source/OpenEXR/Imath/ImathBox.h
C++ Header | 787 lines | 467 code | 194 blank | 126 comment | 92 complexity | 07ffe004658862ac32d1f71ef4968094 MD5 | raw file
1/////////////////////////////////////////////////////////////////////////// 2// 3// Copyright (c) 2004, 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 67namespace Imath { 68 69 70template <class T> 71class Box 72{ 73 public: 74 75 //------------------------- 76 // Data Members are public 77 //------------------------- 78 79 T min; 80 T max; 81 82 //----------------------------------------------------- 83 // Constructors - an "empty" box is created by default 84 //----------------------------------------------------- 85 86 Box (); 87 Box (const T &point); 88 Box (const T &minT, const T &maxT); 89 90 //-------------------- 91 // Operators: ==, != 92 //-------------------- 93 94 bool operator == (const Box<T> &src) const; 95 bool operator != (const Box<T> &src) const; 96 97 //------------------ 98 // Box manipulation 99 //------------------ 100 101 void makeEmpty (); 102 void extendBy (const T &point); 103 void extendBy (const Box<T> &box); 104 105 //--------------------------------------------------- 106 // Query functions - these compute results each time 107 //--------------------------------------------------- 108 109 T size () const; 110 T center () const; 111 bool intersects (const T &point) const; 112 bool intersects (const Box<T> &box) const; 113 114 unsigned int majorAxis () const; 115 116 //---------------- 117 // Classification 118 //---------------- 119 120 bool isEmpty () const; 121 bool hasVolume () const; 122}; 123 124 125//-------------------- 126// Convenient typedefs 127//-------------------- 128 129typedef Box <V2s> Box2s; 130typedef Box <V2i> Box2i; 131typedef Box <V2f> Box2f; 132typedef Box <V2d> Box2d; 133typedef Box <V3s> Box3s; 134typedef Box <V3i> Box3i; 135typedef Box <V3f> Box3f; 136typedef Box <V3d> Box3d; 137 138 139//---------------- 140// Implementation 141 142 143template <class T> 144inline Box<T>::Box() 145{ 146 makeEmpty(); 147} 148 149 150template <class T> 151inline Box<T>::Box (const T &point) 152{ 153 min = point; 154 max = point; 155} 156 157 158template <class T> 159inline Box<T>::Box (const T &minT, const T &maxT) 160{ 161 min = minT; 162 max = maxT; 163} 164 165 166template <class T> 167inline bool 168Box<T>::operator == (const Box<T> &src) const 169{ 170 return (min == src.min && max == src.max); 171} 172 173 174template <class T> 175inline bool 176Box<T>::operator != (const Box<T> &src) const 177{ 178 return (min != src.min || max != src.max); 179} 180 181 182template <class T> 183inline void Box<T>::makeEmpty() 184{ 185 min = T(T::baseTypeMax()); 186 max = T(T::baseTypeMin()); 187} 188 189 190template <class T> 191inline void 192Box<T>::extendBy(const T &point) 193{ 194 for (unsigned int i = 0; i < min.dimensions(); i++) 195 { 196 if (point[i] < min[i]) 197 min[i] = point[i]; 198 199 if (point[i] > max[i]) 200 max[i] = point[i]; 201 } 202} 203 204 205template <class T> 206inline void 207Box<T>::extendBy(const Box<T> &box) 208{ 209 for (unsigned int i = 0; i < min.dimensions(); i++) 210 { 211 if (box.min[i] < min[i]) 212 min[i] = box.min[i]; 213 214 if (box.max[i] > max[i]) 215 max[i] = box.max[i]; 216 } 217} 218 219 220template <class T> 221inline bool 222Box<T>::intersects(const T &point) const 223{ 224 for (unsigned int i = 0; i < min.dimensions(); i++) 225 { 226 if (point[i] < min[i] || point[i] > max[i]) 227 return false; 228 } 229 230 return true; 231} 232 233 234template <class T> 235inline bool 236Box<T>::intersects(const Box<T> &box) const 237{ 238 for (unsigned int i = 0; i < min.dimensions(); i++) 239 { 240 if (box.max[i] < min[i] || box.min[i] > max[i]) 241 return false; 242 } 243 244 return true; 245} 246 247 248template <class T> 249inline T 250Box<T>::size() const 251{ 252 if (isEmpty()) 253 return T (0); 254 255 return max - min; 256} 257 258 259template <class T> 260inline T 261Box<T>::center() const 262{ 263 return (max + min) / 2; 264} 265 266 267template <class T> 268inline bool 269Box<T>::isEmpty() const 270{ 271 for (unsigned int i = 0; i < min.dimensions(); i++) 272 { 273 if (max[i] < min[i]) 274 return true; 275 } 276 277 return false; 278} 279 280 281template <class T> 282inline bool 283Box<T>::hasVolume() const 284{ 285 for (unsigned int i = 0; i < min.dimensions(); i++) 286 { 287 if (max[i] <= min[i]) 288 return false; 289 } 290 291 return true; 292} 293 294 295template<class T> 296inline unsigned int 297Box<T>::majorAxis() const 298{ 299 unsigned int major = 0; 300 T s = size(); 301 302 for (unsigned int i = 1; i < min.dimensions(); i++) 303 { 304 if (s[i] > s[major]) 305 major = i; 306 } 307 308 return major; 309} 310 311//------------------------------------------------------------------- 312// 313// Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T> 314// 315//------------------------------------------------------------------- 316 317template <typename T> class Box; 318 319template <class T> 320class Box<Vec2<T> > 321{ 322 public: 323 324 //------------------------- 325 // Data Members are public 326 //------------------------- 327 328 Vec2<T> min; 329 Vec2<T> max; 330 331 //----------------------------------------------------- 332 // Constructors - an "empty" box is created by default 333 //----------------------------------------------------- 334 335 Box(); 336 Box (const Vec2<T> &point); 337 Box (const Vec2<T> &minT, const Vec2<T> &maxT); 338 339 //-------------------- 340 // Operators: ==, != 341 //-------------------- 342 343 bool operator == (const Box<Vec2<T> > &src) const; 344 bool operator != (const Box<Vec2<T> > &src) const; 345 346 //------------------ 347 // Box manipulation 348 //------------------ 349 350 void makeEmpty(); 351 void extendBy (const Vec2<T> &point); 352 void extendBy (const Box<Vec2<T> > &box); 353 354 //--------------------------------------------------- 355 // Query functions - these compute results each time 356 //--------------------------------------------------- 357 358 Vec2<T> size() const; 359 Vec2<T> center() const; 360 bool intersects (const Vec2<T> &point) const; 361 bool intersects (const Box<Vec2<T> > &box) const; 362 363 unsigned int majorAxis() const; 364 365 //---------------- 366 // Classification 367 //---------------- 368 369 bool isEmpty() const; 370 bool hasVolume() const; 371}; 372 373 374//---------------- 375// Implementation 376 377template <class T> 378inline Box<Vec2<T> >::Box() 379{ 380 makeEmpty(); 381} 382 383 384template <class T> 385inline Box<Vec2<T> >::Box (const Vec2<T> &point) 386{ 387 min = point; 388 max = point; 389} 390 391 392template <class T> 393inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT) 394{ 395 min = minT; 396 max = maxT; 397} 398 399 400template <class T> 401inline bool 402Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const 403{ 404 return (min == src.min && max == src.max); 405} 406 407 408template <class T> 409inline bool 410Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const 411{ 412 return (min != src.min || max != src.max); 413} 414 415 416template <class T> 417inline void Box<Vec2<T> >::makeEmpty() 418{ 419 min = Vec2<T>(Vec2<T>::baseTypeMax()); 420 max = Vec2<T>(Vec2<T>::baseTypeMin()); 421} 422 423 424template <class T> 425inline void 426Box<Vec2<T> >::extendBy (const Vec2<T> &point) 427{ 428 if (point[0] < min[0]) 429 min[0] = point[0]; 430 431 if (point[0] > max[0]) 432 max[0] = point[0]; 433 434 if (point[1] < min[1]) 435 min[1] = point[1]; 436 437 if (point[1] > max[1]) 438 max[1] = point[1]; 439} 440 441 442template <class T> 443inline void 444Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box) 445{ 446 if (box.min[0] < min[0]) 447 min[0] = box.min[0]; 448 449 if (box.max[0] > max[0]) 450 max[0] = box.max[0]; 451 452 if (box.min[1] < min[1]) 453 min[1] = box.min[1]; 454 455 if (box.max[1] > max[1]) 456 max[1] = box.max[1]; 457} 458 459 460template <class T> 461inline bool 462Box<Vec2<T> >::intersects (const Vec2<T> &point) const 463{ 464 if (point[0] < min[0] || point[0] > max[0] || 465 point[1] < min[1] || point[1] > max[1]) 466 return false; 467 468 return true; 469} 470 471 472template <class T> 473inline bool 474Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const 475{ 476 if (box.max[0] < min[0] || box.min[0] > max[0] || 477 box.max[1] < min[1] || box.min[1] > max[1]) 478 return false; 479 480 return true; 481} 482 483 484template <class T> 485inline Vec2<T> 486Box<Vec2<T> >::size() const 487{ 488 if (isEmpty()) 489 return Vec2<T> (0); 490 491 return max - min; 492} 493 494 495template <class T> 496inline Vec2<T> 497Box<Vec2<T> >::center() const 498{ 499 return (max + min) / 2; 500} 501 502 503template <class T> 504inline bool 505Box<Vec2<T> >::isEmpty() const 506{ 507 if (max[0] < min[0] || 508 max[1] < min[1]) 509 return true; 510 511 return false; 512} 513 514 515template <class T> 516inline bool 517Box<Vec2<T> >::hasVolume() const 518{ 519 if (max[0] <= min[0] || 520 max[1] <= min[1]) 521 return false; 522 523 return true; 524} 525 526 527template <class T> 528inline unsigned int 529Box<Vec2<T> >::majorAxis() const 530{ 531 unsigned int major = 0; 532 Vec2<T> s = size(); 533 534 if (s[1] > s[major]) 535 major = 1; 536 537 return major; 538} 539 540 541template <class T> 542class Box<Vec3<T> > 543{ 544 public: 545 546 //------------------------- 547 // Data Members are public 548 //------------------------- 549 550 Vec3<T> min; 551 Vec3<T> max; 552 553 //----------------------------------------------------- 554 // Constructors - an "empty" box is created by default 555 //----------------------------------------------------- 556 557 Box(); 558 Box (const Vec3<T> &point); 559 Box (const Vec3<T> &minT, const Vec3<T> &maxT); 560 561 //-------------------- 562 // Operators: ==, != 563 //-------------------- 564 565 bool operator == (const Box<Vec3<T> > &src) const; 566 bool operator != (const Box<Vec3<T> > &src) const; 567 568 //------------------ 569 // Box manipulation 570 //------------------ 571 572 void makeEmpty(); 573 void extendBy (const Vec3<T> &point); 574 void extendBy (const Box<Vec3<T> > &box); 575 576 //--------------------------------------------------- 577 // Query functions - these compute results each time 578 //--------------------------------------------------- 579 580 Vec3<T> size() const; 581 Vec3<T> center() const; 582 bool intersects (const Vec3<T> &point) const; 583 bool intersects (const Box<Vec3<T> > &box) const; 584 585 unsigned int majorAxis() const; 586 587 //---------------- 588 // Classification 589 //---------------- 590 591 bool isEmpty() const; 592 bool hasVolume() const; 593}; 594 595 596//---------------- 597// Implementation 598 599 600template <class T> 601inline Box<Vec3<T> >::Box() 602{ 603 makeEmpty(); 604} 605 606 607template <class T> 608inline Box<Vec3<T> >::Box (const Vec3<T> &point) 609{ 610 min = point; 611 max = point; 612} 613 614 615template <class T> 616inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT) 617{ 618 min = minT; 619 max = maxT; 620} 621 622 623template <class T> 624inline bool 625Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const 626{ 627 return (min == src.min && max == src.max); 628} 629 630 631template <class T> 632inline bool 633Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const 634{ 635 return (min != src.min || max != src.max); 636} 637 638 639template <class T> 640inline void Box<Vec3<T> >::makeEmpty() 641{ 642 min = Vec3<T>(Vec3<T>::baseTypeMax()); 643 max = Vec3<T>(Vec3<T>::baseTypeMin()); 644} 645 646 647template <class T> 648inline void 649Box<Vec3<T> >::extendBy (const Vec3<T> &point) 650{ 651 if (point[0] < min[0]) 652 min[0] = point[0]; 653 654 if (point[0] > max[0]) 655 max[0] = point[0]; 656 657 if (point[1] < min[1]) 658 min[1] = point[1]; 659 660 if (point[1] > max[1]) 661 max[1] = point[1]; 662 663 if (point[2] < min[2]) 664 min[2] = point[2]; 665 666 if (point[2] > max[2]) 667 max[2] = point[2]; 668} 669 670 671template <class T> 672inline void 673Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box) 674{ 675 if (box.min[0] < min[0]) 676 min[0] = box.min[0]; 677 678 if (box.max[0] > max[0]) 679 max[0] = box.max[0]; 680 681 if (box.min[1] < min[1]) 682 min[1] = box.min[1]; 683 684 if (box.max[1] > max[1]) 685 max[1] = box.max[1]; 686 687 if (box.min[2] < min[2]) 688 min[2] = box.min[2]; 689 690 if (box.max[2] > max[2]) 691 max[2] = box.max[2]; 692} 693 694 695template <class T> 696inline bool 697Box<Vec3<T> >::intersects (const Vec3<T> &point) const 698{ 699 if (point[0] < min[0] || point[0] > max[0] || 700 point[1] < min[1] || point[1] > max[1] || 701 point[2] < min[2] || point[2] > max[2]) 702 return false; 703 704 return true; 705} 706 707 708template <class T> 709inline bool 710Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const 711{ 712 if (box.max[0] < min[0] || box.min[0] > max[0] || 713 box.max[1] < min[1] || box.min[1] > max[1] || 714 box.max[2] < min[2] || box.min[2] > max[2]) 715 return false; 716 717 return true; 718} 719 720 721template <class T> 722inline Vec3<T> 723Box<Vec3<T> >::size() const 724{ 725 if (isEmpty()) 726 return Vec3<T> (0); 727 728 return max - min; 729} 730 731 732template <class T> 733inline Vec3<T> 734Box<Vec3<T> >::center() const 735{ 736 return (max + min) / 2; 737} 738 739 740template <class T> 741inline bool 742Box<Vec3<T> >::isEmpty() const 743{ 744 if (max[0] < min[0] || 745 max[1] < min[1] || 746 max[2] < min[2]) 747 return true; 748 749 return false; 750} 751 752 753template <class T> 754inline bool 755Box<Vec3<T> >::hasVolume() const 756{ 757 if (max[0] <= min[0] || 758 max[1] <= min[1] || 759 max[2] <= min[2]) 760 return false; 761 762 return true; 763} 764 765 766template <class T> 767inline unsigned int 768Box<Vec3<T> >::majorAxis() const 769{ 770 unsigned int major = 0; 771 Vec3<T> s = size(); 772 773 if (s[1] > s[major]) 774 major = 1; 775 776 if (s[2] > s[major]) 777 major = 2; 778 779 return major; 780} 781 782 783 784 785} // namespace Imath 786 787#endif