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