b311480e |
1 | // Created on: 1995-02-24 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
973c2be1 |
8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public version 2.1 as published |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include <ElSLib.hxx> |
18 | |
19 | //======================================================================= |
20 | //function : Normale |
21 | //purpose : |
22 | //======================================================================= |
23 | |
24 | void Contap_SurfProps::Normale(const TheSurface& S, |
25 | const Standard_Real U, |
26 | const Standard_Real V, |
27 | gp_Pnt& P, |
28 | gp_Vec& Norm) |
29 | { |
30 | |
31 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); |
32 | switch (typS) { |
33 | case GeomAbs_Plane: |
34 | { |
35 | gp_Pln pl(TheSurfaceTool::Plane(S)); |
36 | Norm = pl.Axis().Direction(); |
37 | P = ElSLib::Value(U,V,pl); |
38 | if (!pl.Direct()) { |
39 | Norm.Reverse(); |
40 | } |
41 | } |
42 | break; |
43 | |
44 | |
45 | case GeomAbs_Sphere: |
46 | { |
47 | gp_Sphere sp(TheSurfaceTool::Sphere(S)); |
48 | P = ElSLib::Value(U,V,sp); |
49 | Norm = gp_Vec(sp.Location(),P); |
50 | if (sp.Direct()) { |
51 | Norm.Divide(sp.Radius()); |
52 | } |
53 | else { |
54 | Norm.Divide(-sp.Radius()); |
55 | } |
56 | } |
57 | break; |
58 | |
59 | case GeomAbs_Cylinder: |
60 | { |
61 | gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); |
62 | P = ElSLib::Value(U,V,cy); |
63 | Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), |
64 | Sin(U),cy.YAxis().Direction()); |
65 | if (!cy.Direct()) { |
66 | Norm.Reverse(); |
67 | } |
68 | } |
69 | break; |
70 | |
71 | |
72 | case GeomAbs_Cone: |
73 | { |
74 | gp_Cone co(TheSurfaceTool::Cone(S)); |
75 | P = ElSLib::Value(U,V,co); |
76 | Standard_Real Angle = co.SemiAngle(); |
77 | Standard_Real Sina = sin(Angle); |
78 | Standard_Real Cosa = cos(Angle); |
79 | Standard_Real Rad = co.RefRadius(); |
80 | |
81 | Standard_Real Vcalc = V; |
82 | if (Abs(V*Sina + Rad) <= 1e-12) { // on est a l`apex |
83 | /* |
84 | Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); |
85 | if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex |
86 | Vcalc = V - 1; |
87 | } |
88 | else { |
89 | Vcalc = V + 1.; |
90 | } |
91 | */ |
92 | Norm.SetCoord(0,0,0); |
93 | return; |
94 | } |
95 | |
96 | if (Rad + Vcalc*Sina < 0.) { |
97 | Norm.SetLinearForm(Sina, co.Axis().Direction(), |
98 | Cosa*cos(U),co.XAxis().Direction(), |
99 | Cosa*sin(U),co.YAxis().Direction()); |
100 | } |
101 | else { |
102 | Norm.SetLinearForm(-Sina, co.Axis().Direction(), |
103 | Cosa*cos(U),co.XAxis().Direction(), |
104 | Cosa*sin(U),co.YAxis().Direction()); |
105 | } |
106 | if (!co.Direct()) { |
107 | Norm.Reverse(); |
108 | } |
109 | } |
110 | break; |
111 | default: |
112 | { |
113 | gp_Vec d1u,d1v; |
114 | TheSurfaceTool::D1(S,U,V,P,d1u,d1v); |
115 | Norm = d1u.Crossed(d1v); |
116 | } |
117 | break; |
118 | |
119 | |
120 | } |
121 | } |
122 | |
123 | |
124 | //======================================================================= |
125 | //function : DerivAndNorm |
126 | //purpose : |
127 | //======================================================================= |
128 | |
129 | void Contap_SurfProps::DerivAndNorm(const TheSurface& S, |
130 | const Standard_Real U, |
131 | const Standard_Real V, |
132 | gp_Pnt& P, |
133 | gp_Vec& d1u, |
134 | gp_Vec& d1v, |
135 | gp_Vec& Norm) |
136 | { |
137 | |
138 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); |
139 | switch (typS) { |
140 | case GeomAbs_Plane: |
141 | { |
142 | gp_Pln pl(TheSurfaceTool::Plane(S)); |
143 | Norm = pl.Axis().Direction(); |
144 | ElSLib::D1(U,V,pl,P,d1u,d1v); |
145 | if (!pl.Direct()) { |
146 | Norm.Reverse(); |
147 | } |
148 | } |
149 | break; |
150 | |
151 | |
152 | case GeomAbs_Sphere: |
153 | { |
154 | gp_Sphere sp(TheSurfaceTool::Sphere(S)); |
155 | ElSLib::D1(U,V,sp,P,d1u,d1v); |
156 | Norm = gp_Vec(sp.Location(),P); |
157 | if (sp.Direct()) { |
158 | Norm.Divide(sp.Radius()); |
159 | } |
160 | else { |
161 | Norm.Divide(-sp.Radius()); |
162 | } |
163 | } |
164 | break; |
165 | |
166 | case GeomAbs_Cylinder: |
167 | { |
168 | gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); |
169 | ElSLib::D1(U,V,cy,P,d1u,d1v); |
170 | Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), |
171 | Sin(U),cy.YAxis().Direction()); |
172 | if (!cy.Direct()) { |
173 | Norm.Reverse(); |
174 | } |
175 | } |
176 | break; |
177 | |
178 | |
179 | case GeomAbs_Cone: |
180 | { |
181 | gp_Cone co(TheSurfaceTool::Cone(S)); |
182 | ElSLib::D1(U,V,co,P,d1u,d1v); |
183 | Standard_Real Angle = co.SemiAngle(); |
184 | Standard_Real Sina = Sin(Angle); |
185 | Standard_Real Cosa = Cos(Angle); |
186 | Standard_Real Rad = co.RefRadius(); |
187 | |
188 | Standard_Real Vcalc = V; |
189 | if (Abs(V*Sina + Rad) <= RealEpsilon()) { // on est a l`apex |
190 | Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); |
191 | if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex |
192 | Vcalc = V - 1; |
193 | } |
194 | else { |
195 | Vcalc = V + 1.; |
196 | } |
197 | } |
198 | |
199 | if (Rad + Vcalc*Sina < 0.) { |
200 | Norm.SetLinearForm(Sina, co.Axis().Direction(), |
201 | Cosa*Cos(U),co.XAxis().Direction(), |
202 | Cosa*Sin(U),co.YAxis().Direction()); |
203 | } |
204 | else { |
205 | Norm.SetLinearForm(-Sina, co.Axis().Direction(), |
206 | Cosa*Cos(U),co.XAxis().Direction(), |
207 | Cosa*Sin(U),co.YAxis().Direction()); |
208 | } |
209 | if (!co.Direct()) { |
210 | Norm.Reverse(); |
211 | } |
212 | } |
213 | break; |
214 | default: |
215 | { |
216 | TheSurfaceTool::D1(S,U,V,P,d1u,d1v); |
217 | Norm = d1u.Crossed(d1v); |
218 | } |
219 | break; |
220 | } |
221 | } |
222 | |
223 | |
224 | //======================================================================= |
225 | //function : NormAndDn |
226 | //purpose : |
227 | //======================================================================= |
228 | |
229 | void Contap_SurfProps::NormAndDn(const TheSurface& S, |
230 | const Standard_Real U, |
231 | const Standard_Real V, |
232 | gp_Pnt& P, |
233 | gp_Vec& Norm, |
234 | gp_Vec& Dnu, |
235 | gp_Vec& Dnv) |
236 | { |
237 | |
238 | GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(S); |
239 | switch (typS) { |
240 | case GeomAbs_Plane: |
241 | { |
242 | gp_Pln pl(TheSurfaceTool::Plane(S)); |
243 | P = ElSLib::Value(U,V,pl); |
244 | Norm = pl.Axis().Direction(); |
245 | if (!pl.Direct()) { |
246 | Norm.Reverse(); |
247 | } |
248 | Dnu = Dnv = gp_Vec(0.,0.,0.); |
249 | } |
250 | break; |
251 | |
252 | case GeomAbs_Sphere: |
253 | { |
254 | gp_Sphere sp(TheSurfaceTool::Sphere(S)); |
255 | ElSLib::D1(U,V,sp,P,Dnu,Dnv); |
256 | Norm = gp_Vec(sp.Location(),P); |
257 | Standard_Real Rad = sp.Radius(); |
258 | if (!sp.Direct()) { |
259 | Rad = -Rad; |
260 | } |
261 | Norm.Divide(Rad); |
262 | Dnu.Divide(Rad); |
263 | Dnv.Divide(Rad); |
264 | } |
265 | break; |
266 | |
267 | case GeomAbs_Cylinder: |
268 | { |
269 | gp_Cylinder cy(TheSurfaceTool::Cylinder(S)); |
270 | P = ElSLib::Value(U,V,cy); |
271 | Norm.SetLinearForm(Cos(U),cy.XAxis().Direction(), |
272 | Sin(U),cy.YAxis().Direction()); |
273 | Dnu.SetLinearForm(-Sin(U),cy.XAxis().Direction(), |
274 | Cos(U),cy.YAxis().Direction()); |
275 | if (!cy.Direct()) { |
276 | Norm.Reverse(); |
277 | Dnu.Reverse(); |
278 | } |
279 | Dnv = gp_Vec(0.,0.,0.); |
280 | } |
281 | break; |
282 | |
283 | case GeomAbs_Cone: |
284 | { |
285 | |
286 | gp_Cone co(TheSurfaceTool::Cone(S)); |
287 | P = ElSLib::Value(U,V,co); |
288 | Standard_Real Angle = co.SemiAngle(); |
289 | Standard_Real Sina = Sin(Angle); |
290 | Standard_Real Cosa = Cos(Angle); |
291 | Standard_Real Rad = co.RefRadius(); |
292 | Standard_Real Vcalc = V; |
293 | if (Abs(V*Sina + Rad) <= RealEpsilon()) { // on est a l`apex |
294 | Standard_Real Vfi = TheSurfaceTool::FirstVParameter(S); |
295 | if (Vfi < -Rad/Sina) { // partie valide pour V < Vapex |
296 | Vcalc = V - 1; |
297 | } |
298 | else { |
299 | Vcalc = V + 1.; |
300 | } |
301 | } |
302 | |
303 | if (Rad + Vcalc*Sina < 0.) { |
304 | Norm.SetLinearForm(Sina, co.Axis().Direction(), |
305 | Cosa*Cos(U),co.XAxis().Direction(), |
306 | Cosa*Sin(U),co.YAxis().Direction()); |
307 | } |
308 | else { |
309 | Norm.SetLinearForm(-Sina, co.Axis().Direction(), |
310 | Cosa*Cos(U),co.XAxis().Direction(), |
311 | Cosa*Sin(U),co.YAxis().Direction()); |
312 | } |
313 | Dnu.SetLinearForm(-Cosa*Sin(U),co.XAxis().Direction(), |
314 | Cosa*Cos(U),co.YAxis().Direction()); |
315 | if (!co.Direct()) { |
316 | Norm.Reverse(); |
317 | Dnu.Reverse(); |
318 | } |
319 | Dnv = gp_Vec(0.,0.,0.); |
320 | } |
321 | break; |
322 | |
323 | default: |
324 | { |
325 | gp_Vec d1u,d1v,d2u,d2v,d2uv; |
326 | TheSurfaceTool::D2(S,U,V,P,d1u,d1v,d2u,d2v,d2uv); |
327 | Norm = d1u.Crossed(d1v); |
328 | Dnu = d2u.Crossed(d1v) + d1u.Crossed(d2uv); |
329 | Dnv = d2uv.Crossed(d1v) + d1u.Crossed(d2v); |
330 | } |
331 | break; |
332 | } |
333 | } |