Fix for [#36374] Read unitialized memory in Freestyle.
[blender-staging.git] / source / blender / freestyle / intern / geometry / BBox.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 #ifndef __BBOX_H__
22 #define __BBOX_H__
23
24 /** \file blender/freestyle/intern/geometry/BBox.h
25  *  \ingroup freestyle
26  *  \brief A class to hold a bounding box
27  *  \author Stephane Grabli
28  *  \date 22/05/2003
29  */
30
31 #include "BLI_utildefines.h"
32
33 #ifdef WITH_CXX_GUARDEDALLOC
34 #include "MEM_guardedalloc.h"
35 #endif
36
37 namespace Freestyle {
38
39 template <class Point>
40 class BBox
41 {
42 public:
43         inline BBox()
44         {
45                 _empty = true;
46         }
47
48         template <class T>
49         inline BBox(const T& min_in, const T& max_in) : _min(min_in), _max(max_in)
50         {
51                 _empty = false;
52         }
53
54         template <class T>
55         inline BBox(const BBox<T>& b) : _min(b.getMin()), _max(b.getMax())
56         {
57                 _empty = false;
58         }
59
60         template <class T>
61         inline void extendToContain(const T& p)
62         {
63                 if (_empty) {
64                         _min = p;
65                         _max = p;
66                         _empty = false;
67                         return;
68                 }
69                 for (unsigned int i = 0; i < Point::dim(); i++) {
70                         if (p[i] < _min[i])
71                                 _min[i] = p[i];
72                         else if (p[i] > _max[i])
73                                 _max[i] = p[i];
74                 }
75                 _empty = false;
76         }
77
78         inline void clear()
79         {
80                 _empty = true;
81         }
82
83         inline bool empty() const
84         {
85                 return _empty;
86         }
87
88         inline const Point& getMin() const
89         {
90                 return _min;
91         }
92
93         inline const Point& getMax() const
94         {
95                 return _max;
96         }
97
98         inline BBox<Point>& operator=(const BBox<Point>& b)
99         {
100                 BLI_assert(!b.empty());
101                 _min = b.getMin();
102                 _max = b.getMax();
103                 _empty = false;
104                 return *this;
105         }
106
107         inline BBox<Point>& operator+=(const BBox<Point>& b)
108         {
109                 BLI_assert(!b.empty());
110                 if (_empty) {
111                         _min = b.getMin();
112                         _max = b.getMax();
113                         _empty = false;
114                 }
115                 else {
116                         for (unsigned int i = 0; i < Point::dim(); i++) {
117                                 if (b.getMin()[i] < _min[i])
118                                         _min[i] = b.getMin()[i];
119                                 if (b.getMax()[i] > _max[i])
120                                         _max[i] = b.getMax()[i];
121                         }
122                 }
123                 return *this;
124         }
125
126         inline bool inside(const Point& p)
127         {
128                 if (empty())
129                         return false;
130                 for (unsigned int i = 0; i < Point::dim(); i++) {
131                         if ((_min[i]>p[i]) || (_max[i]<p[i]))
132                                 return false;
133                 }
134                 return true;
135         }
136
137 private:
138         Point _min;
139         Point _max;
140         bool _empty;
141
142 #ifdef WITH_CXX_GUARDEDALLOC
143         MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BBox")
144 #endif
145 };
146
147 template <class Point>
148 BBox<Point>& operator+(const BBox<Point> &b1, const BBox<Point> &b2)
149 {
150         Point new_min;
151         Point new_max;
152
153         for (unsigned int i = 0; i < Point::dim(); i++) {
154                 new_min[i] = b1.getMin()[i] < b2.getMin()[i] ? b1.getMin()[i] : b2.getMin()[i];
155                 new_max[i] = b1.getMax()[i] > b2.getMax()[i] ? b1.getMax()[i] : b2.getMax()[i];
156         }
157
158         return BBox<Point>(new_min, new_max);
159 }
160
161 } /* namespace Freestyle */
162
163 #endif // __BBOX_H__