6838b8ae7dbd21baf199ca867b877c9e55813b50
[occt.git] / src / LocOpe / LocOpe_Generator.cxx
1 // File:        LocOpe_Generator.cxx
2 // Created:     Tue Jan  9 13:57:18 1996
3 // Author:      Jacques GOUSSARD
4 //              <jag@bravox>
5 // Modifed:     Portage NT 7-5-97 DPF (return NewParameter)
6
7 #include <LocOpe_Generator.ixx>
8
9 #include <TopTools_MapOfShape.hxx>
10 #include <TopTools_DataMapOfShapeShape.hxx>
11 #include <TopTools_DataMapOfShapeListOfShape.hxx>
12 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
13 #include <TopTools_ListIteratorOfListOfShape.hxx>
14 #include <TopTools_MapIteratorOfMapOfShape.hxx>
15 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
16 #include <TopoDS_Iterator.hxx>
17 #include <TopoDS_Solid.hxx>
18 #include <TopoDS_Wire.hxx>
19 #include <TopoDS_Edge.hxx>
20 #include <TopoDS_Vertex.hxx>
21
22
23 #include <TopExp_Explorer.hxx>
24
25 #include <gp_Pln.hxx>
26 #include <gp_Cylinder.hxx>
27
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAlgo_Loop.hxx>
31
32 #include <Geom_Surface.hxx>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_Plane.hxx>
35 #include <Geom_CylindricalSurface.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_TrimmedCurve.hxx>
38 #include <Geom_Line.hxx>
39 #include <Geom_Circle.hxx>
40 #include <Geom2d_Curve.hxx>
41
42 #include <LocOpe_BuildShape.hxx>
43
44 #include <TopoDS.hxx>
45 #include <TopExp.hxx>
46 #include <BRepTools.hxx>
47 #include <GeomProjLib.hxx>
48 #include <ElCLib.hxx>
49 #include <Precision.hxx>
50
51 static Standard_Boolean ToFuse(const TopoDS_Face& ,
52                                const TopoDS_Face&);
53
54
55 static Standard_Boolean ToFuse(const TopoDS_Edge& ,
56                                const TopoDS_Edge&);
57
58
59 static Standard_Boolean ToFuse(const TopoDS_Edge&,
60                                const TopoDS_Face&,
61                                const TopoDS_Vertex&,
62                                const TopTools_MapOfShape&);
63
64 static Standard_Real NewParameter(const TopoDS_Edge&,
65                                   const TopoDS_Vertex&,
66                                   const TopoDS_Edge&,
67                                   const TopoDS_Vertex&);
68
69 #ifdef DEB
70 static Standard_Boolean Contains(const TopTools_ListOfShape&,
71                                  const TopoDS_Shape&);
72 #endif
73
74
75
76
77 //=======================================================================
78 //function : Perform
79 //purpose  : 
80 //=======================================================================
81
82 void LocOpe_Generator::Perform(const Handle(LocOpe_GeneratedShape)& G)
83 {
84   if (myShape.IsNull()) {
85     Standard_NullObject::Raise();
86   }
87   myDone = Standard_False;
88   myRes.Nullify();
89 //  myDescFaces.Clear();
90   myModShapes.Clear();
91 //  myFFromE.Clear();
92
93   const TopTools_ListOfShape& ledges = G->GeneratingEdges();
94
95   // On genere une liste des faces a gauche du wire. Equivalent du LeftOf.
96   // Attention : il faudra bien propager pour ne pas oublier des faces
97   // a l`interieur
98
99   TopExp_Explorer exp, exp2, exp3;
100   TopTools_MapOfShape theLeft; // Faces a gauche
101
102   TopTools_MapOfShape GEdg,GVtx; // Edges et vertex generateurs
103
104   TopTools_ListIteratorOfListOfShape itl,itl2;
105
106
107   for (itl.Initialize(ledges); itl.More(); itl.Next()) {
108     const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
109     
110     GEdg.Add(edg);
111     for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
112       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
113       if (!GVtx.Contains(vtx)) {
114         GVtx.Add(vtx);
115       }
116     }
117     for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
118       const TopoDS_Face& fac = TopoDS::Face(exp2.Current());
119       for (exp3.Init(fac,TopAbs_EDGE); exp3.More(); exp3.Next()) {
120         if (exp3.Current().IsSame(edg) && 
121             exp3.Current().Orientation() == edg.Orientation()) {
122           theLeft.Add(fac);
123           TopTools_ListOfShape emptylist;
124           if(!myModShapes.IsBound(fac)) {
125             myModShapes.Bind(fac,emptylist);
126           }  
127           break;
128         }
129       }
130       if (exp3.More()) {
131         break;
132       }
133     }
134   }
135
136   TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
137   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
138
139   TopTools_DataMapOfShapeListOfShape theEEMap;
140   TopTools_DataMapOfShapeListOfShape theFFMap;
141   TopTools_MapOfShape toRemove;
142   TopTools_MapIteratorOfMapOfShape itm;
143   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itf;
144
145   // recherche des fusions de faces
146   for (itm.Initialize(GEdg); itm.More(); itm.Next()) {
147     const TopoDS_Edge& edg = TopoDS::Edge(itm.Key());
148     if (!theEFMap.Contains(edg)) {
149       continue;
150     }
151     for (itl2.Initialize(theEFMap.FindFromKey(edg));itl2.More();itl2.Next()){
152       if (!theLeft.Contains(itl2.Value())) {
153         break;
154       }
155     }
156     if (!itl2.More()) { // edge "interne" au shell, ou bord libre
157     }
158     else {
159       const TopoDS_Face& fac = TopoDS::Face(itl2.Value());
160       TopoDS_Face facbis = G->Generated(edg);
161       if (ToFuse(fac,facbis)) {
162         // On recherche si une face a deja fusionne avec facbis
163         Standard_Boolean facbisfound = Standard_False;
164         for (itf.Initialize(theFFMap); itf.More(); itf.Next()) {
165           if (itf.Key().IsSame(fac)) {
166             continue;
167           }
168           for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
169             if (itl.Value().IsSame(facbis)) {
170               facbisfound = Standard_True;
171               break;
172             }
173           }
174           if (facbisfound) {
175             theFFMap(itf.Key()).Append(fac);
176             toRemove.Add(fac);
177             toRemove.Add(edg);
178             break;
179           }
180         }
181
182         if (!facbisfound) {
183           if (!theFFMap.IsBound(fac)) {
184             TopTools_ListOfShape thelist;
185             theFFMap.Bind(fac, thelist);
186           }
187           for (itl.Initialize(theFFMap(fac)); itl.More(); itl.Next()) {
188             if (itl.Value().IsSame(facbis)) {
189               break;
190             }
191           }
192           if (!itl.More()) {
193             theFFMap(fac).Append(facbis);
194           }
195           toRemove.Add(edg);
196           toRemove.Add(facbis);
197         }
198       }
199       else { // face generee par edg : on la marque.
200 //      myFFromE.Bind(edg,facbis);
201       }
202     }
203   }
204
205
206   // Il faut ici ajouter dans toRemove les edges de connexites entre faces
207   // a fusionner avec une meme face de base
208
209 //  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itf(theFFMap);
210   itf.Initialize(theFFMap);
211   for (; itf.More(); itf.Next()) {
212     for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
213       for (exp.Init(itl.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
214         const TopoDS_Edge& ed = TopoDS::Edge(exp.Current());
215         if (toRemove.Contains(ed)) {
216           continue;
217         }
218         for (itl2.Initialize(itf.Value()); itl2.More(); itl2.Next()) {
219           if (!itl2.Value().IsSame(itl.Value())) {
220             for (exp2.Init(itl2.Value(),TopAbs_EDGE);exp2.More();exp2.Next()) {
221               if (ed.IsSame(exp2.Current())) {
222                 toRemove.Add(ed);
223                 break;
224               }
225             }
226             if (exp2.More()) {
227               break;
228             }
229           }
230         }
231       }
232     }
233   }
234
235   TopTools_ListOfShape RebuildFace;
236   TopTools_MapOfShape mapTreated;
237   TopTools_DataMapOfShapeShape DontFuse;
238   TopAbs_Orientation orient,orface,orsav;
239
240   for (itf.Reset(); itf.More(); itf.Next()) {
241     const TopoDS_Face& fac = TopoDS::Face(itf.Key());
242     for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
243       const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
244       if (mapTreated.Contains(edg)) {
245         continue; // on saute l`edge
246       }
247
248       mapTreated.Add(edg);
249       for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
250         const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
251         if (GVtx.Contains(vtx)) {
252           TopoDS_Edge edgbis = G->Generated(vtx);
253
254           if ((edgbis.IsNull() || BRep_Tool::Degenerated(edgbis)) ||
255 //            toRemove.Contains(edgbis) ||
256               !ToFuse(edg,edgbis)) {
257             continue;
258           }
259 // a voir
260           if (BRepTools::IsReallyClosed(edg,fac)) {
261             if (!theEEMap.IsBound(edg)) {
262               TopTools_ListOfShape thelist1;
263               theEEMap.Bind(edg, thelist1);
264               theEEMap(edg).Append(edgbis);
265               toRemove.Add(edgbis); // toujours vrai pour edge double
266               Standard_Boolean FuseEdge = Standard_True;
267               TopoDS_Vertex Vf,Vl;
268               TopExp::Vertices(edg,Vf,Vl);
269               Standard_Boolean ConnectLast = (Vl.IsSame(vtx));
270               for (exp3.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
271                    exp3.More(); exp3.Next()) {
272                 const TopoDS_Edge& eee = TopoDS::Edge(exp3.Current());
273                 orient = eee.Orientation();
274                 if (!eee.IsSame(edg)) {
275                   TopExp::Vertices(eee,Vf,Vl);
276                   if ((Vf.IsSame(vtx) || Vl.IsSame(vtx)) &&
277                       !toRemove.Contains(eee)) {
278                     FuseEdge = Standard_False;
279                     // On recherche celui qu`il ne faut pas fusionner
280                     
281                     if ((Vf.IsSame(vtx) && orient == TopAbs_FORWARD) ||
282                         (Vl.IsSame(vtx) && orient == TopAbs_REVERSED)) {
283                       if (ConnectLast) {
284                         DontFuse.Bind(edg,fac.Oriented(TopAbs_FORWARD));
285                       }
286                       else {
287                         DontFuse.Bind(edg,fac.Oriented(TopAbs_REVERSED));
288                       }
289                     }
290                     else {
291                       if (ConnectLast) {
292                         DontFuse.Bind(edg,fac.Oriented(TopAbs_REVERSED));
293                       }
294                       else {
295                         DontFuse.Bind(edg,fac.Oriented(TopAbs_FORWARD));
296                       }
297                     }
298                     break;
299                   }
300                 }
301               }
302               if (FuseEdge) {
303                 toRemove.Add(vtx);
304               }
305             }
306           }
307
308
309           else {
310 /*  A VOIR
311           if (!BRep_Tool::IsClosed(edg,fac)) {
312 */          
313             if (!theEEMap.IsBound(edg)) {
314               TopTools_ListOfShape thelist2;
315               theEEMap.Bind(edg, thelist2);
316             }
317             theEEMap(edg).Append(edgbis);
318             const TopTools_ListOfShape& L = theEEMap(edg);
319             TopTools_ListIteratorOfListOfShape Lit(L);
320             Standard_Boolean OK = Standard_True;
321             for (; Lit.More(); Lit.Next()) {
322               if (Lit.Value().IsSame(edgbis)) {
323                 OK = Standard_False;
324                 break;
325               }
326             }
327             if (OK) theEEMap(edg).Append(edgbis);
328             
329             itl.Initialize(theEFMap.FindFromKey(edg));
330             Standard_Boolean FuseEdge = ToFuse(edg,fac,vtx,toRemove);
331             if (!FuseEdge) {
332               DontFuse.Bind(edg,fac);
333             }
334             else {
335               for (; itl.More(); itl.Next()) {
336                 if (!itl.Value().IsSame(fac)) {
337                   if (theFFMap.IsBound(itl.Value())) { 
338                     FuseEdge = ToFuse(edg,TopoDS::Face(itl.Value()),
339                                       vtx,toRemove);
340                     // edge a fusionner
341                     if (FuseEdge) {
342                       toRemove.Add(vtx);
343                     }
344                     else {
345                       if (toRemove.Contains(vtx)) {
346                         toRemove.Remove(vtx);
347                       }
348                       DontFuse.Bind(edg,itl.Value());
349                     }
350                   }
351                   else { // on marque comme face a reconstruire
352                     RebuildFace.Append(itl.Value());
353                     if (toRemove.Contains(vtx)) {
354                       toRemove.Remove(vtx);
355                     }
356                     DontFuse.Bind(edg,itl.Value());
357                   }
358                   
359                   break;
360                 }
361               }
362             }
363           }
364         }
365       }
366     }
367   }
368
369
370
371   for (itl.Initialize(RebuildFace); itl.More(); itl.Next()) {
372     TopTools_ListOfShape thelist3;
373     theFFMap.Bind(itl.Value(), thelist3);
374   }
375
376   BRep_Builder B;
377   TopoDS_Face newface;
378   TopoDS_Wire outw,newwire;
379   TopoDS_Edge newedg;
380   TopoDS_Vertex newvtx;
381   TopLoc_Location loc;
382   Standard_Real tol,prm,f,l, Uminc,Umaxc;;
383   gp_Pnt2d pf,pl;
384
385   Handle(Geom_Surface) S;
386   Handle(Geom_Plane) P;
387   Handle(Geom_Curve) C;
388
389   // Fusion des edges
390   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape ite(theEEMap);
391   for (; ite.More(); ite.Next()) {
392     Standard_Boolean KeepNewEdge = Standard_False;
393     const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
394     BRep_Tool::Range(edg,f,l);
395     TopoDS_Shape aLocalEdge = edg.EmptyCopied();
396     newedg = TopoDS::Edge(aLocalEdge);
397 //    newedg = TopoDS::Edge(edg.EmptyCopied());
398     newedg.Orientation(TopAbs_FORWARD);
399     for (exp.Init(edg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
400          exp.More(); exp.Next()) {
401       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
402       prm = BRep_Tool::Parameter(vtx,edg);
403
404       newvtx.Nullify();
405       for (itl.Initialize(theEEMap(edg)); itl.More(); itl.Next()) {
406         const TopoDS_Edge& edgbis = TopoDS::Edge(itl.Value());
407         for (exp2.Init(edgbis,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
408           if (exp2.Current().IsSame(vtx)) {
409             break;
410           }
411         }
412         if (exp2.More()) {
413           for (exp2.ReInit(); exp2.More(); exp2.Next()) {
414             if (!exp2.Current().IsSame(vtx)) {
415               newvtx = TopoDS::Vertex(exp2.Current());
416               prm = NewParameter(edg,vtx,newedg,newvtx);
417               break;
418             }
419           }
420           break;
421         }
422       }
423
424       if (toRemove.Contains(vtx) ||
425           (prm <l && prm > f)) {
426         B.Add(newedg,newvtx.Oriented(vtx.Orientation()));
427         tol = BRep_Tool::Tolerance(newvtx);
428         B.UpdateVertex(newvtx,prm,newedg,tol);
429         toRemove.Add(itl.Value()); // i-e edgbis
430         KeepNewEdge = Standard_True;
431       }
432       else {
433         B.Add(newedg,vtx.Oriented(vtx.Orientation()));
434         tol = BRep_Tool::Tolerance(vtx);
435         B.UpdateVertex(vtx,prm,newedg,tol);
436       }
437     }
438     if (KeepNewEdge) {
439       TopTools_ListOfShape emptylist;
440       if(!myModShapes.IsBound(edg)) {
441         myModShapes.Bind(edg,emptylist);
442       }  
443       myModShapes(edg).Append(newedg);
444       toRemove.Add(edg);
445     }
446   }
447
448   TopTools_MapOfShape EdgAdded;
449
450   // Fusion des faces, ou reconstruction
451   for (itf.Reset();itf.More(); itf.Next()) {
452     const TopoDS_Face& fac = TopoDS::Face(itf.Key());
453     Standard_Boolean ModFace = Standard_False;
454     Standard_Boolean HasWire = Standard_False;
455     TopTools_ListOfShape listofedg;
456
457     EdgAdded.Clear();
458
459     for(exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
460       if (exp.Current().IsSame(fac)) {
461         break;
462       }
463     }
464     orface = exp.Current().Orientation();
465     TopoDS_Shape aLocalFace = fac.EmptyCopied();
466     newface = TopoDS::Face(aLocalFace);
467 //    newface = TopoDS::Face(fac.EmptyCopied());
468     newface.Orientation(TopAbs_FORWARD);
469     S = BRep_Tool::Surface(fac);
470     if (S->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
471       S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
472     }
473     P = Handle(Geom_Plane)::DownCast(S);
474     TopoDS_Wire wir;
475     for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE); 
476          exp.More(); exp.Next()) {
477       wir = TopoDS::Wire(exp.Current());
478       for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
479         const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
480         if (toRemove.Contains(edg) || myModShapes.IsBound(edg) ) {
481           break;
482         }
483       }
484       if (!exp2.More()) { // wire non modifie
485 //      B.Add(newface,wir.Oriented(wir.Orientation()));
486         for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
487           listofedg.Append(exp2.Current());
488         }
489         HasWire = Standard_True;
490       }
491       else {
492         if (!ModFace) { 
493
494           // Petit truc crad pour les p-curves sur les cylindres...
495           if (P.IsNull()) {
496             Standard_Real Vminc,Vmaxc;
497             BRepTools::UVBounds(fac,Uminc,Umaxc,Vminc,Vmaxc);
498           }
499
500
501           // premier passage : on met les wires non touches des faces 
502           // en vis a vis
503
504           for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
505             TopoDS_Face facbis = TopoDS::Face(itl.Value());
506             for (itl2.Initialize(G->OrientedFaces());itl2.More();itl2.Next()) {
507               if (itl2.Value().IsSame(facbis)) {
508                 break;
509               }
510             }
511             if (itl2.More()) {
512               orient = itl2.Value().Orientation();
513               facbis.Orientation(orient);
514             }
515             else { // on fusionne avec une autre face du shape...
516               for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
517                 if (exp2.Current().IsSame(facbis)) {
518                   facbis.Orientation(exp2.Current().Orientation());
519                   break;
520                 }
521               }
522             }
523             
524             for (exp3.Init(facbis,TopAbs_WIRE); exp3.More(); exp3.Next()) {
525               for (exp2.Init(exp3.Current(),TopAbs_EDGE); 
526                    exp2.More(); exp2.Next()) {
527                 if (toRemove.Contains(exp2.Current())) {
528                   break;
529                 }
530               }
531               if (!exp2.More()) {
532                 TopoDS_Wire theNew;
533                 B.MakeWire(theNew); // FORWARD
534                 for (exp2.ReInit(); exp2.More(); exp2.Next()) {
535                   const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
536                   
537                   orient = TopAbs::Compose(orface,edg.Orientation());
538 //                B.Add(theNew,edg.Oriented(or));
539                   listofedg.Append(edg.Oriented(orient));
540                   EdgAdded.Add(edg);
541                   if (P.IsNull()) {  
542                     // on met les courbes 2d si on n`est pas sur un plan
543                     // on ne devrait pas avoir de pb d`edge de couture. 
544                     tol = BRep_Tool::Tolerance(edg);
545                     C = BRep_Tool::Curve(edg,loc,f,l);
546                     if (!loc.IsIdentity()) {
547                       Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
548                       C = *((Handle(Geom_Curve)*)&GG);
549                     }
550                     if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
551                       C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
552                     }
553                     
554                     Handle(Geom2d_Curve) C2d = GeomProjLib::Curve2d(C,f,l,S,tol);
555
556                     // Tentative de recalage dans la facette
557                     pf = C2d->Value(f);
558                     pl = C2d->Value(l);
559                     Standard_Real tttol = Precision::Angular();
560                     while (Min(pf.X(),pl.X()) >= Umaxc-tttol) {
561                       C2d->Translate(gp_Vec2d(-2.*M_PI,0));
562                       pf = C2d->Value(f);
563                       pl = C2d->Value(l);
564                     }
565
566                     while (Max(pf.X(),pl.X()) <= Uminc+tttol) {
567                       C2d->Translate(gp_Vec2d(2.*M_PI,0));
568                       pf = C2d->Value(f);
569                       pl = C2d->Value(l);
570                     }
571
572                     if (!BRepTools::IsReallyClosed(edg,facbis)) {
573                       B.UpdateEdge(edg,C2d,newface,tol);
574                     }
575                     //          else {
576                     //            cout << "Edge double bizarre... " << endl;
577                     //          }
578                   }
579                 }
580 //              B.Add(newface,theNew);
581                 HasWire = Standard_True;
582               }
583             }
584           }
585           ModFace = Standard_True;
586         }
587         
588         orsav = wir.Orientation();
589         // reconstruction du wire
590         //B.MakeWire(newwire);
591
592         Handle(Geom2d_Curve) C2d,C2d1;
593         Standard_Boolean EmptyWire = Standard_True;
594     
595 //      for (exp2.Init(wir.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
596         for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
597           const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
598           orient = edg.Orientation();
599           if (!toRemove.Contains(edg) && !theEEMap.IsBound(edg)) {
600 //          B.Add(newwire,edg.Oriented(or));
601 //            listofedg.Append(edg.Oriented(or));
602             listofedg.Append(edg);
603             EmptyWire = Standard_False;
604           }
605           else if (myModShapes.IsBound(edg) || theEEMap.IsBound(edg)) {
606             if (myModShapes.IsBound(edg)) {
607               newedg = TopoDS::Edge(myModShapes(edg).First());
608             }
609             else {
610               newedg = edg;
611             }
612 //          B.Add(newwire,newedg.Oriented(or));
613             listofedg.Append(newedg.Oriented(orient));
614             EmptyWire = Standard_False;
615             C = BRep_Tool::Curve(newedg,loc,f,l);
616             if (!loc.IsIdentity()) {
617               Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
618               C = *((Handle(Geom_Curve)*)&GG);
619             }
620             if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
621               C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
622             }
623             if (P.IsNull()) { // on met les courbes 2d si on n`est pas 
624                               // sur un plan
625 //            TopAbs_Orientation oredonfafw = TopAbs::Compose(or,orsav);
626               TopAbs_Orientation oredonfafw = orient;
627               tol = BRep_Tool::Tolerance(newedg);
628               TopoDS_Shape aLocalEdge = edg.Oriented(oredonfafw);
629               TopoDS_Shape aLocalFace = fac.Oriented(TopAbs_FORWARD);
630               C2d = BRep_Tool::CurveOnSurface
631                 (TopoDS::Edge(aLocalEdge),TopoDS::Face(aLocalFace),f,l);
632 //            C2d = BRep_Tool::CurveOnSurface
633 //              (TopoDS::Edge(edg.Oriented(oredonfafw)),
634 //               TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
635 //               f,l);
636
637               if (!BRepTools::IsReallyClosed(edg,fac)) {
638                 B.UpdateEdge(newedg,C2d,newface,tol);
639               }
640               else if (C2d1.IsNull()){
641                 C2d1 = C2d;
642               }
643               else {
644 //              if (TopAbs::Compose(orsav,or) == TopAbs_FORWARD) {
645                 if (orient == TopAbs_FORWARD) {
646                   B.UpdateEdge(newedg,C2d,C2d1,newface,tol);
647                 }
648                 else {
649                   B.UpdateEdge(newedg,C2d1,C2d,newface,tol);
650                 }
651               }
652             }
653             Standard_Boolean AddPart = Standard_False;
654             if (DontFuse.IsBound(edg)) {
655               if (!BRepTools::IsReallyClosed(edg,fac)) {
656                 if (DontFuse(edg).IsSame(fac)) {
657                   if (myModShapes.IsBound(edg)) {
658                     AddPart = Standard_True;
659                   }
660                 }
661                 else if (!toRemove.Contains(edg)) {
662                   AddPart = Standard_True;
663                 }
664
665               }
666               else {
667                 if (myModShapes.IsBound(edg)) { // edg raccourci
668 //                if (TopAbs::Compose(orsav,or)==DontFuse(edg).Orientation()){
669                   if (orient == DontFuse(edg).Orientation()){
670                     AddPart = Standard_True;
671                   }
672                 }
673                 else {
674 //                if (TopAbs::Compose(orsav,or) == 
675                   if (orient == 
676                       TopAbs::Reverse(DontFuse(edg).Orientation())) {
677                     AddPart = Standard_True;
678                   }
679                 }
680               }
681             }  
682             if (AddPart) {
683               itl2.Initialize(theEEMap(edg));
684               gp_Vec dir1,dir2;
685               for (; itl2.More(); itl2.Next()) {
686                 if (EdgAdded.Contains(itl2.Value())) {
687                   continue;
688                 }
689                 const TopoDS_Edge& edgbis = TopoDS::Edge(itl2.Value());
690                 TopoDS_Iterator it1(newedg),it2;
691                 for (; it1.More(); it1.Next()) {
692                   for (it2.Initialize(edgbis); it2.More(); it2.Next()) {
693                     if (it1.Value().IsSame(it2.Value())) {
694                       break;
695                     }
696                   }
697                   if (it2.More()) {
698                     break;
699                   }
700                 }
701
702                 if (it1.More()) {
703                   gp_Pnt ptbid;
704                   Standard_Real prmvt = 
705                     BRep_Tool::Parameter(TopoDS::Vertex(it1.Value()),newedg);
706                   C->D1(prmvt,ptbid,dir1);
707
708
709                   C = BRep_Tool::Curve(edgbis,loc,f,l);
710                   if (!loc.IsIdentity()) {
711                     Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
712                     C = *((Handle(Geom_Curve)*)&GG);
713                   }
714                   if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
715                     C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
716                   }
717                   prmvt = 
718                     BRep_Tool::Parameter(TopoDS::Vertex(it1.Value()),edgbis);
719                   C->D1(prmvt,ptbid,dir2);
720                 }
721                 else {
722                   dir1 = dir2 = gp_Vec(1,0,0);
723                 }
724                 EdgAdded.Add(edgbis);
725                 if (dir1.Dot(dir2) <0.) {
726 //                B.Add(newwire,edgbis.Oriented(TopAbs::Reverse(or)));
727                   listofedg.Append(edgbis.Oriented(TopAbs::Reverse(orient)));
728                 }
729                 else {
730 //                B.Add(newwire,edgbis.Oriented(or));
731                   listofedg.Append(edgbis.Oriented(orient));              
732                 }
733
734                 
735                 if (P.IsNull()) {
736                   // on met les courbes 2d si on n`est pas sur un plan
737                   // C est la courbe de edgbis, f et l s`y rapportent
738                   Handle(Geom2d_Curve) PTC = GeomProjLib::Curve2d(C,f,l,S,tol);
739                   if (S->IsUPeriodic()) {
740                     Standard_Real Uref;
741                     if (DontFuse.IsBound(edg)) {
742                       TopAbs_Orientation oredge = DontFuse(edg).Orientation();
743                       if (myModShapes.IsBound(edg)) { // edge raccourci...
744                         TopoDS_Shape aLocalShape = edg.Oriented(oredge);
745                         TopoDS_Shape aLocalFace  = fac.Oriented(TopAbs_FORWARD);
746                         BRep_Tool::
747                         UVPoints(TopoDS::Edge(aLocalShape),TopoDS::Face(aLocalFace),pf,pl);
748 //                      BRep_Tool::
749 //                      UVPoints(TopoDS::Edge(edg.Oriented(oredge)),
750 //                               TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
751 //                               pf,pl);
752                       }
753                       else {
754                         TopoDS_Shape aLocalShape = edg.Oriented(TopAbs::Reverse(oredge));
755                         TopoDS_Shape aLocalFace  = fac.Oriented(TopAbs_FORWARD);
756                         BRep_Tool::
757                         UVPoints(TopoDS::Edge(aLocalShape),TopoDS::Face(aLocalFace),pf,pl);
758 //                      BRep_Tool::
759 //                      UVPoints(TopoDS::Edge(edg.Oriented(TopAbs::Reverse(oredge))),
760 //                               TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
761 //                               pf,pl);
762                       }
763                       Uref = pf.X();
764                     }
765                     else {
766                       BRep_Tool::UVPoints(edg,fac,pf,pl);
767                       Uref = pf.X();
768                     }
769                     
770                     Standard_Real NewU = (PTC->Value(f)).X();
771                     
772 //                  if(abs(NewU - Uref) > Epsilon(S->UPeriod()))   {
773                     if(fabs(NewU - Uref) > Epsilon(S->UPeriod()))   {
774                       PTC -> Translate(gp_Vec2d((Uref - NewU), 0.));
775                     }
776                   }
777
778                   B.UpdateEdge(edgbis,PTC,newface,tol);
779                 }
780               }
781             }
782           }
783         }
784         
785         // Recuperation des edges sur les faces a fusionner.
786
787 // ICICICICI
788
789 //      orface = TopAbs::Compose(orsav,orface);
790
791         Standard_Boolean includeinw = Standard_False;
792         for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
793           TopoDS_Face facbis = TopoDS::Face(itl.Value());
794           Standard_Boolean genface = Standard_True;
795           for (itl2.Initialize(G->OrientedFaces()); itl2.More(); itl2.Next()) {
796             if (itl2.Value().IsSame(facbis)) {
797               break;
798             }
799           }
800           if (itl2.More()) {
801             orient = itl2.Value().Orientation();
802             facbis.Orientation(orient);
803           }
804           else { // on fusionne avec une autre face du shape...
805             genface = Standard_False;
806             for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
807               if (exp2.Current().IsSame(facbis)) {
808                 facbis.Orientation(exp2.Current().Orientation());
809                 break;
810               }
811             }
812           }
813
814           for (exp3.Init(facbis,TopAbs_WIRE); exp3.More(); exp3.Next()) {
815             for (exp2.Init(exp3.Current(),TopAbs_EDGE); 
816                  exp2.More(); exp2.Next()) {
817               if (toRemove.Contains(exp2.Current())) {
818                 break;
819               }
820             }
821             if (genface) {
822               includeinw = Standard_True;
823             }
824             else {
825               Standard_Boolean includeinw = Standard_False;
826               if (exp2.More()) {
827                 for (exp2.ReInit(); exp2.More(); exp2.Next()) {
828                   if (!toRemove.Contains(exp2.Current())) {
829                     continue;
830                   }
831                   TopoDS_Vertex VF,VL;
832                   TopExp::Vertices(TopoDS::Edge(exp2.Current()),VF,VL);
833                   TopExp_Explorer exp4;
834                   for (exp4.Init(wir,TopAbs_VERTEX); 
835 //                for (TopExp_Explorer exp4(wir,TopAbs_VERTEX); 
836                        exp4.More(); exp4.Next()) {
837                     if (exp4.Current().IsSame(VF) ||
838                         exp4.Current().IsSame(VL)) {
839                       includeinw = Standard_True;
840                       break;
841                     }
842                   }
843                   if (includeinw) {
844                     break;
845                   }
846                 }
847               }
848             }
849             
850             if (!includeinw) {
851               continue;
852             }
853             
854             for (exp2.ReInit(); exp2.More(); exp2.Next()) {
855               const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
856               if (!toRemove.Contains(edg) && !EdgAdded.Contains(edg)) {
857                 
858                 orient = TopAbs::Compose(orface,edg.Orientation());
859                 //              B.Add(newwire,edg.Oriented(or));
860                 listofedg.Append(edg.Oriented(orient));
861                 EmptyWire = Standard_False;
862                 EdgAdded.Add(edg);
863                 if (P.IsNull()) {  
864                   // on met les courbes 2d si on n`est pas sur un plan
865                   // on ne devrait pas avoir de pb d`edge de couture. 
866                   tol = BRep_Tool::Tolerance(edg);
867                   C = BRep_Tool::Curve(edg,loc,f,l);
868                   if (!loc.IsIdentity()) {
869                     Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
870                     C = *((Handle(Geom_Curve)*)&GG);
871                   }
872                   if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
873                     C =  (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
874                   }
875                   
876                   C2d = GeomProjLib::Curve2d(C,f,l,S,tol);
877
878                   // Tentative de recalage dans la facette
879                   pf = C2d->Value(f);
880                   pl = C2d->Value(l);
881                   Standard_Real tttol = Precision::Angular();
882                   while (Min(pf.X(),pl.X()) >= Umaxc - tttol) {
883                     C2d->Translate(gp_Vec2d(-2.*M_PI,0));
884                     pf = C2d->Value(f);
885                     pl = C2d->Value(l);
886                   }
887                   
888                   while (Max(pf.X(),pl.X()) <= Uminc + tttol) {
889                     C2d->Translate(gp_Vec2d(2.*M_PI,0));
890                     pf = C2d->Value(f);
891                     pl = C2d->Value(l);
892                   }
893
894                   if (!BRepTools::IsReallyClosed(edg,facbis)) {
895                     B.UpdateEdge(edg,C2d,newface,tol);
896                   }
897                   //            else {
898                   //              cout << "Edge double bizarre... " << endl;
899                   //            }
900                 }
901               }
902             }
903           }
904         }
905       }
906     }
907     if (!listofedg.IsEmpty()) {
908       BRepAlgo_Loop L;
909       L.Init(newface);
910       L.AddConstEdges(listofedg);
911       L.Perform();
912       L.WiresToFaces();
913 #ifdef DEB
914       const TopTools_ListOfShape& listofwires =
915 #endif
916                                                 L.NewWires();
917       const TopTools_ListOfShape& listoffaces = L.NewFaces();
918       toRemove.Add(fac);
919       //      if (!HasWire) {
920       //        newface.Nullify();
921       //      }
922       myModShapes.Bind(fac,listoffaces);
923       for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
924         myModShapes.Bind(itl.Value(),listoffaces);
925       }
926     }
927   }
928
929 /* JAG 16.09.96 : on utilise LocOpe_BuildShape
930   TopoDS_Shell theShell;
931   B.MakeShell(theShell);
932   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
933     const TopoDS_Face& fac = TopoDS::Face(exp.Current());
934     if (!theLeft.Contains(fac)) {
935       if (!toRemove.Contains(exp.Current())) {
936         B.Add(theShell,fac);
937         myModShapes.Bind(fac,fac);
938       }
939       else if (!myModShapes(fac).IsNull())  {
940         B.Add(theShell, myModShapes(fac).Oriented(fac.Orientation()));
941       }
942     }
943   }
944
945
946   TopAbs_Orientation orsolid = myShape.Orientation();
947   for (itl.Initialize(G->OrientedFaces()); itl.More(); itl.Next()) {
948     const TopoDS_Face& fac = TopoDS::Face(itl.Value());
949     if (toRemove.Contains(fac)) {
950       continue;
951     }
952
953     if (orsolid == TopAbs_FORWARD) {
954       B.Add(theShell,fac);
955     }
956     else {
957       B.Add(theShell,fac.Reversed());
958     }
959     myModShapes.Bind(fac,fac);
960
961   }
962
963   B.MakeSolid(TopoDS::Solid(myRes));
964   B.Add(myRes,theShell);
965   myRes.Orientation(orsolid);
966
967 */
968
969   // 06.11.96
970   // Debug temporaire. Il faudra prevoir un syntaxe de BuildShape
971   // qui impose une ori de certaines faces.
972
973   TopoDS_Face FaceRefOri;
974
975   TopTools_ListOfShape lfres;
976   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
977     const TopoDS_Face& fac = TopoDS::Face(exp.Current());
978     if (!theLeft.Contains(fac)) {
979       if (!toRemove.Contains(exp.Current())) {
980         lfres.Append(fac);
981         if(!myModShapes.IsBound(fac)) {
982           TopTools_ListOfShape emptylist;
983           myModShapes.Bind(fac, emptylist);
984         }
985         myModShapes(fac).Append(fac);
986         if (FaceRefOri.IsNull()) {
987           FaceRefOri = fac;
988         }
989       }
990       else if (myModShapes.IsBound(fac))  {
991         lfres.Append(myModShapes(fac).First().Oriented(fac.Orientation()));
992       }
993     }
994   }
995
996
997   TopAbs_Orientation orsolid = myShape.Orientation();
998   for (itl.Initialize(G->OrientedFaces()); itl.More(); itl.Next()) {
999     const TopoDS_Face& fac = TopoDS::Face(itl.Value());
1000     if (toRemove.Contains(fac)) {
1001       continue;
1002     }
1003
1004     if (orsolid == TopAbs_FORWARD) {
1005       lfres.Append(fac);
1006     }
1007     else {
1008       lfres.Append(fac.Reversed());
1009     }
1010     if(!myModShapes.IsBound(fac)) {
1011       TopTools_ListOfShape emptylist;
1012       myModShapes.Bind(fac, emptylist);
1013     }
1014     myModShapes(fac).Append(fac);
1015   }
1016
1017   LocOpe_BuildShape BS(lfres);
1018   myRes = BS.Shape();
1019   // Suite debug du 06.11.96
1020   if (myRes.ShapeType() == TopAbs_SOLID) {
1021     for (exp.Init(myRes,TopAbs_FACE); exp.More(); exp.Next()) {
1022       if (exp.Current().IsSame(FaceRefOri)) {
1023         break;
1024       }
1025     }
1026     if (exp.More() && 
1027         exp.Current().Orientation() != FaceRefOri.Orientation()) {
1028       //        ---C++: return const&   ---C++: return const&   ---C++: return const&Si un seul Shell , on change son orientation
1029       TopoDS_Solid NewSol;
1030       B.MakeSolid(NewSol);
1031       exp.Init(myRes,TopAbs_SHELL);
1032       B.Add(NewSol,exp.Current().Reversed());
1033       myRes.Nullify();
1034       myRes = NewSol;
1035     }
1036   }
1037
1038
1039   // recodage des regularites qui existaient sur le shape colle
1040   
1041   
1042
1043   myDone = Standard_True;
1044 }
1045
1046 //=======================================================================
1047 //function : DescendantFace
1048 //purpose  : 
1049 //=======================================================================
1050
1051  const TopTools_ListOfShape& LocOpe_Generator::DescendantFace(const TopoDS_Face& F)
1052 {
1053  // TopTools_ListOfShape list;
1054
1055   if (!myDone) {StdFail_NotDone::Raise();}
1056   return myModShapes(F);
1057 }
1058
1059 //=======================================================================
1060 //function : ToFuse
1061 //purpose  : 
1062 //=======================================================================
1063
1064 Standard_Boolean ToFuse(const TopoDS_Face& F1,
1065                         const TopoDS_Face& F2)
1066 {
1067   if (F1.IsNull() || F2.IsNull()) {
1068     return Standard_False;
1069   }
1070
1071   Handle(Geom_Surface) S1,S2;
1072   TopLoc_Location loc1, loc2;
1073   Handle(Standard_Type) typS1,typS2;
1074   const Standard_Real tollin = Precision::Confusion();
1075   const Standard_Real tolang = Precision::Angular();
1076
1077   S1 = BRep_Tool::Surface(F1,loc1);
1078   S2 = BRep_Tool::Surface(F2,loc2);
1079
1080   typS1 = S1->DynamicType();
1081   typS2 = S2->DynamicType();
1082
1083   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1084     S1 =  (*((Handle(Geom_RectangularTrimmedSurface)*)&S1))->BasisSurface();
1085     typS1 = S1->DynamicType();
1086   }
1087
1088   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1089     S2 =  (*((Handle(Geom_RectangularTrimmedSurface)*)&S2))->BasisSurface();
1090     typS2 = S2->DynamicType();
1091   }
1092
1093   if (typS1 != typS2) {
1094     return Standard_False;
1095   }
1096
1097
1098   Standard_Boolean ValRet = Standard_False;
1099   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
1100
1101     gp_Pln pl1( (*((Handle(Geom_Plane)*)&S1))->Pln());
1102     gp_Pln pl2( (*((Handle(Geom_Plane)*)&S2))->Pln());
1103
1104     pl1.Transform(loc1.Transformation());
1105     pl2.Transform(loc2.Transformation());
1106
1107     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
1108       ValRet = Standard_True;
1109     }
1110   }
1111
1112   return ValRet;
1113 }
1114
1115
1116 //=======================================================================
1117 //function : ToFuse
1118 //purpose  : 
1119 //=======================================================================
1120
1121 Standard_Boolean ToFuse(const TopoDS_Edge& E1,
1122                         const TopoDS_Edge& E2)
1123 {
1124
1125   if (E1.IsNull() || E2.IsNull()) {
1126     return Standard_False;
1127   }
1128
1129   Handle(Geom_Curve) C1,C2;
1130   TopLoc_Location loc1, loc2;
1131   Handle(Standard_Type) typC1,typC2;
1132   const Standard_Real tollin = Precision::Confusion();
1133   const Standard_Real tolang = Precision::Angular();
1134   Standard_Real f,l;
1135
1136   C1 = BRep_Tool::Curve(E1,loc1,f,l);
1137   if (!loc1.IsIdentity()) {
1138     Handle(Geom_Geometry) CC1 = C1->Transformed(loc1.Transformation());
1139     C1 = *((Handle(Geom_Curve)*)&CC1);
1140   }
1141
1142   C2 = BRep_Tool::Curve(E2,loc2,f,l);
1143   if (!loc2.IsIdentity()) {
1144     Handle(Geom_Geometry) CC2 = C2->Transformed(loc2.Transformation());
1145     C2 = *((Handle(Geom_Curve)*)&CC2);
1146   }
1147
1148   typC1 = C1->DynamicType();
1149   typC2 = C2->DynamicType();
1150
1151   if (typC1 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1152     C1 =  (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
1153     typC1 = C1->DynamicType();
1154   }
1155   if (typC2 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1156     C2 =  (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
1157     typC2 = C2->DynamicType();
1158   }
1159
1160   if (typC1 != typC2) {
1161     return Standard_False;
1162   }
1163
1164   Standard_Boolean ValRet = Standard_False;
1165   if (typC1 == STANDARD_TYPE(Geom_Line)) {
1166     gp_Lin li1( (*((Handle(Geom_Line)*)&C1))->Lin());
1167     gp_Lin li2( (*((Handle(Geom_Line)*)&C2))->Lin());
1168
1169     if (li1.Position().IsCoaxial(li2.Position(),tolang,tollin)) {
1170       ValRet = Standard_True;
1171     }
1172   }
1173
1174   return ValRet;
1175 }
1176
1177
1178 //=======================================================================
1179 //function : ToFuse
1180 //purpose  : 
1181 //=======================================================================
1182
1183 Standard_Boolean ToFuse(const TopoDS_Edge& E,
1184                         const TopoDS_Face& F,
1185                         const TopoDS_Vertex& V,
1186                         const TopTools_MapOfShape& toRemove)
1187 {
1188   TopoDS_Vertex Vf,Vl;
1189   TopExp_Explorer exp;
1190   for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
1191 //  for (TopExp_Explorer exp(F,TopAbs_EDGE); exp.More(); exp.Next()) {
1192     const TopoDS_Edge& eee = TopoDS::Edge(exp.Current());
1193     if (!eee.IsSame(E)) {
1194       TopExp::Vertices(eee,Vf,Vl);
1195       if ((Vf.IsSame(V) || Vl.IsSame(V)) &&
1196           !toRemove.Contains(eee)) {
1197         return Standard_False;
1198       }
1199     }
1200   }
1201   return Standard_True;
1202 }
1203
1204
1205 //=======================================================================
1206 //function : NewParameter
1207 //purpose  : 
1208 //=======================================================================
1209
1210 Standard_Real NewParameter(const TopoDS_Edge& Edg,
1211                            const TopoDS_Vertex& Vtx,
1212                            const TopoDS_Edge& NewEdg,
1213                            const TopoDS_Vertex& NewVtx)
1214 {
1215
1216   Handle(Geom_Curve) C;
1217   TopLoc_Location loc;
1218   Handle(Standard_Type) typC;
1219   Standard_Real f,l;
1220
1221   gp_Pnt P = BRep_Tool::Pnt(NewVtx);
1222
1223   C = BRep_Tool::Curve(Edg,loc,f,l);
1224   if (!loc.IsIdentity()) {
1225     Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
1226     C = *((Handle(Geom_Curve)*)&GG);
1227   }
1228   typC = C->DynamicType();
1229   if (typC == STANDARD_TYPE(Geom_TrimmedCurve)) {
1230     C =  (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
1231     typC = C->DynamicType();
1232   }
1233
1234   if (typC == STANDARD_TYPE(Geom_Line)) {
1235     return ElCLib::Parameter( (*((Handle(Geom_Line)*)&C))->Lin(),P);
1236   }
1237   else if (typC == STANDARD_TYPE(Geom_Circle)) {
1238     Standard_Real prm = ElCLib::Parameter
1239       ( (*((Handle(Geom_Circle)*)&C))->Circ(),P);
1240     // Vtx vient d`une exploration de Edg orientee FORWARD
1241
1242     TopAbs_Orientation orient = TopAbs::Reverse(Vtx.Orientation());
1243     if (orient == TopAbs_FORWARD || orient == TopAbs_REVERSED) {
1244 //      for (TopExp_Explorer exp(NewEdg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1245       TopExp_Explorer exp(NewEdg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX) ;
1246       for ( ; exp.More(); exp.Next()) {
1247         if (exp.Current().Orientation() == orient) {
1248           break;
1249         }
1250       }
1251       if (exp.More()) {
1252         Standard_Real prmmax = BRep_Tool::Parameter
1253           (TopoDS::Vertex(exp.Current()),NewEdg);
1254         if (Abs(prmmax - prm) <= Epsilon(2.*M_PI)) {
1255           if (orient == TopAbs_REVERSED) {
1256             prm -= 2.*M_PI;
1257           }
1258           else {
1259             prm += 2.*M_PI;
1260           }
1261         }
1262       }
1263     }
1264     return prm;
1265   }
1266   return 0;
1267 }
1268
1269
1270 //=======================================================================
1271 //function : Contains
1272 //purpose  : 
1273 //=======================================================================
1274
1275 // Unused :
1276 #ifdef DEB
1277 Standard_Boolean Contains(const TopTools_ListOfShape& L,
1278                           const TopoDS_Shape& S)
1279 {
1280   TopTools_ListIteratorOfListOfShape itl;
1281   for (itl.Initialize(L); itl.More(); itl.Next()) {
1282 //  for (TopTools_ListIteratorOfListOfShape itl(L); itl.More(); itl.Next()) {
1283     if (itl.Value().IsSame(S)) {
1284       return Standard_True;
1285     }
1286   }
1287   return Standard_False;
1288 }
1289 #endif
1290