0022936: Memory leak in inc\MAT_Mat.gxx line
[occt.git] / src / MAT / MAT_Mat.gxx
1 // File:        MAT_Mat.gxx
2 // Created:     Tue Sep 22 17:54:07 1992
3 // Author:      Gilles DEBARBOUILLE
4 //              <gde@bravox>
5
6
7 #include <MAT_Edge.hxx>
8 #include <MAT_ListOfEdge.hxx>
9 #include <MAT_Bisector.hxx>
10 #include <MAT_ListOfBisector.hxx>
11 #include <TColStd_DataMapOfIntegerInteger.hxx>
12 #include <TColStd_Array1OfInteger.hxx>
13 #include <MAT_DataMapOfIntegerBisector.hxx>
14 #include <Precision.hxx>
15
16 //========================================================================
17 //  function : MAT_Mat
18 //  purpose  :
19 //========================================================================
20
21 MAT_Mat::MAT_Mat()
22 {
23   thenumberofbisectors = 0;
24   thenumberofedges     = 0;
25 }
26
27
28 //========================================================================
29 //  function : CreateMat
30 //  purpose  : Calcul des lieux Bisecteurs.
31 //
32 //  Structure de la carte.
33 //  ======================
34 //  La carte des lieux bisecteurs se presente sous la forme d un ou plusieurs
35 //  arbres de bisectrices.
36 //  ( un arbre, si calcul a l interieur du contour, plusieurs sinon).
37 //
38 //  Les branches de plus bas niveau de l arbre separent deux elements voisins 
39 //  du contour.
40 // 
41 //  Principe de l algorithme.
42 //  -------------------------
43 //  l arbre est construit des branches les plus basses vers les plus hautes.
44 //
45 //  0 . Calcul des bisectrices entre elements voisins du contour.
46 //  1 . Elimination de certains element du contour => nouveau contour
47 //  2 . Retour en 0.
48 //  
49 //  Principales etapes de l algorithme.
50 //  ===================================
51 //
52 //  etape 1: Initialisation de l algorithme .
53 //  -----------------------------------------
54 //   Recuperation via le tool du nombre d'elements sur le contour
55 //   Initialisation de <theedgelist>, un edge correspond a chaque 
56 //   element du contour.
57 //
58 //  etape 2 : Boucle principale.
59 //  ----------------------------  
60 //    0 - Tant que Nombre d'edge > 1
61 //         
62 //      1. Pour chaque edge: construction de la bissectrice entre l edge 
63 //         et l edge suivante.
64 //         La bissectrice est semi_infinie, elle est soit trimmee par le
65 //         point commun des deux edges, soit par l intersection de deux
66 //         bissectrices antecedentes.
67 //
68 //      2. Intersection des Bisectrices issue du meme edge
69 //         => une bisectrice est intersectee avec sa voisine a gauche
70 //            et sa voisine a droite.
71 //
72 //      3. Analyse des intersections.
73 //         Si pas d'intersection entre deux bisectrices B1 et B2
74 //         - Recherche de l intersection la plus basse de B1 avec les 
75 //           Bisectrices antecedentes a B2 du cote de B1. Soit Bi la 
76 //           bissectrice intersectee. Toutes les bissectrices constituant la
77 //           branche qui relie B2 a Bi sont marquees a effacer
78 //         - idem pour B2.
79 //  
80 //      4. Suppresion des bisectrices a effacer.
81 //         une bisectrise est a effacer :
82 //          - Anulation de l intersection dont la bissectrice est issue
83 //            => Prolongement des deux bisectrices posterieures.
84 //          - Reinsertion des edge correspondant dans <theedgelist>.       
85 //
86 //      5. Pour chaque edge, analyse des distances entre les points d inter
87 //         section et l edge.
88 //         B1 B2 les bisectrices liee a l edge
89 //         Soit P0 le point d intersection des bissectrices .
90 //         Soit P1 le point d intersection de B1 avec son autre voisine .
91 //         Soit P2 le point d intersection de B2 avec son autre voisine .
92 //        
93 //         si sur B1 le parametre de P0 < parametre de P1 et
94 //         si sur B2 le parametre de P0 < parametre de P2 
95 //         alors suppression de l edge de la liste des edges <theedgelist>.
96 //
97 //         rq: le parametre sur une bissectirce est croissant par rapport
98 //         a la distance du point courant aux edges.
99
100 //      6. Si aucune edge est elimine alors sortie de la boucle principale.
101 //
102 //      7. Retour en 0.
103 //
104 //  etape 3 : Creation des racines des arbres de bisectrices.
105 //  ---------------------------------------------------------
106 //            Recuperation des bissectrices calculees lors du dernier passage
107 //            dans la boucle.
108 //
109 //========================================================================
110 void MAT_Mat::CreateMat(Tool& atool)
111 {
112
113 #ifdef ICONTINUE
114   Standard_Boolean Icontinue;
115 #endif
116
117   Standard_Boolean interrupt = Standard_False;
118
119   Handle(MAT_Edge) edgetoremove;
120   Handle(MAT_Edge) previousedge,currentedge;
121
122   Standard_Integer      noofbisectorstoremove;
123   Handle(MAT_Bisector)  firstbisector,secondbisector;
124   Handle(MAT_Edge)      edge;
125   Standard_Integer      intersectionpoint;
126   Standard_Integer      beginbisector;
127   Standard_Integer      noofbisectors;
128
129   Standard_Integer      NbIterBis = 0;
130   Standard_Integer      EvenNbIterBis = 10;
131   TColStd_Array1OfInteger EdgeNumbers(1, EvenNbIterBis+1);
132   EdgeNumbers.Init(-1);
133   Standard_Boolean      ToNullifyNoofbisectorstoremove = Standard_False;
134
135   Handle(MAT_ListOfBisector) currentbisectorlist;
136
137   Handle(MAT_Bisector) bisectortoremove,lastbisector,currentbisector;
138   Handle(MAT_Bisector) previousbisector;
139
140   Standard_Integer     i,j,k,narea,shift,compact,all;
141   Standard_Integer     noofedges;
142   Standard_Integer     NumberMaxOfIte;
143   Standard_Real        toleranceofconfusion;
144
145   noofedges            = atool.NumberOfItems();
146   toleranceofconfusion = atool.ToleranceOfConfusion();
147   NumberMaxOfIte       = noofedges*noofedges;
148
149   TColStd_Array1OfInteger firstarea(0, noofedges);
150   TColStd_Array1OfInteger lastarea(0, noofedges);
151   TColStd_Array1OfInteger noofarea(0, noofedges);
152
153   Standard_Integer  parama[2];
154   Standard_Integer  paramb[2];
155
156 // -----------------------------------------
157 // Initialisation et remise a zero des maps.
158 // -----------------------------------------
159   bisectoronetoremove.Clear();
160   bisectortwotoremove.Clear();
161   typeofbisectortoremove.Clear();
162   bisectormap.Clear();
163
164   isDone        = Standard_True;
165   noofbisectors = noofedges;
166   beginbisector = 0;
167
168 // --------------------------------------------------------------------
169 // Construction de <theedgelist> un edge correspond a un element simple
170 // du contour.
171 // --------------------------------------------------------------------
172   theedgelist = new MAT_ListOfEdge();
173
174   for(i=0; i<noofedges; i++) {
175     edge = new MAT_Edge();
176     edge->EdgeNumber(i+1);
177     edge->Distance(-1);
178     theedgelist->BackAdd(edge);
179   }
180   
181   theedgelist->Loop();
182
183 //---------------------------------------------------
184 // Initialisation des bissectrices issues du contour.
185 //---------------------------------------------------
186   Standard_Real Dist;
187   theedgelist->First();
188
189   for(i=0; i<theedgelist->Number(); i++) {
190     bisectormap.Bind(i,new MAT_Bisector());
191     bisectormap(i)->IndexNumber(i);
192     bisectormap(i)->FirstEdge(theedgelist->Current());
193     bisectormap(i)->FirstVector
194       (atool.TangentBefore(theedgelist->Current()->EdgeNumber()));
195     theedgelist->Next();
196     bisectormap(i)->SecondEdge(theedgelist->Current());
197     bisectormap(i)->IssuePoint
198       (atool.FirstPoint(theedgelist->Current()->EdgeNumber(),Dist));  
199     bisectormap(i)->DistIssuePoint(Dist);
200     bisectormap(i)->SecondVector
201       (atool.TangentAfter(theedgelist->Current()->EdgeNumber()));
202   }
203
204 //----------------------------------------------------
205 // Affectation a chaque edge de ses deux bissectrices.
206 //----------------------------------------------------
207   theedgelist->First();
208
209   for(i=0; i<theedgelist->Number(); i++) {
210     theedgelist->Current()->FirstBisector
211       (bisectormap((i-1+noofbisectors)%noofbisectors));
212     theedgelist->Current()->SecondBisector
213       (bisectormap(i));
214     theedgelist->Next();
215   }
216
217 //===========================================================================
218 //                         Boucle Principale   (etape 2)
219 //===========================================================================
220   Standard_Integer NumberOfIte = 0;
221
222   while(theedgelist->Number()>1) {
223
224
225     // ------------------------------------------------------------------
226     //  Creation des geometries des bissectrices via le tool. (etape 2.1)
227     // -------------------------------------------------------------------
228
229     for(i=beginbisector; i<noofbisectors; i++) {
230
231       atool.CreateBisector(bisectormap(i));
232       thenumberofbisectors++;
233       
234 #ifdef DEBUG_Mat
235       atool.Dump(bisectormap(i)->BisectorNumber(),1);
236 #ifdef ICONTINUE
237       cin>>Icontinue;
238 #endif
239 #endif
240     }
241
242     // ---------------------------------------------
243     //  Condition de sortie de la boucle principale.
244     // ---------------------------------------------
245
246 //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:28 2000 Begin
247     if (theedgelist->Number() < 3)
248       break;
249 //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:37 2000 End
250     
251     //---------------------------------------------------
252     // boucle 2 Tant qu il y a des bisectrices a effacer.
253     //---------------------------------------------------
254     while(Standard_True) {
255       NbIterBis++;
256
257       noofbisectorstoremove = 0;
258       theedgelist->First();
259
260       //--------------------------------------------------------------
261       // Calcul des intersections des bisectrices voisines.(etape 2.2)
262       //--------------------------------------------------------------
263
264       if (NbIterBis <= EvenNbIterBis+1)
265         EdgeNumbers(NbIterBis) = theedgelist->Number();
266       else
267         {
268           for (k = 1; k <= EvenNbIterBis; k++)
269             EdgeNumbers(k) = EdgeNumbers(k+1);
270           EdgeNumbers(EvenNbIterBis+1) = theedgelist->Number();
271         }
272       if (EdgeNumbers(EvenNbIterBis+1) == EdgeNumbers(1))
273         ToNullifyNoofbisectorstoremove = Standard_True;
274
275       for(i=0; i<theedgelist->Number(); i++) {
276         edge = theedgelist->Current();
277         if(edge->Distance() == -1.) {
278           firstbisector = edge->FirstBisector();
279           secondbisector = edge->SecondBisector();
280           edge->Distance(atool.IntersectBisector
281                          (firstbisector,secondbisector,intersectionpoint));
282           edge->IntersectionPoint(intersectionpoint);
283
284           if(edge->Distance() == Precision::Infinite()) {
285             if(firstbisector->IndexNumber() >= beginbisector ||
286                secondbisector->IndexNumber() >= beginbisector) 
287               Intersect(atool,0,noofbisectorstoremove,
288                         firstbisector,secondbisector );
289           }
290           else {
291             if(firstbisector->IndexNumber() >= beginbisector) {
292               Intersect(atool,1,noofbisectorstoremove,
293                         firstbisector,secondbisector );
294             }
295             if(secondbisector->IndexNumber() >= beginbisector) {
296               Intersect(atool,2,noofbisectorstoremove,
297                         firstbisector,secondbisector );
298             }
299           }
300         }
301         theedgelist->Next();
302       }
303       
304       //-------------------------------
305       // Test de sortie de la boucle 2.
306       //-------------------------------
307
308       if (ToNullifyNoofbisectorstoremove)
309         noofbisectorstoremove = 0;
310       if(noofbisectorstoremove == 0) break;
311
312       //---------------------------------------------------
313       // Annulation des bissectrices a effacer. (etape 2.4)
314       //---------------------------------------------------
315
316       for(i=0; i<noofbisectorstoremove; i++) {
317
318         bisectortoremove = bisectoronetoremove(i);
319
320         //---------------------------------------------------------------
321         // Destruction des bisectrices descendantes de <bisectortoremove>
322         // On descend dans l arbre jusqu a ce qu on atteigne
323         // <bisectortwotoremove(i).
324         //---------------------------------------------------------------
325
326         while(Standard_True){
327
328 #ifdef DEBUG_Mat
329           atool.Dump(bisectortoremove->BisectorNumber(),0);
330 #endif
331           // ----------------------------------
332           // Annulation de <bisectortoremove>.
333           // ----------------------------------
334           thenumberofbisectors--;
335           currentbisectorlist = bisectortoremove->List();
336           currentbisectorlist->First();
337           currentbisector = currentbisectorlist->FirstItem();
338           previousedge = currentbisector->FirstEdge();
339           theedgelist->Init(previousedge);
340           previousedge->Distance(-1.);
341           previousedge->FirstBisector()->SecondParameter(Precision::Infinite());
342           previousedge->SecondBisector()->FirstParameter(Precision::Infinite());
343
344           //------------------------------------------
345           // Annulation des fils de <currentbisector>.
346           //------------------------------------------
347
348           while(currentbisectorlist->More()) {
349             currentbisector = currentbisectorlist->Current();
350             currentedge  = currentbisector->SecondEdge();
351
352             //---------------------------------------
353             // Reinsertion de l edge dans le contour.
354             //---------------------------------------
355             theedgelist->LinkAfter(currentedge);
356             theedgelist->Next();
357             
358             currentedge->FirstBisector(currentbisector);
359             previousedge->SecondBisector(currentbisector);
360 #ifdef DEBUG_Mat                      
361             atool.Dump(currentbisector->BisectorNumber(),0);
362 #endif
363
364             //------------------------------------------------------
365             // Annulation de l intersection ie les fils qui
366             // ont generes l intersection sont prolonges a l infini.
367             //------------------------------------------------------
368
369             currentbisector->FirstParameter (Precision::Infinite());
370             currentbisector->SecondParameter(Precision::Infinite());
371                       
372             atool.TrimBisector(currentbisector);
373             
374 #ifdef DEBUG_Mat
375             atool.Dump(currentbisector->BisectorNumber(),1);
376 #endif
377             currentedge->Distance(-1.);
378             currentedge->FirstBisector()->SecondParameter(Precision::Infinite());
379             currentedge->SecondBisector()->FirstParameter(Precision::Infinite());
380             
381             previousedge = currentedge;
382             currentbisectorlist->Next();
383           }
384           
385           theedgelist->Unlink();
386
387           //-----------------------------------------------------------
388           // Test de sortie de la boucle d annulation des bissectrices.
389           //-----------------------------------------------------------
390
391           if(bisectortoremove->BisectorNumber() ==
392              bisectortwotoremove(i)->BisectorNumber()) break;
393
394           //-----------------------
395           // Descente dans l arbre.
396           //-----------------------
397
398           if(typeofbisectortoremove(i) == 1)
399             bisectortoremove = bisectortoremove->FirstBisector();
400           else
401             bisectortoremove = bisectortoremove->LastBisector();
402         
403         }  //----------------------------------------------------
404            // Fin boucle d annulation des bissectrices issue de 
405            // <bisectoronetoremove(i)>.
406            //----------------------------------------------------
407
408       } //------------------------------------------
409         // Fin boucle d annulation des bissectrices.
410         //-------------------------------------------
411
412 #ifdef ICONTINUE
413       cin>>Icontinue;
414 #endif
415     } //--------------
416       // Fin Boucle 2.
417       //--------------
418     
419     // ----------------------------------------------------------------------
420     // Analyse des parametres des intersections sur les bisectrices de chaque
421     // edge et determination des portions de contour a supprimees. (etape 2.5)
422     // ----------------------------------------------------------------------
423
424     theedgelist->First();
425       
426     currentbisector = theedgelist->Current()->FirstBisector();
427     if (currentbisector->FirstParameter()  == Precision::Infinite() &&
428         currentbisector->SecondParameter() == Precision::Infinite()) {
429       parama[0] = -1;
430       paramb[0] = -1;
431     }
432     else if(currentbisector->FirstParameter() == Precision::Infinite()) {
433       parama[0] = -1;
434       paramb[0] =  1;
435     }
436     else if(currentbisector->SecondParameter() == Precision::Infinite()) {
437       paramb[0] = -1;
438       parama[0] =  1;
439     }
440     else if (atool.Distance(currentbisector,
441                             currentbisector->FirstParameter(),
442                             currentbisector->SecondParameter()) 
443              > toleranceofconfusion) {
444       if((currentbisector->FirstParameter() - 
445           currentbisector->SecondParameter())
446          *currentbisector->Sense() > 0.) {      
447         parama[0] = -1;
448         paramb[0] =  1;
449       }
450       else {
451         paramb[0] = -1;
452         parama[0] =  1;
453       }
454     }
455     else {
456       parama[0] = 1;
457       paramb[0] = 1;
458     }
459     
460     narea = -1;
461     
462     for(i=0; i<theedgelist->Number(); i++) {
463       currentbisector = theedgelist->Current()->SecondBisector();
464       if (currentbisector->FirstParameter()  == Precision::Infinite() &&
465           currentbisector->SecondParameter() == Precision::Infinite()) {
466         parama[1] = -1;
467         paramb[1] = -1;
468       }
469       else if(currentbisector->FirstParameter() == Precision::Infinite()) {
470         parama[1] = -1;
471         paramb[1] =  1;
472       }
473       else if(currentbisector->SecondParameter() == Precision::Infinite()) {
474         paramb[1] = -1;
475         parama[1] =  1;
476       }
477       else if (atool.Distance(currentbisector,
478                               currentbisector->FirstParameter(),
479                               currentbisector->SecondParameter()) 
480                > toleranceofconfusion) {
481         if((currentbisector->FirstParameter() - 
482             currentbisector->SecondParameter()) 
483            *currentbisector->Sense() > 0.) {      
484           parama[1] = -1;
485           paramb[1] =  1;
486         }
487         else {
488           paramb[1] = -1;
489           parama[1] =  1;
490         }
491       }
492       else {
493         parama[1] = 1;
494         paramb[1] = 1;
495       }
496
497       //-----------------------------------------------------------------
498       // Test si l edge est a enlever du contour
499       // Construction des portions de contour a eliminer.
500       //
501       //  narea : nombre de portions continues du contour a eliminer.
502       //  firstarea[i] : indice premier edge de la portion i.
503       //  lastarea[i]  : indice dernier edge de la portion i.
504       //-----------------------------------------------------------------
505
506 #ifdef DEBUG_Mat
507       cout <<" Test sur les parametres pour elimination"<<endl;
508       cout << " Edge number :"<<theedgelist->Current()->EdgeNumber()<<endl;
509 #endif
510
511       if(paramb[0] > 0 && parama[1] > 0) {
512
513 #ifdef DEBUG_Mat
514       cout <<" A ELIMINER "<<endl;
515 #endif  
516         if(narea < 0) {
517           firstarea(++narea) = theedgelist->Index();
518           lastarea(narea) = firstarea(narea);
519           noofarea(narea) = 1;
520         }
521         else {
522           if(theedgelist->Index() == lastarea(narea)+1) {
523             lastarea(narea)++;
524             noofarea(narea)++;
525           }
526           else {
527             firstarea(++narea) = theedgelist->Index();
528             lastarea(narea) = firstarea(narea);
529             noofarea(narea) = 1;
530           }
531         }
532       }
533       parama[0] = parama[1];
534       paramb[0] = paramb[1];
535       theedgelist->Next();
536     
537     } 
538     
539     compact = 0;
540     if(narea > 0) {
541       if(lastarea(narea) == theedgelist->Number() && firstarea(0) == 1) {
542         firstarea(0) = firstarea(narea);
543         noofarea(0) = noofarea(0)+noofarea(narea);
544         compact = noofarea(narea);
545         narea--;
546       }
547     }
548     
549     narea++;
550
551     //------------------------------------------------------------------
552     // Sortie de la boucle principale si il n y a pas d edge a eliminer.
553     // (etape 2.6)
554     //------------------------------------------------------------------
555     if(narea == 0) {
556       interrupt = Standard_True;
557       break;
558     }
559     
560
561     //----------------------------------------------------------------
562     // Elimination des edges a enlever du contour
563     // => Mise a jour du nouveau contour.
564     // => Creation des bissectrices entre les nouvelles edges voisines.
565     //----------------------------------------------------------------
566
567     beginbisector = noofbisectors;
568     shift = 0;
569     all = 0;
570     if(narea == 1 && noofarea(0) == theedgelist->Number()) all = 1;
571
572     for(i=0; i<narea; i++) {
573       if(i == 1)shift = shift-compact;
574       theedgelist->First();
575       edgetoremove = theedgelist->Brackets(firstarea(i)-shift);
576       
577       edgetoremove->FirstBisector()->EndPoint(edgetoremove
578                                               ->IntersectionPoint());
579       
580 #ifdef DEBUG_Mat
581       atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),0);
582 #endif
583
584       edgetoremove->FirstBisector()->FirstParameter
585         (edgetoremove->FirstBisector()->SecondParameter());
586           
587 #ifdef DEBUG_Mat
588       if(atool.TrimBisector(edgetoremove->FirstBisector()))
589         atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),1);
590 #else
591       atool.TrimBisector(edgetoremove->FirstBisector());
592 #endif
593
594       bisectormap.Bind(noofbisectors,new MAT_Bisector());
595       bisectormap(noofbisectors)->IndexNumber(noofbisectors);
596       bisectormap(noofbisectors)->DistIssuePoint(edgetoremove->Distance());
597       bisectormap(noofbisectors)->IssuePoint(edgetoremove
598                                                 ->IntersectionPoint());
599       bisectormap(noofbisectors)->FirstEdge(theedgelist->PreviousItem());
600       bisectormap(noofbisectors)->AddBisector(edgetoremove
601                                                  ->FirstBisector());
602
603       for(j=0; j<noofarea(i); j++) {
604         theedgelist->Unlink();
605         theedgelist->Next();
606         shift++;
607
608 #ifdef DEBUG_Mat
609         cout<<" Suppression de l'arete : "<<edgetoremove->EdgeNumber()<<endl;
610 #endif
611
612         if(all == 0 || j+1 != noofarea(i)) {
613           bisectormap(noofbisectors)->AddBisector(edgetoremove
614                                                      ->SecondBisector());
615         }
616         edgetoremove->SecondBisector()->EndPoint(edgetoremove
617                                                  ->IntersectionPoint());
618
619 #ifdef DEBUG_Mat
620         atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),0);
621 #endif
622
623         edgetoremove->SecondBisector()->SecondParameter
624           (edgetoremove->SecondBisector()->FirstParameter());
625 #ifdef DEBUG_Mat
626         if(atool.TrimBisector(edgetoremove->SecondBisector()))
627           atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),1);
628 #else
629         atool.TrimBisector(edgetoremove->SecondBisector());
630 #endif
631         edgetoremove = theedgelist->Current();
632       }
633       bisectormap(noofbisectors)->SecondEdge(theedgelist->Current());
634           
635       theedgelist->PreviousItem()
636         ->SecondBisector(bisectormap(noofbisectors));
637       theedgelist->Current()->FirstBisector(bisectormap(noofbisectors));
638           
639       bisectormap(noofbisectors)->FirstVector
640         (atool.Tangent
641          (bisectormap(noofbisectors)->FirstBisector()
642           ->BisectorNumber()));
643       
644       bisectormap(noofbisectors)->SecondVector
645         (atool.Tangent
646          (bisectormap(noofbisectors)->LastBisector()
647           ->BisectorNumber()));
648       
649       noofbisectors++;
650       
651       theedgelist->PreviousItem()->Distance(-1);
652       theedgelist->Current()->Distance(-1);
653       
654       theedgelist->PreviousItem()->FirstBisector()
655         ->SecondParameter(Precision::Infinite());
656       theedgelist->Current()->SecondBisector()->FirstParameter(Precision::Infinite());
657     }
658
659     //-----------------------------------------------------------------------
660     // Test sur le nombre d iterations :
661     // A chaque iteration est elimine un element du contour qui ne sera plus
662     // reinsere par la suite => le nombre d iterartions doit etre < au nombre
663     // d elements.
664     // Le nombre d iteration maximum est fixe a numberofedges*numberofedges.
665     //-----------------------------------------------------------------------
666     if (NumberOfIte > NumberMaxOfIte) {
667       isDone = Standard_False;             //Echec calcul de la carte.
668       break;
669     }
670     NumberOfIte++;
671
672   }  //===============================================
673      //            Fin Boucle Principale.
674      //===============================================
675      
676   //----------
677   // etape 3.
678   //----------
679
680
681   //----------------------------------------------
682   // interupt = True => bissectrices semi_infinies.
683   //----------------------------------------------
684   
685   if(interrupt)
686     semiInfinite = Standard_True;
687   else {
688     semiInfinite = Standard_False;
689
690     //------------------------------------------------------------------
691     // Si le nombre d edge > 1 => le nombre d edge = 2 
692     //              (cf test sortie boucle principale)
693     // Les deux dernieres bisectrices separent les memes edges .
694     // Soit elles sont confondues si calcul a l interieur, soit elles
695     // sont semi-Infinies (exemple : contour compose seulement de deux
696     // arcs de cercles).                           
697     //------------------------------------------------------------------
698
699     if(theedgelist->Number() > 1) { //Now this branch is never reachable
700                                     //because the case edgenumber = 2 is processed in the main loop
701       theedgelist->First();
702       edge = theedgelist->Current();
703       if(edge->FirstBisector()->IndexNumber() == noofbisectors-1) {
704 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
705         if (atool.TrimBisector(edge->SecondBisector(),
706                                edge->FirstBisector()->IssuePoint())) {
707           if (edge->SecondBisector()->EndPoint() == 0)
708             edge->SecondBisector()->EndPoint(edge->FirstBisector()->IssuePoint());
709           bisectormap(noofbisectors-1)->AddBisector(edge->SecondBisector());
710         } else
711           semiInfinite = Standard_True;
712 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
713       }
714       else {
715 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
716         if (atool.TrimBisector(edge->FirstBisector(),
717                                edge->SecondBisector()->IssuePoint())) {
718           if (edge->FirstBisector()->EndPoint() == 0)
719             edge->FirstBisector()->EndPoint(edge->SecondBisector()->IssuePoint());
720           bisectormap(noofbisectors-1)->AddBisector(edge->FirstBisector());
721         } else 
722           semiInfinite = Standard_True;
723 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
724       }
725       if (!semiInfinite) {     
726         thenumberofbisectors--;
727         bisectormap(noofbisectors-1)->SecondEdge(edge);
728         bisectormap(noofbisectors-1)->BisectorNumber(-1);
729       }
730     }
731   }
732   if(semiInfinite) {
733     beginbisector = noofbisectors;
734     theedgelist->First();
735     for(i=0; i<theedgelist->Number(); i++) {
736       edge = theedgelist->Current();
737       bisectormap.Bind(noofbisectors,edge->SecondBisector());
738       noofbisectors++;
739       theedgelist->Next();
740     }
741
742   } 
743
744   //---------------------------
745   // Recuperations des racines.
746   //---------------------------
747
748   roots = new MAT_ListOfBisector;
749   
750   if (bisectormap(noofbisectors-1)->BisectorNumber() == -1) {
751     roots = bisectormap(noofbisectors-1)->List();
752     roots->First();
753     roots->Current()->FirstEdge()
754       ->Distance(bisectormap(noofbisectors-1)->DistIssuePoint());
755   }
756   else {
757     for (i=beginbisector;i<noofbisectors;i++) {
758       roots->BackAdd(bisectormap(i));
759     }
760   }
761   
762 }
763
764 //========================================================================
765 //  function : LoadBisectorsToRemove
766 //  purpose  : Chargement des bisectrices a effacer.
767 //========================================================================
768 void MAT_Mat::LoadBisectorsToRemove
769   (      Standard_Integer&     noofbisectorstoremove,
770    const Standard_Real         distance1,
771    const Standard_Real         distance2,
772    const Handle(MAT_Bisector)& firstbisectortoremove1,
773    const Handle(MAT_Bisector)& firstbisectortoremove2,
774    const Handle(MAT_Bisector)& lastbisectortoremove1,
775    const Handle(MAT_Bisector)& lastbisectortoremove2  )
776 {
777
778   Standard_Integer found,index;
779   Handle(MAT_Bisector) firstbisectortoremove[2];
780   Handle(MAT_Bisector) lastbisectortoremove[2];
781
782   firstbisectortoremove[0] = firstbisectortoremove1;
783   firstbisectortoremove[1] = firstbisectortoremove2;
784   lastbisectortoremove[0]  = lastbisectortoremove1;
785   lastbisectortoremove[1]  = lastbisectortoremove2;
786   
787   if     (distance1  < Precision::Infinite() && 
788           distance2 == Precision::Infinite()    )   index =  0;
789   else if(distance2  < Precision::Infinite() && 
790           distance1 == Precision::Infinite()    )   index =  1;
791   else                                              index = -1;
792   
793   if(index != -1) {
794     found = noofbisectorstoremove;
795     for(int j=0; j<noofbisectorstoremove; j++) {
796       if(bisectoronetoremove(j)->BisectorNumber() ==
797          firstbisectortoremove[index]->BisectorNumber()) {
798         found = j;
799         if(bisectortwotoremove(j)->BisectorNumber() <
800            lastbisectortoremove[index]->BisectorNumber())found = -1;
801         break;
802       }
803     }
804     
805     if(found != -1) {
806 #ifdef DEBUG_Mat
807       cout<<" first last bisector to remove :"<<
808         firstbisectortoremove[index]->BisectorNumber()<<" "<<
809           lastbisectortoremove[index]->BisectorNumber()<<endl;
810 #endif
811       bisectoronetoremove.Bind(found,firstbisectortoremove[index]);
812       bisectortwotoremove.Bind(found,lastbisectortoremove[index]);
813       typeofbisectortoremove.Bind(found,index+1);
814       
815       if(found == noofbisectorstoremove)noofbisectorstoremove++;
816     }
817   }
818 }
819
820 //========================================================================
821 //  function : Intersect
822 //  purpose  : Si <aside=0> Intersection de <firstbisector> avec les
823 //                 descendants de <secondbisector> les plus a gauche 
824 //                (ie secondbisector->FirstBisector()->FirstBisector...)
825 //                          Intersection de <secondbisector> avec les
826 //                 descendants de <firstbisector> les plus a droite 
827 //                (ie firstbisector->LastBisector()->LastBisector...)
828 //                
829 //             Si <aside=1> Intersection de <firstbisector> avec ses 
830 //                descendants les plus a gauche et les plus a droite.
831 //
832 //             Si <aside=2> Intersection de <secondbisector> avec ses 
833 //                descendants les plus a gauche et les plus a droite.
834 //========================================================================v
835 void MAT_Mat::Intersect(      Tool&                 atool,
836                         const Standard_Integer      aside,
837                               Standard_Integer&     noofbisectortoremove,
838                         const Handle(MAT_Bisector)& firstbisector,
839                         const Handle(MAT_Bisector)& secondbisector)
840 {
841   Standard_Integer      bisectornumber;
842   Standard_Real         distant,saveparameter;
843   Standard_Real         distance[2];
844   Standard_Integer      intersectionpoint;
845   Handle(MAT_Bisector)  lastbisector,previousbisector;
846   Handle(MAT_Bisector)  firstbisectortoremove[2];
847   Handle(MAT_Bisector)  lastbisectortoremove[2];
848
849   distance[0] = Precision::Infinite();
850   distance[1] = Precision::Infinite();
851
852   for(bisectornumber = 0; bisectornumber<2; bisectornumber++) {
853     if(aside == 0) {
854       if(bisectornumber == 0) 
855         firstbisectortoremove[bisectornumber] = secondbisector;
856       else                    
857         firstbisectortoremove[bisectornumber] = firstbisector;
858     }
859     else if(aside == 1) {
860       firstbisectortoremove[bisectornumber] = firstbisector;
861     }
862     else {
863       firstbisectortoremove[bisectornumber] = secondbisector;
864     }
865     
866     lastbisector = firstbisectortoremove[bisectornumber];
867     
868     if(aside == 0) {
869       previousbisector = firstbisectortoremove[bisectornumber];
870     }
871     else {
872       if(firstbisectortoremove[bisectornumber]->List()->IsEmpty())continue;
873
874       if(bisectornumber == 0)
875         previousbisector = firstbisectortoremove[bisectornumber]
876                               ->FirstBisector();
877       else
878         previousbisector = firstbisectortoremove[bisectornumber]
879                               ->LastBisector();
880     }
881     
882     distant = distance[bisectornumber];
883     while(!previousbisector->List()->IsEmpty()) {
884
885       if(bisectornumber == 0)
886         previousbisector = previousbisector->FirstBisector();
887       else
888         previousbisector = previousbisector->LastBisector();
889       
890       if(aside == 1 || (aside == 0 && bisectornumber == 0)) {
891         saveparameter = previousbisector->FirstParameter();
892         distant = atool.IntersectBisector
893           (firstbisector,previousbisector,intersectionpoint);
894         previousbisector->FirstParameter(saveparameter);
895       }
896       else {
897         saveparameter = previousbisector->SecondParameter();
898         distant = atool.IntersectBisector
899           (previousbisector,secondbisector,intersectionpoint);
900         previousbisector->SecondParameter(saveparameter);
901       }
902       
903       if(distant < Precision::Infinite()) {
904         distance[bisectornumber] = distant;
905         lastbisectortoremove[bisectornumber] = lastbisector;
906       }
907           
908       lastbisector = previousbisector;
909     }
910   }
911
912   //---------------------------------------
913   // Chargement des bissectrices a effacer.
914   //---------------------------------------
915
916   LoadBisectorsToRemove(noofbisectortoremove,
917                         distance[0],distance[1],
918                         firstbisectortoremove[0],firstbisectortoremove[1],
919                         lastbisectortoremove[0] ,lastbisectortoremove[1]);
920 }
921
922 //========================================================================
923 //  function : Init
924 //  purpose  :
925 //========================================================================
926 void MAT_Mat::Init()
927 {
928   roots->First();
929 }
930
931 //========================================================================
932 //  function : More
933 //  purpose  :
934 //========================================================================
935 Standard_Boolean MAT_Mat::More() const
936 {
937   return roots->More();
938 }
939
940 //========================================================================
941 //  function : Next
942 //  purpose  :
943 //========================================================================
944 void MAT_Mat::Next()
945 {
946   roots->Next();
947 }
948
949 //========================================================================
950 //  function : Bisector 
951 //  purpose  :
952 //========================================================================
953 Handle(MAT_Bisector) MAT_Mat::Bisector() const
954 {
955   return roots->Current();
956 }
957
958 //========================================================================
959 //  function : NumberOfBisectors
960 //  purpose  :
961 //========================================================================
962 Standard_Integer MAT_Mat::NumberOfBisectors() const
963 {
964   return thenumberofbisectors;
965 }
966
967 //========================================================================
968 //  function : SemiInfinite
969 //  purpose  :
970 //========================================================================
971 Standard_Boolean MAT_Mat::SemiInfinite() const
972 {
973   return semiInfinite;
974 }
975
976 //========================================================================
977 //  function : IsDone
978 //  purpose  :
979 //========================================================================
980 Standard_Boolean MAT_Mat::IsDone() const
981 {
982   return isDone;
983 }
984