0025298: New option of BRepOffsetAPI_MakeOffset algorithm: processing of sharp corner...
[occt.git] / src / MAT2d / MAT2d_Tool2d.cxx
1 // Created on: 1993-07-12
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1993-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 #define Debug(expr)  cout<<" MAT2d_Tool2d.cxx  :  expr :"<<expr<<endl;
18
19 #ifdef DRAW
20 #include <DBRep.hxx>
21 #include <DrawTrSurf.hxx>
22 #include <stdio.h>
23 #endif
24
25 #ifdef DRAW
26 #include <Draw_Appli.hxx>
27 #include <DrawTrSurf_Curve2d.hxx>
28 #include <GCE2d_MakeSegment.hxx>
29 #include <DrawTrSurf.hxx>
30 #endif
31
32 #include <MAT2d_Tool2d.ixx>
33 #include <MAT2d_MiniPath.hxx>
34 #include <MAT2d_Connexion.hxx>
35 #include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
36 #include <MAT_Edge.hxx>
37 #include <Bisector_Curve.hxx>
38 #include <Bisector_BisecAna.hxx>
39 #include <Bisector_BisecCC.hxx>
40 #include <Bisector_Bisec.hxx>
41 #include <Bisector_Inter.hxx>
42 #include <IntRes2d_Domain.hxx>
43 #include <Extrema_ExtPC2d.hxx>
44 #include <Geom2dInt_GInter.hxx>
45 #include <IntRes2d_IntersectionPoint.hxx>
46 #include <IntRes2d_IntersectionSegment.hxx>
47 #include <Geom2d_Geometry.hxx>
48 #include <Geom2d_Point.hxx>
49 #include <Geom2d_Line.hxx>
50 #include <Geom2d_Circle.hxx>
51 #include <Geom2d_Curve.hxx>
52 #include <Geom2d_Parabola.hxx>
53 #include <Geom2d_Hyperbola.hxx>
54 #include <Geom2d_Ellipse.hxx>
55 #include <Geom2d_CartesianPoint.hxx>
56 #include <Geom2d_TrimmedCurve.hxx>
57 #include <Geom2dAdaptor_Curve.hxx>
58 #include <gp_Lin2d.hxx>
59 #include <gp_Hypr2d.hxx>
60 #include <gp_Parab2d.hxx>
61 #include <gp_Elips2d.hxx>
62 #include <gp_Circ2d.hxx>
63 #include <gp_Vec2d.hxx>
64 #include <TColStd_Array1OfReal.hxx>
65 #include <ElCLib.hxx>
66 #include <StdFail_NotDone.hxx>
67 #include <Standard_NotImplemented.hxx>
68 #include <Precision.hxx>
69
70 #ifdef DRAW
71   static Handle(DrawTrSurf_Curve2d) draw;
72 #endif
73 #ifdef DEB
74   static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
75                               const Standard_Integer      Indice);
76   static Standard_Boolean Store = Standard_False;
77 #endif
78
79 //=====================================================================
80 //  static functions 
81 //=====================================================================
82 static IntRes2d_Domain Domain
83   (const Handle(Geom2d_TrimmedCurve)& Bisector1,
84    const Standard_Real                Tolerance);
85
86 static Handle(Standard_Type) Type (const Handle(Geom2d_Geometry)& acurve);
87
88 static Standard_Boolean AreNeighbours(const Standard_Integer IEdge1,
89                                       const Standard_Integer IEdge2,
90                                       const Standard_Integer NbEdge);
91
92 static void SetTrim(Bisector_Bisec&  Bis , Handle(Geom2d_Curve)& Line1);
93
94 static Standard_Real MAT2d_TOLCONF = 1.e-7;
95
96 //============================================================================
97 //function : 
98 //purpose  :
99 //============================================================================
100 MAT2d_Tool2d::MAT2d_Tool2d()
101 {
102   theDirection         = 1.;
103   theJoinType = GeomAbs_Arc; //default
104   theNumberOfBisectors = 0;
105   theNumberOfVecs      = 0;
106   theNumberOfPnts      = 0;
107 }
108
109 //=============================================================================
110 //function : InitItems
111 //purpose  :
112 //=============================================================================
113 void  MAT2d_Tool2d::InitItems(const Handle(MAT2d_Circuit)& EquiCircuit) 
114 {
115   theGeomBisectors.Clear();
116   theGeomPnts.Clear();
117   theGeomVecs.Clear();
118   theLinesLength.Clear();
119   theNumberOfBisectors = 0;
120   theNumberOfVecs      = 0;
121   theNumberOfPnts      = 0; 
122    
123   theCircuit = EquiCircuit;
124 }
125                         
126 //=============================================================================
127 //function : Sense
128 //purpose  :
129 //=============================================================================
130 void MAT2d_Tool2d::Sense(const MAT_Side aside)
131 {
132   if(aside == MAT_Left) theDirection =  1.;
133   else                  theDirection = -1.;
134 }
135
136 //=============================================================================
137 //function : SetJoinType
138 //purpose  :
139 //=============================================================================
140 void MAT2d_Tool2d::SetJoinType(const GeomAbs_JoinType aJoinType)
141 {
142   theJoinType = aJoinType;
143 }
144
145 //=============================================================================
146 //function : NumberOfItems
147 //purpose  :
148 //=============================================================================
149 Standard_Integer MAT2d_Tool2d::NumberOfItems() const
150 {
151   return theCircuit->NumberOfItems();
152 }
153
154 //=============================================================================
155 //function : ToleranceOfConfusion
156 //purpose  :
157 //=============================================================================
158 Standard_Real MAT2d_Tool2d::ToleranceOfConfusion() const
159 {
160   return 2*MAT2d_TOLCONF;
161 }
162
163 //=============================================================================
164 //function : FirstPoint
165 //purpose  :
166 //=============================================================================
167 Standard_Integer MAT2d_Tool2d::FirstPoint(const Standard_Integer anitem,
168                                                 Standard_Real&   dist  ) 
169 {
170   Handle(Geom2d_Curve) curve;
171   Handle(Geom2d_Point) point;
172   theNumberOfPnts++;
173
174   if (theCircuit->ConnexionOn(anitem)){
175     gp_Pnt2d P1 = theCircuit->Connexion(anitem)->PointOnFirst();
176     gp_Pnt2d P2 = theCircuit->Connexion(anitem)->PointOnSecond();
177     theGeomPnts.Bind(theNumberOfPnts,gp_Pnt2d((P1.X() + P2.X())*0.5,
178                                               (P1.Y() + P2.Y())*0.5));
179     dist = P1.Distance(P2)*0.5;
180     return theNumberOfPnts;
181   }
182
183   Handle(Standard_Type) type;
184   type = theCircuit->Value(anitem)->DynamicType();
185   dist = 0.;
186
187   if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
188     curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
189     theGeomPnts.Bind(theNumberOfPnts,curve->Value(curve->FirstParameter()));
190   }
191   else{
192     point = Handle(Geom2d_Point)::DownCast(theCircuit->Value(anitem));
193     theGeomPnts.Bind(theNumberOfPnts,point->Pnt2d());
194   }
195   return theNumberOfPnts;
196 }
197
198 //=============================================================================
199 //function : TangentBefore
200 //purpose  :
201 //=============================================================================
202 Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem) 
203 {
204   Standard_Integer     item;
205   Handle(Geom2d_Curve) curve;
206   theNumberOfVecs++;
207   
208   item  = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
209   if (theCircuit->ConnexionOn(item)){
210     Standard_Real x1,y1,x2,y2;
211     theCircuit->Connexion(item)->PointOnFirst().Coord(x1,y1);
212     theCircuit->Connexion(item)->PointOnSecond().Coord(x2,y2);
213     theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x2-x1),(y2-y1)));
214     return theNumberOfVecs;
215   }
216
217   Handle(Standard_Type) type;
218   type = theCircuit->Value(anitem)->DynamicType();
219   if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
220     curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
221     theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->LastParameter(),1));
222   }
223   else {
224     curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
225     theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->FirstParameter(),1));
226   }
227
228   return theNumberOfVecs;
229 }
230
231 //=============================================================================
232 //function : TangentAfter
233 //purpose  :
234 //=============================================================================
235 Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem)
236 {
237   Standard_Integer     item;
238   Handle(Geom2d_Curve) curve;
239   gp_Vec2d             thevector;
240   theNumberOfVecs++;
241
242   if (theCircuit->ConnexionOn(anitem)){
243     Standard_Real x1,y1,x2,y2;
244     theCircuit->Connexion(anitem)->PointOnFirst().Coord(x1,y1);
245     theCircuit->Connexion(anitem)->PointOnSecond().Coord(x2,y2);
246     theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x1-x2),(y1-y2)));
247     return theNumberOfVecs;
248   }
249
250   Handle(Standard_Type) type;
251   type = theCircuit->Value(anitem)->DynamicType();
252   if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
253     curve     = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
254     thevector = curve->DN(curve->FirstParameter(),1);
255   }
256   else {
257     item      = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
258     curve     = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
259     thevector = curve->DN(curve->LastParameter(),1);
260   }
261   theGeomVecs.Bind(theNumberOfVecs,thevector.Reversed());
262   return theNumberOfVecs;
263 }
264
265 //=============================================================================
266 //function : Tangent
267 //purpose  :
268 //=============================================================================
269 Standard_Integer MAT2d_Tool2d::Tangent(const Standard_Integer bisector)
270 {
271   theNumberOfVecs++;
272   theGeomVecs.Bind(theNumberOfVecs,GeomBis(bisector).Value()
273                    ->DN(GeomBis(bisector).Value()
274                         ->LastParameter(),1));
275   return theNumberOfVecs;
276 }
277
278 //=============================================================================
279 //function : CreateBisector
280 //purpose  :
281 //=============================================================================
282 void MAT2d_Tool2d::CreateBisector(const Handle(MAT_Bisector)& abisector)
283 {
284   Handle(Geom2d_Point)    point1,point2;
285   Handle(Geom2d_Geometry) elt1,elt2;
286   Bisector_Bisec          bisector;
287   Standard_Real           tolerance    = MAT2d_TOLCONF ;
288
289   Standard_Integer edge1number  = abisector->FirstEdge()->EdgeNumber();
290   Standard_Integer edge2number  = abisector->SecondEdge()->EdgeNumber();
291   Standard_Boolean ontheline    = AreNeighbours(edge1number,
292                                                 edge2number,
293                                                 NumberOfItems());
294   Standard_Boolean InitialNeighbour = ontheline;
295
296   if(theCircuit->ConnexionOn(edge2number)) ontheline = Standard_False;
297
298   elt1 = theCircuit->Value(edge1number);
299   elt2 = theCircuit->Value(edge2number);
300
301   Handle(Standard_Type) type1;
302   type1 = theCircuit->Value(edge1number)->DynamicType();
303   Handle(Standard_Type) type2;
304   type2 = theCircuit->Value(edge2number)->DynamicType();
305   Handle(Geom2d_Curve)  item1;
306   Handle(Geom2d_Curve)  item2;
307
308   if ( type1 != STANDARD_TYPE(Geom2d_CartesianPoint)){
309     item1 = Handle(Geom2d_Curve)::DownCast(elt1);
310   }
311
312   if ( type2 != STANDARD_TYPE(Geom2d_CartesianPoint)){
313     item2 = Handle(Geom2d_Curve)::DownCast(elt2);
314   }
315
316 #ifdef DEB
317   Standard_Boolean Affich = Standard_False;
318   if (Affich) {
319     cout<<endl; 
320     cout<<"BISECTOR number :  "<<theNumberOfBisectors+1<<endl;
321     cout<<"  Item 1 : "<<endl;
322     cout<<edge1number<<endl;
323     cout<<endl;
324 //    elt1->Dump(1,1);
325     cout<<endl;
326     cout<<"  Item 2 : "<<endl;
327     cout<<edge2number<<endl;
328     cout<<endl;
329 //  elt2->Dump(1,1);
330     cout<<endl;
331   }
332 #endif
333
334   if(type1 != STANDARD_TYPE(Geom2d_CartesianPoint) && 
335      type2 != STANDARD_TYPE(Geom2d_CartesianPoint)) {
336     bisector.Perform(item1,item2,
337                      GeomPnt (abisector->IssuePoint()),
338                      GeomVec (abisector->FirstVector()),
339                      GeomVec (abisector->SecondVector()),
340                      theDirection,tolerance,ontheline);
341   }
342   else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint) && 
343           type2 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
344     point1 = Handle(Geom2d_Point)::DownCast(elt1);
345     point2 = Handle(Geom2d_Point)::DownCast(elt2);
346     bisector.Perform(point1,point2,
347                      GeomPnt (abisector->IssuePoint()),
348                      GeomVec (abisector->FirstVector()),
349                      GeomVec (abisector->SecondVector()),
350                      theDirection,tolerance,ontheline);
351   }
352   else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
353     point1 = Handle(Geom2d_Point)::DownCast(elt1);
354     bisector.Perform(point1,item2,
355                      GeomPnt (abisector->IssuePoint()),
356                      GeomVec (abisector->FirstVector()),
357                      GeomVec (abisector->SecondVector()),
358                      theDirection,tolerance,ontheline);
359   }
360   else {
361     point2 = Handle(Geom2d_Point)::DownCast(elt2);
362     bisector.Perform(item1,point2,
363                      GeomPnt (abisector->IssuePoint()),
364                      GeomVec (abisector->FirstVector()),
365                      GeomVec (abisector->SecondVector()),
366                      theDirection,tolerance,ontheline);
367   }
368
369   //------------------------------
370   // Restriction de la bisectrice.
371   //-----------------------------
372   TrimBisec(bisector,edge1number,InitialNeighbour,1);
373   TrimBisec(bisector,edge2number,InitialNeighbour,2);
374
375   theNumberOfBisectors++;
376   theGeomBisectors.Bind(theNumberOfBisectors,bisector);
377
378   abisector->BisectorNumber(theNumberOfBisectors);
379   abisector->Sense(1);
380
381 #ifdef DEB
382   Standard_Boolean AffichDraw = Standard_False;
383   if (AffichDraw) Dump(abisector->BisectorNumber(),1);
384   if (Store) {    
385     Handle(Standard_Type) Type1 = Type(bisector.Value()->BasisCurve());    
386     Handle(Geom2d_Curve)  BasisCurve;
387     if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) {
388       BasisCurve = Handle(Bisector_BisecAna)
389         ::DownCast(bisector.Value()->BasisCurve())->Geom2dCurve();
390 #ifdef DRAW
391       char  *name = new char[100];
392       sprintf(name,"BISSEC_%d",abisector->BisectorNumber());
393       DrawTrSurf::Set(name,BasisCurve);
394       delete [] name;
395 #endif
396     }
397   }
398 #endif
399 }
400
401 //=============================================================================
402 //function : TrimBisec
403 //purpose  : Restriction de la bisectrice.
404 //           Restriction des bissectrice separant deux elements lies par une
405 //           connexion ou l un au moins des elements est un cercle.
406 //           Cette restriction est necessaire a la logique de l algorithme.
407 //=============================================================================
408 void MAT2d_Tool2d::TrimBisec (      Bisector_Bisec&  B1,
409                               const Standard_Integer IndexEdge,
410                               const Standard_Boolean InitialNeighbour,
411                               const Standard_Integer StartOrEnd      ) const
412 {
413   Handle(Geom2d_Curve)        Curve;
414   Handle(Geom2d_TrimmedCurve) LineSupportDomain,Line;
415   Handle(Geom2d_Line)         Line1,Line2;
416   
417   //gp_Vec2d             Tan1,Tan2;
418   gp_Pnt2d             Ori; //PEdge;
419   Standard_Integer     INext;
420   INext = (IndexEdge == theCircuit->NumberOfItems()) ? 1  : (IndexEdge + 1);
421   
422   Handle(Standard_Type) EdgeType = theCircuit->Value(IndexEdge)->DynamicType();
423   
424   if (EdgeType != STANDARD_TYPE(Geom2d_CartesianPoint)) {
425     if(!InitialNeighbour) {
426       Curve = Handle(Geom2d_TrimmedCurve)
427         ::DownCast(theCircuit->Value(IndexEdge))->BasisCurve();
428       EdgeType = Curve->DynamicType();
429       //-------------------------------------------------------------------
430       // si l edge est liee a sa voisine  precedente par une connexion.
431       //-------------------------------------------------------------------
432       if (theCircuit->ConnexionOn(IndexEdge) && StartOrEnd == 1){
433         if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) {
434           Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location();
435           gp_Pnt2d P2 = theCircuit->Connexion(IndexEdge)->PointOnFirst();
436           Line1       = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(),
437                                                       P2.Y() - Ori.Y()));
438         }     
439       }
440       //-----------------------------------------------------------------------
441       // Si l edge est liee a sa voisine suivante par une connexion.
442       //-----------------------------------------------------------------------
443       if (theCircuit->ConnexionOn(INext) && StartOrEnd == 2){
444         if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) {
445           Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location();
446           gp_Pnt2d P2 = theCircuit->Connexion(INext)->PointOnSecond();
447           Line2       = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(),
448                                                       P2.Y() - Ori.Y()));
449         }
450       }
451       if (Line1.IsNull() && Line2.IsNull()) return;
452
453       //-----------------------------------------------------------------------
454       // Restriction de la bisectrice par les demi-droites liees aux connexions
455       // si elles existent.
456       //-----------------------------------------------------------------------
457       if (!Line1.IsNull()) {
458         Line = new Geom2d_TrimmedCurve(Line1,0.,Precision::Infinite());
459         SetTrim(B1,Line);
460       }
461       if (!Line2.IsNull()) {
462         Line = new Geom2d_TrimmedCurve(Line2,0.,Precision::Infinite());
463         SetTrim(B1,Line);
464       }
465     }
466   }
467 }
468
469 //=============================================================================
470 //function : TrimBisector
471 //purpose  :
472 //=============================================================================
473 Standard_Boolean MAT2d_Tool2d::TrimBisector
474   (const Handle(MAT_Bisector)& abisector)
475 {
476   Standard_Real param = abisector->FirstParameter();
477
478 #ifdef DEB
479   Standard_Boolean Affich = Standard_False;
480   if (Affich) cout<<"TRIM de "<<abisector->BisectorNumber()<<endl;
481 #endif
482
483   Handle(Geom2d_TrimmedCurve) 
484     bisector = Handle(Geom2d_TrimmedCurve)
485       ::DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
486   
487   if(bisector->BasisCurve()->IsPeriodic() && param == Precision::Infinite()) {
488     param = bisector->FirstParameter() + 2*M_PI;
489   }
490   if (param > bisector->BasisCurve()->LastParameter()) {
491    param = bisector->BasisCurve()->LastParameter(); 
492   }
493   if(bisector->FirstParameter() == param) return Standard_False;
494
495   bisector->SetTrim(bisector->FirstParameter(),param);
496   return Standard_True;
497 }
498
499 //=============================================================================
500 //function : TrimBisector
501 //purpose  :
502 //=============================================================================
503 Standard_Boolean MAT2d_Tool2d::TrimBisector
504   (const Handle(MAT_Bisector)& abisector,
505    const Standard_Integer      apoint)
506 {
507   Standard_Real Param;
508   Handle(Geom2d_TrimmedCurve)
509     Bisector = Handle(Geom2d_TrimmedCurve)::
510       DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
511
512   Handle(Bisector_Curve) Bis = Handle(Bisector_Curve)::
513     DownCast(Bisector->BasisCurve());
514
515 //  Param = ParameterOnCurve(Bisector,theGeomPnts.Value(apoint));
516   Param = Bis->Parameter(GeomPnt (apoint));
517
518   if (Bisector->BasisCurve()->IsPeriodic()) {
519     if (Bisector->FirstParameter() > Param) Param = Param + 2*M_PI;
520   }
521   if(Bisector->FirstParameter() >= Param)return Standard_False;
522   if(Bisector->LastParameter()  <  Param)return Standard_False;
523   Bisector->SetTrim(Bisector->FirstParameter(),Param);
524
525 #ifdef DEB
526   Standard_Boolean Affich = Standard_False;
527   if (Affich) MAT2d_DrawCurve(Bisector,2);
528 #endif  
529
530   return Standard_True;
531 }
532
533 //=============================================================================
534 //function : Projection
535 //purpose  :
536 //=============================================================================
537 Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge   ,
538                                            const gp_Pnt2d&        PCom    ,
539                                                  Standard_Real&   Distance) 
540      const
541 {  
542   gp_Pnt2d                    PEdge;
543   Handle(Geom2d_Geometry)     Elt    = theCircuit->Value(IEdge);
544   Handle(Standard_Type)       Type   = Elt->DynamicType();      
545   Handle(Geom2d_TrimmedCurve) Curve; 
546   Standard_Integer            INext;   
547   Standard_Real               Eps = MAT2d_TOLCONF;//*10.;
548
549   if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {   
550     PEdge     = Handle(Geom2d_Point)::DownCast(Elt)->Pnt2d();
551     Distance  = PCom.Distance(PEdge);   
552   }
553   else {
554     Distance = Precision::Infinite();
555     Curve    = Handle(Geom2d_TrimmedCurve)::DownCast(Elt);      
556     //-----------------------------------------------------------------------
557     // Calcul des parametres MinMax sur l edge si celui ci est lies a ses
558     // voisins par des connexions la courbe de calcul est limitee par 
559     // celles_ci.         
560     //-----------------------------------------------------------------------
561     Standard_Real ParamMin = Curve->FirstParameter();
562     Standard_Real ParamMax = Curve->LastParameter();
563     if (theCircuit->ConnexionOn(IEdge)) {
564       ParamMin = theCircuit->Connexion(IEdge)->ParameterOnSecond(); 
565     }
566     INext = (IEdge == theCircuit->NumberOfItems()) ? 1 : (IEdge + 1);
567     if (theCircuit->ConnexionOn(INext)) {
568       ParamMax = theCircuit->Connexion(INext)->ParameterOnFirst(); 
569       if (Curve->BasisCurve()->IsPeriodic()){
570         ElCLib::AdjustPeriodic(0.,2*M_PI,Eps,ParamMin,ParamMax);
571       }
572     }
573     //---------------------------------------------------------------------
574     // Constuction de la courbe pour les extremas et ajustement des bornes.
575     //---------------------------------------------------------------------
576     Geom2dAdaptor_Curve C1(Curve);
577     GeomAbs_CurveType TypeC1 = C1.GetType();
578     if (TypeC1 == GeomAbs_Circle) {
579       Standard_Real R       = C1.Circle().Radius();
580       Standard_Real EpsCirc = Eps;
581       if ( R < 1.)  EpsCirc = Eps/R;
582       if (!((ParamMax - ParamMin + 2*EpsCirc) < 2*M_PI)) {
583         ParamMax = ParamMax + EpsCirc; ParamMin = ParamMin - EpsCirc;
584       }
585     }
586     else {
587       ParamMax = ParamMax + Eps; ParamMin = ParamMin - Eps; 
588     }
589     //-----------------------------------------------------
590     // Calcul des extremas et stockage minimum de distance.
591     //-----------------------------------------------------
592     Extrema_ExtPC2d Extremas(PCom,C1,ParamMin,ParamMax);
593     if (Extremas.IsDone()){
594       if (Extremas.NbExt() == 0 ) return Standard_False; // Pas de solution!
595       for (Standard_Integer i = 1; i <= Extremas.NbExt(); i++) {
596         if (Extremas.SquareDistance(i) < Distance * Distance) {
597           Distance      = sqrt (Extremas.SquareDistance(i));
598         }
599       }
600     }
601     else {
602       if (TypeC1 == GeomAbs_Circle) {
603         Distance = C1.Circle().Radius();
604       }
605     }
606   }
607   return Standard_True;
608 }
609
610 //=============================================================================
611 //function : IsSameDistance
612 // purpose :
613 //=============================================================================
614 Standard_Boolean MAT2d_Tool2d::IsSameDistance (
615    const Handle(MAT_Bisector)& BisectorOne,
616    const Handle(MAT_Bisector)& BisectorTwo,
617    const gp_Pnt2d&             PCom,
618    Standard_Real&              Distance) const
619 {
620   TColStd_Array1OfReal Dist(1,4);
621   Standard_Integer     IEdge1,IEdge2,IEdge3,IEdge4;
622
623   IEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
624   IEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
625   IEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
626   IEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
627
628   Projection(IEdge1,PCom,Dist(1));
629   Projection(IEdge2,PCom,Dist(2));
630
631   if      (IEdge3 == IEdge1) Dist(3)  = Dist(1);
632   else if (IEdge3 == IEdge2) Dist(3)  = Dist(2);  
633   else                       Projection(IEdge3,PCom,Dist(3));
634
635   if      (IEdge4 == IEdge1) Dist(4)  = Dist(1);
636   else if (IEdge4 == IEdge2) Dist(4)  = Dist(2);  
637   else                       Projection(IEdge4,PCom,Dist(4));
638
639 #ifdef DEB
640   Standard_Boolean Affich = Standard_False;
641   if (Affich)
642     for (Standard_Integer j = 1; j <= 4;j++){
643       cout <<"Distance number : "<<j<<" is :"<< Dist(j)<<endl;
644     }
645 #endif
646
647   Standard_Real EpsDist = MAT2d_TOLCONF*100. ;
648   Distance = Dist(1);
649   for (Standard_Integer i = 1; i <= 4; i++){
650     if (theJoinType == GeomAbs_Intersection &&
651         Precision::IsInfinite(Dist(i)))
652       continue;
653     if (Abs(Dist(i) - Distance) > EpsDist) {
654       Distance = Precision::Infinite();
655       return Standard_False;
656     }
657   }
658   return Standard_True;
659 }
660
661 //=============================================================================
662 //function : IntersectBisector
663 //purpose  :
664 //=============================================================================
665 Standard_Real MAT2d_Tool2d::IntersectBisector (
666    const Handle(MAT_Bisector)& BisectorOne,
667    const Handle(MAT_Bisector)& BisectorTwo,
668    Standard_Integer&           IntPnt)
669 {
670   Standard_Real    Tolerance     = MAT2d_TOLCONF;
671   Standard_Real    Param1,Param2;
672   Standard_Real    Parama,Paramb;
673   Standard_Real    Distance = 0.,DistanceMini;
674   Standard_Boolean SolutionValide;
675   gp_Pnt2d         PointSolution;
676
677   Handle(Geom2d_TrimmedCurve)
678     Bisector1 = Handle(Geom2d_TrimmedCurve)
679       ::DownCast(ChangeGeomBis(BisectorOne->BisectorNumber()).ChangeValue());
680
681   Handle(Geom2d_TrimmedCurve) 
682     Bisector2 = Handle(Geom2d_TrimmedCurve)
683       ::DownCast(ChangeGeomBis(BisectorTwo->BisectorNumber()).ChangeValue());
684
685   if(Bisector1.IsNull() || Bisector2.IsNull()) return Precision::Infinite();
686
687   //-------------------------------------------------------------------------
688   // Si les deux bissectrices separent des elements consecutifs et qu elles
689   // sont issues des connexions C1 et C2.
690   // Si C1 est la reverse de C2 ,alors les deux bissectrices sont issues
691   // du meme point. Dans ce cas l intersection n est pas validee.
692   //-------------------------------------------------------------------------
693   Standard_Integer IS1 = BisectorOne->SecondEdge()->EdgeNumber();
694   Standard_Integer IS2 = BisectorTwo->SecondEdge()->EdgeNumber();
695   Standard_Integer IF1 = BisectorOne->FirstEdge() ->EdgeNumber();
696   Standard_Integer IF2 = BisectorTwo->FirstEdge() ->EdgeNumber();
697   
698   if (AreNeighbours(IF1,IS1,NumberOfItems()) && 
699       AreNeighbours(IF2,IS2,NumberOfItems()) &&
700       theCircuit->ConnexionOn(IS2)           && 
701       theCircuit->ConnexionOn(IS1)             ) {
702     Handle(MAT2d_Connexion) C1,C2;
703     C1 = theCircuit->Connexion(IS1);
704     C2 = theCircuit->Connexion(IS2); 
705     if (C2->IndexFirstLine() == C1->IndexSecondLine() &&
706         C1->IndexFirstLine() == C2->IndexSecondLine()  )
707       return Precision::Infinite();
708   }
709
710   // -----------------------------------------
711   // Construction des domaines d intersection.
712   // -----------------------------------------
713   IntRes2d_Domain Domain1 = Domain(Bisector1,Tolerance);
714   IntRes2d_Domain Domain2 = Domain(Bisector2,Tolerance);
715
716   if (Domain1.LastParameter() - Domain1.FirstParameter()  < Tolerance) 
717      return Precision::Infinite();
718   if (Domain2.LastParameter() - Domain2.FirstParameter()  < Tolerance) 
719      return Precision::Infinite();
720
721 #ifdef DEB
722   Standard_Boolean Affich = Standard_False;
723   if (Affich) {
724     cout<<endl;
725     cout<<"INTERSECTION de "<<BisectorOne->BisectorNumber()<<
726                    " et de "<<BisectorTwo->BisectorNumber()<<endl;
727     cout<<"  Bisector 1 : "<<endl;
728 //    (Bisector1->BasisCurve())->Dump(-1,1);
729     cout<<endl;
730     Debug(Domain1.FirstParameter());
731     Debug(Domain1.LastParameter());
732     cout<<"-----------------"<<endl;
733     cout<<"  Bisector 2 : "<<endl;
734 //    (Bisector2->BasisCurve())->Dump(-1,1);
735     cout<<endl;
736     Debug(Domain2.FirstParameter());
737     Debug(Domain2.LastParameter());
738     cout<<"-----------------"<<endl;
739   }
740 #endif
741
742 // -------------------------
743 // Calcul de l intersection.
744 // -------------------------
745
746   Bisector_Inter Intersect;
747   Intersect.Perform (GeomBis(BisectorOne->BisectorNumber()),Domain1,
748                      GeomBis(BisectorTwo->BisectorNumber()),Domain2,
749                      Tolerance,Tolerance,Standard_True);
750
751 //  Geom2dInt_GInter Intersect;
752 //  Intersect.Perform(Bisector1,Domain1,Bisector2,Domain2,Tolerance,Tolerance);
753
754 // -------------------------------------------------------------------------
755 // Exploitation du resultat de l intersection et selection du point solution
756 // equidistant des deux edges et le plus proche en parametre de l origine 
757 // des bissectrices.
758 // -------------------------------------------------------------------------
759
760   if(!Intersect.IsDone()) return Precision::Infinite();
761
762   if(Intersect.IsEmpty()) return Precision::Infinite();
763
764   DistanceMini   = Precision::Infinite();
765   Param1         = Precision::Infinite();
766   Param2         = Precision::Infinite();
767   SolutionValide = Standard_False;
768
769   if(Intersect.NbSegments() >= 1) {              
770     Standard_Real    MaxSegmentLength = 10.*Tolerance;
771     for (Standard_Integer i=1;i<=Intersect.NbSegments();i++) {
772       IntRes2d_IntersectionSegment Segment     = Intersect.Segment(i);
773       Standard_Boolean             PointRetenu = Standard_False;
774       gp_Pnt2d                     PointOnSegment;
775       // ----------------------------------------------------------------
776       // Si les segments sont petits, recherche des points sur le segment
777       // equidistants des edges.
778       // ----------------------------------------------------------------
779       if ((Segment.HasFirstPoint() && Segment.HasLastPoint())) { 
780         gp_Pnt2d      P1,P2;
781         Standard_Real SegmentLength;
782         P1 = Segment.FirstPoint().Value();
783         P2 = Segment.LastPoint().Value();
784         SegmentLength = P1.Distance(P2);
785         if (SegmentLength <= Tolerance) {
786           PointOnSegment = P1;
787           if(IsSameDistance(BisectorOne,BisectorTwo,
788                             PointOnSegment,Distance)) 
789             PointRetenu = Standard_True;
790         }
791         else if (SegmentLength <= MaxSegmentLength) {
792           gp_Dir2d  Dir(P2.X()-P1.X(),P2.Y()-P1.Y());
793           Standard_Real Dist = 0.;  
794           while (Dist <= SegmentLength + Tolerance){
795             PointOnSegment = P1.Translated(Dist*Dir);
796             if(IsSameDistance(BisectorOne,BisectorTwo,
797                               PointOnSegment,Distance)) {
798               PointRetenu = Standard_True;
799               break;
800             }
801             Dist = Dist + Tolerance;
802           }
803         }
804       }  
805
806       // ----------------------------------------------------------------
807       // Sauvegarde du point equidistant des edges de plus petit 
808       // parametre sur les bissectrices.
809       // ----------------------------------------------------------------
810       if(PointRetenu) {
811         Parama = Handle(Bisector_Curve)::DownCast(Bisector1->BasisCurve())
812           ->Parameter(PointOnSegment);
813         Paramb = Handle(Bisector_Curve)::DownCast(Bisector2->BasisCurve())
814           ->Parameter(PointOnSegment);
815         if(Parama < Param1 && Paramb < Param2) {
816           Param1         = Parama;
817           Param2         = Paramb;
818           DistanceMini   = Distance;
819           PointSolution  = PointOnSegment;
820           SolutionValide = Standard_True;
821         }
822       }
823     }
824   }
825
826   if(Intersect.NbPoints() != 1) {
827     for(Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
828       if(IsSameDistance(BisectorOne,BisectorTwo,
829                         Intersect.Point(i).Value(),Distance) &&
830          Distance > Tolerance                                   ) {
831         Parama = Intersect.Point(i).ParamOnFirst();
832         Paramb = Intersect.Point(i).ParamOnSecond();
833         if (Parama < Param1 && Paramb < Param2) {
834           Param1         = Parama;
835           Param2         = Paramb;
836           DistanceMini   = Distance;
837           PointSolution  = Intersect.Point(i).Value();
838           SolutionValide = Standard_True;
839         }
840       }
841     }
842   }
843   else {
844     PointSolution  = Intersect.Point(1).Value();
845     Param1         = Intersect.Point(1).ParamOnFirst();
846     Param2         = Intersect.Point(1).ParamOnSecond();
847     SolutionValide = IsSameDistance(BisectorOne,BisectorTwo,
848                                     PointSolution,DistanceMini);
849   }
850
851   if (!SolutionValide) return Precision::Infinite();
852   theNumberOfPnts++;
853   theGeomPnts.Bind(theNumberOfPnts,PointSolution);
854   IntPnt = theNumberOfPnts;
855
856   //-----------------------------------------------------------------------
857   // Si le point d intersection est quasi confondue avec une des extremites
858   // de l une ou l autre des bisectrices, l intersection n est pas validee.
859   //
860   // SAUF si une des bisectrices est issue d une connexion et que les 
861   // edges separes par les bissectrices sont des voisines sur le contour
862   // initiales.
863   // en effet le milieu de la connexion P qui est l origine d une des 
864   // bissectrices peut etre sur l autre bissectrice. 
865   // P est donc point d intersection
866   // et la bissectrice issue de la connexion est de longueur nulle.
867   // (ex : un rectangle dans un rectangle ou la connexion est entre un coin
868   // et un cote).
869   //-----------------------------------------------------------------------
870
871   Standard_Integer IndexEdge1,IndexEdge2,IndexEdge3,IndexEdge4;
872   Standard_Boolean ExtremiteControle = Standard_True;
873
874   IndexEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
875   IndexEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
876   IndexEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
877   IndexEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
878   
879   if (theCircuit->ConnexionOn(IndexEdge2)){
880     // --------------------------------------
881     // BisectorOne est issue d une connexion.  
882     // --------------------------------------
883    if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && 
884        AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) && 
885        IndexEdge2 == IndexEdge3                               ){
886       ExtremiteControle = Standard_False;
887       Param1             = Param1 + Tolerance;
888     }
889   }
890   
891   if (theCircuit->ConnexionOn(IndexEdge4)){
892     // --------------------------------------
893     // BisectorTwo est issue d une connexion.   
894     // --------------------------------------
895     if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && 
896         AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) &&
897         IndexEdge2 == IndexEdge3                               ){
898       ExtremiteControle = Standard_False;
899       Param2            = Param2 + Tolerance;
900     }
901   }
902  
903   if (ExtremiteControle) {
904     if(Bisector1->StartPoint().Distance(PointSolution) < Tolerance ||
905        Bisector2->StartPoint().Distance(PointSolution) < Tolerance  ) 
906       return Precision::Infinite();
907   }
908
909   if(BisectorOne->SecondParameter() < Precision::Infinite() &&
910      BisectorOne->SecondParameter() < Param1*(1. - Tolerance )) 
911     return Precision::Infinite();
912   
913   if(BisectorTwo->FirstParameter() < Precision::Infinite() &&
914      BisectorTwo->FirstParameter() < Param2*(1.- Tolerance)) 
915     return Precision::Infinite();
916
917   BisectorOne->SecondParameter(Param1);
918   BisectorTwo->FirstParameter (Param2);
919   
920 #ifdef DEB
921   if (Affich) {
922     cout<<"   coordonnees    : "<<GeomPnt  (IntPnt).X()<<" "
923                                 <<GeomPnt  (IntPnt).Y()<<endl;
924     cout<<"   parametres     : "<<Param1<<" "<<Param2<<endl;
925     cout<<"   distancemini   : "<<DistanceMini<<endl;
926   }
927 #endif
928   
929   return DistanceMini;
930 }
931
932 //=============================================================================
933 //function : Distance
934 //purpose  :
935 //=============================================================================
936 Standard_Real MAT2d_Tool2d::Distance(const Handle(MAT_Bisector)& Bis,
937                                      const Standard_Real         Param1,
938                                      const Standard_Real         Param2) const
939 {
940   Standard_Real Dist = Precision::Infinite();
941
942   if (Param1 != Precision::Infinite() && Param2 != Precision::Infinite()) {
943     gp_Pnt2d P1 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param1);
944     gp_Pnt2d P2 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param2);
945     Dist        = P1.Distance(P2);
946   }
947   return Dist;
948 }
949
950 //=============================================================================
951 //function : Dump
952 //purpose  :
953 //=============================================================================
954 #ifndef DEB
955 void MAT2d_Tool2d::Dump(const Standard_Integer ,
956                         const Standard_Integer ) const
957 {
958   Standard_NotImplemented::Raise();
959 #else
960 void MAT2d_Tool2d::Dump(const Standard_Integer bisector,
961                         const Standard_Integer) const
962 {
963   if(bisector == -1) return;
964   if(bisector > theNumberOfBisectors) return;
965
966   Handle(Geom2d_Curve) thebisector = GeomBis(bisector).Value(); 
967
968   MAT2d_DrawCurve(thebisector,3);
969
970 #endif
971 }
972
973
974 //=============================================================================
975 //function : GeomBis
976 //purpose  :
977 //=============================================================================
978 const Bisector_Bisec&  MAT2d_Tool2d::GeomBis (const Standard_Integer Index) 
979      const
980 {
981   return theGeomBisectors.Find(Index);
982 }
983
984 //=============================================================================
985 //function : ChangeGeomBis
986 //purpose  :
987 //=============================================================================
988 Bisector_Bisec&  MAT2d_Tool2d::ChangeGeomBis(const Standard_Integer Index)
989 {
990   return theGeomBisectors.ChangeFind(Index);
991 }
992
993
994 //=============================================================================
995 //function : GeomElt
996 //purpose  :
997 //=============================================================================
998 Handle(Geom2d_Geometry)  MAT2d_Tool2d::GeomElt(const Standard_Integer Index)
999                                                                         const 
1000 {
1001   return  theCircuit->Value(Index);
1002 }
1003
1004
1005 //=============================================================================
1006 //function : GeomPnt
1007 //purpose  :
1008 //=============================================================================
1009 const gp_Pnt2d&  MAT2d_Tool2d::GeomPnt(const Standard_Integer Index) const
1010 {
1011   return theGeomPnts.Find(Index);
1012 }
1013
1014 //=============================================================================
1015 //function : GeomVec
1016 //purpose  :
1017 //=============================================================================
1018 const gp_Vec2d&  MAT2d_Tool2d::GeomVec(const Standard_Integer Index)const 
1019 {
1020   return theGeomVecs.Find(Index);
1021 }
1022
1023 //=============================================================================
1024 //function : Circuit
1025 //purpose  :
1026 //=============================================================================
1027 Handle(MAT2d_Circuit) MAT2d_Tool2d::Circuit()const 
1028 {
1029   return theCircuit;
1030 }
1031
1032 //=============================================================================
1033 //function : BisecFusion
1034 //purpose  :
1035 //=============================================================================
1036 void MAT2d_Tool2d::BisecFusion(const Standard_Integer I1,
1037                                const Standard_Integer I2) 
1038 {
1039   Standard_Real               DU,UL1,UF1;
1040   Handle(Geom2d_TrimmedCurve) Bisector1;
1041   Handle(Geom2d_TrimmedCurve) Bisector2;
1042
1043   Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I1).Value());
1044   Bisector2 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I2).Value());
1045   UF1       = Bisector1->FirstParameter();
1046   UL1       = Bisector1->LastParameter();
1047
1048   Handle(Standard_Type) Type1 = Bisector1->BasisCurve()->DynamicType();
1049   if (Type1 == STANDARD_TYPE(Bisector_BisecCC)) {
1050     //------------------------------------------------------------------------------------
1051     // les bissectrice courbe/courbe sont  construites avec un point de depart
1052     // elles ne peuvent pas etre trimes par un point se trouvant de l autre cote du
1053     // point de depart.
1054     // pour faire la fusion des deux bissectrices on reconstruit la bissectrice entre les
1055     // deux courbes avec comme point de depart le dernier point de la Bisector2.
1056     // on trime ensuite la courbe par le dernier point de Bisector1.
1057     //------------------------------------------------------------------------------------
1058     Standard_Real            Tolerance    = MAT2d_TOLCONF;
1059     Bisector_Bisec           Bis;
1060     gp_Vec2d                 VBid(1,0);
1061     gp_Pnt2d                 P2   = Bisector2->Value(Bisector2->LastParameter());     
1062     gp_Pnt2d                 P1   = Bisector1->Value(Bisector1->LastParameter());   
1063     Handle(Bisector_BisecCC) BCC1 = Handle(Bisector_BisecCC)::DownCast(Bisector1->BasisCurve());
1064
1065     Bis.Perform(BCC1->Curve(2), BCC1->Curve(1), P2, VBid, VBid, 
1066                 theDirection, Tolerance, Standard_False); 
1067
1068     Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(Bis.Value());
1069     BCC1      = Handle(Bisector_BisecCC)   ::DownCast(Bisector1->BasisCurve()); 
1070     UF1       = BCC1->FirstParameter();
1071     UL1       = BCC1->Parameter(P1);
1072     Bisector1->SetTrim(UF1,UL1);
1073     theGeomBisectors.Bind(I1,Bis);
1074   }
1075   else {
1076     DU        = Bisector2->LastParameter() - Bisector2->FirstParameter();
1077     UF1       = UF1 - DU;
1078
1079     Handle(Bisector_BisecAna) BAna = Handle(Bisector_BisecAna)::DownCast(Bisector1->BasisCurve());
1080 //---------------------------- uncomment if new method Bisector_BisecAna::SetTrim(f,l) is not used
1081 //    Handle(Geom2d_Curve) C2d = BAna->Geom2dCurve();
1082 //    Handle(Geom2d_TrimmedCurve) trimC2d = new Geom2d_TrimmedCurve(C2d, UF1, UL1);
1083 //    BAna->Init(trimC2d);
1084 //--------------------------- end
1085     BAna->SetTrim(UF1,UL1); // put comment if SetTrim(f,l) is not used
1086
1087     Bisector1->SetTrim(UF1,UL1);
1088   }
1089 }
1090
1091 //=============================================================================
1092 //function : Type
1093 //purpose  :
1094 //=============================================================================
1095 static Handle(Standard_Type) Type(const Handle(Geom2d_Geometry)& aGeom) 
1096 {
1097   Handle(Standard_Type) type = aGeom->DynamicType();
1098   Handle(Geom2d_Curve)  curve;
1099
1100   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1101     curve = Handle(Geom2d_TrimmedCurve)::DownCast(aGeom)->BasisCurve();
1102     type  = curve->DynamicType();
1103   }
1104   return type;
1105 }
1106
1107 //==========================================================================
1108 //function : AreNeighbours
1109 //purpose  : Return TRUE si IEdge1 et IEdge2 correspondent a des elements 
1110 //           consecutifs sur un contour ferme de NbEdge elements.
1111 //==========================================================================
1112 Standard_Boolean AreNeighbours(const Standard_Integer IEdge1,
1113                                const Standard_Integer IEdge2,
1114                                const Standard_Integer NbEdge)
1115 {
1116   if      (Abs(IEdge1 - IEdge2) == 1)         return Standard_True;
1117   else if (Abs(IEdge1 - IEdge2) == NbEdge -1) return Standard_True;
1118   else                                        return Standard_False; 
1119 }
1120
1121 //==========================================================================
1122 //function : SetTrim
1123 //purpose  :
1124 //==========================================================================
1125 void SetTrim(Bisector_Bisec& Bis, Handle(Geom2d_Curve)& Line1)
1126 {  
1127   Geom2dInt_GInter Intersect; 
1128   Standard_Real    Distance;  
1129   Standard_Real    Tolerance = MAT2d_TOLCONF;  
1130   Handle(Geom2d_TrimmedCurve) Bisector = 
1131     Handle(Geom2d_TrimmedCurve)::DownCast(Bis.ChangeValue());
1132
1133   IntRes2d_Domain  Domain1   = Domain(Bisector,Tolerance);
1134   Standard_Real    UB1       = Bisector->FirstParameter();
1135   Standard_Real    UB2       = Bisector->LastParameter();
1136  
1137   gp_Pnt2d         FirstPointBisector = Bisector->Value(UB1);
1138   Standard_Real    UTrim              = Precision::Infinite();
1139
1140   Geom2dAdaptor_Curve AdapBisector(Bisector);
1141   Geom2dAdaptor_Curve AdapLine1   (Line1);
1142   Intersect.Perform(AdapBisector, Domain1, 
1143                     AdapLine1, Tolerance, Tolerance);
1144
1145   if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1146     for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1147       gp_Pnt2d PInt = Intersect.Point(i).Value();
1148       Distance      = FirstPointBisector.Distance(PInt);
1149       if (Distance > 10.*Tolerance                     && 
1150           Intersect.Point(i).ParamOnFirst() < UTrim ) {
1151          UTrim = Intersect.Point(i).ParamOnFirst();
1152       }
1153     }
1154   } 
1155   // ------------------------------------------------------------------------
1156   // Restriction de la Bissectrice par le point d intersection de plus petit
1157   // parametre.
1158   // ------------------------------------------------------------------------
1159   if (UTrim < UB2 && UTrim > UB1) Bisector->SetTrim(UB1,UTrim);
1160 }
1161
1162 //==========================================================================
1163 //function : Domain
1164 //purpose  :
1165 //==========================================================================
1166 IntRes2d_Domain  Domain(const Handle(Geom2d_TrimmedCurve)& Bisector1,
1167                         const Standard_Real                Tolerance)
1168 {
1169   Standard_Real Param1 = Bisector1->FirstParameter();
1170   Standard_Real Param2 = Bisector1->LastParameter();
1171   if(Param2 > 10000.) {
1172     Param2 = 10000.;
1173     Handle(Standard_Type) Type1 = Type(Bisector1->BasisCurve());    
1174     Handle(Geom2d_Curve)  BasisCurve;
1175     if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) {
1176       BasisCurve = Handle(Bisector_BisecAna)
1177         ::DownCast(Bisector1->BasisCurve())->Geom2dCurve();
1178       Type1      = BasisCurve->DynamicType();
1179     }
1180     gp_Parab2d gpParabola;
1181     gp_Hypr2d  gpHyperbola;
1182     Standard_Real Focus;
1183     Standard_Real Limit = 50000.;
1184     if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1185       gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1186       Focus = gpParabola.Focal();
1187       Standard_Real Val1 = Sqrt(Limit*Focus);
1188       Standard_Real Val2 = Sqrt(Limit*Limit);
1189       Param2 = (Val1 <= Val2 ? Val1:Val2);
1190     }
1191     else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1192       gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1193       Standard_Real Majr  = gpHyperbola.MajorRadius();
1194       Standard_Real Minr  = gpHyperbola.MinorRadius();
1195       Standard_Real Valu1 = Limit/Majr;
1196       Standard_Real Valu2 = Limit/Minr;
1197       Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1198       Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1199       Param2 = (Val1 <= Val2 ? Val1:Val2);
1200     }
1201   }
1202  
1203   IntRes2d_Domain Domain1(Bisector1->Value(Param1),Param1,Tolerance,
1204                           Bisector1->Value(Param2),Param2,Tolerance);
1205   if(Bisector1->BasisCurve()->IsPeriodic()) {
1206     Domain1.SetEquivalentParameters(0.,2.*M_PI);
1207   }
1208   return Domain1;
1209 }
1210
1211 #ifdef DEB
1212 //==========================================================================
1213 //function : MAT2d_DrawCurve
1214 //purpose  : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
1215 //           definie par <Indice>.
1216 //            Indice = 1 jaune,
1217 //            Indice = 2 bleu,
1218 //            Indice = 3 rouge,
1219 //            Indice = 4 vert.
1220 //==========================================================================
1221 void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
1222                      const Standard_Integer      /*Indice*/)
1223 {  
1224   Handle(Standard_Type)      type = aCurve->DynamicType();
1225   Handle(Geom2d_Curve)       curve,CurveDraw;
1226 #ifdef DRAW
1227   Handle(DrawTrSurf_Curve2d) dr;
1228   Draw_Color                 Couleur;
1229 #endif
1230
1231   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1232     curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
1233     type = curve->DynamicType();    
1234     // PB de representation des courbes semi_infinies.
1235     gp_Parab2d gpParabola;
1236     gp_Hypr2d  gpHyperbola;
1237     Standard_Real Focus;
1238     Standard_Real Limit = 50000.;
1239     Standard_Real delta = 400;
1240
1241     // PB de representation des courbes semi_infinies.
1242     if (aCurve->LastParameter() == Precision::Infinite()) {
1243       
1244       if (type == STANDARD_TYPE(Geom2d_Parabola)) {
1245         gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
1246         Focus = gpParabola.Focal();
1247         Standard_Real Val1 = Sqrt(Limit*Focus);
1248         Standard_Real Val2 = Sqrt(Limit*Limit);
1249                       delta= (Val1 <= Val2 ? Val1:Val2);
1250       }
1251       else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1252         gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
1253         Standard_Real Majr  = gpHyperbola.MajorRadius();
1254         Standard_Real Minr  = gpHyperbola.MinorRadius();
1255         Standard_Real Valu1 = Limit/Majr;
1256         Standard_Real Valu2 = Limit/Minr;
1257         Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1258         Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1259                       delta  = (Val1 <= Val2 ? Val1:Val2);
1260       }
1261       CurveDraw = new Geom2d_TrimmedCurve(aCurve,
1262                                           aCurve->FirstParameter(),
1263                                           aCurve->FirstParameter() + delta);
1264     }
1265     else {
1266       CurveDraw = aCurve;
1267     }
1268     // fin PB.
1269   }
1270   else {
1271     CurveDraw = aCurve;
1272   }
1273
1274 #ifdef DRAW
1275   if      (Indice == 1) Couleur = Draw_jaune;
1276   else if (Indice == 2) Couleur = Draw_bleu;
1277   else if (Indice == 3) Couleur = Draw_rouge;
1278   else if (Indice == 4) Couleur = Draw_vert;
1279
1280   if (type == STANDARD_TYPE(Geom2d_Circle))
1281     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
1282   else if (type  == STANDARD_TYPE(Geom2d_Line))
1283     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
1284   else
1285     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
1286
1287   dout << dr;
1288   dout.Flush();
1289 #endif
1290 }
1291
1292 #endif
1293