0022805: Bug of STEP read /writer
[occt.git] / src / StepToTopoDS / StepToTopoDS_TranslateEdgeLoop.cxx
1 // File:        StepToTopoDS_TranslateEdgeLoop.cxx
2 // Created:     Wed Mar 29 08:40:15 1995
3 // Author:      Frederic MAUPAS
4 //              <fma@pronox>
5 // gka 21.08.98 PRO7656
6 // gka 15.12.98 UKI60591 #1274560
7 //pdn 18.12.98 to keep pcurves
8 //:o0 abv 16.02.99: POLYLINE allowed as 3d curve of edge
9 //:   abv 07.04.99: S4136: improve tolerance management and dealing with pcurves
10 //    rln 02.06.99 removing #include <StepToTopoDS_DegeneratedTool.hxx>
11 //    smh 31.01.01 BUC60810 : IsNull protection
12 #include <StepToTopoDS_TranslateEdgeLoop.ixx>
13
14 #include <StepToTopoDS.hxx>
15 #include <StepToTopoDS_TranslateVertex.hxx>
16 #include <StepToTopoDS_TranslateEdge.hxx>
17 #include <StepToTopoDS_GeometricTool.hxx>
18 #include <ShapeAnalysis_Curve.hxx>
19 #include <StepToGeom_MakeCurve2d.hxx>
20 #include <StepToGeom_MakeCurve.hxx>
21
22 #include <Geom_RectangularTrimmedSurface.hxx>
23
24 #include <StepShape_EdgeLoop.hxx>
25 #include <StepShape_Edge.hxx>
26 #include <StepShape_OrientedEdge.hxx>
27 #include <StepGeom_Curve.hxx>
28 #include <StepShape_EdgeCurve.hxx>
29 #include <StepGeom_Pcurve.hxx>
30 //#include <StepGeom_Polyline.hxx>
31 #include <StepGeom_SurfaceCurve.hxx>
32 #include <StepRepr_DefinitionalRepresentation.hxx>
33 #include <StepGeom_PcurveOrSurface.hxx>
34
35 #include <BRep_Builder.hxx>
36 #include <BRep_Tool.hxx>
37
38 #include <TopoDS.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Vertex.hxx>
42
43 #include <BRep_TEdge.hxx>
44 #include <BRep_CurveRepresentation.hxx>
45 #include <BRep_ListOfCurveRepresentation.hxx>
46 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
47
48 #include <TopExp_Explorer.hxx>
49 #include <TopExp.hxx>
50
51 #include <TopLoc_Location.hxx>
52 #include <TopAbs.hxx>
53
54 #include <Geom_Surface.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_Curve.hxx>
57
58 #include <Geom2d_Curve.hxx>
59 #include <Geom2d_BoundedCurve.hxx>
60 #include <Geom2d_Line.hxx>
61
62 #include <gp_Pnt.hxx>
63 #include <gp_Pnt2d.hxx>
64
65 #include <Precision.hxx>
66 #include <Interface_Static.hxx>
67 #include <Transfer_TransientProcess.hxx>
68 #include <TopoDS_Iterator.hxx>
69 #include <ShapeFix_EdgeProjAux.hxx>
70 #include <ShapeAnalysis_Edge.hxx>
71 #include <ShapeExtend_WireData.hxx>
72 #include <ShapeBuild_Edge.hxx>
73
74 #include <ShapeAlgo.hxx>
75 #include <ShapeAlgo_AlgoContainer.hxx>
76 #include <ShapeAlgo_ToolContainer.hxx>
77 #include <XSAlgo.hxx>
78 #include <XSAlgo_AlgoContainer.hxx>
79
80 // ============================================================================
81 // Method  : RemoveSinglePCurve
82 // Purpose : 
83 // ============================================================================
84
85 static void RemoveSinglePCurve (const TopoDS_Edge& aEdge, const TopoDS_Face& aFace)
86 {
87   ShapeBuild_Edge().RemovePCurve (aEdge, aFace);
88 }
89
90 // ============================================================================
91 // Method  : RemovePCurves
92 // Purpose : 
93 // ============================================================================
94
95 static void RemovePCurves(const TopoDS_Wire& aWire, const TopoDS_Face& aFace)
96 {
97   TopExp_Explorer EdgeExp(aWire, TopAbs_EDGE);
98   while (EdgeExp.More()) {
99     const TopoDS_Edge& myEdge = TopoDS::Edge(EdgeExp.Current());
100     RemoveSinglePCurve(myEdge,aFace);
101     EdgeExp.Next();
102   }
103 }
104
105 // ============================================================================
106 // Method  : CheckPCurves
107 // Purpose : Checks the pcurves topological trimming parameter consistency
108 //           and deviation between 2D ans 3D  
109 // ============================================================================
110
111 static void CheckPCurves (TopoDS_Wire& aWire, const TopoDS_Face& aFace,
112                           const Standard_Boolean isPlane,const Standard_Real preci )
113 {
114   if (isPlane) { RemovePCurves (aWire,aFace);return; }
115   BRep_Builder B;
116   Standard_Real w1, w2, cf, cl;
117   Handle(Geom_Surface) mySurf = BRep_Tool::Surface(aFace);
118   
119   Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData ( aWire );
120   for (Standard_Integer i = 1; i <= sbwd->NbEdges(); i++) {
121     const TopoDS_Edge& myEdge = sbwd->Edge(i);
122 //    B.SameRange( myEdge, Standard_True );
123 //    B.SameParameter ( myEdge, Standard_True ); 
124     
125     // First Check : 2D Parameters on Edge :
126     // Case 1 : w1 == w2 illegal => Drop the PCurve
127     // Case 2 : on bounded curve w1 < FirstParameter => w1 = FirstParameter
128     //                           w2 > LastParameter  => w2 = LastParameter
129
130     Handle(Geom2d_Curve) thePC;
131     ShapeAnalysis_Edge sae;
132     if (!sae.PCurve (myEdge, aFace, thePC, w1, w2, Standard_False )) {
133       continue;
134     }
135     cf = thePC->FirstParameter();
136     cl = thePC->LastParameter();
137     
138     if (w1 == w2) {
139       RemoveSinglePCurve(myEdge,aFace);
140 #ifdef DEBUG      
141       cout<<"Removing pcuve w1=w2"<<endl;
142 #endif      
143       continue;
144     }
145
146     if (w1 < cf) {
147       B.Range(myEdge, aFace, cf, w2);
148       w1 = cf;
149     }
150     if (w2 > cl) {
151       B.Range(myEdge, aFace, w1, cl);      
152       w2 = cf;
153     }
154     
155     // advanced check
156     XSAlgo::AlgoContainer()->CheckPCurve (myEdge, aFace, preci, sbwd->IsSeam(i) );
157   }
158 }
159
160 // ============================================================================
161 // Method  : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop
162 // Purpose : Empty Constructor
163 // ============================================================================
164
165 StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop()
166 {
167   done = Standard_False;
168 }
169
170 // ============================================================================
171 // Method  : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop
172 // Purpose : Constructor with a FaceSurface and a Tool
173 // ============================================================================
174
175 StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop(const Handle(StepShape_FaceBound)& FB, 
176                                                                const TopoDS_Face& Face,
177                                                                const Handle(Geom_Surface)& GeomSurf,
178                                                                const Handle(StepGeom_Surface)& StepSurf,
179                                                                const Standard_Boolean sameSense,
180                                                                StepToTopoDS_Tool& T,
181                                                                StepToTopoDS_NMTool& NMTool) {
182   Init(FB, Face, GeomSurf, StepSurf, sameSense, T, NMTool);
183 }
184
185 // ============================================================================
186 // Method  : Init
187 // Purpose : Init with a EdgeLoop and a Tool
188 // ============================================================================
189
190 void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& FaceBound, 
191                                           const TopoDS_Face& Face,
192                                           const Handle(Geom_Surface)& GeomSurf,
193                                           const Handle(StepGeom_Surface)& StepSurf,
194                                           const Standard_Boolean sameSense,
195                                           StepToTopoDS_Tool& aTool,
196                                           StepToTopoDS_NMTool& NMTool) {
197   done = Standard_True;
198   Handle(StepShape_EdgeLoop) EL = 
199     Handle(StepShape_EdgeLoop)::DownCast(FaceBound->Bound());
200
201   if (aTool.IsBound(EL)) {
202     myResult = TopoDS::Wire(aTool.Find(EL));
203     myError  = StepToTopoDS_TranslateEdgeLoopDone;
204     done     = Standard_True;
205     return;
206   }
207   Standard_Integer modepcurve = Interface_Static::IVal("read.surfacecurve.mode");
208 //  0,1 : suivre le code,  2 : ne prendre que pcurve,  3 : ne prendre que C3D
209
210   BRep_Builder B;
211   Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
212   
213   Standard_Real preci = Precision();
214   TopoDS_Wire   W;
215   TopoDS_Edge   E;
216   TopoDS_Vertex V;
217
218 //  Standard_Real U1,U2, U1a, U1b, U2a, U2b;
219   
220   Standard_Boolean isSeam, isLikeSeam;
221   
222   Handle(StepShape_Edge)         StepEdge, StepEdge1;
223   Handle(StepShape_OrientedEdge) OrEdge1, OrEdge2;
224   Handle(StepGeom_Curve) StepCurve, StepCurve1, StepCurve2;
225 //  Handle(StepGeom_Pcurve) StepPCurve, StepPCurve1, StepPCurve2;
226   Handle(StepRepr_DefinitionalRepresentation) DRI, Dri1, Dri2;
227   
228   Handle(Geom2d_Curve) C2d, C2d1, C2d2, WhichC2d1, WhichC2d2;
229 // unused  gp_Pnt Pdeb, Pmil, Pfin, pV1, pV2;
230   
231   TopoDS_Edge   suspectE; //:f1, degEdge; 
232   
233   Standard_Integer j, NbEdge = EL->NbEdgeList();
234   if( NbEdge == 0) {
235     TP->AddWarning(EL,"Wire not done. EdgeLoop does not contain edges.");
236     done = Standard_False;
237     return;
238   }
239 // PTV 16.09.2000 
240 // default value set as Standard_True (if not correct see logic of algorithm).
241   Standard_Boolean hasPcurve = Standard_True;
242   Standard_Boolean isPlane = GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane));
243   Handle(Geom_Surface) ConvSurf = GeomSurf;
244   if (GeomSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
245     Handle(Geom_RectangularTrimmedSurface) theRTS =
246       Handle(Geom_RectangularTrimmedSurface)::DownCast(GeomSurf);
247     ConvSurf = theRTS->BasisSurface();
248   }
249
250   aTool.ComputePCurve(Standard_False);
251   
252   // What is the Wire Orientation
253   Standard_Boolean ForwardWire = FaceBound->Orientation();
254
255   // --- Initialize target Wire ---
256
257   B.MakeWire(W);
258
259 //  Standard_Integer lastpcurve = 0;
260
261   // -----------------------------------------------
262   // Preparation : Make Vertices + Curves3d
263   //  Hence, a closed curve limited by distinct vertices
264   //  will give a unique vertex (if same coords)
265   //
266   // In addition : detect shared PCurve (cf SYRKO)
267   //  This case may not be processed, PCurves has to be recomputed from scratch
268   // -----------------------------------------------
269 //  Standard_Integer theSame = 1; //gka 15.12.98
270   
271   for (j=1; j<=NbEdge; j++ ) {
272     OrEdge1  = EL->EdgeListValue(j);
273     StepEdge = OrEdge1->EdgeElement();
274 //    if(j>1 && StepEdge == StepEdge1) theSame++; //gka 15.12.98
275     StepEdge1 = StepEdge;                         //
276     Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge);
277     Handle(StepGeom_Curve) C = EC->EdgeGeometry();
278     if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) {
279       Handle(StepGeom_SurfaceCurve) Sc = Handle(StepGeom_SurfaceCurve)::DownCast(C);
280       C = Sc->Curve3d();
281 //      if (modepcurve != 3) {
282 //      lastpcurve = StepToTopoDS_GeometricTool::PCurve (Sc,StepSurf,StepPCurve1);
283 //      if (StepPCurve1 == StepPCurve) modepcurve = -1;
284 //      StepPCurve = StepPCurve1;
285 //      }
286     }
287 ////    else if (C->IsKind(STANDARD_TYPE(StepGeom_Polyline))) {  }
288 //    else if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) {
289 //      if (modepcurve != 3) {
290 //      if (C == StepPCurve) modepcurve = -1;
291 //      StepPCurve = Handle(StepGeom_Pcurve)::DownCast(C);
292 //      }
293 //    }
294     Handle(Geom_Curve) C1;
295     if (!C.IsNull()) {
296       C1 = Handle(Geom_Curve)::DownCast (TP->FindTransient(C));
297       if (C1.IsNull()) {
298         if (StepToGeom_MakeCurve::Convert(C,C1))
299           TP->BindTransient (C,C1);
300       }
301     }
302
303     Handle(StepShape_Vertex) Vstart, Vend;
304     if (EC->SameSense()) {
305       Vstart = EC->EdgeStart();
306       Vend   = EC->EdgeEnd();
307     }
308     else {
309       Vend   = EC->EdgeStart();
310       Vstart = EC->EdgeEnd();
311     }
312
313     Standard_Boolean istV = aTool.IsBound(Vstart);
314     Standard_Boolean iseV = aTool.IsBound(Vend);
315     TopoDS_Vertex V1, V2;
316     StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool);
317     StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool);
318
319     if (myTranVertex1.IsDone()) {
320       V1 = TopoDS::Vertex(myTranVertex1.Value());
321     }
322 //    if (Vend == Vstart) {  cas normal deja assure par aTool
323 //      aTool.Bind (Vend,V1);
324 //    }
325 //    else
326     if (myTranVertex2.IsDone()) {
327       V2 = TopoDS::Vertex(myTranVertex2.Value());
328       gp_Pnt p1 = BRep_Tool::Pnt(V1);
329       gp_Pnt p2 = BRep_Tool::Pnt(V2);
330       if (p1.Distance(p2) <= Precision::Confusion() ) { //:S4136: preci) {
331         Standard_Boolean Fixed = Standard_True;
332         if(!iseV) aTool.Bind(Vend,V1); //gka 21.08.1998 bug PRO7656 
333         else if(!istV)  aTool.Bind (Vstart,V2);
334         else aTool.Bind (Vend,V1);
335         //Fixed = Standard_False;
336         //aTool.Bind (Vend,V1);
337         if (!C1.IsNull() && !C1->IsClosed() && Fixed)
338           TP->AddWarning(EL->EdgeListValue(j),
339                          "Vertex of same coordinates, set confused");
340       }
341     }
342   }
343 //  if (NbEdge!=1 && theSame == NbEdge) {
344 //    TP->AddWarning(EL,"Wire was ignored. All edges are the same.");
345 //    done = Standard_False;
346 //    return;
347 //  }
348 //  Fixed=Standard_True;
349 //  if (modepcurve == -1) {
350 //    modepcurve = 3;
351 //    TP->AddWarning(EL,"Shared Pcurve not allowed, Pcurves are recomputed");
352 //  }
353
354   //:f6 abv 29 Apr 98: BUC50070 #3815: make sure that each two edges are
355   // connected by the same vertex; else check that vertices confuse
356   // and make it be one vertex
357   // NOTE: this is done only for the case if at least one of edges 
358   // was not yet translated; else nothing will help
359   for (j=1; j<=NbEdge; j++ ) {
360     OrEdge1  = EL->EdgeListValue ( j );
361     OrEdge2  = EL->EdgeListValue ( j < NbEdge ? j + 1 : 1 );
362     Handle(StepShape_EdgeCurve) EC1 = 
363       Handle(StepShape_EdgeCurve)::DownCast ( OrEdge1->EdgeElement() );
364     Handle(StepShape_EdgeCurve) EC2 = 
365       Handle(StepShape_EdgeCurve)::DownCast ( OrEdge2->EdgeElement() );
366
367     Handle(StepShape_Vertex) Vs1, Vs2,Vs11,Vs22;
368     Vs1 = ( OrEdge1->Orientation() ? EC1->EdgeEnd() : EC1->EdgeStart() );
369     Vs2 = ( OrEdge2->Orientation() ? EC2->EdgeStart() : EC2->EdgeEnd() );
370
371     Vs11 = ( OrEdge1->Orientation() ?  EC1->EdgeStart() : EC1->EdgeEnd());
372     Vs22 = ( OrEdge2->Orientation() ?  EC2->EdgeEnd() : EC2->EdgeStart() );
373
374     if((Vs1 == Vs2) || (Vs1 == Vs22) || (Vs2 == Vs11) || (Vs22 == Vs11)) continue;
375     //??    if ( Vs1.IsSame(Vs2) ) continue; // OK
376
377     StepToTopoDS_TranslateVertex myTranVertex1 (Vs1, aTool, NMTool);
378     StepToTopoDS_TranslateVertex myTranVertex2 (Vs2, aTool, NMTool);
379
380     TopoDS_Vertex V1, V2;
381     if ( myTranVertex1.IsDone() ) 
382       V1 = TopoDS::Vertex ( myTranVertex1.Value() );
383     if ( myTranVertex2.IsDone() ) 
384       V2 = TopoDS::Vertex ( myTranVertex2.Value() );
385     if ( V1.IsNull() || V2.IsNull() ) continue; // not treated
386     if ( V1.IsSame(V2) ) continue; // OK
387
388     gp_Pnt p1 = BRep_Tool::Pnt(V1);
389     gp_Pnt p2 = BRep_Tool::Pnt(V2);
390     Standard_Boolean locFixed = Standard_True;
391     if (p1.Distance(p2) <= preci) {
392       if ( ! aTool.IsBound ( EC1 ) ) aTool.Bind ( Vs1, V2 );
393       else if ( ! aTool.IsBound ( EC2 ) ) aTool.Bind ( Vs2, V1 );
394       else locFixed = Standard_False;
395     }
396     else locFixed = Standard_False;
397     if ( locFixed ) TP->AddWarning(EL,"Adjacent edges do not have common vertex; set confused");
398     else TP->AddWarning(EL,"Adjacent edges are not connected");
399   }
400
401   // -----------------------------------------------
402   // Iteration on each Oriented Edge of the EdgeLoop
403   // -----------------------------------------------
404
405   for (j=1; j<=NbEdge; j++ ) {
406
407     Standard_Boolean ThereIsLikeSeam = Standard_False;
408     
409 #ifdef DEBUG
410     cout << "      Processing Edge :" << j << endl;
411 #endif
412
413     OrEdge1  = EL->EdgeListValue(j);
414     StepEdge = OrEdge1->EdgeElement();
415     Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge);
416     
417     // ----------------
418     // Map the StepEdge
419     // ----------------
420     
421     StepToTopoDS_TranslateEdge myTranEdge;
422     
423     myTranEdge.SetPrecision(preci);
424     myTranEdge.SetMaxTol(MaxTol());
425     myTranEdge.Init(OrEdge1, aTool, NMTool);
426
427     if (myTranEdge.IsDone()) {
428       
429       E = TopoDS::Edge(myTranEdge.Value());
430       if (E.IsNull()) continue;  // NULL, on saute
431
432       Handle(StepGeom_Curve) C = EC->EdgeGeometry();
433
434       if (OrEdge1->Orientation() && EC->SameSense()) 
435         E.Orientation(TopAbs_FORWARD);
436       else if (!OrEdge1->Orientation() && !EC->SameSense())
437         E.Orientation(TopAbs_FORWARD);
438       else E.Orientation(TopAbs_REVERSED);
439
440       isSeam = isLikeSeam = Standard_False;
441       
442       // ------------------------------------------
443       // Map the StepEdge parametric representation
444       // ------------------------------------------
445
446       // --------------------------------------------
447       // CASE 1 : The Edge Geometry is of Pcurve Type
448       // --------------------------------------------
449       
450       if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) {
451         Handle(StepGeom_Pcurve) StepPCurve = Handle(StepGeom_Pcurve)::DownCast(C);
452         C2d = myTranEdge.MakePCurve (StepPCurve,ConvSurf);
453         // -- Statistics --
454         aTool.AddContinuity (C2d);
455       }
456
457       // -----------------------------------------
458       // CASE 2 : The curve is a SurfaceCurve i.e. 
459       //           - a 3D Curve (mandatory)
460       //           - 2 PCurveOrSurface
461       //   If modepcurve = 3, PCurve are ignored here
462       // -----------------------------------------
463
464       else if (modepcurve == 3) {
465         aTool.ComputePCurve(Standard_True);
466         hasPcurve = Standard_False;
467       }
468       else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve)) ) {
469         // recouvre les cas SeamCurve et IntersectionCurve
470         
471         Handle(StepGeom_SurfaceCurve) SurfCurve =
472           Handle(StepGeom_SurfaceCurve)::DownCast(C);
473
474         Handle(StepGeom_Pcurve) StepPCurve, StepPCurve1, StepPCurve2;
475         Standard_Integer lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve,StepSurf,StepPCurve,0);
476         hasPcurve = !StepPCurve.IsNull();
477
478         // De toute facon, on recalcule
479
480         if (isPlane) hasPcurve = Standard_False;
481
482         // -------------------------------------------
483         // ---        Special Mapping Cases :      ---
484         // ---   the SurfaceCurve is a SeamCurve   ---
485         // ---        or is like a seam curve      ---
486         // ---         (see CATIA cylinder)        ---
487         // -------------------------------------------
488         isLikeSeam = StepToTopoDS_GeometricTool::IsLikeSeam(SurfCurve,StepSurf,StepEdge,EL);
489
490         isSeam = StepToTopoDS_GeometricTool::IsSeamCurve(SurfCurve, StepSurf,StepEdge, EL);
491         
492         if (isSeam || isLikeSeam) {
493           // isLikeSeam = Two faces on the same Surface
494           StepPCurve1 = SurfCurve->AssociatedGeometryValue(1).Pcurve();
495           StepPCurve2 = SurfCurve->AssociatedGeometryValue(2).Pcurve();
496           if (StepPCurve1.IsNull() || StepPCurve2.IsNull()) hasPcurve = Standard_False; //smh : BUC60810
497           else {
498             C2d1 = myTranEdge.MakePCurve (StepPCurve1,ConvSurf);
499             C2d2 = myTranEdge.MakePCurve (StepPCurve2,ConvSurf);
500             hasPcurve = (!C2d1.IsNull() && !C2d2.IsNull());
501           }
502
503           if (isLikeSeam) {
504             suspectE = E;
505             ThereIsLikeSeam = Standard_True;
506             hasPcurve = Standard_True;
507           }
508         }
509         else if (hasPcurve) {
510 //  GeometricTool : Pcurve a retourne StepPCurve
511           while (lastpcurve > 0) {
512             C2d1 = myTranEdge.MakePCurve (StepPCurve,ConvSurf);
513             if (C2d1.IsNull()) {
514               hasPcurve = Standard_False;
515               break;
516             }
517             else C2d = C2d1;
518             lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve,StepSurf,StepPCurve,lastpcurve);
519             // -- Statistics --
520             aTool.AddContinuity (C2d);
521           }
522         }
523         if (!hasPcurve) {
524           // The edge geometry has no 2D representation
525           aTool.ComputePCurve(Standard_True);
526         }
527       }
528       
529       // ----------------------------------------------------------
530       // CASE 3 : The EdgeCurve Geometry is not a Pcurve 
531       //          nor a SurfaceCurve (i.e. it is a single 3D curve)
532       // ----------------------------------------------------------
533
534       else {
535         aTool.ComputePCurve(Standard_True);
536         hasPcurve = Standard_False;
537       }
538       
539       // ----------------------------------
540       // update the edge with the pcurve(s)
541       // ----------------------------------
542
543       if (hasPcurve && (isSeam || ThereIsLikeSeam)) {
544
545       // -----------------------------------------------------------
546       // The Edge is a Seam Edge : The pcurve wich is FORWARD has to
547       //                           be identified
548       // -----------------------------------------------------------
549       
550         if ((!C2d1.IsNull()) && (!C2d2.IsNull())) {
551           TopAbs_Orientation CumulO, EdgeO, WireO, FaceO;
552           EdgeO = E.Orientation();
553           if (ForwardWire)  WireO = TopAbs_FORWARD;
554           else              WireO = TopAbs_REVERSED;
555           if (sameSense) FaceO = TopAbs_FORWARD;
556           else           FaceO = TopAbs_REVERSED;
557
558           CumulO = TopAbs::Compose(EdgeO, WireO);
559           CumulO = TopAbs::Compose(CumulO, FaceO);
560
561           Standard_Boolean ForwardEdge = (CumulO == TopAbs_FORWARD);
562
563           // if(!ThereIsLikeSeam) ForwardEdge = Standard_True;
564           Standard_Integer forwardPC =
565             ShapeAnalysis_Curve().SelectForwardSeam (C2d1,C2d2);
566           if (forwardPC == 0) {
567             TP->AddFail(StepEdge," Seam curve not mapped");
568             done = Standard_False;
569             myError = StepToTopoDS_TranslateEdgeLoopOther;
570             continue;
571           }
572           else if (!ForwardEdge) forwardPC = 3 - forwardPC;  // inverser 1-2
573
574           if (forwardPC == 1) {
575             if(isSeam) {
576               // When the edge is a Seam, it is better to find the topological
577               // trimming right now. 
578               // Remarque : pour bien faire, il faudrait, si necessaire, recalculer
579               //            les trois courbes de maniere a ce qu`elles soient
580               //            immediatement Same Range et Same Parameter.
581               B.UpdateEdge(E, C2d1, C2d2, Face, 0.);
582 //:S4136              FindParameter(C2d1, C2d2, E, Face, preci);
583             }
584             else
585               B.UpdateEdge(E, C2d1, Face, 0.); //preci
586           }
587           else {
588             if(isSeam) {
589               // When the edge is a Seam, it is better to find the topological
590               // trimming right now. 
591               B.UpdateEdge(E, C2d2, C2d1, Face, 0.);
592 //:S4136              FindParameter(C2d1, C2d2, E, Face, preci);
593             }
594             else
595               B.UpdateEdge(E, C2d2, Face, 0.);
596           }
597         }
598         else {
599           TP->AddFail(StepEdge," Seam curve not mapped");
600           done = Standard_False;
601           myError = StepToTopoDS_TranslateEdgeLoopOther;
602           continue;
603         }
604       }
605       else {
606         
607         // ---------------------------
608         // The Edge is a "normal" edge
609         // ---------------------------
610         
611         if (hasPcurve) {
612           if ( !C2d.IsNull() && !isLikeSeam ) {
613             B.UpdateEdge(E, C2d, Face, 0.);
614           }
615           else {
616             TP->AddFail(StepEdge," Edge: Trimming of 2D curve failed");
617             //    cout << "2D curve type : " << C2d->DynamicType() << endl;
618             done = Standard_False;
619             myError = StepToTopoDS_TranslateEdgeLoopOther;
620             continue;
621           }
622         }
623       }
624
625       if (!E.IsNull()) {
626 //      B.Add(W,E);   -- DABORD regarder degeneree manquante !!!
627       }
628       else {
629         TP->AddFail(StepEdge," an Edge not mapped");
630         done = Standard_False;
631         myError = StepToTopoDS_TranslateEdgeLoopOther;
632 //      continue;
633       }
634     }
635     else { // The Edge is Not mapped => switch to next wire ?
636       TP->AddFail(StepEdge," an Edge not mapped");
637       done = Standard_False;
638       myError = StepToTopoDS_TranslateEdgeLoopOther;
639 //      continue;
640     }
641
642     if (done) B.Add (W,E);  // on le fait ici. Sauf si erreur rencontree ... !
643     else {
644       Handle(StepShape_Vertex) Vs1, Vs2;
645       Vs1 = StepEdge->EdgeStart();
646       Vs2 = StepEdge->EdgeEnd();
647       if(!Vs1.IsNull() && !Vs2.IsNull() && Vs1==Vs2) {
648         done = Standard_True;
649         TP->AddFail(EL," Edge with equal vertices failed, scipped");
650       }
651     }
652   }
653
654   // The EdgeLoop is binded in the Wire
655
656   if (!done) {
657     TP->AddFail(EL,"At least one edge failed : wire not done");
658     return;
659   }
660   aTool.Bind(EL, W);
661   
662   // ----------------------------------------------
663   // Computes the 2D parameter of Vertices on Edges
664   // ----------------------------------------------
665   //pdn compute parameter of Vertices using progecting
666   if (!aTool.ComputePCurve()) 
667     for (TopoDS_Iterator EdgeIt(W);EdgeIt.More();EdgeIt.Next()){
668       TopoDS_Edge edge = TopoDS::Edge(EdgeIt.Value());
669       Handle(ShapeFix_EdgeProjAux) myEdgePro = ShapeAlgo::AlgoContainer()->ToolContainer()->EdgeProjAux();
670       myEdgePro->Init (Face, edge);
671       myEdgePro->Compute(preci);
672       if (myEdgePro->IsFirstDone() && myEdgePro->IsLastDone()) {
673         if (Abs (myEdgePro->FirstParam() - myEdgePro->LastParam()) < Precision::PConfusion())
674           continue;
675         B.Range(edge, Face,myEdgePro->FirstParam(), myEdgePro->LastParam());
676       }
677       else {
678         RemoveSinglePCurve(edge, Face);
679 #ifdef DEBUG
680         cout <<"Removing after prj"<<endl;
681 #endif
682       }
683     }       
684     
685   myResult = W;
686   myError  = StepToTopoDS_TranslateEdgeLoopDone;
687   done     = Standard_True;
688   //  Check des PCurves SYSTEMATIQUE, s il n y en a que quelques unes
689 //  if (isPlane) RemovePCurves (W, Face);
690 // else         CheckPCurves  (W, Face);
691   CheckPCurves  (W, Face,isPlane,preci);
692
693   // --------------------------------------------      
694   // Control the UVLoop (Closed and Head To Tail)
695   // --------------------------------------------
696   
697 //  StepToTopoDS_GeometricToolError tError = 
698 //    StepToTopoDS_GeometricTool::CloseUV(W, Face, aTool);
699 //  if(tError != StepToTopoDS_GeometricToolDone) {
700 //    TP->AddWarning(StepEdge,StepToTopoDS::DecodeGeometricToolError(tError));
701 //  }
702   return;
703 }
704
705
706 // ============================================================================
707 // Method  : Value 
708 // Purpose : Return the mapped Shape
709 // ============================================================================
710
711 const TopoDS_Shape& StepToTopoDS_TranslateEdgeLoop::Value() const 
712 {
713   StdFail_NotDone_Raise_if(!done,"");
714   return myResult;
715 }
716
717 // ============================================================================
718 // Method  : Error
719 // Purpose : Return the TranslateEdgeLoop error
720 // ============================================================================
721
722 StepToTopoDS_TranslateEdgeLoopError StepToTopoDS_TranslateEdgeLoop::Error() const
723 {
724   return myError;
725 }
726