0023024: Update headers of OCCT files
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <stdio.h>
23
24 #include <BRepBlend_SurfRstLineBuilder.ixx>
25 #include <BRepBlend_BlendTool.hxx>
26 #include <TopAbs.hxx>
27 #include <IntSurf.hxx>
28 #include <math_FunctionSetRoot.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Pnt.hxx>
31 #include <gp_Vec2d.hxx>
32 #include <gp_Vec.hxx>
33
34 #ifdef DEB
35 #include <TColStd_Array1OfInteger.hxx>
36 #include <TColStd_Array1OfReal.hxx>
37 #include <TColgp_Array1OfPnt2d.hxx>
38 #include <TColgp_Array1OfVec.hxx>
39 #include <TColgp_Array1OfVec2d.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
41 #include <Geom_BSplineCurve.hxx>
42 #ifdef DRAW
43 #include <DrawTrSurf.hxx>
44 #endif
45 static Standard_Integer IndexOfSection = 0;
46 extern Standard_Boolean Blend_GettraceDRAWSECT(); 
47 // for debug : visualisation of the section
48 static Standard_Boolean BBPP(const Standard_Real param,
49                              Blend_SurfRstFunction& Func,
50                              const math_Vector& sol,
51                              const Standard_Real tol,
52                              Blend_Point& BP)
53 {
54   if(!Func.IsSolution(sol,tol)) return 0;
55   gp_Pnt pnts = Func.PointOnS();
56   gp_Pnt pntrst = Func.PointOnRst();
57   gp_Pnt2d p2ds = Func.Pnt2dOnS();
58   gp_Pnt2d p2drst = Func.Pnt2dOnRst();
59   Standard_Real w = Func.ParameterOnRst();
60   BP = Blend_Point(pnts,pntrst,param,
61                    p2ds.X(),p2ds.Y(),
62                    p2drst.X(),p2drst.Y(),w);
63   return 1;
64 }
65 static void tracederiv(Blend_SurfRstFunction& Func,
66                        const Blend_Point& BP1,
67                        const Blend_Point& BP2)
68 {
69   Standard_Integer hp,hk,hd,hp2d,i;
70   Func.GetShape(hp,hk,hd,hp2d);
71   TColgp_Array1OfPnt TP1(1,hp);
72   TColgp_Array1OfVec TDP1(1,hp);
73   TColgp_Array1OfPnt2d TP2d1(1,hp2d);
74   TColgp_Array1OfVec2d TDP2d1(1,hp2d);
75   TColStd_Array1OfReal TW1(1,hp);
76   TColStd_Array1OfReal TDW1(1,hp);
77   Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
78
79   TColgp_Array1OfPnt TP2(1,hp);
80   TColgp_Array1OfVec TDP2(1,hp);
81   TColgp_Array1OfPnt2d TP2d2(1,hp2d);
82   TColgp_Array1OfVec2d TDP2d2(1,hp2d);
83   TColStd_Array1OfReal TW2(1,hp);
84   TColStd_Array1OfReal TDW2(1,hp);
85   Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
86
87   Standard_Real param1 = BP1.Parameter();
88   Standard_Real param2 = BP2.Parameter();
89   Standard_Real scal = 1./(param1-param2);
90
91   cout<<endl;
92   cout<<"control derivatives at point : "<<param1<<endl;
93
94   for(i = 1; i <= hp; i++){
95     cout<<endl;
96     cout<<"point : "<<i<<endl;
97     cout<<"dx calculated : "<<TDP1(i).X()<<endl;
98     cout<<"dx estimated  : "<<scal*(TP1(i).X()-TP2(i).X())<<endl;
99     cout<<"dy calculated : "<<TDP1(i).Y()<<endl;
100     cout<<"dy estimated  : "<<scal*(TP1(i).Y()-TP2(i).Y())<<endl;
101     cout<<"dz calculated : "<<TDP1(i).Z()<<endl;
102     cout<<"dz estimated  : "<<scal*(TP1(i).Z()-TP2(i).Z())<<endl;
103     cout<<"dw calculated : "<<TDW1(i)<<endl;
104     cout<<"dw estimated  : "<<scal*(TW1(i)-TW2(i))<<endl;
105   }
106   for(i = 1; i <= hp2d; i++){
107     cout<<endl;
108     cout<<"point 2d : "<<i<<endl;
109     cout<<"dx calculated : "<<TDP2d1(i).X()<<endl;
110     cout<<"dx estimated  : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<endl;
111     cout<<"dy calculated : "<<TDP2d1(i).Y()<<endl;
112     cout<<"dy estimated  : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<endl;
113   }
114 }
115
116 static void Drawsect(const Standard_Real param,
117                      Blend_SurfRstFunction& Func)
118 {
119   gp_Pnt pnts = Func.PointOnS();
120   gp_Pnt pntrst = Func.PointOnRst();
121   gp_Pnt2d p2ds = Func.Pnt2dOnS();
122   gp_Pnt2d p2drst = Func.Pnt2dOnRst();
123   Standard_Real w = Func.ParameterOnRst();
124   Blend_Point BP(pnts,pntrst,param,
125                  p2ds.X(),p2ds.Y(),
126                  p2drst.X(),p2drst.Y(),w);
127   Standard_Integer hp,hk,hd,hp2d;
128   Func.GetShape(hp,hk,hd,hp2d);
129   TColStd_Array1OfReal TK(1,hk);
130   Func.Knots(TK);
131   TColStd_Array1OfInteger TMul(1,hk);
132   Func.Mults(TMul);
133   TColgp_Array1OfPnt TP(1,hp);
134   TColgp_Array1OfPnt2d TP2d(1,hp2d);
135   TColStd_Array1OfReal TW(1,hp);
136   Func.Section(BP,TP,TP2d,TW);
137   Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
138     (TP,TW,TK,TMul,hd);
139   IndexOfSection++;
140 #ifdef DRAW
141   char tname[100];
142   Standard_CString name = tname ;
143   sprintf(name,"%s_%d","Section",IndexOfSection);
144   DrawTrSurf::Set(name,sect);
145 #endif
146 }
147 #endif
148
149 //=======================================================================
150 //function :  ArcToRecadre
151 //purpose  : Find a suitable arc
152 //           PrevIndex is used to reject an already tested arc
153 //=======================================================================
154
155 Standard_Integer BRepBlend_SurfRstLineBuilder::
156    ArcToRecadre(const math_Vector& sol,
157                 const Standard_Integer PrevIndex, 
158                 gp_Pnt2d& lastpt2d,
159                 gp_Pnt2d& pt2d,
160                 Standard_Real& ponarc) 
161 {
162   Standard_Integer IndexSol = 0,  nbarc = 0;
163   Standard_Boolean ok = Standard_False;
164   Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
165   Standard_Real distmin = RealLast();
166   Standard_Real uprev,vprev, prm, dist;
167
168   if(byinter) previousP.ParametersOnS(uprev,vprev);
169   pt2d.SetCoord(sol(1),sol(2));
170   lastpt2d.SetCoord(uprev,vprev);
171   domain1->Init();
172
173   while (domain1->More()) {
174     nbarc++; ok = 0;
175     if(byinter) { 
176       ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
177                                                  surf1,
178                                                  domain1->Value(),prm,dist); 
179     }
180     if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
181                                               domain1->Value(),prm,dist);
182
183     if (ok && (nbarc != PrevIndex) ) {
184       if (dist<distmin || okinter) {
185         distmin = dist;
186         ponarc = prm;
187         IndexSol = nbarc;
188         if(okinter && (PrevIndex==0) ) break;
189       }
190     }
191     domain1->Next();
192   }
193   return IndexSol;
194 }
195
196 //=======================================================================
197 //function : BRepBlend_SurfRstLineBuilder
198 //purpose  : 
199 //=======================================================================
200
201 BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
202 (const Handle(Adaptor3d_HSurface)&  Surf1,
203  const Handle(Adaptor3d_TopolTool)& Domain1,
204  const Handle(Adaptor3d_HSurface)&  Surf2,
205  const Handle(Adaptor2d_HCurve2d)&  Rst,
206  const Handle(Adaptor3d_TopolTool)& Domain2):
207  sol(1,3),surf1(Surf1), domain1(Domain1),
208  surf2(Surf2), rst(Rst), domain2(Domain2)
209 {
210 }
211
212 //=======================================================================
213 //function : Perform
214 //purpose  : 
215 //=======================================================================
216
217 void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction&  Func,
218                                            Blend_FuncInv&          Finv,
219                                            Blend_SurfPointFuncInv& FinvP,
220                                            Blend_SurfCurvFuncInv&  FinvC,
221                                            const Standard_Real     Pdep,
222                                            const Standard_Real     Pmax,
223                                            const Standard_Real     MaxStep,
224                                            const Standard_Real     TolGuide,
225                                            const math_Vector&      ParDep,
226                                            const Standard_Real     Tolesp,
227                                            const Standard_Real     Fleche,
228                                            const Standard_Boolean  Appro) 
229 {
230   done = Standard_False;
231   iscomplete = Standard_False;
232   comptra = Standard_False;
233   line = new BRepBlend_Line();
234   tolesp = Abs(Tolesp);
235   tolgui = Abs(TolGuide);
236   fleche = Abs(Fleche);
237   rebrou = Standard_False;
238   pasmax = Abs(MaxStep);
239   
240   if (Pmax-Pdep >= 0.) {
241     sens = 1.;
242   }
243   else {
244     sens = -1.;
245   }
246   
247   Blend_Status State;
248   
249   param = Pdep;
250   Func.Set(param);
251   
252   if (Appro) {
253     TopAbs_State siturst,situs;
254     Standard_Boolean decroch;
255     math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
256     Func.GetTolerance(tolerance,tolesp);
257     Func.GetBounds(infbound,supbound);
258     math_FunctionSetRoot rsnld(Func,tolerance,30);
259     
260     rsnld.Perform(Func,ParDep,infbound,supbound);
261     
262     if (!rsnld.IsDone()) {
263       return;
264     }
265     rsnld.Root(sol);
266     if (!CheckInside(Func,siturst,situs,decroch)) {
267       return;
268     }
269   }
270   else {
271     sol = ParDep;
272   }
273
274   State = TestArret(Func,Standard_False,Blend_OK);
275   if (State!=Blend_OK) {
276     return;
277   }
278 #ifdef DEB
279   if (Blend_GettraceDRAWSECT()){
280     Drawsect(param,Func);
281   }
282 #endif
283   // Update the line.
284   line->Append(previousP);
285   Standard_Real U,V;
286   previousP.ParametersOnS(U,V);
287 //  W = previousP.ParameterOnC();
288   
289   BRepBlend_Extremity ptf1(previousP.PointOnS(),
290                            U,V,previousP.Parameter(),tolesp);
291   BRepBlend_Extremity ptf2(previousP.PointOnC(),
292                            U,V,previousP.Parameter(),tolesp);
293   if (!previousP.IsTangencyPoint()) {
294     ptf1.SetTangent(previousP.TangentOnS());
295     ptf2.SetTangent(previousP.TangentOnC());
296   }
297   if (sens>0.) {    
298     line->SetStartPoints(ptf1, ptf2);    
299   }
300   else {
301     line->SetEndPoints(ptf1, ptf2);
302     
303   }
304   InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
305   done = Standard_True;
306 }
307
308 //=======================================================================
309 //function : PerformFirstSection
310 //purpose  : 
311 //=======================================================================
312
313 Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
314 (Blend_SurfRstFunction&  Func,
315  Blend_FuncInv&          Finv,
316  Blend_SurfPointFuncInv& FinvP,
317  Blend_SurfCurvFuncInv&  FinvC,
318  const Standard_Real     Pdep,
319  const Standard_Real     Pmax,
320  const math_Vector&      ParDep,
321  const Standard_Real     Tolesp,
322  const Standard_Real     TolGuide,
323  const Standard_Boolean  RecRst,
324  const Standard_Boolean  RecP,
325  const Standard_Boolean  RecS,
326  Standard_Real&          Psol,   
327  math_Vector&            ParSol)
328 {
329   done = Standard_False;
330   iscomplete = Standard_False;
331   comptra = Standard_False;
332   line = new BRepBlend_Line();
333   tolesp = Abs(Tolesp);
334   tolgui = Abs(TolGuide);
335   rebrou = Standard_False;
336   
337   if (Pmax-Pdep >= 0.) {
338     sens = 1.;
339   }
340   else {
341     sens = -1.;
342   }
343 #ifndef DEB
344   Blend_Status State = Blend_OnRst12;
345   Standard_Real trst = 0.;
346 #else
347   Blend_Status State;
348   Standard_Real trst;
349 #endif  
350   Standard_Boolean recadp,recadrst,recads;
351   Standard_Real wp,wrst,ws;
352   Standard_Real U,V;
353   math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
354   math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
355   Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
356   Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
357   Handle(Adaptor2d_HCurve2d) Arc;
358   wp = wrst = ws = Pmax;
359   param = Pdep;
360   Func.Set(param);
361   Func.GetTolerance(tolerance,tolesp);
362   Func.GetBounds(infbound,supbound);
363
364   math_FunctionSetRoot rsnld(Func,tolerance,30);
365   rsnld.Perform(Func,ParDep,infbound,supbound);
366   if (!rsnld.IsDone()) return Standard_False;
367   rsnld.Root(sol);
368
369   recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
370   if (recads) {
371     ws = solinvs(1);
372   }
373   recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
374   if (recadp) {
375     wp = solinvp(1);
376   }
377   recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
378   if (recadrst) {
379     wrst = solinvrst(2);
380   }
381   if (!recads && !recadp && !recadrst) return Standard_False;
382   if (recadp && recadrst) {
383     if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
384       wrst = wp;
385       U = solinvp(2);
386       V = solinvp(3);
387       trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
388       IsVtxrst = IsVtxp;
389       Vtxrst = Vtxp;
390     }
391     else{                        
392       U = solinvrst(3);
393       V = solinvrst(4);
394       trst = solinvrst(1);
395     }
396   }
397   else if(recadp){
398     wrst = wp;
399     U = solinvp(2);
400     V = solinvp(3);
401     trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
402     IsVtxrst = IsVtxp;
403     Vtxrst = Vtxp;
404     recadrst = Standard_True;
405   }
406   else if(recadrst){
407     U = solinvrst(3);
408     V = solinvrst(4);
409     trst = solinvrst(1);
410   }
411   if(recads && recadrst){
412     if(Abs(ws - wrst) < tolgui){
413       State = Blend_OnRst12;
414       param = 0.5*(ws+wrst);
415       sol(1) = U;
416       sol(2) = V;
417       sol(3) = solinvs(2);
418     }
419     else if(sens*(ws-wrst)<0){
420       // ground on surf
421       State = Blend_OnRst1;
422       param = ws;
423       Arc->Value(solinvs(3)).Coord(U,V);
424       sol(1) = U;
425       sol(2) = V;
426       sol(3) = solinvs(2);
427     }
428     else{
429       // ground on rst
430       State = Blend_OnRst2;
431       param = wrst;
432       sol(1) = U;
433       sol(2) = V;
434       sol(3) = trst;
435     }
436     Func.Set(param);
437   }
438   else if(recads){
439     // ground on surf
440     State = Blend_OnRst1;
441     param = ws;
442     Arc->Value(solinvs(3)).Coord(U,V);
443     sol(1) = U;
444     sol(2) = V;
445     sol(3) = solinvs(2);
446     Func.Set(param);
447   }
448   else if(recadrst){
449     // ground on rst
450     State = Blend_OnRst2;
451     param = wrst;
452     sol(1) = U;
453     sol(2) = V;
454     sol(3) = trst;
455     Func.Set(param);
456   }
457   State = TestArret(Func,Standard_False,State);
458   Psol = param;
459   ParSol = sol;
460   return Standard_True;
461 }  
462
463 //=======================================================================
464 //function : Complete
465 //purpose  : 
466 //=======================================================================
467
468 Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction&  Func,
469                                                         Blend_FuncInv&          Finv,
470                                                         Blend_SurfPointFuncInv& FinvP,
471                                                         Blend_SurfCurvFuncInv&  FinvC,
472                                                         const Standard_Real     Pmin) 
473 {
474   if (!done) {StdFail_NotDone::Raise();}
475   if (iscomplete) {return Standard_True;}
476   if (sens >0.) {
477     previousP = line->Point(1);
478   }
479   else {
480     previousP = line->Point(line->NbPoints());
481   }
482   sens = -sens;
483   param = previousP.Parameter();
484   previousP.ParametersOnS(sol(1),sol(2));
485   sol(3) = previousP.ParameterOnC();
486
487   InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
488   iscomplete = Standard_True;
489   return Standard_True;
490 }
491
492 //=======================================================================
493 //function : InternalPerform
494 //purpose  : 
495 //=======================================================================
496
497 void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction&  Func,
498                                                    Blend_FuncInv&          Finv,
499                                                    Blend_SurfPointFuncInv& FinvP,
500                                                    Blend_SurfCurvFuncInv&  FinvC,
501                                                    const Standard_Real     Bound) 
502 {
503   Standard_Real stepw = pasmax;
504   Standard_Integer nbp = line->NbPoints();
505   if(nbp >= 2){ //The last step is reproduced if it is not too small.
506     if(sens < 0.){
507       stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
508     }
509     else{
510       stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
511     }
512     stepw = Max(stepw,100.*tolgui);
513   }
514   Standard_Real parprec = param;
515   if (sens*(parprec - Bound) >= -tolgui) {
516     return;
517   }
518 #ifndef DEB
519   Blend_Status State = Blend_OnRst12;
520 #else
521   Blend_Status State;
522 #endif
523   TopAbs_State situonc,situons;
524   Standard_Boolean decroch;
525   Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
526   Standard_Real wp,wrst,ws;
527   Standard_Real U,V;
528 #ifndef DEB
529   Standard_Real  trst = 0.;
530 #else
531   Standard_Real  trst;
532 #endif
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 #if 0
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 #if DEB
725         cout<<"SurfRstLineBuilder : failed reframing"<<endl;
726 #endif
727         State = Blend_SamePoints;
728       }
729     }
730     
731     switch (State) {
732     case Blend_OK :
733       {
734 #ifdef DEB
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 #if DEB
780             cout<<"SurfRstLineBuilder : No advancement in the processing"<<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 DEB
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 DEB
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 DEB
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 DEB
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 #if DEB
886         cout << "SurfRstLineBuilder Points mixed in the processing" << 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 #ifndef DEB
898     default:
899       break;
900 #endif
901     }
902     if (Arrive) {
903       if (sens > 0.) {
904         line->SetEndPoints(Exts,Extrst);
905         decrochfin = decroch;
906       }
907       else {
908         line->SetStartPoints(Exts,Extrst);
909         decrochdeb = decroch;
910       }
911     }
912   }
913 }
914
915 //=======================================================================
916 //function : Recadre
917 //purpose  : Reframe section Surface / Restriction
918 //=======================================================================
919
920 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv&    FinvC,
921                                                        math_Vector&              Solinv,
922                                                        Handle(Adaptor2d_HCurve2d)& Arc,
923                                                        Standard_Boolean&         IsVtx,
924                                                        Handle(Adaptor3d_HVertex)&  Vtx) 
925 {
926   Standard_Boolean recadre = Standard_False;
927
928   gp_Pnt2d pt2d, lastpt2d;
929   Standard_Integer IndexSol, nbarc;
930   Standard_Real pmin;
931
932   IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
933  
934   IsVtx = Standard_False;
935   if (IndexSol == 0) {
936     return Standard_False;
937   }
938
939   domain1->Init();
940   nbarc = 1;
941   while (nbarc < IndexSol) {
942     nbarc++;
943     domain1->Next();
944   }
945   Arc = domain1->Value();
946
947   FinvC.Set(Arc);
948   
949   math_Vector toler(1,3),infb(1,3),supb(1,3);
950   FinvC.GetTolerance(toler,tolesp);
951   FinvC.GetBounds(infb,supb);
952   Solinv(1) = param;
953   Solinv(2) = sol(3);
954   Solinv(3) = pmin;
955   
956   math_FunctionSetRoot rsnld(FinvC,toler,30);
957   rsnld.Perform(FinvC,Solinv,infb,supb);
958
959   if (!rsnld.IsDone()) {
960 #if DEB
961     cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
962 #endif
963   }
964   else {
965       // It is necessary to check the value of the function
966     rsnld.Root(Solinv);
967     recadre = FinvC.IsSolution(Solinv,tolesp);
968   }
969
970   // In case of fail, it is checked if another arc 
971   // can be useful (case of output at the proximity of a vertex)
972   if (!recadre) {
973
974     IndexSol =  ArcToRecadre(sol, IndexSol, 
975                              lastpt2d, pt2d, pmin);
976     if (IndexSol == 0) {
977       return Standard_False; // No other solution
978     }
979
980     domain1->Init();
981     nbarc = 1;
982     while (nbarc < IndexSol) {
983       nbarc++;
984       domain1->Next();
985     }
986
987     Arc = domain1->Value();
988     FinvC.Set(Arc);
989   
990     FinvC.GetTolerance(toler,tolesp);
991     FinvC.GetBounds(infb,supb);
992
993     Solinv(3) = pmin;
994   
995     math_FunctionSetRoot rsnld(FinvC,toler,30);
996     rsnld.Perform(FinvC,Solinv,infb,supb);
997
998     if (!rsnld.IsDone()) {
999 #if DEB
1000       cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
1001 #endif
1002     }
1003     else {
1004       // It is necessary to check the value of the function
1005       rsnld.Root(Solinv);
1006       recadre = FinvC.IsSolution(Solinv,tolesp);
1007     }
1008   }  
1009
1010   if (recadre) {
1011     Standard_Real w = Solinv(2);
1012     if(w < rst->FirstParameter() - toler(2)||
1013        w > rst->LastParameter() + toler(2)){
1014       return Standard_False;
1015     }
1016     domain1->Initialize(Arc);
1017     domain1->InitVertexIterator();
1018     IsVtx = !domain1->MoreVertex();
1019     while (!IsVtx) {
1020       Vtx = domain1->Vertex();
1021       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
1022           BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
1023         IsVtx = Standard_True;
1024       }
1025       else {
1026         domain1->NextVertex();
1027         IsVtx = !domain1->MoreVertex();
1028       }
1029     }
1030     if (!domain1->MoreVertex()) {
1031       IsVtx = Standard_False;
1032     }
1033     return Standard_True;
1034   } 
1035   return Standard_False;
1036 }
1037
1038 //=======================================================================
1039 //function : Recadre
1040 //purpose  : 
1041 //=======================================================================
1042
1043 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction&   Func,
1044                                                        Blend_FuncInv&           Finv,
1045                                                        math_Vector&             Solinv,
1046                                                        Standard_Boolean&        IsVtx,
1047                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1048 {
1049   math_Vector toler(1,4),infb(1,4),supb(1,4);
1050   Finv.GetTolerance(toler,tolesp);
1051   Finv.GetBounds(infb,supb);
1052   Solinv(1) = sol(3);
1053   Solinv(2) = param;
1054   Solinv(3) = sol(1);
1055   Solinv(4) = sol(2);
1056
1057   math_FunctionSetRoot rsnld(Finv,toler,30);
1058   rsnld.Perform(Finv,Solinv,infb,supb);
1059   if (!rsnld.IsDone()) {
1060 #if DEB
1061     cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1062 #endif
1063     return Standard_False;
1064   }
1065   rsnld.Root(Solinv);
1066   
1067   if(Finv.IsSolution(Solinv,tolesp)){
1068     gp_Pnt2d p2d(Solinv(3),Solinv(4));
1069     TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
1070     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1071       return Standard_False;
1072     }
1073     domain2->Initialize(rst);
1074     domain2->InitVertexIterator();
1075     IsVtx = !domain2->MoreVertex();
1076     while (!IsVtx) {
1077       Vtx = domain2->Vertex();
1078       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
1079           BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1080         IsVtx = Standard_True;
1081       }
1082       else {
1083         domain2->NextVertex();
1084         IsVtx = !domain2->MoreVertex();
1085       }
1086     }
1087     if (!domain2->MoreVertex()) {
1088       IsVtx = Standard_False;
1089     }
1090     // The section is recalculated by direct resolution, otherwise 
1091     // incoherences between the parameter and the ground caused by yawn are returned.
1092
1093     math_Vector infbound(1,3),supbound(1,3);
1094     math_Vector parinit(1,3),tolerance(1,3);
1095     Func.GetTolerance(tolerance,tolesp);
1096     Func.GetBounds(infbound,supbound);
1097
1098     math_FunctionSetRoot rsnld2(Func,tolerance,30);
1099     parinit(1) = Solinv(3);
1100     parinit(2) = Solinv(4);
1101     parinit(3) = Solinv(1);
1102     Func.Set(Solinv(2));
1103     rsnld2.Perform(Func,parinit,infbound,supbound);
1104     if(!rsnld2.IsDone()) return Standard_False;
1105     rsnld2.Root(parinit);
1106     Solinv(3) = parinit(1);
1107     Solinv(4) = parinit(2);
1108     Solinv(1) = parinit(3);
1109     return Standard_True;
1110   }
1111   return Standard_False;
1112 }
1113
1114 //=======================================================================
1115 //function : Recadre
1116 //purpose  : 
1117 //=======================================================================
1118
1119 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv&  FinvP,
1120                                                        math_Vector&             Solinv,
1121                                                        Standard_Boolean&        IsVtx,
1122                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1123 {
1124   // Le point.
1125   gp_Pnt2d p2drst;
1126   Standard_Real firstrst = rst->FirstParameter();
1127   Standard_Real lastrst = rst->LastParameter();
1128   Standard_Real wpoint = firstrst;
1129   if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
1130   p2drst = rst->Value(wpoint);
1131   gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
1132
1133   FinvP.Set(thepoint);
1134   math_Vector toler(1,3),infb(1,3),supb(1,3);
1135   FinvP.GetTolerance(toler,tolesp);
1136   FinvP.GetBounds(infb,supb);
1137   Solinv(1) = param;
1138   Solinv(2) = sol(1);
1139   Solinv(3) = sol(2);
1140
1141   math_FunctionSetRoot rsnld(FinvP,toler,30);
1142   rsnld.Perform(FinvP,Solinv,infb,supb);
1143   if (!rsnld.IsDone()) {
1144 #if DEB
1145     cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1146 #endif
1147     return Standard_False;
1148   }
1149   rsnld.Root(Solinv);
1150   
1151   if(FinvP.IsSolution(Solinv,tolesp)){
1152     gp_Pnt2d p2d(Solinv(2),Solinv(3));
1153     TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
1154     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1155       return Standard_False;
1156     }
1157     domain2->Initialize(rst);
1158     domain2->InitVertexIterator();
1159     IsVtx = !domain2->MoreVertex();
1160     while (!IsVtx) {
1161       Vtx = domain2->Vertex();
1162       if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
1163           BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1164         IsVtx = Standard_True;
1165       }
1166       else {
1167         domain2->NextVertex();
1168         IsVtx = !domain2->MoreVertex();
1169       }
1170     }
1171     if (!domain2->MoreVertex()) {
1172       IsVtx = Standard_False;
1173     }
1174     return Standard_True;
1175   }
1176   return Standard_False;
1177 }
1178
1179 //=======================================================================
1180 //function : Transition
1181 //purpose  : 
1182 //=======================================================================
1183
1184 void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean          OnFirst,
1185                                               const Handle(Adaptor2d_HCurve2d)& Arc,
1186                                               const Standard_Real             Param,
1187                                               IntSurf_Transition&             TLine,
1188                                               IntSurf_Transition&             TArc) 
1189 {
1190   Standard_Boolean computetranstionaveclacorde = 0;
1191   gp_Vec tgline;
1192   Blend_Point prevprev;
1193
1194   if(previousP.IsTangencyPoint()){
1195     if(line->NbPoints() < 2) return;
1196     computetranstionaveclacorde = 1;
1197     if(sens < 0){
1198       prevprev = line->Point(2);
1199     }
1200     else {
1201       prevprev = line->Point(line->NbPoints() - 1);
1202     }
1203   }
1204   gp_Pnt2d p2d;
1205   gp_Vec2d dp2d;
1206   
1207   gp_Pnt pbid;
1208   gp_Vec d1u,d1v,normale,tgrst;
1209   
1210   Arc->D1(Param,p2d,dp2d);
1211   if (OnFirst) {
1212     surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1213     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
1214     else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
1215   }
1216   else {
1217     surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1218     if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
1219     else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
1220   }
1221   
1222   tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
1223   normale = d1u.Crossed(d1v);
1224   
1225   IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
1226 }
1227
1228 //=======================================================================
1229 //function : MakeExtremity
1230 //purpose  : 
1231 //=======================================================================
1232
1233 void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity&            Extrem,
1234                                                  const Standard_Boolean          OnFirst,
1235                                                  const Handle(Adaptor2d_HCurve2d)& Arc,
1236                                                  const Standard_Real             Param,
1237                                                  const Standard_Boolean          IsVtx,
1238                                                  const Handle(Adaptor3d_HVertex)&  Vtx) 
1239 {
1240   IntSurf_Transition Tline,Tarc;
1241   Standard_Real prm;
1242   Handle(Adaptor3d_TopolTool) Iter;
1243   if (OnFirst) {
1244     Extrem.SetValue(previousP.PointOnS(),
1245                     sol(1),sol(2),
1246                     previousP.Parameter(),tolesp);
1247     if (!previousP.IsTangencyPoint()) 
1248       Extrem.SetTangent(previousP.TangentOnS());
1249     Iter = domain1;
1250   }
1251   else {
1252     Extrem.SetValue(previousP.PointOnC(),
1253                     sol(3),
1254                     previousP.Parameter(),tolesp);
1255     if (!previousP.IsTangencyPoint()) 
1256       Extrem.SetTangent(previousP.TangentOnC());    
1257     Iter = domain2;
1258   }
1259   
1260   Iter->Init();
1261   if (!IsVtx) {
1262     Transition(OnFirst,Arc,Param,Tline,Tarc);
1263     Extrem.AddArc(Arc,Param,Tline,Tarc);
1264   }
1265   else {
1266     Extrem.SetVertex(Vtx);
1267     while (Iter->More()) {
1268 //#ifndef DEB
1269       Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
1270 //#else
1271 //      Handle(Adaptor2d_HCurve2d)& arc = Iter->Value();
1272 //#endif
1273       if (arc != Arc) {
1274         Iter->Initialize(arc);
1275         Iter->InitVertexIterator();
1276         while (Iter->MoreVertex()) {
1277           if (Iter->Identical(Vtx,Iter->Vertex())) {
1278             prm = BRepBlend_BlendTool::Parameter(Vtx,arc);
1279             Transition(OnFirst,arc,prm,Tline,Tarc);
1280             Extrem.AddArc(arc,prm,Tline,Tarc);
1281           }
1282           Iter->NextVertex();
1283         }
1284       }
1285       else {
1286         Transition(OnFirst,arc,Param,Tline,Tarc);
1287         Extrem.AddArc(arc,Param,Tline,Tarc);
1288       }
1289       Iter->Next();
1290     }
1291   }
1292 }
1293
1294 //=======================================================================
1295 //function : CheckDeflectionOnSurf
1296 //purpose  : 
1297 //=======================================================================
1298
1299 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
1300 {
1301   //Controls 3d of Blend_CSWalking.
1302
1303   //rule by tests in U4 corresponds to 11.478 d
1304   const Standard_Real CosRef3D = 0.98;
1305   Standard_Real Cosi=0, Cosi2=0;
1306   Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1307   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1308
1309   gp_Pnt Psurf = CurPoint.PointOnS();
1310   gp_Vec Tgsurf;
1311   if(!curpointistangent){
1312     Tgsurf = CurPoint.TangentOnS();
1313   }
1314   gp_Pnt prevP = previousP.PointOnS();
1315   gp_Vec prevTg;
1316   if(!prevpointistangent){
1317     prevTg = previousP.TangentOnS();
1318   }
1319 #ifndef DEB
1320   Standard_Real Norme,prevNorme = 0.;
1321 #else
1322   Standard_Real Norme,prevNorme;
1323 #endif
1324   gp_Vec Corde(prevP,Psurf);
1325   Norme = Corde.SquareMagnitude();
1326 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1327   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1328
1329   if (Norme <= tolesp*tolesp){
1330     // it can be necessary to force same point
1331     return Blend_SamePoints;
1332   }
1333   if(!prevpointistangent){
1334     if(prevNorme <= tolesp*tolesp) {
1335       return Blend_SamePoints;
1336     }
1337     Cosi = sens*Corde*prevTg;
1338     if (Cosi <0.) { // angle 3d>pi/2. --> return back
1339       return Blend_Backward;
1340     }
1341     
1342     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1343     if (Cosi2 < CosRef3D) { 
1344       return Blend_StepTooLarge;
1345     }
1346   }
1347   
1348   if(!curpointistangent){
1349     // Check if it is necessary to control the sign of prevtg*Tgsurf
1350     Cosi = sens*Corde*Tgsurf;
1351     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1352     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1353       return Blend_StepTooLarge;
1354     }
1355   }  
1356
1357   if(!curpointistangent && !prevpointistangent){
1358     // Estimation of the current arrow
1359     Standard_Real FlecheCourante = 
1360       (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1361     
1362     if (FlecheCourante <= 0.25*fleche*fleche) {
1363       return Blend_StepTooSmall;
1364     }
1365     if (FlecheCourante > fleche*fleche) {
1366       // not too great : 
1367       return Blend_StepTooLarge;
1368     }
1369   }
1370   return Blend_OK;
1371 }
1372
1373
1374 //=======================================================================
1375 //function : CheckDeflectionOnRst
1376 //purpose  : 
1377 //=======================================================================
1378
1379 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
1380 {
1381   //Controls 3D of Blend_CSWalking.
1382
1383   // rule by tests in U4 corresponds to 11.478 d
1384   const Standard_Real CosRef3D = 0.98;
1385   Standard_Real Cosi, Cosi2;
1386   Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1387   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1388
1389   gp_Pnt Psurf = CurPoint.PointOnC();
1390   gp_Vec Tgsurf;
1391   if(!curpointistangent){
1392     Tgsurf = CurPoint.TangentOnC();
1393   }
1394   gp_Pnt prevP = previousP.PointOnC();
1395   gp_Vec prevTg;
1396   if(!prevpointistangent){
1397     prevTg = previousP.TangentOnC();
1398   }
1399 #ifndef DEB
1400   Standard_Real Norme,prevNorme = 0.;
1401 #else
1402   Standard_Real Norme,prevNorme;
1403 #endif
1404   gp_Vec Corde(prevP,Psurf);
1405   Norme = Corde.SquareMagnitude();
1406 //  if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1407   if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1408
1409   if (Norme <= tolesp*tolesp){
1410     // it can be necessary to force same point
1411     return Blend_SamePoints;
1412   }
1413   if(!prevpointistangent){
1414     if(prevNorme <= tolesp*tolesp) {
1415       return Blend_SamePoints;
1416     }
1417     Cosi = sens*Corde*prevTg;
1418     if (Cosi <0.) { // angle 3d>pi/2. --> return back
1419       return Blend_Backward;
1420     }
1421     
1422     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1423     if (Cosi2 < CosRef3D) { 
1424       return Blend_StepTooLarge;
1425     }
1426   }
1427   
1428   if(!curpointistangent){
1429     // Check if it is necessary to control the sign of prevtg*Tgsurf
1430     Cosi = sens*Corde*Tgsurf;
1431     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1432     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1433       return Blend_StepTooLarge;
1434     }
1435   }  
1436
1437   if(!curpointistangent && !prevpointistangent){
1438     // Estimation of the current arrow
1439     Standard_Real FlecheCourante = 
1440       (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1441     
1442     if (FlecheCourante <= 0.25*fleche*fleche) {
1443       return Blend_StepTooSmall;
1444     }
1445     if (FlecheCourante > fleche*fleche) {
1446       // not too great
1447       return Blend_StepTooLarge;
1448     }
1449   }
1450   return Blend_OK;
1451 }
1452
1453 static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1454 {
1455   if(O == TopAbs_FORWARD) return IntSurf_In;
1456   return IntSurf_Out;
1457 }
1458
1459 //=======================================================================
1460 //function : TestArret
1461 //purpose  : 
1462 //=======================================================================
1463
1464 Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
1465                                                      const Standard_Boolean TestDeflection,
1466                                                      const Blend_Status     State) 
1467 {
1468   gp_Pnt pts,ptrst;
1469   gp_Pnt2d pt2drst;
1470   gp_Vec tgs,tgrst;
1471   gp_Vec2d tg2ds,tg2drst;
1472   Blend_Status StateS,StateRst;
1473 #ifndef DEB
1474   IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
1475 #else
1476   IntSurf_TypeTrans tras,trarst;
1477 #endif
1478   Blend_Point curpoint;
1479
1480   if (Func.IsSolution(sol,tolesp)) {
1481     Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1482     pts = Func.PointOnS();
1483     ptrst = Func.PointOnRst();
1484     pt2drst = Func.Pnt2dOnRst();
1485     if(curpointistangent){
1486       curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1487                         pt2drst.X(),pt2drst.Y(),sol(3));
1488     }
1489     else{
1490       tgs     = Func.TangentOnS();
1491       tgrst   = Func.TangentOnRst();
1492       tg2ds   = Func.Tangent2dOnS();
1493       tg2drst = Func.Tangent2dOnRst();
1494
1495       curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1496                         pt2drst.X(),pt2drst.Y(),sol(3),
1497                         tgs,tgrst,tg2ds,tg2drst);
1498     }
1499     if (TestDeflection) {
1500       StateS = CheckDeflectionOnSurf(curpoint);
1501       StateRst = CheckDeflectionOnRst(curpoint);
1502     }
1503     else {
1504       StateS = StateRst = Blend_OK;
1505     }
1506     if (StateS == Blend_Backward) {
1507       StateS = Blend_StepTooLarge;
1508       rebrou= Standard_True;
1509     }
1510     if (StateRst == Blend_Backward) {
1511       StateRst = Blend_StepTooLarge;
1512       rebrou = Standard_True;
1513     }
1514     if (StateS == Blend_StepTooLarge ||
1515         StateRst == Blend_StepTooLarge) {
1516       return Blend_StepTooLarge;
1517     }
1518
1519     if (!comptra && !curpointistangent) {
1520       gp_Vec tgsecs,nors;
1521       Func.Decroch(sol,nors,tgsecs);
1522       nors.Normalize();
1523       Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
1524       if (Abs(testra) > tolesp) {
1525         if (testra < 0.) {
1526           tras = IntSurf_In;
1527         }
1528         else if (testra >0.) {
1529           tras = IntSurf_Out;
1530         }
1531         gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
1532         rst->D1(sol(3),p2drstref,tg2drstref);
1533         testra = tg2drst.Dot(tg2drstref);
1534         TopAbs_Orientation Or = domain2->Orientation(rst);
1535         if (Abs(testra) > 1.e-8) {
1536           if (testra < 0.) {
1537             trarst = ConvOrToTra(TopAbs::Reverse(Or));
1538           }
1539           else if (testra >0.) {
1540             trarst = ConvOrToTra(Or);
1541           }
1542           comptra = Standard_True;
1543           line->Set(tras,trarst);
1544         }
1545       }
1546     }
1547     if (StateS == Blend_OK ||
1548         StateRst == Blend_OK ) {
1549       previousP = curpoint;
1550       return State;
1551     }
1552     if (StateS == Blend_StepTooSmall &&
1553         StateRst == Blend_StepTooSmall) {
1554       previousP = curpoint;
1555       if (State == Blend_OK) {
1556         return Blend_StepTooSmall;
1557       }
1558       else {
1559         return State;
1560       }
1561     }
1562     if (State == Blend_OK) {
1563       return Blend_SamePoints;
1564     }
1565     else {
1566       return State;
1567     }
1568   }
1569   return Blend_StepTooLarge;
1570 }
1571
1572 //=======================================================================
1573 //function : CheckInside
1574 //purpose  : 
1575 //=======================================================================
1576
1577 Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
1578                                                            TopAbs_State&          SituOnC,
1579                                                            TopAbs_State&          SituOnS,
1580                                                            Standard_Boolean&      Decroch)
1581 {
1582   math_Vector tolerance(1,3);
1583   Func.GetTolerance(tolerance,tolesp);
1584   //face pcurve.
1585   Standard_Real w = sol(3);
1586   if(w < rst->FirstParameter() - tolerance(3)||
1587      w > rst->LastParameter() + tolerance(3)){
1588     SituOnC = TopAbs_OUT;
1589   }
1590   else if (w > rst->FirstParameter() &&
1591            w < rst->LastParameter()){
1592     SituOnC = TopAbs_IN;
1593   }
1594   else SituOnC = TopAbs_ON;
1595
1596   //face surface
1597   gp_Pnt2d p2d(sol(1),sol(2));
1598   SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
1599
1600   //lost contact
1601   gp_Vec tgs,nors;
1602   Decroch = Func.Decroch(sol,tgs,nors);
1603
1604   return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);
1605 }
1606