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