PageRenderTime 51ms CodeModel.GetById 15ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/OpenEXR/Imath/ImathBox.h

https://bitbucket.org/cabalistic/ogredeps/
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