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