849ce9080ffc091f2c489a9d697af33d110b58b1
[occt.git] / src / IntWalk / IntWalk_IWalking_4.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 #include <NCollection_IncAllocator.hxx>
21
22 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
23                                         const TColStd_SequenceOfReal& Vmult,
24                                         const ThePOPIterator& Pnts1,
25                                         const ThePOLIterator& Pnts2,
26                                         TheIWFunction& Func,
27                                         Standard_Boolean& Rajout ) 
28 // *********** Processing of closed line **********************
29 //
30 // for any interior non-processed point 
31 //       calculate the step of advancement=step depending on the arrow and max step
32 //       calculate a point of approach (this point is on the tangent to the section
33 // of distance = no interior point)
34 //  conditions 
35 //            (all calculated points do not form a closed loop)  
36 //                              or                    
37 //            (all points do not form an open line going from 
38 //            one border of the domain to the other or from a point tangent
39 //            to the border or from 2 tangent points : single cases)
40 //  
41 //     frame the point of approach on borders if necessary
42 //     calculate the point
43 //     if point not found divide the step
44 //     test of stop    
45 //     calculate step depending on the arrow and the max step (stop possible)
46 //
47 // ******************************************************************** 
48 {
49
50   Standard_Integer I,N = 0;
51   Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
52   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
53   math_Vector Uvap(aUVap,1,2);// parameters of current approach
54   Standard_Real PasC;  // rate of advancement on the tangent
55   Standard_Real PasCu; // rate of advancement current by U
56   Standard_Real PasCv; // step of advancement current by V
57   Standard_Real PasSav; // save first step of advancement
58   Standard_Boolean Arrive;// show if line ends
59   Standard_Boolean Cadre; // show if on border of the  domains
60   Standard_Boolean ArretAjout; // show if on the added point
61   IntSurf_PntOn2S Psol;
62   Handle(IntWalk_TheIWLine)  CurrentLine; //line under construction
63   ThePointOfPath PathPnt;
64   ThePointOfLoop LoopPnt;
65
66   Standard_Boolean Tgtbeg,Tgtend;
67
68   Standard_Integer StepSign;
69   
70   IntWalk_StatusDeflection Status,StatusPrecedent;
71   Standard_Integer NbDivision ;   // number of divisions of step 
72   // during calculation of  1 section
73
74   Standard_Integer Ipass ;
75   //index in the iterator of points on edge of point of passage  
76
77
78   BornInf(1) = Um;
79   BornSup(1) = UM;
80   BornInf(2) = Vm;
81   BornSup(2) = VM;
82   
83   math_FunctionSetRoot Rsnld(Func,tolerance);
84   Standard_Integer nbLoop = Pnts2.Length();
85   
86   for (I = 1;I<=nbLoop;I++) {
87     if (wd2[I].etat > 12) { // start point of closed line
88       
89       LoopPnt = Pnts2.Value(I);
90       previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
91                              wd2[I].ustart,wd2[I].vstart);
92       previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
93       previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
94
95       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
96       CurrentLine->AddPoint(previousPoint);
97       CurrentLine->SetTangentVector(previousd3d,1);
98       Tgtbeg = Standard_False;
99       Tgtend = Standard_False;
100       Uvap(1) = wd2[I].ustart;
101       Uvap(2) = wd2[I].vstart;
102
103       StepSign = 1;
104
105       // first step of advancement
106
107       Standard_Real d2dx = Abs(previousd2d.X()); 
108       Standard_Real d2dy = Abs(previousd2d.Y()); 
109       if (d2dx < tolerance(1)) {
110         PasC = pas * (VM-Vm)/d2dy;
111       }
112       else if (d2dy < tolerance(2)) {
113         PasC = pas * (UM-Um)/d2dx;
114       }
115       else {
116         PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
117       }
118
119       PasSav = PasC;
120
121       Arrive = Standard_False;
122       ArretAjout = Standard_False;
123       NbDivision = 0;
124       StatusPrecedent = IntWalk_OK;
125       while (!Arrive) {  // as no test of stop is passed
126         Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
127 #ifdef CHRONO
128         Chronrsnld.Start();
129 #endif
130
131         Rsnld.Perform(Func,Uvap,BornInf,BornSup);
132
133 #ifdef CHRONO
134         Chronrsnld.Stop();
135 #endif
136
137         if (Cadre) { // update of limits.
138           BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
139         }
140         if (Rsnld.IsDone()) {
141           if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
142             PasC = PasC/2.;
143             PasCu = Abs(PasC*previousd2d.X());
144             PasCv = Abs(PasC*previousd2d.Y());
145
146             if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
147               if (CurrentLine->NbPoints()==1) break;
148               Arrive = Standard_True;
149               CurrentLine->AddStatusFirstLast(Standard_False,
150                                               Standard_False,Standard_False);
151               Rajout = Standard_True;
152               seqAjout.Append(lines.Length()+1);
153               Tgtend = Standard_True;
154             }
155           }
156           else { // there is a solution
157             Rsnld.Root(Uvap);
158             Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
159             if (Arrive) {//reset proper parameter to test the arrow.
160               Psol = CurrentLine->Value(1);
161               if (!reversed) {
162                 Psol.ParametersOnS2(Uvap(1),Uvap(2));
163               }
164               else {
165                 Psol.ParametersOnS1(Uvap(1),Uvap(2));
166               }
167               Cadre=Standard_False; 
168               //in case if there is a frame and arrival at the same time
169             }
170             else { // modif jag 940615
171
172               if (Rajout) {    // test on added points
173                 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
174                 if (ArretAjout) {
175                   if (N >0) {
176                     Tgtend = lines.Value(N)->IsTangentAtEnd();
177                     N = -N;
178                   }
179                   else {
180                     Tgtend = lines.Value(-N)->IsTangentAtBegining();
181                   }
182                   Arrive = (wd2[I].etat == 12);
183                 }
184               }
185
186               if (!ArretAjout&& Cadre) {  // test on already marked points
187                 if (CurrentLine->NbPoints() == 1)  break; // cancel the line
188                 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
189 //              if (N==0) {
190                 if (N <= 0) { // jag 941017
191                   MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
192                   Tgtend = Func.IsTangent(); // jag 940616
193                   N = -N;
194                 }
195                 Arrive = (wd2[I].etat == 12); // the line is open
196               }
197             }
198             Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
199                                     NbDivision,PasC,StepSign);
200             StatusPrecedent = Status; 
201             if (Status == IntWalk_PasTropGrand) {// division of the step
202               Arrive = Standard_False;
203               ArretAjout = Standard_False;
204               Tgtend = Standard_False; // jag 940616
205               if (!reversed) {
206                 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
207               }
208               else {
209                 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
210               }
211             }
212             else if (ArretAjout || Cadre) {
213
214               if (Arrive) { // line s is open
215                 CurrentLine->AddStatusLast(Standard_False);
216                 if (Status != IntWalk_ArretSurPointPrecedent) {
217                   CurrentLine->AddPoint(Psol);                      
218                 }
219                 if (Cadre && N==0) {
220                   Rajout = Standard_True;
221                   seqAjout.Append(lines.Length()+1);
222                 }
223                 
224               }
225               else { // open
226                 wd2[I].etat = 12; // declare it open
227                 Tgtbeg = Tgtend;
228                 Tgtend = Standard_False;
229                 ArretAjout = Standard_False;
230                 StepSign = -1;
231                 StatusPrecedent = IntWalk_OK;
232                 PasC = PasSav;
233                 if (Status == IntWalk_ArretSurPointPrecedent) {
234                   OpenLine(0,Psol,Pnts1,Func,CurrentLine);
235                 }
236                 else {
237                   OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
238                 }
239                 if (Cadre && N==0) {
240                   Rajout = Standard_True;
241                   seqAjout.Append(-lines.Length()-1);
242                 }
243               }
244             }
245
246             else if ( Status == IntWalk_ArretSurPointPrecedent) {
247               if (CurrentLine->NbPoints() == 1) { //cancel the line
248                 Arrive = Standard_False;
249                 break;
250               }
251               if (wd2[I].etat >12) { //the line should become open
252                 wd2[I].etat = 12; //declare it open
253                 ArretAjout = Standard_False;
254                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
255                 StepSign = -1;
256                 StatusPrecedent = IntWalk_OK;
257                 Arrive = Standard_False;
258                 PasC = PasSav;
259                 Rajout = Standard_True;
260                 seqAjout.Append(-lines.Length()-1);
261               }
262               else { // line s is open                 
263                 Arrive =Standard_True;
264                 CurrentLine->AddStatusLast(Standard_False);
265                 Rajout = Standard_True;
266                 seqAjout.Append(lines.Length()+1);
267               } 
268             }
269             else if (Arrive)  {
270               if (wd2[I].etat > 12) {  //line closed good case
271                 CurrentLine->AddStatusFirstLast(Standard_True,
272                                                Standard_False,Standard_False);
273                 CurrentLine->AddPoint(CurrentLine->Value(1));              
274               }
275               else if (N >0) { //point of stop given at input 
276                 PathPnt = Pnts1.Value(N);
277                 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
278                 AddPointInCurrentLine(N,PathPnt,CurrentLine);
279               }
280             }
281             else if (Status == IntWalk_ArretSurPoint) {
282               if (wd2[I].etat >12) { //line should become open
283                 wd2[I].etat = 12; //declare it open
284                 Tgtbeg = Standard_True;
285                 Tgtend = Standard_False;
286                 N= -lines.Length()-1;
287                 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
288                 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
289                 StepSign = -1;
290                 Rajout = Standard_True;
291                 seqAjout.Append(N);
292                 StatusPrecedent = IntWalk_OK;
293                 Arrive = Standard_False;
294                 PasC = PasSav;  
295               }
296               else { 
297                 Arrive = Standard_True;                   
298                 if (Ipass!=0) { //point of passage, point of stop
299                   PathPnt = Pnts1.Value(Ipass);
300                   CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
301                   AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
302                 }
303                 else {
304                   CurrentLine->AddStatusLast(Standard_False);
305                   IntSurf_PntOn2S newP;
306                   newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
307                   CurrentLine->AddPoint(newP);
308                   Rajout = Standard_True;
309                   seqAjout.Append(lines.Length()+1);
310                 }
311               }
312             }
313             else if (Status == IntWalk_OK) { 
314               if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
315               previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
316               previousd3d = Func.Direction3d();
317               previousd2d = Func.Direction2d();
318               CurrentLine->AddPoint(previousPoint);
319             }
320           }
321         }
322         else { //no numerical solution NotDone
323           PasC = PasC/2.;
324           PasCu = Abs(PasC*previousd2d.X());
325           PasCv = Abs(PasC*previousd2d.Y());
326
327           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
328             if (CurrentLine->NbPoints() == 1)  break; // cancel the line
329             Arrive = Standard_True;
330             CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
331                                            Standard_False);
332             Tgtend = Standard_True;
333             Rajout = Standard_True;
334             seqAjout.Append(lines.Length()+1);
335           }  
336         }
337       }// end of started line 
338       if (Arrive) {
339         CurrentLine->SetTangencyAtBegining(Tgtbeg);
340         CurrentLine->SetTangencyAtEnd(Tgtend);
341         
342         lines.Append(CurrentLine);
343         wd2[I].etat=-wd2[I].etat; //mark point as processed
344       }
345     } //end of processing of start point
346   } //end of all start points
347 }
348
349
350
351
352
353