0024473: TKMath, BVH - introduce template-based package for Bounding volume hierarchy...
[occt.git] / src / BVH / BVH_Box.lxx
1 // Created on: 2013-12-20
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
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 #include <Standard_ShortReal.hxx>
17
18 namespace BVHTools
19 {
20   template<class T, int N>
21   struct CenterAxis {
22     // Not implemented
23   };
24
25   template<class T>
26   struct CenterAxis<T, 2>
27   {
28     static T Center (const BVH_Box<T, 2>&   theBox,
29                      const Standard_Integer theAxis)
30     {
31       if (theAxis == 0)
32       {
33         return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
34       }
35       else if (theAxis == 1)
36       {
37         return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
38       }
39       return static_cast<T> (0.0);
40     }
41   };
42
43   template<class T>
44   struct CenterAxis<T, 3>
45   {
46     static T Center (const BVH_Box<T, 3>&   theBox,
47                      const Standard_Integer theAxis)
48     {
49       if (theAxis == 0)
50       {
51         return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
52       }
53       else if (theAxis == 1)
54       {
55         return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
56       }
57       else if (theAxis == 2)
58       {
59         return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5);
60       }
61       return static_cast<T> (0.0);
62     }
63   };
64
65   template<class T>
66   struct CenterAxis<T, 4>
67   {
68     static T Center (const BVH_Box<T, 4>&   theBox,
69                      const Standard_Integer theAxis)
70     {
71       if (theAxis == 0)
72       {
73         return (theBox.CornerMin().x() + theBox.CornerMax().x()) * static_cast<T> (0.5);
74       }
75       else if (theAxis == 1)
76       {
77         return (theBox.CornerMin().y() + theBox.CornerMax().y()) * static_cast<T> (0.5);
78       }
79       else if (theAxis == 2)
80       {
81         return (theBox.CornerMin().z() + theBox.CornerMax().z()) * static_cast<T> (0.5);
82       }
83       return static_cast<T> (0.0);
84     }
85   };
86 }
87
88 // =======================================================================
89 // function : Clear
90 // purpose  :
91 // =======================================================================
92 template<class T, int N>
93 void BVH_Box<T, N>::Clear()
94 {
95   myInitialized = Standard_False;
96 }
97
98 // =======================================================================
99 // function : Clear
100 // purpose  :
101 // =======================================================================
102 template<class T, int N>
103 Standard_Boolean BVH_Box<T, N>::IsValid() const
104 {
105   return myInitialized;
106 }
107
108 // =======================================================================
109 // function : Add
110 // purpose  :
111 // =======================================================================
112 template<class T, int N>
113 void BVH_Box<T, N>::Add (const BVH_VecNt& thePoint)
114 {
115   if (!myInitialized)
116   {
117     myMinPoint = thePoint;
118     myMaxPoint = thePoint;
119
120     myInitialized = Standard_True;
121   }
122   else
123   {
124     myMinPoint = myMinPoint.cwiseMin (thePoint);
125     myMaxPoint = myMaxPoint.cwiseMax (thePoint);
126   }
127 }
128
129 // =======================================================================
130 // function : Combine
131 // purpose  :
132 // =======================================================================
133 template<class T, int N>
134 void BVH_Box<T, N>::Combine (const BVH_Box& theBox)
135 {
136   if (!theBox.myInitialized)
137   {
138     return;
139   }
140
141   if (!myInitialized)
142   {
143     myMinPoint = theBox.myMinPoint;
144     myMaxPoint = theBox.myMaxPoint;
145
146     myInitialized = Standard_True;
147   }
148   else
149   {
150     myMinPoint = myMinPoint.cwiseMin (theBox.myMinPoint);
151     myMaxPoint = myMaxPoint.cwiseMax (theBox.myMaxPoint);
152   }
153 }
154
155 namespace BVHTools
156 {
157   template<class T, int N>
158   struct SurfaceCalculator
159   {
160     // Not implemented
161   };
162
163   template<class T>
164   struct SurfaceCalculator<T, 2>
165   {
166     static T Area (const typename BVH_Box<T, 2>::BVH_VecNt& theSize)
167     {
168       return theSize.x() * theSize.y();
169     }
170   };
171
172   template<class T>
173   struct SurfaceCalculator<T, 3>
174   {
175     static T Area (const typename BVH_Box<T, 3>::BVH_VecNt& theSize)
176     {
177       return ( theSize.x() * theSize.y() +
178                theSize.x() * theSize.z() +
179                theSize.z() * theSize.y() ) * static_cast<T> (2.0);
180     }
181   };
182
183   template<class T>
184   struct SurfaceCalculator<T, 4>
185   {
186     static T Area (const typename BVH_Box<T, 4>::BVH_VecNt& theSize)
187     {
188       return ( theSize.x() * theSize.y() +
189                theSize.x() * theSize.z() +
190                theSize.z() * theSize.y() ) * static_cast<T> (2.0);
191     }
192   };
193 }
194
195 // =======================================================================
196 // function : Area
197 // purpose  :
198 // =======================================================================
199 template<class T, int N>
200 T BVH_Box<T, N>::Area() const
201 {
202   return BVHTools::SurfaceCalculator<T, N>::Area (myMaxPoint - myMinPoint);
203 }
204
205 // =======================================================================
206 // function : CornerMin
207 // purpose  :
208 // =======================================================================
209 template<class T, int N>
210 const typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMin() const
211 {
212   return myMinPoint;
213 }
214
215 // =======================================================================
216 // function : CornerMax
217 // purpose  :
218 // =======================================================================
219 template<class T, int N>
220 const typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMax() const
221 {
222   return myMaxPoint;
223 }
224
225 // =======================================================================
226 // function : CornerMin
227 // purpose  :
228 // =======================================================================
229 template<class T, int N>
230 typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMin()
231 {
232   return myMinPoint;
233 }
234
235 // =======================================================================
236 // function : CornerMax
237 // purpose  :
238 // =======================================================================
239 template<class T, int N>
240 typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMax()
241 {
242   return myMaxPoint;
243 }
244
245 // =======================================================================
246 // function : Size
247 // purpose  :
248 // =======================================================================
249 template<class T, int N>
250 typename BVH_Box<T, N>::BVH_VecNt BVH_Box<T, N>::Size() const
251 {
252   return myMaxPoint - myMinPoint;
253 }
254
255 // =======================================================================
256 // function : Center
257 // purpose  :
258 // =======================================================================
259 template<class T, int N>
260 typename BVH_Box<T, N>::BVH_VecNt BVH_Box<T, N>::Center() const
261 {
262   return (myMinPoint + myMaxPoint) * static_cast<T> (0.5);
263 }