Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BRepBlend / BRepBlend_RstRstLineBuilder.cxx
1 // File:        BRepBlend_RstRstLineBuilder.cxx
2 // Created:     Fri Jan 24 10:39:44 1997
3 // Author:      Jacques GOUSSARD
4 // Author:      Laurent BOURESCHE
5 //              <lbo@pomalox.paris1.matra-dtv.fr>
6
7 #include <stdio.h>
8
9 #include <BRepBlend_RstRstLineBuilder.ixx>
10 #include <BRepBlend_BlendTool.hxx>
11 #include <TopAbs.hxx>
12 #include <IntSurf.hxx>
13 #include <math_FunctionSetRoot.hxx>
14 #include <gp_Pnt2d.hxx>
15 #include <gp_Pnt.hxx>
16 #include <gp_Vec2d.hxx>
17 #include <gp_Vec.hxx>
18
19 #ifdef DEB
20 #include <TColStd_Array1OfInteger.hxx>
21 #include <TColStd_Array1OfReal.hxx>
22 #include <TColgp_Array1OfPnt2d.hxx>
23 #include <TColgp_Array1OfVec.hxx>
24 #include <TColgp_Array1OfVec2d.hxx>
25 #include <TColgp_Array1OfPnt.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #ifdef DRAW
28 #include <DrawTrSurf.hxx>
29 #endif
30 static Standard_Integer IndexOfSection = 0;
31 extern Standard_Boolean Blend_GettraceDRAWSECT(); 
32
33 //-----------------------------------------------------
34 // Pour debug : visualisation de la section
35 static Standard_Boolean BBPP(const Standard_Real param,
36                              Blend_RstRstFunction& Func,
37                              const math_Vector& sol,
38                              const Standard_Real tol,
39                              Blend_Point& BP)
40 {
41   if(!Func.IsSolution(sol,tol)) return 0;
42   gp_Pnt pntrst1    = Func.PointOnRst1();
43   gp_Pnt pntrst2    = Func.PointOnRst2();
44   gp_Pnt2d p2drst1  = Func.Pnt2dOnRst1();
45   gp_Pnt2d p2drst2  = Func.Pnt2dOnRst2();
46   Standard_Real w1  = Func.ParameterOnRst1();
47   Standard_Real w2  = Func.ParameterOnRst2();
48   BP = Blend_Point(pntrst1, pntrst2, param,
49                    p2drst1.X(), p2drst1.Y(),
50                    p2drst2.X(), p2drst2.Y(), w1, w2);
51   return 1;
52 }
53
54
55 //-----------------------------------------------------
56 static void tracederiv(Blend_RstRstFunction& Func,
57                        const Blend_Point& BP1,
58                        const Blend_Point& BP2)
59 {
60   Standard_Integer hp,hk,hd,hp2d,i;
61   Func.GetShape(hp,hk,hd,hp2d);
62   TColgp_Array1OfPnt TP1(1,hp);
63   TColgp_Array1OfVec TDP1(1,hp);
64   TColgp_Array1OfPnt2d TP2d1(1,hp2d);
65   TColgp_Array1OfVec2d TDP2d1(1,hp2d);
66   TColStd_Array1OfReal TW1(1,hp);
67   TColStd_Array1OfReal TDW1(1,hp);
68   Func.Section(BP1, TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
69
70   TColgp_Array1OfPnt TP2(1,hp);
71   TColgp_Array1OfVec TDP2(1,hp);
72   TColgp_Array1OfPnt2d TP2d2(1,hp2d);
73   TColgp_Array1OfVec2d TDP2d2(1,hp2d);
74   TColStd_Array1OfReal TW2(1,hp);
75   TColStd_Array1OfReal TDW2(1,hp);
76   Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
77
78   Standard_Real param1 = BP1.Parameter();
79   Standard_Real param2 = BP2.Parameter();
80   Standard_Real scal = 1./ (param1 - param2);
81
82   cout<<endl;
83   cout<<"controle des derivees au point : "<<param1<<endl;
84
85   for(i = 1; i <= hp; i++){
86     cout<<endl;
87     cout<<"point : "<<i<<endl;
88     cout<<"dx calcule : "<<TDP1(i).X()<<endl;
89     cout<<"dx estime  : "<<scal*(TP1(i).X()-TP2(i).X())<<endl;
90     cout<<"dy calcule : "<<TDP1(i).Y()<<endl;
91     cout<<"dy estime  : "<<scal*(TP1(i).Y()-TP2(i).Y())<<endl;
92     cout<<"dz calcule : "<<TDP1(i).Z()<<endl;
93     cout<<"dz estime  : "<<scal*(TP1(i).Z()-TP2(i).Z())<<endl;
94     cout<<"dw calcule : "<<TDW1(i)<<endl;
95     cout<<"dw estime  : "<<scal*(TW1(i)-TW2(i))<<endl;
96   }
97   for(i = 1; i <= hp2d; i++){
98     cout<<endl;
99     cout<<"point 2d : "<<i<<endl;
100     cout<<"dx calcule : "<<TDP2d1(i).X()<<endl;
101     cout<<"dx estime  : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<endl;
102     cout<<"dy calcule : "<<TDP2d1(i).Y()<<endl;
103     cout<<"dy estime  : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<endl;
104   }
105 }
106
107
108 //-----------------------------------------------------
109 static void Drawsect(const Standard_Real param,
110                      Blend_RstRstFunction& Func)
111 {
112   gp_Pnt pntrst1   = Func.PointOnRst1();
113   gp_Pnt pntrst2   = Func.PointOnRst2();
114   gp_Pnt2d p2drst1 = Func.Pnt2dOnRst1();
115   gp_Pnt2d p2drst2 = Func.Pnt2dOnRst2();
116   Standard_Real u  = Func.ParameterOnRst1();
117   Standard_Real v  = Func.ParameterOnRst2();
118   Blend_Point BP(pntrst1, pntrst2, param,
119                  p2drst1.X(), p2drst1.Y(),
120                  p2drst2.X(), p2drst2.Y(), u, v);
121   Standard_Integer hp,hk,hd,hp2d;
122   Func.GetShape(hp,hk,hd,hp2d);
123   TColStd_Array1OfReal TK(1,hk);
124   Func.Knots(TK);
125   TColStd_Array1OfInteger TMul(1,hk);
126   Func.Mults(TMul);
127   TColgp_Array1OfPnt TP(1,hp);
128   TColgp_Array1OfPnt2d TP2d(1,hp2d);
129   TColStd_Array1OfReal TW(1,hp);
130   Func.Section(BP,TP,TP2d,TW);
131   Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
132     (TP,TW,TK,TMul,hd);
133   IndexOfSection++;
134 #ifdef DRAW
135   char tname[100];
136   Standard_CString name = tname ;
137   sprintf(name,"%s_%d","Section",IndexOfSection);
138   DrawTrSurf::Set(name,sect);
139 #endif
140 }
141 #endif
142
143 //=======================================================================
144 //function : BRepBlend_RstRstLineBuilder
145 //purpose  : 
146 //=======================================================================
147
148 BRepBlend_RstRstLineBuilder::BRepBlend_RstRstLineBuilder
149 (const Handle(Adaptor3d_HSurface)&  Surf1,
150  const Handle(Adaptor2d_HCurve2d)&  Rst1,
151  const Handle(Adaptor3d_TopolTool)& Domain1,
152  const Handle(Adaptor3d_HSurface)&  Surf2,
153  const Handle(Adaptor2d_HCurve2d)&  Rst2,
154  const Handle(Adaptor3d_TopolTool)& Domain2):
155  sol(1,2), surf1(Surf1), domain1(Domain1),
156  surf2(Surf2), domain2(Domain2), rst1(Rst1), rst2(Rst2)
157 {
158 }
159
160 //=======================================================================
161 //function : Perform
162 //purpose  : lance le processus de cheminement
163 //=======================================================================
164
165 void BRepBlend_RstRstLineBuilder::Perform(Blend_RstRstFunction&   Func,
166                                           Blend_SurfCurvFuncInv& Finv1,
167                                           Blend_CurvPointFuncInv& FinvP1,
168                                           Blend_SurfCurvFuncInv& Finv2,
169                                           Blend_CurvPointFuncInv& FinvP2,
170                                           const Standard_Real     Pdep,
171                                           const Standard_Real     Pmax,
172                                           const Standard_Real     MaxStep,
173                                           const Standard_Real     TolGuide,
174                                           const math_Vector&      ParDep,
175                                           const Standard_Real     Tolesp,
176                                           const Standard_Real     Fleche,
177                                           const Standard_Boolean  Appro) 
178 {
179   done       = Standard_False;
180   iscomplete = Standard_False;
181   comptra    = Standard_False;
182   line       = new BRepBlend_Line();
183   tolesp     = Abs(Tolesp);
184   tolgui     = Abs(TolGuide);
185   fleche     = Abs(Fleche);
186   rebrou     = Standard_False;
187   pasmax     = Abs(MaxStep);
188   
189   if (Pmax - Pdep >= 0.) {
190     sens = 1.;
191   }
192   else {
193     sens = -1.;
194   }
195   
196   Blend_Status State;
197   
198   param = Pdep;
199   Func.Set(param);
200   
201   if (Appro) {
202     TopAbs_State siturst1, siturst2;
203     Blend_DecrochStatus decroch;
204     math_Vector tolerance(1, 2), infbound(1, 2), supbound(1, 2);
205     Func.GetTolerance(tolerance, tolesp);
206     Func.GetBounds(infbound, supbound);
207     math_FunctionSetRoot rsnld(Func, tolerance, 30);
208     
209     rsnld.Perform(Func, ParDep, infbound, supbound);
210     
211     if (!rsnld.IsDone()) {
212       return;
213     }
214     rsnld.Root(sol);
215     if (!CheckInside(Func, siturst1, siturst2, decroch)) {
216       return;
217     }
218   }
219   else {
220     sol = ParDep;
221   }
222
223   State = TestArret(Func, Standard_False, Blend_OK);
224   if (State != Blend_OK) {
225     return;
226   }
227 #ifdef DEB
228   if (Blend_GettraceDRAWSECT()){
229     Drawsect(param, Func);
230   }
231 #endif
232   // Mettre a jour la ligne.
233   line->Append(previousP);
234   Standard_Real U, V;
235   U = previousP.ParameterOnC1();
236   V = previousP.ParameterOnC2();
237   BRepBlend_Extremity ptf1 (previousP.PointOnC1(),
238                             U, previousP.Parameter(),tolesp);
239   BRepBlend_Extremity ptf2 (previousP.PointOnC2(),
240                             V, previousP.Parameter(),tolesp);
241   if (!previousP.IsTangencyPoint()) {
242     ptf1.SetTangent(previousP.TangentOnC1());
243     ptf2.SetTangent(previousP.TangentOnC2());
244   }
245   
246   if (sens > 0.) {
247     line->SetStartPoints(ptf1, ptf2);
248   }
249   else {
250     line->SetEndPoints(ptf1, ptf2);
251   }
252
253   InternalPerform(Func, Finv1, FinvP1, Finv2, FinvP2, Pmax);
254   done = Standard_True;
255 }
256
257 //=======================================================================
258 //function : PerformFirstSection
259 //purpose  : Creation de la premiere section
260 //=======================================================================
261
262 Standard_Boolean BRepBlend_RstRstLineBuilder::PerformFirstSection
263 (Blend_RstRstFunction&   Func,
264  Blend_SurfCurvFuncInv&  Finv1,
265  Blend_CurvPointFuncInv& FinvP1,
266  Blend_SurfCurvFuncInv&  Finv2,
267  Blend_CurvPointFuncInv& FinvP2,
268  const Standard_Real     Pdep,
269  const Standard_Real     Pmax,
270  const math_Vector&      ParDep,
271  const Standard_Real     Tolesp,
272  const Standard_Real     TolGuide,
273  const Standard_Boolean  RecRst1,
274  const Standard_Boolean  RecP1,
275  const Standard_Boolean  RecRst2,
276  const Standard_Boolean  RecP2,
277  Standard_Real&          Psol,   
278  math_Vector&            ParSol)
279 {
280   done       = Standard_False;
281   iscomplete = Standard_False;
282   comptra    = Standard_False;
283   line       = new BRepBlend_Line();
284   tolesp     = Abs(Tolesp);
285   tolgui     = Abs(TolGuide);
286   rebrou     = Standard_False;
287   
288   if (Pmax - Pdep >= 0.) {
289     sens = 1.;
290   }
291   else {
292     sens = -1.;
293   }
294   
295   Standard_Boolean recadp1, recadp2, recadrst1, recadrst2;
296   Standard_Real wp1, wp2, wrst1, wrst2;
297 #ifndef DEB
298   Blend_Status State = Blend_OnRst12;
299   Standard_Real trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
300 #else
301   Blend_Status State;
302   Standard_Real trst11, trst12, trst21, trst22;
303 #endif
304   math_Vector infbound(1, 2), supbound(1, 2), tolerance(1, 2);
305   math_Vector solinvp1(1, 2), solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
306   Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2, Vtxc;
307   Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
308   Handle(Adaptor2d_HCurve2d) Arc;
309   wp1   = wp2 = wrst1 = wrst2 = Pmax;
310   param = Pdep;
311   Func.Set(param);
312   Func.GetTolerance(tolerance, tolesp);
313   Func.GetBounds(infbound, supbound);
314
315   math_FunctionSetRoot rsnld(Func, tolerance, 30);
316   rsnld.Perform(Func, ParDep, infbound, supbound);
317   if (!rsnld.IsDone()) return Standard_False;
318   rsnld.Root(sol);
319
320   recadrst1 = RecRst1 && Recadre1(Func, Finv1, solinvrst1, IsVtxrst1, Vtxrst1);
321   if (recadrst1) {
322     wrst1 = solinvrst1(1);
323   }
324
325   recadp1 = RecP1 && Recadre1(FinvP1, solinvp1, IsVtxp1, Vtxp1);
326   if (recadp1) {
327     wp1 = solinvp1(1);
328   }
329
330   recadrst2 = RecRst2 && Recadre2(Func, Finv2, solinvrst2, IsVtxrst2, Vtxrst2);
331   if (recadrst2) {
332     wrst2 = solinvrst2(1);
333   }
334
335   recadp2 = RecP2 && Recadre2(FinvP2, solinvp2, IsVtxp2, Vtxp2);
336   if (recadp2) {
337     wp2 = solinvp2(1);
338   }
339
340   if (!recadrst1 && !recadp1 && !recadrst2 && !recadp2) return Standard_False;
341
342
343   // on regarde si on a decroche ou sorti du domaine 1
344   if (recadp1 && recadrst1) {
345     if (sens * (wrst1 - wp1) > tolgui){ //on sort du domaine d abord
346       wrst1     = wp1;
347       trst12    = solinvp1(2);
348       trst11    = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
349       IsVtxrst2 = IsVtxp1;
350       Vtxrst2   = Vtxp1;
351       recadrst1 = Standard_False;
352     }
353     else { // on a decroche
354       trst11  = solinvrst1(3);
355       trst12  = solinvrst1(2);
356       recadp1 = Standard_False;
357     }
358   }
359   else if (recadp1) {
360     wrst1     = wp1;
361     trst12    = solinvp1(2);
362     trst11    = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
363     IsVtxrst1 = IsVtxp1;
364     Vtxrst1   = Vtxp1;
365   }
366   else if (recadrst1) {
367     trst11  = solinvrst1(3);
368     trst12  = solinvrst1(2);
369   }
370
371   // on regarde si on a decrocher ou sortie du domaine 2
372   if (recadp2 && recadrst2) {
373     if (sens * (wrst2 - wp2) > tolgui) { //on sort du domaine d abord
374       wrst2     = wp2;
375       trst21    = solinvp2(2);
376       trst22    = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
377       IsVtxrst2 = IsVtxp2;
378       Vtxrst2   = Vtxp2;
379       recadrst2 = Standard_False;
380     }
381     else { 
382       trst22  = solinvrst2(3);
383       trst21  = solinvrst2(2);
384       recadp2 = Standard_False;
385     }
386   }
387   else if (recadp2) {
388     wrst2     = wp2;
389     trst21    = solinvp2(2);
390     trst22    = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
391     IsVtxrst2 = IsVtxp2;
392     Vtxrst2   = Vtxp2;
393   }
394   else if (recadrst2) {
395     trst22  = solinvrst2(3);
396     trst21  = solinvrst2(2);
397   }
398
399   // on regarde sur laquelle des courbes on decroche en premier
400   if (recadrst1 && recadrst2) {
401     if (Abs(wrst1 - wrst2) < tolgui) {
402       State    = Blend_OnRst12;
403       param    = 0.5 * (wrst1 + wrst2);
404       sol(1)   = trst11;
405       sol(2)   = trst22;
406     }
407     else if (sens * (wrst1 - wrst2) < 0) {
408       // on decroche sur Rst1
409       State   = Blend_OnRst1;
410       param   = wrst1;
411       sol(1)  = trst11;
412       sol(2)  = trst12;
413     }
414     else {
415       // on decroche sur rst2
416       State   = Blend_OnRst2;
417       param   = wrst2;
418       sol(1)  = trst21;
419       sol(2)  = trst22;
420     }
421   Func.Set(param);
422   }
423   else if (recadrst1) {
424     // sol sur rst1
425     State   = Blend_OnRst1;
426     param   = wrst1;
427     sol(1)  = trst11;
428     sol(2)  = trst12;
429     Func.Set(param);
430   }
431   else if (recadrst2) {
432     // sol sur rst2
433     State   = Blend_OnRst2;
434     param   = wrst2;
435     sol(1)  = trst21;
436     sol(2)  = trst22;
437     Func.Set(param);
438   }
439   // on regarde sur laquelle des courbes on sort en premier
440   else if (recadp1 && recadp2) {
441     if (Abs(wrst1 - wrst2) < tolgui) {
442       State  = Blend_OnRst12;
443       param  = 0.5 * (wrst1 + wrst2);
444       sol(1) = trst11;
445       sol(2) = trst22;
446     }
447     else if (sens * (wrst1 - wrst2) < 0) {
448       // sol sur Rst1
449       State  = Blend_OnRst1;
450       param  = wrst1;
451       sol(1) = trst11;
452       sol(2) = trst12;
453     }
454     else {
455       // sol sur rst2
456       State  = Blend_OnRst2;
457       param  = wrst2;
458       sol(1) = trst21;
459       sol(2) = trst22;
460     }
461     Func.Set(param);
462   }
463   else if (recadp1) {
464     // sol sur rst1
465     State  = Blend_OnRst1;
466     param  = wrst1;
467     sol(1) = trst11;
468     sol(2) = trst12;
469     Func.Set(param);
470   }
471   else if (recadp2) {
472     // sol sur rst2
473     State  = Blend_OnRst2;
474     param  = wrst2;
475     sol(1) = trst21;
476     sol(2) = trst22;
477     Func.Set(param);
478   }
479
480   State  = TestArret(Func, Standard_False, State);
481   Psol   = param;
482   ParSol = sol;
483   return Standard_True;
484 }  
485
486 //=======================================================================
487 //function : Complete
488 //purpose  : 
489 //=======================================================================
490
491 Standard_Boolean BRepBlend_RstRstLineBuilder::Complete(Blend_RstRstFunction&   Func,
492                                                        Blend_SurfCurvFuncInv&  Finv1,
493                                                        Blend_CurvPointFuncInv& FinvP1,
494                                                        Blend_SurfCurvFuncInv&  Finv2,
495                                                        Blend_CurvPointFuncInv& FinvP2, 
496                                                        const Standard_Real     Pmin) 
497 {
498   if (!done) {StdFail_NotDone::Raise();}
499   if (iscomplete) {return Standard_True;}
500   if (sens >0.) {
501     previousP = line->Point(1);
502   }
503   else {
504     previousP = line->Point(line->NbPoints());
505   }
506   sens   = -sens;
507   param  = previousP.Parameter();
508   sol(1) = previousP.ParameterOnC1();
509   sol(2) = previousP.ParameterOnC2();
510
511   InternalPerform(Func, Finv1, FinvP1, Finv2, FinvP2, Pmin);
512   iscomplete = Standard_True;
513   return Standard_True;
514 }
515
516 //=======================================================================
517 //function : InternalPerform
518 //purpose  : algorithme de cheminement sauf aux extremites
519 //=======================================================================
520
521 void BRepBlend_RstRstLineBuilder::InternalPerform(Blend_RstRstFunction&   Func,
522                                                   Blend_SurfCurvFuncInv&  Finv1,
523                                                   Blend_CurvPointFuncInv& FinvP1,
524                                                   Blend_SurfCurvFuncInv&  Finv2,
525                                                   Blend_CurvPointFuncInv& FinvP2,
526                                                   const Standard_Real     Bound) 
527 {
528   Standard_Real stepw  = pasmax;
529   Standard_Integer nbp = line->NbPoints();
530   if(nbp >= 2){ //On reprend le dernier step s il n est pas trop petit.
531     if(sens < 0.){
532       stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
533     }
534     else{
535       stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
536     }
537     stepw = Max(stepw, 100. * tolgui);
538   }
539   Standard_Real parprec = param;
540   if (sens* (parprec - Bound) >= -tolgui) {
541     return;
542   }
543 #ifndef DEB
544   Blend_Status State = Blend_OnRst12;
545   Standard_Real trst11 = 0., trst12 = 0., trst21 = 0., trst22 = 0.;
546 #else
547   Blend_Status State;
548   Standard_Real trst11, trst12, trst21, trst22;
549 #endif
550   TopAbs_State situonc1, situonc2;
551   Blend_DecrochStatus decroch;
552   Standard_Boolean Arrive, recadp1, recadp2, recadrst1, recadrst2, echecrecad;
553   Standard_Real wp1, wp2, wrst1, wrst2;
554   math_Vector infbound(1, 2), supbound(1, 2);
555   math_Vector parinit(1, 2), tolerance(1, 2);
556   math_Vector solinvp1(1, 2),  solinvp2(1, 2), solinvrst1(1, 3), solinvrst2(1, 3);
557   Handle(Adaptor3d_HVertex) Vtxp1, Vtxp2, Vtxrst1, Vtxrst2;
558   Standard_Boolean IsVtxp1 = 0, IsVtxp2 = 0, IsVtxrst1 = 0, IsVtxrst2 = 0;
559   BRepBlend_Extremity Extrst1, Extrst2;
560
561   //IntSurf_Transition Tline, Tarc;
562
563   Func.GetTolerance(tolerance, tolesp);
564   Func.GetBounds(infbound, supbound);
565
566   math_FunctionSetRoot rsnld(Func, tolerance, 30);
567   parinit = sol;
568
569   Arrive = Standard_False;
570   param = parprec + sens * stepw;
571   if (sens * (param - Bound) > 0.) {
572     stepw = sens * (Bound - parprec) * 0.5;
573     param = parprec + sens * stepw;
574   }
575
576   while (!Arrive) {
577     Standard_Boolean bonpoint = 1;
578 #if 0
579     //debdebdebdebdebdeb
580     Func.Set(param);
581     rsnld.Perform(Func, parinit, infbound, supbound);
582     if (rsnld.IsDone()) {
583       rsnld.Root(sol);
584       Blend_Point bp1;
585       if(BBPP(param, Func, sol, tolesp, bp1)){
586         Standard_Real dw = 1.e-10;
587         Func.Set(param + dw);
588         rsnld.Perform(Func, parinit, infbound, supbound);
589         if (rsnld.IsDone()) {
590           rsnld.Root(sol);
591           Blend_Point bp2;
592           if(BBPP(param + dw, Func, sol, tolesp, bp2)){
593             tracederiv(Func, bp1, bp2);
594           }
595         }
596       }
597     }
598     //debdebdebdebdebdeb
599 #endif
600     Func.Set(param);
601     rsnld.Perform(Func, parinit, infbound, supbound);
602     
603     if (rsnld.IsDone()) {
604       rsnld.Root(sol);
605       if(!CheckInside(Func, situonc1, situonc2, decroch) && line->NbPoints() == 1){
606         State = Blend_StepTooLarge;
607         bonpoint = 0;
608       }
609     }
610     else {
611       State = Blend_StepTooLarge;
612       bonpoint = 0;
613     }
614     if(bonpoint){
615       wp1     = wp2 = wrst1 = wrst2 = Bound;
616       recadp1 = recadp2 = recadrst1 = recadrst2 = Standard_False;
617       echecrecad = Standard_False;
618       if (situonc1 != TopAbs_IN) {
619         // pb inverse rst/rst
620         recadp1 = Recadre1(FinvP1, solinvp1, IsVtxp1, Vtxp1);
621         if (recadp1) {
622           wp1 = solinvp1(1);
623         }
624         else {
625           echecrecad = Standard_True;
626         }
627       }
628
629       if (situonc2 != TopAbs_IN) {
630         // pb inverse point/surf
631         recadp2 = Recadre2(FinvP2, solinvp2, IsVtxp2, Vtxp2);
632         if (recadp2) {
633           wp2 = solinvp2(1);
634         }
635         else {
636           echecrecad = Standard_True;
637         }
638       }
639
640       if (decroch == Blend_DecrochRst1 || decroch == Blend_DecrochBoth) {
641         // pb inverse rst1/surf1
642         recadrst1 = Recadre1(Func, Finv1, solinvrst1, IsVtxrst1, Vtxrst1);
643         if (recadrst1) {
644           wrst1 = solinvrst1(1);
645         }
646         else {
647           echecrecad = Standard_True;
648         }
649       }
650
651       if (decroch == Blend_DecrochRst2 || decroch == Blend_DecrochBoth) {
652         // pb inverse rst2/surf2
653         recadrst2 = Recadre2(Func, Finv2, solinvrst2, IsVtxrst2, Vtxrst2);
654         if (recadrst2) {
655           wrst2 = solinvrst2(1);
656         }
657         else {
658           echecrecad = Standard_True;
659         }
660       }
661
662       decroch = Blend_NoDecroch;
663       if (recadp1 || recadp2 || recadrst1 || recadrst2) echecrecad = Standard_False;
664  
665       if (!echecrecad) {
666         // on regarde si on a decroche ou sorti du domaine 1
667         if (recadp1 && recadrst1) {
668           if (sens * (wrst1 - wp1) > tolgui){ //on sort du domaine d abord
669             wrst1     = wp1;
670             trst12    = solinvp1(2);
671             trst11    = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
672             IsVtxrst2 = IsVtxp1;
673             Vtxrst2   = Vtxp1;
674             recadrst1 = Standard_False;
675           }
676           else { // on a decroche
677             trst11  = solinvrst1(3);
678             trst12  = solinvrst1(2);
679             recadp1 = Standard_False;
680           }
681         }
682         else if (recadp1) {
683           wrst1     = wp1;
684           trst12    = solinvp1(2);
685           trst11    = BRepBlend_BlendTool::Parameter(Vtxp1, rst1);
686           IsVtxrst1 = IsVtxp1;
687           Vtxrst1   = Vtxp1;
688         }
689         else if (recadrst1) {
690           trst11  = solinvrst1(3);
691           trst12  = solinvrst1(2);
692         }
693
694         // on regarde si on a decrocher ou sortie du domaine 2
695         if (recadp2 && recadrst2) {
696           if (sens * (wrst2 - wp2) > tolgui) { //on sort du domaine d abord
697             wrst2     = wp2;
698             trst21    = solinvp2(2);
699             trst22    = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
700             IsVtxrst2 = IsVtxp2;
701             Vtxrst2   = Vtxp2;
702             recadrst2 = Standard_False;
703           }
704           else { 
705             trst22  = solinvrst2(3);
706             trst21  = solinvrst2(2);
707             recadp2 = Standard_False;
708           }
709         }
710         else if (recadp2) {
711           wrst2     = wp2;
712           trst21    = solinvp2(2);
713           trst22    = BRepBlend_BlendTool::Parameter(Vtxp2, rst2);
714           IsVtxrst2 = IsVtxp2;
715           Vtxrst2   = Vtxp2;
716         }
717         else if (recadrst2) {
718           trst22  = solinvrst2(3);
719           trst21  = solinvrst2(2);
720         }
721
722         // on regarde sur laquelle des courbes on decroche en premier
723         if (recadrst1 && recadrst2) {
724           if (Abs(wrst1 - wrst2) < tolgui) {
725             State    = Blend_OnRst12;
726             decroch  = Blend_DecrochBoth;
727             param    = 0.5 * (wrst1 + wrst2);
728             sol(1)   = trst11;
729             sol(2)   = trst22;
730           }
731           else if (sens * (wrst1 - wrst2) < 0) {
732             // on decroche sur Rst1
733             State   = Blend_OnRst1;
734             decroch = Blend_DecrochRst1; 
735             param   = wrst1;
736             sol(1)  = trst11;
737             sol(2)  = trst12;
738           }
739           else {
740             // on decroche sur rst2
741             State   = Blend_OnRst2;
742             decroch = Blend_DecrochRst2;
743             param   = wrst2;
744             sol(1)  = trst21;
745             sol(2)  = trst22;
746           }
747           Func.Set(param);
748         }
749         else if (recadrst1) {
750           // sol sur rst1
751           State   = Blend_OnRst1;
752           decroch = Blend_DecrochRst1;
753           param   = wrst1;
754           sol(1)  = trst11;
755           sol(2)  = trst12;
756           Func.Set(param);
757         }
758         else if (recadrst2) {
759           // sol sur rst2
760           State   = Blend_OnRst2;
761           decroch = Blend_DecrochRst2;
762           param   = wrst2;
763           sol(1)  = trst21;
764           sol(2)  = trst22;
765           Func.Set(param);
766         }
767         // on regarde sur laquelle des courbes on sort en premier
768         else if (recadp1 && recadp2) {
769           if (Abs(wrst1 - wrst2) < tolgui) {
770             State  = Blend_OnRst12;
771             param  = 0.5 * (wrst1 + wrst2);
772             sol(1) = trst11;
773             sol(2) = trst22;
774           }
775           else if (sens * (wrst1 - wrst2) < 0) {
776             // sol sur Rst1
777             State  = Blend_OnRst1;
778             param  = wrst1;
779             sol(1) = trst11;
780             sol(2) = trst12;
781           }
782           else {
783             // sol sur rst2
784             State  = Blend_OnRst2;
785             param  = wrst2;
786             sol(1) = trst21;
787             sol(2) = trst22;
788           }
789           Func.Set(param);
790         }
791         else if (recadp1) {
792           // sol sur rst1
793           State  = Blend_OnRst1;
794           param  = wrst1;
795           sol(1) = trst11;
796           sol(2) = trst12;
797           Func.Set(param);
798         }
799         else if (recadp2) {
800           // sol sur rst2
801           State  = Blend_OnRst2;
802           param  = wrst2;
803           sol(1) = trst21;
804           sol(2) = trst22;
805           Func.Set(param);
806         }
807         else {
808           State = Blend_OK;
809         }
810
811         State = TestArret(Func, Standard_True, State);
812       }
813       else{
814         // echec recadrage. On sort avec PointsConfondus
815         cout<<"echec recadrage"<<endl;
816         State = Blend_SamePoints;
817       }
818     }
819     
820     switch (State) {
821     case Blend_OK :
822       {
823 #ifdef DEB
824         if (Blend_GettraceDRAWSECT()){
825           Drawsect(param, Func);
826         }
827 #endif
828         // Mettre a jour la ligne.
829         if (sens > 0.) {
830           line->Append(previousP);
831         }
832         else {
833           line->Prepend(previousP);
834         }
835         parinit = sol;
836         parprec = param;
837         
838         if (param == Bound) {
839           Arrive = Standard_True;
840           Extrst1.SetValue(previousP.PointOnC1(),
841                            previousP.ParameterOnC1(),
842                            previousP.Parameter(), tolesp);
843           MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
844           // Indiquer que fin sur Bound.
845         }
846         else {
847           param = param + sens * stepw;
848           if (sens * (param - Bound) > - tolgui) {
849             param = Bound;
850           }
851         }
852       }
853       break;
854       
855     case Blend_StepTooLarge :
856       {
857         stepw = stepw / 2.;
858         if (Abs(stepw) < tolgui) {
859           Extrst1.SetValue(previousP.PointOnC1(),
860                            previousP.ParameterOnC1(),
861                            previousP.Parameter(), tolesp);
862           Extrst2.SetValue(previousP.PointOnC2(),
863                            previousP.ParameterOnC2(),
864                            previousP.Parameter(), tolesp);
865           Arrive = Standard_True;
866           if (line->NbPoints()>=2) {
867             // Indiquer qu on s arrete en cours de cheminement
868             cout<<"On n avance plus dans le cheminement"<<endl;
869           }
870         }
871         else {
872           param = parprec + sens * stepw;  // on ne risque pas de depasser Bound.
873         }
874       }
875       break;
876       
877     case Blend_StepTooSmall :
878       {
879 #ifdef DEB
880         if (Blend_GettraceDRAWSECT()){
881           Drawsect(param,Func);
882         }
883 #endif
884         // Mettre a jour la ligne.
885         if (sens > 0.) {
886           line->Append(previousP);
887         }
888         else {
889           line->Prepend(previousP);
890         }
891         parinit = sol;
892         parprec = param;
893         
894         stepw   = Min(1.5 * stepw, pasmax);
895         if (param == Bound) {
896           Arrive = Standard_True;
897           Extrst1.SetValue(previousP.PointOnC1(),
898                            previousP.ParameterOnC1(),
899                            previousP.Parameter(), tolesp);
900           MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
901           // Indiquer que fin sur Bound.
902         }
903         else {
904           param = param + sens * stepw;
905           if (sens * (param - Bound) > - tolgui) {
906             param = Bound;
907           }
908         }
909       }
910       break;
911       
912     case Blend_OnRst1  :
913       {
914 #ifdef DEB
915         if (Blend_GettraceDRAWSECT()){
916           Drawsect(param, Func);
917         }
918 #endif
919         if (sens > 0.) {
920           line->Append(previousP);
921         }
922         else {
923           line->Prepend(previousP);
924         }
925         MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
926         MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
927         Arrive = Standard_True;
928       }
929       break;
930       
931     case Blend_OnRst2  :
932       {
933 #ifdef DEB
934         if (Blend_GettraceDRAWSECT()){
935           Drawsect(param, Func);
936         }
937 #endif
938         if (sens>0.) {
939           line->Append(previousP);
940         }
941         else {
942           line->Prepend(previousP);
943         }
944
945         MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
946         MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
947         Arrive = Standard_True;
948       }
949       break;
950       
951     case Blend_OnRst12  :
952       {
953 #ifdef DEB
954         if (Blend_GettraceDRAWSECT()){
955           Drawsect(param, Func);
956         }
957 #endif
958         if (sens > 0.) {
959           line->Append(previousP);
960         }
961         else {
962           line->Prepend(previousP);
963         }
964
965         MakeExtremity(Extrst1, Standard_True, rst1, sol(1), IsVtxrst1, Vtxrst1);
966         MakeExtremity(Extrst2, Standard_False, rst2, sol(2), IsVtxrst2, Vtxrst2);
967         Arrive = Standard_True;
968       }
969       break;
970       
971     case Blend_SamePoints :
972       {
973         // On arrete
974         cout << " Points confondus dans le cheminement" << endl;
975         Extrst1.SetValue(previousP.PointOnC1(),
976                          previousP.ParameterOnC1(),
977                          previousP.Parameter(), tolesp);
978         Extrst2.SetValue(previousP.PointOnC2(),
979                          previousP.ParameterOnC2(),
980                          previousP.Parameter(), tolesp);
981         Arrive = Standard_True;
982       }
983       break;
984 #ifndef DEB
985     default:
986       break;
987 #endif
988     }
989     if (Arrive) {
990       if (sens > 0.) {
991         line->SetEndPoints(Extrst1, Extrst2);
992         decrochfin = decroch;
993       }
994       else {
995         line->SetStartPoints(Extrst1, Extrst2);
996         decrochdeb = decroch;
997       }
998     }
999   }
1000 }
1001
1002
1003 //=======================================================================
1004 //function : Recadre1
1005 //purpose  : On a decroche en 1
1006 //=======================================================================
1007
1008 Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_RstRstFunction&    Func,
1009                                                        Blend_SurfCurvFuncInv&   Finv,
1010                                                        math_Vector&             Solinv,
1011                                                        Standard_Boolean&        IsVtx,
1012                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1013 {
1014   math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
1015   Finv.GetTolerance(toler, tolesp);
1016   Finv.GetBounds(infb, supb);
1017   Solinv(1) = param;
1018   Solinv(2) = sol(2);
1019   Solinv(3) = sol(1);
1020  
1021   // On recherche le point de non decrochement
1022   math_FunctionSetRoot rsnld(Finv, toler, 30);
1023   rsnld.Perform(Finv, Solinv, infb, supb);
1024   if (!rsnld.IsDone()) {
1025     cout << "RSNLD not done "<< endl << endl;
1026     return Standard_False;
1027   }
1028
1029   rsnld.Root(Solinv);
1030
1031   // On doit verifier la valeur de la fonction est bien
1032   //  sur la seconde restriction
1033   if (Finv.IsSolution(Solinv, tolesp)) {
1034     Standard_Real w = Solinv(2);
1035     if(w < rst2->FirstParameter() - toler(2)||
1036        w > rst2->LastParameter() + toler(2)){
1037       return Standard_False;
1038     }
1039  
1040     // on regarde si on n est pas sur un Vertex
1041     domain1->Initialize(rst1);
1042     domain1->InitVertexIterator();
1043     IsVtx = !domain1->MoreVertex();
1044     while (!IsVtx) {
1045       Vtx = domain1->Vertex();
1046       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1)-Solinv(3)) <=
1047           BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
1048         IsVtx = Standard_True;
1049       }
1050       else {
1051         domain1->NextVertex();
1052         IsVtx = !domain1->MoreVertex();
1053       }
1054     }
1055     if (!domain1->MoreVertex()) {
1056       IsVtx = Standard_False;
1057     }
1058     // On recalcule la section par resolution directe, sinon, on se recupere 
1059     // des incoherences entre le parametre et sol dues au baillement.
1060
1061     math_Vector infbound(1, 2), supbound(1, 2);
1062     math_Vector parinit(1, 2), tolerance(1, 2);
1063     Func.GetTolerance(tolerance, tolesp);
1064     Func.GetBounds(infbound, supbound);
1065
1066     math_FunctionSetRoot rsnld2(Func, tolerance, 30);
1067     parinit(1) = Solinv(3);
1068     parinit(2) = Solinv(2);
1069     Func.Set(Solinv(1));
1070     rsnld2.Perform(Func, parinit, infbound, supbound);
1071     if(!rsnld2.IsDone()) return Standard_False;
1072     rsnld2.Root(parinit);
1073     Solinv(2) = parinit(2);
1074     Solinv(3) = parinit(1);
1075     return Standard_True;
1076   }
1077   return Standard_False;
1078 }
1079
1080
1081
1082
1083
1084 //=======================================================================
1085 //function : Recadre2
1086 //purpose  : On a decroche sur Rst2
1087 //=======================================================================
1088
1089 Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_RstRstFunction&    Func,
1090                                                        Blend_SurfCurvFuncInv&   Finv,
1091                                                        math_Vector&             Solinv,
1092                                                        Standard_Boolean&        IsVtx,
1093                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1094 {
1095   math_Vector toler(1, 3), infb(1, 3), supb(1, 3);
1096   Finv.GetTolerance(toler, tolesp);
1097   Finv.GetBounds(infb, supb);
1098   Solinv(1) = param;
1099   Solinv(2) = sol(1);
1100   Solinv(3) = sol(2);
1101  
1102   math_FunctionSetRoot rsnld(Finv, toler, 30);
1103   rsnld.Perform(Finv, Solinv, infb, supb);
1104   if (!rsnld.IsDone()) {
1105     cout << "RSNLD not done "<< endl << endl;
1106     return Standard_False;
1107   }
1108
1109   rsnld.Root(Solinv);
1110
1111   // On doit verifier la valeur de la fonction
1112   if (Finv.IsSolution(Solinv, tolesp)) {
1113     Standard_Real w = Solinv(2);
1114     if(w < rst1->FirstParameter() - toler(2)||
1115        w > rst1->LastParameter() + toler(2)){
1116       return Standard_False;
1117     }
1118  
1119     domain2->Initialize(rst2);
1120     domain2->InitVertexIterator();
1121     IsVtx = !domain2->MoreVertex();
1122     while (!IsVtx) {
1123       Vtx = domain2->Vertex();
1124       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2)-Solinv(3)) <=
1125           BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
1126         IsVtx = Standard_True;
1127       }
1128       else {
1129         domain2->NextVertex();
1130         IsVtx = !domain2->MoreVertex();
1131       }
1132     }
1133     if (!domain2->MoreVertex()) {
1134       IsVtx = Standard_False;
1135     }
1136     // On recalcule la section par resolution directe, sinon, on se recupere 
1137     // des incoherences entre le parametre et sol dues au baillement.
1138
1139     math_Vector infbound(1, 2), supbound(1, 2);
1140     math_Vector parinit(1,2), tolerance(1,2);
1141     Func.GetTolerance(tolerance, tolesp);
1142     Func.GetBounds(infbound, supbound);
1143
1144     math_FunctionSetRoot rsnld2(Func, tolerance, 30);
1145     parinit(1) = Solinv(2);
1146     parinit(2) = Solinv(3);
1147     Func.Set(Solinv(1));
1148     rsnld2.Perform(Func, parinit, infbound, supbound);
1149     if(!rsnld2.IsDone()) return Standard_False;
1150     rsnld2.Root(parinit);
1151     Solinv(2) = parinit(1);
1152     Solinv(3) = parinit(2);
1153     return Standard_True;
1154   }
1155   return Standard_False;
1156 }
1157
1158 //=======================================================================
1159 //function : Recadre
1160 //purpose  : On est en fin de la courbe rst1
1161 //=======================================================================
1162
1163 Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre1(Blend_CurvPointFuncInv&  FinvP,
1164                                                        math_Vector&             Solinv,
1165                                                        Standard_Boolean&        IsVtx,
1166                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1167 {
1168   // On se place sur le dernier ou le premier point, suivant le
1169   // sens de cheminement.
1170   gp_Pnt2d p2drst1;
1171   Standard_Real firstrst1 = rst1->FirstParameter();
1172   Standard_Real lastrst1  = rst1->LastParameter();
1173   Standard_Real upoint    = firstrst1;
1174
1175   if((sol(1) - firstrst1) > (lastrst1 - sol(1))) upoint = lastrst1;
1176   p2drst1 = rst1->Value(upoint);
1177   gp_Pnt thepoint = surf1->Value(p2drst1.X(), p2drst1.Y());
1178
1179   FinvP.Set(thepoint);
1180   math_Vector toler(1,2), infb(1, 2), supb(1, 2);
1181   FinvP.GetTolerance(toler, tolesp);
1182   FinvP.GetBounds(infb, supb);
1183   Solinv(1) = param;
1184   Solinv(2) = sol(2);
1185
1186   math_FunctionSetRoot rsnld(FinvP, toler, 30);
1187   rsnld.Perform(FinvP, Solinv, infb, supb);
1188   if (!rsnld.IsDone()) {
1189     cout << "RSNLD not done "<< endl << endl;
1190     return Standard_False;
1191   }
1192   rsnld.Root(Solinv);
1193   
1194   if(FinvP.IsSolution(Solinv, tolesp)){
1195     gp_Pnt2d p2drst2  = rst2->Value(Solinv(2));
1196     TopAbs_State situ = domain2->Classify(p2drst2, toler(2), 0);
1197     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1198       return Standard_False;
1199     }
1200     domain1->Initialize(rst1);
1201     domain1->InitVertexIterator();
1202     IsVtx = !domain1->MoreVertex();
1203     while (!IsVtx) {
1204       Vtx = domain1->Vertex();
1205       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst1) - upoint) <=
1206           BRepBlend_BlendTool::Tolerance(Vtx, rst1)) {
1207         IsVtx = Standard_True;
1208       }
1209       else {
1210         domain1->NextVertex();
1211         IsVtx = !domain1->MoreVertex();
1212       }
1213     }
1214     if (!domain1->MoreVertex()) {
1215       IsVtx = Standard_False;
1216     }
1217     return Standard_True;
1218   }
1219   return Standard_False;
1220 }
1221
1222
1223
1224 //=======================================================================
1225 //function : Recadre2
1226 //purpose  : On est en fin de la courbe rst2
1227 //=======================================================================
1228
1229 Standard_Boolean BRepBlend_RstRstLineBuilder::Recadre2(Blend_CurvPointFuncInv&  FinvP,
1230                                                        math_Vector&             Solinv,
1231                                                        Standard_Boolean&        IsVtx,
1232                                                        Handle(Adaptor3d_HVertex)& Vtx) 
1233 {
1234   // On se place sur le dernier ou le premier point, suivant le
1235   // sens de cheminement.
1236   gp_Pnt2d p2drst2;
1237   Standard_Real firstrst2 = rst2->FirstParameter();
1238   Standard_Real lastrst2  = rst2->LastParameter();
1239   Standard_Real vpoint    = firstrst2;
1240
1241   if((sol(2) - firstrst2) > (lastrst2 - sol(2))) vpoint = lastrst2;
1242   p2drst2 = rst2->Value(vpoint);
1243   gp_Pnt thepoint = surf2->Value(p2drst2.X(), p2drst2.Y());
1244
1245   FinvP.Set(thepoint);
1246   math_Vector toler(1,2), infb(1, 2), supb(1, 2);
1247   FinvP.GetTolerance(toler, tolesp);
1248   FinvP.GetBounds(infb, supb);
1249   Solinv(1) = param;
1250   Solinv(2) = sol(1);
1251
1252   math_FunctionSetRoot rsnld(FinvP, toler, 30);
1253   rsnld.Perform(FinvP, Solinv, infb, supb);
1254   if (!rsnld.IsDone()) {
1255     cout << "RSNLD not done "<< endl << endl;
1256     return Standard_False;
1257   }
1258   rsnld.Root(Solinv);
1259   
1260   if(FinvP.IsSolution(Solinv, tolesp)){
1261     gp_Pnt2d p2drst1  = rst1->Value(Solinv(2));
1262     TopAbs_State situ = domain1->Classify(p2drst1, toler(2), 0);
1263     if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1264       return Standard_False;
1265     }
1266     domain2->Initialize(rst2);
1267     domain2->InitVertexIterator();
1268     IsVtx = !domain2->MoreVertex();
1269     while (!IsVtx) {
1270       Vtx = domain2->Vertex();
1271       if (Abs(BRepBlend_BlendTool::Parameter(Vtx, rst2) - vpoint) <=
1272           BRepBlend_BlendTool::Tolerance(Vtx, rst2)) {
1273         IsVtx = Standard_True;
1274       }
1275       else {
1276         domain2->NextVertex();
1277         IsVtx = !domain2->MoreVertex();
1278       }
1279     }
1280     if (!domain2->MoreVertex()) {
1281       IsVtx = Standard_False;
1282     }
1283     return Standard_True;
1284   }
1285   return Standard_False;
1286 }
1287
1288
1289 //=======================================================================
1290 //function : Transition
1291 //purpose  : 
1292 //=======================================================================
1293
1294 void BRepBlend_RstRstLineBuilder::Transition(const Standard_Boolean          OnFirst,
1295                                              const Handle(Adaptor2d_HCurve2d)& Arc,
1296                                              const Standard_Real             Param,
1297                                              IntSurf_Transition&             TLine,
1298                                              IntSurf_Transition&             TArc) 
1299 {
1300   Standard_Boolean computetranstionaveclacorde = 0;
1301   gp_Vec tgline;
1302   Blend_Point prevprev;
1303
1304   if(previousP.IsTangencyPoint()){
1305     if(line->NbPoints() < 2) return;
1306     computetranstionaveclacorde = 1;
1307     if(sens < 0){
1308       prevprev = line->Point(2);
1309     }
1310     else {
1311       prevprev = line->Point(line->NbPoints() - 1);
1312     }
1313   }
1314   gp_Pnt2d p2d;
1315   gp_Vec2d dp2d;
1316   
1317   gp_Pnt pbid;
1318   gp_Vec d1u, d1v, normale, tgrst;
1319   
1320   Arc->D1(Param, p2d, dp2d);
1321   if (OnFirst) {
1322     surf1->D1(p2d.X(), p2d.Y(), pbid, d1u, d1v);
1323     if(!computetranstionaveclacorde) tgline = previousP.TangentOnC1();
1324     else tgline = gp_Vec(prevprev.PointOnC1(), previousP.PointOnC1());
1325   }
1326   else {
1327     surf2->D1(p2d.X(), p2d.Y(), pbid, d1u, d1v);
1328     if(!computetranstionaveclacorde) tgline = previousP.TangentOnC2();
1329     else tgline = gp_Vec(prevprev.PointOnC2(), previousP.PointOnC2());
1330   }
1331   
1332   tgrst.SetLinearForm(dp2d.X(), d1u, dp2d.Y(), d1v);
1333   normale = d1u.Crossed(d1v);
1334   
1335   IntSurf::MakeTransition(tgline, tgrst, normale, TLine, TArc);
1336 }
1337
1338 //=======================================================================
1339 //function : MakeExtremity
1340 //purpose  : fabrique l extremite d une courbe
1341 //=======================================================================
1342
1343 void BRepBlend_RstRstLineBuilder::MakeExtremity(BRepBlend_Extremity&            Extrem,
1344                                                 const Standard_Boolean          OnFirst,
1345                                                 const Handle(Adaptor2d_HCurve2d)& Arc,
1346                                                 const Standard_Real             Param,
1347                                                 const Standard_Boolean          IsVtx,
1348                                                 const Handle(Adaptor3d_HVertex)&  Vtx) 
1349 {
1350   IntSurf_Transition Tline, Tarc;
1351   Standard_Real prm;
1352   Handle(Adaptor3d_TopolTool) Iter;
1353   if (OnFirst) {
1354     Extrem.SetValue(previousP.PointOnC1(),
1355                     sol(1),
1356                     previousP.Parameter(), tolesp);
1357     if (!previousP.IsTangencyPoint()) 
1358       Extrem.SetTangent(previousP.TangentOnC1());
1359     Iter = domain1;
1360   }
1361   else {
1362     Extrem.SetValue(previousP.PointOnC2(),
1363                     sol(2),
1364                     previousP.Parameter(), tolesp);
1365     if (!previousP.IsTangencyPoint()) 
1366       Extrem.SetTangent(previousP.TangentOnC1());
1367     Iter = domain2;
1368   }
1369   
1370   Iter->Init();
1371   if (!IsVtx) {
1372     Transition(OnFirst, Arc, Param, Tline, Tarc);
1373     Extrem.AddArc(Arc, Param, Tline, Tarc);
1374   }
1375   else {
1376     Extrem.SetVertex(Vtx);
1377     while (Iter->More()) {
1378 //#ifndef DEB
1379       Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
1380 //#else
1381 //      Handle(Adaptor2d_HCurve2d)& arc = Iter->Value();
1382 //#endif
1383      if (arc != Arc) {
1384         Iter->Initialize(arc);
1385         Iter->InitVertexIterator();
1386         while (Iter->MoreVertex()) {
1387           if (Iter->Identical(Vtx, Iter->Vertex())) {
1388             prm = BRepBlend_BlendTool::Parameter(Vtx, arc);
1389             Transition(OnFirst, arc, prm, Tline, Tarc);
1390             Extrem.AddArc(arc, prm, Tline, Tarc);
1391           }
1392           Iter->NextVertex();
1393         }
1394       }
1395       else {
1396         Transition(OnFirst, arc, Param, Tline, Tarc);
1397         Extrem.AddArc(arc, Param, Tline, Tarc);
1398       }
1399       Iter->Next();
1400     }
1401   }
1402 }
1403
1404 //=======================================================================
1405 //function : CheckDeflectionOnRst1
1406 //purpose  : 
1407 //=======================================================================
1408
1409 Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst1(const Blend_Point& CurPoint)
1410 {
1411   //Controles 3d du Blend_CSWalking.
1412
1413   // regle par tests dans U4 correspond a 11.478 d
1414   const Standard_Real CosRef3D = 0.98;
1415   Standard_Real Cosi, Cosi2;
1416   Standard_Boolean curpointistangent  = CurPoint.IsTangencyPoint();
1417   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1418
1419   gp_Pnt Psurf = CurPoint.PointOnC1();
1420   gp_Vec Tgsurf;
1421   if(!curpointistangent){
1422     Tgsurf = CurPoint.TangentOnC1();
1423   }
1424   gp_Pnt prevP = previousP.PointOnC1();
1425   gp_Vec prevTg;
1426   if(!prevpointistangent){
1427     prevTg = previousP.TangentOnC1();
1428   }
1429   Standard_Real Norme, curNorme;
1430 #ifndef DEB
1431   Standard_Real prevNorme = 0.;
1432 #else
1433   Standard_Real prevNorme;
1434 #endif
1435   gp_Vec Corde(prevP, Psurf);
1436   Norme = Corde.SquareMagnitude();
1437   if (!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1438   if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1439
1440   if (Norme <= tolesp * tolesp) {
1441     // il faudra peut etre  forcer meme point
1442     return Blend_SamePoints;
1443   }
1444   if(!prevpointistangent){
1445     if (prevNorme <= tolesp * tolesp) {
1446       return Blend_SamePoints;
1447     }
1448     Cosi = sens * Corde * prevTg;
1449     if (Cosi < 0.) { // angle 3d>pi/2. --> retour arriere
1450       return Blend_Backward;
1451     }
1452     
1453     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1454     if (Cosi2 < CosRef3D) { 
1455       return Blend_StepTooLarge;
1456     }
1457   }
1458   
1459   if(!curpointistangent){
1460     // Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
1461     Cosi = sens * Corde * Tgsurf;
1462     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1463     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1464       return Blend_StepTooLarge;
1465     }
1466   }  
1467
1468   if (!curpointistangent && !prevpointistangent) {
1469     // Estimation de la fleche courante
1470     Standard_Real FlecheCourante = 
1471       (prevTg.Normalized().XYZ() - Tgsurf.Normalized().XYZ()).SquareModulus() * Norme / 64.;
1472     
1473     if (FlecheCourante <= 0.25 * fleche * fleche) {
1474       return Blend_StepTooSmall;
1475     }
1476     if (FlecheCourante > fleche * fleche) {
1477       // pas trop grand : commentaire interessant
1478       return Blend_StepTooLarge;
1479     }
1480   }
1481   return Blend_OK;
1482 }
1483
1484
1485 //=======================================================================
1486 //function : CheckDeflectionOnRst2
1487 //purpose  : 
1488 //=======================================================================
1489
1490 Blend_Status BRepBlend_RstRstLineBuilder::CheckDeflectionOnRst2(const Blend_Point& CurPoint)
1491 {
1492   //Controles 3d du Blend_CSWalking.
1493
1494   // regle par tests dans U4 correspond a 11.478 d
1495   const Standard_Real CosRef3D = 0.98;
1496   Standard_Real Cosi, Cosi2;
1497   Standard_Boolean curpointistangent  = CurPoint.IsTangencyPoint();
1498   Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1499
1500   gp_Pnt Psurf = CurPoint.PointOnC2();
1501   gp_Vec Tgsurf;
1502
1503   if (!curpointistangent) {
1504     Tgsurf = CurPoint.TangentOnC2();
1505   }
1506   gp_Pnt prevP = previousP.PointOnC2();
1507   gp_Vec prevTg;
1508   if (!prevpointistangent) {
1509     prevTg = previousP.TangentOnC2();
1510   }
1511   Standard_Real Norme, curNorme;
1512 #ifndef DEB
1513   Standard_Real prevNorme = 0.;
1514 #else
1515   Standard_Real prevNorme;
1516 #endif
1517   gp_Vec Corde(prevP, Psurf);
1518   Norme = Corde.SquareMagnitude();
1519   if (!curpointistangent) curNorme   = Tgsurf.SquareMagnitude();
1520   if (!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1521
1522   if (Norme <= tolesp * tolesp){
1523     // il faudra peut etre  forcer meme point
1524     return Blend_SamePoints;
1525   }
1526   if (!prevpointistangent) {
1527     if (prevNorme <= tolesp * tolesp) {
1528       return Blend_SamePoints;
1529     }
1530     Cosi = sens * Corde * prevTg;
1531     if (Cosi < 0.) { // angle 3d>pi/2. --> retour arriere
1532       return Blend_Backward;
1533     }
1534     
1535     Cosi2 = Cosi * Cosi / prevNorme / Norme;
1536     if (Cosi2 < CosRef3D) { 
1537       return Blend_StepTooLarge;
1538     }
1539   }
1540   
1541   if (!curpointistangent) {
1542     // Voir s il faut faire le controle sur le signe de prevtg*Tgsurf
1543     Cosi  = sens * Corde * Tgsurf;
1544     Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1545     if (Cosi2 < CosRef3D || Cosi < 0.) { 
1546       return Blend_StepTooLarge;
1547     }
1548   }  
1549
1550   if(!curpointistangent && !prevpointistangent){
1551     // Estimation de la fleche courante
1552     Standard_Real FlecheCourante = 
1553       (prevTg.Normalized().XYZ() - Tgsurf.Normalized().XYZ()).SquareModulus() * Norme/64.;
1554     
1555     if (FlecheCourante <= 0.25 * fleche * fleche) {
1556       return Blend_StepTooSmall;
1557     }
1558     if (FlecheCourante > fleche * fleche) {
1559       // pas trop grand : commentaire interessant
1560       return Blend_StepTooLarge;
1561     }
1562   }
1563   return Blend_OK;
1564 }
1565
1566 static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1567 {
1568   if(O == TopAbs_FORWARD) return IntSurf_In;
1569   return IntSurf_Out;
1570 }
1571
1572 //=======================================================================
1573 //function : TestArret
1574 //purpose  : 
1575 //=======================================================================
1576
1577 Blend_Status BRepBlend_RstRstLineBuilder::TestArret(Blend_RstRstFunction& Func,
1578                                                     const Standard_Boolean TestDeflection,
1579                                                     const Blend_Status     State) 
1580 {
1581   gp_Pnt ptrst1, ptrst2;
1582   gp_Pnt2d pt2drst1, pt2drst2;
1583   gp_Vec tgrst1, tgrst2;
1584   gp_Vec2d tg2drst1, tg2drst2;
1585   Blend_Status StateRst1, StateRst2;
1586 #ifndef DEB
1587   IntSurf_TypeTrans trarst1 = IntSurf_Undecided, trarst2 = IntSurf_Undecided;
1588 #else
1589   IntSurf_TypeTrans trarst1, trarst2;
1590 #endif
1591   Blend_Point curpoint;
1592
1593   if (Func.IsSolution(sol, tolesp)) {
1594     Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1595     ptrst1   = Func.PointOnRst1();
1596     ptrst2   = Func.PointOnRst2();
1597     pt2drst1 = Func.Pnt2dOnRst1();
1598     pt2drst2 = Func.Pnt2dOnRst2();
1599
1600     if(curpointistangent){
1601       curpoint.SetValue(ptrst1, ptrst2, param, pt2drst1.X(), pt2drst1.Y(), 
1602                         pt2drst2.X(), pt2drst2.Y(), sol(1), sol(2));
1603     }
1604     else{
1605       tgrst1   = Func.TangentOnRst1();
1606       tgrst2   = Func.TangentOnRst2();
1607       tg2drst1 = Func.Tangent2dOnRst1();
1608       tg2drst2 = Func.Tangent2dOnRst2();
1609       curpoint.SetValue(ptrst1, ptrst2, param, pt2drst1.X(), pt2drst1.Y(), 
1610                         pt2drst2.X(), pt2drst2.Y(), sol(1), sol(2),
1611                         tgrst1, tgrst2, tg2drst1, tg2drst2);
1612     }
1613     if (TestDeflection) {
1614       StateRst1 = CheckDeflectionOnRst1(curpoint);
1615       StateRst2 = CheckDeflectionOnRst2(curpoint);
1616     }
1617     else {
1618       StateRst1 = StateRst2 = Blend_OK;
1619     }
1620     if (StateRst1 == Blend_Backward) {
1621       StateRst1 = Blend_StepTooLarge;
1622       rebrou    = Standard_True;
1623     }
1624     if (StateRst2 == Blend_Backward) {
1625       StateRst2 = Blend_StepTooLarge;
1626       rebrou    = Standard_True;
1627     }
1628     if (StateRst1 == Blend_StepTooLarge ||
1629         StateRst2 == Blend_StepTooLarge) {
1630       return Blend_StepTooLarge;
1631     }
1632
1633     if (!comptra && !curpointistangent) {
1634       gp_Pnt2d p2drstref;
1635       gp_Vec2d tg2drstref;
1636       rst1->D1(sol(1), p2drstref, tg2drstref);
1637       Standard_Real testra = tg2drst1.Dot(tg2drstref);
1638       TopAbs_Orientation Or = domain1->Orientation(rst1);
1639
1640       if (Abs(testra) > tolesp) {
1641         if (testra < 0.) {
1642           trarst1 = ConvOrToTra(TopAbs::Reverse(Or));
1643         }
1644         else if (testra >0.) {
1645           trarst1 = ConvOrToTra(Or);
1646         }
1647
1648         rst2->D1(sol(2), p2drstref, tg2drstref);
1649         testra = tg2drst2.Dot(tg2drstref);
1650
1651         Or = domain2->Orientation(rst2);
1652         if (Abs(testra) > tolesp) {
1653           if (testra < 0.) {
1654             trarst2 = ConvOrToTra(TopAbs::Reverse(Or));
1655           }
1656           else if (testra >0.) {
1657             trarst2 = ConvOrToTra(Or);
1658           }
1659           comptra = Standard_True;
1660           line->Set(trarst1, trarst2);
1661         }
1662       }
1663     }
1664     if (StateRst1 == Blend_OK ||
1665         StateRst2 == Blend_OK ) {
1666       previousP = curpoint;
1667       return State;
1668     }
1669     if (StateRst1 == Blend_StepTooSmall &&
1670         StateRst2 == Blend_StepTooSmall) {
1671       previousP = curpoint;
1672       if (State == Blend_OK) {
1673         return Blend_StepTooSmall;
1674       }
1675       else {
1676         return State;
1677       }
1678     }
1679     if (State == Blend_OK) {
1680       return Blend_SamePoints;
1681     }
1682     else {
1683       return State;
1684     }
1685   }
1686   return Blend_StepTooLarge;
1687 }
1688
1689 //=======================================================================
1690 //function : CheckInside
1691 //purpose  : 
1692 //=======================================================================
1693
1694 Standard_Boolean BRepBlend_RstRstLineBuilder::CheckInside(Blend_RstRstFunction&  Func,
1695                                                           TopAbs_State&          SituOnC1,
1696                                                           TopAbs_State&          SituOnC2,
1697                                                           Blend_DecrochStatus &  Decroch)
1698 {
1699 //  Standard_Boolean inside = Standard_True;
1700   math_Vector tolerance(1, 2);
1701   Func.GetTolerance(tolerance, tolesp);
1702
1703   //cote pcurve 1.
1704   Standard_Real v = sol(1);
1705   if(v < rst1->FirstParameter() - tolerance(2)||
1706      v > rst1->LastParameter() + tolerance(2)){
1707     SituOnC1 = TopAbs_OUT;
1708   }
1709   else if (v > rst1->FirstParameter() &&
1710            v < rst1->LastParameter()){
1711     SituOnC1 = TopAbs_IN;
1712   }
1713   else SituOnC1 = TopAbs_ON;
1714
1715   //cote pcurve 2.
1716   v = sol(2);
1717   if(v < rst2->FirstParameter() - tolerance(2)||
1718      v > rst2->LastParameter() + tolerance(2)){
1719     SituOnC2 = TopAbs_OUT;
1720   }
1721   else if (v > rst2->FirstParameter() &&
1722            v < rst2->LastParameter()){
1723     SituOnC2 = TopAbs_IN;
1724   }
1725   else SituOnC2 = TopAbs_ON;
1726
1727
1728   //decrochage
1729   gp_Vec tgrst1, norst1, tgrst2, norst2;
1730   Decroch = Func.Decroch(sol,tgrst1, norst1, tgrst2, norst2);
1731
1732   return (SituOnC1 == TopAbs_IN && SituOnC2 == TopAbs_IN && Decroch == Blend_NoDecroch);
1733 }
1734
1735
1736