0023625: New functionality building reflect lines on a shape
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 // jag 940616 #define Tolpetit 1.e-16
23
24
25 #include <gp.hxx>
26
27
28 Contap_SurfFunction::Contap_SurfFunction ():
29        myMean(1.),
30        myType(Contap_ContourStd),
31        myDir(0.,0.,1.),
32        myCosAng(0.), // PI/2 - Angle de depouille
33        tol(1.e-6),
34        computed(Standard_False),
35        derived(Standard_False)
36 {}
37
38 void Contap_SurfFunction::Set(const TheSurface& S)
39 {
40   mySurf = S;
41   Standard_Integer i;
42   Standard_Integer nbs = TheContTool::NbSamplePoints(S);
43   Standard_Real U,V;
44   gp_Vec norm;
45   if (nbs > 0) {
46     myMean = 0.;
47     for (i = 1; i <= nbs; i++) {
48       TheContTool::SamplePoint(S,i,U,V);
49 //      TheSurfaceTool::D1(S,U,V,solpt,d1u,d1v);
50 //      myMean = myMean + d1u.Crossed(d1v).Magnitude();
51       TheSurfProps::Normale(S,U,V,solpt,norm);
52       myMean = myMean + norm.Magnitude();
53     }
54     myMean = myMean / ((Standard_Real)nbs);
55   }
56   computed = Standard_False;
57   derived = Standard_False;
58 }
59
60
61 Standard_Integer Contap_SurfFunction::NbVariables () const
62 {
63   return 2;
64 }
65
66 Standard_Integer Contap_SurfFunction::NbEquations () const
67 {
68   return 1;
69 }
70
71
72 Standard_Boolean Contap_SurfFunction::Value(const math_Vector& X,
73                                             math_Vector& F)
74 {
75   Usol = X(1); Vsol = X(2);
76 //  TheSurfaceTool::D1(mySurf,Usol,Vsol,solpt,d1u,d1v);
77 //  gp_Vec norm(d1u.Crossed(d1v));
78   gp_Vec norm;
79   TheSurfProps::Normale(mySurf,Usol,Vsol,solpt,norm);
80   switch (myType) {
81   case Contap_ContourStd:
82     {
83       F(1) = valf = (norm.Dot(myDir))/myMean;
84     }
85     break;
86   case Contap_ContourPrs:
87     {
88       F(1) = valf = (norm.Dot(gp_Vec(myEye,solpt)))/myMean;
89     }
90     break;
91   case Contap_DraftStd:
92     {
93       F(1) = valf = (norm.Dot(myDir)-myCosAng*norm.Magnitude())/myMean;
94     }
95     break;
96   default:
97     {
98     }
99   }
100   computed = Standard_False;
101   derived = Standard_False;
102   return Standard_True;
103 }
104
105
106 Standard_Boolean Contap_SurfFunction::Derivatives(const math_Vector& X,
107                                                   math_Matrix& Grad)
108 {
109 //  gp_Vec d2u,d2v,d2uv;
110   Usol = X(1); Vsol = X(2);
111 //  TheSurfaceTool::D2(mySurf,Usol,Vsol,solpt,d1u,d1v,d2u,d2v,d2uv);
112
113   gp_Vec norm,dnu,dnv;
114   TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
115
116   switch (myType) {
117   case Contap_ContourStd:
118     {
119 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
120 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
121       Grad(1,1) = (dnu.Dot(myDir))/myMean;
122       Grad(1,2) = (dnv.Dot(myDir))/myMean;
123     }
124     break;
125   case Contap_ContourPrs:
126     {
127       gp_Vec Ep(myEye,solpt);
128       Grad(1,1) = (dnu.Dot(Ep))/myMean;
129       Grad(1,2) = (dnv.Dot(Ep))/myMean;
130     }
131     break;
132   case Contap_DraftStd:
133     {
134 //      gp_Vec norm(d1u.Crossed(d1v).Normalized());
135 //      gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
136 //      Grad(1,1) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
137 //      dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
138 //      Grad(1,2) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
139       norm.Normalize();
140       Grad(1,1) = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
141       Grad(1,2) = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
142     }
143     break;
144   case Contap_DraftPrs:
145   default:
146     {
147     }
148   }
149   Fpu = Grad(1,1); Fpv = Grad(1,2);
150   computed = Standard_False;
151   derived = Standard_True;
152   return Standard_True;
153 }
154
155
156 Standard_Boolean Contap_SurfFunction::Values (const math_Vector& X,
157                                               math_Vector& F,
158                                               math_Matrix& Grad)
159 {
160 //  gp_Vec d2u,d2v,d2uv;
161
162   Usol = X(1); Vsol = X(2);
163 //  TheSurfaceTool::D2(mySurf,Usol,Vsol,solpt,d1u,d1v,d2u,d2v,d2uv);
164 //  gp_Vec norm(d1u.Crossed(d1v));
165   gp_Vec norm,dnu,dnv;
166   TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
167
168   switch (myType) {
169
170   case Contap_ContourStd:
171     {
172       F(1)      = (norm.Dot(myDir))/myMean;
173 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
174 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
175       Grad(1,1) = (dnu.Dot(myDir))/myMean;
176       Grad(1,2) = (dnv.Dot(myDir))/myMean;
177     }
178     break;
179   case Contap_ContourPrs:
180     {
181       gp_Vec Ep(myEye,solpt);
182       F(1)      = (norm.Dot(Ep))/myMean;
183 //      Grad(1,1) = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(Ep))/myMean;
184 //      Grad(1,2) = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(Ep))/myMean;
185       Grad(1,1) = (dnu.Dot(Ep))/myMean;
186       Grad(1,2) = (dnv.Dot(Ep))/myMean;
187     }
188     break;
189   case Contap_DraftStd:
190     {
191       F(1) = (norm.Dot(myDir)-myCosAng*norm.Magnitude())/myMean;
192       norm.Normalize();
193 /*
194       gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
195       Grad(1,1) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
196       dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
197       Grad(1,2) = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
198 */
199       Grad(1,1) = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
200       Grad(1,2) = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
201     }
202     break;
203   case Contap_DraftPrs:
204   default:
205     {
206     }
207   }
208   valf = F(1);
209   Fpu = Grad(1,1); Fpv = Grad(1,2);
210   computed = Standard_False;
211   derived = Standard_True;
212   return Standard_True;
213 }
214
215
216 Standard_Boolean Contap_SurfFunction::IsTangent ()
217 {
218   if (!computed) {
219     computed = Standard_True;
220     if(!derived) {
221 //      gp_Vec d2u,d2v,d2uv;
222 //      TheSurfaceTool::D2(mySurf, Usol, Vsol, solpt, d1u, d1v, d2u, d2v, d2uv);
223       gp_Vec norm,dnu,dnv;
224       TheSurfProps::NormAndDn(mySurf,Usol,Vsol,solpt,norm,dnu,dnv);
225
226       switch (myType) {
227       case Contap_ContourStd:
228         {
229 //        Fpu = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(myDir))/myMean;
230 //        Fpv = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(myDir))/myMean;
231           Fpu = (dnu.Dot(myDir))/myMean;
232           Fpv = (dnv.Dot(myDir))/myMean;
233         }
234         break;
235       case Contap_ContourPrs:
236         {
237           gp_Vec Ep(myEye,solpt);
238 //        Fpu = ((d2u.Crossed(d1v) + d1u.Crossed(d2uv)).Dot(Ep))/myMean;
239 //        Fpv = ((d2uv.Crossed(d1v) + d1u.Crossed(d2v)).Dot(Ep))/myMean;
240           Fpu = (dnu.Dot(Ep))/myMean;
241           Fpv = (dnv.Dot(Ep))/myMean;
242         }
243         break;
244       case Contap_DraftStd:
245         {
246 /*
247           gp_Vec norm(d1u.Crossed(d1v).Normalized());
248           gp_Vec dnorm(d2u.Crossed(d1v) + d1u.Crossed(d2uv));
249           Fpu = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
250           dnorm = d2uv.Crossed(d1v) + d1u.Crossed(d2v);
251           Fpv = (dnorm.Dot(myDir)-myCosAng*dnorm.Dot(norm))/myMean;
252 */
253           norm.Normalize();
254           Fpu = (dnu.Dot(myDir)-myCosAng*dnu.Dot(norm))/myMean;
255           Fpv = (dnv.Dot(myDir)-myCosAng*dnv.Dot(norm))/myMean;
256         }
257         break;
258       case Contap_DraftPrs:
259       default:
260         {
261         }
262       }
263       derived = Standard_True;
264     }
265     tangent = Standard_False;
266     Standard_Real D = Sqrt (Fpu * Fpu + Fpv * Fpv);
267
268     if (D <= gp::Resolution()) {
269       tangent = Standard_True;
270     }
271     else {
272       d2d = gp_Dir2d(-Fpv,Fpu);
273       gp_Vec d1u,d1v;
274       TheSurfaceTool::D1(mySurf, Usol, Vsol, solpt, d1u, d1v); // ajout jag 02.95
275
276       gp_XYZ d3dxyz(-Fpv*d1u.XYZ());
277       d3dxyz.Add(Fpu*d1v.XYZ());
278       d3d.SetXYZ(d3dxyz);
279     
280       //jag 940616    if (d3d.Magnitude() <= Tolpetit) {
281       if (d3d.Magnitude() <= tol) {
282         tangent = Standard_True;
283       }
284     }
285   }
286   return tangent;
287 }