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