0024727: Convertation of the generic classes to the non-generic. Part 3
[occt.git] / src / IntWalk / IntWalk_PWalking_3.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 #include <Standard_Failure.hxx>
16 #include <Precision.hxx>
17
18 //#define DEBUG 0 
19
20 namespace {
21 //OCC431(apo): modified ->
22 static const Standard_Real CosRef2D =  Cos(M_PI/9.0),  AngRef2D = M_PI/2.0; 
23
24 static const Standard_Real d = 7.0;
25 }
26
27 IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
28
29 // test if vector is observed by calculating an increase of vector 
30 //     or the previous point and its tangent, the new calculated point and its  
31 //     tangent; it is possible to find a cube passing by the 2 points and having as a 
32 //     derivative the tangents of the intersection
33 //     calculate the point with parameter 0.5 on cube=p1 
34 //     calculate the medium point of 2 points of intersection=p2
35 //   if arrow/2<=||p1p2||<= arrow consider that the vector is observed
36 //   otherwise adjust the step depending on the ratio ||p1p2||/vector
37 //   and the previous step 
38 // test if in  2 tangent planes of surfaces there is no too great angle2d 
39 // grand : if yes divide the step
40 // test if there is no change of side
41 //  
42 {
43   if(line->NbPoints() ==1 ) { 
44     STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
45   }
46
47   IntWalk_StatusDeflection Status = IntWalk_OK;
48   Standard_Real FlecheCourante ,Ratio;
49
50
51   const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); 
52   //==================================================================================
53   //=========               S t o p   o n   p o i n t                 ============
54   //================================================================================== 
55   if (myIntersectionOn2S.IsTangent())  { 
56     return IntWalk_ArretSurPoint;  
57   }
58
59   const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
60
61   //==================================================================================
62   //=========   R i s k   o f    i n f l e x i o n   p o i n t  ============
63   //==================================================================================  
64   if (TgCourante.Dot(previousd)<0) {
65     //------------------------------------------------------------
66     //-- Risk of inflexion point : Divide the step by 2
67     //-- Initialize STATIC_PRECEDENT_INFLEXION so that 
68     //-- at the next call to return Pas_OK if there is no 
69     //-- more risk of the point of inflexion
70     //------------------------------------------------------------
71
72     pasuv[0]*=0.5;
73     pasuv[1]*=0.5;
74     pasuv[2]*=0.5;
75     pasuv[3]*=0.5;
76     STATIC_PRECEDENT_INFLEXION+=3; 
77     if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
78       return IntWalk_ArretSurPointPrecedent;
79     else 
80       return IntWalk_PasTropGrand;
81   }
82   
83   else {
84     if(STATIC_PRECEDENT_INFLEXION  > 0) { 
85       STATIC_PRECEDENT_INFLEXION -- ;
86       return IntWalk_OK;
87     }
88   }
89   
90   //==================================================================================
91   //=========  D e t e c t    c o n f u s e d    P o in t s       ===========
92   //==================================================================================
93
94   Standard_Real Dist = previousPoint.Value().
95     SquareDistance(CurrentPoint.Value());
96
97
98   if (Dist < tolconf*tolconf ) { 
99     pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
100     pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
101     pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
102     pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
103     Status = IntWalk_PointConfondu;
104   }
105
106   //==================================================================================
107   Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
108   Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
109
110   previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
111   CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);               
112
113   Du1 = Uc1 - Up1;   Dv1 = Vc1 - Vp1;
114   Du2 = Uc2 - Up2;   Dv2 = Vc2 - Vp2;
115
116   AbsDu1 = Abs(Du1);
117   AbsDu2 = Abs(Du2);
118   AbsDv1 = Abs(Dv1);
119   AbsDv2 = Abs(Dv2);
120   //=================================================================================
121   //====   S t e p   o f   p  r o g r e s s i o n (between previous and Current)   =======
122   //=================================================================================
123   if (   AbsDu1 < ResoU1 && AbsDv1 < ResoV1 
124       && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
125     pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
126     return(IntWalk_ArretSurPointPrecedent);
127   }
128   //==================================================================================
129   
130   Standard_Real tolArea = 100.0;
131   if (ResoU1 < Precision::PConfusion() ||
132       ResoV1 < Precision::PConfusion() ||
133       ResoU2 < Precision::PConfusion() ||
134       ResoV2 < Precision::PConfusion() )
135     tolArea =  tolArea*2.0;
136
137   Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;   
138   Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;   
139   Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
140   Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
141   Duv1 = Du1*Du1 + Dv1*Dv1;
142   Duv2 = Du2*Du2 + Dv2*Dv2;
143   ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
144   ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
145   //
146   //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
147   //
148   Standard_Real aMinDiv2=Precision::Confusion();
149   aMinDiv2=aMinDiv2*aMinDiv2;
150   //
151   d1=d;
152   if (Duv1>aMinDiv2)  {
153     d1 = Abs(ResoUV1/Duv1);
154     d1 = Min(Sqrt(d1)*tolArea, d);  
155   } 
156   //d1 = Abs(ResoUV1/Duv1); 
157   //d1 = Min(Sqrt(d1)*tolArea,d);  
158   //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
159   tolCoeff1 = Exp(d1);
160   //
161   //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
162   d2=d;
163   if (Duv2>aMinDiv2) {
164     d2 = Abs(ResoUV2/Duv2); 
165     d2 = Min(Sqrt(d2)*tolArea,d); 
166   }
167   //d2 = Abs(ResoUV2/Duv2); 
168   //d2 = Min(Sqrt(d2)*tolArea,d);  
169   //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
170   tolCoeff2 = Exp(d2);
171   CosRef1 = CosRef2D/tolCoeff1;
172   CosRef2 = CosRef2D/tolCoeff2;
173   //
174   //==================================================================================
175   //== The points are not confused :                                           ==
176   //== D e t e c t    t h e   S t o p   a  t   p r e v i o u s  p o i n t ==
177   //==                           N o t    T o o    G r e a t (angle in space UV)    ==
178   //==                           C h a n g e    o f    s i d e                ==
179   //==================================================================================
180   if (Status != IntWalk_PointConfondu) { 
181     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
182       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
183       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) { 
184         return(IntWalk_ArretSurPointPrecedent);
185       }
186       else {
187         pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
188         return(IntWalk_PasTropGrand);
189       }
190     }
191     const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
192     const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
193     Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
194     Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
195     Ang1 = Abs(previousd1.Angle(Tg2dcourante1));  
196     Ang2 = Abs(previousd2.Angle(Tg2dcourante2));  
197     AngRef1 = AngRef2D*tolCoeff1;
198     AngRef2 = AngRef2D*tolCoeff2;
199     //-------------------------------------------------------
200     //-- Test : Angle too great in space UV       -----
201     //--        Change of  side                      -----
202     //-------------------------------------------------------
203     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
204       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
205       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) 
206         return(IntWalk_ArretSurPoint);
207       else 
208         return(IntWalk_PasTropGrand);
209     }
210   }
211   //<-OCC431(apo)
212   //==================================================================================
213   //== D e t e c t i o n   o f    :  Step Too Small 
214   //==                               STEP TOO Great 
215   //==================================================================================
216
217   //---------------------------------------
218   //-- Estimate of the vector           --
219   //---------------------------------------
220   FlecheCourante =
221     Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
222
223   if ( FlecheCourante<= fleche*0.5) {     //-- Current step too small
224     if(FlecheCourante>1e-16) { 
225       Ratio = 0.5*(fleche/FlecheCourante);
226     }
227     else { 
228       Ratio = 10.0;
229     }
230     Standard_Real pasSu1 = pasuv[0];
231     Standard_Real pasSv1 = pasuv[1];
232     Standard_Real pasSu2 = pasuv[2];
233     Standard_Real pasSv2 = pasuv[3];
234     
235     //-- In  case if 
236     //-- a point at U+DeltaU is required, ....
237     //-- return a point at U + Epsilon
238     //-- Epsilon << DeltaU.
239     
240     if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
241     if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
242     if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
243     if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
244     
245     if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
246     if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
247     if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
248     if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
249     //-- if(Ratio>10.0 ) { Ratio=10.0; } 
250     Standard_Real R1,R = pasInit[0]/pasuv[0];
251     R1= pasInit[1]/pasuv[1];     if(R1<R) R=R1;
252     R1= pasInit[2]/pasuv[2];     if(R1<R) R=R1;
253     R1= pasInit[3]/pasuv[3];     if(R1<R) R=R1;
254     if(Ratio > R) Ratio=R;
255     pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
256     pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
257     pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
258     pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
259     if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2|| 
260         pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
261       if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
262         STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
263         return IntWalk_PasTropGrand; 
264       }
265     }
266     if(Status == IntWalk_OK) { 
267       STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
268       //-- Try to increase the step
269     }
270     return Status;
271   }
272   else {                                //-- CurrentVector > vector*0.5 
273     if (FlecheCourante > fleche) {      //-- Current step too Great
274       Ratio = fleche/FlecheCourante; 
275       pasuv[0] = Ratio*pasuv[0];
276       pasuv[1] = Ratio*pasuv[1];
277       pasuv[2] = Ratio*pasuv[2];
278       pasuv[3] = Ratio*pasuv[3];
279       //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
280       //        STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
281         return IntWalk_PasTropGrand; 
282       //}
283     }
284     else {                             //-- vector/2  <  CurrentVector <= vector   
285       Ratio = 0.75 * (fleche / FlecheCourante);
286     }
287   }
288   pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
289   pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
290   pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
291   pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
292   if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
293   return Status;
294 }
295      
296
297