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