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