0024059: Eliminate compiler warning C4701 in MSVC++ with warning level 4
[occt.git] / src / Blend / Blend_Walking_1.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 Blend_Walking::Blend_Walking(const TheSurface& Surf1,
20                              const TheSurface& Surf2,
21                              const Handle(TheTopolTool)& Domain1,
22                              const Handle(TheTopolTool)& Domain2):
23        sol(1,4),surf1(Surf1),surf2(Surf2),
24        done(Standard_False),
25        clasonS1(Standard_True),clasonS2(Standard_True),
26        check2d(Standard_True),check(Standard_True),
27        twistflag1(Standard_False),twistflag2(Standard_False)
28
29 {
30   domain1 = Domain1;
31   domain2 = Domain2;
32   recdomain1 = Domain1;
33   recdomain2 = Domain2;  
34 }
35
36 void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1,
37                                         const Handle(TheTopolTool)& Domain2)
38 {
39   recdomain1 = Domain1;
40   recdomain2 = Domain2;
41 }
42
43 void Blend_Walking::AddSingularPoint(const Blend_Point& P) 
44 {
45   if (jalons.Length() == 0) {
46     jalons.Append(P);
47   }
48   else {
49     Standard_Integer ii, jj;
50     Standard_Real tp = P.Parameter(), 
51                   ti=jalons.First().Parameter();
52     for (jj=1, ii=1; ii<=jalons.Length() && tp>ti; ii++) {
53       jj = ii;
54       ti = jalons.Value(jj).Parameter();
55     }
56     if (tp > ti) jalons.InsertAfter(jj, P);
57     else         jalons.InsertBefore(jj, P); 
58   }
59 }
60
61 void Blend_Walking::Perform(Blend_Function& Func,
62                             Blend_FuncInv& FuncInv,
63                             const Standard_Real Pdep,   
64                             const Standard_Real Pmax,
65                             const Standard_Real MaxStep,
66                             const Standard_Real TolGuide,
67                             const math_Vector& ParDep,
68                             const Standard_Real Tolesp,
69                             const Standard_Real Fleche,
70                             const Standard_Boolean Appro)
71 {
72
73   done = Standard_False;
74   iscomplete = Standard_False;
75   comptra = Standard_False;
76   Standard_Boolean doextremities = 1;
77   if(line.IsNull()) line = new TheLine ();
78   else {line->Clear();doextremities = 0;}
79   tolesp = Abs(Tolesp);
80   tolgui = Abs(TolGuide);
81   fleche = Abs(Fleche);
82   rebrou = Standard_False;
83   pasmax = Abs(MaxStep);
84   if (Pmax-Pdep >= 0.) {
85     sens = 1.;
86   }
87   else {
88     sens = -1.;
89   }
90
91   Blend_Status State;
92   TheExtremity ptf1,ptf2;
93
94   param = Pdep;
95   Func.Set(param);
96
97   if (Appro) {
98
99     TopAbs_State situ1,situ2;
100     math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
101     Func.GetTolerance(tolerance,tolesp);
102     Func.GetBounds(infbound,supbound);
103     math_FunctionSetRoot rsnld(Func,tolerance,30);
104
105     rsnld.Perform(Func,ParDep,infbound,supbound);
106     
107     if (!rsnld.IsDone()) {
108       return;
109     }
110     rsnld.Root(sol);
111
112     if(clasonS1) situ1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
113                                            Min(tolerance(1),tolerance(2)),0);
114     else situ1 = TopAbs_IN;
115     if(clasonS2) situ2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
116                                            Min(tolerance(3),tolerance(4)),0);
117     else situ2 = TopAbs_IN;
118
119     if (situ1 != TopAbs_IN || situ2 != TopAbs_IN) {
120       return;
121     }
122   }
123   else {
124     sol = ParDep;
125   }
126
127 #ifdef DEB
128   sectioncalculee = 0;
129 #endif
130   State = TestArret(Func, Blend_OK, Standard_False);
131   if (State!=Blend_OK) {
132     return;
133   }
134 #ifdef DEB
135   if (Blend_GettraceDRAWSECT()){
136     Drawsect(surf1,surf2,sol,param,Func);
137   }
138   nbcomputedsection = 1;
139 #endif
140   // Mettre a jour la ligne.
141   line->Append(previousP);
142
143   if(doextremities){
144     TheExtremity ptf1 (previousP.PointOnS1(),
145                        sol(1),sol(2),tolesp);
146     TheExtremity ptf2 (previousP.PointOnS2(),
147                        sol(3),sol(4),tolesp);
148     if (!previousP.IsTangencyPoint()) {
149       ptf1.SetTangent(previousP.TangentOnS1());
150       ptf2.SetTangent(previousP.TangentOnS2());
151     }
152     
153     if (sens>0.) {      
154       line->SetStartPoints(ptf1, ptf2);      
155     }
156     else {
157       line->SetEndPoints(ptf1, ptf2);
158     }
159   }
160
161   InternalPerform(Func,FuncInv,Pmax);
162
163 #ifdef DEB
164 //  cout <<"Perform : "<<nbcomputedsection<<" sections calculees"<<endl;
165 //  cout <<line->NbPoints()<<" sections gardees"<<endl;
166 #endif
167
168   done = Standard_True;
169 }
170
171
172 Standard_Boolean Blend_Walking::PerformFirstSection
173 (Blend_Function&     Func,
174  const Standard_Real Pdep,   
175  math_Vector&        ParDep,
176  const Standard_Real Tolesp,
177  const Standard_Real TolGuide,
178  TopAbs_State&       Pos1,
179  TopAbs_State&       Pos2)
180 {
181   iscomplete = Standard_False;
182   comptra = Standard_False;
183   line = new TheLine ();
184   tolesp = Abs(Tolesp);
185   tolgui = Abs(TolGuide);
186
187   Pos1 = Pos2 = TopAbs_UNKNOWN;
188
189   Blend_Status State;
190
191   param = Pdep;
192   Func.Set(param);
193
194   math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
195   Func.GetTolerance(tolerance,tolesp);
196   Func.GetBounds(infbound,supbound);
197   math_FunctionSetRoot rsnld(Func,tolerance,30);
198   
199   rsnld.Perform(Func,ParDep,infbound,supbound);
200   
201   if (!rsnld.IsDone()) {
202     return Standard_False;
203   }
204   rsnld.Root(sol);
205   ParDep = sol;
206   Pos1 = domain1->Classify(gp_Pnt2d(sol(1),sol(2)),
207                            Min(tolerance(1),tolerance(2)),0);
208   Pos2 = domain2->Classify(gp_Pnt2d(sol(3),sol(4)),
209                            Min(tolerance(3),tolerance(4)),0);
210   if (Pos1 != TopAbs_IN || Pos2 != TopAbs_IN) {
211     return Standard_False;
212   }
213
214   State = TestArret(Func, Blend_OK, Standard_False);
215 #ifdef DEB
216   if (Blend_GettraceDRAWSECT()){
217     Drawsect(surf1,surf2,sol,param,Func);
218   }
219 #endif
220   return Standard_True;
221 }
222
223
224 Standard_Boolean Blend_Walking::PerformFirstSection
225    (Blend_Function& Func,
226     Blend_FuncInv& FuncInv,
227     const Standard_Real Pdep,   
228     const Standard_Real Pmax,   
229     const math_Vector& ParDep,
230     const Standard_Real Tolesp,
231     const Standard_Real TolGuide,
232     const Standard_Boolean RecOnS1,
233     const Standard_Boolean RecOnS2,
234     Standard_Real& Psol,   
235     math_Vector& ParSol)
236
237 {
238   iscomplete = Standard_False;
239   comptra = Standard_False;
240   line = new TheLine ();
241
242   Standard_Real w1,w2, extrapol;
243   Standard_Boolean recad1,recad2;
244
245   tolesp = Abs(Tolesp);
246   tolgui = Abs(TolGuide);
247   if (Pmax-Pdep >= 0.) {
248     sens = 1.;
249   }
250   else {
251     sens = -1.;
252   }
253   extrapol = Abs(Pmax-Pdep)/50; // 2%
254
255   Blend_Status State;
256
257   param = Pdep;
258   Func.Set(param);
259
260   math_Vector tolerance(1,4),infbound(1,4),supbound(1,4);
261   math_Vector solrst1(1,4),solrst2(1,4);
262   TheExtremity Ext1,Ext2;
263   Standard_Integer Index1 = 0, Index2 = 0, nbarc;
264   Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False;
265   TheVertex Vtx1,Vtx2;
266   gp_Pnt2d p2d;
267
268   Func.GetTolerance(tolerance,tolesp);
269   Func.GetBounds(infbound,supbound);
270   math_FunctionSetRoot rsnld(Func,tolerance,30);
271
272   rsnld.Perform(Func,ParDep,infbound,supbound);
273     
274   if (!rsnld.IsDone()) {
275     return Standard_False;
276   }
277   rsnld.Root(sol);
278
279   w1 = w2 = Pmax;
280
281   recad1 = RecOnS1 && Recadre(FuncInv,Standard_True,
282                               sol,solrst1,Index1,Isvtx1,Vtx1, extrapol);
283   if (recad1) {
284     w1 = solrst1(2);
285   }
286
287   recad2 = RecOnS2 && Recadre(FuncInv,Standard_False,
288                               sol,solrst2,Index2,Isvtx2,Vtx2, extrapol);
289   if (recad2) {
290     w2 = solrst2(2);
291   }
292
293   if (!recad1 && !recad2) {
294     return Standard_False;
295   }
296
297   if (recad1 && recad2) {
298     if (Abs(w1-w2) <= tolgui) {
299       //sol sur 1 et 2 a la fois
300       State = Blend_OnRst12;
301       param = w1;
302       ParSol(1) = solrst2(3);
303       ParSol(2) = solrst2(4);
304       ParSol(3) = solrst1(3);
305       ParSol(4) = solrst1(4);
306     }
307     else if (sens*(w2-w1) < 0.) { // on garde le plus grand
308       //sol sur 1
309       State = Blend_OnRst1;
310       param = w1;
311       
312       recdomain1->Init();
313       nbarc = 1;
314       while (nbarc < Index1) {
315         nbarc++;
316         recdomain1->Next();
317       }
318       p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
319       ParSol(1) = p2d.X();
320       ParSol(2) = p2d.Y();
321       ParSol(3) = solrst1(3);
322       ParSol(4) = solrst1(4);
323       
324     }
325     else {
326       //sol sur 2
327       State = Blend_OnRst2;
328       param = w2;
329       
330       recdomain2->Init();
331       nbarc = 1;
332       while (nbarc < Index2) {
333         nbarc++;
334         recdomain2->Next();
335       }
336       p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
337       ParSol(1) = solrst2(3);
338       ParSol(2) = solrst2(4);
339       ParSol(3) = p2d.X();
340       ParSol(4) = p2d.Y();
341     }
342   }
343   else if (recad1) {
344     // sol sur 1
345     State = Blend_OnRst1;
346     param = w1;
347     recdomain1->Init();
348     nbarc = 1;
349     while (nbarc < Index1) {
350       nbarc++;
351       recdomain1->Next();
352     }
353     p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
354     ParSol(1) = p2d.X();
355     ParSol(2) = p2d.Y();
356     ParSol(3) = solrst1(3);
357     ParSol(4) = solrst1(4);
358   }
359   else { //if (recad2) {
360     //sol sur 2
361     State = Blend_OnRst2;
362     param = w2;
363     
364     recdomain2->Init();
365     nbarc = 1;
366     while (nbarc < Index2) {
367       nbarc++;
368       recdomain2->Next();
369     }
370     p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
371     ParSol(1) = solrst2(3);
372     ParSol(2) = solrst2(4);
373     ParSol(3) = p2d.X();
374     ParSol(4) = p2d.Y();
375   }
376
377   Psol = param;
378   sol = ParSol;
379   Func.Set(param);
380   State = TestArret(Func, State, Standard_False);
381   switch (State) {
382   case Blend_OnRst1  :
383     {
384 #ifdef DEB
385       if (Blend_GettraceDRAWSECT()){
386         Drawsect(surf1,surf2,sol,param,Func);
387       }
388 #endif
389       MakeExtremity(Ext1,Standard_True,Index1,
390                     solrst1(1),Isvtx1,Vtx1);
391       Ext2.SetValue(previousP.PointOnS2(),
392                     sol(3),sol(4),tolesp);
393     }
394     break;
395     
396   case Blend_OnRst2  :
397     {
398 #ifdef DEB
399       if (Blend_GettraceDRAWSECT()){
400         Drawsect(surf1,surf2,sol,param,Func);
401       }
402 #endif
403       Ext1.SetValue(previousP.PointOnS1(),
404                     sol(1),sol(2),tolesp);
405       MakeExtremity(Ext2,Standard_False,Index2,
406                     solrst2(1),Isvtx2,Vtx2);
407     }
408     break;
409     
410   case Blend_OnRst12 :
411     {
412 #ifdef DEB
413       if (Blend_GettraceDRAWSECT()){
414         Drawsect(surf1,surf2,sol,param,Func);
415       }
416 #endif
417       MakeExtremity(Ext1,Standard_True,Index1,
418                     solrst1(1),Isvtx1,Vtx1);
419       MakeExtremity(Ext2,Standard_False,Index2,
420                     solrst2(1),Isvtx2,Vtx2);
421     }
422     break;
423   default:
424     {
425       Standard_Failure::Raise("Blend_Walking::PerformFirstSection : echec");
426     }
427   }
428   if (sens < 0.) {
429     line->SetEndPoints(Ext1,Ext2);
430   }
431   else {
432     line->SetStartPoints(Ext1,Ext2);
433   }
434   return Standard_True;
435 }
436
437
438
439 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
440                                         Blend_FuncInv& FuncInv,
441                                         const Standard_Real P)
442 {
443   if (!done) {StdFail_NotDone::Raise();}
444   const Blend_Point& firstBP =  line->Point(1);
445   const Blend_Point& lastBP =  line->Point(line->NbPoints());
446
447   if (P < firstBP.Parameter()){
448     sens = -1.;
449     previousP = firstBP;
450   }
451   else if(P > lastBP.Parameter()){
452     sens = 1.;
453     previousP = lastBP;
454   }
455
456   param = previousP.Parameter();
457   previousP.ParametersOnS1(sol(1),sol(2));
458   previousP.ParametersOnS2(sol(3),sol(4));
459
460   InternalPerform(Func,FuncInv,P);
461   return Standard_True;
462 }
463
464
465 Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
466                                         Blend_FuncInv& FuncInv,
467                                         const Standard_Real P,
468                                         const Standard_Boolean OnS1)
469 {
470   if (!done) {StdFail_NotDone::Raise();}
471   TheExtremity Ext1,Ext2;
472   if (sens < 0.) {
473     Ext1 = line->StartPointOnFirst();
474     Ext2 = line->StartPointOnSecond();
475     if (OnS1 && Ext1.NbPointOnRst() == 0 ||
476         !OnS1 && Ext2.NbPointOnRst() == 0) {
477       return Standard_False;
478     }
479     previousP = line->Point(1);
480
481
482   }
483   else {
484     Ext1 = line->EndPointOnFirst();
485     Ext2 = line->EndPointOnSecond();
486     if (OnS1 && Ext1.NbPointOnRst() == 0 ||
487         !OnS1 && Ext2.NbPointOnRst() == 0) {
488       return Standard_False;
489     }
490     previousP = line->Point(line->NbPoints());
491   }
492
493   Standard_Integer length = line->NbPoints();
494   param = previousP.Parameter();
495   previousP.ParametersOnS1(sol(1),sol(2));
496   previousP.ParametersOnS2(sol(3),sol(4));
497   
498   if(OnS1) clasonS1 = Standard_False;
499   else clasonS2 = Standard_False;
500
501   InternalPerform(Func,FuncInv,P);
502
503   clasonS1 = Standard_True;
504   clasonS2 = Standard_True;
505
506   Standard_Integer newlength = line->NbPoints();
507   if (sens <0.) {
508     if (OnS1 && line->StartPointOnSecond().NbPointOnRst() == 0 ||
509         !OnS1 && line->StartPointOnFirst().NbPointOnRst() == 0) {
510       line->Remove(1,newlength-length);
511       line->SetStartPoints(Ext1,Ext2);
512       return Standard_False;
513     }
514   }
515   else {
516     if (OnS1 && line->EndPointOnSecond().NbPointOnRst() == 0 ||
517         !OnS1 && line->EndPointOnFirst().NbPointOnRst() == 0) {
518       line->Remove(length,newlength);
519       line->SetEndPoints(Ext1,Ext2);
520       return Standard_False;
521     }
522   }
523   return Standard_True;
524 }
525
526
527 Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
528                                          Blend_FuncInv& FuncInv,
529                                          const Standard_Real Pmin)
530 {
531   if (!done) {StdFail_NotDone::Raise();}
532   if (iscomplete) {return Standard_True;}
533
534   if (sens >0.) {
535     previousP = line->Point(1);
536   }
537   else {
538     previousP = line->Point(line->NbPoints());
539   }
540
541   sens = -sens;
542
543   param = previousP.Parameter();
544   previousP.ParametersOnS1(sol(1),sol(2));
545   previousP.ParametersOnS2(sol(3),sol(4));
546
547   InternalPerform(Func,FuncInv,Pmin);
548
549 #ifdef DEB
550 //  cout <<"Complete : "<<nbcomputedsection<<" sections calculees"<<endl;
551 //  cout <<line->NbPoints()<<" sections gardees"<<endl;
552 #endif
553
554   iscomplete = Standard_True;
555   return Standard_True;
556 }
557
558 void Blend_Walking::ClassificationOnS1(const Standard_Boolean C)
559 {
560   clasonS1 = C;
561 }
562
563 void Blend_Walking::ClassificationOnS2(const Standard_Boolean C)
564 {
565   clasonS2 = C;
566 }
567
568 void Blend_Walking::Check2d(const Standard_Boolean C)
569 {
570   check2d = C;
571 }
572
573 void Blend_Walking::Check(const Standard_Boolean C)
574 {
575   check = C;
576 }
577