0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BRepBlend / BRepBlend_SurfRstLineBuilder.cxx
1 // Created on: 1997-01-24
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_HVertex.hxx>
21 #include <Adaptor3d_TopolTool.hxx>
22 #include <Blend_FuncInv.hxx>
23 #include <Blend_Point.hxx>
24 #include <Blend_SurfCurvFuncInv.hxx>
25 #include <Blend_SurfPointFuncInv.hxx>
26 #include <Blend_SurfRstFunction.hxx>
27 #include <BRepBlend_BlendTool.hxx>
28 #include <BRepBlend_Extremity.hxx>
29 #include <BRepBlend_Line.hxx>
30 #include <BRepBlend_SurfRstLineBuilder.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Vec.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <IntSurf.hxx>
36 #include <IntSurf_Transition.hxx>
37 #include <math_FunctionSetRoot.hxx>
38 #include <TopAbs.hxx>
39
40 #include <stdio.h>
41 #ifdef OCCT_DEBUG
42 #include <TColStd_Array1OfInteger.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44 #include <TColgp_Array1OfPnt2d.hxx>
45 #include <TColgp_Array1OfVec.hxx>
46 #include <TColgp_Array1OfVec2d.hxx>
47 #include <TColgp_Array1OfPnt.hxx>
48 #include <Geom_BSplineCurve.hxx>
49 #ifdef DRAW
50 #include <DrawTrSurf.hxx>
51 #endif
52 static Standard_Integer IndexOfSection = 0;
53 extern Standard_Boolean Blend_GettraceDRAWSECT(); 
54 #ifdef OCCT_DEBUG_BBPP_N_TRDERIV
55 // for debug : visualisation of the section
56 static Standard_Boolean BBPP(const Standard_Real param,
57                              Blend_SurfRstFunction& Func,
58                              const math_Vector& sol,
59                              const Standard_Real tol,
60                              Blend_Point& BP)
61 {
62   if(!Func.IsSolution(sol,tol)) return 0;
63   gp_Pnt pnts = Func.PointOnS();
64   gp_Pnt pntrst = Func.PointOnRst();
65   gp_Pnt2d p2ds = Func.Pnt2dOnS();
66   gp_Pnt2d p2drst = Func.Pnt2dOnRst();
67   Standard_Real w = Func.ParameterOnRst();
68   BP = Blend_Point(pnts,pntrst,param,
69                    p2ds.X(),p2ds.Y(),
70                    p2drst.X(),p2drst.Y(),w);
71   return 1;
72 }
73 static void tracederiv(Blend_SurfRstFunction& Func,
74                        const Blend_Point& BP1,
75                        const Blend_Point& BP2)
76 {
77   Standard_Integer hp,hk,hd,hp2d,i;
78   Func.GetShape(hp,hk,hd,hp2d);
79   TColgp_Array1OfPnt TP1(1,hp);
80   TColgp_Array1OfVec TDP1(1,hp);
81   TColgp_Array1OfPnt2d TP2d1(1,hp2d);
82   TColgp_Array1OfVec2d TDP2d1(1,hp2d);
83   TColStd_Array1OfReal TW1(1,hp);
84   TColStd_Array1OfReal TDW1(1,hp);
85   Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
86
87   TColgp_Array1OfPnt TP2(1,hp);
88   TColgp_Array1OfVec TDP2(1,hp);
89   TColgp_Array1OfPnt2d TP2d2(1,hp2d);
90   TColgp_Array1OfVec2d TDP2d2(1,hp2d);
91   TColStd_Array1OfReal TW2(1,hp);
92   TColStd_Array1OfReal TDW2(1,hp);
93   Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
94
95   Standard_Real param1 = BP1.Parameter();
96   Standard_Real param2 = BP2.Parameter();
97   Standard_Real scal = 1./(param1-param2);
98
99   std::cout<<std::endl;
100   std::cout<<"control derivatives at point : "<<param1<<std::endl;
101
102   for(i = 1; i <= hp; i++){
103     std::cout<<std::endl;
104     std::cout<<"point : "<<i<<std::endl;
105     std::cout<<"dx calculated : "<<TDP1(i).X()<<std::endl;
106     std::cout<<"dx estimated  : "<<scal*(TP1(i).X()-TP2(i).X())<<std::endl;
107     std::cout<<"dy calculated : "<<TDP1(i).Y()<<std::endl;
108     std::cout<<"dy estimated  : "<<scal*(TP1(i).Y()-TP2(i).Y())<<std::endl;
109     std::cout<<"dz calculated : "<<TDP1(i).Z()<<std::endl;
110     std::cout<<"dz estimated  : "<<scal*(TP1(i).Z()-TP2(i).Z())<<std::endl;
111     std::cout<<"dw calculated : "<<TDW1(i)<<std::endl;
112     std::cout<<"dw estimated  : "<<scal*(TW1(i)-TW2(i))<<std::endl;
113   }
114   for(i = 1; i <= hp2d; i++){
115     std::cout<<std::endl;
116     std::cout<<"point 2d : "<<i<<std::endl;
117     std::cout<<"dx calculated : "<<TDP2d1(i).X()<<std::endl;
118     std::cout<<"dx estimated  : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<std::endl;
119     std::cout<<"dy calculated : "<<TDP2d1(i).Y()<<std::endl;
120     std::cout<<"dy estimated  : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<std::endl;
121   }
122 }
123 #endif
124 static void Drawsect(const Standard_Real param,
125                      Blend_SurfRstFunction& Func)
126 {
127   gp_Pnt pnts = Func.PointOnS();
128   gp_Pnt pntrst = Func.PointOnRst();
129   gp_Pnt2d p2ds = Func.Pnt2dOnS();
130   gp_Pnt2d p2drst = Func.Pnt2dOnRst();
131   Standard_Real w = Func.ParameterOnRst();
132   Blend_Point BP(pnts,pntrst,param,
133                  p2ds.X(),p2ds.Y(),
134                  p2drst.X(),p2drst.Y(),w);
135   Standard_Integer hp,hk,hd,hp2d;
136   Func.GetShape(hp,hk,hd,hp2d);
137   TColStd_Array1OfReal TK(1,hk);
138   Func.Knots(TK);
139   TColStd_Array1OfInteger TMul(1,hk);
140   Func.Mults(TMul);
141   TColgp_Array1OfPnt TP(1,hp);
142   TColgp_Array1OfPnt2d TP2d(1,hp2d);
143   TColStd_Array1OfReal TW(1,hp);
144   Func.Section(BP,TP,TP2d,TW);
145   Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
146     (TP,TW,TK,TMul,hd);
147   IndexOfSection++;
148 #ifdef DRAW
149   char tname[100];
150   Standard_CString name = tname ;
151   sprintf(name,"%s_%d","Section",IndexOfSection);
152   DrawTrSurf::Set(name,sect);
153 #endif
154 }
155 #endif
156
157 //=======================================================================
158 //function :  ArcToRecadre
159 //purpose  : Find a suitable arc
160 //           PrevIndex is used to reject an already tested arc
161 //=======================================================================
162
163 Standard_Integer BRepBlend_SurfRstLineBuilder::
164    ArcToRecadre(const math_Vector& theSol,
165                 const Standard_Integer PrevIndex, 
166                 gp_Pnt2d& lastpt2d,
167                 gp_Pnt2d& pt2d,
168                 Standard_Real& ponarc) 
169 {
170   Standard_Integer IndexSol = 0,  nbarc = 0;
171   Standard_Boolean ok = Standard_False;
172   Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
173   Standard_Real distmin = RealLast();
174   Standard_Real uprev = 0.,vprev = 0., prm =  0., dist = 0.;
175
176   if(byinter) previousP.ParametersOnS(uprev,vprev);
177   pt2d.SetCoord(theSol(1),theSol(2));
178   lastpt2d.SetCoord(uprev,vprev);
179   domain1->Init();
180
181   while (domain1->More()) {
182     nbarc++; ok = 0;
183     if(byinter) { 
184       ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
185                                                  surf1,
186                                                  domain1->Value(),prm,dist); 
187     }
188     if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
189                                               domain1->Value(),prm,dist);
190
191     if (ok && (nbarc != PrevIndex) ) {
192       if (dist<distmin || okinter) {
193         distmin = dist;
194         ponarc = prm;
195         IndexSol = nbarc;
196         if(okinter && (PrevIndex==0) ) break;
197       }
198     }
199     domain1->Next();
200   }
201   return IndexSol;
202 }
203
204 //=======================================================================
205 //function : BRepBlend_SurfRstLineBuilder
206 //purpose  : 
207 //=======================================================================
208
209 BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
210 (const Handle(Adaptor3d_HSurface)&  Surf1,
211  const Handle(Adaptor3d_TopolTool)& Domain1,
212  const Handle(Adaptor3d_HSurface)&  Surf2,
213  const Handle(Adaptor2d_HCurve2d)&  Rst,
214  const Handle(Adaptor3d_TopolTool)& Domain2):
215  done(Standard_False), sol(1, 3), surf1(Surf1),
216  domain1(Domain1), surf2(Surf2), rst(Rst),
217  domain2(Domain2), tolesp(0.0), tolgui(0.0),
218  pasmax(0.0), fleche(0.0), param(0.0),
219  rebrou(Standard_False), iscomplete(Standard_False),
220  comptra(Standard_False), sens(0.0),
221  decrochdeb(Standard_False), decrochfin(Standard_False)
222 {
223 }
224
225 //=======================================================================
226 //function : Perform
227 //purpose  : 
228 //=======================================================================
229
230 void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
231                                            Blend_FuncInv&          Finv,
232                                            Blend_SurfPointFuncInv& FinvP,
233                                            Blend_SurfCurvFuncInv&  FinvC,
234                                            const Standard_Real     Pdep,
235                                            const Standard_Real     Pmax,
236                                            const Standard_Real     MaxStep,
237                                            const Standard_Real     TolGuide,
238                                            const math_Vector&      ParDep,
239                                            const Standard_Real     Tolesp,
240                                            const Standard_Real     Fleche,
241                                            const Standard_Boolean  Appro) 
242 {
243   done = Standard_False;
244   iscomplete = Standard_False;
245   comptra = Standard_False;
246   line = new BRepBlend_Line();
247   tolesp = Abs(Tolesp);
248   tolgui = Abs(TolGuide);
249   fleche = Abs(Fleche);
250   rebrou = Standard_False;
251   pasmax = Abs(MaxStep);
252   
253   if (Pmax-Pdep >= 0.) {
254     sens = 1.;
255   }
256   else {
257     sens = -1.;
258   }
259   
260   Blend_Status State;
261   
262   param = Pdep;
263   Func.Set(param);
264   
265   if (Appro) {
266     TopAbs_State siturst,situs;
267     Standard_Boolean decroch;
268     math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
269     Func.GetTolerance(tolerance,tolesp);
270     Func.GetBounds(infbound,supbound);
271     math_FunctionSetRoot rsnld(Func,tolerance,30);
272     
273     rsnld.Perform(Func,ParDep,infbound,supbound);
274     
275     if (!rsnld.IsDone()) {
276       return;
277     }
278     rsnld.Root(sol);
279     if (!CheckInside(Func,siturst,situs,decroch)) {
280       return;
281     }
282   }
283   else {
284     sol = ParDep;
285   }
286
287   State = TestArret(Func,Standard_False,Blend_OK);
288   if (State!=Blend_OK) {
289     return;
290   }
291 #ifdef OCCT_DEBUG
292   if (Blend_GettraceDRAWSECT()){
293     Drawsect(param,Func);
294   }
295 #endif
296   // Update the line.
297   line->Append(previousP);
298   Standard_Real U,V;
299   previousP.ParametersOnS(U,V);
300 //  W = previousP.ParameterOnC();
301   
302   BRepBlend_Extremity ptf1(previousP.PointOnS(),
303                            U,V,previousP.Parameter(),tolesp);
304   BRepBlend_Extremity ptf2(previousP.PointOnC(),
305                            U,V,previousP.Parameter(),tolesp);
306   if (!previousP.IsTangencyPoint()) {
307     ptf1.SetTangent(previousP.TangentOnS());
308     ptf2.SetTangent(previousP.TangentOnC());
309   }
310   if (sens>0.) {    
311     line->SetStartPoints(ptf1, ptf2);    
312   }
313   else {
314     line->SetEndPoints(ptf1, ptf2);
315     
316   }
317   InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
318   done = Standard_True;
319 }
320
321 //=======================================================================
322 //function : PerformFirstSection
323 //purpose  : 
324 //=======================================================================
325
326 Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
327 (Blend_SurfRstFunction&  Func,
328  Blend_FuncInv&          Finv,
329  Blend_SurfPointFuncInv& FinvP,
330  Blend_SurfCurvFuncInv&  FinvC,
331  const Standard_Real     Pdep,
332  const Standard_Real     Pmax,
333  const math_Vector&      ParDep,
334  const Standard_Real     Tolesp,
335  const Standard_Real     TolGuide,
336  const Standard_Boolean  RecRst,
337  const Standard_Boolean  RecP,
338  const Standard_Boolean  RecS,
339  Standard_Real&          Psol,   
340  math_Vector&            ParSol)
341 {
342   done = Standard_False;
343   iscomplete = Standard_False;
344   comptra = Standard_False;
345   line = new BRepBlend_Line();
346   tolesp = Abs(Tolesp);
347   tolgui = Abs(TolGuide);
348   rebrou = Standard_False;
349   
350   if (Pmax-Pdep >= 0.) {
351     sens = 1.;
352   }
353   else {
354     sens = -1.;
355   }
356   Blend_Status State = Blend_OnRst12;
357   Standard_Real trst = 0.;
358   Standard_Boolean recadp,recadrst,recads;
359   Standard_Real wp,wrst,ws;
360   Standard_Real U = 0.,V = 0.;
361   math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
362   math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
363   Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
364   Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
365   Handle(Adaptor2d_HCurve2d) Arc;
366   wp = wrst = ws = Pmax;
367   param = Pdep;
368   Func.Set(param);
369   Func.GetTolerance(tolerance,tolesp);
370   Func.GetBounds(infbound,supbound);
371
372   math_FunctionSetRoot rsnld(Func,tolerance,30);
373   rsnld.Perform(Func,ParDep,infbound,supbound);
374   if (!rsnld.IsDone()) return Standard_False;
375   rsnld.Root(sol);
376
377   recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
378   if (recads) {
379     ws = solinvs(1);
380   }
381   recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
382   if (recadp) {
383     wp = solinvp(1);
384   }
385   recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
386   if (recadrst) {
387     wrst = solinvrst(2);
388   }
389   if (!recads && !recadp && !recadrst) return Standard_False;
390   if (recadp && recadrst) {
391     if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
392       wrst = wp;
393       U = solinvp(2);
394       V = solinvp(3);
395       trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
396       IsVtxrst = IsVtxp;
397       Vtxrst = Vtxp;
398     }
399     else{                        
400       U = solinvrst(3);
401       V = solinvrst(4);
402       trst = solinvrst(1);
403     }
404   }
405   else if(recadp){
406     wrst = wp;
407     U = solinvp(2);
408     V = solinvp(3);
409     trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
410     IsVtxrst = IsVtxp;
411     Vtxrst = Vtxp;
412     recadrst = Standard_True;
413   }
414   else if(recadrst){
415     U = solinvrst(3);
416     V = solinvrst(4);
417     trst = solinvrst(1);
418   }
419   if(recads && recadrst){
420     if(Abs(ws - wrst) < tolgui){
421       State = Blend_OnRst12;
422       param = 0.5*(ws+wrst);
423       sol(1) = U;
424       sol(2) = V;
425       sol(3) = solinvs(2);
426     }
427     else if(sens*(ws-wrst)<0){
428       // ground on surf
429       State = Blend_OnRst1;
430       param = ws;
431       Arc->Value(solinvs(3)).Coord(U,V);
432       sol(1) = U;
433       sol(2) = V;
434       sol(3) = solinvs(2);
435     }
436     else{
437       // ground on rst
438       State = Blend_OnRst2;
439       param = wrst;
440       sol(1) = U;
441       sol(2) = V;
442       sol(3) = trst;
443     }
444     Func.Set(param);
445   }
446   else if(recads){
447     // ground on surf
448     State = Blend_OnRst1;
449     param = ws;
450     Arc->Value(solinvs(3)).Coord(U,V);
451     sol(1) = U;
452     sol(2) = V;
453     sol(3) = solinvs(2);
454     Func.Set(param);
455   }
456   else if(recadrst){
457     // ground on rst
458     State = Blend_OnRst2;
459     param = wrst;
460     sol(1) = U;
461     sol(2) = V;
462     sol(3) = trst;
463     Func.Set(param);
464   }
465   State = TestArret(Func,Standard_False,State);
466   Psol = param;
467   ParSol = sol;
468   return Standard_True;
469 }  
470
471 //=======================================================================
472 //function : Complete
473 //purpose  : 
474 //=======================================================================
475
476 Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction&  Func,
477                                                         Blend_FuncInv&          Finv,
478                                                         Blend_SurfPointFuncInv& FinvP,
479                                                         Blend_SurfCurvFuncInv&  FinvC,
480                                                         const Standard_Real     Pmin) 
481 {
482   if (!done) {throw StdFail_NotDone();}
483   if (iscomplete) {return Standard_True;}
484   if (sens >0.) {
485     previousP = line->Point(1);
486   }
487   else {
488     previousP = line->Point(line->NbPoints());
489   }
490   sens = -sens;
491   param = previousP.Parameter();
492   previousP.ParametersOnS(sol(1),sol(2));
493   sol(3) = previousP.ParameterOnC();
494
495   InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
496   iscomplete = Standard_True;
497   return Standard_True;
498 }
499
500 //=======================================================================
501 //function : InternalPerform
502 //purpose  : 
503 //=======================================================================
504
505 void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
506                                                    Blend_FuncInv&          Finv,
507                                                    Blend_SurfPointFuncInv& FinvP,
508                                                    Blend_SurfCurvFuncInv&  FinvC,
509                                                    const Standard_Real     Bound) 
510 {
511   Standard_Real stepw = pasmax;
512   Standard_Integer nbp = line->NbPoints();
513   if(nbp >= 2){ //The last step is reproduced if it is not too small.
514     if(sens < 0.){
515       stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
516     }
517     else{
518       stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
519     }
520     stepw = Max(stepw,100.*tolgui);
521   }
522   Standard_Real parprec = param;
523   if (sens*(parprec - Bound) >= -tolgui) {
524     return;
525   }
526   Blend_Status State = Blend_OnRst12;
527   TopAbs_State situonc = TopAbs_UNKNOWN, situons = TopAbs_UNKNOWN;
528   Standard_Boolean decroch = Standard_False;
529   Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
530   Standard_Real wp,wrst,ws;
531   Standard_Real U = 0.,V = 0.;
532   Standard_Real trst = 0.;
533   math_Vector infbound(1,3),supbound(1,3);
534   math_Vector parinit(1,3),tolerance(1,3);
535   math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
536   Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
537   Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
538   BRepBlend_Extremity Extrst,Exts;
539   Handle(Adaptor2d_HCurve2d) Arc;
540
541   //IntSurf_Transition Tline,Tarc;
542
543   Func.GetTolerance(tolerance,tolesp);
544   Func.GetBounds(infbound,supbound);
545
546   math_FunctionSetRoot rsnld(Func,tolerance,30);
547   parinit = sol;
548
549   Arrive = Standard_False;
550   param = parprec + sens*stepw;
551   if(sens *(param - Bound) > 0.) {
552     stepw = sens*(Bound - parprec)*0.5;
553     param = parprec + sens*stepw;
554   }
555
556   while (!Arrive) {
557     Standard_Boolean bonpoint = 1;
558 #ifdef OCCT_DEBUG_BBPP_N_TRDERIV
559     //debdebdebdebdebdeb
560     Func.Set(param);
561     rsnld.Perform(Func,parinit,infbound,supbound);
562     if (rsnld.IsDone()) {
563       rsnld.Root(sol);
564       Blend_Point bp1;
565       if(BBPP(param,Func,sol,tolesp,bp1)){
566         Standard_Real dw = 1.e-10;
567         Func.Set(param+dw);
568         rsnld.Perform(Func,parinit,infbound,supbound);
569         if (rsnld.IsDone()) {
570           rsnld.Root(sol);
571           Blend_Point bp2;
572           if(BBPP(param+dw,Func,sol,tolesp,bp2)){
573             tracederiv(Func,bp1,bp2);
574           }
575         }
576       }
577     }
578     //debdebdebdebdebdeb
579 #endif
580     Func.Set(param);
581     rsnld.Perform(Func,parinit,infbound,supbound);
582     
583     if (rsnld.IsDone()) {
584       rsnld.Root(sol);
585       if(!CheckInside(Func,situonc,situons,decroch) && line->NbPoints() == 1){
586         State = Blend_StepTooLarge;
587         bonpoint = 0;
588       }
589     }
590     else {
591       State = Blend_StepTooLarge;
592       bonpoint = 0;
593     }
594     if(bonpoint){
595       wp = wrst = ws = Bound;
596       recadp = recadrst = recads = Standard_False;
597       echecrecad = Standard_False;
598       if (situons == TopAbs_OUT || situons == TopAbs_ON) {
599         // pb inverse rst/rst
600         recads = Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
601         if (recads) {
602           ws = solinvs(1);
603           // It is necessary to reevaluate the deviation (BUC60360)
604           gp_Vec t, n;
605           Func.Set(ws);
606           Arc->Value(solinvs(3)).Coord(U,V);
607           sol(1) = U;
608           sol(2) = V;
609           sol(3) = solinvs(2);
610           decroch = Func.Decroch(sol, t, n); 
611         }
612         else {
613           echecrecad = Standard_True;
614         }
615       }
616       if (situonc == TopAbs_OUT || situonc == TopAbs_ON) {
617         // pb inverse point/surf
618         recadp = Recadre(FinvP,solinvp,IsVtxp,Vtxp);
619         if (recadp) {
620           wp = solinvp(1);
621         }
622         else {
623           echecrecad = Standard_True;
624         }
625       }
626       if (decroch) {
627         // pb inverse rst/surf
628         recadrst = Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
629         if (recadrst) {
630           wrst = solinvrst(2);
631         }
632         else {
633           echecrecad = Standard_True;
634         }
635       }
636       decroch = 0;
637       if(recadp || recads || recadrst) echecrecad = Standard_False; 
638       if (!echecrecad) {
639         if (recadp && recadrst) {
640           if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
641             wrst = wp;
642             U = solinvp(2);
643             V = solinvp(3);
644             trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
645             IsVtxrst = IsVtxp;
646             Vtxrst = Vtxp;
647           }
648           else{                        
649             decroch = 1;
650             U = solinvrst(3);
651             V = solinvrst(4);
652             trst = solinvrst(1);
653           }
654         }
655         else if(recadp){
656           wrst = wp;
657           U = solinvp(2);
658           V = solinvp(3);
659           trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
660           IsVtxrst = IsVtxp;
661           Vtxrst = Vtxp;
662           recadrst = Standard_True;
663         }
664         else if(recadrst){
665           decroch = 1;
666           U = solinvrst(3);
667           V = solinvrst(4);
668           trst = solinvrst(1);
669         }
670         if(recads && recadrst){
671           if(Abs(ws - wrst) < tolgui){
672             State = Blend_OnRst12;
673             param = 0.5*(ws+wrst);
674             sol(1) = U;
675             sol(2) = V;
676             sol(3) = solinvs(3);
677           }
678           else if(sens*(ws-wrst)<0){
679             // ground on surf
680             decroch = 0;
681             State = Blend_OnRst1;
682             param = ws;
683             Arc->Value(solinvs(3)).Coord(U,V);
684             sol(1) = U;
685             sol(2) = V;
686             sol(3) = solinvs(2);
687           }
688           else{
689             // ground on rst
690             State = Blend_OnRst2;
691             param = wrst;
692             sol(1) = U;
693             sol(2) = V;
694             sol(3) = trst;
695           }
696           Func.Set(param);
697         }
698         else if(recads){
699           // ground on surf
700           State = Blend_OnRst1;
701           param = ws;
702           Arc->Value(solinvs(3)).Coord(U,V);
703           sol(1) = U;
704           sol(2) = V;
705           sol(3) = solinvs(2);
706           Func.Set(param);
707         }
708         else if(recadrst){
709           // ground on rst
710           State = Blend_OnRst2;
711           param = wrst;
712           sol(1) = U;
713           sol(2) = V;
714           sol(3) = trst;
715           Func.Set(param);
716         }
717         else {
718           State = Blend_OK;
719         }
720         State = TestArret(Func,Standard_True,State);
721       }
722       else{
723         // Failed reframing. Leave with PointsConfondus
724 #ifdef OCCT_DEBUG
725         std::cout<<"SurfRstLineBuilder : failed reframing"<<std::endl;
726 #endif
727         State = Blend_SamePoints;
728       }
729     }
730     
731     switch (State) {
732     case Blend_OK :
733       {
734 #ifdef OCCT_DEBUG
735         if (Blend_GettraceDRAWSECT()){
736           Drawsect(param,Func);
737         }
738 #endif
739         // Update the line.
740         if (sens>0.) {
741           line->Append(previousP);
742         }
743         else {
744           line->Prepend(previousP);
745         }
746         parinit = sol;
747         parprec = param;
748         
749         if (param == Bound) {
750           Arrive = Standard_True;
751           Exts.SetValue(previousP.PointOnS(),
752                         sol(1),sol(2),
753                         previousP.Parameter(),tolesp);
754           MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
755           // Indicate end on Bound.
756         }
757         else {
758           param = param + sens*stepw;
759           if (sens*(param - Bound) > - tolgui) {
760             param = Bound;
761           }
762         }
763       }
764       break;
765       
766     case Blend_StepTooLarge :
767       {
768         stepw = stepw/2.;
769         if (Abs(stepw) < tolgui) {
770           previousP.ParametersOnS(U,V);
771           Exts.SetValue(previousP.PointOnS(),U,V,
772                         previousP.Parameter(),tolesp);
773           Extrst.SetValue(previousP.PointOnC(),
774                           previousP.ParameterOnC(),
775                           previousP.Parameter(),tolesp);
776           Arrive = Standard_True;
777           if (line->NbPoints()>=2) {
778             // Indicate that one stops during the processing
779 #ifdef OCCT_DEBUG
780             std::cout<<"SurfRstLineBuilder : No advancement in the processing"<<std::endl;
781 #endif
782           }
783         }
784         else {
785           param = parprec + sens*stepw;  // no risk to exceed Bound.
786         }
787       }
788       break;
789       
790     case Blend_StepTooSmall :
791       {
792 #ifdef OCCT_DEBUG
793         if (Blend_GettraceDRAWSECT()){
794           Drawsect(param,Func);
795         }
796 #endif
797         // Update the line.
798         if (sens>0.) {
799           line->Append(previousP);
800         }
801         else {
802           line->Prepend(previousP);
803         }
804         parinit = sol;
805         parprec = param;
806         
807         stepw = Min(1.5*stepw,pasmax);
808         if (param == Bound) {
809           Arrive = Standard_True;
810           Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
811                         previousP.Parameter(),tolesp);
812           MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
813           // Indicate end on Bound.
814         }
815         else {
816           param = param + sens*stepw;
817           if (sens*(param - Bound) > - tolgui) {
818             param = Bound;
819           }
820         }
821       }
822       break;
823       
824     case Blend_OnRst1  :
825       {
826 #ifdef OCCT_DEBUG
827         if (Blend_GettraceDRAWSECT()){
828           Drawsect(param,Func);
829         }
830 #endif
831         if (sens>0.) {
832           line->Append(previousP);
833         }
834         else {
835           line->Prepend(previousP);
836         }
837         MakeExtremity(Exts,Standard_True,Arc,solinvs(3),IsVtxs,Vtxs);
838         MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
839         Arrive = Standard_True;
840       }
841       break;
842       
843     case Blend_OnRst2  :
844       {
845 #ifdef OCCT_DEBUG
846         if (Blend_GettraceDRAWSECT()){
847           Drawsect(param,Func);
848         }
849 #endif
850         if (sens>0.) {
851           line->Append(previousP);
852         }
853         else {
854           line->Prepend(previousP);
855         }
856         Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
857                       previousP.Parameter(),tolesp);
858         MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
859         Arrive = Standard_True;
860       }
861       break;
862       
863     case Blend_OnRst12  :
864       {
865 #ifdef OCCT_DEBUG
866         if (Blend_GettraceDRAWSECT()){
867           Drawsect(param,Func);
868         }
869 #endif
870         if (sens>0.) {
871           line->Append(previousP);
872         }
873         else {
874           line->Prepend(previousP);
875         }
876         MakeExtremity(Exts,Standard_True,Arc,solinvs(1),IsVtxs,Vtxs);
877         MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
878         Arrive = Standard_True;
879       }
880       break;
881       
882     case Blend_SamePoints :
883       {
884         // Stop
885 #ifdef OCCT_DEBUG
886         std::cout << "SurfRstLineBuilder Points mixed in the processing" << std::endl;
887 #endif
888         previousP.ParametersOnS(U,V);
889         Exts.SetValue(previousP.PointOnS(),U,V,
890                       previousP.Parameter(),tolesp);
891         Extrst.SetValue(previousP.PointOnC(),
892                         previousP.ParameterOnC(),
893                         previousP.Parameter(),tolesp);
894         Arrive = Standard_True;
895       }
896       break;
897     default:
898       break;
899     }
900     if (Arrive) {
901       if (sens > 0.) {
902         line->SetEndPoints(Exts,Extrst);
903         decrochfin = decroch;
904       }
905       else {
906         line->SetStartPoints(Exts,Extrst);
907         decrochdeb = decroch;
908       }
909     }
910   }
911 }
912
913 //=======================================================================
914 //function : Recadre
915 //purpose  : Reframe section Surface / Restriction
916 //=======================================================================
917
918 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&    FinvC,
919                                                        math_Vector&              Solinv,
920                                                        Handle(Adaptor2d_HCurve2d)& Arc,
921                                                        Standard_Boolean&         IsVtx,
922                                                        Handle(Adaptor3d_HVertex)&  Vtx) 
923 {
924   Standard_Boolean recadre = Standard_False;
925
926   gp_Pnt2d pt2d, lastpt2d;
927   Standard_Integer IndexSol, nbarc;
928   Standard_Real pmin;
929
930   IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
931  
932   IsVtx = Standard_False;
933   if (IndexSol == 0) {
934     return Standard_False;
935   }
936
937   domain1->Init();
938   nbarc = 1;
939   while (nbarc < IndexSol) {
940     nbarc++;
941     domain1->Next();
942   }
943   Arc = domain1->Value();
944
945   FinvC.Set(Arc);
946   
947   math_Vector toler(1,3),infb(1,3),supb(1,3);
948   FinvC.GetTolerance(toler,tolesp);
949   FinvC.GetBounds(infb,supb);
950   Solinv(1) = param;
951   Solinv(2) = sol(3);
952   Solinv(3) = pmin;
953   
954   math_FunctionSetRoot rsnld(FinvC,toler,30);
955   rsnld.Perform(FinvC,Solinv,infb,supb);
956
957   if (!rsnld.IsDone()) {
958 #ifdef OCCT_DEBUG
959     std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
960 #endif
961   }
962   else {
963       // It is necessary to check the value of the function
964     rsnld.Root(Solinv);
965     recadre = FinvC.IsSolution(Solinv,tolesp);
966   }
967
968   // In case of fail, it is checked if another arc 
969   // can be useful (case of output at the proximity of a vertex)
970   if (!recadre) {
971
972     IndexSol =  ArcToRecadre(sol, IndexSol, 
973                              lastpt2d, pt2d, pmin);
974     if (IndexSol == 0) {
975       return Standard_False; // No other solution
976     }
977
978     domain1->Init();
979     nbarc = 1;
980     while (nbarc < IndexSol) {
981       nbarc++;
982       domain1->Next();
983     }
984
985     Arc = domain1->Value();
986     FinvC.Set(Arc);
987   
988     FinvC.GetTolerance(toler,tolesp);
989     FinvC.GetBounds(infb,supb);
990
991     Solinv(3) = pmin;
992   
993     math_FunctionSetRoot aRsnld(FinvC,toler,30);
994     aRsnld.Perform(FinvC,Solinv,infb,supb);
995
996     if (!aRsnld.IsDone()) {
997 #ifdef OCCT_DEBUG
998       std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
999 #endif
1000     }
1001     else {
1002       // It is necessary to check the value of the function
1003       aRsnld.Root(Solinv);
1004       recadre = FinvC.IsSolution(Solinv,tolesp);
1005     }
1006   }  
1007
1008   if (recadre) {
1009     Standard_Real w = Solinv(2);
1010     if(w < rst->FirstParameter() - toler(2)||
1011        w > rst->LastParameter() + toler(2)){
1012       return Standard_False;
1013     }
1014     domain1->Initialize(Arc);
1015     domain1->InitVertexIterator();
1016     IsVtx = !domain1->MoreVertex();
1017     while (!IsVtx) {
1018       Vtx = domain1->Vertex();
1019       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
1020           BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
1021         IsVtx = Standard_True;
1022       }
1023       else {
1024         domain1->NextVertex();
1025         IsVtx = !domain1->MoreVertex();
1026       }
1027     }
1028     if (!domain1->MoreVertex()) {
1029       IsVtx = Standard_False;
1030     }
1031     return Standard_True;
1032   } 
1033   return Standard_False;
1034 }
1035
1036 //=======================================================================
1037 //function : Recadre
1038 //purpose  : 
1039 //=======================================================================
1040
1041 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction&   Func,
1042                                                        Blend_FuncInv&           Finv,
1043                                                        math_Vector&             Solinv,
1044                                                        Standard_Boolean&        IsVtx,
1045                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1046 {
1047   math_Vector toler(1,4),infb(1,4),supb(1,4);
1048   Finv.GetTolerance(toler,tolesp);
1049   Finv.GetBounds(infb,supb);
1050   Solinv(1) = sol(3);
1051   Solinv(2) = param;
1052   Solinv(3) = sol(1);
1053   Solinv(4) = sol(2);
1054
1055   math_FunctionSetRoot rsnld(Finv,toler,30);
1056   rsnld.Perform(Finv,Solinv,infb,supb);
1057   if (!rsnld.IsDone()) {
1058 #ifdef OCCT_DEBUG
1059     std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
1060 #endif
1061     return Standard_False;
1062   }
1063   rsnld.Root(Solinv);
1064   
1065   if(Finv.IsSolution(Solinv,tolesp)){
1066     gp_Pnt2d p2d(Solinv(3),Solinv(4));
1067     TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
1068     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1069       return Standard_False;
1070     }
1071     domain2->Initialize(rst);
1072     domain2->InitVertexIterator();
1073     IsVtx = !domain2->MoreVertex();
1074     while (!IsVtx) {
1075       Vtx = domain2->Vertex();
1076       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
1077           BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1078         IsVtx = Standard_True;
1079       }
1080       else {
1081         domain2->NextVertex();
1082         IsVtx = !domain2->MoreVertex();
1083       }
1084     }
1085     if (!domain2->MoreVertex()) {
1086       IsVtx = Standard_False;
1087     }
1088     // The section is recalculated by direct resolution, otherwise 
1089     // incoherences between the parameter and the ground caused by yawn are returned.
1090
1091     math_Vector infbound(1,3),supbound(1,3);
1092     math_Vector parinit(1,3),tolerance(1,3);
1093     Func.GetTolerance(tolerance,tolesp);
1094     Func.GetBounds(infbound,supbound);
1095
1096     math_FunctionSetRoot rsnld2(Func,tolerance,30);
1097     parinit(1) = Solinv(3);
1098     parinit(2) = Solinv(4);
1099     parinit(3) = Solinv(1);
1100     Func.Set(Solinv(2));
1101     rsnld2.Perform(Func,parinit,infbound,supbound);
1102     if(!rsnld2.IsDone()) return Standard_False;
1103     rsnld2.Root(parinit);
1104     Solinv(3) = parinit(1);
1105     Solinv(4) = parinit(2);
1106     Solinv(1) = parinit(3);
1107     return Standard_True;
1108   }
1109   return Standard_False;
1110 }
1111
1112 //=======================================================================
1113 //function : Recadre
1114 //purpose  : 
1115 //=======================================================================
1116
1117 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv&  FinvP,
1118                                                        math_Vector&             Solinv,
1119                                                        Standard_Boolean&        IsVtx,
1120                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1121 {
1122   // Le point.
1123   gp_Pnt2d p2drst;
1124   Standard_Real firstrst = rst->FirstParameter();
1125   Standard_Real lastrst = rst->LastParameter();
1126   Standard_Real wpoint = firstrst;
1127   if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
1128   p2drst = rst->Value(wpoint);
1129   gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
1130
1131   FinvP.Set(thepoint);
1132   math_Vector toler(1,3),infb(1,3),supb(1,3);
1133   FinvP.GetTolerance(toler,tolesp);
1134   FinvP.GetBounds(infb,supb);
1135   Solinv(1) = param;
1136   Solinv(2) = sol(1);
1137   Solinv(3) = sol(2);
1138
1139   math_FunctionSetRoot rsnld(FinvP,toler,30);
1140   rsnld.Perform(FinvP,Solinv,infb,supb);
1141   if (!rsnld.IsDone()) {
1142 #ifdef OCCT_DEBUG
1143     std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
1144 #endif
1145     return Standard_False;
1146   }
1147   rsnld.Root(Solinv);
1148   
1149   if(FinvP.IsSolution(Solinv,tolesp)){
1150     gp_Pnt2d p2d(Solinv(2),Solinv(3));
1151     TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
1152     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1153       return Standard_False;
1154     }
1155     domain2->Initialize(rst);
1156     domain2->InitVertexIterator();
1157     IsVtx = !domain2->MoreVertex();
1158     while (!IsVtx) {
1159       Vtx = domain2->Vertex();
1160       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
1161           BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1162         IsVtx = Standard_True;
1163       }
1164       else {
1165         domain2->NextVertex();
1166         IsVtx = !domain2->MoreVertex();
1167       }
1168     }
1169     if (!domain2->MoreVertex()) {
1170       IsVtx = Standard_False;
1171     }
1172     return Standard_True;
1173   }
1174   return Standard_False;
1175 }
1176
1177 //=======================================================================
1178 //function : Transition
1179 //purpose  : 
1180 //=======================================================================
1181
1182 void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean          OnFirst,
1183                                               const Handle(Adaptor2d_HCurve2d)& Arc,
1184                                               const Standard_Real             Param,
1185                                               IntSurf_Transition&             TLine,
1186                                               IntSurf_Transition&             TArc) 
1187 {
1188   Standard_Boolean computetranstionaveclacorde = 0;
1189   gp_Vec tgline;
1190   Blend_Point prevprev;
1191
1192   if(previousP.IsTangencyPoint()){
1193     if(line->NbPoints() < 2) return;
1194     computetranstionaveclacorde = 1;
1195     if(sens < 0){
1196       prevprev = line->Point(2);
1197     }
1198     else {
1199       prevprev = line->Point(line->NbPoints() - 1);
1200     }
1201   }
1202   gp_Pnt2d p2d;
1203   gp_Vec2d dp2d;
1204   
1205   gp_Pnt pbid;
1206   gp_Vec d1u,d1v,normale,tgrst;
1207   
1208   Arc->D1(Param,p2d,dp2d);
1209   if (OnFirst) {
1210     surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1211     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
1212     else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
1213   }
1214   else {
1215     surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1216     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
1217     else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
1218   }
1219   
1220   tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
1221   normale = d1u.Crossed(d1v);
1222   
1223   IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
1224 }
1225
1226 //=======================================================================
1227 //function : MakeExtremity
1228 //purpose  : 
1229 //=======================================================================
1230
1231 void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity&            Extrem,
1232                                                  const Standard_Boolean          OnFirst,
1233                                                  const Handle(Adaptor2d_HCurve2d)& Arc,
1234                                                  const Standard_Real             Param,
1235                                                  const Standard_Boolean          IsVtx,
1236                                                  const Handle(Adaptor3d_HVertex)&  Vtx) 
1237 {
1238   IntSurf_Transition Tline,Tarc;
1239   Standard_Real prm;
1240   Handle(Adaptor3d_TopolTool) Iter;
1241   if (OnFirst) {
1242     Extrem.SetValue(previousP.PointOnS(),
1243                     sol(1),sol(2),
1244                     previousP.Parameter(),tolesp);
1245     if (!previousP.IsTangencyPoint()) 
1246       Extrem.SetTangent(previousP.TangentOnS());
1247     Iter = domain1;
1248   }
1249   else {
1250     Extrem.SetValue(previousP.PointOnC(),
1251                     sol(3),
1252                     previousP.Parameter(),tolesp);
1253     if (!previousP.IsTangencyPoint()) 
1254       Extrem.SetTangent(previousP.TangentOnC());    
1255     Iter = domain2;
1256   }
1257   
1258   Iter->Init();
1259   if (!IsVtx) {
1260     Transition(OnFirst,Arc,Param,Tline,Tarc);
1261     Extrem.AddArc(Arc,Param,Tline,Tarc);
1262   }
1263   else {
1264     Extrem.SetVertex(Vtx);
1265     while (Iter->More()) {
1266       Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
1267       if (arc != Arc) {
1268         Iter->Initialize(arc);
1269         Iter->InitVertexIterator();
1270         while (Iter->MoreVertex()) {
1271           if (Iter->Identical(Vtx,Iter->Vertex())) {
1272             prm = BRepBlend_BlendTool::Parameter(Vtx,arc);
1273             Transition(OnFirst,arc,prm,Tline,Tarc);
1274             Extrem.AddArc(arc,prm,Tline,Tarc);
1275           }
1276           Iter->NextVertex();
1277         }
1278       }
1279       else {
1280         Transition(OnFirst,arc,Param,Tline,Tarc);
1281         Extrem.AddArc(arc,Param,Tline,Tarc);
1282       }
1283       Iter->Next();
1284     }
1285   }
1286 }
1287
1288 //=======================================================================
1289 //function : CheckDeflectionOnSurf
1290 //purpose  : 
1291 //=======================================================================
1292
1293 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
1294 {
1295   //Controls 3d of Blend_CSWalking.
1296
1297   //rule by tests in U4 corresponds to 11.478 d
1298   const Standard_Real CosRef3D = 0.98;
1299   Standard_Real Cosi=0, Cosi2=0;
1300   Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1301   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1302
1303   gp_Pnt Psurf = CurPoint.PointOnS();
1304   gp_Vec Tgsurf;
1305   if(!curpointistangent){
1306     Tgsurf = CurPoint.TangentOnS();
1307   }
1308   gp_Pnt prevP = previousP.PointOnS();
1309   gp_Vec prevTg;
1310   if(!prevpointistangent){
1311     prevTg = previousP.TangentOnS();
1312   }
1313   Standard_Real Norme,prevNorme = 0.;
1314   gp_Vec Corde(prevP,Psurf);
1315   Norme = Corde.SquareMagnitude();
1316 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1317   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1318
1319   if (Norme <= tolesp*tolesp){
1320     // it can be necessary to force same point
1321     return Blend_SamePoints;
1322   }
1323   if(!prevpointistangent){
1324     if(prevNorme <= tolesp*tolesp) {
1325       return Blend_SamePoints;
1326     }
1327     Cosi = sens*Corde*prevTg;
1328     if (Cosi <0.) { // angle 3d>pi/2. --> return back
1329       return Blend_Backward;
1330     }
1331     
1332     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1333     if (Cosi2 < CosRef3D) { 
1334       return Blend_StepTooLarge;
1335     }
1336   }
1337   
1338   if(!curpointistangent){
1339     // Check if it is necessary to control the sign of prevtg*Tgsurf
1340     Cosi = sens*Corde*Tgsurf;
1341     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1342     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1343       return Blend_StepTooLarge;
1344     }
1345   }  
1346
1347   if(!curpointistangent && !prevpointistangent){
1348     // Estimation of the current arrow
1349     Standard_Real FlecheCourante = 
1350       (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1351     
1352     if (FlecheCourante <= 0.25*fleche*fleche) {
1353       return Blend_StepTooSmall;
1354     }
1355     if (FlecheCourante > fleche*fleche) {
1356       // not too great : 
1357       return Blend_StepTooLarge;
1358     }
1359   }
1360   return Blend_OK;
1361 }
1362
1363
1364 //=======================================================================
1365 //function : CheckDeflectionOnRst
1366 //purpose  : 
1367 //=======================================================================
1368
1369 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
1370 {
1371   //Controls 3D of Blend_CSWalking.
1372
1373   // rule by tests in U4 corresponds to 11.478 d
1374   const Standard_Real CosRef3D = 0.98;
1375   Standard_Real Cosi, Cosi2;
1376   Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1377   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1378
1379   gp_Pnt Psurf = CurPoint.PointOnC();
1380   gp_Vec Tgsurf;
1381   if(!curpointistangent){
1382     Tgsurf = CurPoint.TangentOnC();
1383   }
1384   gp_Pnt prevP = previousP.PointOnC();
1385   gp_Vec prevTg;
1386   if(!prevpointistangent){
1387     prevTg = previousP.TangentOnC();
1388   }
1389   Standard_Real Norme,prevNorme = 0.;
1390   gp_Vec Corde(prevP,Psurf);
1391   Norme = Corde.SquareMagnitude();
1392 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1393   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1394
1395   if (Norme <= tolesp*tolesp){
1396     // it can be necessary to force same point
1397     return Blend_SamePoints;
1398   }
1399   if(!prevpointistangent){
1400     if(prevNorme <= tolesp*tolesp) {
1401       return Blend_SamePoints;
1402     }
1403     Cosi = sens*Corde*prevTg;
1404     if (Cosi <0.) { // angle 3d>pi/2. --> return back
1405       return Blend_Backward;
1406     }
1407     
1408     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1409     if (Cosi2 < CosRef3D) { 
1410       return Blend_StepTooLarge;
1411     }
1412   }
1413   
1414   if(!curpointistangent){
1415     // Check if it is necessary to control the sign of prevtg*Tgsurf
1416     Cosi = sens*Corde*Tgsurf;
1417     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1418     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1419       return Blend_StepTooLarge;
1420     }
1421   }  
1422
1423   if(!curpointistangent && !prevpointistangent){
1424     // Estimation of the current arrow
1425     Standard_Real FlecheCourante = 
1426       (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1427     
1428     if (FlecheCourante <= 0.25*fleche*fleche) {
1429       return Blend_StepTooSmall;
1430     }
1431     if (FlecheCourante > fleche*fleche) {
1432       // not too great
1433       return Blend_StepTooLarge;
1434     }
1435   }
1436   return Blend_OK;
1437 }
1438
1439 static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1440 {
1441   if(O == TopAbs_FORWARD) return IntSurf_In;
1442   return IntSurf_Out;
1443 }
1444
1445 //=======================================================================
1446 //function : TestArret
1447 //purpose  : 
1448 //=======================================================================
1449
1450 Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
1451                                                      const Standard_Boolean TestDeflection,
1452                                                      const Blend_Status     State) 
1453 {
1454   gp_Pnt pts,ptrst;
1455   gp_Pnt2d pt2drst;
1456   gp_Vec tgs,tgrst;
1457   gp_Vec2d tg2ds,tg2drst;
1458   Blend_Status StateS,StateRst;
1459   IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
1460   Blend_Point curpoint;
1461
1462   if (Func.IsSolution(sol,tolesp)) {
1463     Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1464     pts = Func.PointOnS();
1465     ptrst = Func.PointOnRst();
1466     pt2drst = Func.Pnt2dOnRst();
1467     if(curpointistangent){
1468       curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1469                         pt2drst.X(),pt2drst.Y(),sol(3));
1470     }
1471     else{
1472       tgs     = Func.TangentOnS();
1473       tgrst   = Func.TangentOnRst();
1474       tg2ds   = Func.Tangent2dOnS();
1475       tg2drst = Func.Tangent2dOnRst();
1476
1477       curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1478                         pt2drst.X(),pt2drst.Y(),sol(3),
1479                         tgs,tgrst,tg2ds,tg2drst);
1480     }
1481     if (TestDeflection) {
1482       StateS = CheckDeflectionOnSurf(curpoint);
1483       StateRst = CheckDeflectionOnRst(curpoint);
1484     }
1485     else {
1486       StateS = StateRst = Blend_OK;
1487     }
1488     if (StateS == Blend_Backward) {
1489       StateS = Blend_StepTooLarge;
1490       rebrou= Standard_True;
1491     }
1492     if (StateRst == Blend_Backward) {
1493       StateRst = Blend_StepTooLarge;
1494       rebrou = Standard_True;
1495     }
1496     if (StateS == Blend_StepTooLarge ||
1497         StateRst == Blend_StepTooLarge) {
1498       return Blend_StepTooLarge;
1499     }
1500
1501     if (!comptra && !curpointistangent) {
1502       gp_Vec tgsecs,nors;
1503       Func.Decroch(sol,nors,tgsecs);
1504       nors.Normalize();
1505       Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
1506       if (Abs(testra) > tolesp) {
1507         if (testra < 0.) {
1508           tras = IntSurf_In;
1509         }
1510         else if (testra >0.) {
1511           tras = IntSurf_Out;
1512         }
1513         gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
1514         rst->D1(sol(3),p2drstref,tg2drstref);
1515         testra = tg2drst.Dot(tg2drstref);
1516         TopAbs_Orientation Or = domain2->Orientation(rst);
1517         if (Abs(testra) > 1.e-8) {
1518           if (testra < 0.) {
1519             trarst = ConvOrToTra(TopAbs::Reverse(Or));
1520           }
1521           else if (testra >0.) {
1522             trarst = ConvOrToTra(Or);
1523           }
1524           comptra = Standard_True;
1525           line->Set(tras,trarst);
1526         }
1527       }
1528     }
1529     if (StateS == Blend_OK ||
1530         StateRst == Blend_OK ) {
1531       previousP = curpoint;
1532       return State;
1533     }
1534     if (StateS == Blend_StepTooSmall &&
1535         StateRst == Blend_StepTooSmall) {
1536       previousP = curpoint;
1537       if (State == Blend_OK) {
1538         return Blend_StepTooSmall;
1539       }
1540       else {
1541         return State;
1542       }
1543     }
1544     if (State == Blend_OK) {
1545       return Blend_SamePoints;
1546     }
1547     else {
1548       return State;
1549     }
1550   }
1551   return Blend_StepTooLarge;
1552 }
1553
1554 //=======================================================================
1555 //function : CheckInside
1556 //purpose  : 
1557 //=======================================================================
1558
1559 Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
1560                                                            TopAbs_State&          SituOnC,
1561                                                            TopAbs_State&          SituOnS,
1562                                                            Standard_Boolean&      Decroch)
1563 {
1564   math_Vector tolerance(1,3);
1565   Func.GetTolerance(tolerance,tolesp);
1566   //face pcurve.
1567   Standard_Real w = sol(3);
1568   if(w < rst->FirstParameter() - tolerance(3)||
1569      w > rst->LastParameter() + tolerance(3)){
1570     SituOnC = TopAbs_OUT;
1571   }
1572   else if (w > rst->FirstParameter() &&
1573            w < rst->LastParameter()){
1574     SituOnC = TopAbs_IN;
1575   }
1576   else SituOnC = TopAbs_ON;
1577
1578   //face surface
1579   gp_Pnt2d p2d(sol(1),sol(2));
1580   SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
1581
1582   //lost contact
1583   gp_Vec tgs,nors;
1584   Decroch = Func.Decroch(sol,tgs,nors);
1585
1586   return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);
1587 }
1588