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