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