0030731: Modeling Data - B-Spline should have explicit data check error messages
[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
f5b72419 19#include <BVH_Constants.hxx>
3c4e78f2 20#include <BVH_Types.hxx>
e28f12b3 21#include <Standard_ShortReal.hxx>
3c4e78f2 22
0bb09048 23#include <limits>
24
679d3878 25//! Defines axis aligned bounding box (AABB) based on BVH vectors.
26//! \tparam T Numeric data type
27//! \tparam N Vector dimension
3c4e78f2 28template<class T, int N>
29class BVH_Box
30{
31public:
32
3a7a7013 33 typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
3c4e78f2 34
35public:
36
37 //! Creates uninitialized bounding box.
679d3878 38 BVH_Box() : myIsInited (Standard_False) {}
3c4e78f2 39
40 //! Creates bounding box of given point.
41 BVH_Box (const BVH_VecNt& thePoint)
679d3878 42 : myMinPoint (thePoint),
43 myMaxPoint (thePoint),
44 myIsInited (Standard_True) {}
3c4e78f2 45
46 //! Creates copy of another bounding box.
47 BVH_Box (const BVH_Box& theBox)
679d3878 48 : myMinPoint (theBox.myMinPoint),
49 myMaxPoint (theBox.myMaxPoint),
50 myIsInited (theBox.myIsInited) {}
3c4e78f2 51
52 //! Creates bounding box from corner points.
53 BVH_Box (const BVH_VecNt& theMinPoint,
54 const BVH_VecNt& theMaxPoint)
679d3878 55 : myMinPoint (theMinPoint),
56 myMaxPoint (theMaxPoint),
57 myIsInited (Standard_True) {}
3c4e78f2 58
59public:
60
61 //! Clears bounding box.
e28f12b3 62 void Clear() { myIsInited = Standard_False; }
3c4e78f2 63
64 //! Is bounding box valid?
e28f12b3 65 Standard_Boolean IsValid() const { return myIsInited; }
3c4e78f2 66
67 //! Appends new point to the bounding box.
e28f12b3 68 void Add (const BVH_VecNt& thePoint)
69 {
70 if (!myIsInited)
71 {
72 myMinPoint = thePoint;
73 myMaxPoint = thePoint;
74 myIsInited = Standard_True;
75 }
76 else
77 {
78 myMinPoint = myMinPoint.cwiseMin (thePoint);
79 myMaxPoint = myMaxPoint.cwiseMax (thePoint);
80 }
81 }
3c4e78f2 82
83 //! Combines bounding box with another one.
e28f12b3 84 void Combine (const BVH_Box& theBox);
3c4e78f2 85
86 //! Returns minimum point of bounding box.
e28f12b3 87 const BVH_VecNt& CornerMin() const { return myMinPoint; }
3c4e78f2 88
89 //! Returns maximum point of bounding box.
e28f12b3 90 const BVH_VecNt& CornerMax() const { return myMaxPoint; }
3c4e78f2 91
92 //! Returns minimum point of bounding box.
e28f12b3 93 BVH_VecNt& CornerMin() { return myMinPoint; }
3c4e78f2 94
95 //! Returns maximum point of bounding box.
e28f12b3 96 BVH_VecNt& CornerMax() { return myMaxPoint; }
3c4e78f2 97
98 //! Returns surface area of bounding box.
0bb09048 99 //! If the box is degenerated into line, returns the perimeter instead.
3c4e78f2 100 T Area() const;
101
102 //! Returns diagonal of bounding box.
e28f12b3 103 BVH_VecNt Size() const { return myMaxPoint - myMinPoint; }
3c4e78f2 104
105 //! Returns center of bounding box.
e28f12b3 106 BVH_VecNt Center() const { return (myMinPoint + myMaxPoint) * static_cast<T> (0.5); }
3c4e78f2 107
679d3878 108 //! Returns center of bounding box along the given axis.
109 T Center (const Standard_Integer theAxis) const;
110
3c4e78f2 111protected:
112
679d3878 113 BVH_VecNt myMinPoint; //!< Minimum point of bounding box
114 BVH_VecNt myMaxPoint; //!< Maximum point of bounding box
115 Standard_Boolean myIsInited; //!< Is bounding box initialized?
3c4e78f2 116
117};
118
679d3878 119namespace BVH
120{
121 //! Tool class for calculating box center along the given axis.
122 //! \tparam T Numeric data type
123 //! \tparam N Vector dimension
124 template<class T, int N>
125 struct CenterAxis
126 {
127 // Not implemented
128 };
129
130 template<class T>
131 struct CenterAxis<T, 2>
132 {
133 static T Center (const BVH_Box<T, 2>& theBox, const Standard_Integer theAxis)
134 {
135 if (theAxis == 0)
136 {
137 return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
138 }
139 else if (theAxis == 1)
140 {
141 return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
142 }
143 return static_cast<T> (0.0);
144 }
145 };
146
147 template<class T>
148 struct CenterAxis<T, 3>
149 {
150 static T Center (const BVH_Box<T, 3>& theBox, const Standard_Integer theAxis)
151 {
152 if (theAxis == 0)
153 {
154 return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
155 }
156 else if (theAxis == 1)
157 {
158 return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
159 }
160 else if (theAxis == 2)
161 {
162 return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5);
163 }
164 return static_cast<T> (0.0);
165 }
166 };
167
168 template<class T>
169 struct CenterAxis<T, 4>
170 {
171 static T Center (const BVH_Box<T, 4>& theBox, const Standard_Integer theAxis)
172 {
173 if (theAxis == 0)
174 {
175 return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
176 }
177 else if (theAxis == 1)
178 {
179 return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
180 }
181 else if (theAxis == 2)
182 {
183 return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5);
184 }
185 return static_cast<T> (0.0);
186 }
187 };
188
189 //! Tool class for calculating surface area of the box.
190 //! \tparam T Numeric data type
191 //! \tparam N Vector dimension
192 template<class T, int N>
193 struct SurfaceCalculator
194 {
195 // Not implemented
196 };
197
198 template<class T>
199 struct SurfaceCalculator<T, 2>
200 {
201 static T Area (const typename BVH_Box<T, 2>::BVH_VecNt& theSize)
202 {
0bb09048 203 const T anArea = theSize.x() * theSize.y();
204
205 if (anArea < std::numeric_limits<T>::epsilon())
206 {
207 return theSize.x() + theSize.y();
208 }
209
210 return anArea;
679d3878 211 }
212 };
213
214 template<class T>
215 struct SurfaceCalculator<T, 3>
216 {
217 static T Area (const typename BVH_Box<T, 3>::BVH_VecNt& theSize)
218 {
0bb09048 219 const T anArea = ( theSize.x() * theSize.y() +
220 theSize.x() * theSize.z() +
221 theSize.z() * theSize.y() ) * static_cast<T> (2.0);
222
223 if (anArea < std::numeric_limits<T>::epsilon())
224 {
225 return theSize.x() +
226 theSize.y() +
227 theSize.z();
228 }
229
230 return anArea;
679d3878 231 }
232 };
233
234 template<class T>
235 struct SurfaceCalculator<T, 4>
236 {
237 static T Area (const typename BVH_Box<T, 4>::BVH_VecNt& theSize)
238 {
0bb09048 239 const T anArea = ( theSize.x() * theSize.y() +
240 theSize.x() * theSize.z() +
241 theSize.z() * theSize.y() ) * static_cast<T> (2.0);
242
243 if (anArea < std::numeric_limits<T>::epsilon())
244 {
245 return theSize.x() +
246 theSize.y() +
247 theSize.z();
248 }
249
250 return anArea;
679d3878 251 }
252 };
253
254 //! Tool class for calculate component-wise vector minimum
255 //! and maximum (optimized version).
256 //! \tparam T Numeric data type
257 //! \tparam N Vector dimension
258 template<class T, int N>
259 struct BoxMinMax
260 {
261 typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
262
263 static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2)
264 {
265 theVec1.x() = Min (theVec1.x(), theVec2.x());
266 theVec1.y() = Min (theVec1.y(), theVec2.y());
267 theVec1.z() = Min (theVec1.z(), theVec2.z());
268 }
269
270 static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2)
271 {
272 theVec1.x() = Max (theVec1.x(), theVec2.x());
273 theVec1.y() = Max (theVec1.y(), theVec2.y());
274 theVec1.z() = Max (theVec1.z(), theVec2.z());
275 }
276 };
277
278 template<class T>
279 struct BoxMinMax<T, 2>
280 {
281 typedef typename BVH::VectorType<T, 2>::Type BVH_VecNt;
282
283 static void CwiseMin (BVH_VecNt& theVec1, const BVH_VecNt& theVec2)
284 {
285 theVec1.x() = Min (theVec1.x(), theVec2.x());
286 theVec1.y() = Min (theVec1.y(), theVec2.y());
287 }
288
289 static void CwiseMax (BVH_VecNt& theVec1, const BVH_VecNt& theVec2)
290 {
291 theVec1.x() = Max (theVec1.x(), theVec2.x());
292 theVec1.y() = Max (theVec1.y(), theVec2.y());
293 }
294 };
295}
296
e28f12b3 297// =======================================================================
298// function : Combine
299// purpose :
300// =======================================================================
301template<class T, int N>
302void BVH_Box<T, N>::Combine (const BVH_Box& theBox)
303{
304 if (theBox.myIsInited)
305 {
306 if (!myIsInited)
307 {
308 myMinPoint = theBox.myMinPoint;
309 myMaxPoint = theBox.myMaxPoint;
310 myIsInited = Standard_True;
311 }
312 else
313 {
314 BVH::BoxMinMax<T, N>::CwiseMin (myMinPoint, theBox.myMinPoint);
315 BVH::BoxMinMax<T, N>::CwiseMax (myMaxPoint, theBox.myMaxPoint);
316 }
317 }
318}
319
320// =======================================================================
321// function : Area
322// purpose :
323// =======================================================================
324template<class T, int N>
325T BVH_Box<T, N>::Area() const
326{
327 return !myIsInited ? static_cast<T> (0.0) : BVH::SurfaceCalculator<T, N>::Area (myMaxPoint - myMinPoint);
328}
329
330// =======================================================================
331// function : Center
332// purpose :
333// =======================================================================
334template<class T, int N>
335T BVH_Box<T, N>::Center (const Standard_Integer theAxis) const
336{
337 return BVH::CenterAxis<T, N>::Center (*this, theAxis);
338}
3c4e78f2 339
340#endif // _BVH_Box_Header