1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <IntSurf_Quadric.ixx>
16 #include <StdFail_NotDone.hxx>
24 // ============================================================
25 IntSurf_Quadric::IntSurf_Quadric ():typ(GeomAbs_OtherSurface),
26 prm1(0.), prm2(0.), prm3(0.), prm4(0.)
28 // ============================================================
29 IntSurf_Quadric::IntSurf_Quadric (const gp_Pln& P):
30 ax3(P.Position()),typ(GeomAbs_Plane)
32 ax3direc = ax3.Direct();
33 P.Coefficients(prm1,prm2,prm3,prm4);
35 // ============================================================
36 IntSurf_Quadric::IntSurf_Quadric (const gp_Cylinder& C):
38 ax3(C.Position()),lin(ax3.Axis()),typ(GeomAbs_Cylinder)
41 ax3direc=ax3.Direct();
44 // ============================================================
45 IntSurf_Quadric::IntSurf_Quadric (const gp_Sphere& S):
47 ax3(S.Position()),lin(ax3.Axis()),typ(GeomAbs_Sphere)
50 ax3direc = ax3.Direct();
53 // ============================================================
54 IntSurf_Quadric::IntSurf_Quadric (const gp_Cone& C):
56 ax3(C.Position()),typ(GeomAbs_Cone)
58 ax3direc = ax3.Direct();
59 lin.SetPosition(ax3.Axis());
65 // ============================================================
66 void IntSurf_Quadric::SetValue (const gp_Pln& P)
70 ax3direc = ax3.Direct();
71 P.Coefficients(prm1,prm2,prm3,prm4);
73 // ============================================================
74 void IntSurf_Quadric::SetValue (const gp_Cylinder& C)
76 typ = GeomAbs_Cylinder;
78 ax3direc = ax3.Direct();
79 lin.SetPosition(ax3.Axis());
83 // ============================================================
84 void IntSurf_Quadric::SetValue (const gp_Sphere& S)
88 ax3direc = ax3.Direct();
89 lin.SetPosition(ax3.Axis());
93 // ============================================================
94 void IntSurf_Quadric::SetValue (const gp_Cone& C)
98 ax3direc = ax3.Direct();
99 lin.SetPosition(ax3.Axis());
100 prm1 = C.RefRadius();
101 prm2 = C.SemiAngle();
105 // ============================================================
106 Standard_Real IntSurf_Quadric::Distance (const gp_Pnt& P) const {
108 case GeomAbs_Plane: // plan
109 return prm1*P.X() + prm2*P.Y() + prm3*P.Z() + prm4;
110 case GeomAbs_Cylinder: // cylindre
111 return (lin.Distance(P) - prm1);
112 case GeomAbs_Sphere: // sphere
113 return (lin.Location().Distance(P) - prm1);
114 case GeomAbs_Cone: // cone
116 Standard_Real dist = lin.Distance(P);
118 ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
119 gp_Pnt Pp = ElSLib::ConeValue(U,V,ax3,prm1,prm2);
120 Standard_Real distp = lin.Distance(Pp);
121 dist = (dist-distp)/prm3;
131 // ============================================================
132 gp_Vec IntSurf_Quadric::Gradient (const gp_Pnt& P) const {
135 case GeomAbs_Plane: // plan
136 grad.SetCoord(prm1,prm2,prm3);
138 case GeomAbs_Cylinder: // cylindre
140 gp_XYZ PP(lin.Location().XYZ());
141 PP.Add(ElCLib::Parameter(lin,P)*lin.Direction().XYZ());
142 grad.SetXYZ(P.XYZ()-PP);
143 Standard_Real N = grad.Magnitude();
144 if(N>1e-14) { grad.Divide(N); }
145 else { grad.SetCoord(0.0,0.0,0.0); }
148 case GeomAbs_Sphere: // sphere
151 grad.SetXYZ((PP-lin.Location().XYZ()));
152 Standard_Real N = grad.Magnitude();
153 if(N>1e-14) { grad.Divide(N); }
154 else { grad.SetCoord(0.0,0.0,0.0); }
157 case GeomAbs_Cone: // cone
160 ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
161 gp_Pnt Pp = ElSLib::ConeValue(U,V,ax3,prm1,prm2);
163 ElSLib::ConeD1(U,V,ax3,prm1,prm2,Pp,D1u,D1v);
164 grad=D1u.Crossed(D1v);
165 if(ax3direc==Standard_False) {
177 // ============================================================
178 void IntSurf_Quadric::ValAndGrad (const gp_Pnt& P,
186 Dist = prm1*P.X() + prm2*P.Y() + prm3*P.Z() + prm4;
187 Grad.SetCoord(prm1,prm2,prm3);
190 case GeomAbs_Cylinder:
192 Dist = lin.Distance(P) - prm1;
193 gp_XYZ PP(lin.Location().XYZ());
194 PP.Add(ElCLib::Parameter(lin,P)*lin.Direction().XYZ());
195 Grad.SetXYZ((P.XYZ()-PP));
196 Standard_Real N = Grad.Magnitude();
197 if(N>1e-14) { Grad.Divide(N); }
198 else { Grad.SetCoord(0.0,0.0,0.0); }
203 Dist = lin.Location().Distance(P) - prm1;
205 Grad.SetXYZ((PP-lin.Location().XYZ()));
206 Standard_Real N = Grad.Magnitude();
207 if(N>1e-14) { Grad.Divide(N); }
208 else { Grad.SetCoord(0.0,0.0,0.0); }
213 Standard_Real dist = lin.Distance(P);
217 ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
218 ElSLib::ConeD1(U,V,ax3,prm1,prm2,Pp,D1u,D1v);
219 Standard_Real distp = lin.Distance(Pp);
220 dist = (dist-distp)/prm3;
222 Grad=D1u.Crossed(D1v);
223 if(ax3direc==Standard_False) {
226 //-- lbr le 7 mars 96
227 //-- Si le gardient est nul, on est sur l axe
228 //-- et dans ce cas dist vaut 0
229 //-- On peut donc renvoyer une valeur quelconque.
232 || Grad.Z() > 1e-13) {
242 // ============================================================
243 gp_Pnt IntSurf_Quadric::Value(const Standard_Real U,
244 const Standard_Real V) const
249 return ElSLib::PlaneValue(U,V,ax3);
250 case GeomAbs_Cylinder:
251 return ElSLib::CylinderValue(U,V,ax3,prm1);
253 return ElSLib::SphereValue(U,V,ax3,prm1);
255 return ElSLib::ConeValue(U,V,ax3,prm1,prm2);
264 // return gp_Pnt(0,0,0);
266 // ============================================================
267 void IntSurf_Quadric::D1(const Standard_Real U,
268 const Standard_Real V,
275 ElSLib::PlaneD1(U,V,ax3,P,D1U,D1V);
277 case GeomAbs_Cylinder:
278 ElSLib::CylinderD1(U,V,ax3,prm1,P,D1U,D1V);
281 ElSLib::SphereD1(U,V,ax3,prm1,P,D1U,D1V);
284 ElSLib::ConeD1(U,V,ax3,prm1,prm2,P,D1U,D1V);
292 // ============================================================
293 gp_Vec IntSurf_Quadric::DN(const Standard_Real U,
294 const Standard_Real V,
295 const Standard_Integer Nu,
296 const Standard_Integer Nv) const
300 return ElSLib::PlaneDN(U,V,ax3,Nu,Nv);
301 case GeomAbs_Cylinder:
302 return ElSLib::CylinderDN(U,V,ax3,prm1,Nu,Nv);
304 return ElSLib::SphereDN(U,V,ax3,prm1,Nu,Nv);
306 return ElSLib::ConeDN(U,V,ax3,prm1,prm2,Nu,Nv);
315 // return gp_Vec(0,0,0);
317 // ============================================================
318 gp_Vec IntSurf_Quadric::Normale(const Standard_Real U,
319 const Standard_Real V) const
324 return ax3.Direction();
326 return ax3.Direction().Reversed();
327 case GeomAbs_Cylinder:
328 return Normale(Value(U,V));
330 return Normale(Value(U,V));
335 ElSLib::ConeD1(U,V,ax3,prm1,prm2,P,D1u,D1v);
336 if(D1u.Magnitude()<0.0000001) {
337 gp_Vec Vn(0.0,0.0,0.0);
340 return(D1u.Crossed(D1v));
350 // return gp_Vec(0,0,0);
352 // ============================================================
353 gp_Vec IntSurf_Quadric::Normale (const gp_Pnt& P) const
358 return ax3.Direction();
360 return ax3.Direction().Reversed();
361 case GeomAbs_Cylinder:
364 return lin.Normal(P).Direction();
367 gp_Dir D(lin.Normal(P).Direction());
375 gp_Vec ax3P(ax3.Location(),P);
379 gp_Vec Pax3(P,ax3.Location());
386 ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
387 return Normale(U,V);;
396 // ============================================================
397 void IntSurf_Quadric::Parameters (const gp_Pnt& P,
399 Standard_Real& V) const
403 ElSLib::PlaneParameters(ax3,P,U,V);
405 case GeomAbs_Cylinder:
406 ElSLib::CylinderParameters(ax3,prm1,P,U,V);
409 ElSLib::SphereParameters(ax3,prm1,P,U,V);
413 ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
421 // ============================================================