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