3c4e78f2 |
1 | // Created on: 2013-12-20 |
2 | // Created by: Denis BOGOLEPOV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
3c4e78f2 |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
3c4e78f2 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #ifndef _BVH_Box_Header |
17 | #define _BVH_Box_Header |
18 | |
19 | #include <BVH_Types.hxx> |
20 | |
0bb09048 |
21 | #include <limits> |
22 | |
679d3878 |
23 | //! Defines axis aligned bounding box (AABB) based on BVH vectors. |
24 | //! \tparam T Numeric data type |
25 | //! \tparam N Vector dimension |
3c4e78f2 |
26 | template<class T, int N> |
27 | class BVH_Box |
28 | { |
29 | public: |
30 | |
3a7a7013 |
31 | typedef typename BVH::VectorType<T, N>::Type BVH_VecNt; |
3c4e78f2 |
32 | |
33 | public: |
34 | |
35 | //! Creates uninitialized bounding box. |
679d3878 |
36 | BVH_Box() : myIsInited (Standard_False) {} |
3c4e78f2 |
37 | |
38 | //! Creates bounding box of given point. |
39 | BVH_Box (const BVH_VecNt& thePoint) |
679d3878 |
40 | : myMinPoint (thePoint), |
41 | myMaxPoint (thePoint), |
42 | myIsInited (Standard_True) {} |
3c4e78f2 |
43 | |
44 | //! Creates copy of another bounding box. |
45 | BVH_Box (const BVH_Box& theBox) |
679d3878 |
46 | : myMinPoint (theBox.myMinPoint), |
47 | myMaxPoint (theBox.myMaxPoint), |
48 | myIsInited (theBox.myIsInited) {} |
3c4e78f2 |
49 | |
50 | //! Creates bounding box from corner points. |
51 | BVH_Box (const BVH_VecNt& theMinPoint, |
52 | const BVH_VecNt& theMaxPoint) |
679d3878 |
53 | : myMinPoint (theMinPoint), |
54 | myMaxPoint (theMaxPoint), |
55 | myIsInited (Standard_True) {} |
3c4e78f2 |
56 | |
57 | public: |
58 | |
59 | //! Clears bounding box. |
60 | void Clear(); |
61 | |
62 | //! Is bounding box valid? |
63 | Standard_Boolean IsValid() const; |
64 | |
65 | //! Appends new point to the bounding box. |
66 | void Add (const BVH_VecNt& thePoint); |
67 | |
68 | //! Combines bounding box with another one. |
69 | void Combine (const BVH_Box& theVolume); |
70 | |
71 | //! Returns minimum point of bounding box. |
72 | const BVH_VecNt& CornerMin() const; |
73 | |
74 | //! Returns maximum point of bounding box. |
75 | const BVH_VecNt& CornerMax() const; |
76 | |
77 | //! Returns minimum point of bounding box. |
78 | BVH_VecNt& CornerMin(); |
79 | |
80 | //! Returns maximum point of bounding box. |
81 | BVH_VecNt& CornerMax(); |
82 | |
83 | //! Returns surface area of bounding box. |
0bb09048 |
84 | //! If the box is degenerated into line, returns the perimeter instead. |
3c4e78f2 |
85 | T Area() const; |
86 | |
87 | //! Returns diagonal of bounding box. |
88 | BVH_VecNt Size() const; |
89 | |
90 | //! Returns center of bounding box. |
91 | BVH_VecNt Center() const; |
92 | |
679d3878 |
93 | //! Returns center of bounding box along the given axis. |
94 | T Center (const Standard_Integer theAxis) const; |
95 | |
3c4e78f2 |
96 | protected: |
97 | |
679d3878 |
98 | BVH_VecNt myMinPoint; //!< Minimum point of bounding box |
99 | BVH_VecNt myMaxPoint; //!< Maximum point of bounding box |
100 | Standard_Boolean myIsInited; //!< Is bounding box initialized? |
3c4e78f2 |
101 | |
102 | }; |
103 | |
679d3878 |
104 | namespace BVH |
105 | { |
106 | //! Tool class for calculating box center along the given axis. |
107 | //! \tparam T Numeric data type |
108 | //! \tparam N Vector dimension |
109 | template<class T, int N> |
110 | struct CenterAxis |
111 | { |
112 | // Not implemented |
113 | }; |
114 | |
115 | template<class T> |
116 | struct CenterAxis<T, 2> |
117 | { |
118 | static T Center (const BVH_Box<T, 2>& theBox, const Standard_Integer theAxis) |
119 | { |
120 | if (theAxis == 0) |
121 | { |
122 | return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5); |
123 | } |
124 | else if (theAxis == 1) |
125 | { |
126 | return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5); |
127 | } |
128 | return static_cast<T> (0.0); |
129 | } |
130 | }; |
131 | |
132 | template<class T> |
133 | struct CenterAxis<T, 3> |
134 | { |
135 | static T Center (const BVH_Box<T, 3>& theBox, const Standard_Integer theAxis) |
136 | { |
137 | if (theAxis == 0) |
138 | { |
139 | return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5); |
140 | } |
141 | else if (theAxis == 1) |
142 | { |
143 | return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5); |
144 | } |
145 | else if (theAxis == 2) |
146 | { |
147 | return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5); |
148 | } |
149 | return static_cast<T> (0.0); |
150 | } |
151 | }; |
152 | |
153 | template<class T> |
154 | struct CenterAxis<T, 4> |
155 | { |
156 | static T Center (const BVH_Box<T, 4>& theBox, const Standard_Integer theAxis) |
157 | { |
158 | if (theAxis == 0) |
159 | { |
160 | return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5); |
161 | } |
162 | else if (theAxis == 1) |
163 | { |
164 | return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5); |
165 | } |
166 | else if (theAxis == 2) |
167 | { |
168 | return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5); |
169 | } |
170 | return static_cast<T> (0.0); |
171 | } |
172 | }; |
173 | |
174 | //! Tool class for calculating surface area of the box. |
175 | //! \tparam T Numeric data type |
176 | //! \tparam N Vector dimension |
177 | template<class T, int N> |
178 | struct SurfaceCalculator |
179 | { |
180 | // Not implemented |
181 | }; |
182 | |
183 | template<class T> |
184 | struct SurfaceCalculator<T, 2> |
185 | { |
186 | static T Area (const typename BVH_Box<T, 2>::BVH_VecNt& theSize) |
187 | { |
0bb09048 |
188 | const T anArea = theSize.x() * theSize.y(); |
189 | |
190 | if (anArea < std::numeric_limits<T>::epsilon()) |
191 | { |
192 | return theSize.x() + theSize.y(); |
193 | } |
194 | |
195 | return anArea; |
679d3878 |
196 | } |
197 | }; |
198 | |
199 | template<class T> |
200 | struct SurfaceCalculator<T, 3> |
201 | { |
202 | static T Area (const typename BVH_Box<T, 3>::BVH_VecNt& theSize) |
203 | { |
0bb09048 |
204 | const T anArea = ( theSize.x() * theSize.y() + |
205 | theSize.x() * theSize.z() + |
206 | theSize.z() * theSize.y() ) * static_cast<T> (2.0); |
207 | |
208 | if (anArea < std::numeric_limits<T>::epsilon()) |
209 | { |
210 | return theSize.x() + |
211 | theSize.y() + |
212 | theSize.z(); |
213 | } |
214 | |
215 | return anArea; |
679d3878 |
216 | } |
217 | }; |
218 | |
219 | template<class T> |
220 | struct SurfaceCalculator<T, 4> |
221 | { |
222 | static T Area (const typename BVH_Box<T, 4>::BVH_VecNt& theSize) |
223 | { |
0bb09048 |
224 | const T anArea = ( theSize.x() * theSize.y() + |
225 | theSize.x() * theSize.z() + |
226 | theSize.z() * theSize.y() ) * static_cast<T> (2.0); |
227 | |
228 | if (anArea < std::numeric_limits<T>::epsilon()) |
229 | { |
230 | return theSize.x() + |
231 | theSize.y() + |
232 | theSize.z(); |
233 | } |
234 | |
235 | return anArea; |
679d3878 |
236 | } |
237 | }; |
238 | |
239 | //! Tool class for calculate component-wise vector minimum |
240 | //! and maximum (optimized version). |
241 | //! \tparam T Numeric data type |
242 | //! \tparam N Vector dimension |
243 | template<class T, int N> |
244 | struct BoxMinMax |
245 | { |
246 | typedef typename BVH::VectorType<T, N>::Type BVH_VecNt; |
247 | |
248 | static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) |
249 | { |
250 | theVec1.x() = Min (theVec1.x(), theVec2.x()); |
251 | theVec1.y() = Min (theVec1.y(), theVec2.y()); |
252 | theVec1.z() = Min (theVec1.z(), theVec2.z()); |
253 | } |
254 | |
255 | static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) |
256 | { |
257 | theVec1.x() = Max (theVec1.x(), theVec2.x()); |
258 | theVec1.y() = Max (theVec1.y(), theVec2.y()); |
259 | theVec1.z() = Max (theVec1.z(), theVec2.z()); |
260 | } |
261 | }; |
262 | |
263 | template<class T> |
264 | struct BoxMinMax<T, 2> |
265 | { |
266 | typedef typename BVH::VectorType<T, 2>::Type BVH_VecNt; |
267 | |
268 | static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) |
269 | { |
270 | theVec1.x() = Min (theVec1.x(), theVec2.x()); |
271 | theVec1.y() = Min (theVec1.y(), theVec2.y()); |
272 | } |
273 | |
274 | static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2) |
275 | { |
276 | theVec1.x() = Max (theVec1.x(), theVec2.x()); |
277 | theVec1.y() = Max (theVec1.y(), theVec2.y()); |
278 | } |
279 | }; |
280 | } |
281 | |
3c4e78f2 |
282 | #include <BVH_Box.lxx> |
283 | |
284 | #endif // _BVH_Box_Header |