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