0023952: Improving thread-safety of intersections, approximations and other modeling...
[occt.git] / src / IntWalk / IntWalk_IWalking_3.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20
21 #ifndef DEB
22 #define No_Standard_RangeError
23 #define No_Standard_OutOfRange
24 #endif
25
26 // modified by NIZHNY-MKK  Thu Nov  2 15:07:26 2000.BEGIN
27 static Standard_Boolean TestPassedSolutionWithNegativeState(const TColStd_SequenceOfInteger& etat,
28                                                             const TColStd_SequenceOfReal& Umult,
29                                                             const TColStd_SequenceOfReal& Vmult,
30                                                             const TColStd_SequenceOfReal& ustart,
31                                                             const TColStd_SequenceOfReal& vstart,
32                                                             const Standard_Real& prevUp, 
33                                                             const Standard_Real& prevVp,
34                                                             const TColStd_SequenceOfInteger& nbMultiplicities,
35                                                             const math_Vector& tolerance,
36                                                             TheIWFunction& sp,
37                                                             math_Vector& UV,
38                                                             Standard_Integer& Irang);
39 // modified by NIZHNY-MKK  Thu Nov  2 15:07:39 2000.END
40
41
42 void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
43                                        const TColStd_SequenceOfReal& Vmult,
44                                        const ThePOPIterator& Pnts1,
45                                        TheIWFunction& Func,
46                                        Standard_Boolean& Rajout) 
47
48 // Processing of open line.
49 //
50 // 1) for any starting point, which is not passing and not tangent and not yet processed,
51 //    calculation of the step of advancement = step depending on the arrow and the maximum step.
52 //
53 // 2) calculate a point of approach (this point is on the tangent to the section
54 // of distance = no point in the interior)
55 //  
56 // 3) conditions  {
57 //            (all calculated points do not exceed a point in the
58 //             list of starting points)
59 //                              or                    
60 //            (all points do not form an open line going 
61 //            from one border of the domain to the other or from a point tangent 
62 //            to border or from 2 tangent points : single cases)
63 //  
64 //     1) framing of approached point on borders if necessary (there is
65 //        calculation of step)
66 //     2) calculation of the point
67 //     3) if the point is not found the step is divided
68 //     4) stpo tests    
69 //     5) calculation of the step depending on the arrow and the max step,
70 //        (TestDeflection)
71 //        stop  possible.
72 //    end of conditions.
73
74 {
75   Standard_Integer I, N;
76   Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
77   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
78   Standard_Real PasC, PasCu, PasCv;
79   Standard_Boolean Arrive; // shows if the line ends
80   Standard_Boolean Cadre;  // shows if one is on border of the domain
81   Standard_Boolean ArretAjout;  //shows if one is on added point
82   IntSurf_PntOn2S Psol;
83   Handle(IntWalk_TheIWLine)  CurrentLine;    // line under construction
84   Standard_Boolean Tgtend;
85
86   IntWalk_StatusDeflection Status, StatusPrecedent;
87   
88   Standard_Integer NbDivision; 
89   // number of divisions of step for each section
90
91   Standard_Integer StepSign;
92   
93   ThePointOfPath PathPnt;
94
95   BornInf(1) = Um;
96   BornSup(1) = UM;
97   BornInf(2) = Vm;
98   BornSup(2) = VM;
99
100   math_FunctionSetRoot Rsnld(Func, tolerance);
101   Standard_Integer nbPath = Pnts1.Length();
102
103   // modified by NIZHNY-MKK  Fri Oct 27 12:32:34 2000.BEGIN
104   TColStd_SequenceOfInteger movementdirectioninfo;
105   for (I = 1; I <= nbPath; I++) {
106     movementdirectioninfo.Append(0);
107   }
108   // modified by NIZHNY-MKK  Fri Oct 27 12:32:38 2000.END
109
110   for (I = 1; I <= nbPath; I++) {
111     //start point of the progression
112     //     if (etat1(I) > 11) {                
113     // modified by NIZHNY-MKK  Fri Oct 27 12:33:37 2000.BEGIN
114     if ((etat1(I) > 11) || ((etat1(I) < -11) && (movementdirectioninfo(I)!=0))) {
115     // modified by NIZHNY-MKK  Fri Oct 27 12:33:43 2000.END
116       PathPnt = Pnts1.Value(I);     
117       CurrentLine = new IntWalk_TheIWLine ();
118       CurrentLine->SetTangencyAtBegining(Standard_False);
119       Tgtend = Standard_False;
120       CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
121       UVap(1) = ustart1(I);
122       UVap(2) = vstart1(I);
123       MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
124       previousd3d = Func.Direction3d();
125       previousd2d = Func.Direction2d();
126       CurrentLine->AddPoint(previousPoint);
127       // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
128       if(movementdirectioninfo(I) !=0) {
129         if(movementdirectioninfo(I) < 0) {
130           StepSign = -1;
131           CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
132         } else {
133           StepSign = 1; 
134           CurrentLine->SetTangentVector(previousd3d,1);
135         }
136       } else {
137         Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
138         if( tyutuyt < 0) {
139           StepSign = -1;
140           CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
141         }
142         else {
143           StepSign = 1; 
144           CurrentLine->SetTangentVector(previousd3d,1);
145         }
146       }
147       // modified by NIZHNY-MKK  Fri Oct 27 12:34:37 2000.END
148
149 //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
150       etat1(I) = - abs(etat1(I));
151       movementdirectioninfo(I) = (movementdirectioninfo(I)==0) ? StepSign : 0;
152 //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
153       // first step of advancement
154       Standard_Real d2dx = Abs(previousd2d.X()); 
155       Standard_Real d2dy = Abs(previousd2d.Y()); 
156       if (d2dx < tolerance(1)) {
157         PasC = pas * (VM-Vm)/d2dy;
158       }
159       else if (d2dy < tolerance(2)) {
160         PasC = pas * (UM-Um)/d2dx;
161       }
162       else {
163         PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
164       }
165
166       Arrive = Standard_False;
167       ArretAjout = Standard_False;
168       NbDivision = 0;
169       StatusPrecedent = IntWalk_OK;
170       // modified by NIZHNY-MKK  Fri Oct 27 12:39:37 2000
171       Standard_Integer IndexOfPathPointDoNotCheck=0;
172
173       while (!Arrive) { //    as one of stop tests is not checked
174
175         Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
176         //  Border?
177
178 #ifdef CHRONO
179         Chronrsnld.Start();
180 #endif
181
182         Rsnld.Perform(Func,UVap,BornInf,BornSup);
183
184 #ifdef CHRONO
185         Chronrsnld.Stop();
186 #endif
187
188         if (Cadre) {
189           BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
190         }
191         if (Rsnld.IsDone()) {
192           if (Abs(Func.Root()) > Func.Tolerance()) {
193             PasC = PasC / 2.0;
194             PasCu = Abs(PasC*previousd2d.X());
195             PasCv = Abs(PasC*previousd2d.Y());
196             if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
197               if (CurrentLine->NbPoints() == 1) break;
198               Arrive = Standard_True;
199               CurrentLine->AddStatusLast(Standard_False);
200               Tgtend = Standard_True; // check
201               Rajout = Standard_True;
202               seqAjout.Append(lines.Length() + 1);
203             }  
204           }
205           else { // test stop
206             Rsnld.Root(UVap);
207             Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
208             if (Arrive) {
209               Cadre = Standard_False;
210               //in case if there is a frame and arrive at the same time
211             }
212             else {
213               if (Rajout) {
214                 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
215                 if (ArretAjout) {
216                   // jag 940615
217                   Tgtend = lines.Value(N)->IsTangentAtEnd();
218                   N = -N;
219                 }
220               }
221               // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
222               if(!(Rajout && ArretAjout)) {
223                 Standard_Real prevUp, prevVp;
224                 if (!reversed) {
225                   previousPoint.ParametersOnS2(prevUp, prevVp);
226                 }
227                 else {
228                   previousPoint.ParametersOnS1(prevUp, prevVp);
229                 }
230                 Arrive = TestPassedSolutionWithNegativeState(etat1, Umult, Vmult, ustart1, vstart1, prevUp, prevVp,
231                                                              nbMultiplicities, tolerance, Func, UVap, N);               
232                 if(Arrive) {
233                   Cadre = Standard_False;
234                 }
235               }
236               // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
237               if (!ArretAjout && Cadre) {
238                 if (CurrentLine->NbPoints() == 1) break; // cancel the line
239                 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
240 //              if (N == 0) {
241                 if (N <= 0) { // jag 941017
242                   MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
243                   Tgtend = Func.IsTangent();
244                   N = -N;
245                 }
246               }
247             }
248             Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
249                                     NbDivision,PasC,StepSign);
250             StatusPrecedent = Status;
251             if (Status == IntWalk_PasTropGrand) {
252               Arrive = Standard_False;
253               ArretAjout = Standard_False;
254               Tgtend = Standard_False; // jag 940615
255               if (!reversed) {
256                 previousPoint.ParametersOnS2(UVap(1), UVap(2));
257               }
258               else {
259                 previousPoint.ParametersOnS1(UVap(1), UVap(2));
260               }
261             }
262             else if (ArretAjout || Cadre) {
263               Arrive = Standard_True;
264               CurrentLine->AddStatusLast(Standard_False);
265               if (Status != IntWalk_ArretSurPointPrecedent) {
266                 CurrentLine->AddPoint(Psol);                      
267               }
268               if (Cadre && N==0) {
269                 Rajout = Standard_True;
270                 seqAjout.Append(lines.Length()+1);
271               }
272             }
273             else if (Status == IntWalk_ArretSurPointPrecedent) {
274               if (CurrentLine->NbPoints() == 1) { //cancel the line
275                 Arrive = Standard_False;
276                 break;
277               }
278               Arrive = Standard_True;
279               Rajout = Standard_True;
280               seqAjout.Append(lines.Length() + 1);
281               CurrentLine->AddStatusLast(Standard_False);
282               Tgtend = Standard_True; // check
283             }
284             else if (Arrive)  {
285               if (CurrentLine->NbPoints() == 1 &&    // cancel the line
286                   (N == I || Status == IntWalk_PointConfondu) ) {
287                 // if N == I the main uv is probably lost
288                 // or the point is a point of accumulation
289                 // if point is confused the start data is bad
290                 Arrive =  Standard_False;
291                 break;
292               }
293               // necessairily N > 0 jag 940617
294               // point of stop given at input 
295               PathPnt = Pnts1.Value(N);
296               
297               Standard_Integer etat1N=etat1(N);
298               // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
299               //              if (etat1N < 11) { // passing point that is a stop  
300               if (Abs(etat1N) < 11) { // passing point that is a stop    
301                 // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
302                 if (Status == IntWalk_ArretSurPoint) { 
303                   CurrentLine->AddStatusLast(Standard_False);
304                   Tgtend = Standard_True; // need check
305                 }
306                 else { 
307                   Arrive = Standard_False;
308                 }
309                 CurrentLine->AddIndexPassing(N);
310               }
311               else { // point of stop given at input
312                 if (etat1N == 11) {
313                   Tgtend = Standard_True;
314                 }
315                 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
316               }
317               AddPointInCurrentLine(N,PathPnt,CurrentLine);
318               if ((etat1N != 1 && etat1N != 11)) {
319                 // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
320                 //              etat1(N)= - etat1N;
321                 etat1(N)= - Abs(etat1N);                
322                 movementdirectioninfo(N) = (movementdirectioninfo(N)==0) ? StepSign : 0;
323                 if(Arrive && movementdirectioninfo(N)!=0) {
324                   IndexOfPathPointDoNotCheck = N;
325                 }
326
327                 if(Arrive) {
328                   Rajout = Standard_True;
329                   seqAjout.Append(lines.Length() + 1);
330                 }
331                 // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
332               }
333             }
334             else if (Status == IntWalk_ArretSurPoint) {
335               Arrive = Standard_True;                   
336               CurrentLine->AddStatusLast(Standard_False);
337               Tgtend = Standard_True;
338               MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
339               CurrentLine->AddPoint(Psol);
340               Rajout = Standard_True;
341               seqAjout.Append(lines.Length() + 1);
342             }
343             else if (Status == IntWalk_OK) { 
344               MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
345               previousd3d = Func.Direction3d();
346               previousd2d = Func.Direction2d();
347               CurrentLine->AddPoint(previousPoint);
348             }                           
349           }
350         }
351         else { // no numerical solution
352           PasC = PasC / 2.;
353           PasCu = Abs(PasC*previousd2d.X());
354           PasCv = Abs(PasC*previousd2d.Y());
355           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
356             if (CurrentLine->NbPoints()==1) break;
357             Arrive = Standard_True;
358             CurrentLine->AddStatusLast(Standard_False);
359             Tgtend = Standard_True; // need check
360             Rajout = Standard_True;
361             seqAjout.Append(lines.Length() + 1);
362           }  
363         }
364       } // end of started line
365       
366       if (Arrive) {
367         CurrentLine->SetTangencyAtEnd(Tgtend);
368         lines.Append(CurrentLine);
369         // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
370         movementdirectioninfo(I)=0;
371         if(etat1(I) > 0)
372         // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
373           etat1(I)=-etat1(I);
374
375         //-- lbr le 5 juin 97 (Pb ds Contap)
376         for(Standard_Integer av=1; av<=nbPath; av++) { 
377           // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
378           //      if (etat1(av) > 11) {
379           if ((etat1(av) > 11) || 
380               ((av!=I) && 
381                (av!=IndexOfPathPointDoNotCheck) && 
382                (etat1(av) < -11)  && 
383                (movementdirectioninfo(av)!=0))) {
384           // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
385             Standard_Real Uav=ustart1(av);
386             Standard_Real Vav=vstart1(av);
387             Standard_Real Uavp,Vavp;
388             const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
389             if (!reversed) {
390               avP.ParametersOnS2(Uavp,Vavp);
391             }
392             else {
393               avP.ParametersOnS1(Uavp,Vavp);
394             }
395             Uav-=Uavp;
396             Vav-=Vavp;
397             Uav*=0.001; Vav*=0.001;
398             if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
399               // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
400               //              etat1(av)=-etat1(av);
401               if(etat1(av) < 0) {
402                 movementdirectioninfo(av) = 0;
403               } else {
404                 etat1(av)=-etat1(av);
405                 movementdirectioninfo(av) = StepSign;
406               }
407               // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
408               CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
409               //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
410             }
411             
412             const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
413             if (!reversed) {
414               avPP.ParametersOnS2(Uavp,Vavp);
415             }
416             else {
417               avPP.ParametersOnS1(Uavp,Vavp);
418             }
419             Uav=ustart1(av);
420             Vav=vstart1(av);
421             Uav-=Uavp;
422             Vav-=Vavp;
423             Uav*=0.001; Vav*=0.001;
424             if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
425               // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
426               //              etat1(av)=-etat1(av);
427               if(etat1(av) < 0) {
428                 movementdirectioninfo(av) = 0;
429               } else {
430                 etat1(av)=-etat1(av);
431                 movementdirectioninfo(av) = -StepSign;
432               }
433               // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
434               //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
435               CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
436             }
437           }
438         }
439           
440       }
441     } //end of point processing
442   } //end of all points
443 }
444
445 // modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
446 static Standard_Boolean TestPassedSolutionWithNegativeState(const TColStd_SequenceOfInteger& etat,
447                                                             const TColStd_SequenceOfReal& Umult,
448                                                             const TColStd_SequenceOfReal& Vmult,
449                                                             const TColStd_SequenceOfReal& ustart,
450                                                             const TColStd_SequenceOfReal& vstart,
451                                                             const Standard_Real& prevUp,
452                                                             const Standard_Real& prevVp,
453                                                             const TColStd_SequenceOfInteger& nbMultiplicities,
454                                                             const math_Vector& tolerance,
455                                                             TheIWFunction& sp,
456                                                             math_Vector& UV,
457                                                             Standard_Integer& Irang) {
458   Standard_Boolean Arrive = Standard_False;
459   Standard_Real Dup, Dvp, Utest,Vtest;
460   Standard_Real tolu = tolerance(1);
461   Standard_Real tolv = tolerance(2);
462   Standard_Integer i, j, k, N;
463   for (i = 1; i <= etat.Length(); i++) {
464     if (etat(i) < -11) {
465
466  // debug jag see with isg
467
468       Utest = ustart(i);
469       Vtest = vstart(i);
470       Dup = prevUp - Utest;
471       Dvp = prevVp - Vtest;
472       if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
473         Standard_Real UV1mUtest = UV(1)-Utest;
474         Standard_Real UV2mVtest = UV(2)-Vtest;
475         if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
476            (   Abs(UV1mUtest) < tolu 
477             && Abs(UV2mVtest) < tolv)) {
478           Irang=i;
479           Arrive = Standard_True;
480           UV(1) = Utest;
481           UV(2) = Vtest;
482         }
483         else if (nbMultiplicities(i) > 0) {
484           N=0;
485           for (k = 1; k < i; k++) { 
486             N+=nbMultiplicities(k);
487           }
488           for (j = N + 1; j <= N + nbMultiplicities(i); j++) {
489             if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
490                  (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
491                 (Abs(UV(1)-Umult(j)) < tolu &&
492                  Abs(UV(2)-Vmult(j)) < tolv)) {
493               Irang=i;
494               Arrive = Standard_True;
495               UV(1) = Utest;
496               UV(2) = Vtest;
497               break;
498             }
499           }
500         }
501         if (Arrive) {
502           Standard_Real abidF[1], abidD[1][2];
503           math_Vector bidF(abidF,1,1);
504           math_Matrix bidD(abidD,1,1,1,2); 
505       sp.Values(UV,bidF,bidD);
506           break;
507         }
508       }
509     }    
510   }
511   return Arrive;
512 }
513 // modified by NIZHNY-MKK  Thu Nov  2 15:07:58 2000.END