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