0027202: Visualization - add sensitivity Select3D_SensitivePrimitiveArray for Graphic...
[occt.git] / src / BVH / BVH_Box.hxx
CommitLineData
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 26template<class T, int N>
27class BVH_Box
28{
29public:
30
3a7a7013 31 typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
3c4e78f2 32
33public:
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
57public:
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 96protected:
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 104namespace 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