0024624: Lost word in license statement in source files
[occt.git] / src / Blend / Blend_Walking_2.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License 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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 Blend_Status Blend_Walking::TestArret(Blend_Function& Function,
16                                       const Blend_Status State,
17                                       const Standard_Boolean TestDefl,
18                                       const Standard_Boolean TestSolu,
19                                       const Standard_Boolean TestLengthStep)
20
21 // On regarde si le point donne est solution.
22 // Si c est le cas,
23 //  On verifie le critere de fleche sur surf1 et surf2
24 //   Si OK, on classifie les points sur surf1 et sur surf2.
25 //    Si les deux sont dedans : on retourne Blend_OK
26 //    sinon si un seul est dedans
27 //     on resout le pb inverse sur la restriction concernee
28 //    sinon on resout le pb inverse sur la surface pour laquelle
29 //     le point est le plus loin.
30 //   sinon (fleche non OK)
31 //    on renvoie Blend_StepTooLarge.
32 // sinon on renvoie Blend_StepTooLarge.
33 //
34
35 {
36   gp_Pnt pt1,pt2;
37   gp_Vec V1,V2;
38   gp_Vec Tgp1,Tgp2,Nor1,Nor2;
39   gp_Vec2d V12d,V22d;
40   Blend_Status State1,State2;
41   IntSurf_TypeTrans tras1,tras2;
42   Blend_Point curpoint;
43   Standard_Boolean loctwist1 = Standard_False, loctwist2 = Standard_False;
44   Standard_Real tolsolu = tolesp;
45
46   if ( !TestSolu) tolsolu *= 1000; //Ca doit toujours etre bon
47   if (Function.IsSolution(sol,tolsolu)) {
48
49 #ifdef DEB
50     sectioncalculee = 1;
51 #endif
52     Standard_Boolean curpointistangent = Function.IsTangencyPoint();
53     pt1  = Function.PointOnS1();
54     pt2  = Function.PointOnS2();
55     if(curpointistangent){
56       curpoint.SetValue(pt1,pt2,param,
57                         sol(1),sol(2),sol(3),sol(4));
58     }
59     else{
60       V1   = Function.TangentOnS1();
61       V2   = Function.TangentOnS2();
62       V12d = Function.Tangent2dOnS1();
63       V22d = Function.Tangent2dOnS2();
64       curpoint.SetValue(pt1,pt2,param,
65                         sol(1),sol(2),sol(3),sol(4),
66                         V1,V2,V12d,V22d);
67       if(Function.TwistOnS1()) loctwist1 = Standard_True;
68       if(Function.TwistOnS2()) loctwist2 = Standard_True;
69     }
70
71     if (TestDefl && check) {
72
73       // Verification du critere de fleche sur chaque surface
74       //et sur la ligne guide
75     
76       State1 = CheckDeflection(Standard_True,curpoint);
77       State2 = CheckDeflection(Standard_False,curpoint);
78     }
79     else {
80        State1 = Blend_OK;
81        State2 = Blend_OK;
82        if (TestLengthStep) {
83          // On verifie juste que le pas n'est pas trop grand
84          // (Cas des prolongements foireux)
85          Standard_Real curparamu,curparamv, prevparamu,prevparamv;
86          math_Vector inf(1,4), sup(1,4);
87          Function.GetBounds(inf, sup);
88          sup -= inf;
89          sup *= 0.05; // Pas max : 5% du domaine
90      
91          curpoint.ParametersOnS1(curparamu,curparamv);
92          previousP.ParametersOnS1(prevparamu,prevparamv);
93          if (Abs(curparamu-prevparamu) > sup(1)) State1 = Blend_StepTooLarge;
94          if (Abs(curparamv-prevparamv) > sup(2)) State1 = Blend_StepTooLarge;     
95          curpoint.ParametersOnS2(curparamu,curparamv);
96          previousP.ParametersOnS2(prevparamu,prevparamv);
97          if (Abs(curparamu-prevparamu) > sup(3)) State2 = Blend_StepTooLarge;
98          if (Abs(curparamv-prevparamv) > sup(4)) State2 = Blend_StepTooLarge;
99        }
100     }
101       
102     if (State1 == Blend_Backward) {
103       State1 = Blend_StepTooLarge;
104       rebrou= Standard_True;
105     }
106
107     if (State2 == Blend_Backward) {
108       State2 = Blend_StepTooLarge;
109       rebrou = Standard_True;
110     }
111
112     if (State1 == Blend_StepTooLarge ||
113         State2 == Blend_StepTooLarge) {
114       
115       return Blend_StepTooLarge;
116     }
117     
118
119     // Ici seulement on peut statuer sur le twist
120     // Car les rejet ont ete effectue (BUC60322)
121     if (loctwist1) twistflag1 = Standard_True;
122     if (loctwist2) twistflag2 = Standard_True;
123
124     if (!comptra && !curpointistangent) {
125       Function.Tangent(sol(1),sol(2),sol(3),sol(4),Tgp1,Tgp2,Nor1,Nor2);
126       Nor1.Normalize();
127       Nor2.Normalize();
128       Standard_Real testra = Tgp1.Dot(Nor1.Crossed(V1));
129       if (Abs(testra) > Precision::Confusion()) {
130         tras1 = IntSurf_In;
131         if ((testra > 0. && !loctwist1) || (testra < 0. && loctwist1)) {
132           tras1 = IntSurf_Out;
133         }
134       
135         testra = Tgp2.Dot(Nor2.Crossed(V2));
136         if (Abs(testra) > Precision::Confusion()) {
137           tras2 = IntSurf_Out;
138           if ((testra > 0. && !loctwist2) || (testra < 0. && loctwist2)) {
139             tras2 = IntSurf_In;
140           }
141           comptra = Standard_True;
142           line->Set(tras1,tras2);
143         }
144       }
145     }
146
147     if (State1 == Blend_OK ||
148         State2 == Blend_OK ) {
149       previousP = curpoint;
150       return State;
151     }
152
153     if (State1 == Blend_StepTooSmall &&
154         State2 == Blend_StepTooSmall) {
155       previousP = curpoint;
156       if (State == Blend_OK) {
157         return Blend_StepTooSmall;
158       }
159       else {
160         return State;
161       }
162     }
163
164     if (State == Blend_OK) {
165       return Blend_SamePoints;
166     }
167     else {
168       return State;
169     }
170
171   }
172   else {
173     return Blend_StepTooLarge;
174   }
175 }
176
177
178 Blend_Status Blend_Walking::CheckDeflection
179   (const Standard_Boolean OnFirst,
180    const Blend_Point&     CurPoint)
181 {
182   // regle par tests dans U4 correspond a 11.478 d
183   const Standard_Real CosRef3D = 0.98;
184
185   const Standard_Real CosRef2D = 0.88; // correspond a 25 d
186
187   Standard_Real Norme, Cosi, Cosi2;
188   Standard_Real prevNorme = 0.;
189   Standard_Real FlecheCourante;
190   Standard_Real Du,Dv,Duv;
191   Standard_Real tolu,tolv;
192
193   gp_Pnt Psurf;
194   gp_Vec Tgsurf;
195   gp_Vec2d Tgonsurf;
196   Standard_Real curparamu, curparamv;
197   Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
198
199   gp_Pnt prevP;
200   gp_Vec prevTg;
201   gp_Vec2d previousd2d;
202   Standard_Real prevparamu, prevparamv;
203   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
204
205   if (OnFirst) {
206     Psurf = CurPoint.PointOnS1();
207     if(!curpointistangent){
208       Tgsurf = CurPoint.TangentOnS1();
209     }
210     prevP = previousP.PointOnS1();
211     if(!prevpointistangent){
212       prevTg = previousP.TangentOnS1();
213     }
214     tolu = TheSurfaceTool::UResolution(surf1,tolesp);
215     tolv = TheSurfaceTool::VResolution(surf1,tolesp);
216   }
217   else {
218     Psurf = CurPoint.PointOnS2();
219     if(!curpointistangent){
220       Tgsurf = CurPoint.TangentOnS2();
221     }
222     prevP = previousP.PointOnS2();
223     if(!prevpointistangent){
224       prevTg = previousP.TangentOnS2();
225     }
226     tolu = TheSurfaceTool::UResolution(surf2,tolesp);
227     tolv = TheSurfaceTool::VResolution(surf2,tolesp);
228   }
229
230   gp_Vec Corde(prevP,Psurf);
231   Norme = Corde.SquareMagnitude();
232 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
233   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
234
235
236   if (Norme <= tolesp*tolesp){
237     // il faudra peut etre  forcer meme point
238     return Blend_SamePoints;
239   }
240   if(!prevpointistangent){
241     if(prevNorme <= tolesp*tolesp) {
242       return Blend_SamePoints;
243     }
244     Cosi = sens*Corde*prevTg;
245     if (Cosi <0.) { // angle 3d>pi/2. --> retour arriere
246       return Blend_Backward;
247     }
248     
249     Cosi2 = Cosi * Cosi / prevNorme / Norme;
250     if (Cosi2 < CosRef3D) { 
251       return Blend_StepTooLarge;
252     }
253   }
254
255   if(!curpointistangent){
256     // Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
257     Cosi = sens*Corde*Tgsurf;
258     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
259     if (Cosi2 < CosRef3D || Cosi < 0.) { 
260       return Blend_StepTooLarge;
261     }
262   }  
263     
264   if(check2d){
265     if (OnFirst) {
266       CurPoint.ParametersOnS1(curparamu,curparamv);
267       if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS1();
268       previousP.ParametersOnS1(prevparamu,prevparamv);
269       if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS1();
270     }
271     else {
272       CurPoint.ParametersOnS2(curparamu,curparamv);
273       if(!curpointistangent) Tgonsurf = CurPoint.Tangent2dOnS2();
274       previousP.ParametersOnS2(prevparamu,prevparamv);
275       if(!prevpointistangent) previousd2d = previousP.Tangent2dOnS2();
276     }
277     
278     Du = curparamu - prevparamu;
279     Dv = curparamv - prevparamv;
280     Duv = Du * Du + Dv * Dv;
281 //    SqrtDuv = Sqrt(Duv);
282     if (Abs(Du) < tolu && Abs(Dv) < tolv){
283       // il faudra peut etre  forcer meme point
284       return Blend_SamePoints; //point confondu 2d
285     }
286     if(!prevpointistangent){
287       if(Abs(previousd2d.X()) < tolu && Abs(previousd2d.Y()) < tolv){
288         // il faudra peut etre  forcer meme point
289         return Blend_SamePoints; //point confondu 2d
290       }
291       Cosi = sens*(Du * previousd2d.X() + Dv * previousd2d.Y());
292       if (Cosi < 0) {
293         return Blend_Backward; 
294       }
295     }    
296     if(!curpointistangent){
297       // Voir s il faut faire le controle sur le signe de Cosi
298       Cosi = sens*(Du * Tgonsurf.X() +  Dv * Tgonsurf.Y())/Tgonsurf.Magnitude();
299       Cosi2 = Cosi * Cosi / Duv;
300       if (Cosi2 < CosRef2D || Cosi <0.) { 
301         return Blend_StepTooLarge;
302       }
303     }
304   }
305   if(!curpointistangent && !prevpointistangent){
306     // Estimation de la fleche courante
307     FlecheCourante = (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
308     
309     if (FlecheCourante <= 0.25*fleche*fleche) {
310       return Blend_StepTooSmall;
311     }
312     if (FlecheCourante > fleche*fleche) {
313       // pas trop grand : commentaire interessant
314       return Blend_StepTooLarge;
315     }
316   }
317   return Blend_OK;
318 }