0026916: Configuration, CMake - configure variables to customize installation path...
[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) 
507     bisector = Handle(Geom2d_TrimmedCurve)
508     ::DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
509
510   if(bisector->BasisCurve()->IsPeriodic() && param == Precision::Infinite()) {
511     param = bisector->FirstParameter() + 2*M_PI;
512   }
513   if (param > bisector->BasisCurve()->LastParameter()) {
514     param = bisector->BasisCurve()->LastParameter(); 
515   }
516   if(bisector->FirstParameter() == param) return Standard_False;
517
518   bisector->SetTrim(bisector->FirstParameter(),param);
519   return Standard_True;
520 }
521
522 //=============================================================================
523 //function : TrimBisector
524 //purpose  :
525 //=============================================================================
526 Standard_Boolean MAT2d_Tool2d::TrimBisector
527   (const Handle(MAT_Bisector)& abisector,
528   const Standard_Integer      apoint)
529 {
530   Standard_Real Param;
531   Handle(Geom2d_TrimmedCurve)
532     Bisector = Handle(Geom2d_TrimmedCurve)::
533     DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
534
535   Handle(Bisector_Curve) Bis = Handle(Bisector_Curve)::
536     DownCast(Bisector->BasisCurve());
537
538   //  Param = ParameterOnCurve(Bisector,theGeomPnts.Value(apoint));
539   Param = Bis->Parameter(GeomPnt (apoint));
540
541   if (Bisector->BasisCurve()->IsPeriodic()) {
542     if (Bisector->FirstParameter() > Param) Param = Param + 2*M_PI;
543   }
544   if(Bisector->FirstParameter() >= Param)return Standard_False;
545   if(Bisector->LastParameter()  <  Param)return Standard_False;
546   Bisector->SetTrim(Bisector->FirstParameter(),Param);
547
548 #ifdef OCCT_DEBUG
549   Standard_Boolean Affich = Standard_False;
550   if (Affich) MAT2d_DrawCurve(Bisector,2);
551 #endif  
552
553   return Standard_True;
554 }
555
556 //=============================================================================
557 //function : Projection
558 //purpose  :
559 //=============================================================================
560 Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge   ,
561   const gp_Pnt2d&        PCom    ,
562   Standard_Real&   Distance) 
563   const
564 {  
565   gp_Pnt2d                    PEdge;
566   Handle(Geom2d_Geometry)     Elt    = theCircuit->Value(IEdge);
567   Handle(Standard_Type)       Type   = Elt->DynamicType();      
568   Handle(Geom2d_TrimmedCurve) Curve; 
569   Standard_Integer            INext;   
570   Standard_Real               Eps = MAT2d_TOLCONF;//*10.;
571
572   if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {   
573     PEdge     = Handle(Geom2d_Point)::DownCast(Elt)->Pnt2d();
574     Distance  = PCom.Distance(PEdge);   
575   }
576   else {
577     Distance = Precision::Infinite();
578     Curve    = Handle(Geom2d_TrimmedCurve)::DownCast(Elt);      
579     //-----------------------------------------------------------------------
580     // Calcul des parametres MinMax sur l edge si celui ci est lies a ses
581     // voisins par des connexions la courbe de calcul est limitee par 
582     // celles_ci.         
583     //-----------------------------------------------------------------------
584     Standard_Real ParamMin = Curve->FirstParameter();
585     Standard_Real ParamMax = Curve->LastParameter();
586     if (theCircuit->ConnexionOn(IEdge)) {
587       ParamMin = theCircuit->Connexion(IEdge)->ParameterOnSecond(); 
588     }
589     INext = (IEdge == theCircuit->NumberOfItems()) ? 1 : (IEdge + 1);
590     if (theCircuit->ConnexionOn(INext)) {
591       ParamMax = theCircuit->Connexion(INext)->ParameterOnFirst(); 
592       if (Curve->BasisCurve()->IsPeriodic()){
593         ElCLib::AdjustPeriodic(0.,2*M_PI,Eps,ParamMin,ParamMax);
594       }
595     }
596     //---------------------------------------------------------------------
597     // Constuction de la courbe pour les extremas et ajustement des bornes.
598     //---------------------------------------------------------------------
599     Geom2dAdaptor_Curve C1(Curve);
600     GeomAbs_CurveType TypeC1 = C1.GetType();
601     if (TypeC1 == GeomAbs_Circle) {
602       Standard_Real R       = C1.Circle().Radius();
603       Standard_Real EpsCirc = 100.*Eps;
604       if ( R < 1.)  EpsCirc = Eps/R;
605       if (((ParamMax - ParamMin + 2*EpsCirc) < 2*M_PI)) {
606         ParamMax = ParamMax + EpsCirc; ParamMin = ParamMin - EpsCirc;
607       }
608     }
609     else {
610       ParamMax = ParamMax + Eps; ParamMin = ParamMin - Eps; 
611     }
612     //-----------------------------------------------------
613     // Calcul des extremas et stockage minimum de distance.
614     //-----------------------------------------------------
615     Extrema_ExtPC2d Extremas(PCom,C1,ParamMin,ParamMax);
616     if (Extremas.IsDone()){
617       Distance = Precision::Infinite();
618       if(Extremas.NbExt() < 1) 
619       {
620         return Standard_False;
621       }
622       for (Standard_Integer i = 1; i <= Extremas.NbExt(); i++) {
623         if (Extremas.SquareDistance(i) < Distance) {
624           Distance      = Extremas.SquareDistance(i);
625         }
626       }
627       Distance = Sqrt(Distance);
628     }
629     else {
630       if (TypeC1 == GeomAbs_Circle) {
631         Distance = C1.Circle().Radius();
632       }
633     }
634   }
635   return Standard_True;
636 }
637
638 //=============================================================================
639 //function : IsSameDistance
640 // purpose :
641 //=============================================================================
642 Standard_Boolean MAT2d_Tool2d::IsSameDistance (
643   const Handle(MAT_Bisector)& BisectorOne,
644   const Handle(MAT_Bisector)& BisectorTwo,
645   const gp_Pnt2d&             PCom,
646   Standard_Real&              Distance) const
647 {
648   TColStd_Array1OfReal Dist(1,4);
649   const Standard_Real eps = 1.e-7;
650   Standard_Integer     IEdge1,IEdge2,IEdge3,IEdge4;
651
652   IEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
653   IEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
654   IEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
655   IEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
656
657   Standard_Boolean isDone1 = Projection(IEdge1,PCom,Dist(1));
658   Standard_Boolean isDone2 = Projection(IEdge2,PCom,Dist(2));
659
660   if(isDone1)
661   {
662     if(!isDone2)
663     {
664       Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge2);
665       Standard_Real Tol = Max(Precision::Confusion(), eps*Dist(1));
666       if(CheckEnds (Elt, PCom, Dist(1), Tol))
667       { 
668         Dist(2) = Dist(1);
669       }   
670     }
671   }
672   else
673   {
674     if(isDone2)
675     {
676       Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge1);
677       Standard_Real Tol = Max(Precision::Confusion(), eps*Dist(2));
678       if(CheckEnds (Elt, PCom, Dist(2), Tol))
679       { 
680         Dist(1) = Dist(2);
681       }   
682     }
683   }
684
685   Standard_Boolean isDone3 = Standard_True, isDone4 = Standard_True;
686   if      (IEdge3 == IEdge1) Dist(3)  = Dist(1);
687   else if (IEdge3 == IEdge2) Dist(3)  = Dist(2);  
688   else    isDone3 = Projection(IEdge3,PCom,Dist(3));
689
690   if      (IEdge4 == IEdge1) Dist(4)  = Dist(1);
691   else if (IEdge4 == IEdge2) Dist(4)  = Dist(2);  
692   else    isDone4 = Projection(IEdge4,PCom,Dist(4));
693   //
694   if(isDone3)
695   {
696     if(!isDone4)
697     {
698       Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge4);
699       Standard_Real Tol = Max(Precision::Confusion(), eps*Dist(3));
700       if(CheckEnds (Elt, PCom, Dist(3), Tol))
701       { 
702         Dist(4) = Dist(3);
703       }   
704     }
705   }
706   else
707   {
708     if(isDone4)
709     {
710       Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge3);
711       Standard_Real Tol = Max(Precision::Confusion(), eps*Dist(4));
712       if(CheckEnds (Elt, PCom, Dist(4), Tol))
713       { 
714         Dist(3) = Dist(4);
715       }   
716     }
717   }
718
719 #ifdef OCCT_DEBUG
720   if (AffichDist)
721     for (Standard_Integer j = 1; j <= 4;j++){
722       cout <<"Distance number : "<<j<<" is :"<< Dist(j)<<endl;
723     }
724 #endif
725
726     Standard_Real EpsDist = MAT2d_TOLCONF*300. ;
727     Distance = Dist(1);
728     if (theJoinType == GeomAbs_Intersection &&
729         Precision::IsInfinite(Distance))
730     {
731       for (Standard_Integer i = 2; i <= 4; i++)
732         if (!Precision::IsInfinite(Dist(i)))
733         {
734           Distance = Dist(i);
735           break;
736         }
737     }
738     for (Standard_Integer i = 1; i <= 4; i++){
739       if (theJoinType == GeomAbs_Intersection &&
740           Precision::IsInfinite(Dist(i)))
741         continue;
742       if (Abs(Dist(i) - Distance) > EpsDist) {
743         Distance = Precision::Infinite();
744         return Standard_False;
745       }
746     }
747     return Standard_True;
748 }
749
750 //=============================================================================
751 //function : IntersectBisector
752 //purpose  :
753 //=============================================================================
754 Standard_Real MAT2d_Tool2d::IntersectBisector (
755   const Handle(MAT_Bisector)& BisectorOne,
756   const Handle(MAT_Bisector)& BisectorTwo,
757   Standard_Integer&           IntPnt)
758 {
759   Standard_Real    Tolerance     = MAT2d_TOLCONF;
760   Standard_Real    Param1,Param2;
761   Standard_Real    Parama,Paramb;
762   Standard_Real    Distance = 0.,DistanceMini;
763   Standard_Boolean SolutionValide;
764   gp_Pnt2d         PointSolution;
765
766   Handle(Geom2d_TrimmedCurve)
767     Bisector1 = Handle(Geom2d_TrimmedCurve)
768     ::DownCast(ChangeGeomBis(BisectorOne->BisectorNumber()).ChangeValue());
769
770   Handle(Geom2d_TrimmedCurve) 
771     Bisector2 = Handle(Geom2d_TrimmedCurve)
772     ::DownCast(ChangeGeomBis(BisectorTwo->BisectorNumber()).ChangeValue());
773
774   if(Bisector1.IsNull() || Bisector2.IsNull()) return Precision::Infinite();
775
776   //-------------------------------------------------------------------------
777   // Si les deux bissectrices separent des elements consecutifs et qu elles
778   // sont issues des connexions C1 et C2.
779   // Si C1 est la reverse de C2 ,alors les deux bissectrices sont issues
780   // du meme point. Dans ce cas l intersection n est pas validee.
781   //-------------------------------------------------------------------------
782   Standard_Integer IS1 = BisectorOne->SecondEdge()->EdgeNumber();
783   Standard_Integer IS2 = BisectorTwo->SecondEdge()->EdgeNumber();
784   Standard_Integer IF1 = BisectorOne->FirstEdge() ->EdgeNumber();
785   Standard_Integer IF2 = BisectorTwo->FirstEdge() ->EdgeNumber();
786
787   if (AreNeighbours(IF1,IS1,NumberOfItems()) && 
788     AreNeighbours(IF2,IS2,NumberOfItems()) &&
789     theCircuit->ConnexionOn(IS2)           && 
790     theCircuit->ConnexionOn(IS1)             ) {
791       Handle(MAT2d_Connexion) C1,C2;
792       C1 = theCircuit->Connexion(IS1);
793       C2 = theCircuit->Connexion(IS2); 
794       if (C2->IndexFirstLine() == C1->IndexSecondLine() &&
795         C1->IndexFirstLine() == C2->IndexSecondLine()  )
796         return Precision::Infinite();
797   }
798
799   // -----------------------------------------
800   // Construction des domaines d intersection.
801   // -----------------------------------------
802   IntRes2d_Domain Domain1 = Domain(Bisector1,Tolerance);
803   IntRes2d_Domain Domain2 = Domain(Bisector2,Tolerance);
804
805   if (Domain1.LastParameter() - Domain1.FirstParameter()  < Tolerance) 
806     return Precision::Infinite();
807   if (Domain2.LastParameter() - Domain2.FirstParameter()  < Tolerance) 
808     return Precision::Infinite();
809
810 #ifdef OCCT_DEBUG
811   Standard_Boolean Affich = Standard_False;
812   if (Affich) {
813     cout<<endl;
814     cout<<"INTERSECTION de "<<BisectorOne->BisectorNumber()<<
815       " et de "<<BisectorTwo->BisectorNumber()<<endl;
816     cout<<"  Bisector 1 : "<<endl;
817     //    (Bisector1->BasisCurve())->Dump(-1,1);
818     cout<<endl;
819     Debug(Domain1.FirstParameter());
820     Debug(Domain1.LastParameter());
821     cout<<"-----------------"<<endl;
822     cout<<"  Bisector 2 : "<<endl;
823     //    (Bisector2->BasisCurve())->Dump(-1,1);
824     cout<<endl;
825     Debug(Domain2.FirstParameter());
826     Debug(Domain2.LastParameter());
827     cout<<"-----------------"<<endl;
828   }
829 #endif
830
831   // -------------------------
832   // Calcul de l intersection.
833   // -------------------------
834
835   Bisector_Inter Intersect;
836   Intersect.Perform (GeomBis(BisectorOne->BisectorNumber()),Domain1,
837     GeomBis(BisectorTwo->BisectorNumber()),Domain2,
838     Tolerance,Tolerance,Standard_True);
839
840   //  Geom2dInt_GInter Intersect;
841   //  Intersect.Perform(Bisector1,Domain1,Bisector2,Domain2,Tolerance,Tolerance);
842
843   // -------------------------------------------------------------------------
844   // Exploitation du resultat de l intersection et selection du point solution
845   // equidistant des deux edges et le plus proche en parametre de l origine 
846   // des bissectrices.
847   // -------------------------------------------------------------------------
848
849   if(!Intersect.IsDone()) return Precision::Infinite();
850
851   if(Intersect.IsEmpty()) return Precision::Infinite();
852
853   DistanceMini   = Precision::Infinite();
854   Param1         = Precision::Infinite();
855   Param2         = Precision::Infinite();
856   SolutionValide = Standard_False;
857
858   if(Intersect.NbSegments() >= 1) {              
859     Standard_Real    MaxSegmentLength = 10.*Tolerance;
860     for (Standard_Integer i=1;i<=Intersect.NbSegments();i++) {
861       IntRes2d_IntersectionSegment Segment     = Intersect.Segment(i);
862       Standard_Boolean             PointRetenu = Standard_False;
863       gp_Pnt2d                     PointOnSegment;
864       // ----------------------------------------------------------------
865       // Si les segments sont petits, recherche des points sur le segment
866       // equidistants des edges.
867       // ----------------------------------------------------------------
868       if ((Segment.HasFirstPoint() && Segment.HasLastPoint())) { 
869         gp_Pnt2d      P1,P2;
870         Standard_Real SegmentLength;
871         P1 = Segment.FirstPoint().Value();
872         P2 = Segment.LastPoint().Value();
873         SegmentLength = P1.Distance(P2);
874         if (SegmentLength <= Tolerance) {
875           PointOnSegment = P1;
876           if(IsSameDistance(BisectorOne,BisectorTwo,
877             PointOnSegment,Distance)) 
878             PointRetenu = Standard_True;
879         }
880         else if (SegmentLength <= MaxSegmentLength) {
881           gp_Dir2d  Dir(P2.X()-P1.X(),P2.Y()-P1.Y());
882           Standard_Real Dist = 0.;  
883           while (Dist <= SegmentLength + Tolerance){
884             PointOnSegment = P1.Translated(Dist*Dir);
885             if(IsSameDistance(BisectorOne,BisectorTwo,
886               PointOnSegment,Distance)) {
887                 PointRetenu = Standard_True;
888                 break;
889             }
890             Dist = Dist + Tolerance;
891           }
892         }
893       }  
894
895       // ----------------------------------------------------------------
896       // Sauvegarde du point equidistant des edges de plus petit 
897       // parametre sur les bissectrices.
898       // ----------------------------------------------------------------
899       if(PointRetenu) {
900         Parama = Handle(Bisector_Curve)::DownCast(Bisector1->BasisCurve())
901           ->Parameter(PointOnSegment);
902         Paramb = Handle(Bisector_Curve)::DownCast(Bisector2->BasisCurve())
903           ->Parameter(PointOnSegment);
904         if(Parama < Param1 && Paramb < Param2) {
905           Param1         = Parama;
906           Param2         = Paramb;
907           DistanceMini   = Distance;
908           PointSolution  = PointOnSegment;
909           SolutionValide = Standard_True;
910         }
911       }
912     }
913   }
914
915   if(Intersect.NbPoints() != 1) {
916     for(Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
917       if(IsSameDistance(BisectorOne,BisectorTwo,
918         Intersect.Point(i).Value(),Distance) &&
919         Distance > Tolerance                                   ) {
920           Parama = Intersect.Point(i).ParamOnFirst();
921           Paramb = Intersect.Point(i).ParamOnSecond();
922           if (Parama < Param1 && Paramb < Param2) {
923             Param1         = Parama;
924             Param2         = Paramb;
925             DistanceMini   = Distance;
926             PointSolution  = Intersect.Point(i).Value();
927             SolutionValide = Standard_True;
928           }
929       }
930     }
931   }
932   else {
933     PointSolution  = Intersect.Point(1).Value();
934     Param1         = Intersect.Point(1).ParamOnFirst();
935     Param2         = Intersect.Point(1).ParamOnSecond();
936     SolutionValide = IsSameDistance(BisectorOne,BisectorTwo,
937       PointSolution,DistanceMini);
938   }
939
940   if (!SolutionValide) return Precision::Infinite();
941   theNumberOfPnts++;
942   theGeomPnts.Bind(theNumberOfPnts,PointSolution);
943   IntPnt = theNumberOfPnts;
944
945   //-----------------------------------------------------------------------
946   // Si le point d intersection est quasi confondue avec une des extremites
947   // de l une ou l autre des bisectrices, l intersection n est pas validee.
948   //
949   // SAUF si une des bisectrices est issue d une connexion et que les 
950   // edges separes par les bissectrices sont des voisines sur le contour
951   // initiales.
952   // en effet le milieu de la connexion P qui est l origine d une des 
953   // bissectrices peut etre sur l autre bissectrice. 
954   // P est donc point d intersection
955   // et la bissectrice issue de la connexion est de longueur nulle.
956   // (ex : un rectangle dans un rectangle ou la connexion est entre un coin
957   // et un cote).
958   //-----------------------------------------------------------------------
959
960   Standard_Integer IndexEdge1,IndexEdge2,IndexEdge3,IndexEdge4;
961   Standard_Boolean ExtremiteControle = Standard_True;
962
963   IndexEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
964   IndexEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
965   IndexEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
966   IndexEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
967
968   if (theCircuit->ConnexionOn(IndexEdge2)){
969     // --------------------------------------
970     // BisectorOne est issue d une connexion.  
971     // --------------------------------------
972     if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && 
973       AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) && 
974       IndexEdge2 == IndexEdge3                               ){
975         ExtremiteControle = Standard_False;
976         Param1             = Param1 + Tolerance;
977     }
978   }
979
980   if (theCircuit->ConnexionOn(IndexEdge4)){
981      //--------------------------------------
982      //BisectorTwo est issue d une connexion.   
983      //--------------------------------------
984     if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && 
985       AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) &&
986       IndexEdge2 == IndexEdge3                               ){
987         ExtremiteControle = Standard_False;
988         Param2            = Param2 + Tolerance;
989     }
990   }
991
992   //if (ExtremiteControle) {
993   //  if(Bisector1->StartPoint().Distance(PointSolution) < Tolerance ||
994   //    Bisector2->StartPoint().Distance(PointSolution) < Tolerance  ) 
995   //    return Precision::Infinite();
996   //}
997
998   if(ExtremiteControle)
999   {
1000     if(Bisector1->StartPoint().Distance(PointSolution) < Tolerance)
1001     {
1002 #ifdef DRAW
1003       if(AffichBis)
1004       {
1005         DrawTrSurf::Set("Bis1", Bisector1);
1006         DrawTrSurf::Set("Bis2", Bisector2);
1007       }
1008 #endif
1009       return Precision::Infinite();
1010     }
1011     if(Bisector2->StartPoint().Distance(PointSolution) < Tolerance)
1012     {
1013         
1014 #ifdef DRAW
1015       if(AffichBis)
1016       {
1017         DrawTrSurf::Set("Bis1", Bisector1);
1018         DrawTrSurf::Set("Bis2", Bisector2);
1019       }
1020 #endif
1021       return Precision::Infinite();
1022     }
1023   }
1024
1025
1026
1027   if(BisectorOne->SecondParameter() < Precision::Infinite() &&
1028     BisectorOne->SecondParameter() < Param1*(1. - Tolerance )) 
1029     return Precision::Infinite();
1030
1031   if(BisectorTwo->FirstParameter() < Precision::Infinite() &&
1032     BisectorTwo->FirstParameter() < Param2*(1.- Tolerance)) 
1033     return Precision::Infinite();
1034
1035   BisectorOne->SecondParameter(Param1);
1036   BisectorTwo->FirstParameter (Param2);
1037
1038   
1039 #ifdef OCCT_DEBUG
1040   if (Affich) {
1041     cout<<"   coordonnees    : "<<GeomPnt  (IntPnt).X()<<" "
1042       <<GeomPnt  (IntPnt).Y()<<endl;
1043     cout<<"   parametres     : "<<Param1<<" "<<Param2<<endl;
1044     cout<<"   distancemini   : "<<DistanceMini<<endl;
1045   }
1046 #endif
1047
1048   return DistanceMini;
1049 }
1050
1051 //=============================================================================
1052 //function : Distance
1053 //purpose  :
1054 //=============================================================================
1055 Standard_Real MAT2d_Tool2d::Distance(const Handle(MAT_Bisector)& Bis,
1056   const Standard_Real         Param1,
1057   const Standard_Real         Param2) const
1058 {
1059   Standard_Real Dist = Precision::Infinite();
1060
1061   if (Param1 != Precision::Infinite() && Param2 != Precision::Infinite()) {
1062     gp_Pnt2d P1 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param1);
1063     gp_Pnt2d P2 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param2);
1064     Dist        = P1.Distance(P2);
1065   }
1066   return Dist;
1067 }
1068
1069 //=============================================================================
1070 //function : Dump
1071 //purpose  :
1072 //=============================================================================
1073 #ifndef OCCT_DEBUG
1074 void MAT2d_Tool2d::Dump(const Standard_Integer ,
1075   const Standard_Integer ) const
1076 {
1077   Standard_NotImplemented::Raise();
1078 #else
1079 void MAT2d_Tool2d::Dump(const Standard_Integer bisector,
1080   const Standard_Integer) const
1081 {
1082   if(bisector == -1) return;
1083   if(bisector > theNumberOfBisectors) return;
1084
1085   Handle(Geom2d_Curve) thebisector = Handle(Geom2d_Curve)::DownCast(GeomBis(bisector).Value());
1086
1087   MAT2d_DrawCurve(thebisector,3);
1088
1089 #endif
1090 }
1091
1092
1093 //=============================================================================
1094 //function : GeomBis
1095 //purpose  :
1096 //=============================================================================
1097 const Bisector_Bisec&  MAT2d_Tool2d::GeomBis (const Standard_Integer Index) 
1098   const
1099 {
1100   return theGeomBisectors.Find(Index);
1101 }
1102
1103 //=============================================================================
1104 //function : ChangeGeomBis
1105 //purpose  :
1106 //=============================================================================
1107 Bisector_Bisec&  MAT2d_Tool2d::ChangeGeomBis(const Standard_Integer Index)
1108 {
1109   return theGeomBisectors.ChangeFind(Index);
1110 }
1111
1112
1113 //=============================================================================
1114 //function : GeomElt
1115 //purpose  :
1116 //=============================================================================
1117 Handle(Geom2d_Geometry)  MAT2d_Tool2d::GeomElt(const Standard_Integer Index)
1118   const 
1119 {
1120   return  theCircuit->Value(Index);
1121 }
1122
1123
1124 //=============================================================================
1125 //function : GeomPnt
1126 //purpose  :
1127 //=============================================================================
1128 const gp_Pnt2d&  MAT2d_Tool2d::GeomPnt(const Standard_Integer Index) const
1129 {
1130   return theGeomPnts.Find(Index);
1131 }
1132
1133 //=============================================================================
1134 //function : GeomVec
1135 //purpose  :
1136 //=============================================================================
1137 const gp_Vec2d&  MAT2d_Tool2d::GeomVec(const Standard_Integer Index)const 
1138 {
1139   return theGeomVecs.Find(Index);
1140 }
1141
1142 //=============================================================================
1143 //function : Circuit
1144 //purpose  :
1145 //=============================================================================
1146 Handle(MAT2d_Circuit) MAT2d_Tool2d::Circuit()const 
1147 {
1148   return theCircuit;
1149 }
1150
1151 //=============================================================================
1152 //function : BisecFusion
1153 //purpose  :
1154 //=============================================================================
1155 void MAT2d_Tool2d::BisecFusion(const Standard_Integer I1,
1156   const Standard_Integer I2) 
1157 {
1158   Standard_Real               DU,UL1,UF1;
1159   Handle(Geom2d_TrimmedCurve) Bisector1;
1160   Handle(Geom2d_TrimmedCurve) Bisector2;
1161
1162   Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I1).Value());
1163   Bisector2 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I2).Value());
1164   UF1       = Bisector1->FirstParameter();
1165   UL1       = Bisector1->LastParameter();
1166
1167   Handle(Standard_Type) Type1 = Bisector1->BasisCurve()->DynamicType();
1168   if (Type1 == STANDARD_TYPE(Bisector_BisecCC)) {
1169     //------------------------------------------------------------------------------------
1170     // les bissectrice courbe/courbe sont  construites avec un point de depart
1171     // elles ne peuvent pas etre trimes par un point se trouvant de l autre cote du
1172     // point de depart.
1173     // pour faire la fusion des deux bissectrices on reconstruit la bissectrice entre les
1174     // deux courbes avec comme point de depart le dernier point de la Bisector2.
1175     // on trime ensuite la courbe par le dernier point de Bisector1.
1176     //------------------------------------------------------------------------------------
1177     Standard_Real            Tolerance    = MAT2d_TOLCONF;
1178     Bisector_Bisec           Bis;
1179     gp_Vec2d                 VBid(1,0);
1180     gp_Pnt2d                 P2   = Bisector2->Value(Bisector2->LastParameter());     
1181     gp_Pnt2d                 P1   = Bisector1->Value(Bisector1->LastParameter());   
1182     Handle(Bisector_BisecCC) BCC1 = Handle(Bisector_BisecCC)::DownCast(Bisector1->BasisCurve());
1183
1184     Bis.Perform(BCC1->Curve(2), BCC1->Curve(1), P2, VBid, VBid, 
1185                 theDirection, theJoinType, Tolerance, Standard_False); 
1186
1187     Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(Bis.Value());
1188     BCC1      = Handle(Bisector_BisecCC)   ::DownCast(Bisector1->BasisCurve()); 
1189     UF1       = BCC1->FirstParameter();
1190     UL1       = BCC1->Parameter(P1);
1191     Bisector1->SetTrim(UF1,UL1);
1192     theGeomBisectors.Bind(I1,Bis);
1193   }
1194   else {
1195     DU        = Bisector2->LastParameter() - Bisector2->FirstParameter();
1196     UF1       = UF1 - DU;
1197
1198     Handle(Bisector_BisecAna) BAna = Handle(Bisector_BisecAna)::DownCast(Bisector1->BasisCurve());
1199     //---------------------------- uncomment if new method Bisector_BisecAna::SetTrim(f,l) is not used
1200     //    Handle(Geom2d_Curve) C2d = BAna->Geom2dCurve();
1201     //    Handle(Geom2d_TrimmedCurve) trimC2d = new Geom2d_TrimmedCurve(C2d, UF1, UL1);
1202     //    BAna->Init(trimC2d);
1203     //--------------------------- end
1204     BAna->SetTrim(UF1,UL1); // put comment if SetTrim(f,l) is not used
1205
1206     Bisector1->SetTrim(UF1,UL1);
1207   }
1208 }
1209
1210 //=============================================================================
1211 //function : Type
1212 //purpose  :
1213 //=============================================================================
1214 static Handle(Standard_Type) Type(const Handle(Geom2d_Geometry)& aGeom) 
1215 {
1216   Handle(Standard_Type) type = aGeom->DynamicType();
1217   Handle(Geom2d_Curve)  curve;
1218
1219   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1220     curve = Handle(Geom2d_TrimmedCurve)::DownCast(aGeom)->BasisCurve();
1221     type  = curve->DynamicType();
1222   }
1223   return type;
1224 }
1225
1226 //==========================================================================
1227 //function : AreNeighbours
1228 //purpose  : Return TRUE si IEdge1 et IEdge2 correspondent a des elements 
1229 //           consecutifs sur un contour ferme de NbEdge elements.
1230 //==========================================================================
1231 Standard_Boolean AreNeighbours(const Standard_Integer IEdge1,
1232   const Standard_Integer IEdge2,
1233   const Standard_Integer NbEdge)
1234 {
1235   if      (Abs(IEdge1 - IEdge2) == 1)         return Standard_True;
1236   else if (Abs(IEdge1 - IEdge2) == NbEdge -1) return Standard_True;
1237   else                                        return Standard_False; 
1238 }
1239
1240 //==========================================================================
1241 //function : SetTrim
1242 //purpose  :
1243 //==========================================================================
1244 static void SetTrim(Bisector_Bisec& Bis, const Handle(Geom2d_Curve)& Line1)
1245 {  
1246   Geom2dInt_GInter Intersect; 
1247   Standard_Real    Distance;  
1248   Standard_Real    Tolerance = MAT2d_TOLCONF;  
1249   Handle(Geom2d_TrimmedCurve) Bisector = 
1250     Handle(Geom2d_TrimmedCurve)::DownCast(Bis.ChangeValue());
1251
1252   IntRes2d_Domain  Domain1   = Domain(Bisector,Tolerance);
1253   Standard_Real    UB1       = Bisector->FirstParameter();
1254   Standard_Real    UB2       = Bisector->LastParameter();
1255
1256   gp_Pnt2d         FirstPointBisector = Bisector->Value(UB1);
1257   Standard_Real    UTrim              = Precision::Infinite();
1258
1259   Geom2dAdaptor_Curve AdapBisector(Bisector);
1260   Geom2dAdaptor_Curve AdapLine1   (Line1);
1261   Intersect.Perform(AdapBisector, Domain1, 
1262     AdapLine1, Tolerance, Tolerance);
1263
1264   if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1265     for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1266       gp_Pnt2d PInt = Intersect.Point(i).Value();
1267       Distance      = FirstPointBisector.Distance(PInt);
1268       if (Distance > 10.*Tolerance                     && 
1269         Intersect.Point(i).ParamOnFirst() < UTrim ) {
1270           UTrim = Intersect.Point(i).ParamOnFirst();
1271       }
1272     }
1273   } 
1274   // ------------------------------------------------------------------------
1275   // Restriction de la Bissectrice par le point d intersection de plus petit
1276   // parametre.
1277   // ------------------------------------------------------------------------
1278   if (UTrim < UB2 && UTrim > UB1) Bisector->SetTrim(UB1,UTrim);
1279 }
1280
1281 //==========================================================================
1282 //function : Domain
1283 //purpose  :
1284 //==========================================================================
1285 IntRes2d_Domain  Domain(const Handle(Geom2d_TrimmedCurve)& Bisector1,
1286   const Standard_Real                Tolerance)
1287 {
1288   Standard_Real Param1 = Bisector1->FirstParameter();
1289   Standard_Real Param2 = Bisector1->LastParameter();
1290   if(Param2 > 10000.) {
1291     Param2 = 10000.;
1292     Handle(Standard_Type) Type1 = Type(Bisector1->BasisCurve());    
1293     Handle(Geom2d_Curve)  BasisCurve;
1294     if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) {
1295       BasisCurve = Handle(Bisector_BisecAna)
1296         ::DownCast(Bisector1->BasisCurve())->Geom2dCurve();
1297       Type1      = BasisCurve->DynamicType();
1298     }
1299     gp_Parab2d gpParabola;
1300     gp_Hypr2d  gpHyperbola;
1301     Standard_Real Focus;
1302     Standard_Real Limit = 50000.;
1303     if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1304       gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1305       Focus = gpParabola.Focal();
1306       Standard_Real Val1 = Sqrt(Limit*Focus);
1307       Standard_Real Val2 = Sqrt(Limit*Limit);
1308       Param2 = (Val1 <= Val2 ? Val1:Val2);
1309     }
1310     else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1311       gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1312       Standard_Real Majr  = gpHyperbola.MajorRadius();
1313       Standard_Real Minr  = gpHyperbola.MinorRadius();
1314       Standard_Real Valu1 = Limit/Majr;
1315       Standard_Real Valu2 = Limit/Minr;
1316       Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1317       Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1318       Param2 = (Val1 <= Val2 ? Val1:Val2);
1319     }
1320   }
1321
1322   IntRes2d_Domain Domain1(Bisector1->Value(Param1),Param1,Tolerance,
1323     Bisector1->Value(Param2),Param2,Tolerance);
1324   if(Bisector1->BasisCurve()->IsPeriodic()) {
1325     Domain1.SetEquivalentParameters(0.,2.*M_PI);
1326   }
1327   return Domain1;
1328 }
1329
1330 //=============================================================================
1331 //function : CheckEnds
1332 //purpose  :
1333 //=============================================================================
1334 Standard_Boolean CheckEnds (const Handle(Geom2d_Geometry)& Elt    ,
1335                             const gp_Pnt2d&                PCom   ,
1336                             const Standard_Real            Distance,
1337                             const Standard_Real            Tol) 
1338  
1339 {  
1340   Handle(Standard_Type)       Type   = Elt->DynamicType();      
1341   Handle(Geom2d_TrimmedCurve) Curve; 
1342
1343   if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {   
1344     return Standard_False;
1345   }
1346   else {
1347     Curve    = Handle(Geom2d_TrimmedCurve)::DownCast(Elt);      
1348     gp_Pnt2d aPf = Curve->StartPoint();
1349     gp_Pnt2d aPl = Curve->EndPoint();
1350     Standard_Real df = PCom.Distance(aPf);
1351     Standard_Real dl = PCom.Distance(aPl);
1352     if(Abs(df - Distance) <= Tol)
1353       return Standard_True;
1354     if(Abs(dl - Distance) <= Tol)
1355       return Standard_True;
1356   }
1357   return Standard_False;
1358 }
1359
1360
1361 #ifdef OCCT_DEBUG
1362 //==========================================================================
1363 //function : MAT2d_DrawCurve
1364 //purpose  : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
1365 //           definie par <Indice>.
1366 //            Indice = 1 jaune,
1367 //            Indice = 2 bleu,
1368 //            Indice = 3 rouge,
1369 //            Indice = 4 vert.
1370 //==========================================================================
1371 void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
1372   const Standard_Integer      /*Indice*/)
1373 {  
1374   Handle(Standard_Type)      type = aCurve->DynamicType();
1375   Handle(Geom2d_Curve)       curve,CurveDraw;
1376 #ifdef DRAW
1377   Handle(DrawTrSurf_Curve2d) dr;
1378   Draw_Color                 Couleur;
1379 #endif
1380
1381   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1382     curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
1383     type = curve->DynamicType();    
1384     // PB de representation des courbes semi_infinies.
1385     gp_Parab2d gpParabola;
1386     gp_Hypr2d  gpHyperbola;
1387     Standard_Real Focus;
1388     Standard_Real Limit = 50000.;
1389     Standard_Real delta = 400;
1390
1391     // PB de representation des courbes semi_infinies.
1392     if (aCurve->LastParameter() == Precision::Infinite()) {
1393
1394       if (type == STANDARD_TYPE(Geom2d_Parabola)) {
1395         gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
1396         Focus = gpParabola.Focal();
1397         Standard_Real Val1 = Sqrt(Limit*Focus);
1398         Standard_Real Val2 = Sqrt(Limit*Limit);
1399         delta= (Val1 <= Val2 ? Val1:Val2);
1400       }
1401       else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1402         gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
1403         Standard_Real Majr  = gpHyperbola.MajorRadius();
1404         Standard_Real Minr  = gpHyperbola.MinorRadius();
1405         Standard_Real Valu1 = Limit/Majr;
1406         Standard_Real Valu2 = Limit/Minr;
1407         Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1408         Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1409         delta  = (Val1 <= Val2 ? Val1:Val2);
1410       }
1411       CurveDraw = new Geom2d_TrimmedCurve(aCurve,
1412         aCurve->FirstParameter(),
1413         aCurve->FirstParameter() + delta);
1414     }
1415     else {
1416       CurveDraw = aCurve;
1417     }
1418     // fin PB.
1419   }
1420   else {
1421     CurveDraw = aCurve;
1422   }
1423
1424 #ifdef DRAW
1425   Standard_Integer Indice = 1;
1426   if      (Indice == 1) Couleur = Draw_jaune;
1427   else if (Indice == 2) Couleur = Draw_bleu;
1428   else if (Indice == 3) Couleur = Draw_rouge;
1429   else if (Indice == 4) Couleur = Draw_vert;
1430
1431   if (type == STANDARD_TYPE(Geom2d_Circle))
1432     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
1433   else if (type  == STANDARD_TYPE(Geom2d_Line))
1434     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
1435   else
1436     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
1437
1438   //dout << dr;
1439   //dout.Flush();
1440 #endif
1441 }
1442
1443 #endif
1444