0032341: Coding Rules - eliminate GCC11 compiler warnings -Wmaybe-uninitialized
[occt.git] / src / IntWalk / IntWalk_IWalking_4.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 <NCollection_IncAllocator.hxx>
16
17 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
18                                         const TColStd_SequenceOfReal& Vmult,
19                                         const ThePOPIterator& Pnts1,
20                                         const ThePOLIterator& Pnts2,
21                                         TheIWFunction& Func,
22                                         Standard_Boolean& Rajout )
23 // *********** Processing of closed line **********************
24 //
25 // for any interior non-processed point 
26 //       calculate the step of advancement=step depending on the arrow and max step
27 //       calculate a point of approach (this point is on the tangent to the section
28 // of distance = no interior point)
29 //  conditions 
30 //            (all calculated points do not form a closed loop)  
31 //                              or                    
32 //            (all points do not form an open line going from 
33 //            one border of the domain to the other or from a point tangent
34 //            to the border or from 2 tangent points : single cases)
35 //  
36 //     frame the point of approach on borders if necessary
37 //     calculate the point
38 //     if point not found divide the step
39 //     test of stop    
40 //     calculate step depending on the arrow and the max step (stop possible)
41 //
42 // ******************************************************************** 
43 {
44   Standard_Integer I = 0, N = 0,SaveN = 0;
45   Standard_Real aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
46   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
47   math_Vector Uvap(aUVap,1,2);// parameters of current approach
48   Standard_Real PasC = 0.0;  // step of advancement on the tangent
49   Standard_Real PasCu = 0.0; // step of advancement current by U
50   Standard_Real PasCv = 0.0; // step of advancement current by V
51   Standard_Real PasSav = 0.0; // save first step of advancement
52   Standard_Boolean Arrive = false;// show if line ends
53   Standard_Boolean Cadre = false; // show if on border of the  domains
54   Standard_Boolean ArretAjout = false; // show if on the added point
55   IntSurf_PntOn2S Psol;
56   Handle(IntWalk_TheIWLine)  CurrentLine; //line under construction
57   ThePointOfPath PathPnt;
58   ThePointOfLoop LoopPnt;
59
60   Standard_Boolean Tgtbeg = false, Tgtend = false;
61
62   Standard_Integer StepSign = 0;
63   
64   IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent;
65   Standard_Integer NbDivision = 0;   // number of divisions of step
66   // during calculation of  1 section
67
68   Standard_Integer Ipass = 0;
69   //index in the iterator of points on edge of point of passage  
70
71
72   BornInf(1) = Um;
73   BornSup(1) = UM;
74   BornInf(2) = Vm;
75   BornSup(2) = VM;
76   
77   math_FunctionSetRoot Rsnld(Func,tolerance);
78   Standard_Integer nbLoop = Pnts2.Length();
79
80   // Check borders for degeneracy:
81   math_Matrix D(1,1,1,2);
82   const Standard_Integer aNbSamplePnt = 10;
83   Standard_Boolean isLeftDegeneratedBorder[2] = {Standard_True, Standard_True};
84   Standard_Boolean isRightDegeneratedBorder[2] = {Standard_True, Standard_True};
85   math_Vector aStep(1,2);
86   aStep = (BornSup - BornInf) / (aNbSamplePnt - 1);
87   for(Standard_Integer aBorderIdx = 1; aBorderIdx <= 2; aBorderIdx++)
88   {
89     Standard_Integer aChangeIdx = aBorderIdx == 2? 1 : 2;
90     math_Vector UV(1,2);
91
92     // Left border.
93     UV(aBorderIdx) = BornInf(aBorderIdx);
94     for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
95     {
96       Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
97       UV(aChangeIdx) = aParam;
98       Func.Derivatives(UV, D);
99       if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
100       {
101         isLeftDegeneratedBorder[aBorderIdx - 1] = Standard_False;
102         break;
103       }
104     }
105
106     // Right border.
107     UV(aBorderIdx) = BornSup(aBorderIdx);
108     for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
109     {
110       Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
111       UV(aChangeIdx) = aParam;
112       Func.Derivatives(UV, D);
113       if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
114       {
115         isRightDegeneratedBorder[aBorderIdx - 1] = Standard_False;
116         break;
117       }
118     }
119   }
120
121   TheIWFunction aFuncForDuplicate = Func;
122
123   for (I = 1;I<=nbLoop;I++) {
124     if (wd2[I].etat > 12)
125     { // start point of closed line
126       LoopPnt = Pnts2.Value(I);
127       previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed,
128                              wd2[I].ustart, wd2[I].vstart);
129
130       if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
131       {
132         wd2[I].etat = -wd2[I].etat; //mark point as processed
133         continue;
134       }
135
136       previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
137       previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
138
139       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
140       CurrentLine->AddPoint(previousPoint);
141       CurrentLine->SetTangentVector(previousd3d,1);
142       Tgtbeg = Standard_False;
143       Tgtend = Standard_False;
144       Uvap(1) = wd2[I].ustart;
145       Uvap(2) = wd2[I].vstart;
146
147       StepSign = 1;
148
149       // first step of advancement
150
151       Standard_Real d2dx = Abs(previousd2d.X()); 
152       Standard_Real d2dy = Abs(previousd2d.Y()); 
153       if (d2dx < tolerance(1)) {
154         PasC = pas * (VM-Vm)/d2dy;
155       }
156       else if (d2dy < tolerance(2)) {
157         PasC = pas * (UM-Um)/d2dx;
158       }
159       else {
160         PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
161       }
162
163       PasSav = PasC;
164
165       Arrive = Standard_False;
166       ArretAjout = Standard_False;
167       NbDivision = 0;
168       StatusPrecedent = IntWalk_OK;
169       Standard_Integer aNbIter = 10;
170       while (!Arrive) {  // as no test of stop is passed
171         Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
172 #ifdef CHRONO
173         Chronrsnld.Start();
174 #endif
175
176         Rsnld.Perform(Func,Uvap,BornInf,BornSup);
177
178 #ifdef CHRONO
179         Chronrsnld.Stop();
180 #endif
181
182         if (Cadre) { // update of limits.
183           BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
184         }
185         if (Rsnld.IsDone()) {
186           if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
187             PasC = PasC/2.;
188             PasCu = Abs(PasC*previousd2d.X());
189             PasCv = Abs(PasC*previousd2d.Y());
190
191             if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
192               if (CurrentLine->NbPoints()==1)
193               {
194                 RemoveTwoEndPoints(I);
195                 break; //cancel the line
196               }
197               if (wd2[I].etat >12) { //the line should become open
198                 wd2[I].etat = 12; //declare it open
199                 ArretAjout = Standard_False;
200                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
201                 StepSign = -1;
202                 StatusPrecedent = IntWalk_OK;
203                 Arrive = Standard_False;
204                 PasC = PasSav;
205                 Rajout = Standard_True;
206                 seqAlone.Append(-lines.Length()-1);
207                 seqAjout.Append(-lines.Length()-1);
208               }
209               else { // line s is open                 
210                 Arrive =Standard_True;
211                 CurrentLine->AddStatusLast(Standard_False);
212                 Rajout = Standard_True;
213                 seqAlone.Append(lines.Length()+1);
214                 seqAjout.Append(lines.Length()+1);
215                 Tgtend = Standard_True;
216               } 
217               /*              
218               Arrive = Standard_True;
219               CurrentLine->AddStatusFirstLast(Standard_False,
220                 Standard_False,Standard_False);
221               Rajout = Standard_True;
222               seqAlone.Append(lines.Length()+1);
223               seqAjout.Append(lines.Length()+1);
224               Tgtend = Standard_True;
225               */
226             }
227           }
228           else { // there is a solution
229             Rsnld.Root(Uvap);
230
231             // Avoid uninitialized memory access.
232             if (CurrentLine->NbPoints() > 2)
233             {
234               for(Standard_Integer aCoordIdx = 1; aCoordIdx <= 2; aCoordIdx++)
235               {
236                 // Check degenerated cases and fix if possible.
237                 if ( ( isLeftDegeneratedBorder[aCoordIdx - 1]
238                 && Abs (Uvap(aCoordIdx) - BornInf(aCoordIdx)) < Precision::PConfusion())||
239                   (isRightDegeneratedBorder[aCoordIdx - 1]
240                 && Abs (Uvap(aCoordIdx) - BornSup(aCoordIdx)) < Precision::PConfusion()) )
241                 {
242                   Standard_Real uvprev[2], uv[2];
243                   if (!reversed)
244                   {
245                     CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS2(uvprev[0], uvprev[1]);
246                     CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS2(uv[0], uv[1]);
247                   }
248                   else
249                   {
250                     CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS1(uvprev[0], uvprev[1]);
251                     CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS1(uv[0], uv[1]);
252                   }
253
254                   Standard_Real aScaleCoeff = 0.0;
255
256                   // Avoid finite cycle which lead to stop computing iline.
257                   if (aStatus != IntWalk_PasTropGrand)
258                   {
259                     // Make linear extrapolation.
260                     if ( Abs(uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) > gp::Resolution())
261                       aScaleCoeff = Abs ((Uvap(aCoordIdx) - uv[aCoordIdx - 1])
262                                       /  (uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) );
263                     Standard_Integer aFixIdx =  aCoordIdx == 1? 2 : 1; // Fixing index;
264                     Uvap(aFixIdx) = uv[aFixIdx - 1] + (uv[aFixIdx - 1] - uvprev[aFixIdx - 1]) * aScaleCoeff;
265                   }
266                 }
267               }
268             }
269
270             Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
271             if (Arrive) {//reset proper parameter to test the arrow.
272               Psol = CurrentLine->Value(1);
273               if (!reversed) {
274                 Psol.ParametersOnS2(Uvap(1),Uvap(2));
275               }
276               else {
277                 Psol.ParametersOnS1(Uvap(1),Uvap(2));
278               }
279               Cadre=Standard_False; 
280               //in case if there is a frame and arrival at the same time
281             }
282             else { // modif jag 940615
283               if (Rajout) {    // test on added points
284                 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
285                 SaveN = N;
286                 if (ArretAjout) {
287                   if (N >0) {
288                     Tgtend = lines.Value(N)->IsTangentAtEnd();
289                     N = -N;
290                   }
291                   else {
292                     Tgtend = lines.Value(-N)->IsTangentAtBegining();
293                   }
294                   Arrive = (wd2[I].etat == 12);
295                 }
296               }
297
298               if (!ArretAjout&& Cadre) {  // test on already marked points
299                 if (CurrentLine->NbPoints() == 1)
300                 {
301                   RemoveTwoEndPoints(I);
302                   break; // cancel the line
303                 }
304                 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
305                 SaveN = N;
306                 //              if (N==0) {
307                 if (N <= 0) { // jag 941017
308                   MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
309                   Tgtend = Func.IsTangent(); // jag 940616
310                   N = -N;
311                 }
312                 Arrive = (wd2[I].etat == 12); // the line is open
313               }
314             }
315             aStatus = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
316                                                 NbDivision,PasC,StepSign);
317
318             StatusPrecedent = aStatus;
319             if (aStatus == IntWalk_PasTropGrand) {// division of the step
320               Arrive = Standard_False;
321               ArretAjout = Standard_False;
322               Tgtend = Standard_False; // jag 940616
323               if (!reversed) {
324                 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
325               }
326               else {
327                 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
328               }
329             }
330             else if (ArretAjout || Cadre) {
331
332               if (Arrive) { // line s is open
333                 CurrentLine->AddStatusLast(Standard_False);
334                 //if (aStatus != IntWalk_ArretSurPointPrecedent)
335                 CurrentLine->AddPoint(Psol);
336
337                 //Remove <SaveN> from <seqAlone> and, if it is first found point,
338                 //from <seqAjout> too
339                 if (IsValidEndPoint(I, SaveN))
340                 {
341                   for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
342                     if (seqAlone(iseq) == SaveN)
343                     {
344                       seqAlone.Remove(iseq);
345                       break;
346                     }
347                   if (CurrentLine->NbPoints() <= 3)
348                     for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
349                       if (seqAjout(iseq) == SaveN)
350                       {
351                         seqAjout.Remove(iseq);
352                         break;
353                       }
354                 }
355                 else
356                 {
357                   if (seqAlone.Last() == -lines.Length()-1)
358                   {
359                     seqAlone.Remove(seqAlone.Length());
360                     seqAjout.Remove(seqAjout.Length());
361                   }
362                   RemoveTwoEndPoints(I);
363                   Arrive = Standard_False;
364                   break; //cancel the line
365                 }
366
367                 if (Cadre && N==0) {
368                   Rajout = Standard_True;
369                   //seqAlone.Append(lines.Length()+1);
370                   seqAjout.Append(lines.Length()+1);
371                 }
372
373               }
374               else { // open
375                 wd2[I].etat = 12; // declare it open
376                 Tgtbeg = Tgtend;
377                 Tgtend = Standard_False;
378                 ArretAjout = Standard_False;
379                 StepSign = -1;
380                 StatusPrecedent = IntWalk_OK;
381                 PasC = PasSav;
382                 if (aStatus == IntWalk_ArretSurPointPrecedent) {
383                   CurrentLine->AddPoint(Psol);
384                   OpenLine(0,Psol,Pnts1,Func,CurrentLine);
385                 }
386                 else {
387                   OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
388                 }
389                 //Remove <SaveN> from <seqAlone> and, if it is first found point,
390                 //from <seqAjout> too
391                 if (IsValidEndPoint(I, SaveN))
392                 {
393                   for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
394                     if (seqAlone(iseq) == SaveN)
395                     {
396                       seqAlone.Remove(iseq);
397                       break;
398                     }
399                   if (CurrentLine->NbPoints() <= 2)
400                     for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
401                       if (seqAjout(iseq) == SaveN)
402                       {
403                         seqAjout.Remove(iseq);
404                         break;
405                       }
406                 }
407                 else
408                 {
409                   RemoveTwoEndPoints(I);
410                   break; //cancel the line
411                 }
412                 
413                 if (Cadre && N==0) {
414                   Rajout = Standard_True;
415                   seqAjout.Append(-lines.Length()-1);
416                 }
417               }
418             }
419             else if (aStatus == IntWalk_ArretSurPointPrecedent) {
420               if (CurrentLine->NbPoints() == 1) { //cancel the line
421                 Arrive = Standard_False;
422                 RemoveTwoEndPoints(I);
423                 break;
424               }
425               if (wd2[I].etat >12) { //the line should become open
426                 wd2[I].etat = 12; //declare it open
427                 ArretAjout = Standard_False;
428                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
429                 StepSign = -1;
430                 StatusPrecedent = IntWalk_OK;
431                 Arrive = Standard_False;
432                 PasC = PasSav;
433                 Rajout = Standard_True;
434                 seqAlone.Append(-lines.Length()-1);
435                 seqAjout.Append(-lines.Length()-1);
436               }
437               else { // line s is open                 
438                 Arrive =Standard_True;
439                 CurrentLine->AddStatusLast(Standard_False);
440                 Rajout = Standard_True;
441                 seqAlone.Append(lines.Length()+1);
442                 seqAjout.Append(lines.Length()+1);
443               } 
444             }
445             else if (Arrive)  {
446               if (wd2[I].etat > 12) {  //line closed good case
447                 CurrentLine->AddStatusFirstLast(Standard_True,
448                   Standard_False,Standard_False);
449                 CurrentLine->AddPoint(CurrentLine->Value(1));
450               }
451               else if ((N >0) && (Pnts1.Length() >= N))
452               {
453                 //point of stop given at input 
454                 PathPnt = Pnts1.Value(N);
455                 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
456                 AddPointInCurrentLine(N,PathPnt,CurrentLine);
457               }
458             }
459             else if (aStatus == IntWalk_ArretSurPoint) {
460               if (wd2[I].etat >12) { //line should become open
461                 wd2[I].etat = 12; //declare it open
462                 Tgtbeg = Standard_True;
463                 Tgtend = Standard_False;
464                 N= -lines.Length()-1;
465                 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
466                 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
467                 StepSign = -1;
468                 Rajout = Standard_True;
469                 seqAlone.Append(N);
470                 seqAjout.Append(N);
471                 StatusPrecedent = IntWalk_OK;
472                 Arrive = Standard_False;
473                 PasC = PasSav;  
474               }
475               else { 
476                 Arrive = Standard_True;                   
477                 if (Ipass!=0) { //point of passage, point of stop
478                   PathPnt = Pnts1.Value(Ipass);
479                   CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
480                   AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
481                 }
482                 else {
483                   CurrentLine->AddStatusLast(Standard_False);
484                   IntSurf_PntOn2S newP;
485                   newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
486                   CurrentLine->AddPoint(newP);
487                   Rajout = Standard_True;
488                   seqAlone.Append(lines.Length()+1);
489                   seqAjout.Append(lines.Length()+1);
490                 }
491               }
492             }
493             else if (aStatus == IntWalk_OK) {
494               if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
495               previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
496               previousd3d = Func.Direction3d();
497               previousd2d = Func.Direction2d();
498               CurrentLine->AddPoint(previousPoint);
499             }
500             else if (aStatus == IntWalk_PointConfondu)
501             {
502               aNbIter --;
503             }
504           }
505         }
506         else { //no numerical solution NotDone
507           PasC = PasC/2.;
508           PasCu = Abs(PasC*previousd2d.X());
509           PasCv = Abs(PasC*previousd2d.Y());
510
511           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
512             if (CurrentLine->NbPoints() == 1)
513             {
514               RemoveTwoEndPoints(I);
515               break; // cancel the line
516             }
517             if (wd2[I].etat >12) { //the line should become open
518               wd2[I].etat = 12; //declare it open
519               ArretAjout = Standard_False;
520               OpenLine(0,Psol,Pnts1,Func,CurrentLine);
521               StepSign = -1;
522               StatusPrecedent = IntWalk_OK;
523               Arrive = Standard_False;
524               PasC = PasSav;
525               Rajout = Standard_True;
526               seqAlone.Append(-lines.Length()-1);
527               seqAjout.Append(-lines.Length()-1);
528             }
529             else { // line s is open                 
530               Arrive =Standard_True;
531               CurrentLine->AddStatusLast(Standard_False);
532               Tgtend = Standard_True;
533               Rajout = Standard_True;
534               seqAlone.Append(lines.Length()+1);
535               seqAjout.Append(lines.Length()+1);
536             } 
537             /*
538             Arrive = Standard_True;
539             CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
540               Standard_False);
541             Tgtend = Standard_True;
542             Rajout = Standard_True;
543             seqAlone.Append(lines.Length()+1);
544             seqAjout.Append(lines.Length()+1);
545             */
546           }  
547         }
548
549         if(aNbIter < 0)
550           break;
551       }// end of started line 
552       if (Arrive) {
553         CurrentLine->SetTangencyAtBegining(Tgtbeg);
554         CurrentLine->SetTangencyAtEnd(Tgtend);
555
556         lines.Append(CurrentLine);
557         wd2[I].etat=-wd2[I].etat; //mark point as processed
558       }
559     } //end of processing of start point
560   } //end of all start points
561 }