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