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