0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / Contap / Contap_SurfProps.cxx
CommitLineData
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 29void 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 134void 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 234void 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}