0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / MAT2d / MAT2d_Circuit.cxx
1 // Created on: 1993-11-19
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 #include <Adaptor2d_OffsetCurve.hxx>
18 #include <Geom2d_CartesianPoint.hxx>
19 #include <Geom2d_Geometry.hxx>
20 #include <Geom2d_TrimmedCurve.hxx>
21 #include <Geom2dAdaptor_HCurve.hxx>
22 #include <Geom2dInt_GInter.hxx>
23 #include <IntRes2d_IntersectionPoint.hxx>
24 #include <MAT2d_BiInt.hxx>
25 #include <MAT2d_Circuit.hxx>
26 #include <MAT2d_Connexion.hxx>
27 #include <MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger.hxx>
28 #include <MAT2d_DataMapOfBiIntSequenceOfInteger.hxx>
29 #include <MAT2d_DataMapOfIntegerConnexion.hxx>
30 #include <MAT2d_MiniPath.hxx>
31 #include <MAT2d_SequenceOfConnexion.hxx>
32 #include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
33 #include <Precision.hxx>
34 #include <Standard_Type.hxx>
35 #include <TColStd_Array1OfBoolean.hxx>
36 #include <TColStd_Array1OfInteger.hxx>
37 #include <TColStd_SequenceOfInteger.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(MAT2d_Circuit,Standard_Transient)
40
41 #ifdef OCCT_DEBUG
42 #include <GCE2d_MakeSegment.hxx>
43 #include <Geom2d_Curve.hxx>
44 #include <Geom2d_Parabola.hxx>
45 #include <Geom2d_Hyperbola.hxx>
46 #include <Geom2d_TrimmedCurve.hxx>
47 #include <Geom2d_CartesianPoint.hxx>
48 #include <Geom2d_Line.hxx>
49 #include <Geom2d_Circle.hxx>
50 #endif
51
52 #ifdef DRAW
53 #include <Draw_Appli.hxx>
54 #include <DrawTrSurf_Curve2d.hxx>
55 #include <Draw_Marker2D.hxx>
56   static Handle(DrawTrSurf_Curve2d) draw;
57   Standard_EXPORT Draw_Viewer dout;
58 #endif
59 #ifdef OCCT_DEBUG
60   static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
61                               const Standard_Integer      Indice);
62   static Standard_Boolean AffichCircuit = 0;
63 #endif
64
65 // static functions:
66
67 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
68                                const Handle(Geom2d_Geometry)& Geom2,
69                                      Standard_Real&           DotProd);
70
71
72 //=============================================================================
73 //function : Constructor
74 //purpose :
75 //=============================================================================
76 MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType,
77                              const Standard_Boolean IsOpenResult)
78 : direction(0.0)
79 {
80   myJoinType = aJoinType;
81   myIsOpenResult = IsOpenResult;
82 }
83
84 //=============================================================================
85 //function : Perform
86 //purpose :
87 //=============================================================================
88 void  MAT2d_Circuit::Perform
89   (       MAT2d_SequenceOfSequenceOfGeometry& FigItem,
90    const TColStd_SequenceOfBoolean          & IsClosed,
91    const Standard_Integer                     IndRefLine,
92    const Standard_Boolean                     Trigo)
93 {
94   Standard_Integer          NbLines = FigItem.Length();
95   Standard_Integer          i;
96   TColStd_Array1OfBoolean   Open(1,NbLines);
97   MAT2d_SequenceOfConnexion SVide;
98   Handle(MAT2d_Connexion)   ConnexionNul;
99
100   if (Trigo) direction = 1.; else direction = -1.;
101
102   //---------------------
103   // Reinitialisation SD.
104   //---------------------
105   geomElements.Clear();
106   connexionMap.Clear();
107   linkRefEqui.Clear();
108   linesLength.Clear();
109
110   //----------------------------
111   // Detection Lignes ouvertes.
112   //----------------------------
113   for ( i = 1; i <= NbLines; i++) {    
114     Handle(Geom2d_TrimmedCurve) Curve;
115     Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
116     gp_Pnt2d P1 = Curve->StartPoint();  
117     Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
118     gp_Pnt2d P2 = Curve->EndPoint();
119 //  Modified by Sergey KHROMOV - Wed Mar  6 16:59:01 2002 Begin
120 //     if ( P1.IsEqual(P2,Precision::Confusion()))  Open(i) = Standard_False;
121 //     else                                         Open(i) = Standard_True;
122     if (IsClosed(i))                                Open(i) = Standard_False;
123     else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
124     else                                            Open(i) = Standard_True;
125 //  Modified by Sergey KHROMOV - Wed Mar  6 16:59:04 2002 End
126   }
127     
128   //---------------------------------------------------------------
129   // Insertion des cassures saillantes ou
130   // ajout des extremites de chaque courbe si la ligne est ouverte.
131   //---------------------------------------------------------------
132   for ( i = 1; i <= NbLines; i++) {
133     if (Open(i)) {
134       InitOpen(FigItem.ChangeValue(i));  
135       linesLength.Append(FigItem.Value(i).Length());
136     }
137     else {
138       InsertCorner(FigItem.ChangeValue(i));
139       linesLength.Append(FigItem.Value(i).Length());
140     }
141   }
142
143   //---------------------------------
144   // Une seule ligne => Rien a faire.
145   //---------------------------------
146   if (NbLines == 1) {
147     if (Open(1)) {
148       DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction);  
149       linesLength.SetValue(1,FigItem.Value(1).Length());
150     }
151     geomElements  = FigItem.Value(1);
152     UpDateLink(1,1,1,geomElements.Length());     
153     linesLength.Append(FigItem.Value(1).Length());
154     return;
155   }
156     
157   //------------------
158   // Plusieurs lignes.
159   //------------------
160   
161   //---------------------------------------------------------
162   // Calcul de l ensemble des connexions realisant le chemin. 
163   //---------------------------------------------------------
164   MAT2d_MiniPath  Road;
165   Road.Perform(FigItem,IndRefLine,Trigo);
166   
167   //------------------------
168   // Fermeture ligne ouverte.
169   //-------------------------
170   for ( i = 1; i <= NbLines; i++) {
171     if (Open(i)) {
172       Handle(MAT2d_Connexion)  CF;
173       if (Road.IsRoot(i))      CF = ConnexionNul; else CF = Road.Father(i);
174       if (Road.IsConnexionsFrom(i)) {
175         DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i),
176                    CF,direction);  
177       }
178       else {
179         DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction);  
180       }
181       linesLength.SetValue(i,FigItem.Value(i).Length());
182     }
183   }
184
185   //------------------------
186   // Construction du chemin.
187   //------------------------
188   Road.RunOnConnexions();
189
190 #ifdef OCCT_DEBUG
191   if (AffichCircuit) {
192     Standard_Integer NbConnexions = Road.Path().Length();
193     for (i = 1; i <= NbConnexions; i++) {
194       Handle(Geom2d_TrimmedCurve) edge;
195       edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(),
196                                Road.Path().Value(i)->PointOnSecond());
197       MAT2d_DrawCurve(edge,2);
198     }
199   }
200 #endif
201
202   //-------------------------
203   // Construction du Circuit.
204   //-------------------------
205   ConstructCircuit(FigItem,IndRefLine,Road);
206 }
207
208 //=======================================================================
209 //function : IsSharpCorner
210 //purpose  : Return True Si le point commun entre <Geom1> et <Geom2> est 
211 //           une cassure saillante par rapport <Direction>
212 //=======================================================================
213
214 Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1,
215                                               const Handle(Geom2d_Geometry)& Geom2,
216                                               const Standard_Real Direction) const
217 {
218   Standard_Real    DotProd;
219   Standard_Real    ProVec = CrossProd (Geom1,Geom2,DotProd);
220   Standard_Integer NbTest = 1;
221   Standard_Real    DU = Precision::Confusion();
222   Handle(Geom2d_TrimmedCurve) C1,C2;
223
224   C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
225   C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
226 //  Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
227 // Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
228 //  Standard_Real  TolAng = 1.E-5;
229   Standard_Real  TolAng = 1.E-8;
230 //  Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
231
232   if (myJoinType == GeomAbs_Arc)
233   {
234     while (NbTest <= 10) {
235       if      ((ProVec)*Direction < -TolAng)                 
236         return Standard_True;                // Saillant.
237       if      ((ProVec)*Direction >  TolAng)
238         return Standard_False;              // Rentrant.
239       else { 
240         if (DotProd > 0) {
241           return Standard_False;            // Plat.
242         }
243         TolAng = 1.E-8;
244         Standard_Real U1 = C1->LastParameter()  - NbTest*DU;
245         Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
246         gp_Dir2d Dir1(C1->DN(U1,1));
247         gp_Dir2d Dir2(C2->DN(U2,1));
248         DotProd = Dir1.Dot(Dir2);
249         ProVec  =  Dir1^Dir2;
250         NbTest++;
251       } 
252     }
253     
254     
255     
256     // Rebroussement.
257     // on calculde des paralleles aux deux courbes du cote du domaine
258     // de calcul
259     // Si pas dintersection => saillant.
260     // Sinon                => rentrant.
261     Standard_Real D ;
262     Standard_Real Tol   = Precision::Confusion();
263     Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
264     Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
265     gp_Pnt2d      P     = C1->Value(C1->LastParameter());
266     gp_Pnt2d      P1    = C1->Value(MilC1);
267     gp_Pnt2d      P2    = C2->Value(MilC2);
268     
269     D = Min(P1.Distance(P),P2.Distance(P));
270     D /= 10;
271     
272     if (Direction < 0.) D = -D;
273
274     Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
275     Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
276     Adaptor2d_OffsetCurve OC1(HC1, D, MilC1, C1->LastParameter());
277     Adaptor2d_OffsetCurve OC2(HC2, D, C2->FirstParameter(), MilC2);
278     Geom2dInt_GInter Intersect; 
279     Intersect.Perform(OC1,OC2,Tol,Tol);
280     
281 #ifdef OCCT_DEBUG
282     static Standard_Boolean Affich = 0;
283     if (Affich) {
284 #ifdef DRAW
285       Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
286       Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
287       for (Standard_Integer ki = 0; ki <= 9; ki++) {
288         gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
289         gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
290         Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
291         Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge); 
292         dout << dr1;
293         dout << dr2;
294       }
295       dout.Flush();
296 #endif
297     }
298 #endif
299     
300     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
301       return Standard_False;
302     }
303     else {
304       return Standard_True;
305     }
306   } //end of if (myJoinType == GeomAbs_Arc)
307   else if (myJoinType == GeomAbs_Intersection)
308   {
309     if (Abs(ProVec) <= TolAng &&
310         DotProd < 0)
311     {
312       while (NbTest <= 10)
313       {
314         Standard_Real U1 = C1->LastParameter()  - NbTest*DU;
315         Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
316         gp_Dir2d Dir1(C1->DN(U1,1));
317         gp_Dir2d Dir2(C2->DN(U2,1));
318         DotProd = Dir1.Dot(Dir2);
319         ProVec  =  Dir1^Dir2;
320         if      ((ProVec)*Direction < -TolAng)                 
321           return Standard_True;                // Saillant.
322         if      ((ProVec)*Direction >  TolAng)
323           return Standard_False;              // Rentrant.
324         
325         NbTest++;
326       }
327       return Standard_False;
328     }
329     else
330       return Standard_False;
331   }
332   return Standard_False;
333 }
334
335 //=======================================================================
336 //function : SubSequence
337 //purpose  : 
338 //=======================================================================
339 static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1,
340                               Standard_Integer               IF,
341                               Standard_Integer               IL,
342                               TColGeom2d_SequenceOfGeometry& S2)
343 {
344   S2.Clear();
345   for (Standard_Integer i = IF; i<= IL; i++){
346     S2.Append(S1.Value(i));
347   }
348 }
349
350                         
351 //=============================================================================
352 //function : ConstructCircuit
353 //purpose :
354 //=============================================================================
355 void  MAT2d_Circuit::ConstructCircuit
356   (const MAT2d_SequenceOfSequenceOfGeometry& FigItem, 
357    const Standard_Integer                    IndRefLine,
358    const MAT2d_MiniPath&                     Road)
359 {
360   Handle(MAT2d_Connexion)            PrevC,CurC;
361   TColGeom2d_SequenceOfGeometry      SetOfItem;
362   Standard_Integer                   NbConnexions;
363   Standard_Integer                   ILastItem;
364   Standard_Integer                   IndLast;
365   Standard_Integer                   i;
366   
367   NbConnexions = Road.Path().Length();
368   //-----------------------------------------------------
369   // Depart du premier element de la ligne de reference.
370   //-----------------------------------------------------
371   PrevC = Road.Path().Value(1);
372   SubSequence(FigItem.Value(IndRefLine),
373               1,
374               PrevC->IndexItemOnFirst(),
375               geomElements);
376   UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst());
377   connexionMap.Bind(geomElements.Length()+1,PrevC);
378   ILastItem = geomElements.Length();
379   
380   //-----------------------------------------------------------------------
381   // Ajout des portion de lignes delimites par deux connexions successives.
382   //-----------------------------------------------------------------------
383   for ( i = 2; i <= NbConnexions; i++) {
384     CurC = Road.Path().Value(i);
385     if (PassByLast(PrevC,CurC)) {
386       //------------------------------------------------------
387       // La portion passe par le dernier element de la ligne.
388       // - ajout de la portion de PrevC au dernier element 
389       //   de la ligne.
390       // - Si la ligne contient plus d'un element ajout de la 
391       //   portion du premier element de la ligne a CurC.
392       //------------------------------------------------------
393       IndLast = FigItem.Value(CurC->IndexFirstLine()).Length();
394       SubSequence (FigItem.Value(CurC->IndexFirstLine()),
395                    PrevC->IndexItemOnSecond(),
396                    IndLast,
397                    SetOfItem);
398       UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
399                  PrevC->IndexItemOnSecond(),IndLast);
400       geomElements.Append(SetOfItem);
401       ILastItem = geomElements.Length();
402
403       if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) {
404         SubSequence(FigItem.Value(CurC->IndexFirstLine()),
405                     1,
406                     CurC->IndexItemOnFirst(),
407                     SetOfItem);
408         UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
409                    1,CurC->IndexItemOnFirst());
410         geomElements.Append(SetOfItem);
411         ILastItem = geomElements.Length();
412       }
413       connexionMap.Bind(ILastItem+1,CurC);
414     }
415     else{     
416
417       //------------------------------------------------------
418       // La portion ne passe par le dernier element de la ligne.
419       //------------------------------------------------------
420       SubSequence(FigItem.Value(CurC->IndexFirstLine()),
421                   PrevC->IndexItemOnSecond(),
422                   CurC ->IndexItemOnFirst(),
423                   SetOfItem);
424       UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
425                  PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst());
426       geomElements.Append(SetOfItem);
427       ILastItem = geomElements.Length();
428       connexionMap.Bind(ILastItem+1,CurC);
429     }
430     PrevC = CurC;
431   }
432
433   //-------------------------------------------------------------
434   // Fermeture : de la derniere connexion au dernier element de la
435   //             ligne de reference.
436   //-------------------------------------------------------------
437   IndLast = FigItem.Value(IndRefLine).Length();
438   if (IndLast == 1) {
439     connexionMap.Bind(1,CurC);
440     connexionMap.UnBind(ILastItem+1);
441   }
442   else {
443     SubSequence(FigItem.Value(IndRefLine),
444                 PrevC->IndexItemOnSecond(),
445                 IndLast,
446                 SetOfItem);
447     UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast);
448     geomElements.Append(SetOfItem);
449     ILastItem = geomElements.Length();
450   }
451
452   //--------------------------------------
453   // Tri des RefToEqui pour chaque element.
454   //--------------------------------------
455   MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite;
456
457   for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) {
458     if (Ite.Value().Length() > 1) {
459       SortRefToEqui(Ite.Key());
460     }
461   }
462
463 #ifdef OCCT_DEBUG
464   if (AffichCircuit) {
465     ILastItem = geomElements.Length();
466     for (i = 1; i <= ILastItem; i++) {
467       if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){
468         MAT2d_DrawCurve
469           (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2);
470       }
471     }
472   }
473 #endif
474 }
475
476 //=============================================================================
477 //function : InitOpen
478 //purpose  :
479 //=============================================================================
480 void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const 
481
482   Handle(Geom2d_TrimmedCurve) Curve;
483   Standard_Real               DotProd;
484
485   Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
486   Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
487   Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
488   Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
489   
490   for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
491     if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
492          DotProd < 0. ) {
493       Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
494       Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint()));
495       i++;
496     }
497   }
498 }
499
500 //=============================================================================
501 //function : DoubleLine
502 //purpose  :
503 //=============================================================================
504 void MAT2d_Circuit::DoubleLine 
505   (      TColGeom2d_SequenceOfGeometry& Line,
506          MAT2d_SequenceOfConnexion&     ConnexionFrom,
507    const Handle(MAT2d_Connexion)&       ConnexionFather,
508    const Standard_Real                  SideRef)
509 const
510
511   Handle(Standard_Type)          Type;
512   Handle(Geom2d_TrimmedCurve)    Curve;
513   Standard_Integer               NbItems = Line.Length();
514   Standard_Integer               i;
515   Standard_Real                  ProVec,DotProd;
516   Handle(MAT2d_Connexion)        CC;
517
518   //--------------------------
519   // Completion de la ligne.
520   //--------------------------
521   if (!myIsOpenResult)
522   {
523     for ( i = NbItems - 1; i > 1; i--){
524       Type = Line.Value(i)->DynamicType();
525       if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
526         Line.Append(Line.Value(i));
527       }
528       else {
529         Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
530         Curve->Reverse();
531         Line.Append(Curve);
532       }
533     }
534   }
535
536   //------------------------------------------
537   // Repartition des connexions sur la ligne
538   //------------------------------------------
539   Standard_Integer IAfter       = ConnexionFrom.Length();
540   Standard_Integer NbConnexions = IAfter;
541   Standard_Integer IndCOF;
542
543   for (i = 1; i <= IAfter; i++) {
544     CC     = ConnexionFrom.Value(i);
545     IndCOF = CC->IndexItemOnFirst();
546     Type = Line.Value(IndCOF)->DynamicType();
547
548     if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
549       if (IndCOF!= NbItems && IndCOF!= 1) {
550         ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
551         if ((ProVec)*SideRef > 0){
552            CC->IndexItemOnFirst(2*NbItems - IndCOF);
553            ConnexionFrom.InsertAfter(IAfter,CC);
554            ConnexionFrom.Remove(i);
555            IAfter--;
556            i--;
557          }
558       }
559     }
560     else  if (Side(CC,Line) != SideRef){
561       Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
562       CC->IndexItemOnFirst(2*NbItems - IndCOF);
563       CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst()));
564       ConnexionFrom.InsertAfter(IAfter,CC);
565       ConnexionFrom.Remove(i);
566       IAfter--;
567       i--;
568     }
569   }
570
571   //---------------------------
572   // Mise a jour connexion pere.  
573   //---------------------------
574   if (!ConnexionFather.IsNull()) {
575     CC     = ConnexionFather->Reverse();
576     IndCOF = CC->IndexItemOnFirst();
577     Type = Line.Value(IndCOF)->DynamicType();
578
579     if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
580       if (IndCOF != NbItems && IndCOF != 1) {
581         ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
582         if ((ProVec)*SideRef > 0){
583           ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
584          }
585       }
586     }
587     else  if (Side(CC,Line) != SideRef){
588       Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
589       ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
590       ConnexionFather->ParameterOnSecond
591         (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond()));
592     }
593   } 
594   
595   //-------------------------------------
596   // Suppression des cassures rentrantes.
597   //-------------------------------------
598   Standard_Integer        IndLine = 1;
599   Standard_Integer        ICorres = 1;
600   TColStd_Array1OfInteger Corres(1,Line.Length());
601     
602   while (Line.Value(IndLine) != Line.Last()){
603     Corres(ICorres) = IndLine;
604     Type = Line.Value(IndLine)->DynamicType();
605
606     if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) && 
607         ICorres != 1 && ICorres != NbItems)  {
608
609       if (!IsSharpCorner(Line.Value(IndLine - 1),
610                          Line.Value(IndLine + 1),SideRef)){
611         Line.Remove(IndLine);
612         IndLine--;
613         Corres(ICorres) =0;
614       }
615     }
616     IndLine++;
617     ICorres++;
618   }
619   Corres(ICorres) = IndLine;
620
621   if (!myIsOpenResult)
622   {
623     for (i = 1; i < 2*NbItems - 2; i++) {
624       if (Corres(i) == 0)
625         Corres(i) = Corres(2*NbItems - i);
626     }
627     
628 #ifdef OCCT_DEBUG
629     if (AffichCircuit) {
630       for (i = 1; i <= 2*NbItems - 2; i++) {
631         std::cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<std::endl;
632       }
633     }
634 #endif
635     
636     //----------------------------
637     // Mise a jour des Connexions.
638     //----------------------------
639     for ( i = 1; i <= NbConnexions; i++){
640       CC = ConnexionFrom.ChangeValue(i);
641       CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
642     }
643     
644     if (!ConnexionFather.IsNull()) {
645       ConnexionFather
646         ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
647     }
648   }
649 }
650
651
652 //=============================================================================
653 //function : InsertCorner
654 //purpose :
655 //=============================================================================
656 void  MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
657 {
658   Standard_Integer              i,isuiv;
659   Handle(Geom2d_TrimmedCurve)   Curve;
660   Standard_Boolean              Insert;
661
662   for ( i = 1; i <= Line.Length(); i++) {
663     isuiv  = (i == Line.Length()) ? 1 : i + 1;
664     Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction);
665
666 #ifdef OCCT_DEBUG
667   if (AffichCircuit) {
668     if (Insert) {
669       Curve      = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
670 #ifdef DRAW
671       gp_Pnt2d P = Curve->StartPoint();
672       Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert); 
673       dout << dr;
674       dout.Flush();
675 #endif
676     }
677   }
678 #endif
679
680     if (Insert) {     
681       Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
682       Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint()));
683       i++;
684     }
685   }
686 }
687
688 //=============================================================================
689 //function : NumberOfItem
690 //purpose :
691 //=============================================================================
692 Standard_Integer  MAT2d_Circuit::NumberOfItems()const 
693 {
694   return geomElements.Length();
695 }
696
697 //=============================================================================
698 //function : LineLength 
699 //purpose  :
700 //=============================================================================
701 Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const
702 {
703   return linesLength(I);
704 }
705
706 //=============================================================================
707 //function : Value
708 //purpose  :
709 //=============================================================================
710 Handle(Geom2d_Geometry)  MAT2d_Circuit::Value 
711        (const Standard_Integer Index)const
712 {
713   return geomElements.Value(Index);
714 }
715
716 //=============================================================================
717 //function : RefToEqui
718 //purpose  :
719 //=============================================================================
720 const TColStd_SequenceOfInteger&  MAT2d_Circuit::RefToEqui
721        (const Standard_Integer IndLine, 
722         const Standard_Integer IndCurve) const
723 {
724   MAT2d_BiInt Key(IndLine,IndCurve);
725   return linkRefEqui(Key);
726 }
727
728 //=============================================================================
729 //function : SortRefToEqui
730 //purpose  :
731 //=============================================================================
732 void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef)
733 {
734   Standard_Integer i;
735   TColStd_SequenceOfInteger&  S = linkRefEqui.ChangeFind(BiRef);
736   TColStd_SequenceOfInteger   SFin;
737
738   for( i = 1; i <=  S.Length(); i++){
739     if (!ConnexionOn(S.Value(i))) break;
740   }
741   if ( i > 1 && i <= S.Length()) {
742     SFin = S;
743     SFin.Split(i,S);
744     S.Append(SFin);
745   }
746 }
747
748 //=============================================================================
749 //function : Connexion
750 //purpose  :
751 //=============================================================================
752 Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const
753 {
754   return connexionMap(I);
755 }
756
757 //=============================================================================
758 //function : ConnexionOn
759 //purpose  :
760 //=============================================================================
761 Standard_Boolean  MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const
762 {
763   return connexionMap.IsBound(I);
764 }
765
766 //=============================================================================
767 //function : Side
768 //purpose  :
769 //=============================================================================
770 Standard_Real MAT2d_Circuit::Side
771   (const Handle(MAT2d_Connexion)&               C1,
772    const TColGeom2d_SequenceOfGeometry&         Line)
773 const
774 {
775   Handle(Geom2d_TrimmedCurve) Curve;
776
777   gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(),
778                  C1->PointOnSecond().Y() - C1->PointOnFirst().Y());
779   Curve = Handle(Geom2d_TrimmedCurve)::DownCast
780                                        (Line.Value(C1->IndexItemOnFirst()));
781   gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1);  
782   if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.;
783 }
784
785 //=============================================================================
786 //function : PassByLast
787 //purpose  :
788 //=============================================================================
789 Standard_Boolean MAT2d_Circuit::PassByLast
790   (const Handle(MAT2d_Connexion)& C1,
791    const Handle(MAT2d_Connexion)& C2) const
792 {
793   if (C2->IndexFirstLine() == C1->IndexSecondLine()){
794     if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) {
795       return Standard_True;
796     }
797     else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) {
798       if (C1->IndexFirstLine() == C2->IndexSecondLine()) {
799         return Standard_True;
800       }
801       if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) {
802         gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst());
803         gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond());
804         if ((Vect1^Vect2)*direction > 0) {
805           return Standard_True;
806         }
807       }
808       else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) {
809         return Standard_True;
810       }
811     }
812   }
813   return Standard_False;
814 }
815
816 //=============================================================================
817 //function : UpDateLink
818 //purpose  :
819 //=============================================================================
820 void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst,
821                                const Standard_Integer ILine,
822                                const Standard_Integer ICurveFirst,
823                                const Standard_Integer ICurveLast)
824 {
825   Standard_Integer IEqui = IFirst;
826   Standard_Integer i;
827
828   for (i = ICurveFirst; i <= ICurveLast; i++) {
829     MAT2d_BiInt Key(ILine,i);
830     if (linkRefEqui.IsBound(Key)) {
831       linkRefEqui(Key).Append(IEqui);
832     }
833     else {
834       TColStd_SequenceOfInteger L;
835       linkRefEqui.Bind(Key,L);
836       linkRefEqui(Key).Append(IEqui);
837     }
838     IEqui++;
839   }
840 }
841
842 //==========================================================================
843 //function : CrossProd 
844 //purpose  : Calcul le produit vectoriel et scalaire  entre les directions des
845 //            tangentes a la fin de Geom1 et au debut de Geom2.
846 //            Geom1 et Geom2 doivent etre des courbes.
847 //==========================================================================
848 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
849                                const Handle(Geom2d_Geometry)& Geom2,
850                                      Standard_Real&           DotProd)
851 {
852   Handle(Geom2d_TrimmedCurve) Curve;
853
854   Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
855   gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1));
856   Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
857   gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1));
858   DotProd = Dir1.Dot(Dir2);
859   return Dir1^Dir2;
860 }
861
862
863
864
865
866 #ifdef OCCT_DEBUG
867 //==========================================================================
868 //function : MAT2d_DrawCurve
869 //purpose  : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
870 //            definie par <Indice>.
871 //            Indice = 1 jaune,
872 //            Indice = 2 bleu,
873 //            Indice = 3 rouge,
874 //            Indice = 4 vert.
875 //==========================================================================
876 void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
877                      const Standard_Integer      /*Indice*/)
878 {  
879   Handle(Standard_Type)      type = aCurve->DynamicType();
880   Handle(Geom2d_Curve)       curve,CurveDraw;
881 #ifdef DRAW
882   Handle(DrawTrSurf_Curve2d) dr;
883   Draw_Color                 Couleur;
884 #endif
885
886   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
887     curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
888     type = curve->DynamicType();    
889     // PB de representation des courbes semi_infinies.
890     gp_Parab2d gpParabola;
891     gp_Hypr2d  gpHyperbola;
892     Standard_Real Focus;
893     Standard_Real Limit = 50000.;
894     Standard_Real delta = 400;
895
896     // PB de representation des courbes semi_infinies.
897     if (aCurve->LastParameter() == Precision::Infinite()) {
898       
899       if (type == STANDARD_TYPE(Geom2d_Parabola)) {
900         gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
901         Focus = gpParabola.Focal();
902         Standard_Real Val1 = Sqrt(Limit*Focus);
903         Standard_Real Val2 = Sqrt(Limit*Limit);
904                       delta= (Val1 <= Val2 ? Val1:Val2);
905       }
906       else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
907         gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
908         Standard_Real Majr  = gpHyperbola.MajorRadius();
909         Standard_Real Minr  = gpHyperbola.MinorRadius();
910         Standard_Real Valu1 = Limit/Majr;
911         Standard_Real Valu2 = Limit/Minr;
912         Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
913         Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
914                       delta  = (Val1 <= Val2 ? Val1:Val2);
915       }
916       CurveDraw = new Geom2d_TrimmedCurve(aCurve,
917                                           aCurve->FirstParameter(),
918                                           aCurve->FirstParameter() + delta);
919     }
920     else {
921       CurveDraw = aCurve;
922     }
923     // fin PB.
924   }
925   else {
926     CurveDraw = aCurve;
927   }
928
929 #ifdef DRAW
930   if      (Indice == 1) Couleur = Draw_jaune;
931   else if (Indice == 2) Couleur = Draw_bleu;
932   else if (Indice == 3) Couleur = Draw_rouge;
933   else if (Indice == 4) Couleur = Draw_vert;
934
935   if (type == STANDARD_TYPE(Geom2d_Circle))
936     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
937   else if (type  == STANDARD_TYPE(Geom2d_Line))
938     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
939   else
940     dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
941
942   dout << dr;
943   dout.Flush();
944 #endif
945 }
946
947 #endif
948