Integration of OCCT 6.5.0 from SVN
[occt.git] / src / IntWalk / IntWalk_IWalking_3.gxx
1 //-- File IntWalk_IWalking_3.gxx
2
3
4 #ifndef DEB
5 #define No_Standard_RangeError
6 #define No_Standard_OutOfRange
7 #endif
8
9 // modified by NIZHNY-MKK  Thu Nov  2 15:07:26 2000.BEGIN
10 static Standard_Boolean TestPassedSolutionWithNegativeState(const TColStd_SequenceOfInteger& etat,
11                                                             const TColStd_SequenceOfReal& Umult,
12                                                             const TColStd_SequenceOfReal& Vmult,
13                                                             const TColStd_SequenceOfReal& ustart,
14                                                             const TColStd_SequenceOfReal& vstart,
15                                                             const Standard_Real& prevUp, 
16                                                             const Standard_Real& prevVp,
17                                                             const TColStd_SequenceOfInteger& nbMultiplicities,
18                                                             const math_Vector& tolerance,
19                                                             TheIWFunction& sp,
20                                                             math_Vector& UV,
21                                                             Standard_Integer& Irang);
22 // modified by NIZHNY-MKK  Thu Nov  2 15:07:39 2000.END
23
24
25 void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
26                                        const TColStd_SequenceOfReal& Vmult,
27                                        const ThePOPIterator& Pnts1,
28                                        TheIWFunction& Func,
29                                        Standard_Boolean& Rajout) 
30
31 // traitement ligne ouvert.
32 //
33 // 1) pour tout point de depart non passant et non tangent et non encore traite
34 //    calcul du pas d'avancement = pas en fonction de la fleche et du pas max.
35 //
36 // 2) calcul d'un point approche (ce point est sur la tangente a la section
37 // de distance = pas du point interieur)
38 //  
39 // 3) tant que {
40 //            (l'ensemble des points calcules ne depassent pas un point dans la
41 //             liste des points de depart)
42 //                              ou                    
43 //            (l'ensemble des points ne forme pas une ligne ouverte allant 
44 //            d 'une frontiere du domaine a un autre ou d un point de tangence
45 //            a une frontiere ou de 2 points de tangence : cas singuliers)
46 //  
47 //     1) cadrage du point approche sur les frontieres si necessaire (il
48 //        y a calcul du pas)
49 //     2) calcul du point
50 //     3) si point non trouve on divise le pas
51 //     4) tests d'arrets    
52 //     5) calcul du pas en fonction de la fleche et du pas maxi,
53 //        (TestDeflection)
54 //        arret possible.
55 //    fin tant que.
56
57 {
58   Standard_Integer I, N;
59   static math_Vector BornInf(1,2), BornSup(1,2), UVap(1,2);
60   Standard_Real PasC, PasCu, PasCv;
61   Standard_Boolean Arrive; // indique si ligne terminee
62   Standard_Boolean Cadre;  //indique si on est sur frontiere du domaine
63   Standard_Boolean ArretAjout;  //indique si on est sur point ajoute
64   IntSurf_PntOn2S Psol;
65   Handle(IntWalk_TheIWLine)  CurrentLine;    // ligne en construction
66   Standard_Boolean Tgtend;
67
68   IntWalk_StatusDeflection Status, StatusPrecedent;
69   
70   Standard_Integer NbDivision; 
71   // nombre de fois que l on a divise le pas pour une section
72
73   Standard_Integer StepSign;
74   
75   ThePointOfPath PathPnt;
76
77   BornInf(1) = Um;
78   BornSup(1) = UM;
79   BornInf(2) = Vm;
80   BornSup(2) = VM;
81
82   math_FunctionSetRoot Rsnld(Func, tolerance);
83   Standard_Integer nbPath = Pnts1.Length();
84
85   // modified by NIZHNY-MKK  Fri Oct 27 12:32:34 2000.BEGIN
86   TColStd_SequenceOfInteger movementdirectioninfo;
87   for (I = 1; I <= nbPath; I++) {
88     movementdirectioninfo.Append(0);
89   }
90   // modified by NIZHNY-MKK  Fri Oct 27 12:32:38 2000.END
91
92   for (I = 1; I <= nbPath; I++) {
93     //point de depart de cheminement
94     //     if (etat1(I) > 11) {                
95     // modified by NIZHNY-MKK  Fri Oct 27 12:33:37 2000.BEGIN
96     if ((etat1(I) > 11) || ((etat1(I) < -11) && (movementdirectioninfo(I)!=0))) {
97     // modified by NIZHNY-MKK  Fri Oct 27 12:33:43 2000.END
98       PathPnt = Pnts1.Value(I);     
99       CurrentLine = new IntWalk_TheIWLine ();
100       CurrentLine->SetTangencyAtBegining(Standard_False);
101       Tgtend = Standard_False;
102       CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
103       UVap(1) = ustart1(I);
104       UVap(2) = vstart1(I);
105       MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
106       previousd3d = Func.Direction3d();
107       previousd2d = Func.Direction2d();
108       CurrentLine->AddPoint(previousPoint);
109       // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
110       if(movementdirectioninfo(I) !=0) {
111         if(movementdirectioninfo(I) < 0) {
112           StepSign = -1;
113           CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
114         } else {
115           StepSign = 1; 
116           CurrentLine->SetTangentVector(previousd3d,1);
117         }
118       } else {
119         Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
120         if( tyutuyt < 0) {
121           StepSign = -1;
122           CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
123         }
124         else {
125           StepSign = 1; 
126           CurrentLine->SetTangentVector(previousd3d,1);
127         }
128       }
129       // modified by NIZHNY-MKK  Fri Oct 27 12:34:37 2000.END
130
131 //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
132       etat1(I) = - abs(etat1(I));
133       movementdirectioninfo(I) = (movementdirectioninfo(I)==0) ? StepSign : 0;
134 //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
135       // premier pas d avancement
136       Standard_Real d2dx = Abs(previousd2d.X()); 
137       Standard_Real d2dy = Abs(previousd2d.Y()); 
138       if (d2dx < tolerance(1)) {
139         PasC = pas * (VM-Vm)/d2dy;
140       }
141       else if (d2dy < tolerance(2)) {
142         PasC = pas * (UM-Um)/d2dx;
143       }
144       else {
145         PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
146       }
147
148       Arrive = Standard_False;
149       ArretAjout = Standard_False;
150       NbDivision = 0;
151       StatusPrecedent = IntWalk_OK;
152       // modified by NIZHNY-MKK  Fri Oct 27 12:39:37 2000
153       Standard_Integer IndexOfPathPointDoNotCheck=0;
154
155       while (!Arrive) { //    tant que un des tests d  arret est non verifie
156
157         Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
158         //  Frontiere?
159
160 #ifdef CHRONO
161         Chronrsnld.Start();
162 #endif
163
164         Rsnld.Perform(Func,UVap,BornInf,BornSup);
165
166 #ifdef CHRONO
167         Chronrsnld.Stop();
168 #endif
169
170         if (Cadre) {
171           BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
172         }
173         if (Rsnld.IsDone()) {
174           if (Abs(Func.Root()) > Func.Tolerance()) {
175             PasC = PasC / 2.0;
176             PasCu = Abs(PasC*previousd2d.X());
177             PasCv = Abs(PasC*previousd2d.Y());
178             if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
179               if (CurrentLine->NbPoints() == 1) break;
180               Arrive = Standard_True;
181               CurrentLine->AddStatusLast(Standard_False);
182               Tgtend = Standard_True; // a voir
183               Rajout = Standard_True;
184               seqAjout.Append(lines.Length() + 1);
185             }  
186           }
187           else { // test arret
188             Rsnld.Root(UVap);
189             Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
190             if (Arrive) {
191               Cadre = Standard_False;
192               //au cas ou on aurait cadre et arrive en meme temps
193             }
194             else {
195               if (Rajout) {
196                 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
197                 if (ArretAjout) {
198                   // jag 940615
199                   Tgtend = lines.Value(N)->IsTangentAtEnd();
200                   N = -N;
201                 }
202               }
203               // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
204               if(!(Rajout && ArretAjout)) {
205                 Standard_Real prevUp, prevVp;
206                 if (!reversed) {
207                   previousPoint.ParametersOnS2(prevUp, prevVp);
208                 }
209                 else {
210                   previousPoint.ParametersOnS1(prevUp, prevVp);
211                 }
212                 Arrive = TestPassedSolutionWithNegativeState(etat1, Umult, Vmult, ustart1, vstart1, prevUp, prevVp,
213                                                              nbMultiplicities, tolerance, Func, UVap, N);               
214                 if(Arrive) {
215                   Cadre = Standard_False;
216                 }
217               }
218               // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
219               if (!ArretAjout && Cadre) {
220                 if (CurrentLine->NbPoints() == 1) break; // annuler la ligne
221                 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
222 //              if (N == 0) {
223                 if (N <= 0) { // jag 941017
224                   MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
225                   Tgtend = Func.IsTangent();
226                   N = -N;
227                 }
228               }
229             }
230             Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
231                                     NbDivision,PasC,StepSign);
232             StatusPrecedent = Status;
233             if (Status == IntWalk_PasTropGrand) {
234               Arrive = Standard_False;
235               ArretAjout = Standard_False;
236               Tgtend = Standard_False; // jag 940615
237               if (!reversed) {
238                 previousPoint.ParametersOnS2(UVap(1), UVap(2));
239               }
240               else {
241                 previousPoint.ParametersOnS1(UVap(1), UVap(2));
242               }
243             }
244             else if (ArretAjout || Cadre) {
245               Arrive = Standard_True;
246               CurrentLine->AddStatusLast(Standard_False);
247               if (Status != IntWalk_ArretSurPointPrecedent) {
248                 CurrentLine->AddPoint(Psol);                      
249               }
250               if (Cadre && N==0) {
251                 Rajout = Standard_True;
252                 seqAjout.Append(lines.Length()+1);
253               }
254             }
255             else if (Status == IntWalk_ArretSurPointPrecedent) {
256               if (CurrentLine->NbPoints() == 1) { //annuler la ligne
257                 Arrive = Standard_False;
258                 break;
259               }
260               Arrive = Standard_True;
261               Rajout = Standard_True;
262               seqAjout.Append(lines.Length() + 1);
263               CurrentLine->AddStatusLast(Standard_False);
264               Tgtend = Standard_True; // a voir
265             }
266             else if (Arrive)  {
267               if (CurrentLine->NbPoints() == 1 &&    // annuler la ligne
268                   (N == I || Status == IntWalk_PointConfondu) ) {
269                 // si N == I on s est probablement trompe de uv 
270                 // principal ou bien le point 
271                 // est un point d accumulation
272                 // si point confondu les donnees de depart sont mauvaises
273                 Arrive =  Standard_False;
274                 break;
275               }
276               // on a necessairement N > 0 jag 940617
277               // point d arret donne en entree 
278               PathPnt = Pnts1.Value(N);
279               
280               Standard_Integer etat1N=etat1(N);
281               // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
282               //              if (etat1N < 11) { // point passant qui est un arret  
283               if (Abs(etat1N) < 11) { // point passant qui est un arret  
284                 // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
285                 if (Status == IntWalk_ArretSurPoint) { 
286                   CurrentLine->AddStatusLast(Standard_False);
287                   Tgtend = Standard_True; // a voir
288                 }
289                 else { 
290                   Arrive = Standard_False;
291                 }
292                 CurrentLine->AddIndexPassing(N);
293               }
294               else { // point d  arret donne en entree
295                 if (etat1N == 11) {
296                   Tgtend = Standard_True;
297                 }
298                 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
299               }
300               AddPointInCurrentLine(N,PathPnt,CurrentLine);
301               if ((etat1N != 1 && etat1N != 11)) {
302                 // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
303                 //              etat1(N)= - etat1N;
304                 etat1(N)= - Abs(etat1N);                
305                 movementdirectioninfo(N) = (movementdirectioninfo(N)==0) ? StepSign : 0;
306                 if(Arrive && movementdirectioninfo(N)!=0) {
307                   IndexOfPathPointDoNotCheck = N;
308                 }
309
310                 if(Arrive) {
311                   Rajout = Standard_True;
312                   seqAjout.Append(lines.Length() + 1);
313                 }
314                 // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
315               }
316             }
317             else if (Status == IntWalk_ArretSurPoint) {
318               Arrive = Standard_True;                   
319               CurrentLine->AddStatusLast(Standard_False);
320               Tgtend = Standard_True;
321               MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
322               CurrentLine->AddPoint(Psol);
323               Rajout = Standard_True;
324               seqAjout.Append(lines.Length() + 1);
325             }
326             else if (Status == IntWalk_OK) { 
327               MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
328               previousd3d = Func.Direction3d();
329               previousd2d = Func.Direction2d();
330               CurrentLine->AddPoint(previousPoint);
331             }                           
332           }
333         }
334         else { // pas de solution numerique
335           PasC = PasC / 2.;
336           PasCu = Abs(PasC*previousd2d.X());
337           PasCv = Abs(PasC*previousd2d.Y());
338           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
339             if (CurrentLine->NbPoints()==1) break;
340             Arrive = Standard_True;
341             CurrentLine->AddStatusLast(Standard_False);
342             Tgtend = Standard_True; // a voir
343             Rajout = Standard_True;
344             seqAjout.Append(lines.Length() + 1);
345           }  
346         }
347       } // fin de la ligne commencee
348       
349       if (Arrive) {
350         CurrentLine->SetTangencyAtEnd(Tgtend);
351         lines.Append(CurrentLine);
352         // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
353         movementdirectioninfo(I)=0;
354         if(etat1(I) > 0)
355         // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
356           etat1(I)=-etat1(I);
357
358         //-- lbr le 5 juin 97 (Pb ds Contap)
359         for(Standard_Integer av=1; av<=nbPath; av++) { 
360           // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
361           //      if (etat1(av) > 11) {
362           if ((etat1(av) > 11) || 
363               ((av!=I) && 
364                (av!=IndexOfPathPointDoNotCheck) && 
365                (etat1(av) < -11)  && 
366                (movementdirectioninfo(av)!=0))) {
367           // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
368             Standard_Real Uav=ustart1(av);
369             Standard_Real Vav=vstart1(av);
370             Standard_Real Uavp,Vavp;
371             const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
372             if (!reversed) {
373               avP.ParametersOnS2(Uavp,Vavp);
374             }
375             else {
376               avP.ParametersOnS1(Uavp,Vavp);
377             }
378             Uav-=Uavp;
379             Vav-=Vavp;
380             Uav*=0.001; Vav*=0.001;
381             if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
382               // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
383               //              etat1(av)=-etat1(av);
384               if(etat1(av) < 0) {
385                 movementdirectioninfo(av) = 0;
386               } else {
387                 etat1(av)=-etat1(av);
388                 movementdirectioninfo(av) = StepSign;
389               }
390               // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
391               CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
392               //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
393             }
394             
395             const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
396             if (!reversed) {
397               avPP.ParametersOnS2(Uavp,Vavp);
398             }
399             else {
400               avPP.ParametersOnS1(Uavp,Vavp);
401             }
402             Uav=ustart1(av);
403             Vav=vstart1(av);
404             Uav-=Uavp;
405             Vav-=Vavp;
406             Uav*=0.001; Vav*=0.001;
407             if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
408               // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
409               //              etat1(av)=-etat1(av);
410               if(etat1(av) < 0) {
411                 movementdirectioninfo(av) = 0;
412               } else {
413                 etat1(av)=-etat1(av);
414                 movementdirectioninfo(av) = -StepSign;
415               }
416               // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
417               //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
418               CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
419             }
420           }
421         }
422           
423       }
424     } //fin de traitement d  un point
425   } //fin de tous les points
426 }
427
428 // modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
429 static Standard_Boolean TestPassedSolutionWithNegativeState(const TColStd_SequenceOfInteger& etat,
430                                                             const TColStd_SequenceOfReal& Umult,
431                                                             const TColStd_SequenceOfReal& Vmult,
432                                                             const TColStd_SequenceOfReal& ustart,
433                                                             const TColStd_SequenceOfReal& vstart,
434                                                             const Standard_Real& prevUp,
435                                                             const Standard_Real& prevVp,
436                                                             const TColStd_SequenceOfInteger& nbMultiplicities,
437                                                             const math_Vector& tolerance,
438                                                             TheIWFunction& sp,
439                                                             math_Vector& UV,
440                                                             Standard_Integer& Irang) {
441   Standard_Boolean Arrive = Standard_False;
442   Standard_Real Dup, Dvp, Utest,Vtest;
443   Standard_Real tolu = tolerance(1);
444   Standard_Real tolv = tolerance(2);
445   Standard_Integer i, j, k, N;
446   for (i = 1; i <= etat.Length(); i++) {
447     if (etat(i) < -11) {
448
449  // debug jag voir avec isg
450
451       Utest = ustart(i);
452       Vtest = vstart(i);
453       Dup = prevUp - Utest;
454       Dvp = prevVp - Vtest;
455       if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
456         Standard_Real UV1mUtest = UV(1)-Utest;
457         Standard_Real UV2mVtest = UV(2)-Vtest;
458         if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
459            (   Abs(UV1mUtest) < tolu 
460             && Abs(UV2mVtest) < tolv)) {
461           Irang=i;
462           Arrive = Standard_True;
463           UV(1) = Utest;
464           UV(2) = Vtest;
465         }
466         else if (nbMultiplicities(i) > 0) {
467           N=0;
468           for (k = 1; k < i; k++) { 
469             N+=nbMultiplicities(k);
470           }
471           for (j = N + 1; j <= N + nbMultiplicities(i); j++) {
472             if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
473                  (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
474                 (Abs(UV(1)-Umult(j)) < tolu &&
475                  Abs(UV(2)-Vmult(j)) < tolv)) {
476               Irang=i;
477               Arrive = Standard_True;
478               UV(1) = Utest;
479               UV(2) = Vtest;
480               break;
481             }
482           }
483         }
484         if (Arrive) {
485           static math_Vector bidF(1,1);
486           static math_Matrix bidD(1,1,1,2);
487 #ifdef DEB
488           Standard_Boolean bidB = 
489 #endif
490             sp.Values(UV,bidF,bidD);
491           break;
492         }
493       }
494     }    
495   }
496   return Arrive;
497 }
498 // modified by NIZHNY-MKK  Thu Nov  2 15:07:58 2000.END