6fdbd2ed1387e80293061cb6c3251b195b4ff6dd
[occt.git] / src / Contap / Contap_SurfFunction.gxx
1 // Created on: 1993-06-03
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-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 // jag 940616 #define Tolpetit 1.e-16
18
19
20 #include <gp.hxx>
21
22
23 Contap_SurfFunction::Contap_SurfFunction ():
24        myMean(1.),
25        myType(Contap_ContourStd),
26        myDir(0.,0.,1.),
27        myCosAng(0.), // PI/2 - Angle de depouille
28        tol(1.e-6),
29        computed(Standard_False),
30        derived(Standard_False)
31 {}
32
33 void Contap_SurfFunction::Set(const TheSurface& S)
34 {
35   mySurf = S;
36   Standard_Integer i;
37   Standard_Integer nbs = TheContTool::NbSamplePoints(S);
38   Standard_Real U,V;
39   gp_Vec norm;
40   if (nbs > 0) {
41     myMean = 0.;
42     for (i = 1; i <= nbs; i++) {
43       TheContTool::SamplePoint(S,i,U,V);
44 //      TheSurfaceTool::D1(S,U,V,solpt,d1u,d1v);
45 //      myMean = myMean + d1u.Crossed(d1v).Magnitude();
46       TheSurfProps::Normale(S,U,V,solpt,norm);
47       myMean = myMean + norm.Magnitude();
48     }
49     myMean = myMean / ((Standard_Real)nbs);
50   }
51   computed = Standard_False;
52   derived = Standard_False;
53 }
54
55
56 Standard_Integer Contap_SurfFunction::NbVariables () const
57 {
58   return 2;
59 }
60
61 Standard_Integer Contap_SurfFunction::NbEquations () const
62 {
63   return 1;
64 }
65
66
67 Standard_Boolean Contap_SurfFunction::Value(const math_Vector& X,
68                                             math_Vector& F)
69 {
70   Usol = X(1); Vsol = X(2);
71 //  TheSurfaceTool::D1(mySurf,Usol,Vsol,solpt,d1u,d1v);
72 //  gp_Vec norm(d1u.Crossed(d1v));
73   gp_Vec norm;
74   TheSurfProps::Normale(mySurf,Usol,Vsol,solpt,norm);
75   switch (myType) {
76   case Contap_ContourStd:
77     {
78       F(1) = valf = (norm.Dot(myDir))/myMean;
79     }
80     break;
81   case Contap_ContourPrs:
82     {
83       F(1) = valf = (norm.Dot(gp_Vec(myEye,solpt)))/myMean;
84     }
85     break;
86   case Contap_DraftStd:
87     {
88       F(1) = valf = (norm.Dot(myDir)-myCosAng*norm.Magnitude())/myMean;
89     }
90     break;
91   default:
92     {
93     }
94   }
95   computed = Standard_False;
96   derived = Standard_False;
97   return Standard_True;
98 }
99
100
101 Standard_Boolean Contap_SurfFunction::Derivatives(const math_Vector& X,
102                                                   math_Matrix& Grad)
103 {
104 //  gp_Vec d2u,d2v,d2uv;
105   Usol = X(1); Vsol = X(2);
106 //  TheSurfaceTool::D2(mySurf,Usol,Vsol,solpt,d1u,d1v,d2u,d2v,d2uv);
107
108   gp_Vec norm,dnu,dnv;
109   TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
110
111   switch (myType) {
112   case Contap_ContourStd:
113     {
114 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
115 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
116       Grad(1,1) = (dnu.Dot(myDir))/myMean;
117       Grad(1,2) = (dnv.Dot(myDir))/myMean;
118     }
119     break;
120   case Contap_ContourPrs:
121     {
122       gp_Vec Ep(myEye,solpt);
123       Grad(1,1) = (dnu.Dot(Ep))/myMean;
124       Grad(1,2) = (dnv.Dot(Ep))/myMean;
125     }
126     break;
127   case Contap_DraftStd:
128     {
129 //      gp_Vec norm(d1u.Crossed(d1v).Normalized());
130 //      gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
131 //      Grad(1,1) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
132 //      dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
133 //      Grad(1,2) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
134       norm.Normalize();
135       Grad(1,1) = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
136       Grad(1,2) = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
137     }
138     break;
139   case Contap_DraftPrs:
140   default:
141     {
142     }
143   }
144   Fpu = Grad(1,1); Fpv = Grad(1,2);
145   computed = Standard_False;
146   derived = Standard_True;
147   return Standard_True;
148 }
149
150
151 Standard_Boolean Contap_SurfFunction::Values (const math_Vector& X,
152                                               math_Vector& F,
153                                               math_Matrix& Grad)
154 {
155 //  gp_Vec d2u,d2v,d2uv;
156
157   Usol = X(1); Vsol = X(2);
158 //  TheSurfaceTool::D2(mySurf,Usol,Vsol,solpt,d1u,d1v,d2u,d2v,d2uv);
159 //  gp_Vec norm(d1u.Crossed(d1v));
160   gp_Vec norm,dnu,dnv;
161   TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
162
163   switch (myType) {
164
165   case Contap_ContourStd:
166     {
167       F(1)      = (norm.Dot(myDir))/myMean;
168 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
169 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
170       Grad(1,1) = (dnu.Dot(myDir))/myMean;
171       Grad(1,2) = (dnv.Dot(myDir))/myMean;
172     }
173     break;
174   case Contap_ContourPrs:
175     {
176       gp_Vec Ep(myEye,solpt);
177       F(1)      = (norm.Dot(Ep))/myMean;
178 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(Ep))/myMean;
179 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(Ep))/myMean;
180       Grad(1,1) = (dnu.Dot(Ep))/myMean;
181       Grad(1,2) = (dnv.Dot(Ep))/myMean;
182     }
183     break;
184   case Contap_DraftStd:
185     {
186       F(1) = (norm.Dot(myDir)-myCosAng*norm.Magnitude())/myMean;
187       norm.Normalize();
188 /*
189       gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
190       Grad(1,1) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
191       dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
192       Grad(1,2) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
193 */
194       Grad(1,1) = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
195       Grad(1,2) = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
196     }
197     break;
198   case Contap_DraftPrs:
199   default:
200     {
201     }
202   }
203   valf = F(1);
204   Fpu = Grad(1,1); Fpv = Grad(1,2);
205   computed = Standard_False;
206   derived = Standard_True;
207   return Standard_True;
208 }
209
210
211 Standard_Boolean Contap_SurfFunction::IsTangent ()
212 {
213   if (!computed) {
214     computed = Standard_True;
215     if(!derived) {
216 //      gp_Vec d2u,d2v,d2uv;
217 //      TheSurfaceTool::D2(mySurf, Usol, Vsol, solpt, d1u, d1v, d2u, d2v, d2uv);
218       gp_Vec norm,dnu,dnv;
219       TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
220
221       switch (myType) {
222       case Contap_ContourStd:
223         {
224 //        Fpu = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
225 //        Fpv = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
226           Fpu = (dnu.Dot(myDir))/myMean;
227           Fpv = (dnv.Dot(myDir))/myMean;
228         }
229         break;
230       case Contap_ContourPrs:
231         {
232           gp_Vec Ep(myEye,solpt);
233 //        Fpu = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(Ep))/myMean;
234 //        Fpv = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(Ep))/myMean;
235           Fpu = (dnu.Dot(Ep))/myMean;
236           Fpv = (dnv.Dot(Ep))/myMean;
237         }
238         break;
239       case Contap_DraftStd:
240         {
241 /*
242           gp_Vec norm(d1u.Crossed(d1v).Normalized());
243           gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
244           Fpu = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
245           dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
246           Fpv = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
247 */
248           norm.Normalize();
249           Fpu = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
250           Fpv = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
251         }
252         break;
253       case Contap_DraftPrs:
254       default:
255         {
256         }
257       }
258       derived = Standard_True;
259     }
260     tangent = Standard_False;
261     Standard_Real D = Sqrt (Fpu * Fpu + Fpv * Fpv);
262
263     if (D <= gp::Resolution()) {
264       tangent = Standard_True;
265     }
266     else {
267       d2d = gp_Dir2d(-Fpv,Fpu);
268       gp_Vec d1u,d1v;
269       TheSurfaceTool::D1(mySurf, Usol, Vsol, solpt, d1u, d1v); // ajout jag 02.95
270
271       gp_XYZ d3dxyz(-Fpv*d1u.XYZ());
272       d3dxyz.Add(Fpu*d1v.XYZ());
273       d3d.SetXYZ(d3dxyz);
274     
275       //jag 940616    if (d3d.Magnitude() <= Tolpetit) {
276       if (d3d.Magnitude() <= tol) {
277         tangent = Standard_True;
278       }
279     }
280   }
281   return tangent;
282 }