0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / Bisector / Bisector_Bisec.cxx
1 // Created on: 1994-07-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-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 <Bisector.hxx>
19 #include <Bisector_Bisec.hxx>
20 #include <Bisector_BisecAna.hxx>
21 #include <Bisector_BisecCC.hxx>
22 #include <Bisector_BisecPC.hxx>
23 #include <Bisector_Curve.hxx>
24 #include <GCE2d_MakeSegment.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom2d_CartesianPoint.hxx>
27 #include <Geom2d_Circle.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Point.hxx>
31 #include <Geom2d_TrimmedCurve.hxx>
32 #include <gp.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <Precision.hxx>
36 #include <Standard_NotImplemented.hxx>
37 #include <StdFail_NotDone.hxx>
38
39 #ifdef OCCT_DEBUG
40 //#define DRAW
41 #ifdef DRAW
42 #include <DrawTrSurf.hxx>
43 #pragma comment(lib, "TKDraw.lib")
44 static char name[100];
45 static Standard_Integer nbb  = 0;
46 static Standard_Boolean Affich = Standard_False;
47 #endif
48 #endif
49
50
51 static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
52   Standard_Real         U,
53   Standard_Real&        R);
54
55 static void ReplaceByLineIfIsToSmall (Handle(Bisector_Curve)& Bis,
56   Standard_Real&        UFirst,
57   Standard_Real&        ULast);                                 
58 //=============================================================================
59 //function : Empty Constructor                                                
60 //=============================================================================
61 Bisector_Bisec::Bisector_Bisec()
62 {
63 }
64
65 //===========================================================================
66 //    calculate the bissectrice between two curves coming from a point.         
67 //                                                                          
68 //   afirstcurve   : \ curves between which the          
69 //   asecondcurve  : / bissectrice is calculated.                                         
70 //   apoint        :   point through which the bissectrice should pass.         
71 //   afirstvector  : \ vectors to determine the sector where       
72 //   asecondvector : / the bissectrice should be located.                      
73 //   adirection    :   shows the the side of the bissectrice to be preserved.       
74 //   tolerance     :   threshold starting from which the bisectrices are degenerated
75 //===========================================================================
76
77 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve   ,
78                              const Handle(Geom2d_Curve)& asecondcurve  ,
79                              const gp_Pnt2d&             apoint        ,
80                              const gp_Vec2d&             afirstvector  ,
81                              const gp_Vec2d&             asecondvector ,
82                              const Standard_Real         adirection    ,
83                              const GeomAbs_JoinType      ajointype     ,
84                              const Standard_Real         tolerance     ,
85                              const Standard_Boolean      oncurve       )
86 {
87   Handle(Standard_Type)  Type1 = afirstcurve ->DynamicType();
88   Handle(Standard_Type)  Type2 = asecondcurve->DynamicType();
89   Handle(Bisector_Curve) Bis;
90   Standard_Real          UFirst,ULast;
91
92   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
93     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
94       ->BasisCurve()->DynamicType();
95   }
96   if (Type2 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
97     Type2 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
98       ->BasisCurve()->DynamicType();
99   }
100
101   Handle(Geom2d_Curve) afirstcurve1 = afirstcurve;
102   Handle(Geom2d_Curve) asecondcurve1 = asecondcurve;
103
104   if(Type1 == STANDARD_TYPE(Geom2d_BSplineCurve))
105   {
106     Handle(Geom2d_BSplineCurve) aBS;
107     if(afirstcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
108     {
109       aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
110                                                                                ->BasisCurve());
111     }
112     else
113     {
114       aBS = Handle(Geom2d_BSplineCurve)::DownCast(afirstcurve);
115     }
116     if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
117     {
118       if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
119       {
120         afirstcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2)).Value();
121         Type1 = STANDARD_TYPE(Geom2d_Line);
122       }
123     }
124   }
125
126
127   if(Type2 == STANDARD_TYPE(Geom2d_BSplineCurve))
128   {
129     Handle(Geom2d_BSplineCurve) aBS;
130     if(asecondcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
131     {
132       aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
133                                                                                ->BasisCurve());
134     }
135     else
136     {
137       aBS = Handle(Geom2d_BSplineCurve)::DownCast(asecondcurve);
138     }
139     if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
140     {
141       if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
142       {
143         asecondcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2)).Value();
144         Type2 = STANDARD_TYPE(Geom2d_Line);
145       }
146     }
147   }
148
149   if ( (Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) &&
150     (Type2 == STANDARD_TYPE(Geom2d_Circle) || Type2 == STANDARD_TYPE(Geom2d_Line))   )
151   {    
152     //------------------------------------------------------------------
153     // Analytic Bissectrice.
154     //------------------------------------------------------------------
155      Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
156      BisAna->Perform(afirstcurve1  ,
157                      asecondcurve1 ,
158                      apoint        ,
159                      afirstvector  ,
160                      asecondvector ,
161                      adirection    ,
162                      ajointype     ,
163                      tolerance     ,
164                      oncurve       );
165      UFirst = BisAna->ParameterOfStartPoint();
166      ULast  = BisAna->ParameterOfEndPoint();    
167      Bis = BisAna;   
168   }
169   else {  
170     Standard_Boolean IsLine = Standard_False;
171
172     if (oncurve) {
173       gp_Dir2d Fd(afirstvector);
174       gp_Dir2d Sd(asecondvector);
175       //if (Fd.Dot(Sd) < Precision::Angular() - 1.) { 
176       //if (Fd.Dot(Sd) < 10*Precision::Angular() - 1.) //patch
177       if (Fd.Dot(Sd) < Sqrt(2.*Precision::Angular()) - 1.)
178         IsLine = Standard_True;
179     }
180     if (IsLine) {     
181       //------------------------------------------------------------------
182       // Half-Staight.
183       //------------------------------------------------------------------
184       gp_Dir2d N ( - adirection*afirstvector.Y(), adirection*afirstvector.X());
185       Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(apoint);
186       Handle (Geom2d_Line)           L      = new Geom2d_Line (apoint,N);
187       Handle (Geom2d_TrimmedCurve)   
188         BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
189       Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
190       BisAna->Init(BisL);
191       UFirst = BisAna->ParameterOfStartPoint();
192       ULast  = BisAna->ParameterOfEndPoint();
193       Bis    = BisAna;
194     }
195     else {
196       //-------------------------------------------------------------------
197       // Bissectrice algo
198       //-------------------------------------------------------------------
199       Handle(Bisector_BisecCC) BisCC = new Bisector_BisecCC();
200       BisCC -> Perform(asecondcurve1, 
201         afirstcurve1 ,
202         adirection  , 
203         adirection  , 
204         apoint);
205
206       if (BisCC -> IsEmpty()) {
207         // bissectrice is empty. a point is projected at the end of the guide curve. 
208         // Construction of a false bissectrice.
209         //  modified by NIZHNY-EAP Mon Feb 21 12:00:13 2000 ___BEGIN___
210         gp_Pnt2d aP1 = afirstcurve1->Value(afirstcurve1->LastParameter());
211         gp_Pnt2d aP2 = asecondcurve1->Value(asecondcurve1->FirstParameter());
212         gp_Pnt2d aPm(.5*(aP1.XY()+aP2.XY()));
213         Standard_Real Nx, Ny;
214         if(aPm.Distance(apoint) > 10.*Precision::Confusion())
215         {
216           Nx = apoint.X() - aPm.X();
217           Ny = apoint.Y() - aPm.Y();
218           if(adirection < 0)
219           {
220             Nx = -Nx;
221             Ny = -Ny;
222           }
223         }
224         else
225         {
226           gp_Dir2d dir1(afirstvector), dir2(asecondvector);
227           Nx = - dir1.X() - dir2.X(),
228           Ny = - dir1.Y() - dir2.Y();
229           if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
230             Nx = -afirstvector.Y();
231             Ny = afirstvector.X();
232           }
233         }
234         gp_Dir2d N ( adirection*Nx, adirection*Ny);
235         //  modified by NIZHNY-EAP Mon Feb 21 12:00:19 2000 ___END___
236
237         Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(apoint);
238         Handle (Geom2d_Line)           L      = new Geom2d_Line (apoint,N);
239         Handle (Geom2d_TrimmedCurve)   
240           BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
241         Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
242         BisAna->Init(BisL);
243         UFirst = BisAna->ParameterOfStartPoint();
244         ULast  = BisAna->ParameterOfEndPoint();
245         Bis    = BisAna;
246       }
247       else {
248         UFirst = BisCC->FirstParameter();
249         ULast  = BisCC->LastParameter ();
250         Bis    = BisCC;
251         ReplaceByLineIfIsToSmall(Bis,UFirst,ULast);
252       }
253     }
254   }
255   UFirst = Max(UFirst, Bis->FirstParameter());
256   ULast = Min(ULast, Bis->LastParameter());
257   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
258 #ifdef DRAW  
259   if(Affich) 
260   {
261     sprintf( name, "c1_%d", ++nbb );
262     DrawTrSurf::Set( name, afirstcurve );
263     sprintf( name, "c2_%d", nbb );
264     DrawTrSurf::Set( name, asecondcurve );
265     sprintf( name, "p%d", nbb );
266     DrawTrSurf::Set( name, apoint );
267     sprintf( name, "b%d", nbb );
268     DrawTrSurf::Set( name, thebisector );
269   }
270 #endif
271   
272 }
273
274 //===========================================================================
275 //  calculate the bissectrice between a curve and a point starting in a point. 
276 //                                                                          
277 //   afirstcurve   : \ curve and point the bissectrice between which is calculated.
278 //   asecondpoint  : /                                          
279 //   apoint        :   point through which the bissectrice should pass.         
280 //   afirstvector  : \ vectors to find the sector where       
281 //   asecondvector : / the bissectrice should be located.                      
282 //   adirection    :   shows the side of the bissectrice to be preserved.       
283 //   tolerance     :   threshold starting from which the bisectrices are degenerated
284 //===========================================================================
285
286 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve  ,
287   const Handle(Geom2d_Point)& asecondpoint ,
288   const gp_Pnt2d&             apoint       ,
289   const gp_Vec2d&             afirstvector ,
290   const gp_Vec2d&             asecondvector,
291   const Standard_Real         adirection   ,
292   const Standard_Real         tolerance    ,
293   const Standard_Boolean      oncurve       )
294 {  
295   //gp_Pnt2d SecondPnt = asecondpoint->Pnt2d();
296
297   Handle(Bisector_Curve) Bis;
298   Handle(Standard_Type)  Type1 = afirstcurve ->DynamicType();
299   Standard_Real          UFirst,ULast;
300
301   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
302     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
303       ->BasisCurve()->DynamicType();
304   }
305
306   if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
307     //------------------------------------------------------------------
308     // Analytic Bissectrice.
309     //------------------------------------------------------------------
310     Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
311     BisAna -> Perform (afirstcurve   ,
312       asecondpoint  ,
313       apoint        ,
314       afirstvector  ,
315       asecondvector ,
316       adirection    ,
317       tolerance     ,
318       oncurve       );
319     UFirst = BisAna->ParameterOfStartPoint();
320     ULast  = BisAna->ParameterOfEndPoint();
321     Bis    = BisAna;
322   }
323   else {  
324     Standard_Boolean IsLine    = Standard_False;
325     Standard_Real    RC        = Precision::Infinite();
326
327     if (oncurve) {
328       if (Bisector::IsConvex(afirstcurve,adirection) || 
329         IsMaxRC(afirstcurve,afirstcurve->LastParameter(),RC)) { 
330           IsLine = Standard_True; 
331       }
332     }
333     if (IsLine) {     
334       //------------------------------------------------------------------
335       // Half-Right.
336       //------------------------------------------------------------------
337       gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
338       Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
339       Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
340       Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
341       BisAna->Init(BisL);
342       UFirst = BisAna->ParameterOfStartPoint();
343       ULast  = BisAna->ParameterOfEndPoint();
344       Bis    = BisAna;
345     }
346     else {
347       //-------------------------------------------------------------------
348       // Bissectrice algo
349       //-------------------------------------------------------------------
350       Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
351       Handle(Geom2d_Curve) afirstcurvereverse = afirstcurve->Reversed();
352
353       BisPC -> Perform(afirstcurvereverse   ,
354         asecondpoint->Pnt2d(),
355         - adirection         );
356       //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
357       if (BisPC -> IsEmpty()) {
358         gp_Dir2d dir1(afirstvector), dir2(asecondvector);
359         Standard_Real
360           Nx = - dir1.X() - dir2.X(),
361           Ny = - dir1.Y() - dir2.Y();
362         if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
363           Nx = - afirstvector.Y();
364           Ny = afirstvector.X();
365         }
366         //      gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
367         gp_Dir2d N ( adirection*Nx, adirection*Ny);
368         Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
369         Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
370         Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
371         BisAna->Init(BisL);
372         UFirst = BisAna->ParameterOfStartPoint();
373         ULast  = BisAna->ParameterOfEndPoint();
374         Bis    = BisAna;
375       } else {
376         //  Modified by Sergey KHROMOV - Wed Mar  6 17:01:08 2002 End
377         UFirst = BisPC->Parameter(apoint);
378         ULast  = BisPC->LastParameter();
379         if(UFirst >= ULast)
380         {
381           //Standard_Real t = .9;
382           //UFirst = (1. - t) * BisPC->FirstParameter() + t * ULast;
383           //Extrapolate by line
384           //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
385           gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
386           gp_Dir2d N( V );
387           Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
388           Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
389           Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
390           BisAna->Init(BisL);
391           UFirst = BisAna->ParameterOfStartPoint();
392           ULast  = BisAna->ParameterOfEndPoint();
393           Bis    = BisAna;
394         }
395         else
396           Bis    = BisPC;
397       }
398     }
399   }
400   if(UFirst < Bis->FirstParameter())
401     UFirst = Bis->FirstParameter();
402   if(ULast > Bis->LastParameter())
403     ULast = Bis->LastParameter();
404   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
405
406 #ifdef DRAW
407   if(Affich)
408   {
409   sprintf( name, "c1_%d", ++nbb );
410   DrawTrSurf::Set( name, afirstcurve );
411   sprintf( name, "c2_%d", nbb );
412   DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
413   sprintf( name, "p%d", nbb );
414   DrawTrSurf::Set( name, apoint );
415   sprintf( name, "b%d", nbb );
416   DrawTrSurf::Set( name, thebisector );
417   }
418 #endif
419 }
420
421 //===========================================================================
422 //   calculate the bissectrice between a curve and a point starting in a point. 
423 //                                                                          
424 //   afirstpoint   : \ curve and point the bissectrice between which is calculated.         
425 //   asecondcurve  : /                                          
426 //   apoint        :   point through which the bissectrice should pass.         
427 //   afirstvector  : \ vectors to find the sector where       
428 //   asecondvector : / the bissectrice should be located.                      
429 //   adirection    :   shows the side of the bissectrice to be preserved.       
430 //   tolerance     :   threshold starting from which the bisectrices are degenerated
431 //===========================================================================
432
433 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
434   const Handle(Geom2d_Curve)& asecondcurve ,
435   const gp_Pnt2d&             apoint       ,
436   const gp_Vec2d&             afirstvector ,
437   const gp_Vec2d&             asecondvector,
438   const Standard_Real         adirection   ,
439   const Standard_Real         tolerance    ,
440   const Standard_Boolean      oncurve       )
441
442 {  
443   //gp_Pnt2d FirstPnt = afirstpoint->Pnt2d();
444
445   Handle(Bisector_Curve) Bis;
446   Handle(Standard_Type)  Type1 = asecondcurve ->DynamicType();
447   Standard_Real          UFirst,ULast;
448
449   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
450     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
451       ->BasisCurve()->DynamicType();
452   }
453
454   if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
455     //------------------------------------------------------------------
456     // Analytic Bissectrice.
457     //------------------------------------------------------------------
458     Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
459     BisAna -> Perform (afirstpoint   ,
460       asecondcurve  ,
461       apoint        ,
462       afirstvector  ,
463       asecondvector ,
464       adirection    ,
465       tolerance     ,
466       oncurve       );
467     UFirst = BisAna->ParameterOfStartPoint();
468     ULast  = BisAna->ParameterOfEndPoint();
469     Bis    = BisAna;
470   }
471   else {   
472     //  Standard_Real    UPoint    = 0.;
473     Standard_Boolean IsLine    = Standard_False;
474     Standard_Real    RC        = Precision::Infinite();
475
476     if (oncurve) {
477       if (Bisector::IsConvex(asecondcurve, adirection) || 
478         IsMaxRC(asecondcurve,asecondcurve->FirstParameter(),RC)) {
479           IsLine = Standard_True;
480       }
481     }    
482     if (IsLine) {     
483       //------------------------------------------------------------------
484       // Half-Staight.
485       //------------------------------------------------------------------
486       gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
487       Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
488       Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
489       Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
490       BisAna->Init(BisL);
491       UFirst = BisAna->ParameterOfStartPoint();
492       ULast  = BisAna->ParameterOfEndPoint();
493       Bis    = BisAna;
494     }
495     else {
496       //-------------------------------------------------------------------
497       // Bissectrice algo
498       //-------------------------------------------------------------------
499       Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
500       BisPC -> Perform(asecondcurve        ,
501         afirstpoint->Pnt2d(),
502         adirection          );
503       //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
504       if (BisPC -> IsEmpty()) {
505         gp_Dir2d dir1(afirstvector), dir2(asecondvector);
506         Standard_Real
507           Nx = - dir1.X() - dir2.X(),
508           Ny = - dir1.Y() - dir2.Y();
509         if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
510           Nx = - afirstvector.Y();
511           Ny = afirstvector.X();
512         }
513         //      gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
514         gp_Dir2d N ( adirection*Nx, adirection*Ny);
515         Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
516         Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
517         Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
518         BisAna->Init(BisL);
519         UFirst = BisAna->ParameterOfStartPoint();
520         ULast  = BisAna->ParameterOfEndPoint();
521         Bis    = BisAna;
522       } else {
523         //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:58 2002 End
524         UFirst = BisPC->Parameter(apoint);
525         ULast  = BisPC->LastParameter();
526         if(UFirst >= ULast)
527         {
528           //Extrapolate by line
529           //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
530           gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
531           gp_Dir2d N( V );
532           Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
533           Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
534           Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
535           BisAna->Init(BisL);
536           UFirst = BisAna->ParameterOfStartPoint();
537           ULast  = BisAna->ParameterOfEndPoint();
538           Bis    = BisAna;
539         }
540         else
541           Bis    = BisPC;
542       }
543     }
544   }
545  
546   UFirst = Max(UFirst, Bis->FirstParameter());
547   ULast = Min(ULast, Bis->LastParameter());
548   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
549
550 #ifdef DRAW
551   if(Affich)
552   {
553   sprintf( name, "c1_%d", ++nbb );
554   DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
555   sprintf( name, "c2_%d", nbb );
556   DrawTrSurf::Set( name, asecondcurve );
557   sprintf( name, "p%d", nbb );
558   DrawTrSurf::Set( name, apoint );
559   sprintf( name, "b%d", nbb );
560   DrawTrSurf::Set( name, thebisector );
561   }
562 #endif
563
564 }
565
566 //===========================================================================
567 //        calculate the bissectrice between two points starting in a point.      
568 //                                                                          
569 //   afirstpoint   : \ curves the bissectrice between which should be          
570 //   asecondpoint  : / calculated.                                         
571 //   apoint        :   point through which the bissectrice should pass.         
572 //   afirstvector  : \ vectors to find the sector where       
573 //   asecondvector : / the bissectrice should be located.                      
574 //   adirection    :   shows the side of the bissectrice to be preserved.       
575 //===========================================================================
576
577 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
578   const Handle(Geom2d_Point)& asecondpoint ,
579   const gp_Pnt2d&             apoint       ,
580   const gp_Vec2d&             afirstvector ,
581   const gp_Vec2d&             asecondvector,
582   const Standard_Real         adirection   ,
583   const Standard_Real         tolerance    ,
584   const Standard_Boolean      oncurve      )
585 {
586   Handle(Bisector_BisecAna) Bis = new Bisector_BisecAna();
587
588   Bis -> Perform (afirstpoint   ,
589     asecondpoint  ,
590     apoint        ,
591     afirstvector  ,
592     asecondvector ,
593     adirection    ,
594     tolerance     ,
595     oncurve       ); 
596   thebisector = new Geom2d_TrimmedCurve(Bis,
597     Bis->ParameterOfStartPoint(),
598     Bis->ParameterOfEndPoint());
599
600 #ifdef DRAW
601   if(Affich)
602   {
603   sprintf( name, "c1_%d", ++nbb );
604   DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
605   sprintf( name, "c2_%d", nbb );
606   DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
607   sprintf( name, "p%d", nbb );
608   DrawTrSurf::Set( name, apoint );
609   sprintf( name, "b%d", nbb );
610   DrawTrSurf::Set( name, thebisector );
611   }
612 #endif
613 }
614
615 //=============================================================================
616 //function : Value
617 //purpose  :
618 //=============================================================================
619 const Handle(Geom2d_TrimmedCurve)&  Bisector_Bisec::Value() const
620 {
621   return thebisector;
622 }
623
624 //=============================================================================
625 //function : ChangeValue
626 //purpose  :
627 //=============================================================================
628 const Handle(Geom2d_TrimmedCurve)&  Bisector_Bisec::ChangeValue()
629 {
630   return thebisector;
631 }
632
633 //=============================================================================
634 //function : ReplaceByLineIfIsToSmall 
635 //purpose  : If the size of an algorithmic bissectrice is negligeable it is
636 //           replaced by a half-straight.
637 //=============================================================================
638 static void ReplaceByLineIfIsToSmall (Handle(Bisector_Curve)& Bis,
639   Standard_Real&        UFirst,
640   Standard_Real&        ULast )
641
642 {
643   if (Abs(ULast - UFirst) > 2.*Precision::PConfusion()*10.) return; //patch
644
645   gp_Pnt2d PF = Bis->Value(UFirst);
646   gp_Pnt2d PL = Bis->Value(ULast);
647
648   if (PF.Distance(PL) > Precision::Confusion()*10.) return;
649
650   gp_Vec2d T1 = Bis->DN(UFirst,1);
651
652   Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(PF);
653   Handle (Geom2d_Line)           L      = new Geom2d_Line (PF,T1);
654   Handle (Geom2d_TrimmedCurve)   
655     BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
656   Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
657   BisAna->Init(BisL);
658   UFirst = BisAna->ParameterOfStartPoint();
659   ULast  = BisAna->ParameterOfEndPoint();
660   Bis    = BisAna;
661 }
662
663 //=============================================================================
664 //function : IsMaxRC
665 //purpose  :
666 //=============================================================================
667 static Standard_Boolean  IsMaxRC (const Handle(Geom2d_Curve)& C,
668   Standard_Real         U,
669   Standard_Real&        R)
670 {  
671   Standard_Real KF,KL;
672   Standard_Real US = C->FirstParameter();
673   Standard_Real UL = C->LastParameter();
674
675   gp_Vec2d      D1,D2;
676   gp_Pnt2d      P;
677   Standard_Real Norm2;
678
679   C->D2(US,P,D1,D2);
680   Norm2 = D1.SquareMagnitude();
681   if (Norm2 < gp::Resolution()) { KF = 0.0;}
682   else                          { KF = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
683
684   C->D2(UL,P,D1,D2);
685   Norm2 = D1.SquareMagnitude();
686   if (Norm2 < gp::Resolution()) { KL = 0.0;}
687   else                          { KL = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
688
689   Standard_Boolean IsMax = Standard_False;
690
691   if (U == UL) {
692     if (KL < KF) {
693       if (KL == 0.0) R = Precision::Infinite(); else R = 1/KL;
694       IsMax = Standard_True;
695     }
696   }
697   else {   
698     if (KF < KL) {
699       if (KF == 0.0) R = Precision::Infinite(); else R = 1/KF;
700       IsMax = Standard_True;
701     }
702   }
703   return IsMax;
704 }