0028636: Optimisation of gp_* classes in order to avoid unnecesary calling gp_Dir...
[occt.git] / src / gp / gp_Ax3.lxx
1 // Copyright (c) 1996-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <gp_Ax2.hxx>
16
17 inline gp_Ax3::gp_Ax3()
18   :
19   vydir(0.,1.,0.)
20   // vxdir(1.,0.,0.) use default ctor of gp_Dir, as it creates the same dir(1,0,0)
21 { }
22
23 inline gp_Ax3::gp_Ax3(const gp_Ax2& A) :
24 axis(A.Axis()),
25 vydir(A.YDirection()),
26 vxdir(A.XDirection())
27 { }
28
29 inline gp_Ax3::gp_Ax3(const gp_Pnt& P, const gp_Dir& N, const gp_Dir& Vx) :
30 axis(P, N), vydir(N), vxdir(N)
31 {
32   vxdir.CrossCross(Vx, N);
33   vydir.Cross(vxdir);
34 }
35
36 inline void  gp_Ax3::XReverse()
37 { vxdir.Reverse(); }
38
39 inline void  gp_Ax3::YReverse()
40 { vydir.Reverse(); }
41
42 inline void  gp_Ax3::ZReverse()
43 { axis.Reverse();  }
44
45 inline void  gp_Ax3::SetAxis(const gp_Ax1& A1)
46 {
47   Standard_Boolean direct = Direct();
48   axis = A1;
49   vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
50   if(direct) { vydir = axis.Direction().Crossed(vxdir); }
51   else       { vydir = vxdir.Crossed(axis.Direction()); }
52 }
53
54 inline void  gp_Ax3::SetDirection(const gp_Dir& V)
55 {
56   Standard_Boolean direct = Direct();
57   axis.SetDirection (V);
58   vxdir = V.CrossCrossed (vxdir, V);
59   if (direct) { vydir = V.Crossed (vxdir); }
60   else        { vydir = vxdir.Crossed (V); }
61 }
62
63 inline void  gp_Ax3::SetLocation(const gp_Pnt& P)
64 {  axis.SetLocation(P); }
65
66 inline void  gp_Ax3::SetXDirection(const gp_Dir& Vx)
67 {
68   Standard_Boolean direct = Direct();
69   vxdir = axis.Direction().CrossCrossed (Vx, axis.Direction());
70   if (direct) { vydir = axis.Direction().Crossed(vxdir); }
71   else        { vydir = vxdir.Crossed(axis.Direction()); }
72 }
73
74 inline void  gp_Ax3::SetYDirection(const gp_Dir& Vy)
75 {
76   Standard_Boolean direct = Direct();
77   vxdir = Vy.Crossed (axis.Direction());
78   vydir = (axis.Direction()).Crossed (vxdir);
79   if (!direct) { vxdir.Reverse(); }
80 }
81
82 inline Standard_Real  gp_Ax3::Angle(const gp_Ax3& Other) const 
83 { return axis.Angle (Other.axis); }
84
85 inline const gp_Ax1&  gp_Ax3::Axis()const
86 {  return axis; }
87
88 inline gp_Ax2  gp_Ax3::Ax2()const 
89 {
90   gp_Dir zz = axis.Direction();
91   if (!Direct()) { zz.Reverse(); }
92   return gp_Ax2 (axis.Location(),zz,vxdir);
93 }
94
95 inline const gp_Dir&  gp_Ax3::Direction()const
96 {   return axis.Direction(); }
97
98 inline const gp_Pnt&  gp_Ax3::Location()const
99 {   return axis.Location(); }
100
101 inline const gp_Dir&  gp_Ax3::XDirection()const
102 {  return vxdir;  }
103
104 inline const gp_Dir&  gp_Ax3::YDirection()const
105 {  return vydir; }
106
107 inline Standard_Boolean  gp_Ax3::Direct()const 
108 { return (vxdir.Crossed(vydir).Dot(axis.Direction()) > 0.); }
109
110 inline Standard_Boolean gp_Ax3::IsCoplanar
111 (const gp_Ax3& Other, 
112  const Standard_Real LinearTolerance, 
113  const Standard_Real AngularTolerance)const 
114 {
115   gp_Vec vec(axis.Location(),Other.axis.Location());
116   Standard_Real D1 = gp_Vec(axis.Direction()      ).Dot(vec);
117   if (D1 < 0) D1 = - D1;
118   Standard_Real D2 = gp_Vec(Other.axis.Direction()).Dot(vec);
119   if (D2 < 0) D2 = - D2;
120   return (D1 <= LinearTolerance && D2 <= LinearTolerance &&
121           axis.IsParallel (Other.axis, AngularTolerance));
122 }
123
124 inline Standard_Boolean gp_Ax3::IsCoplanar
125 (const gp_Ax1& A1, 
126  const Standard_Real LinearTolerance, 
127  const Standard_Real AngularTolerance)const 
128 {
129   gp_Vec vec(axis.Location(),A1.Location());
130   Standard_Real D1 = gp_Vec(axis.Direction()).Dot(vec);
131   if (D1 < 0) D1 = - D1;
132   Standard_Real D2 = (gp_Vec(A1.Direction()).Crossed(vec)).Magnitude();
133   if (D2 < 0) D2 = - D2;
134   return (D1 <= LinearTolerance && D2 <= LinearTolerance &&
135           axis.IsNormal (A1, AngularTolerance));
136 }
137
138 inline void  gp_Ax3::Rotate(const gp_Ax1& A1,
139                             const Standard_Real Ang)
140 {
141   axis.Rotate (A1,Ang);
142   vxdir.Rotate (A1,Ang);
143   vydir.Rotate (A1,Ang);
144 }
145
146 inline gp_Ax3  gp_Ax3::Rotated(const gp_Ax1& A1,
147                                const Standard_Real Ang)const
148 {
149   gp_Ax3 Temp = *this;
150   Temp.Rotate (A1,Ang);
151   return Temp;
152 }
153
154 inline void  gp_Ax3::Scale(const gp_Pnt& P, const Standard_Real S)
155 {
156   axis.Scale (P,S);
157   if (S < 0.) {
158     vxdir.Reverse ();
159     vydir.Reverse ();
160   }
161 }
162
163 inline gp_Ax3  gp_Ax3::Scaled(const gp_Pnt& P,
164                               const Standard_Real S)const
165 {
166   gp_Ax3 Temp = *this;
167   Temp.Scale (P,S);
168   return Temp;
169 }
170
171 inline void  gp_Ax3::Transform(const gp_Trsf& T)
172 {
173   axis.Transform (T);
174   vxdir.Transform (T);
175   vydir.Transform (T);
176 }
177
178 inline gp_Ax3  gp_Ax3::Transformed(const gp_Trsf& T)const
179 {
180   gp_Ax3 Temp = *this;
181   Temp.Transform (T);
182   return Temp;
183 }
184
185 inline void  gp_Ax3::Translate(const gp_Vec& V)
186 { axis.Translate (V); }
187
188 inline gp_Ax3  gp_Ax3::Translated(const gp_Vec& V)const
189 {
190   gp_Ax3 Temp = *this;
191   Temp.Translate (V);
192   return Temp;
193 }
194
195 inline void  gp_Ax3::Translate(const gp_Pnt& P1, const gp_Pnt& P2)
196 { Translate(gp_Vec(P1,P2)); }
197
198 inline gp_Ax3  gp_Ax3::Translated(const gp_Pnt& P1, const gp_Pnt& P2)const
199 { return Translated(gp_Vec(P1,P2)); }
200