0022312: Translation of french commentaries in OCCT files
[occt.git] / src / BRepAlgo / BRepAlgo_Loop.cxx
1 // File:        BRepAlgo_Loop.cxx
2 // Created:     Fri Nov 10 16:25:22 1995
3 // Author:      Yves FRICAUD
4 //              <yfr@stylox>
5
6 #include <stdio.h>
7
8 #include <BRepAlgo_Loop.ixx>
9
10 #include <BRep_Builder.hxx>
11 #include <BRepAlgo_FaceRestrictor.hxx>
12 #include <BRep_Tool.hxx>
13
14 #include <Geom2d_Curve.hxx>
15 #include <Geom_Surface.hxx>
16 #include <TopExp.hxx>
17 #include <TopTools_SequenceOfShape.hxx>
18 #include <TopTools_MapOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
21
22 #include <TopoDS.hxx>
23 #include <TopoDS_Vertex.hxx>
24 #include <TopoDS_Wire.hxx>
25 #include <gp_Pnt.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <Precision.hxx>
28 #include <BRep_TVertex.hxx>
29 #include <BRep_TEdge.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
33
34 #ifdef DRAW
35 #include <DBRep.hxx>
36 #endif
37 #ifdef DEB
38 Standard_Boolean AffichLoop  = Standard_False;
39 Standard_Integer NbLoops     = 0;
40 Standard_Integer NbWires     = 1;
41 static char* name = new char[100];
42 #endif
43
44 //=======================================================================
45 //function : BRepAlgo_Loop
46 //purpose  : 
47 //=======================================================================
48
49 BRepAlgo_Loop::BRepAlgo_Loop()
50 {
51 }
52
53
54 //=======================================================================
55 //function : Init
56 //purpose  : 
57 //=======================================================================
58
59 void BRepAlgo_Loop::Init(const TopoDS_Face& F)
60 {
61   myConstEdges.Clear(); 
62   myVerOnEdges.Clear();
63   myNewWires  .Clear();
64   myNewFaces  .Clear();
65   myNewEdges  .Clear();
66   myFace = F;
67 }
68
69
70 //=======================================================================
71 //function : Bubble
72 //purpose  : Orders the sequence of vertices by increasing parameter. 
73 //=======================================================================
74
75 static void Bubble(const TopoDS_Edge&        E,
76                    TopTools_SequenceOfShape& Seq) 
77 {
78   Standard_Boolean Invert   = Standard_True;
79   Standard_Integer NbPoints = Seq.Length();
80   Standard_Real    U1,U2;
81   TopoDS_Vertex    V1,V2;
82
83   while (Invert) {
84     Invert = Standard_False;
85     for ( Standard_Integer i = 1; i < NbPoints; i++) {
86       TopoDS_Shape aLocalV = Seq.Value(i)  .Oriented(TopAbs_INTERNAL);
87       V1 = TopoDS::Vertex(aLocalV);
88       aLocalV = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
89       V2 = TopoDS::Vertex(aLocalV);
90 //      V1 = TopoDS::Vertex(Seq.Value(i)  .Oriented(TopAbs_INTERNAL));
91 //      V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
92
93       U1 = BRep_Tool::Parameter(V1,E);
94       U2 = BRep_Tool::Parameter(V2,E);
95       if (U2 < U1) {
96         Seq.Exchange(i,i+1);
97         Invert = Standard_True;
98       }
99     }
100   }
101 }
102
103
104
105 //=======================================================================
106 //function : AddEdges
107 //purpose  : 
108 //=======================================================================
109
110 void BRepAlgo_Loop::AddEdge (TopoDS_Edge&                E, 
111                              const TopTools_ListOfShape& LV)
112 {
113   myVerOnEdges.Bind(E,LV);
114 }
115
116
117 //=======================================================================
118 //function : AddConstEdges
119 //purpose  : 
120 //=======================================================================
121
122 void BRepAlgo_Loop::AddConstEdge (const TopoDS_Edge& E)
123 {
124   myConstEdges.Append(E);
125 }
126
127 //=======================================================================
128 //function : AddConstEdges
129 //purpose  : 
130 //=======================================================================
131
132 void BRepAlgo_Loop::AddConstEdges(const TopTools_ListOfShape& LE)
133 {
134   TopTools_ListIteratorOfListOfShape itl(LE);
135   for (; itl.More(); itl.Next()) {
136     myConstEdges.Append(itl.Value());
137   }
138 }
139
140
141 //=======================================================================
142 //function : UpdateClosedEdge
143 //purpose  : If the first or the last vertex of intersection
144 //           coincides with the closing vertex, it is removed from SV.
145 //           it will be added at the beginning and the end of SV by the caller.
146 //=======================================================================
147
148 static TopoDS_Vertex  UpdateClosedEdge(const TopoDS_Edge&         E,
149                                        TopTools_SequenceOfShape&  SV)
150 {
151   TopoDS_Vertex    VB [2], V1, V2, VRes;
152   gp_Pnt           P,PC;
153   Standard_Boolean OnStart = 0, OnEnd = 0;
154   //// modified by jgv, 13.04.04 for OCC5634 ////
155   TopExp::Vertices (E,V1,V2);
156   //Standard_Real    Tol = Precision::Confusion();
157   Standard_Real    Tol = BRep_Tool::Tolerance( V1 );
158   ///////////////////////////////////////////////
159   
160   if (SV.IsEmpty()) return VRes;
161
162   VB[0] = TopoDS::Vertex(SV.First());
163   VB[1] = TopoDS::Vertex(SV.Last ());
164   PC = BRep_Tool::Pnt(V1);
165
166   for ( Standard_Integer i = 0 ; i < 2 ; i++) {
167     P = BRep_Tool::Pnt(VB [i]);
168     if (P.IsEqual(PC,Tol)) {
169       VRes = VB [i];
170       if (i == 0) OnStart = Standard_True;
171       else        OnEnd   = Standard_True;
172     }
173   }
174   if (OnStart && OnEnd) {
175     if (!VB[0].IsSame(VB[1])) {
176 #ifdef DEB
177       if (AffichLoop)
178         cout <<"Two different vertices on the closing vertex"<<endl;
179 #endif
180     }
181     else {
182       SV.Remove(1);
183       if (!SV.IsEmpty()) SV.Remove(SV.Length());
184     }
185   }
186   else if (OnStart) SV.Remove(1);
187   else if (OnEnd  ) SV.Remove(SV.Length());
188
189   return VRes;
190 }
191
192
193
194 //=======================================================================
195 //function : RemovePendingEdges
196 //purpose  : 
197 //=======================================================================
198
199 static void RemovePendingEdges(TopTools_DataMapOfShapeListOfShape& MVE)
200 {
201   //--------------------------------
202   // Remove hanging edges.
203   //--------------------------------
204   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
205   TopTools_ListOfShape                     ToRemove;
206   TopTools_ListIteratorOfListOfShape       itl;
207   Standard_Boolean                         YaSupress = Standard_True;
208   TopoDS_Vertex                            V1,V2;
209   
210   while (YaSupress) {
211     YaSupress = Standard_False;
212     TopTools_ListOfShape VToRemove;
213     TopTools_MapOfShape  EToRemove;
214
215     for (Mapit.Initialize(MVE); Mapit.More(); Mapit.Next()) {
216
217       if (Mapit.Value().IsEmpty()) {
218         VToRemove.Append(Mapit.Key());
219       }
220       if (Mapit.Value().Extent() == 1) {
221         const TopoDS_Edge& E = TopoDS::Edge(Mapit.Value().First());
222         TopExp::Vertices(E,V1,V2) ;
223         if (!V1.IsSame(V2)) {
224           VToRemove.Append(Mapit.Key());
225           EToRemove.Add(Mapit.Value().First());
226         }
227       }
228     }
229     
230     if (!VToRemove.IsEmpty()) {
231       YaSupress = Standard_True;
232       for (itl.Initialize(VToRemove); itl.More(); itl.Next()) {
233         MVE.UnBind(itl.Value());
234       }
235       if (!EToRemove.IsEmpty()) {
236         for (Mapit.Initialize(MVE); Mapit.More(); Mapit.Next()) {
237           TopTools_ListOfShape& LE = MVE.ChangeFind(Mapit.Key());
238           itl.Initialize(LE);
239           while (itl.More()) {
240             if (EToRemove.Contains(itl.Value())) {
241               LE.Remove(itl);
242             }
243             else itl.Next();
244           }
245         }
246       }
247     } 
248   }
249 }
250 //=======================================================================
251 //function : SamePnt2d
252 //purpose  : 
253 //=======================================================================
254
255 static Standard_Boolean  SamePnt2d(TopoDS_Vertex  V,
256                                    TopoDS_Edge&   E1,
257                                    TopoDS_Edge&   E2,
258                                    TopoDS_Face&   F)
259 {
260   Standard_Real   f1,f2,l1,l2;
261   gp_Pnt2d        P1,P2;
262   TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
263   TopoDS_Face FF = TopoDS::Face(aLocalF);
264 //  TopoDS_Face FF = TopoDS::Face(F.Oriented(TopAbs_FORWARD));
265   Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);  
266   Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);  
267   if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
268   else                                     P1 = C1->Value(l1);
269   
270   if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
271   else                                     P2 = C2->Value(f2);
272   Standard_Real Tol  = 100*BRep_Tool::Tolerance(V);
273   Standard_Real Dist = P1.Distance(P2);
274   return Dist < Tol; 
275 }
276
277 //=======================================================================
278 //function : SelectEdge
279 //purpose  : Find edge <NE> connected to <CE> by vertex <CV> in the
280 //           list <LE>. <NE> is removed from the list. If <CE> is 
281 //           also in the list <LE> with the same orientation, it is
282 //           removed from the list.
283 //=======================================================================
284
285 static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
286                                     const TopoDS_Edge&    CE,
287                                     const TopoDS_Vertex&  CV,
288                                     TopoDS_Edge&          NE,
289                                     TopTools_ListOfShape& LE)
290 {
291   TopTools_ListIteratorOfListOfShape itl;
292   NE.Nullify();
293 #ifdef DEB  
294   if (AffichLoop) {
295     if ( LE.Extent() > 2) {
296       cout <<"vertex on more than 2 edges in a face."<<endl;
297     }
298   }
299 #endif
300   for ( itl.Initialize(LE); itl.More(); itl.Next()) {
301     if (itl.Value().IsEqual(CE)) {
302       LE.Remove(itl);
303       break;
304     }
305   }
306   if (LE.Extent() > 1) {
307     //--------------------------------------------------------------
308     // Several edges possible.  
309     // - Test edges different from CE , Selection of edge
310     // for which CV has U,V closer to the face
311     // than corresponding to CE.
312     // - If several edges give representation less than the tolerance.
313     // discrimination on tangents.
314     //--------------------------------------------------------------
315     TopLoc_Location L;
316     Standard_Real   f,l;
317     TopoDS_Face FForward = F;
318     FForward.Orientation(TopAbs_FORWARD);
319
320     Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(CE,FForward,f,l);
321     Standard_Integer k = 1, kmin = 0;
322     Standard_Real    dist,distmin  = 100*BRep_Tool::Tolerance(CV);
323     Standard_Real    u ;
324     if (CE.Orientation () == TopAbs_FORWARD) u = l;
325     else                                     u = f;
326
327     gp_Pnt2d         P2,PV = C->Value(u); 
328     
329     for ( itl.Initialize(LE); itl.More(); itl.Next()) {
330       const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
331       if (!E.IsSame(CE)) {
332         C    = BRep_Tool::CurveOnSurface(E,FForward,f,l);
333         if (E.Orientation () == TopAbs_FORWARD) u = f;
334         else                                    u = l;
335         P2   = C->Value(u); 
336         dist = PV.Distance(P2);
337         if ( dist <= distmin) {
338           kmin    = k;
339           distmin = dist;
340         }
341       }
342       k++;
343     }
344     if (kmin == 0) return Standard_False;
345
346     k = 1; itl.Initialize(LE);
347     while (k < kmin) {k++; itl.Next();}
348     NE = TopoDS::Edge(itl.Value());
349     LE.Remove(itl);
350   }
351   else if (LE.Extent() == 1) {
352     NE = TopoDS::Edge(LE.First());
353     LE.RemoveFirst();
354   }
355   else {
356     return Standard_False;
357   }
358 #ifdef DRAW
359   if (AffichLoop) {  
360     DBRep::Set("Selected",NE);
361   }
362
363 #endif
364   return Standard_True;
365 }
366 //=======================================================================
367 //function : Store
368 //purpose  : 
369 //=======================================================================
370
371 static void  PurgeNewEdges(TopTools_DataMapOfShapeListOfShape& NewEdges,
372                            const TopTools_MapOfShape&          UsedEdges)
373 {
374   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(NewEdges);
375   for (; it.More(); it.Next()) {
376     TopTools_ListOfShape& LNE = NewEdges.ChangeFind(it.Key());
377     TopTools_ListIteratorOfListOfShape itL(LNE);
378     while (itL.More()) {
379       const TopoDS_Shape& NE = itL.Value();
380       if (!UsedEdges.Contains(NE)) {
381         LNE.Remove(itL);
382       }
383       else {
384         itL.Next();
385       }
386     }
387   }
388   
389 }
390
391 //=======================================================================
392 //function : Store
393 //purpose  : 
394 //=======================================================================
395
396 static void StoreInMVE (const TopoDS_Face&                  F,
397                         TopoDS_Edge&                  E,
398                         TopTools_DataMapOfShapeListOfShape& MVE,
399                         Standard_Boolean&                   YaCouture,
400                         TopTools_DataMapOfShapeShape& VerticesForSubstitute )
401 {      
402   TopoDS_Vertex V1, V2, V;
403   TopTools_ListOfShape Empty;
404   
405   Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
406 //  gp_Pnt P1, P2, P;
407   gp_Pnt P1, P;
408   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
409   BRep_Builder BB;
410   for (Mapit.Initialize( MVE ); Mapit.More(); Mapit.Next())
411     {
412       V = TopoDS::Vertex( Mapit.Key() );
413       P = BRep_Tool::Pnt( V );
414       TopTools_ListOfShape VList;
415       TopoDS_Iterator VerExp( E );
416       for (; VerExp.More(); VerExp.Next())
417         VList.Append( VerExp.Value() );
418       TopTools_ListIteratorOfListOfShape itl( VList );
419       for (; itl.More(); itl.Next())
420         {
421           V1 = TopoDS::Vertex( itl.Value() );
422           P1 = BRep_Tool::Pnt( V1 );
423           if (P.IsEqual( P1, Tol ) && !V.IsSame(V1))
424             {
425               V.Orientation( V1.Orientation() );
426               if (VerticesForSubstitute.IsBound( V1 ))
427                 {
428                   TopoDS_Shape OldNewV = VerticesForSubstitute( V1 );
429                   if (! OldNewV.IsSame( V ))
430                     {
431                       VerticesForSubstitute.Bind( OldNewV, V );
432                       VerticesForSubstitute( V1 ) = V;
433                     }
434                 }
435               else
436                 {
437                   if (VerticesForSubstitute.IsBound( V ))
438                     {
439                       TopoDS_Shape NewNewV = VerticesForSubstitute( V );
440                       if (! NewNewV.IsSame( V1 ))
441                         VerticesForSubstitute.Bind( V1, NewNewV );
442                     }
443                   else
444                     {
445                       VerticesForSubstitute.Bind( V1, V );
446                       TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( VerticesForSubstitute );
447                       for (; mapit.More(); mapit.Next())
448                         if (mapit.Value().IsSame( V1 ))
449                           VerticesForSubstitute( mapit.Key() ) = V;
450                     }
451                 }
452               E.Free( Standard_True );
453               BB.Remove( E, V1 );
454               BB.Add( E, V );
455             }
456         }
457     }
458
459   TopExp::Vertices(E,V1,V2);
460   if( V1.IsNull() && V2.IsNull() ){ YaCouture = Standard_False; return; }
461   if (!MVE.IsBound(V1)) {
462     MVE.Bind(V1,Empty);
463   }
464   MVE(V1).Append(E);
465   if (!V1.IsSame(V2)) {
466      if (!MVE.IsBound(V2)) {
467       MVE.Bind(V2,Empty);
468     }
469     MVE(V2).Append(E);
470   }
471   TopLoc_Location L ;
472   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
473   if (BRep_Tool::IsClosed(E,S,L)) {
474     MVE(V2).Append(E.Reversed());
475     if (!V1.IsSame(V2)) {
476       MVE(V1).Append(E.Reversed());
477     }
478     YaCouture = Standard_True;
479   }
480 }
481
482 //=======================================================================
483 //function : Perform
484 //purpose  : 
485 //=======================================================================
486
487 void BRepAlgo_Loop::Perform()
488 {
489   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;  
490   TopTools_ListIteratorOfListOfShape                  itl;
491   TopoDS_Vertex                                       V1,V2;
492   Standard_Boolean                                    YaCouture = Standard_False;
493
494 #ifdef DEB
495   if (AffichLoop) {
496     cout <<"NewLoop"<<endl;
497     Standard_Integer NbEdges = 1;
498     NbLoops++;
499 #ifdef DRAW
500     sprintf(name,"FLoop_%d",NbLoops);
501     DBRep::Set(name,myFace);
502 #endif
503     for (Mapit.Initialize(myVerOnEdges); Mapit.More(); Mapit.Next()) { 
504       const TopoDS_Edge& E = TopoDS::Edge(Mapit.Key());
505 #ifdef DRAW
506       sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++);
507       DBRep::Set(name,E);
508 #endif
509     }
510     for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
511       const TopoDS_Edge& E = TopoDS::Edge(itl.Value());    
512 #ifdef DRAW
513       sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++);
514       DBRep::Set(name,E);
515 #endif
516     }
517   }
518 #endif
519   
520   //------------------------------------------------
521   // Cut edges
522   //------------------------------------------------
523   for (Mapit.Initialize(myVerOnEdges); Mapit.More(); Mapit.Next()) {
524     TopTools_ListOfShape LCE;
525
526     CutEdge (TopoDS::Edge(Mapit.Key()),Mapit.Value(), LCE);
527
528     myNewEdges.Bind(Mapit.Key(),LCE);
529   }
530   //-----------------------------------
531   // Construction map vertex => edges
532   //-----------------------------------
533   TopTools_DataMapOfShapeListOfShape MVE;
534
535   // add cut edges.
536   for (Mapit.Initialize(myNewEdges); Mapit.More(); Mapit.Next()) {
537     for (itl.Initialize(myNewEdges(Mapit.Key())); itl.More(); itl.Next()) {
538       TopoDS_Edge& E = TopoDS::Edge(itl.Value());
539       StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
540     }
541   }
542   
543   // add const edges
544   // Sewn edges can be doubled or not in myConstEdges
545   // => call only once StoreInMVE which should double them
546   TopTools_MapOfShape DejaVu;
547   for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
548     TopoDS_Edge& E = TopoDS::Edge(itl.Value());
549     if (DejaVu.Add(E))
550       StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
551   }
552
553 #ifdef DRAW
554   if (AffichLoop) {
555     cout <<"NewLoop"<<endl;
556     Standard_Integer NbEdges = 1;
557     TopTools_MapOfShape Done;
558     for (Mapit.Initialize(MVE); Mapit.More();Mapit.Next()) {
559       for (itl.Initialize(Mapit.Value()); itl.More(); itl.Next()) {
560         TopoDS_Edge& E = TopoDS::Edge(itl.Value());
561         if (Done.Add(E)) {
562           sprintf(name,"EEC_%d_%d",NbLoops,NbEdges++);
563           DBRep::Set(name,E);
564         }
565       }
566     }
567   }
568 #endif
569
570   //-----------------------------------------------
571   // Construction of wires and new faces. 
572   //----------------------------------------------
573   TopoDS_Vertex    VF,VL,CV;
574   TopoDS_Edge      CE,NE,EF;
575   BRep_Builder     B;
576   TopoDS_Wire      NW;
577   Standard_Boolean End;
578
579   TopTools_MapOfShape UsedEdges;
580
581   while (!MVE.IsEmpty()) {
582     B.MakeWire(NW);
583     //--------------------------------
584     // Removal of hanging edges.
585     //--------------------------------
586     RemovePendingEdges(MVE);
587
588     if (MVE.IsEmpty()) break; 
589     //--------------------------------
590     // Start edge.
591     //--------------------------------
592     Mapit.Initialize(MVE);
593     EF = CE = TopoDS::Edge(Mapit.Value().First());
594     TopExp::Vertices(CE,V1,V2);
595     //--------------------------------
596     // VF vertex start of new wire
597     //--------------------------------
598     if (CE.Orientation() == TopAbs_FORWARD) { CV = VF = V1;}
599     else                                    { CV = VF = V2;}
600     if (!MVE.IsBound(CV)) continue;
601     for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
602       if (itl.Value().IsEqual(CE)) {
603         MVE(CV).Remove(itl);
604         break;
605       }
606     }
607     End  = Standard_False;
608     
609     while (!End) {
610       //-------------------------------
611       // Construction of a wire.
612       //-------------------------------
613       TopExp::Vertices(CE,V1,V2);
614       if (!CV.IsSame(V1)) CV = V1; else CV = V2;
615
616       B.Add (NW,CE);
617       UsedEdges.Add(CE);
618
619       if (!MVE.IsBound(CV) || MVE(CV).IsEmpty()) {
620         End = Standard_True;
621       }
622       else {
623         End = !SelectEdge(myFace,CE,CV,NE,MVE(CV));
624         if (!End) {
625           CE = NE;
626           if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
627         }       
628       }
629     }
630     //--------------------------------------------------
631     // Add new wire to the set of wires
632     //------------------------------------------------
633     Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
634     TopExp_Explorer explo( NW, TopAbs_VERTEX );
635     for (; explo.More(); explo.Next())
636       {
637         const TopoDS_Vertex& aV = TopoDS::Vertex( explo.Current() );
638         Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &(aV).TShape());
639         TV->Tolerance( Tol );
640         TV->Modified( Standard_True );
641       }
642     for (explo.Init( NW, TopAbs_EDGE ); explo.More(); explo.Next())
643       {
644         const TopoDS_Edge& aE = TopoDS::Edge( explo.Current() );
645         Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &(aE).TShape());
646         TE->Tolerance( Tol );
647         TE->Modified( Standard_True );
648       }
649
650     if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace))
651       myNewWires.Append (NW);
652     else {
653 #ifdef DEB
654       cout <<"BRepAlgo_Loop: Open Wire"<<endl;
655       if (AffichLoop)
656         cout << "OpenWire is : NW_"<<NbLoops<<"_"<<NbWires<<endl;
657 #endif
658     }
659 #ifdef DRAW
660     if (AffichLoop) {
661       sprintf(name,"NW_%d_%d",NbLoops,NbWires++);       
662       DBRep::Set(name,NW);
663     }
664 #endif
665   }
666   
667   PurgeNewEdges(myNewEdges,UsedEdges);
668 }
669
670 //=======================================================================
671 //function : CutEdges
672 //purpose  : 
673 //=======================================================================
674
675 void BRepAlgo_Loop::CutEdge (const TopoDS_Edge&          E,
676                              const TopTools_ListOfShape& VOnE,
677                                      TopTools_ListOfShape& NE   ) const 
678 {
679   TopoDS_Shape aLocalE  = E.Oriented(TopAbs_FORWARD);
680   TopoDS_Edge WE = TopoDS::Edge(aLocalE);
681 //  TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
682
683   Standard_Real                      U1,U2;
684   TopoDS_Vertex                      V1,V2;
685   TopTools_SequenceOfShape           SV;
686   TopTools_ListIteratorOfListOfShape it(VOnE);
687   BRep_Builder                       B;
688
689   for ( ; it.More(); it.Next()) {
690     SV.Append(it.Value());
691   }
692   //--------------------------------
693   // Parse vertices on the edge.
694   //--------------------------------
695   Bubble (WE,SV);
696
697   Standard_Integer NbVer = SV.Length();
698   //----------------------------------------------------------------
699   // Construction of new edges.
700   // Note :  vertices at the extremities of edges are not 
701   //         onligatorily in the list of vertices
702   //----------------------------------------------------------------
703   if (SV.IsEmpty()) {
704     NE.Append(E);
705     return;
706   }
707   TopoDS_Vertex    VF,VL;
708   Standard_Real    f,l;
709   BRep_Tool::Range(WE,f,l);
710   TopExp::Vertices(WE,VF,VL);
711
712   if (NbVer == 2) {
713     if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
714       NE.Append(E);
715 #ifdef DRAW
716       if (AffichLoop) {  
717       DBRep::Set("ECOpied",E);
718     }      
719 #endif
720       return;
721     }
722   }
723   //----------------------------------------------------
724   // Processing of closed edges 
725   // If a vertex of intersection is on the common vertex
726   // it should appear at the beginning and end of SV.
727   //----------------------------------------------------
728   TopoDS_Vertex VCEI;
729   if (!VF.IsNull() && VF.IsSame(VL)) {
730     VCEI = UpdateClosedEdge(WE,SV);    
731     if (!VCEI.IsNull()) {
732       TopoDS_Shape aLocalV = VCEI.Oriented(TopAbs_FORWARD);
733       VF = TopoDS::Vertex(aLocalV);
734       aLocalV = VCEI.Oriented(TopAbs_REVERSED); 
735       VL = TopoDS::Vertex(aLocalV);
736 //      VF = TopoDS::Vertex(VCEI.Oriented(TopAbs_FORWARD));
737 //      VL = TopoDS::Vertex(VCEI.Oriented(TopAbs_REVERSED)); 
738     }
739     SV.Prepend(VF);
740     SV.Append(VL);
741   }
742   else {
743     //-----------------------------------------
744     // Eventually all extremities of the edge.
745     //-----------------------------------------
746     if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
747     if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
748   }
749
750   while (!SV.IsEmpty()) {
751     while (!SV.IsEmpty() && 
752            SV.First().Orientation() != TopAbs_FORWARD) {
753       SV.Remove(1);
754     }
755     if (SV.IsEmpty())
756       break;
757     V1  = TopoDS::Vertex(SV.First());
758     SV.Remove(1);
759     if (SV.IsEmpty())
760       break;
761     if (SV.First().Orientation() == TopAbs_REVERSED) {
762       V2  = TopoDS::Vertex(SV.First());
763       SV.Remove(1);
764       //-------------------------------------------
765       // Copy the edge and restriction by V1 V2.
766       //-------------------------------------------
767       TopoDS_Shape NewEdge = WE.EmptyCopied();
768       TopoDS_Shape aLocalEdge = V1.Oriented(TopAbs_FORWARD);
769       B.Add  (NewEdge,aLocalEdge);
770       aLocalEdge = V2.Oriented(TopAbs_REVERSED);
771       B.Add  (TopoDS::Edge(NewEdge),aLocalEdge);
772 //      B.Add  (NewEdge,V1.Oriented(TopAbs_FORWARD));
773 //      B.Add  (NewEdge,V2.Oriented(TopAbs_REVERSED));
774       if (V1.IsSame(VF)) 
775         U1 = f;
776       else 
777 //      U1=BRep_Tool::Parameter
778 //        (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
779         {
780           TopoDS_Shape aLocalV = V1.Oriented(TopAbs_INTERNAL);
781           U1=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE);
782         }
783       if (V2.IsSame(VL))
784         U2 = l;
785       else
786         {
787           TopoDS_Shape aLocalV = V2.Oriented(TopAbs_INTERNAL);
788           U2=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE);
789 //      U2=BRep_Tool::Parameter
790 //        (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
791         }
792       B.Range (TopoDS::Edge(NewEdge),U1,U2);
793 #ifdef DRAW
794     if (AffichLoop) {  
795       DBRep::Set("Cut",NewEdge);
796     }
797 #endif
798       NE.Append(NewEdge.Oriented(E.Orientation()));
799     }
800   }
801
802   //Remove edges with size <= tolerance
803   Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
804   it.Initialize(NE);
805   while (it.More())
806     {
807       // skl : I change "E" to "EE"
808       TopoDS_Edge EE = TopoDS::Edge( it.Value() );
809       Standard_Real fpar, lpar;
810       BRep_Tool::Range( EE, fpar, lpar );
811       if (lpar - fpar <= Precision::Confusion())
812         NE.Remove(it);
813       else
814         {
815           gp_Pnt2d pf, pl;
816           BRep_Tool::UVPoints( EE, myFace, pf, pl );
817           if (pf.Distance(pl) <= Tol && !EE.Closed())
818             NE.Remove(it);
819           else
820             it.Next();
821         }
822     }
823 }
824
825 //=======================================================================
826 //function : NewWires
827 //purpose  : 
828 //=======================================================================
829
830 const TopTools_ListOfShape&  BRepAlgo_Loop::NewWires() const 
831 {  
832   return myNewWires;
833 }
834
835 //=======================================================================
836 //function : NewFaces
837 //purpose  : 
838 //=======================================================================
839
840 const TopTools_ListOfShape&  BRepAlgo_Loop::NewFaces() const 
841 {  
842   return myNewFaces;
843 }
844  
845 //=======================================================================
846 //function : WiresToFaces
847 //purpose  : 
848 //=======================================================================
849
850 void  BRepAlgo_Loop::WiresToFaces() 
851 {  
852   if (!myNewWires.IsEmpty()) {
853     BRepAlgo_FaceRestrictor FR;
854     TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
855     FR.Init (TopoDS::Face(aLocalS),Standard_False);
856 //    FR.Init (TopoDS::Face(myFace.Oriented(TopAbs_FORWARD)),
857 //           Standard_False);
858     TopTools_ListIteratorOfListOfShape it(myNewWires);
859     for (; it.More(); it.Next()) {
860       FR.Add(TopoDS::Wire(it.Value()));
861     }
862
863     FR.Perform();
864     
865     if (FR.IsDone()) {
866       TopAbs_Orientation OriF = myFace.Orientation();
867       for (; FR.More(); FR.Next()) {
868         myNewFaces.Append(FR.Current().Oriented(OriF));
869       }
870     }
871   }
872 }
873
874
875 //=======================================================================
876 //function : NewEdges
877 //purpose  : 
878 //=======================================================================
879
880 const TopTools_ListOfShape&  BRepAlgo_Loop::NewEdges(const TopoDS_Edge& E) const 
881 {
882   return myNewEdges(E);
883 }
884
885 //=======================================================================
886 //function : GetVerticesForSubstitute
887 //purpose  : 
888 //=======================================================================
889
890 void  BRepAlgo_Loop::GetVerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap ) const
891 {
892   VerVerMap = myVerticesForSubstitute;
893 }
894 //=======================================================================
895 //function : VerticesForSubstitute
896 //purpose  : 
897 //=======================================================================
898
899 void  BRepAlgo_Loop::VerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap )
900 {
901   myVerticesForSubstitute = VerVerMap;
902 }