0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Bisector / Bisector_BisecAna.cxx
1 // Created on: 1992-10-19
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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 //  Modified by skv - Fri Jul  1 16:23:17 2005 IDEM(Airbus)
18 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus)
19
20 #include <Bisector_BisecAna.hxx>
21 #include <ElCLib.hxx>
22 #include <GccAna_Circ2dBisec.hxx>
23 #include <GccAna_CircLin2dBisec.hxx>
24 #include <GccAna_CircPnt2dBisec.hxx>
25 #include <GccAna_LinPnt2dBisec.hxx>
26 #include <GccAna_Pnt2dBisec.hxx>
27 #include <GccInt_BLine.hxx>
28 #include <GccInt_IType.hxx>
29 #include <Geom2d_Circle.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2d_Ellipse.hxx>
32 #include <Geom2d_Geometry.hxx>
33 #include <Geom2d_Hyperbola.hxx>
34 #include <Geom2d_Line.hxx>
35 #include <Geom2d_Parabola.hxx>
36 #include <Geom2d_Point.hxx>
37 #include <Geom2d_TrimmedCurve.hxx>
38 #include <Geom2dAdaptor_Curve.hxx>
39 #include <gp_Pnt2d.hxx>
40 #include <gp_Trsf2d.hxx>
41 #include <gp_Vec2d.hxx>
42 #include <IntAna2d_AnaIntersection.hxx>
43 #include <Precision.hxx>
44 #include <Standard_Type.hxx>
45 #include <StdFail_NotDone.hxx>
46
47 IMPLEMENT_STANDARD_RTTIEXT(Bisector_BisecAna,Bisector_Curve)
48
49 static Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
50                                    const Standard_Real   Tolerance);
51
52 //=============================================================================
53 //function :           
54 //=============================================================================
55 Bisector_BisecAna::Bisector_BisecAna()
56 {
57 }
58
59 //=============================================================================
60 //              calcul the distance between the point and the bissectrice.              +
61 //              and orientation of the bissectrice.                             +
62 //    apoint        :       point of passage.                                 +
63 //    abisector     :       calculated bissectrice.                          +
64 //    afirstvector  :       first vector. \                                +
65 //    asecondvector :       second vector./ to choose the proper sector.    +
66 //    adirection    :       shows if the bissectrice is interior or exterior.  +
67 //    aparameter    : out : the start parameter of the bissectrice.         +
68 //    asense        : out : the direction of the bissectrice.                        +
69 //    astatus       : out : shows if the bissectrice is preserved.               +
70 //=============================================================================
71 Standard_Real Bisector_BisecAna::Distance (
72    const gp_Pnt2d&             apoint,
73    const Handle(GccInt_Bisec)& abisector,
74    const gp_Vec2d&             afirstvector ,
75    const gp_Vec2d&             asecondvector,
76    const gp_Vec2d&             VecRef,
77    const Standard_Real         adirection,
78    Standard_Real&              aparameter,
79    Standard_Boolean&           asense,
80    Standard_Boolean&           astatus,
81    Standard_Boolean            IsBisecOfTwoLines)
82 {
83   astatus = Standard_True;
84
85   gp_Hypr2d  gphyperbola;
86   gp_Parab2d gpparabola ;
87   gp_Elips2d gpellipse  ;
88   gp_Circ2d  gpcircle   ;
89   gp_Lin2d   gpline     ;
90
91   Standard_Real distance = 0.;
92   gp_Vec2d tangent;
93   gp_Pnt2d point;
94
95   GccInt_IType type = abisector->ArcType();
96   
97   if (type == GccInt_Lin) {
98     gpline     = abisector->Line();
99     aparameter = ElCLib::Parameter(gpline,apoint);
100     ElCLib::D1(aparameter,gpline,point,tangent);
101   }
102   else if (type == GccInt_Cir) {
103     gpcircle   = abisector->Circle();
104     aparameter = ElCLib::Parameter(gpcircle,apoint);
105     ElCLib::D1(aparameter,gpcircle,point,tangent);
106   }
107   else if (type == GccInt_Hpr) {
108     gphyperbola   = abisector->Hyperbola();
109     aparameter    = ElCLib::Parameter(gphyperbola,apoint);
110     ElCLib::D1(aparameter,gphyperbola,point,tangent);
111   }
112   else if (type == GccInt_Par) {
113     gpparabola   = abisector->Parabola();
114     aparameter   = ElCLib::Parameter(gpparabola,apoint);
115     ElCLib::D1(aparameter,gpparabola,point,tangent);
116   }
117   else if (type == GccInt_Ell) {
118     gpellipse   = abisector->Ellipse();
119     aparameter  = ElCLib::Parameter(gpellipse,apoint);
120     ElCLib::D1(aparameter,gpellipse,point,tangent);
121   }
122
123   distance = apoint.Distance(point);
124
125   gp_Dir2d afirstdir (afirstvector);
126   gp_Dir2d aseconddir(asecondvector);
127   gp_Dir2d tangdir   (tangent);
128   gp_Dir2d secdirrev = aseconddir.Reversed();
129  
130
131 // 1st passage to learn if the curve is in the proper sector
132     
133   if(asense) {
134     // the status is determined only in case on curve ie:
135     // tangent to the bissectrice is bisectrice of two vectors.
136     Standard_Real SinPlat = 1.e-3;
137     if (Abs(afirstdir^aseconddir) < SinPlat) {   //flat
138       if (afirstdir*aseconddir >= 0.0) {       //tangent mixed
139         // correct if the scalar product is close to 1.
140         if (Abs(tangdir*afirstdir) < 0.5) {
141           astatus = Standard_False;            
142         }
143       }
144       else {  // opposed tangents.
145         // correct if the scalar product is close to 0.
146         if (Abs(tangdir*afirstdir) > 0.5 ) { 
147           astatus = Standard_False;
148         }
149       }
150     }
151     else if ((afirstdir^tangdir)*(tangdir^aseconddir) < -1.E-8) {
152       astatus = Standard_False;
153     }
154   }
155   else {
156     asense = Standard_True;
157
158     if (!IsBisecOfTwoLines)
159     {
160       //  Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 Begin
161       // Replacement of -1.E-8 for a tolerance 1.e-4
162       Standard_Real aTol = 1.e-4;
163       
164       if ((afirstdir^secdirrev)*adirection < -0.1) {   // input
165         if((afirstdir^tangdir)*adirection < aTol &&
166            (secdirrev^tangdir)*adirection < aTol)
167           asense = Standard_False;
168       }
169       else if((afirstdir^secdirrev)*adirection > 0.1) { // output
170         if((afirstdir^tangdir)*adirection < aTol ||
171            (secdirrev^tangdir)*adirection < aTol)
172           asense = Standard_False;
173       }
174       else  {                                                // flat
175         if (afirstdir.Dot(secdirrev) > 0.) {                // tangent 
176           if ((afirstdir^tangdir)*adirection < 0.)
177             asense = Standard_False;
178         }
179         else{                                                // turn back
180           //  Modified by Sergey KHROMOV - Thu Oct 31 14:16:53 2002
181           //    if ((afirstdir.Dot(tangdir))*adirection > 0.) asense = Standard_False;
182           if (afirstdir.Dot(tangdir) < 0.) asense = Standard_False;
183           //  Modified by Sergey KHROMOV - Thu Oct 31 14:16:54 2002
184         }
185       }
186       //jgv: for OCC26185
187       if (VecRef.SquareMagnitude() != 0)
188       {
189         gp_Dir2d DirRef = VecRef;
190         if (tangdir * DirRef < 0.)
191           asense = Standard_False;
192       }
193       ///////////////////
194       //  Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 End
195     }
196   }
197   return distance;
198 }
199
200 //===========================================================================
201 //    calculate the bissectrice between two curves coming from a point.         +
202 //                                                                          +
203 //   afirstcurve   : \ curves the bissectrice between which will be calculated.      +
204 //   asecondcurve  : /                                          +
205 //   apoint        :   point through which the bissectrice should pass.         +
206 //   afirstvector  : \ vectors to find the sector where       +
207 //   asecondvector : / the bissectrice should be located.                      +
208 //   adirection    :   shows the side of the bissectrice to be preserved.       +
209 //   tolerance     :   threshold starting from which the bisectrices are degenerated +
210 //===========================================================================
211 void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve   ,
212                                 const Handle(Geom2d_Curve)& asecondcurve  ,
213                                 const gp_Pnt2d&             apoint        ,
214                                 const gp_Vec2d&             afirstvector  ,
215                                 const gp_Vec2d&             asecondvector ,
216                                 const Standard_Real         adirection    ,
217                                 const GeomAbs_JoinType      ajointype     ,
218                                 const Standard_Real         tolerance     ,
219                                 const Standard_Boolean      oncurve       )
220 {
221
222   Standard_Boolean ok;
223   Standard_Real    distanceptsol,parameter,firstparameter =0.;
224   Standard_Boolean thesense = Standard_False,sense;
225   Standard_Real    distancemini;
226   Standard_Integer nbsolution;
227   Standard_Real    PreConf = Precision::Confusion();
228
229   Handle(Standard_Type) type1 = afirstcurve->DynamicType();
230   Handle(Standard_Type) type2 = asecondcurve->DynamicType();
231   Handle(Geom2d_Curve)  CurveF;
232   Handle(Geom2d_Curve)  CurveE;
233   Handle(GccInt_Bisec)  TheSol;
234
235   //jgv: for OCC26296
236   gp_Vec2d LineBisVec(0.,0.);
237   gp_Vec2d tan1, tan2;
238   gp_Pnt2d Pnt1, Pnt2;
239   afirstcurve->D1(afirstcurve->LastParameter(),  Pnt1, tan1);
240   asecondcurve->D1(asecondcurve->FirstParameter(), Pnt2, tan2);
241   if (!oncurve)
242   {
243     LineBisVec = gp_Vec2d(Pnt1, Pnt2);
244     LineBisVec.Rotate(M_PI/2.);
245   }
246   ///////////////////
247   
248   tan1.Reverse();
249
250   if (type1 == STANDARD_TYPE(Geom2d_TrimmedCurve))
251     CurveF = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)->BasisCurve();
252   else 
253     CurveF = afirstcurve;
254
255   if (type2 == STANDARD_TYPE(Geom2d_TrimmedCurve))
256     CurveE  = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)->BasisCurve();
257   else
258     CurveE = asecondcurve;
259
260   type1 = CurveF->DynamicType();
261   type2 = CurveE->DynamicType();
262   Standard_Integer cas =0;
263   gp_Circ2d circle1,circle2;
264   gp_Lin2d line1,line2;
265
266 //=============================================================================
267 //                Determination of the nature of arguments.                   +
268 //=============================================================================
269
270   if (type1 == STANDARD_TYPE(Geom2d_Circle)) {
271     if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
272       cas = 1;
273       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
274       circle1 = C1->Circ2d();
275       Handle(Geom2d_Circle) C2 = Handle(Geom2d_Circle)::DownCast(CurveE);
276       circle2 = C2->Circ2d();
277     }
278     else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
279       cas = 2;
280       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
281       circle1 = C1->Circ2d();
282       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
283       line2   = L2->Lin2d();
284     }
285     else {
286       std::cout << "Not yet implemented" << std::endl;
287     }
288   }
289   else if (type1 == STANDARD_TYPE(Geom2d_Line)) {
290     if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
291       cas = 2;
292       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveE);
293       circle1 = C1->Circ2d();
294       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveF);
295       line2   = L2->Lin2d();
296     }
297     else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
298       cas = 3;
299       Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(CurveF);
300       line1   = L1->Lin2d();
301       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
302       line2   = L2->Lin2d();
303     }
304     else {
305       std::cout << "Not yet implemented" << std::endl;
306     }
307   }
308   else {
309     std::cout << "Not yet implemented" << std::endl;
310   }
311
312   switch(cas) {
313
314 //=============================================================================
315 //                       Bissectrice circle - circle.                         +
316 //=============================================================================
317
318   case 1 : {
319     Standard_Real radius1 = circle1.Radius();
320     Standard_Real radius2 = circle2.Radius();
321
322     //-----------------------------------------------------
323     // Particular case when two circles are mixed.
324     //-----------------------------------------------------
325     if (circle1.Location().IsEqual(circle2.Location(),PreConf)&&
326         (Abs(radius1 - radius2) <= PreConf)){
327       gp_Pnt2d P1   = afirstcurve ->Value(afirstcurve ->LastParameter());
328       gp_Pnt2d P2   = asecondcurve->Value(asecondcurve->FirstParameter());
329       gp_Pnt2d PMil;
330       gp_Lin2d line;
331       PMil = gp_Pnt2d((P1.X() + P2.X())/2.,
332                       (P1.Y() + P2.Y())/2.);
333 //  Modified by skv - Fri Jul  1 16:23:32 2005 IDEM(Airbus) Begin
334 //       line = gp_Lin2d(PMil,
335 //                    gp_Dir2d(circle1.Location().X() - PMil.X(), 
336 //                             circle1.Location().Y() - PMil.Y()));
337       if (!circle1.Location().IsEqual(PMil,PreConf)) {
338         // PMil doesn't coincide with the circle location.
339         line = gp_Lin2d(PMil,
340                         gp_Dir2d(circle1.Location().X() - PMil.X(), 
341                                  circle1.Location().Y() - PMil.Y()));
342       } else if (radius1 >= PreConf) {
343         // PMil coincides with the circle location and radius is greater then 0.
344         line = gp_Lin2d(circle1.Location(),
345                         gp_Dir2d(P1.Y() - circle1.Location().Y(), 
346                                  circle1.Location().X() - P1.X()));
347       } else {
348         // radius is equal to 0. No matter what direction to chose.
349         line = gp_Lin2d(circle1.Location(), gp_Dir2d(1., 0.));
350       }
351 //  Modified by skv - Fri Jul  1 16:23:32 2005 IDEM(Airbus) End
352       Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
353       sense = Standard_False;
354 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
355 //       distanceptsol = Distance(apoint,solution,
356 //                             afirstvector,asecondvector,
357 //                             adirection,parameter,sense,ok);
358       if (oncurve)
359         distanceptsol = Distance(apoint,solution,
360                                  tan2,tan1,LineBisVec,
361                                  adirection,parameter,sense,ok);
362       else
363         distanceptsol = Distance(apoint,solution,
364                                  afirstvector,asecondvector,LineBisVec,
365                                  adirection,parameter,sense,ok);
366 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
367       Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
368       if (!sense)
369         thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
370                                              parameter,
371                                              - Precision::Infinite());
372       else {
373         Standard_Real parameter2;
374         parameter2  = ElCLib::Parameter(line,circle1.Location());
375         parameter2  += 1.e-8;
376         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
377                                               parameter,
378                                               parameter2);
379       }
380       break;
381     } //end of case mixed circles. 
382     
383     if (radius1 < radius2) {
384       gp_Circ2d circle = circle1;
385       circle1 = circle2;
386       circle2 = circle;
387       
388       Standard_Real radius = radius1;
389       radius1 = radius2;
390       radius2 = radius;
391     }
392     
393     // small reframing of circles. in the case when the circles
394     // are OnCurve , if they are almost tangent they become tangent.
395     Standard_Real    EntreAxe = circle1.Location().Distance(circle2.Location());
396     Standard_Real    D1       = 0.5*(radius1 - EntreAxe - radius2);
397     Standard_Boolean CirclesTangent = Standard_False;
398
399 //  Modified by Sergey KHROMOV - Thu Oct 31 12:42:21 2002 End
400 //     if ( oncurve && Abs(D1) <  PreConf) {
401     if ( oncurve && Abs(D1) <  PreConf && tan1.IsParallel(tan2, 1.e-8)) {
402 //  Modified by Sergey KHROMOV - Thu Oct 31 12:42:22 2002 Begin
403       // C2 included in C1 and tangent.
404       circle1.SetRadius(radius1 - D1);
405       circle2.SetRadius(radius2 + D1);
406       CirclesTangent = Standard_True;
407     }
408     else {
409       D1 = 0.5*(radius1 - EntreAxe + radius2);
410 //  Modified by Sergey KHROMOV - Thu Oct 31 12:44:24 2002 Begin
411 //       if (oncurve && Abs(D1) < PreConf) {
412       if (oncurve && Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
413 //  Modified by Sergey KHROMOV - Thu Oct 31 12:44:25 2002 End
414         // C2 and C1 tangent and disconnected.
415         circle1.SetRadius(radius1 - D1);
416         circle2.SetRadius(radius2 - D1);
417         CirclesTangent = Standard_True;
418       }
419     }   // end of reframing.
420
421     GccAna_Circ2dBisec Bisector(circle1,circle2);
422     
423     distancemini = Precision::Infinite();
424         
425     if (Bisector.IsDone()) {
426       nbsolution = Bisector.NbSolutions();
427       for (Standard_Integer i = 1; i <= nbsolution; i++) {
428         Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
429         Degenerate(solution,tolerance);
430         sense = Standard_True;
431         if (oncurve) {
432           distanceptsol = Distance(apoint,solution,
433                                    tan1,tan2,LineBisVec,
434                                    adirection,parameter,sense,ok);
435         }
436         else {ok = Standard_True;}
437
438         if (ok) {
439           sense = Standard_False;
440 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
441 //       distanceptsol = Distance(apoint,solution,
442 //                             afirstvector,asecondvector,
443 //                             adirection,parameter,sense,ok);
444           if (oncurve)
445             distanceptsol = Distance(apoint,solution,
446                                      tan2,tan1,LineBisVec,
447                                      adirection,parameter,sense,ok);
448           else
449             distanceptsol = Distance(apoint,solution,
450                                      afirstvector,asecondvector,LineBisVec,
451                                      adirection,parameter,sense,ok);
452 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
453           if (distanceptsol <= distancemini) {
454             TheSol         = solution;
455             firstparameter = parameter;
456             thesense       = sense;
457             distancemini   = distanceptsol;
458           }
459         }
460       }
461       if (!TheSol.IsNull()) {
462         Handle(Geom2d_Curve) bisectorcurve;
463         GccInt_IType type = TheSol->ArcType();
464         if (type == GccInt_Lin) {
465           gp_Lin2d gpline = TheSol->Line(); 
466           bisectorcurve  = new Geom2d_Line(gpline);
467           
468           Standard_Real  secondparameter =   Precision::Infinite();
469           if (!thesense) secondparameter = - Precision::Infinite();
470           
471           if (oncurve) {
472             // bisectrice right and oncurve 
473             // is cut between two circle of the same radius if circles are tangent.
474
475             // if tangent flat and the bissectrice at the side of the concavity
476             // of one of the circles. the bissectrice is a segment of the point common to 
477             // first of 2 centers of circle that it meets. 
478             // in this case it is important to set a segmnent for 
479             // intersection in Tool2d.
480             
481             if (CirclesTangent) {
482               //  Modified by skv - Tue Apr 13 17:23:31 2004 IDEM(Airbus) Begin
483               //  Trying to correct the line if the distance between it
484               //  and the reference point is too big.
485               if (distancemini > tolerance) {
486                 gp_Pnt2d      aPloc    = gpline.Location();
487                 gp_Dir2d      aNewDir(apoint.XY() - aPloc.XY());
488                 gp_Lin2d      aNewLin(aPloc, aNewDir);
489                 gp_Pnt2d      aCC2     = circle2.Location();
490                 Standard_Real aNewDMin = aNewLin.Distance(apoint);
491                 Standard_Real aTolConf = 1.e-3;
492                 // Hope, aNewDMin is equal to 0...
493
494                 if (aNewLin.Distance(aCC2) <= aTolConf) {
495                   distancemini   =     aNewDMin;
496                   firstparameter =     ElCLib::Parameter(aNewLin, apoint);
497                   bisectorcurve  = new Geom2d_Line(aNewLin);
498                 }
499               }
500               //  Modified by skv - Tue Apr 13 17:23:32 2004 IDEM(Airbus) End
501               if (tan1.Dot(tan2) < 0.) {
502                 // flat and not turn back.
503                 Standard_Real Par1 = ElCLib::Parameter(gpline, circle1.Location());
504                 Standard_Real Par2 = ElCLib::Parameter(gpline, circle2.Location());
505                 Standard_Real MinPar = Min(Par1,Par2);
506                 Standard_Real MaxPar = Max(Par1,Par2);
507                 
508                 if (!thesense) {
509                   if (MaxPar < firstparameter) 
510                     secondparameter = MaxPar - 1.E-8;
511                   else if (MinPar < firstparameter)
512                     secondparameter = MinPar - 1.E-8;
513                 }
514                 else {
515                   if (MinPar > firstparameter) 
516                     secondparameter = MinPar + 1.E-8;
517                   else if (MaxPar > firstparameter)
518                     secondparameter = MaxPar + 1.E-8;
519                 }
520               }
521             }
522           }
523           
524           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
525                                                 firstparameter,
526                                                 secondparameter);
527         }
528         else if (type == GccInt_Cir) { 
529           bisectorcurve = new Geom2d_Circle(TheSol->Circle());
530           if (!thesense)
531             thebisector = new Geom2d_TrimmedCurve
532               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
533           else
534             thebisector = new Geom2d_TrimmedCurve
535               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
536         }
537         else if (type == GccInt_Hpr) {
538           bisectorcurve = new Geom2d_Hyperbola(TheSol->Hyperbola());
539           if (!thesense)
540             thebisector = new Geom2d_TrimmedCurve
541               (bisectorcurve,firstparameter, - Precision::Infinite());
542           else
543             thebisector = new Geom2d_TrimmedCurve
544               (bisectorcurve,firstparameter,Precision::Infinite());
545         }
546         else if (type == GccInt_Ell) {
547           bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
548           if (!thesense)
549             thebisector = new Geom2d_TrimmedCurve
550               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
551           else
552             thebisector = new Geom2d_TrimmedCurve
553               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
554         }
555       }
556     }
557   }
558   break;
559     
560 //=============================================================================
561 //                       Bissectrice circle - straight.                         +
562 //=============================================================================
563       
564   case 2 : {
565     // small reframing of circles. in case OnCurve.
566     // If the circle and the straight line are almost tangent they become tangent.
567     if (oncurve) {
568       Standard_Real radius1 = circle1.Radius();
569       Standard_Real D1 = (line2.Distance(circle1.Location()) - radius1);
570 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:43 2002 Begin
571 //       if (Abs(D1) < PreConf) {
572       if (Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
573 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:44 2002 End
574         circle1.SetRadius(radius1+D1);
575       }
576     }
577
578     GccAna_CircLin2dBisec Bisector(circle1,line2);
579     
580     distancemini = Precision::Infinite();
581
582     if (Bisector.IsDone()) {
583       nbsolution = Bisector.NbSolutions();
584       for (Standard_Integer i = 1; i <= nbsolution; i++) {
585         Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
586         Degenerate(solution,tolerance);
587         sense = Standard_True;
588         distanceptsol = Distance(apoint,solution,tan1,tan2,LineBisVec,
589                                  adirection,parameter,sense,ok);
590         if (ok || !oncurve) {
591           sense = Standard_False;
592 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
593 //       distanceptsol = Distance(apoint,solution,
594 //                             afirstvector,asecondvector,
595 //                             adirection,parameter,sense,ok);
596           if (oncurve)
597             distanceptsol = Distance(apoint,solution,
598                                      tan2,tan1,LineBisVec,
599                                      adirection,parameter,sense,ok);
600           else
601             distanceptsol = Distance(apoint,solution,
602                                      afirstvector,asecondvector,LineBisVec,
603                                      adirection,parameter,sense,ok);
604 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
605           if (distanceptsol <= distancemini) {
606             TheSol         = solution;
607             firstparameter = parameter;
608             thesense       = sense;
609             distancemini   = distanceptsol+1.e-8;
610           }
611         }
612       }
613       if (!TheSol.IsNull()) {
614         GccInt_IType type = TheSol->ArcType();
615         Handle(Geom2d_Curve) bisectorcurve;
616         if (type == GccInt_Lin) {
617           // -----------------------------------------------------------------
618           // If the bisectrice is a line 
619           //       => the straight line is tangent to the circle.
620           //       It the part of bisectrice concerned is at the side of the center.
621           //       => the bisectrice is limited by the point and the center of the circle.
622           // Note : In the latter case the bisectrice is a degenerated parabole.
623           // -----------------------------------------------------------------
624           gp_Pnt2d      circlecenter;
625           gp_Lin2d      gpline;
626           Standard_Real secondparameter;
627           
628           circlecenter    = circle1.Location();
629           gpline          = TheSol->Line(); 
630           secondparameter = ElCLib::Parameter(gpline, circlecenter);
631           bisectorcurve   = new Geom2d_Line(gpline);
632
633           if (!thesense) {
634             if (secondparameter > firstparameter) {
635               secondparameter = - Precision::Infinite();
636             }
637             else {
638               secondparameter = secondparameter - 1.E-8;
639             }
640           }
641           else {
642             if (secondparameter < firstparameter) {
643               secondparameter = Precision::Infinite();
644             }
645             else {
646               secondparameter = secondparameter + 1.E-8;
647             }
648           }
649           
650           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
651                                                 firstparameter,
652                                                 secondparameter);
653         }
654         else if (type == GccInt_Par) {
655           bisectorcurve = new Geom2d_Parabola(TheSol->Parabola());
656           gp_Pnt2d apex = bisectorcurve->Value(0.);
657           gp_Pnt2d firstpnt = bisectorcurve->Value(firstparameter);
658           Standard_Real ChordLen = apex.Distance(firstpnt);
659           const Standard_Real TolPar = 1.e-5;
660           Standard_Real secondparameter = Precision::Infinite();
661           if (!thesense)
662           {
663             if (ajointype == GeomAbs_Intersection &&
664                 TolPar < firstparameter &&
665                 ChordLen >= circle1.Radius()) //first parameter is too far from peak of parabola
666               secondparameter = 0.;
667             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
668                                                   firstparameter,
669                                                   -secondparameter);
670           }
671           else
672           {
673             if (ajointype == GeomAbs_Intersection &&
674                 firstparameter < -TolPar &&
675                 ChordLen >= circle1.Radius()) //first parameter is too far from peak of parabola
676               secondparameter = 0.;
677             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
678                                                   firstparameter,
679                                                   secondparameter);
680           }
681         }
682       }
683     }
684   }
685     break;
686     
687 //=============================================================================
688 //                       Bissectrice straight - straight.                     +
689 //=============================================================================
690   case 3 : {
691     gp_Dir2d Direc1(line1.Direction());
692     gp_Dir2d Direc2(line2.Direction());
693     gp_Lin2d line;
694     distancemini = Precision::Infinite();
695
696 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:43 2002 Begin
697 //  Change to the same criterion as in MAT2d_Circuit.cxx:
698 //         method MAT2d_Circuit::InitOpen(..)
699 //     if (Direc1.IsParallel(Direc2,RealEpsilon())) {
700     if (Direc1.IsParallel(Direc2,1.e-8)) {
701 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:45 2002 End
702       if (line1.Distance(line2.Location())/2. <= Precision::Confusion())
703         line = gp_Lin2d(apoint,gp_Dir2d(-line1.Direction().Y(),
704                                         line1.Direction().X()));
705       else
706         line = gp_Lin2d(apoint,line2.Direction());
707       
708       Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
709 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) Begin
710 //       sense = Standard_True;
711 //       distanceptsol = Distance(apoint,solution,
712 //                             tan1,tan2,
713 //                             adirection,parameter,sense,ok);
714 //       theSense = sense;
715 //       if (ok || !oncurve) {
716       sense = Standard_False;
717 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
718 //       distanceptsol = Distance(apoint,solution,
719 //                             afirstvector,asecondvector,
720 //                             adirection,parameter,sense,ok);
721       if (oncurve)
722         distanceptsol = Distance(apoint,solution,
723                                  tan2,tan1,LineBisVec,
724                                  adirection,parameter,sense,ok);
725       else
726         distanceptsol = Distance(apoint,solution,
727                                  afirstvector,asecondvector,LineBisVec,
728                                  adirection,parameter,sense,ok);
729 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
730 //      if (distanceptsol <= distancemini) {
731       firstparameter = parameter;
732       Handle(Geom2d_Curve) bisectorcurve;
733       bisectorcurve = new Geom2d_Line(line);
734       if (!sense)
735         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
736                                               firstparameter,
737                                               - Precision::Infinite());
738       else
739         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
740                                               firstparameter,
741                                               Precision::Infinite());
742 //      }
743 //       }
744 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) End
745     }
746     else {
747       gp_Lin2d l(apoint,gp_Dir2d(Direc2.XY()-Direc1.XY()));
748       Handle(GccInt_Bisec) solution = new GccInt_BLine(l);
749       Standard_Boolean isOk;
750       sense = Standard_False;
751 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
752 //       distanceptsol = Distance(apoint,solution,
753 //                             afirstvector,asecondvector,
754 //                             adirection,parameter,sense,ok);
755       if (oncurve)
756         distanceptsol = Distance(apoint,solution,
757                                  tan2,tan1,LineBisVec,
758                                  adirection,parameter,sense, isOk);
759       else
760         distanceptsol = Distance(apoint,solution,
761                                  afirstvector,asecondvector,LineBisVec,
762                                  adirection,parameter,sense, isOk, Standard_True);
763 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
764       if (isOk || !oncurve) {
765         thesense = sense;
766         distancemini = distanceptsol;
767       }
768       TheSol = new GccInt_BLine(l);
769       Handle(Geom2d_Curve) bisectorcurve;
770       bisectorcurve = new Geom2d_Line(TheSol->Line());
771       if (!thesense)
772         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
773                                               0.,- Precision::Infinite());
774       else
775         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
776                                               0., Precision::Infinite());
777     }
778   }
779     break;
780
781     default :
782       throw StdFail_NotDone();
783     break;
784   }
785 }
786
787
788 //===========================================================================
789 //  calculate the bissectrice between a curve and a point and starting in a point. +
790 //                                                                          +
791 //   afirstcurve   : \ curve and point the bissectrice between which is calculated +
792 //   asecondpoint  : /                                          +
793 //   apoint        :   point through which the bissectrice should pass.         +
794 //   afirstvector  : \ vectors to determine the sector in which      +
795 //   asecondvector : / the bissectrice should be located.                      +
796 //   adirection    :   shows the side of the bissectrice to be preserved.       +
797 //   tolerance     :   threshold starting from which the bisectrices are degenerated+
798 //===========================================================================
799
800 void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve  ,
801                                 const Handle(Geom2d_Point)& asecondpoint ,
802                                 const gp_Pnt2d&             apoint       ,
803                                 const gp_Vec2d&             afirstvector ,
804                                 const gp_Vec2d&             asecondvector,
805                                 const Standard_Real         adirection   ,
806                                 const Standard_Real         tolerance    ,
807                                 const Standard_Boolean      oncurve       )
808 {
809   Standard_Boolean ok;
810   Standard_Boolean thesense = Standard_False,sense;
811   Standard_Real    distanceptsol,parameter,firstparameter =0.,secondparameter;
812   gp_Vec2d VecRef(0.,0.);
813   Handle(Geom2d_Curve) curve;
814   Handle(GccInt_Bisec) TheSol;
815
816   gp_Circ2d circle;
817   gp_Lin2d  line;
818   gp_Pnt2d  circlecenter;
819
820   Standard_Integer cas = 0;
821
822   Handle(Standard_Type) aFirstCurveType = afirstcurve->DynamicType();
823
824   if (aFirstCurveType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
825     curve = Handle(Geom2d_TrimmedCurve)::DownCast (afirstcurve)->BasisCurve();
826   }
827   else {
828     curve = afirstcurve;
829   }
830
831   aFirstCurveType = curve->DynamicType();
832   const gp_Pnt2d aPoint(asecondpoint->Pnt2d());
833   (void )aPoint;
834   if (aFirstCurveType == STANDARD_TYPE(Geom2d_Circle)) {
835     cas = 1;
836     Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(curve);
837     circle = C1->Circ2d();
838   }
839   else if (aFirstCurveType == STANDARD_TYPE(Geom2d_Line)) {
840     cas = 2;
841     Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(curve);
842     line   = L1->Lin2d();
843   }
844   else {
845     std::cout << "Not yet implemented" << std::endl;
846   }
847
848   switch(cas) {
849
850 //=============================================================================
851 //                       Bissectrice point - circle.                          +
852 //=============================================================================
853     case 1 : {
854       GccAna_CircPnt2dBisec Bisector(circle, asecondpoint->Pnt2d(), tolerance);
855       Standard_Real distancemini = Precision::Infinite();
856       if (Bisector.IsDone()) {
857         Standard_Integer nbsolution = Bisector.NbSolutions();
858         for (Standard_Integer i = 1; i <= nbsolution; i++) {
859           Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
860           Degenerate(solution,tolerance);
861           sense = Standard_False;
862           distanceptsol = Distance(apoint,solution,
863                                    afirstvector,asecondvector,VecRef,
864                                    adirection,parameter,sense,ok);
865
866           if (distanceptsol <= distancemini) {
867             TheSol = solution;
868             firstparameter = parameter;
869             thesense = sense;
870             distancemini = distanceptsol;
871           }
872         }
873         if (!TheSol.IsNull()) {
874           GccInt_IType aSolType = TheSol->ArcType();
875           Handle(Geom2d_Curve) bisectorcurve;
876           if (aSolType == GccInt_Lin) {
877
878 // ----------------------------------------------------------------------------
879 // If the bisectrice is a line 
880 //       => the point is on the circle.
881 //       If the part of bisectrice concerned is at the side of the center.
882 //       => the bisectrice is limited by the point and the center of the circle.
883 // Note : In this latter case the bisectrice is actually an ellipse of small null axis.
884 // ----------------------------------------------------------------------------
885             
886             circlecenter    = circle.Location();
887             line            = TheSol->Line(); 
888             secondparameter = ElCLib::Parameter(line, circlecenter);
889             bisectorcurve   = new Geom2d_Line(line);
890
891             if (!thesense) {
892               if (secondparameter > firstparameter) {
893                 secondparameter = - Precision::Infinite();
894               }
895               else {
896                 secondparameter = secondparameter - 1.E-8;
897               }
898             }
899             else {
900               if (secondparameter < firstparameter) {
901                 secondparameter = Precision::Infinite();
902               }
903               else {
904                 secondparameter = secondparameter + 1.E-8;
905               }
906             }
907
908             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
909                                                   firstparameter,
910                                                   secondparameter);
911
912           }
913           else if (aSolType == GccInt_Cir) {
914             bisectorcurve = new Geom2d_Circle(TheSol->Circle());
915             if (!thesense)
916               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
917                                                     firstparameter-2.0*M_PI,
918                                                     firstparameter,
919                                                     thesense);
920             else
921               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
922                                                     firstparameter,
923                                                     firstparameter+2.0*M_PI,
924                                                     thesense);
925           }
926           else if (aSolType == GccInt_Hpr) {
927             bisectorcurve=new Geom2d_Hyperbola(TheSol->Hyperbola());
928             if (!thesense)
929               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
930                                                     firstparameter,
931                                                     - Precision::Infinite());
932             else
933               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
934                                                     firstparameter,
935                                                     Precision::Infinite());
936           }
937           else if (aSolType == GccInt_Ell) {
938             bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
939             if (!thesense)
940               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
941                                                     firstparameter-2.0*M_PI,
942                                                     firstparameter,
943                                                     thesense);
944             else
945               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
946                                                     firstparameter,
947                                                     firstparameter+2.0*M_PI,
948                                                     thesense);
949           }
950         }
951       }
952     }
953       break;
954
955 //=============================================================================
956 //                       Bissectrice point - straight.                          +
957 //=============================================================================
958     case 2 : {
959       GccAna_LinPnt2dBisec Bisector(line,asecondpoint->Pnt2d());
960       
961 #ifdef OCCT_DEBUG
962       gp_Vec2d V(line.Direction());
963 #else
964       line.Direction();
965 #endif
966       Handle(GccInt_Bisec) solution = Bisector.ThisSolution();
967       Degenerate(solution,tolerance);      
968       GccInt_IType type = solution->ArcType();
969       Handle(Geom2d_Curve) bisectorcurve;
970       
971       if (type == GccInt_Lin) {
972         bisectorcurve = new Geom2d_Line(solution->Line());
973       }
974       else if (type == GccInt_Par) {
975         bisectorcurve = new Geom2d_Parabola(solution->Parabola());
976       }
977       sense = Standard_False;
978       distanceptsol = Distance(apoint,solution,
979                                afirstvector,asecondvector,VecRef,
980                                adirection,parameter,sense,ok);
981
982       if (ok || !oncurve) {
983         firstparameter = parameter;
984         thesense = sense;
985       }
986       
987       if (!thesense)
988         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
989                                               firstparameter, 
990                                               - Precision::Infinite());
991       else
992         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
993                                               firstparameter, 
994                                               Precision::Infinite());
995     }
996       break;
997
998     default:
999       {
1000         std::cout << "Not yet implemented" << std::endl;
1001         break;
1002       }
1003     }
1004 }
1005
1006
1007 //===========================================================================
1008 //  calculate the bissectrice between a curve and a point starting at a point. +
1009 //                                                                          +
1010 //   afirstpoint   : \ curves between which the                             +
1011 //   asecondcurve  : / bissectrice is calculated.                           +
1012 //   apoint        :   point through which the bissectrice should pass.     +
1013 //   afirstvector  : \ vectors to determine the secteur in which            +
1014 //   asecondvector : / the bissectrice should be located.                   +
1015 //   adirection    :   shows the side of the bissectrice to be preserved.   +
1016 //   tolerance     :   threshold at which the bisectrices become degenerated+
1017 //===========================================================================
1018
1019 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
1020                                 const Handle(Geom2d_Curve)& asecondcurve ,
1021                                 const gp_Pnt2d&             apoint       ,
1022                                 const gp_Vec2d&             afirstvector ,
1023                                 const gp_Vec2d&             asecondvector,
1024                                 const Standard_Real         adirection   ,
1025 //                              const Standard_Real         tolerance    ,
1026                                 const Standard_Real             ,
1027                                 const Standard_Boolean      oncurve       )
1028      
1029 {
1030   Standard_Real  adirectionreverse = - adirection;
1031   Perform(asecondcurve        , 
1032           afirstpoint         , 
1033           apoint              , 
1034           asecondvector       ,
1035           afirstvector        ,
1036           adirectionreverse   ,
1037 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
1038           0.,
1039 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
1040           oncurve             );
1041 }
1042
1043 //===========================================================================
1044 //        calculate the bissectrice between two points starting at a point. +
1045 //                                                                          +
1046 //   afirstpoint   : \ curves between which the                             +
1047 //   asecondpoint  : / bissectrice is calculated.                           +
1048 //   apoint        :   point through which the bissectrice should pass.     +
1049 //   afirstvector  : \ vectors to determine the sector in which the         +
1050 //   asecondvector : / bissectrice should be located.                       +
1051 //   adirection    :   shows the side of the bissectrice to be preserved.   +
1052 //===========================================================================
1053
1054 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
1055                                 const Handle(Geom2d_Point)& asecondpoint ,
1056                                 const gp_Pnt2d&             apoint       ,
1057                                 const gp_Vec2d&             afirstvector ,
1058                                 const gp_Vec2d&             asecondvector,
1059                                 const Standard_Real         adirection   ,
1060 //                              const Standard_Real         tolerance    ,
1061                                 const Standard_Real             ,
1062                                 const Standard_Boolean      oncurve       )
1063 {
1064   Standard_Boolean sense,ok;
1065   Standard_Real parameter;
1066   gp_Vec2d VecRef(0.,0.);
1067
1068   GccAna_Pnt2dBisec bisector(afirstpoint->Pnt2d(),asecondpoint->Pnt2d());
1069   gp_Lin2d line = bisector.ThisSolution();
1070   Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
1071
1072   sense = Standard_False;
1073   Distance(apoint,solution,
1074            afirstvector,asecondvector,VecRef,
1075            adirection,parameter,sense,ok);
1076   if (ok || !oncurve) {
1077     Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
1078     if (!sense)
1079       thebisector=new Geom2d_TrimmedCurve(bisectorcurve,
1080                                           parameter,- Precision::Infinite());
1081     else
1082       thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
1083                                            parameter,Precision::Infinite());
1084   }
1085 }
1086
1087 //=============================================================================
1088 //function : IsExtendAtStart
1089 //purpose  :
1090 //=============================================================================
1091 Standard_Boolean Bisector_BisecAna::IsExtendAtStart() const
1092 {
1093   return Standard_False;
1094 }
1095
1096 //=============================================================================
1097 //function : IsExtendAtEnd
1098 //purpose  :
1099 //=============================================================================
1100 Standard_Boolean Bisector_BisecAna::IsExtendAtEnd() const
1101 {
1102   return Standard_False;
1103 }
1104
1105 //=============================================================================
1106 //function : SetTrim
1107 //purpose  : Restriction of the bissectrice by the domain of the curve Cu.
1108 //           The domain of the curve is the set of points that are closer to the
1109 //           than to its extremities. 
1110 //           For the calculation the domain is extended. Extension of Epsilon1 of the 
1111 //           First and the Last parameter of the curve.
1112 //=============================================================================
1113 //void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& Cu)
1114 void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& )
1115 {
1116 /*
1117   Handle(Standard_Type)       Type;
1118   Handle(Geom2d_Curve)        TheCurve;
1119   Handle(Geom2d_Circle)       CircleCu;
1120   Handle(Geom2d_Line)         LineCu;
1121   Handle(Geom2d_Curve)        FirstLimit;
1122   Handle(Geom2d_Curve)        LastLimit;
1123
1124   gp_Lin2d                    gpLine;
1125   gp_Pnt2d                    P, PFirst, PLast, FirstPointBisector, Center;
1126   gp_Vec2d                    TanFirst, TanLast;
1127
1128   IntRes2d_Domain             FirstDomain;
1129   IntRes2d_Domain             LastDomain ;
1130   
1131   Standard_Real   UFirst, ULast, UB1, UB2;
1132   Standard_Real   UBisInt1, UBisInt2, Utrim;
1133   Standard_Real   Distance;
1134   Standard_Real   Radius;
1135
1136   Standard_Real Epsilon1  = 1.E-6; // Epsilon sur le parametre de la courbe.
1137   Standard_Real Tolerance = 1.E-8; // Tolerance pour les intersections.
1138
1139    Type = Cu->DynamicType();
1140
1141   if (Type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1142     TheCurve = Handle(Geom2d_TrimmedCurve)::DownCast(Cu)->BasisCurve();
1143     Type     = TheCurve->DynamicType();
1144   }
1145   else {
1146     TheCurve = Cu;
1147   }
1148
1149   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1150     CircleCu = Handle(Geom2d_Circle)::DownCast(TheCurve);
1151   }
1152   else {
1153     LineCu = Handle(Geom2d_Line)::DownCast(TheCurve);
1154   }
1155
1156   // Recuperation de UFirst, ULast.
1157   // -------------------------------
1158   UFirst   = Cu->FirstParameter();
1159   ULast    = Cu->LastParameter();
1160
1161   // Creation des lignes Limites du domaine si elles existent.
1162   // et Determination de leur domaine d intersection.
1163   // ---------------------------------------------------------
1164   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1165     CircleCu->D1(UFirst,PFirst,TanFirst);
1166     CircleCu->D1(ULast ,PLast ,TanLast);
1167     Radius = CircleCu->Radius();
1168
1169     if (PFirst.Distance(PLast) > 2.*Epsilon1 && Radius > Epsilon1) {
1170       Center     = CircleCu->Location();
1171       P          = PFirst.Translated( - (Epsilon1/Radius)*TanFirst );
1172
1173       FirstLimit = new Geom2d_Line(P,
1174                                    gp_Dir2d(PFirst.X() - Center.X(), 
1175                                             PFirst.Y() - Center.Y()));
1176       P          = PLast .Translated( (Epsilon1/Radius)*TanLast );
1177
1178       LastLimit  = new Geom2d_Line(P,
1179                                    gp_Dir2d(PLast.X() - Center.X(), 
1180                                             PLast.Y() - Center.Y()));
1181
1182       Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1183       Geom2dAdaptor_Curve ALastLimit (LastLimit);
1184       Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1185                                  ALastLimit  , LastDomain ,
1186                                  Tolerance   , Tolerance     );
1187       
1188       if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1189         if (Intersect.NbPoints() >= 1) {
1190           FirstDomain.SetValues(Intersect.Point(1).Value(),
1191                                 Intersect.Point(1).ParamOnFirst(),
1192                                 Tolerance,Standard_True);
1193           LastDomain. SetValues(Intersect.Point(1).Value(),
1194                                 Intersect.Point(1).ParamOnSecond(),
1195                                 Tolerance,Standard_True);
1196         }
1197       }
1198     }  
1199   }
1200   else if (Type == STANDARD_TYPE(Geom2d_Line)) {
1201     gpLine = LineCu->Lin2d();
1202     if (UFirst > - Precision::Infinite()){
1203       P          = LineCu->Value(UFirst - Epsilon1);
1204       FirstLimit = new Geom2d_Line(gpLine.Normal(P)) ;
1205     }
1206     if (ULast < Precision::Infinite()) {
1207       P         = LineCu->Value(ULast + Epsilon1);
1208       LastLimit = new Geom2d_Line(gpLine.Normal(P));
1209     }
1210   }
1211   else {
1212     throw Standard_NotImplemented();
1213   }
1214     
1215   // Determination domaine d intersection de la Bissectrice.
1216   // -------------------------------------------------------
1217   UB1 = thebisector->FirstParameter();
1218   UB2 = thebisector->LastParameter();
1219   if (UB2 > 10000.) {
1220     UB2 = 10000.;
1221     Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1222     Handle(Standard_Type) Type1 = BasisCurve->DynamicType();
1223     gp_Parab2d gpParabola;
1224     gp_Hypr2d  gpHyperbola;
1225     Standard_Real Focus;
1226     Standard_Real Limit = 50000.;
1227     if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1228       gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1229       Focus = gpParabola.Focal();
1230       Standard_Real Val1 = Sqrt(Limit*Focus);
1231       Standard_Real Val2 = Sqrt(Limit*Limit);
1232       UB2 = (Val1 <= Val2 ? Val1:Val2);
1233     }
1234     else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1235       gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1236       Standard_Real Majr  = gpHyperbola.MajorRadius();
1237       Standard_Real Minr  = gpHyperbola.MinorRadius();
1238       Standard_Real Valu1 = Limit/Majr;
1239       Standard_Real Valu2 = Limit/Minr;
1240       Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1241       Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1242       UB2 = (Val1 <= Val2 ? Val1:Val2);
1243     }
1244   }
1245
1246   IntRes2d_Domain DomainBisector(thebisector->Value(UB1), UB1, Tolerance,
1247                                  thebisector->Value(UB2), UB2, Tolerance);
1248
1249   if (thebisector->BasisCurve()->IsPeriodic()) {
1250     DomainBisector.SetEquivalentParameters(0.0,2.*M_PI);
1251   }
1252   FirstPointBisector = thebisector->Value(UB1);
1253
1254
1255   // Intersection Bisectrice avec FirstLimit => UBisInt1.
1256   // ----------------------------------------------------
1257   UBisInt1 = Precision::Infinite();
1258   if (!FirstLimit.IsNull()) {
1259     Geom2dAdaptor_Curve AdapBis    (thebisector);
1260     Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1261     Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1262                                AdapBis     , DomainBisector,
1263                                Tolerance   , Tolerance     );
1264
1265     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1266       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1267         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1268         if (Distance > 2.*Tolerance) {
1269           UBisInt1 = Intersect.Point(i).ParamOnSecond();
1270           break;
1271         }
1272       }
1273     } 
1274   } 
1275   // Intersection Bisectrice avec LastLimit => UBisInt2.
1276   // ---------------------------------------------------
1277   UBisInt2 = Precision::Infinite();
1278   if (!LastLimit.IsNull()) {
1279     Geom2dAdaptor_Curve AdapBis    (thebisector);
1280     Geom2dAdaptor_Curve ALastLimit (LastLimit);
1281     Geom2dInt_GInter Intersect(ALastLimit , LastDomain    ,
1282                                AdapBis    , DomainBisector, 
1283                                Tolerance  , Tolerance     );
1284
1285     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1286       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1287         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1288         if (Distance > 2.*Tolerance) {
1289           UBisInt2 = Intersect.Point(i).ParamOnSecond();
1290           break;
1291         }
1292       }
1293     }
1294   }
1295   // Restriction de la Bissectrice par le point d intersection de plus petit
1296   // parametre.
1297   //------------------------------------------------------------------------
1298   Utrim = (UBisInt1 < UBisInt2) ? UBisInt1 : UBisInt2;
1299   
1300   if (Utrim < UB2 && Utrim > UB1) thebisector->SetTrim(UB1,Utrim);
1301 */
1302 }
1303
1304 void Bisector_BisecAna::SetTrim(const Standard_Real uf, const Standard_Real ul)
1305 {
1306   thebisector->SetTrim(uf, ul);
1307 }
1308 //=============================================================================
1309 //function : Reverse 
1310 //purpose  :
1311 //=============================================================================
1312 void Bisector_BisecAna::Reverse()
1313 {
1314   thebisector->Reverse();
1315 }
1316
1317 //=============================================================================
1318 //function : ReversedParameter 
1319 //purpose  :
1320 //=============================================================================
1321 Standard_Real Bisector_BisecAna::ReversedParameter(const Standard_Real U) const 
1322 {
1323   return thebisector->ReversedParameter(U);
1324 }
1325
1326 //=============================================================================
1327 //function : IsCN
1328 //purpose  :
1329 //=============================================================================
1330 Standard_Boolean Bisector_BisecAna::IsCN(const Standard_Integer N) const 
1331 {
1332   return thebisector->IsCN(N);
1333 }
1334
1335 //=============================================================================
1336 //function : Copy 
1337 //purpose  :
1338 //=============================================================================
1339 Handle(Geom2d_Geometry) Bisector_BisecAna::Copy() const 
1340 {
1341   Handle(Bisector_BisecAna) C = new  Bisector_BisecAna();
1342   C->Init (Handle(Geom2d_TrimmedCurve)::DownCast(thebisector->Copy()));
1343   return C;
1344 }
1345
1346 //=============================================================================
1347 //function : Transform
1348 //purpose  :
1349 //=============================================================================
1350 void Bisector_BisecAna::Transform(const gp_Trsf2d& T)
1351 {
1352   thebisector->Transform(T);
1353 }
1354
1355 //=============================================================================
1356 //function : FirstParameter
1357 //purpose  :
1358 //=============================================================================
1359 Standard_Real Bisector_BisecAna::FirstParameter() const 
1360 {
1361 //  modified by NIZHNY-EAP Thu Feb  3 17:23:42 2000 ___BEGIN___
1362 //  return thebisector->BasisCurve()->FirstParameter();
1363   return thebisector->FirstParameter();
1364 //  modified by NIZHNY-EAP Thu Feb  3 17:23:48 2000 ___END___
1365 }
1366
1367 //=============================================================================
1368 //function : LastParameter
1369 //purpose  :
1370 //=============================================================================
1371 Standard_Real Bisector_BisecAna::LastParameter() const 
1372 {
1373   return thebisector->LastParameter();
1374 }
1375
1376 //=============================================================================
1377 //function : IsClosed
1378 //purpose  :
1379 //=============================================================================
1380 Standard_Boolean Bisector_BisecAna::IsClosed() const 
1381 {
1382   return thebisector->BasisCurve()->IsClosed(); 
1383 }
1384
1385 //=============================================================================
1386 //function : IsPeriodic
1387 //purpose  :
1388 //=============================================================================
1389 Standard_Boolean Bisector_BisecAna::IsPeriodic() const 
1390 {
1391   return thebisector->BasisCurve()->IsPeriodic(); 
1392 }
1393
1394 //=============================================================================
1395 //function : Continuity
1396 //purpose  :
1397 //=============================================================================
1398 GeomAbs_Shape Bisector_BisecAna::Continuity() const 
1399 {
1400  return thebisector->Continuity(); 
1401 }
1402
1403 //=============================================================================
1404 //function : D0 
1405 //purpose  :
1406 //=============================================================================
1407 void Bisector_BisecAna::D0(const Standard_Real U, gp_Pnt2d& P) const 
1408 {
1409   thebisector->BasisCurve()->D0(U,P);
1410 }
1411
1412 //=============================================================================
1413 //function : D1
1414 //purpose  :
1415 //=============================================================================
1416 void Bisector_BisecAna::D1(const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1) const 
1417 {
1418   thebisector->BasisCurve()->D1(U,P,V1);
1419 }
1420 //=============================================================================
1421 //function : D2
1422 //purpose  :
1423 //=============================================================================
1424 void Bisector_BisecAna::D2(const Standard_Real U, 
1425                            gp_Pnt2d&           P, 
1426                            gp_Vec2d&           V1, 
1427                            gp_Vec2d&           V2) const 
1428 {
1429   thebisector->BasisCurve()->D2(U,P,V1,V2);
1430 }
1431 //=============================================================================
1432 //function : D3
1433 //purpose  :
1434 //=============================================================================
1435 void Bisector_BisecAna::D3(const Standard_Real U,
1436                            gp_Pnt2d&           P, 
1437                            gp_Vec2d&           V1, 
1438                            gp_Vec2d&           V2, 
1439                            gp_Vec2d&           V3) const 
1440 {
1441   thebisector->BasisCurve()->D3(U,P,V1,V2,V3);
1442 }
1443 //=============================================================================
1444 //function : DN
1445 //purpose  :
1446 //=============================================================================
1447 gp_Vec2d Bisector_BisecAna::DN(const Standard_Real U, const Standard_Integer N) const 
1448 {
1449   return thebisector->BasisCurve()->DN (U, N);
1450 }
1451
1452 //=============================================================================
1453 //function : Geom2dCurve
1454 //purpose  :
1455 //=============================================================================
1456 Handle(Geom2d_Curve) Bisector_BisecAna::Geom2dCurve() const
1457 {
1458   return thebisector->BasisCurve();
1459 }
1460
1461 //==========================================================================
1462 //function : ParameterOfStartPoint
1463 //purpose  :
1464 //==========================================================================
1465 Standard_Real Bisector_BisecAna::ParameterOfStartPoint() const
1466 {
1467   return thebisector->FirstParameter();
1468 }
1469
1470 //==========================================================================
1471 //function : ParameterOfEndPoint
1472 //purpose  :
1473 //==========================================================================
1474 Standard_Real Bisector_BisecAna::ParameterOfEndPoint() const
1475 {
1476   return thebisector->LastParameter();
1477 }
1478
1479 //==========================================================================
1480 //function : Parameter
1481 //purpose  :
1482 //==========================================================================
1483 Standard_Real Bisector_BisecAna::Parameter(const gp_Pnt2d& P) const
1484 {
1485   gp_Hypr2d  gphyperbola;
1486   gp_Parab2d gpparabola ;
1487   gp_Elips2d gpellipse  ;
1488   gp_Circ2d  gpcircle   ;
1489   gp_Lin2d   gpline     ;
1490
1491   Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1492   Handle(Standard_Type) Type       = BasisCurve ->DynamicType();
1493   
1494   if (Type == STANDARD_TYPE(Geom2d_Line)) {
1495     gpline     = Handle(Geom2d_Line)::DownCast(BasisCurve)->Lin2d();
1496     return ElCLib::Parameter(gpline,P);
1497   }
1498   else if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1499     gpcircle   = Handle(Geom2d_Circle)::DownCast(BasisCurve)->Circ2d();
1500     return ElCLib::Parameter(gpcircle,P);
1501   } 
1502    else if (Type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1503     gphyperbola   = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1504     return ElCLib::Parameter(gphyperbola,P);
1505   }
1506   else if (Type == STANDARD_TYPE(Geom2d_Parabola)) {
1507     gpparabola   = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1508     return ElCLib::Parameter(gpparabola,P);
1509   }
1510   else if (Type == STANDARD_TYPE(Geom2d_Ellipse)) {
1511     gpellipse   = Handle(Geom2d_Ellipse)::DownCast(BasisCurve)->Elips2d();
1512     return ElCLib::Parameter(gpellipse,P);
1513   }
1514   return 0.;
1515 }
1516
1517 //=============================================================================
1518 //function : NbIntervals
1519 //purpose  :
1520 //=============================================================================
1521 Standard_Integer Bisector_BisecAna::NbIntervals() const
1522 {
1523   return 1;
1524 }
1525
1526 //=============================================================================
1527 //function : IntervalFirst
1528 //purpose  :
1529 //=============================================================================
1530 Standard_Real Bisector_BisecAna::IntervalFirst(const Standard_Integer I) const
1531 {
1532   if (I != 1) throw Standard_OutOfRange();
1533   return FirstParameter();
1534 }
1535
1536 //=============================================================================
1537 //function : IntervalLast
1538 //purpose  : 
1539 //=============================================================================
1540 Standard_Real Bisector_BisecAna::IntervalLast(const Standard_Integer I) const
1541 {  
1542   if (I != 1) throw Standard_OutOfRange();
1543   return LastParameter();
1544 }
1545
1546 //=============================================================================
1547 //function :           
1548 //=============================================================================
1549 void Bisector_BisecAna::Init(const Handle(Geom2d_TrimmedCurve)& Bis)
1550 {
1551   thebisector = Bis;
1552 }
1553
1554 //=============================================================================
1555 //function : Degenerate
1556 //purpose  : Replace the bisectrice by a straight line,
1557 //           if the bisectrice is an ellipse, a parabole or a degenerated ellipse.
1558 //=============================================================================
1559 Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
1560                             const Standard_Real   Tolerance)
1561 {
1562   Standard_Boolean Degeneree = Standard_False;
1563
1564   gp_Hypr2d  gphyperbola;
1565   gp_Parab2d gpparabola ;
1566   gp_Elips2d gpellipse  ;
1567   //gp_Circ2d  gpcircle   ;
1568
1569   Handle(GccInt_Bisec) NewBisector;
1570
1571   GccInt_IType type = aBisector->ArcType();
1572
1573   if (type == GccInt_Hpr) {
1574     gphyperbola   = aBisector->Hyperbola();
1575
1576     // If the Hyperbola is degenerated, it is replaced by the straight line
1577     // with direction to the axis if symmetry.
1578
1579     if (gphyperbola.MajorRadius() < Tolerance) {
1580       gp_Lin2d gpline(gphyperbola.YAxis());
1581       NewBisector = new GccInt_BLine(gpline);
1582       aBisector   = NewBisector;
1583       Degeneree   = Standard_True;
1584     }
1585     if (gphyperbola.MinorRadius() < Tolerance) {
1586       gp_Lin2d gpline(gphyperbola.XAxis());
1587       NewBisector = new GccInt_BLine(gpline);
1588       aBisector   = NewBisector;
1589       Degeneree   = Standard_True;
1590     }
1591   }
1592   else if (type == GccInt_Par) {
1593     gpparabola   = aBisector->Parabola();
1594     
1595     // If the parabole is degenerated, it is replaces by the straight 
1596     // line starting at the Top and with direction of the axis of symmetry.
1597     
1598     if (gpparabola.Focal() < Tolerance) {
1599       gp_Lin2d gpline(gpparabola.MirrorAxis());
1600       NewBisector = new GccInt_BLine(gpline);
1601       aBisector   = NewBisector;
1602       Degeneree   = Standard_True;
1603     }
1604   }
1605   else if (type == GccInt_Ell) {
1606     gpellipse   = aBisector->Ellipse();
1607     
1608     // If the ellipse is degenerated, it is replaced by the straight line 
1609     // defined by the great axis.
1610     
1611     if (gpellipse.MinorRadius() < Tolerance) {
1612       gp_Lin2d gpline(gpellipse.XAxis());
1613       NewBisector = new GccInt_BLine(gpline);
1614       aBisector   = NewBisector;
1615       Degeneree   = Standard_True;
1616     }
1617   }
1618   return Degeneree;
1619
1620
1621 static void Indent (const Standard_Integer Offset) {
1622   if (Offset > 0) {
1623     for (Standard_Integer i = 0; i < Offset; i++) { std::cout << " "; }
1624   }
1625 }
1626
1627 //=============================================================================
1628 //function : Dump
1629 // purpose : 
1630 //=============================================================================
1631 //void Bisector_BisecAna::Dump(const Standard_Integer Deep, 
1632 void Bisector_BisecAna::Dump(const Standard_Integer , 
1633                              const Standard_Integer Offset) const 
1634 {
1635   Indent (Offset);
1636   std::cout<<"Bisector_BisecAna"<<std::endl;
1637   Indent (Offset);
1638 //  thebisector->Dump();
1639 }