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