0030655: Modeling Data - Provide interfaces for selection of the elements from BVH...
[occt.git] / src / BVH / BVH_Tools.hxx
1 // Created by: Eugeny MALTCHIKOV
2 // Created on: 2019-04-17
3 // Copyright (c) 2019 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 under
8 // the terms of the GNU Lesser General Public License 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 #ifndef _BVH_Tools_Header
17 #define _BVH_Tools_Header
18
19 #include <BVH_Box.hxx>
20 #include <BVH_Types.hxx>
21
22 //! Defines a set of static methods operating with points and bounding boxes.
23 //! \tparam T Numeric data type
24 //! \tparam N Vector dimension
25 template <class T, int N>
26 class BVH_Tools
27 {
28 public: //! @name public types
29
30   typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
31
32 public: //! @name Box-Box Square distance
33
34   //! Computes Square distance between Axis aligned bounding boxes
35   static T BoxBoxSquareDistance (const BVH_Box<T, N>& theBox1,
36                                  const BVH_Box<T, N>& theBox2)
37   {
38     return BoxBoxSquareDistance (theBox1.CornerMin(), theBox1.CornerMax(),
39                                  theBox2.CornerMin(), theBox2.CornerMax());
40   }
41
42   //! Computes Square distance between Axis aligned bounding boxes
43   static T BoxBoxSquareDistance (const BVH_VecNt& theCMin1,
44                                  const BVH_VecNt& theCMax1,
45                                  const BVH_VecNt& theCMin2,
46                                  const BVH_VecNt& theCMax2)
47   {
48     T aDist = 0;
49     for (int i = 0; i < N; ++i)
50     {
51       if      (theCMin1[i] > theCMax2[i]) { T d = theCMin1[i] - theCMax2[i]; d *= d; aDist += d; }
52       else if (theCMax1[i] < theCMin2[i]) { T d = theCMin2[i] - theCMax1[i]; d *= d; aDist += d; }
53     }
54     return aDist;
55   }
56
57 public: //! @name Point-Box Square distance
58
59   //! Computes square distance between point and bounding box
60   static T PointBoxSquareDistance (const BVH_VecNt& thePoint,
61                                    const BVH_Box<T, N>& theBox)
62   {
63     return PointBoxSquareDistance (thePoint,
64                                    theBox.CornerMin(),
65                                    theBox.CornerMax());
66   }
67
68   //! Computes square distance between point and bounding box
69   static T PointBoxSquareDistance (const BVH_VecNt& thePoint,
70                                    const BVH_VecNt& theCMin,
71                                    const BVH_VecNt& theCMax)
72   {
73     T aDist = 0;
74     for (int i = 0; i < N; ++i)
75     {
76       if      (thePoint[i] < theCMin[i]) { T d = theCMin[i] - thePoint[i]; d *= d; aDist += d; }
77       else if (thePoint[i] > theCMax[i]) { T d = thePoint[i] - theCMax[i]; d *= d; aDist += d; }
78     }
79     return aDist;
80   }
81
82 public: //! @name Point-Triangle Square distance
83
84   //! Computes square distance between point and triangle
85   static T PointTriangleSquareDistance (const BVH_VecNt& thePoint,
86                                         const BVH_VecNt& theNode0,
87                                         const BVH_VecNt& theNode1,
88                                         const BVH_VecNt& theNode2)
89   {
90     const BVH_VecNt aAB = theNode1 - theNode0;
91     const BVH_VecNt aAC = theNode2 - theNode0;
92     const BVH_VecNt aAP = thePoint - theNode0;
93   
94     T aABdotAP = aAB.Dot(aAP);
95     T aACdotAP = aAC.Dot(aAP);
96   
97     if (aABdotAP <= 0. && aACdotAP <= 0.)
98     {
99       return aAP.Dot(aAP);
100     }
101   
102     const BVH_VecNt aBC = theNode2 - theNode1;
103     const BVH_VecNt aBP = thePoint - theNode1;
104   
105     T aBAdotBP = -(aAB.Dot(aBP));
106     T aBCdotBP =  (aBC.Dot(aBP));
107   
108     if (aBAdotBP <= 0. && aBCdotBP <= 0.)
109     {
110       return (aBP.Dot(aBP));
111     }
112   
113     const BVH_VecNt aCP = thePoint - theNode2;
114   
115     T aCBdotCP = -(aBC.Dot(aCP));
116     T aCAdotCP = -(aAC.Dot(aCP));
117   
118     if (aCAdotCP <= 0. && aCBdotCP <= 0.)
119     {
120       return (aCP.Dot(aCP));
121     }
122   
123     T aACdotBP = (aAC.Dot(aBP));
124   
125     T aVC = aABdotAP * aACdotBP + aBAdotBP * aACdotAP;
126   
127     if (aVC <= 0. && aABdotAP > 0. && aBAdotBP > 0.)
128     {
129       const BVH_VecNt aDirect = aAP - aAB * (aABdotAP / (aABdotAP + aBAdotBP));
130   
131       return (aDirect.Dot(aDirect));
132     }
133   
134     T aABdotCP = (aAB.Dot(aCP));
135   
136     T aVA = aBAdotBP * aCAdotCP - aABdotCP * aACdotBP;
137   
138     if (aVA <= 0. && aBCdotBP > 0. && aCBdotCP > 0.)
139     {
140       const BVH_VecNt aDirect = aBP - aBC * (aBCdotBP / (aBCdotBP + aCBdotCP));
141   
142       return (aDirect.Dot(aDirect));
143     }
144   
145     T aVB = aABdotCP * aACdotAP + aABdotAP * aCAdotCP;
146   
147     if (aVB <= 0. && aACdotAP > 0. && aCAdotCP > 0.)
148     {
149       const BVH_VecNt aDirect = aAP - aAC * (aACdotAP / (aACdotAP + aCAdotCP));
150   
151       return (aDirect.Dot(aDirect));
152     }
153   
154     T aNorm = aVA + aVB + aVC;
155   
156     const BVH_VecNt& aDirect = thePoint - (theNode0 * aVA +
157                                            theNode1 * aVB +
158                                            theNode2 * aVC) / aNorm;
159   
160     return (aDirect.Dot(aDirect));
161   }
162
163 };
164
165 #endif