0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / MAT2d / MAT2d_Mat2d.cxx
1 // Created on: 1992-09-22
2 // Created by: Gilles DEBARBOUILLE
3 // Copyright (c) 1992-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
18 #include <MAT2d_Mat2d.hxx>
19 #include <MAT2d_Tool2d.hxx>
20 #include <MAT_Bisector.hxx>
21 #include <MAT_DataMapOfIntegerBisector.hxx>
22 #include <MAT_Edge.hxx>
23 #include <MAT_ListOfBisector.hxx>
24 #include <MAT_ListOfEdge.hxx>
25 #include <Precision.hxx>
26 #include <TColStd_Array1OfInteger.hxx>
27 #include <TColStd_DataMapOfIntegerInteger.hxx>
28
29 //========================================================================
30 //  function : MAT2d_Mat2d
31 //  purpose  :
32 //========================================================================
33 MAT2d_Mat2d::MAT2d_Mat2d(const Standard_Boolean IsOpenResult)
34 : semiInfinite(Standard_False),
35   isDone(Standard_False)
36 {
37   myIsOpenResult = IsOpenResult;
38   thenumberofbisectors = 0;
39   thenumberofedges     = 0;
40 }
41
42
43 //========================================================================
44 //  function : CreateMat
45 //  purpose  : Calcul des lieux Bisecteurs.
46 //
47 //  Structure de la carte.
48 //  ======================
49 //  La carte des lieux bisecteurs se presente sous la forme d un ou plusieurs
50 //  arbres de bisectrices.
51 //  ( un arbre, si calcul a l interieur du contour, plusieurs sinon).
52 //
53 //  Les branches de plus bas niveau de l arbre separent deux elements voisins 
54 //  du contour.
55 // 
56 //  Principe de l algorithme.
57 //  -------------------------
58 //  l arbre est construit des branches les plus basses vers les plus hautes.
59 //
60 //  0 . Calcul des bisectrices entre elements voisins du contour.
61 //  1 . Elimination de certains element du contour => nouveau contour
62 //  2 . Retour en 0.
63 //  
64 //  Principales etapes de l algorithme.
65 //  ===================================
66 //
67 //  etape 1: Initialisation de l algorithme .
68 //  -----------------------------------------
69 //   Recuperation via le tool du nombre d'elements sur le contour
70 //   Initialisation de <theedgelist>, un edge correspond a chaque 
71 //   element du contour.
72 //
73 //  etape 2 : Boucle principale.
74 //  ----------------------------  
75 //    0 - Tant que Nombre d'edge > 1
76 //         
77 //      1. Pour chaque edge: construction de la bissectrice entre l edge 
78 //         et l edge suivante.
79 //         La bissectrice est semi_infinie, elle est soit trimmee par le
80 //         point commun des deux edges, soit par l intersection de deux
81 //         bissectrices antecedentes.
82 //
83 //      2. Intersection des Bisectrices issue du meme edge
84 //         => une bisectrice est intersectee avec sa voisine a gauche
85 //            et sa voisine a droite.
86 //
87 //      3. Analyse des intersections.
88 //         Si pas d'intersection entre deux bisectrices B1 et B2
89 //         - Recherche de l intersection la plus basse de B1 avec les 
90 //           Bisectrices antecedentes a B2 du cote de B1. Soit Bi la 
91 //           bissectrice intersectee. Toutes les bissectrices constituant la
92 //           branche qui relie B2 a Bi sont marquees a effacer
93 //         - idem pour B2.
94 //  
95 //      4. Suppresion des bisectrices a effacer.
96 //         une bisectrise est a effacer :
97 //          - Anulation de l intersection dont la bissectrice est issue
98 //            => Prolongement des deux bisectrices posterieures.
99 //          - Reinsertion des edge correspondant dans <theedgelist>.       
100 //
101 //      5. Pour chaque edge, analyse des distances entre les points d inter
102 //         section et l edge.
103 //         B1 B2 les bisectrices liee a l edge
104 //         Soit P0 le point d intersection des bissectrices .
105 //         Soit P1 le point d intersection de B1 avec son autre voisine .
106 //         Soit P2 le point d intersection de B2 avec son autre voisine .
107 //        
108 //         si sur B1 le parametre de P0 < parametre de P1 et
109 //         si sur B2 le parametre de P0 < parametre de P2 
110 //         alors suppression de l edge de la liste des edges <theedgelist>.
111 //
112 //         rq: le parametre sur une bissectirce est croissant par rapport
113 //         a la distance du point courant aux edges.
114
115 //      6. Si aucune edge est elimine alors sortie de la boucle principale.
116 //
117 //      7. Retour en 0.
118 //
119 //  etape 3 : Creation des racines des arbres de bisectrices.
120 //  ---------------------------------------------------------
121 //            Recuperation des bissectrices calculees lors du dernier passage
122 //            dans la boucle.
123 //
124 //========================================================================
125 void MAT2d_Mat2d::CreateMatOpen(MAT2d_Tool2d& atool)
126 {
127
128 #ifdef ICONTINUE
129   Standard_Boolean Icontinue;
130 #endif
131
132   Standard_Boolean interrupt = Standard_False;
133
134   Handle(MAT_Edge) edgetoremove;
135   Handle(MAT_Edge) previousedge,currentedge;
136
137   Standard_Integer      noofbisectorstoremove;
138   Handle(MAT_Bisector)  firstbisector,secondbisector;
139   Handle(MAT_Edge)      edge;
140   Standard_Integer      intersectionpoint;
141   Standard_Integer      beginbisector;
142   Standard_Integer      noofbisectors;
143
144   Standard_Integer      NbIterBis = 0;
145   Standard_Integer      EvenNbIterBis = 10;
146   TColStd_Array1OfInteger EdgeNumbers(1, EvenNbIterBis+1);
147   EdgeNumbers.Init(-1);
148   Standard_Boolean      ToNullifyNoofbisectorstoremove = Standard_False;
149
150   Handle(MAT_ListOfBisector) currentbisectorlist;
151
152   Handle(MAT_Bisector) bisectortoremove,lastbisector,currentbisector;
153   Handle(MAT_Bisector) previousbisector;
154
155   Standard_Integer     i,j,k,narea,shift,compact,all;
156   Standard_Integer     noofedges;
157   Standard_Integer     NumberMaxOfIte;
158   Standard_Real        toleranceofconfusion;
159
160   noofedges            = atool.NumberOfItems();
161   toleranceofconfusion = atool.ToleranceOfConfusion();
162   NumberMaxOfIte       = noofedges*noofedges;
163
164   TColStd_Array1OfInteger firstarea(0, noofedges);
165   TColStd_Array1OfInteger lastarea(0, noofedges);
166   TColStd_Array1OfInteger noofarea(0, noofedges);
167
168   Standard_Integer  parama[2];
169   Standard_Integer  paramb[2];
170
171 // -----------------------------------------
172 // Initialisation et remise a zero des maps.
173 // -----------------------------------------
174   bisectoronetoremove.Clear();
175   bisectortwotoremove.Clear();
176   typeofbisectortoremove.Clear();
177   bisectormap.Clear();
178
179   isDone        = Standard_True;
180   noofbisectors = noofedges-1;
181   beginbisector = 0;
182
183 // --------------------------------------------------------------------
184 // Construction de <theedgelist> un edge correspond a un element simple
185 // du contour.
186 // --------------------------------------------------------------------
187   theedgelist = new MAT_ListOfEdge();
188   RemovedEdgesList = new MAT_ListOfEdge();
189
190   for(i=0; i<noofedges; i++) {
191     edge = new MAT_Edge();
192     edge->EdgeNumber(i+1);
193     edge->Distance(-1);
194     theedgelist->BackAdd(edge);
195   }
196   
197   theedgelist->Loop();
198
199 //---------------------------------------------------
200 // Initialisation des bissectrices issues du contour.
201 //---------------------------------------------------
202   Standard_Real Dist;
203   theedgelist->First();
204
205   for(i=0; i<theedgelist->Number()-1; i++) {
206     bisectormap.Bind(i,new MAT_Bisector());
207     bisectormap(i)->IndexNumber(i);
208     bisectormap(i)->FirstEdge(theedgelist->Current());
209     bisectormap(i)->FirstVector
210       (atool.TangentBefore(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
211     theedgelist->Next();
212     bisectormap(i)->SecondEdge(theedgelist->Current());
213     bisectormap(i)->IssuePoint
214       (atool.FirstPoint(theedgelist->Current()->EdgeNumber(),Dist));  
215     bisectormap(i)->DistIssuePoint(Dist);
216     bisectormap(i)->SecondVector
217       (atool.TangentAfter(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
218   }
219
220 //----------------------------------------------------
221 // Affectation a chaque edge de ses deux bissectrices.
222 //----------------------------------------------------
223   theedgelist->First();
224   theedgelist->Current()->FirstBisector(bisectormap(0));
225   theedgelist->Current()->SecondBisector(bisectormap(0));
226   theedgelist->Next();
227
228   for(i=1; i<theedgelist->Number()-1; i++) {
229     theedgelist->Current()->FirstBisector
230       (bisectormap(i-1));
231     theedgelist->Current()->SecondBisector
232       (bisectormap(i));
233     theedgelist->Next();
234   }
235
236   theedgelist->Current()->FirstBisector(bisectormap(theedgelist->Number()-2));
237   theedgelist->Current()->SecondBisector(bisectormap(theedgelist->Number()-2));
238
239 //===========================================================================
240 //                         Boucle Principale   (etape 2)
241 //===========================================================================
242   Standard_Integer NumberOfIte = 0;
243
244   while(theedgelist->Number()>1) {
245
246
247     // ------------------------------------------------------------------
248     //  Creation des geometries des bissectrices via le tool. (etape 2.1)
249     // -------------------------------------------------------------------
250
251     for(i=beginbisector; i<noofbisectors; i++) {
252
253       atool.CreateBisector(bisectormap(i));
254       thenumberofbisectors++;
255       
256 #ifdef OCCT_DEBUG_Mat
257       atool.Dump(bisectormap(i)->BisectorNumber(),1);
258 #ifdef ICONTINUE
259       std::cin>>Icontinue;
260 #endif
261 #endif
262     }
263
264     // ---------------------------------------------
265     //  Condition de sortie de la boucle principale.
266     // ---------------------------------------------
267
268 //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:28 2000 Begin
269     if (theedgelist->Number() < 3)
270       break;
271 //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:37 2000 End
272     
273     //---------------------------------------------------
274     // boucle 2 Tant qu il y a des bisectrices a effacer.
275     //---------------------------------------------------
276     for(;;) {
277       NbIterBis++;
278
279       noofbisectorstoremove = 0;
280       theedgelist->First();
281       theedgelist->Next();
282
283       //--------------------------------------------------------------
284       // Calcul des intersections des bisectrices voisines.(etape 2.2)
285       //--------------------------------------------------------------
286
287       if (NbIterBis <= EvenNbIterBis+1)
288         EdgeNumbers(NbIterBis) = theedgelist->Number();
289       else
290         {
291           for (k = 1; k <= EvenNbIterBis; k++)
292             EdgeNumbers(k) = EdgeNumbers(k+1);
293           EdgeNumbers(EvenNbIterBis+1) = theedgelist->Number();
294         }
295       if (EdgeNumbers(EvenNbIterBis+1) == EdgeNumbers(1))
296         ToNullifyNoofbisectorstoremove = Standard_True;
297
298       for(i=1; i<theedgelist->Number()-1; i++) {
299         edge = theedgelist->Current();
300         if(edge->Distance() == -1.) {
301           firstbisector = edge->FirstBisector();
302           secondbisector = edge->SecondBisector();
303           edge->Distance(atool.IntersectBisector
304                          (firstbisector,secondbisector,intersectionpoint));
305           edge->IntersectionPoint(intersectionpoint);
306
307           if(edge->Distance() == Precision::Infinite()) {
308             if(firstbisector->IndexNumber() >= beginbisector ||
309                secondbisector->IndexNumber() >= beginbisector) 
310               Intersect(atool,0,noofbisectorstoremove,
311                         firstbisector,secondbisector );
312           }
313           else {
314             if(firstbisector->IndexNumber() >= beginbisector) {
315               Intersect(atool,1,noofbisectorstoremove,
316                         firstbisector,secondbisector );
317             }
318             if(secondbisector->IndexNumber() >= beginbisector) {
319               Intersect(atool,2,noofbisectorstoremove,
320                         firstbisector,secondbisector );
321             }
322           }
323         }
324         theedgelist->Next();
325       }
326       
327       //-------------------------------
328       // Test de sortie de la boucle 2.
329       //-------------------------------
330
331       if (ToNullifyNoofbisectorstoremove)
332         noofbisectorstoremove = 0;
333       if(noofbisectorstoremove == 0) break;
334
335       //---------------------------------------------------
336       // Annulation des bissectrices a effacer. (etape 2.4)
337       //---------------------------------------------------
338
339       for(i=0; i<noofbisectorstoremove; i++) {
340
341         bisectortoremove = bisectoronetoremove(i);
342
343         //---------------------------------------------------------------
344         // Destruction des bisectrices descendantes de <bisectortoremove>
345         // On descend dans l arbre jusqu a ce qu on atteigne
346         // <bisectortwotoremove(i).
347         //---------------------------------------------------------------
348
349         for(;;){
350
351 #ifdef OCCT_DEBUG_Mat
352           atool.Dump(bisectortoremove->BisectorNumber(),0);
353 #endif
354           // ----------------------------------
355           // Annulation de <bisectortoremove>.
356           // ----------------------------------
357           thenumberofbisectors--;
358           currentbisectorlist = bisectortoremove->List();
359           currentbisectorlist->First();
360           currentbisector = currentbisectorlist->FirstItem();
361           previousedge = currentbisector->FirstEdge();
362           theedgelist->Init(previousedge);
363           previousedge->Distance(-1.);
364           previousedge->FirstBisector()->SecondParameter(Precision::Infinite());
365           previousedge->SecondBisector()->FirstParameter(Precision::Infinite());
366
367           //------------------------------------------
368           // Annulation des fils de <currentbisector>.
369           //------------------------------------------
370
371           while(currentbisectorlist->More()) {
372             currentbisector = currentbisectorlist->Current();
373             currentedge  = currentbisector->SecondEdge();
374
375             //---------------------------------------
376             // Reinsertion de l edge dans le contour.
377             //---------------------------------------
378             theedgelist->LinkAfter(currentedge);
379             theedgelist->Next();
380             
381             currentedge->FirstBisector(currentbisector);
382             previousedge->SecondBisector(currentbisector);
383 #ifdef OCCT_DEBUG_Mat                 
384             atool.Dump(currentbisector->BisectorNumber(),0);
385 #endif
386
387             //------------------------------------------------------
388             // Annulation de l intersection ie les fils qui
389             // ont generes l intersection sont prolonges a l infini.
390             //------------------------------------------------------
391
392             currentbisector->FirstParameter (Precision::Infinite());
393             currentbisector->SecondParameter(Precision::Infinite());
394                       
395             atool.TrimBisector(currentbisector);
396             
397 #ifdef OCCT_DEBUG_Mat
398             atool.Dump(currentbisector->BisectorNumber(),1);
399 #endif
400             currentedge->Distance(-1.);
401             currentedge->FirstBisector()->SecondParameter(Precision::Infinite());
402             currentedge->SecondBisector()->FirstParameter(Precision::Infinite());
403             
404             previousedge = currentedge;
405             currentbisectorlist->Next();
406           }
407
408           RemovedEdgesList->BackAdd(theedgelist->Current());
409           theedgelist->Unlink();
410
411           //-----------------------------------------------------------
412           // Test de sortie de la boucle d annulation des bissectrices.
413           //-----------------------------------------------------------
414
415           if(bisectortoremove->BisectorNumber() ==
416              bisectortwotoremove(i)->BisectorNumber()) break;
417
418           //-----------------------
419           // Descente dans l arbre.
420           //-----------------------
421
422           if(typeofbisectortoremove(i) == 1)
423             bisectortoremove = bisectortoremove->FirstBisector();
424           else
425             bisectortoremove = bisectortoremove->LastBisector();
426         
427         }  //----------------------------------------------------
428            // Fin boucle d annulation des bissectrices issue de 
429            // <bisectoronetoremove(i)>.
430            //----------------------------------------------------
431
432       } //------------------------------------------
433         // Fin boucle d annulation des bissectrices.
434         //-------------------------------------------
435
436 #ifdef ICONTINUE
437       std::cin>>Icontinue;
438 #endif
439     } //--------------
440       // Fin Boucle 2.
441       //--------------
442     
443     // ----------------------------------------------------------------------
444     // Analyse des parametres des intersections sur les bisectrices de chaque
445     // edge et determination des portions de contour a supprimees. (etape 2.5)
446     // ----------------------------------------------------------------------
447
448     theedgelist->First();
449     theedgelist->Next();
450       
451     currentbisector = theedgelist->Current()->FirstBisector();
452     if (currentbisector->FirstParameter()  == Precision::Infinite() &&
453         currentbisector->SecondParameter() == Precision::Infinite()) {
454       parama[0] = -1;
455       paramb[0] = -1;
456     }
457     else if(currentbisector->FirstParameter() == Precision::Infinite()) {
458       parama[0] = -1;
459       paramb[0] =  1;
460     }
461     else if(currentbisector->SecondParameter() == Precision::Infinite()) {
462       paramb[0] = -1;
463       parama[0] =  1;
464     }
465     else if (atool.Distance(currentbisector,
466                             currentbisector->FirstParameter(),
467                             currentbisector->SecondParameter()) 
468              > toleranceofconfusion) {
469       if((currentbisector->FirstParameter() - 
470           currentbisector->SecondParameter())
471          *currentbisector->Sense() > 0.) {      
472         parama[0] = -1;
473         paramb[0] =  1;
474       }
475       else {
476         paramb[0] = -1;
477         parama[0] =  1;
478       }
479     }
480     else {
481       parama[0] = 1;
482       paramb[0] = 1;
483     }
484     
485     narea = -1;
486     
487     for(i=1; i<theedgelist->Number()-1; i++) {
488       currentbisector = theedgelist->Current()->SecondBisector();
489       if (currentbisector->FirstParameter()  == Precision::Infinite() &&
490           currentbisector->SecondParameter() == Precision::Infinite()) {
491         parama[1] = -1;
492         paramb[1] = -1;
493       }
494       else if(currentbisector->FirstParameter() == Precision::Infinite()) {
495         parama[1] = -1;
496         paramb[1] =  1;
497       }
498       else if(currentbisector->SecondParameter() == Precision::Infinite()) {
499         paramb[1] = -1;
500         parama[1] =  1;
501       }
502       else if (atool.Distance(currentbisector,
503                               currentbisector->FirstParameter(),
504                               currentbisector->SecondParameter()) 
505                > toleranceofconfusion) {
506         if((currentbisector->FirstParameter() - 
507             currentbisector->SecondParameter()) 
508            *currentbisector->Sense() > 0.) {      
509           parama[1] = -1;
510           paramb[1] =  1;
511         }
512         else {
513           paramb[1] = -1;
514           parama[1] =  1;
515         }
516       }
517       else {
518         parama[1] = 1;
519         paramb[1] = 1;
520       }
521
522       //-----------------------------------------------------------------
523       // Test si l edge est a enlever du contour
524       // Construction des portions de contour a eliminer.
525       //
526       //  narea : nombre de portions continues du contour a eliminer.
527       //  firstarea[i] : indice premier edge de la portion i.
528       //  lastarea[i]  : indice dernier edge de la portion i.
529       //-----------------------------------------------------------------
530
531 #ifdef OCCT_DEBUG_Mat
532       std::cout <<" Test sur les parametres pour elimination"<<std::endl;
533       std::cout << " Edge number :"<<theedgelist->Current()->EdgeNumber()<<std::endl;
534 #endif
535
536       if(paramb[0] > 0 && parama[1] > 0) {
537
538 #ifdef OCCT_DEBUG_Mat
539       std::cout <<" A ELIMINER "<<std::endl;
540 #endif  
541         if(narea < 0) {
542           firstarea(++narea) = theedgelist->Index();
543           lastarea(narea) = firstarea(narea);
544           noofarea(narea) = 1;
545         }
546         else {
547           if(theedgelist->Index() == lastarea(narea)+1) {
548             lastarea(narea)++;
549             noofarea(narea)++;
550           }
551           else {
552             firstarea(++narea) = theedgelist->Index();
553             lastarea(narea) = firstarea(narea);
554             noofarea(narea) = 1;
555           }
556         }
557       }
558       parama[0] = parama[1];
559       paramb[0] = paramb[1];
560       theedgelist->Next();
561     
562     } 
563     
564     compact = 0;
565     if(narea > 0) {
566       if(lastarea(narea) == theedgelist->Number() && firstarea(0) == 1) {
567         firstarea(0) = firstarea(narea);
568         noofarea(0) = noofarea(0)+noofarea(narea);
569         compact = noofarea(narea);
570         narea--;
571       }
572     }
573     
574     narea++;
575
576     //------------------------------------------------------------------
577     // Sortie de la boucle principale si il n y a pas d edge a eliminer.
578     // (etape 2.6)
579     //------------------------------------------------------------------
580     if(narea == 0) {
581       interrupt = Standard_True;
582       break;
583     }
584     
585
586     //----------------------------------------------------------------
587     // Elimination des edges a enlever du contour
588     // => Mise a jour du nouveau contour.
589     // => Creation des bissectrices entre les nouvelles edges voisines.
590     //----------------------------------------------------------------
591
592     beginbisector = noofbisectors;
593     shift = 0;
594     all = 0;
595     if(narea == 1 && noofarea(0) == theedgelist->Number()) all = 1;
596
597     for(i=0; i<narea; i++) {
598       if(i == 1)shift = shift-compact;
599       theedgelist->First();
600       theedgelist->Next();
601       edgetoremove = theedgelist->Brackets(firstarea(i)-shift);
602       
603       edgetoremove->FirstBisector()->EndPoint(edgetoremove
604                                               ->IntersectionPoint());
605       
606 #ifdef OCCT_DEBUG_Mat
607       atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),0);
608 #endif
609
610       edgetoremove->FirstBisector()->FirstParameter
611         (edgetoremove->FirstBisector()->SecondParameter());
612           
613 #ifdef OCCT_DEBUG_Mat
614       if(atool.TrimBisector(edgetoremove->FirstBisector()))
615         atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),1);
616 #else
617       atool.TrimBisector(edgetoremove->FirstBisector());
618 #endif
619
620       bisectormap.Bind(noofbisectors,new MAT_Bisector());
621       bisectormap(noofbisectors)->IndexNumber(noofbisectors);
622       bisectormap(noofbisectors)->DistIssuePoint(edgetoremove->Distance());
623       bisectormap(noofbisectors)->IssuePoint(edgetoremove
624                                                 ->IntersectionPoint());
625       bisectormap(noofbisectors)->FirstEdge(theedgelist->PreviousItem());
626       bisectormap(noofbisectors)->AddBisector(edgetoremove
627                                                  ->FirstBisector());
628
629       for(j=0; j<noofarea(i); j++) {
630         RemovedEdgesList->BackAdd(theedgelist->Current());
631         theedgelist->Unlink();
632         theedgelist->Next();
633         shift++;
634
635 #ifdef OCCT_DEBUG_Mat
636         std::cout<<" Suppression de l'arete : "<<edgetoremove->EdgeNumber()<<std::endl;
637 #endif
638
639         if(all == 0 || j+1 != noofarea(i)) {
640           bisectormap(noofbisectors)->AddBisector(edgetoremove
641                                                      ->SecondBisector());
642         }
643         edgetoremove->SecondBisector()->EndPoint(edgetoremove
644                                                  ->IntersectionPoint());
645
646 #ifdef OCCT_DEBUG_Mat
647         atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),0);
648 #endif
649
650         edgetoremove->SecondBisector()->SecondParameter
651           (edgetoremove->SecondBisector()->FirstParameter());
652 #ifdef OCCT_DEBUG_Mat
653         if(atool.TrimBisector(edgetoremove->SecondBisector()))
654           atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),1);
655 #else
656         atool.TrimBisector(edgetoremove->SecondBisector());
657 #endif
658         edgetoremove = theedgelist->Current();
659       }
660       bisectormap(noofbisectors)->SecondEdge(theedgelist->Current());
661
662       theedgelist->PreviousItem()
663         ->SecondBisector(bisectormap(noofbisectors));
664       theedgelist->Current()->FirstBisector(bisectormap(noofbisectors));
665           
666       bisectormap(noofbisectors)->FirstVector
667         (atool.Tangent
668          (bisectormap(noofbisectors)->FirstBisector()
669           ->BisectorNumber()));
670       
671       bisectormap(noofbisectors)->SecondVector
672         (atool.Tangent
673          (bisectormap(noofbisectors)->LastBisector()
674           ->BisectorNumber()));
675       
676       noofbisectors++;
677       
678       theedgelist->PreviousItem()->Distance(-1);
679       theedgelist->Current()->Distance(-1);
680
681       theedgelist->PreviousItem()->FirstBisector()
682         ->SecondParameter(Precision::Infinite());
683       theedgelist->Current()->SecondBisector()->FirstParameter(Precision::Infinite());
684     }
685
686     //-----------------------------------------------------------------------
687     // Test sur le nombre d iterations :
688     // A chaque iteration est elimine un element du contour qui ne sera plus
689     // reinsere par la suite => le nombre d iterartions doit etre < au nombre
690     // d elements.
691     // Le nombre d iteration maximum est fixe a numberofedges*numberofedges.
692     //-----------------------------------------------------------------------
693     if (NumberOfIte > NumberMaxOfIte) {
694       isDone = Standard_False;             //Echec calcul de la carte.
695       break;
696     }
697     NumberOfIte++;
698
699   }  //===============================================
700      //            Fin Boucle Principale.
701      //===============================================
702      
703   //----------
704   // etape 3.
705   //----------
706
707
708   //----------------------------------------------
709   // interupt = True => bissectrices semi_infinies.
710   //----------------------------------------------
711   
712   if(interrupt)
713     semiInfinite = Standard_True;
714   else {
715     semiInfinite = Standard_False;
716
717     //------------------------------------------------------------------
718     // Si le nombre d edge > 1 => le nombre d edge = 2 
719     //              (cf test sortie boucle principale)
720     // Les deux dernieres bisectrices separent les memes edges .
721     // Soit elles sont confondues si calcul a l interieur, soit elles
722     // sont semi-Infinies (exemple : contour compose seulement de deux
723     // arcs de cercles).                           
724     //------------------------------------------------------------------
725
726     if(theedgelist->Number() > 1) { //Now this branch is never reachable
727                                     //because the case edgenumber = 2 is processed in the main loop
728       theedgelist->First();
729       edge = theedgelist->Current();
730       if(edge->FirstBisector()->IndexNumber() == noofbisectors-1) {
731 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
732         if (atool.TrimBisector(edge->SecondBisector(),
733                                edge->FirstBisector()->IssuePoint())) {
734           if (edge->SecondBisector()->EndPoint() == 0)
735             edge->SecondBisector()->EndPoint(edge->FirstBisector()->IssuePoint());
736           bisectormap(noofbisectors-1)->AddBisector(edge->SecondBisector());
737         } else
738           semiInfinite = Standard_True;
739 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
740       }
741       else {
742 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
743         if (atool.TrimBisector(edge->FirstBisector(),
744                                edge->SecondBisector()->IssuePoint())) {
745           if (edge->FirstBisector()->EndPoint() == 0)
746             edge->FirstBisector()->EndPoint(edge->SecondBisector()->IssuePoint());
747           bisectormap(noofbisectors-1)->AddBisector(edge->FirstBisector());
748         } else 
749           semiInfinite = Standard_True;
750 //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
751       }
752       if (!semiInfinite) {     
753         thenumberofbisectors--;
754         bisectormap(noofbisectors-1)->SecondEdge(edge);
755         bisectormap(noofbisectors-1)->BisectorNumber(-1);
756       }
757     }
758   }
759
760   if(semiInfinite) {
761     beginbisector = noofbisectors;
762     theedgelist->First();
763     for(i=1; i<theedgelist->Number(); i++) {
764       edge = theedgelist->Current();
765       bisectormap.Bind(noofbisectors,edge->SecondBisector());
766       noofbisectors++;
767       theedgelist->Next();
768     }
769
770   }
771
772   //---------------------------
773   // Recuperations des racines.
774   //---------------------------
775
776   roots = new MAT_ListOfBisector;
777   
778   if (bisectormap(noofbisectors-1)->BisectorNumber() == -1) {
779     roots = bisectormap(noofbisectors-1)->List();
780     roots->First();
781     roots->Current()->FirstEdge()
782       ->Distance(bisectormap(noofbisectors-1)->DistIssuePoint());
783   }
784   else {
785     for (i=beginbisector;i<noofbisectors;i++) {
786       roots->BackAdd(bisectormap(i));
787     }
788   }
789   
790 }
791
792 void MAT2d_Mat2d::CreateMat(MAT2d_Tool2d& atool)
793 {
794
795 #ifdef ICONTINUE
796   Standard_Boolean Icontinue;
797 #endif
798
799   Standard_Boolean interrupt = Standard_False;
800
801   Handle(MAT_Edge) edgetoremove;
802   Handle(MAT_Edge) previousedge,currentedge;
803
804   Standard_Integer      noofbisectorstoremove;
805   Handle(MAT_Bisector)  firstbisector,secondbisector;
806   Handle(MAT_Edge)      edge;
807   Standard_Integer      intersectionpoint;
808   Standard_Integer      beginbisector;
809   Standard_Integer      noofbisectors;
810
811   Standard_Integer      NbIterBis = 0;
812   Standard_Integer      EvenNbIterBis = 10;
813   TColStd_Array1OfInteger EdgeNumbers(1, EvenNbIterBis+1);
814   EdgeNumbers.Init(-1);
815   Standard_Boolean      ToNullifyNoofbisectorstoremove = Standard_False;
816
817   Handle(MAT_ListOfBisector) currentbisectorlist;
818
819   Handle(MAT_Bisector) bisectortoremove,lastbisector,currentbisector;
820   Handle(MAT_Bisector) previousbisector;
821
822   Standard_Integer     i,j,k,narea,shift,compact,all;
823   Standard_Integer     noofedges;
824   Standard_Integer     NumberMaxOfIte;
825   Standard_Real        toleranceofconfusion;
826
827   noofedges            = atool.NumberOfItems();
828   toleranceofconfusion = atool.ToleranceOfConfusion();
829   NumberMaxOfIte       = noofedges*noofedges;
830
831   TColStd_Array1OfInteger firstarea(0, noofedges);
832   TColStd_Array1OfInteger lastarea(0, noofedges);
833   TColStd_Array1OfInteger noofarea(0, noofedges);
834
835   Standard_Integer  parama[2];
836   Standard_Integer  paramb[2];
837   //
838   Standard_Integer aNbOfNarea1 = 0, aPrefNarea = 0, aNbMaxNarea1 = 10;
839   Standard_Integer aNbElts[2] = {0, 0}, aCountElts[2] = {0, 0};
840   Standard_Boolean isBreak = Standard_False;
841
842   // -----------------------------------------
843   // Initialisation et remise a zero des maps.
844   // -----------------------------------------
845   bisectoronetoremove.Clear();
846   bisectortwotoremove.Clear();
847   typeofbisectortoremove.Clear();
848   bisectormap.Clear();
849
850   isDone        = Standard_True;
851   noofbisectors = noofedges;
852   beginbisector = 0;
853
854   // --------------------------------------------------------------------
855   // Construction de <theedgelist> un edge correspond a un element simple
856   // du contour.
857   // --------------------------------------------------------------------
858   theedgelist = new MAT_ListOfEdge();
859   RemovedEdgesList = new MAT_ListOfEdge();
860
861   for(i=0; i<noofedges; i++) {
862     edge = new MAT_Edge();
863     edge->EdgeNumber(i+1);
864     edge->Distance(-1);
865     theedgelist->BackAdd(edge);
866   }
867
868   theedgelist->Loop();
869
870   //---------------------------------------------------
871   // Initialisation des bissectrices issues du contour.
872   //---------------------------------------------------
873   Standard_Real Dist;
874   theedgelist->First();
875
876   for(i=0; i<theedgelist->Number(); i++) {
877     bisectormap.Bind(i,new MAT_Bisector());
878     bisectormap(i)->IndexNumber(i);
879     bisectormap(i)->FirstEdge(theedgelist->Current());
880     bisectormap(i)->FirstVector
881       (atool.TangentBefore(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
882     theedgelist->Next();
883     bisectormap(i)->SecondEdge(theedgelist->Current());
884     bisectormap(i)->IssuePoint
885       (atool.FirstPoint(theedgelist->Current()->EdgeNumber(),Dist));  
886     bisectormap(i)->DistIssuePoint(Dist);
887     bisectormap(i)->SecondVector
888       (atool.TangentAfter(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
889   }
890
891   //----------------------------------------------------
892   // Affectation a chaque edge de ses deux bissectrices.
893   //----------------------------------------------------
894   theedgelist->First();
895
896   for(i=0; i<theedgelist->Number(); i++) {
897     theedgelist->Current()->FirstBisector
898       (bisectormap((i-1+noofbisectors)%noofbisectors));
899     theedgelist->Current()->SecondBisector
900       (bisectormap(i));
901     theedgelist->Next();
902   }
903
904   //===========================================================================
905   //                         Boucle Principale   (etape 2)
906   //===========================================================================
907   Standard_Integer NumberOfIte = 0;
908
909   while(theedgelist->Number()>1) {
910
911
912     // ------------------------------------------------------------------
913     //  Creation des geometries des bissectrices via le tool. (etape 2.1)
914     // -------------------------------------------------------------------
915     Standard_Integer aNbBis = noofbisectors - beginbisector;
916     for(i=beginbisector; i<noofbisectors; i++) {
917
918       atool.CreateBisector(bisectormap(i));
919       thenumberofbisectors++;
920
921 #ifdef OCCT_DEBUG_Mat
922       atool.Dump(bisectormap(i)->BisectorNumber(),1);
923 #ifdef ICONTINUE
924       std::cin>>Icontinue;
925 #endif
926 #endif
927     }
928
929     //Patch to prevent infinit loop because of
930     //bad geometry
931     if(aNbBis == 1)
932     {
933       if(aPrefNarea == 1)
934       {
935         aNbOfNarea1++;
936         Standard_Integer edge1number  = bisectormap(beginbisector)->FirstEdge()->EdgeNumber();
937         Standard_Integer edge2number  = bisectormap(beginbisector)->SecondEdge()->EdgeNumber();
938         if(aNbElts[0] == edge1number)
939         {
940           aCountElts[0]++;
941         }
942         else
943         {
944           aCountElts[0] = 0;
945           aNbElts[0] = edge1number;
946         }
947         if(aNbElts[1] == edge2number)
948         {
949           aCountElts[1]++;
950         }
951         else
952         {
953           aCountElts[1] = 0;
954           aNbElts[1] = edge2number;
955         }
956         if(aNbOfNarea1 >= aNbMaxNarea1 && (aCountElts[0] >= aNbMaxNarea1 || aCountElts[1] >= aNbMaxNarea1))
957         {
958           isBreak = Standard_True;
959         }
960       }
961       else
962       {
963         aNbOfNarea1 = 0;
964         aCountElts[0] = 0;
965         aCountElts[1] = 0;
966       }
967     }
968     aPrefNarea = aNbBis;
969     // ---------------------------------------------
970     //  Condition de sortie de la boucle principale.
971     // ---------------------------------------------
972
973     //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:28 2000 Begin
974     if (theedgelist->Number() < 3)
975       break;
976     //  Modified by Sergey KHROMOV - Fri Nov 17 10:28:37 2000 End
977
978     //---------------------------------------------------
979     // boucle 2 Tant qu il y a des bisectrices a effacer.
980     //---------------------------------------------------
981     for(;;) {
982       NbIterBis++;
983
984       noofbisectorstoremove = 0;
985       theedgelist->First();
986
987       //--------------------------------------------------------------
988       // Calcul des intersections des bisectrices voisines.(etape 2.2)
989       //--------------------------------------------------------------
990
991       if (NbIterBis <= EvenNbIterBis+1)
992         EdgeNumbers(NbIterBis) = theedgelist->Number();
993       else
994       {
995         for (k = 1; k <= EvenNbIterBis; k++)
996           EdgeNumbers(k) = EdgeNumbers(k+1);
997         EdgeNumbers(EvenNbIterBis+1) = theedgelist->Number();
998       }
999       if (EdgeNumbers(EvenNbIterBis+1) == EdgeNumbers(1))
1000         ToNullifyNoofbisectorstoremove = Standard_True;
1001
1002       for(i=0; i<theedgelist->Number(); i++) {
1003         edge = theedgelist->Current();
1004         if(edge->Distance() == -1.) {
1005           firstbisector = edge->FirstBisector();
1006           secondbisector = edge->SecondBisector();
1007           edge->Distance(atool.IntersectBisector
1008             (firstbisector,secondbisector,intersectionpoint));
1009           edge->IntersectionPoint(intersectionpoint);
1010
1011           if(edge->Distance() == Precision::Infinite()) {
1012             if(firstbisector->IndexNumber() >= beginbisector ||
1013               secondbisector->IndexNumber() >= beginbisector) 
1014               Intersect(atool,0,noofbisectorstoremove,
1015               firstbisector,secondbisector );
1016           }
1017           else {
1018             if(firstbisector->IndexNumber() >= beginbisector) {
1019               Intersect(atool,1,noofbisectorstoremove,
1020                 firstbisector,secondbisector );
1021             }
1022             if(secondbisector->IndexNumber() >= beginbisector) {
1023               Intersect(atool,2,noofbisectorstoremove,
1024                 firstbisector,secondbisector );
1025             }
1026           }
1027         }
1028         theedgelist->Next();
1029       }
1030
1031       //-------------------------------
1032       // Test de sortie de la boucle 2.
1033       //-------------------------------
1034
1035       if (ToNullifyNoofbisectorstoremove)
1036         noofbisectorstoremove = 0;
1037       if(noofbisectorstoremove == 0) break;
1038
1039       //---------------------------------------------------
1040       // Annulation des bissectrices a effacer. (etape 2.4)
1041       //---------------------------------------------------
1042
1043       for(i=0; i<noofbisectorstoremove; i++) {
1044
1045         bisectortoremove = bisectoronetoremove(i);
1046
1047         //---------------------------------------------------------------
1048         // Destruction des bisectrices descendantes de <bisectortoremove>
1049         // On descend dans l arbre jusqu a ce qu on atteigne
1050         // <bisectortwotoremove(i).
1051         //---------------------------------------------------------------
1052
1053         for(;;){
1054
1055 #ifdef OCCT_DEBUG_Mat
1056           atool.Dump(bisectortoremove->BisectorNumber(),0);
1057 #endif
1058           // ----------------------------------
1059           // Annulation de <bisectortoremove>.
1060           // ----------------------------------
1061           thenumberofbisectors--;
1062           currentbisectorlist = bisectortoremove->List();
1063           currentbisectorlist->First();
1064           currentbisector = currentbisectorlist->FirstItem();
1065           previousedge = currentbisector->FirstEdge();
1066           theedgelist->Init(previousedge);
1067           previousedge->Distance(-1.);
1068           previousedge->FirstBisector()->SecondParameter(Precision::Infinite());
1069           previousedge->SecondBisector()->FirstParameter(Precision::Infinite());
1070
1071           //------------------------------------------
1072           // Annulation des fils de <currentbisector>.
1073           //------------------------------------------
1074
1075           while(currentbisectorlist->More()) {
1076             currentbisector = currentbisectorlist->Current();
1077             currentedge  = currentbisector->SecondEdge();
1078
1079             //---------------------------------------
1080             // Reinsertion de l edge dans le contour.
1081             //---------------------------------------
1082             theedgelist->LinkAfter(currentedge);
1083             theedgelist->Next();
1084
1085             currentedge->FirstBisector(currentbisector);
1086             previousedge->SecondBisector(currentbisector);
1087 #ifdef OCCT_DEBUG_Mat                 
1088             atool.Dump(currentbisector->BisectorNumber(),0);
1089 #endif
1090
1091             //------------------------------------------------------
1092             // Annulation de l intersection ie les fils qui
1093             // ont generes l intersection sont prolonges a l infini.
1094             //------------------------------------------------------
1095
1096             currentbisector->FirstParameter (Precision::Infinite());
1097             currentbisector->SecondParameter(Precision::Infinite());
1098
1099             atool.TrimBisector(currentbisector);
1100
1101 #ifdef OCCT_DEBUG_Mat
1102             atool.Dump(currentbisector->BisectorNumber(),1);
1103 #endif
1104             currentedge->Distance(-1.);
1105             currentedge->FirstBisector()->SecondParameter(Precision::Infinite());
1106             currentedge->SecondBisector()->FirstParameter(Precision::Infinite());
1107
1108             previousedge = currentedge;
1109             currentbisectorlist->Next();
1110           }
1111
1112           RemovedEdgesList->BackAdd(theedgelist->Current());
1113           theedgelist->Unlink();
1114
1115           //-----------------------------------------------------------
1116           // Test de sortie de la boucle d annulation des bissectrices.
1117           //-----------------------------------------------------------
1118
1119           if(bisectortoremove->BisectorNumber() ==
1120             bisectortwotoremove(i)->BisectorNumber()) break;
1121
1122           //-----------------------
1123           // Descente dans l arbre.
1124           //-----------------------
1125
1126           if(typeofbisectortoremove(i) == 1)
1127             bisectortoremove = bisectortoremove->FirstBisector();
1128           else
1129             bisectortoremove = bisectortoremove->LastBisector();
1130
1131         }  //----------------------------------------------------
1132         // Fin boucle d annulation des bissectrices issue de 
1133         // <bisectoronetoremove(i)>.
1134         //----------------------------------------------------
1135
1136       } //------------------------------------------
1137       // Fin boucle d annulation des bissectrices.
1138       //-------------------------------------------
1139
1140 #ifdef ICONTINUE
1141       std::cin>>Icontinue;
1142 #endif
1143     } //--------------
1144     // Fin Boucle 2.
1145     //--------------
1146
1147     // ----------------------------------------------------------------------
1148     // Analyse des parametres des intersections sur les bisectrices de chaque
1149     // edge et determination des portions de contour a supprimees. (etape 2.5)
1150     // ----------------------------------------------------------------------
1151
1152     theedgelist->First();
1153
1154     currentbisector = theedgelist->Current()->FirstBisector();
1155     if (currentbisector->FirstParameter()  == Precision::Infinite() &&
1156       currentbisector->SecondParameter() == Precision::Infinite()) {
1157         parama[0] = -1;
1158         paramb[0] = -1;
1159     }
1160     else if(currentbisector->FirstParameter() == Precision::Infinite()) {
1161       parama[0] = -1;
1162       paramb[0] =  1;
1163     }
1164     else if(currentbisector->SecondParameter() == Precision::Infinite()) {
1165       paramb[0] = -1;
1166       parama[0] =  1;
1167     }
1168     else if (atool.Distance(currentbisector,
1169       currentbisector->FirstParameter(),
1170       currentbisector->SecondParameter()) 
1171       > toleranceofconfusion) {
1172         if((currentbisector->FirstParameter() - 
1173           currentbisector->SecondParameter())
1174           *currentbisector->Sense() > 0.) {      
1175             parama[0] = -1;
1176             paramb[0] =  1;
1177         }
1178         else {
1179           paramb[0] = -1;
1180           parama[0] =  1;
1181         }
1182     }
1183     else {
1184       parama[0] = 1;
1185       paramb[0] = 1;
1186     }
1187
1188     narea = -1;
1189
1190     for(i=0; i<theedgelist->Number(); i++) {
1191       currentbisector = theedgelist->Current()->SecondBisector();
1192       if (currentbisector->FirstParameter()  == Precision::Infinite() &&
1193         currentbisector->SecondParameter() == Precision::Infinite()) {
1194           parama[1] = -1;
1195           paramb[1] = -1;
1196       }
1197       else if(currentbisector->FirstParameter() == Precision::Infinite()) {
1198         parama[1] = -1;
1199         paramb[1] =  1;
1200       }
1201       else if(currentbisector->SecondParameter() == Precision::Infinite()) {
1202         paramb[1] = -1;
1203         parama[1] =  1;
1204       }
1205       else if (atool.Distance(currentbisector,
1206         currentbisector->FirstParameter(),
1207         currentbisector->SecondParameter()) 
1208     > toleranceofconfusion) {
1209       if((currentbisector->FirstParameter() - 
1210         currentbisector->SecondParameter()) 
1211         *currentbisector->Sense() > 0.) {      
1212           parama[1] = -1;
1213           paramb[1] =  1;
1214       }
1215       else {
1216         paramb[1] = -1;
1217         parama[1] =  1;
1218       }
1219       }
1220       else {
1221         parama[1] = 1;
1222         paramb[1] = 1;
1223       }
1224
1225       //-----------------------------------------------------------------
1226       // Test si l edge est a enlever du contour
1227       // Construction des portions de contour a eliminer.
1228       //
1229       //  narea : nombre de portions continues du contour a eliminer.
1230       //  firstarea[i] : indice premier edge de la portion i.
1231       //  lastarea[i]  : indice dernier edge de la portion i.
1232       //-----------------------------------------------------------------
1233
1234 #ifdef OCCT_DEBUG_Mat
1235       std::cout <<" Test sur les parametres pour elimination"<<std::endl;
1236       std::cout << " Edge number :"<<theedgelist->Current()->EdgeNumber()<<std::endl;
1237 #endif
1238
1239       if(paramb[0] > 0 && parama[1] > 0) {
1240
1241 #ifdef OCCT_DEBUG_Mat
1242         std::cout <<" A ELIMINER "<<std::endl;
1243 #endif  
1244         if(narea < 0) {
1245           firstarea(++narea) = theedgelist->Index();
1246           lastarea(narea) = firstarea(narea);
1247           noofarea(narea) = 1;
1248         }
1249         else {
1250           if(theedgelist->Index() == lastarea(narea)+1) {
1251             lastarea(narea)++;
1252             noofarea(narea)++;
1253           }
1254           else {
1255             firstarea(++narea) = theedgelist->Index();
1256             lastarea(narea) = firstarea(narea);
1257             noofarea(narea) = 1;
1258           }
1259         }
1260       }
1261       parama[0] = parama[1];
1262       paramb[0] = paramb[1];
1263       theedgelist->Next();
1264
1265     } 
1266
1267     compact = 0;
1268     if(narea > 0) {
1269       if(lastarea(narea) == theedgelist->Number() && firstarea(0) == 1) {
1270         firstarea(0) = firstarea(narea);
1271         noofarea(0) = noofarea(0)+noofarea(narea);
1272         compact = noofarea(narea);
1273         narea--;
1274       }
1275     }
1276
1277     narea++;
1278
1279     //------------------------------------------------------------------
1280     // Sortie de la boucle principale si il n y a pas d edge a eliminer.
1281     // (etape 2.6)
1282     //------------------------------------------------------------------
1283     //
1284     //Patch to break infinite loop.
1285     if(narea == 1 && isBreak)
1286     {
1287       narea = 0;
1288     }
1289     //
1290     if(narea == 0) {
1291       interrupt = Standard_True;
1292       break;
1293     }
1294
1295
1296     //----------------------------------------------------------------
1297     // Elimination des edges a enlever du contour
1298     // => Mise a jour du nouveau contour.
1299     // => Creation des bissectrices entre les nouvelles edges voisines.
1300     //----------------------------------------------------------------
1301
1302     beginbisector = noofbisectors;
1303     shift = 0;
1304     all = 0;
1305     if(narea == 1 && noofarea(0) == theedgelist->Number()) all = 1;
1306
1307     for(i=0; i<narea; i++) {
1308       if(i == 1)shift = shift-compact;
1309       theedgelist->First();
1310       edgetoremove = theedgelist->Brackets(firstarea(i)-shift);
1311
1312       edgetoremove->FirstBisector()->EndPoint(edgetoremove
1313         ->IntersectionPoint());
1314
1315 #ifdef OCCT_DEBUG_Mat
1316       atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),0);
1317 #endif
1318
1319       edgetoremove->FirstBisector()->FirstParameter
1320         (edgetoremove->FirstBisector()->SecondParameter());
1321
1322 #ifdef OCCT_DEBUG_Mat
1323       if(atool.TrimBisector(edgetoremove->FirstBisector()))
1324         atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),1);
1325 #else
1326       atool.TrimBisector(edgetoremove->FirstBisector());
1327 #endif
1328
1329       bisectormap.Bind(noofbisectors,new MAT_Bisector());
1330       bisectormap(noofbisectors)->IndexNumber(noofbisectors);
1331       bisectormap(noofbisectors)->DistIssuePoint(edgetoremove->Distance());
1332       bisectormap(noofbisectors)->IssuePoint(edgetoremove
1333         ->IntersectionPoint());
1334       bisectormap(noofbisectors)->FirstEdge(theedgelist->PreviousItem());
1335       bisectormap(noofbisectors)->AddBisector(edgetoremove
1336         ->FirstBisector());
1337
1338       for(j=0; j<noofarea(i); j++) {
1339         RemovedEdgesList->BackAdd(theedgelist->Current());
1340         theedgelist->Unlink();
1341         theedgelist->Next();
1342         shift++;
1343
1344 #ifdef OCCT_DEBUG_Mat
1345         std::cout<<" Suppression de l'arete : "<<edgetoremove->EdgeNumber()<<std::endl;
1346 #endif
1347
1348         if(all == 0 || j+1 != noofarea(i)) {
1349           bisectormap(noofbisectors)->AddBisector(edgetoremove
1350             ->SecondBisector());
1351         }
1352         edgetoremove->SecondBisector()->EndPoint(edgetoremove
1353           ->IntersectionPoint());
1354
1355 #ifdef OCCT_DEBUG_Mat
1356         atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),0);
1357 #endif
1358
1359         edgetoremove->SecondBisector()->SecondParameter
1360           (edgetoremove->SecondBisector()->FirstParameter());
1361 #ifdef OCCT_DEBUG_Mat
1362         if(atool.TrimBisector(edgetoremove->SecondBisector()))
1363           atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),1);
1364 #else
1365         atool.TrimBisector(edgetoremove->SecondBisector());
1366 #endif
1367         edgetoremove = theedgelist->Current();
1368       }
1369       bisectormap(noofbisectors)->SecondEdge(theedgelist->Current());
1370
1371       theedgelist->PreviousItem()
1372         ->SecondBisector(bisectormap(noofbisectors));
1373       theedgelist->Current()->FirstBisector(bisectormap(noofbisectors));
1374
1375       bisectormap(noofbisectors)->FirstVector
1376         (atool.Tangent
1377         (bisectormap(noofbisectors)->FirstBisector()
1378         ->BisectorNumber()));
1379
1380       bisectormap(noofbisectors)->SecondVector
1381         (atool.Tangent
1382         (bisectormap(noofbisectors)->LastBisector()
1383         ->BisectorNumber()));
1384
1385       noofbisectors++;
1386
1387       theedgelist->PreviousItem()->Distance(-1);
1388       theedgelist->Current()->Distance(-1);
1389
1390       theedgelist->PreviousItem()->FirstBisector()
1391         ->SecondParameter(Precision::Infinite());
1392       theedgelist->Current()->SecondBisector()->FirstParameter(Precision::Infinite());
1393     }
1394
1395     //-----------------------------------------------------------------------
1396     // Test sur le nombre d iterations :
1397     // A chaque iteration est elimine un element du contour qui ne sera plus
1398     // reinsere par la suite => le nombre d iterartions doit etre < au nombre
1399     // d elements.
1400     // Le nombre d iteration maximum est fixe a numberofedges*numberofedges.
1401     //-----------------------------------------------------------------------
1402     if (NumberOfIte > NumberMaxOfIte) {
1403       isDone = Standard_False;             //Echec calcul de la carte.
1404       break;
1405     }
1406     NumberOfIte++;
1407
1408   }  //===============================================
1409   //            Fin Boucle Principale.
1410   //===============================================
1411
1412   //----------
1413   // etape 3.
1414   //----------
1415
1416
1417   //----------------------------------------------
1418   // interupt = True => bissectrices semi_infinies.
1419   //----------------------------------------------
1420
1421   if(interrupt)
1422     semiInfinite = Standard_True;
1423   else {
1424     semiInfinite = Standard_False;
1425
1426     //------------------------------------------------------------------
1427     // Si le nombre d edge > 1 => le nombre d edge = 2 
1428     //              (cf test sortie boucle principale)
1429     // Les deux dernieres bisectrices separent les memes edges .
1430     // Soit elles sont confondues si calcul a l interieur, soit elles
1431     // sont semi-Infinies (exemple : contour compose seulement de deux
1432     // arcs de cercles).                           
1433     //------------------------------------------------------------------
1434
1435     if(theedgelist->Number() > 1) { //Now this branch is never reachable
1436       //because the case edgenumber = 2 is processed in the main loop
1437       theedgelist->First();
1438       edge = theedgelist->Current();
1439       if(edge->FirstBisector()->IndexNumber() == noofbisectors-1) {
1440         //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
1441         if (atool.TrimBisector(edge->SecondBisector(),
1442           edge->FirstBisector()->IssuePoint())) {
1443             if (edge->SecondBisector()->EndPoint() == 0)
1444               edge->SecondBisector()->EndPoint(edge->FirstBisector()->IssuePoint());
1445             bisectormap(noofbisectors-1)->AddBisector(edge->SecondBisector());
1446         } else
1447           semiInfinite = Standard_True;
1448         //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
1449       }
1450       else {
1451         //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
1452         if (atool.TrimBisector(edge->FirstBisector(),
1453           edge->SecondBisector()->IssuePoint())) {
1454             if (edge->FirstBisector()->EndPoint() == 0)
1455               edge->FirstBisector()->EndPoint(edge->SecondBisector()->IssuePoint());
1456             bisectormap(noofbisectors-1)->AddBisector(edge->FirstBisector());
1457         } else 
1458           semiInfinite = Standard_True;
1459         //  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
1460       }
1461       if (!semiInfinite) {     
1462         thenumberofbisectors--;
1463         bisectormap(noofbisectors-1)->SecondEdge(edge);
1464         bisectormap(noofbisectors-1)->BisectorNumber(-1);
1465       }
1466     }
1467   }
1468   if(semiInfinite) {
1469     beginbisector = noofbisectors;
1470     theedgelist->First();
1471     for(i=0; i<theedgelist->Number(); i++) {
1472       edge = theedgelist->Current();
1473       bisectormap.Bind(noofbisectors,edge->SecondBisector());
1474       noofbisectors++;
1475       theedgelist->Next();
1476     }
1477
1478   } 
1479
1480   //---------------------------
1481   // Recuperations des racines.
1482   //---------------------------
1483
1484   roots = new MAT_ListOfBisector;
1485
1486   if (bisectormap(noofbisectors-1)->BisectorNumber() == -1) {
1487     roots = bisectormap(noofbisectors-1)->List();
1488     roots->First();
1489     roots->Current()->FirstEdge()
1490       ->Distance(bisectormap(noofbisectors-1)->DistIssuePoint());
1491   }
1492   else {
1493     for (i=beginbisector;i<noofbisectors;i++) {
1494       roots->BackAdd(bisectormap(i));
1495     }
1496   }
1497
1498 }
1499
1500 //========================================================================
1501 //  function : LoadBisectorsToRemove
1502 //  purpose  : Chargement des bisectrices a effacer.
1503 //========================================================================
1504 void MAT2d_Mat2d::LoadBisectorsToRemove
1505   (      Standard_Integer&     noofbisectorstoremove,
1506   const Standard_Real         distance1,
1507   const Standard_Real         distance2,
1508   const Handle(MAT_Bisector)& firstbisectortoremove1,
1509   const Handle(MAT_Bisector)& firstbisectortoremove2,
1510   const Handle(MAT_Bisector)& lastbisectortoremove1,
1511   const Handle(MAT_Bisector)& lastbisectortoremove2  )
1512 {
1513
1514   Standard_Integer found,index;
1515   Handle(MAT_Bisector) firstbisectortoremove[2];
1516   Handle(MAT_Bisector) lastbisectortoremove[2];
1517
1518   firstbisectortoremove[0] = firstbisectortoremove1;
1519   firstbisectortoremove[1] = firstbisectortoremove2;
1520   lastbisectortoremove[0]  = lastbisectortoremove1;
1521   lastbisectortoremove[1]  = lastbisectortoremove2;
1522
1523   if     (distance1  < Precision::Infinite() && 
1524     distance2 == Precision::Infinite()    )   index =  0;
1525   else if(distance2  < Precision::Infinite() && 
1526     distance1 == Precision::Infinite()    )   index =  1;
1527   else                                              index = -1;
1528
1529   if(index != -1) {
1530     found = noofbisectorstoremove;
1531     for(int j=0; j<noofbisectorstoremove; j++) {
1532       if(bisectoronetoremove(j)->BisectorNumber() ==
1533         firstbisectortoremove[index]->BisectorNumber()) {
1534           found = j;
1535           if(bisectortwotoremove(j)->BisectorNumber() <
1536             lastbisectortoremove[index]->BisectorNumber())found = -1;
1537           break;
1538       }
1539     }
1540
1541     if(found != -1) {
1542 #ifdef OCCT_DEBUG_Mat
1543       std::cout<<" first last bisector to remove :"<<
1544         firstbisectortoremove[index]->BisectorNumber()<<" "<<
1545         lastbisectortoremove[index]->BisectorNumber()<<std::endl;
1546 #endif
1547       bisectoronetoremove.Bind(found,firstbisectortoremove[index]);
1548       bisectortwotoremove.Bind(found,lastbisectortoremove[index]);
1549       typeofbisectortoremove.Bind(found,index+1);
1550
1551       if(found == noofbisectorstoremove)noofbisectorstoremove++;
1552     }
1553   }
1554 }
1555
1556 //========================================================================
1557 //  function : Intersect
1558 //  purpose  : Si <aside=0> Intersection de <firstbisector> avec les
1559 //                 descendants de <secondbisector> les plus a gauche 
1560 //                (ie secondbisector->FirstBisector()->FirstBisector...)
1561 //                          Intersection de <secondbisector> avec les
1562 //                 descendants de <firstbisector> les plus a droite 
1563 //                (ie firstbisector->LastBisector()->LastBisector...)
1564 //                
1565 //             Si <aside=1> Intersection de <firstbisector> avec ses 
1566 //                descendants les plus a gauche et les plus a droite.
1567 //
1568 //             Si <aside=2> Intersection de <secondbisector> avec ses 
1569 //                descendants les plus a gauche et les plus a droite.
1570 //========================================================================v
1571 void MAT2d_Mat2d::Intersect(      MAT2d_Tool2d&                 atool,
1572   const Standard_Integer      aside,
1573   Standard_Integer&     noofbisectortoremove,
1574   const Handle(MAT_Bisector)& firstbisector,
1575   const Handle(MAT_Bisector)& secondbisector)
1576 {
1577   Standard_Integer      bisectornumber;
1578   Standard_Real         distant,saveparameter;
1579   Standard_Real         distance[2];
1580   Standard_Integer      intersectionpoint;
1581   Handle(MAT_Bisector)  lastbisector,previousbisector;
1582   Handle(MAT_Bisector)  firstbisectortoremove[2];
1583   Handle(MAT_Bisector)  lastbisectortoremove[2];
1584
1585   distance[0] = Precision::Infinite();
1586   distance[1] = Precision::Infinite();
1587
1588   for(bisectornumber = 0; bisectornumber<2; bisectornumber++) {
1589     if(aside == 0) {
1590       if(bisectornumber == 0) 
1591         firstbisectortoremove[bisectornumber] = secondbisector;
1592       else                    
1593         firstbisectortoremove[bisectornumber] = firstbisector;
1594     }
1595     else if(aside == 1) {
1596       firstbisectortoremove[bisectornumber] = firstbisector;
1597     }
1598     else {
1599       firstbisectortoremove[bisectornumber] = secondbisector;
1600     }
1601
1602     lastbisector = firstbisectortoremove[bisectornumber];
1603
1604     if(aside == 0) {
1605       previousbisector = firstbisectortoremove[bisectornumber];
1606     }
1607     else {
1608       if(firstbisectortoremove[bisectornumber]->List()->IsEmpty())continue;
1609
1610       if(bisectornumber == 0)
1611         previousbisector = firstbisectortoremove[bisectornumber]
1612       ->FirstBisector();
1613       else
1614         previousbisector = firstbisectortoremove[bisectornumber]
1615       ->LastBisector();
1616     }
1617
1618     distant = distance[bisectornumber];
1619     while(!previousbisector->List()->IsEmpty()) {
1620
1621       if(bisectornumber == 0)
1622         previousbisector = previousbisector->FirstBisector();
1623       else
1624         previousbisector = previousbisector->LastBisector();
1625
1626       if(aside == 1 || (aside == 0 && bisectornumber == 0)) {
1627         saveparameter = previousbisector->FirstParameter();
1628         distant = atool.IntersectBisector
1629           (firstbisector,previousbisector,intersectionpoint);
1630         previousbisector->FirstParameter(saveparameter);
1631       }
1632       else {
1633         saveparameter = previousbisector->SecondParameter();
1634         distant = atool.IntersectBisector
1635           (previousbisector,secondbisector,intersectionpoint);
1636         previousbisector->SecondParameter(saveparameter);
1637       }
1638
1639       if(distant < Precision::Infinite()) {
1640         distance[bisectornumber] = distant;
1641         lastbisectortoremove[bisectornumber] = lastbisector;
1642       }
1643
1644       lastbisector = previousbisector;
1645     }
1646   }
1647
1648   //---------------------------------------
1649   // Chargement des bissectrices a effacer.
1650   //---------------------------------------
1651
1652   LoadBisectorsToRemove(noofbisectortoremove,
1653     distance[0],distance[1],
1654     firstbisectortoremove[0],firstbisectortoremove[1],
1655     lastbisectortoremove[0] ,lastbisectortoremove[1]);
1656 }
1657
1658 //========================================================================
1659 //  function : Init
1660 //  purpose  :
1661 //========================================================================
1662 void MAT2d_Mat2d::Init()
1663 {
1664   roots->First();
1665 }
1666
1667 //========================================================================
1668 //  function : More
1669 //  purpose  :
1670 //========================================================================
1671 Standard_Boolean MAT2d_Mat2d::More() const
1672 {
1673   return roots->More();
1674 }
1675
1676 //========================================================================
1677 //  function : Next
1678 //  purpose  :
1679 //========================================================================
1680 void MAT2d_Mat2d::Next()
1681 {
1682   roots->Next();
1683 }
1684
1685 //========================================================================
1686 //  function : Bisector 
1687 //  purpose  :
1688 //========================================================================
1689 Handle(MAT_Bisector) MAT2d_Mat2d::Bisector() const
1690 {
1691   return roots->Current();
1692 }
1693
1694 //========================================================================
1695 //  function : NumberOfBisectors
1696 //  purpose  :
1697 //========================================================================
1698 Standard_Integer MAT2d_Mat2d::NumberOfBisectors() const
1699 {
1700   return thenumberofbisectors;
1701 }
1702
1703 //========================================================================
1704 //  function : SemiInfinite
1705 //  purpose  :
1706 //========================================================================
1707 Standard_Boolean MAT2d_Mat2d::SemiInfinite() const
1708 {
1709   return semiInfinite;
1710 }
1711
1712 //========================================================================
1713 //  function : IsDone
1714 //  purpose  :
1715 //========================================================================
1716 Standard_Boolean MAT2d_Mat2d::IsDone() const
1717 {
1718   return isDone;
1719 }
1720
1721 //=======================================================================
1722 //function : ~MAT2d_Mat2d
1723 //purpose  : 
1724 //=======================================================================
1725
1726 MAT2d_Mat2d::~MAT2d_Mat2d()
1727 {
1728   MAT_DataMapIteratorOfDataMapOfIntegerBisector itmap(bisectormap);
1729   for (; itmap.More(); itmap.Next())
1730   {
1731     Handle(MAT_Bisector) aBisector = itmap.Value();
1732     aBisector->FirstEdge(NULL);
1733     aBisector->SecondEdge(NULL);
1734   }
1735
1736   if (!theedgelist.IsNull())
1737   {
1738     theedgelist->First();
1739     for (Standard_Integer i = 1; i <= theedgelist->Number(); i++)
1740     {
1741       Handle(MAT_Edge) anEdge = theedgelist->Current();
1742       anEdge->FirstBisector(NULL);
1743       anEdge->SecondBisector(NULL);
1744       theedgelist->Next();
1745     }
1746   }
1747   if (!RemovedEdgesList.IsNull())
1748   {
1749     RemovedEdgesList->First();
1750     for (Standard_Integer i = 1; i <= RemovedEdgesList->Number(); i++)
1751     {
1752       Handle(MAT_Edge) anEdge = RemovedEdgesList->Current();
1753       anEdge->FirstBisector(NULL);
1754       anEdge->SecondBisector(NULL);
1755       RemovedEdgesList->Next();
1756     }
1757   }
1758 }