Coverage Report

Created: 2023-12-08 06:53

/src/freeimage-svn/FreeImage/trunk/Source/OpenEXR/Imath/ImathBox.h
Line
Count
Source (jump to first uncovered line)
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
68
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
69
70
71
template <class T>  
72
class 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
132
typedef Box <V2s> Box2s;
133
typedef Box <V2i> Box2i;
134
typedef Box <V2f> Box2f;
135
typedef Box <V2d> Box2d;
136
typedef Box <V3s> Box3s;
137
typedef Box <V3i> Box3i;
138
typedef Box <V3f> Box3f;
139
typedef Box <V3d> Box3d;
140
141
142
//----------------
143
//  Implementation
144
145
146
template <class T>
147
inline Box<T>::Box()
148
{
149
    makeEmpty();
150
}
151
152
153
template <class T>
154
inline Box<T>::Box (const T &point)
155
{
156
    min = point;
157
    max = point;
158
}
159
160
161
template <class T>
162
inline Box<T>::Box (const T &minT, const T &maxT)
163
{
164
    min = minT;
165
    max = maxT;
166
}
167
168
169
template <class T>
170
inline bool
171
Box<T>::operator == (const Box<T> &src) const
172
{
173
    return (min == src.min && max == src.max);
174
}
175
176
177
template <class T>
178
inline bool
179
Box<T>::operator != (const Box<T> &src) const
180
{
181
    return (min != src.min || max != src.max);
182
}
183
184
185
template <class T>
186
inline void Box<T>::makeEmpty()
187
{
188
    min = T(T::baseTypeMax());
189
    max = T(T::baseTypeMin());
190
}
191
192
template <class T>
193
inline void Box<T>::makeInfinite()
194
{
195
    min = T(T::baseTypeMin());
196
    max = T(T::baseTypeMax());
197
}
198
199
200
template <class T>
201
inline void
202
Box<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
215
template <class T>
216
inline void
217
Box<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
230
template <class T>
231
inline bool
232
Box<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
244
template <class T>
245
inline bool
246
Box<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
258
template <class T> 
259
inline T
260
Box<T>::size() const 
261
{ 
262
    if (isEmpty())
263
  return T (0);
264
265
    return max - min;
266
}
267
268
269
template <class T> 
270
inline T
271
Box<T>::center() const 
272
{ 
273
    return (max + min) / 2;
274
}
275
276
277
template <class T>
278
inline bool
279
Box<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
290
template <class T>
291
inline bool
292
Box<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
304
template <class T>
305
inline bool
306
Box<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
318
template<class T>
319
inline unsigned int
320
Box<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
340
template <typename T> class Box;
341
342
template <class T>
343
class 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
402
template <class T>
403
inline Box<Vec2<T> >::Box()
404
0
{
405
0
    makeEmpty();
406
0
}
Unexecuted instantiation: Imath_2_2::Box<Imath_2_2::Vec2<int> >::Box()
Unexecuted instantiation: Imath_2_2::Box<Imath_2_2::Vec2<float> >::Box()
407
408
409
template <class T>
410
inline Box<Vec2<T> >::Box (const Vec2<T> &point)
411
{
412
    min = point;
413
    max = point;
414
}
415
416
417
template <class T>
418
inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
419
0
{
420
0
    min = minT;
421
0
    max = maxT;
422
0
}
423
424
425
template <class T>
426
inline bool
427
Box<Vec2<T> >::operator ==  (const Box<Vec2<T> > &src) const
428
0
{
429
0
    return (min == src.min && max == src.max);
430
0
}
431
432
433
template <class T>
434
inline bool
435
Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
436
0
{
437
0
    return (min != src.min || max != src.max);
438
0
}
439
440
441
template <class T>
442
inline void Box<Vec2<T> >::makeEmpty()
443
0
{
444
0
    min = Vec2<T>(Vec2<T>::baseTypeMax());
445
0
    max = Vec2<T>(Vec2<T>::baseTypeMin());
446
0
}
Unexecuted instantiation: Imath_2_2::Box<Imath_2_2::Vec2<int> >::makeEmpty()
Unexecuted instantiation: Imath_2_2::Box<Imath_2_2::Vec2<float> >::makeEmpty()
447
448
template <class T>
449
inline void Box<Vec2<T> >::makeInfinite()
450
{
451
    min = Vec2<T>(Vec2<T>::baseTypeMin());
452
    max = Vec2<T>(Vec2<T>::baseTypeMax());
453
}
454
455
456
template <class T>
457
inline void
458
Box<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
474
template <class T>
475
inline void
476
Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
477
0
{
478
0
    if (box.min[0] < min[0])
479
0
        min[0] = box.min[0];
480
481
0
    if (box.max[0] > max[0])
482
0
        max[0] = box.max[0];
483
484
0
    if (box.min[1] < min[1])
485
0
        min[1] = box.min[1];
486
487
0
    if (box.max[1] > max[1])
488
0
        max[1] = box.max[1];
489
0
}
490
491
492
template <class T>
493
inline bool
494
Box<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
504
template <class T>
505
inline bool
506
Box<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
516
template <class T> 
517
inline Vec2<T>
518
Box<Vec2<T> >::size() const 
519
0
{ 
520
0
    if (isEmpty())
521
0
        return Vec2<T> (0);
522
523
0
    return max - min;
524
0
}
525
526
527
template <class T> 
528
inline Vec2<T>
529
Box<Vec2<T> >::center() const 
530
{ 
531
    return (max + min) / 2;
532
}
533
534
535
template <class T>
536
inline bool
537
Box<Vec2<T> >::isEmpty() const
538
0
{
539
0
    if (max[0] < min[0] ||
540
0
        max[1] < min[1])
541
0
        return true;
542
543
0
    return false;
544
0
}
545
546
template <class T>
547
inline bool
548
Box<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
558
template <class T>
559
inline bool
560
Box<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
570
template <class T>
571
inline unsigned int
572
Box<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
584
template <class T>
585
class 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
645
template <class T>
646
inline Box<Vec3<T> >::Box()
647
{
648
    makeEmpty();
649
}
650
651
652
template <class T>
653
inline Box<Vec3<T> >::Box (const Vec3<T> &point)
654
{
655
    min = point;
656
    max = point;
657
}
658
659
660
template <class T>
661
inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
662
{
663
    min = minT;
664
    max = maxT;
665
}
666
667
668
template <class T>
669
inline bool
670
Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
671
{
672
    return (min == src.min && max == src.max);
673
}
674
675
676
template <class T>
677
inline bool
678
Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
679
{
680
    return (min != src.min || max != src.max);
681
}
682
683
684
template <class T>
685
inline void Box<Vec3<T> >::makeEmpty()
686
{
687
    min = Vec3<T>(Vec3<T>::baseTypeMax());
688
    max = Vec3<T>(Vec3<T>::baseTypeMin());
689
}
690
691
template <class T>
692
inline void Box<Vec3<T> >::makeInfinite()
693
{
694
    min = Vec3<T>(Vec3<T>::baseTypeMin());
695
    max = Vec3<T>(Vec3<T>::baseTypeMax());
696
}
697
698
699
template <class T>
700
inline void
701
Box<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
723
template <class T>
724
inline void
725
Box<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
747
template <class T>
748
inline bool
749
Box<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
760
template <class T>
761
inline bool
762
Box<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
773
template <class T> 
774
inline Vec3<T>
775
Box<Vec3<T> >::size() const 
776
{ 
777
    if (isEmpty())
778
        return Vec3<T> (0);
779
780
    return max - min;
781
}
782
783
784
template <class T> 
785
inline Vec3<T>
786
Box<Vec3<T> >::center() const 
787
{ 
788
    return (max + min) / 2;
789
}
790
791
792
template <class T>
793
inline bool
794
Box<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
804
template <class T>
805
inline bool
806
Box<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
817
template <class T>
818
inline bool
819
Box<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
830
template <class T>
831
inline unsigned int
832
Box<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
847
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
848
849
#endif // INCLUDED_IMATHBOX_H