39153cc20b5af9ef88193063d71c9158514c7c1d
[occt.git] / src / BRepToIGES / BRepToIGES_BRWire.cxx
1 // Created on: 1995-01-27
2 // Created by: Marie Jose MARTZ
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 //:q4 abv 16.03.99: PRO17828 face 555: transform pcurves on SurfaceOfRevolution
18 //szv#4 S4163
19 //S4181 pdn implementing of writing IGES elementary surfaces.
20
21 #include <BRepToIGES_BRWire.ixx>
22
23 #include <BRep_Tool.hxx>
24 #include <BRepTools.hxx>
25 #include <BRepTools_WireExplorer.hxx>
26
27 #include <gp.hxx>
28 #include <gp_Ax2d.hxx>
29 #include <gp_Dir2d.hxx>
30 #include <gp_Pln.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Trsf.hxx>
33 #include <gp_Trsf2d.hxx>
34
35 #include <Geom_CartesianPoint.hxx>
36 #include <Geom_ConicalSurface.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_CylindricalSurface.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <Geom_SphericalSurface.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_SurfaceOfLinearExtrusion.hxx>
44 #include <Geom_SurfaceOfRevolution.hxx>
45 #include <Geom_ToroidalSurface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_Line.hxx>
50
51 #include <GeomToIGES_GeomPoint.hxx>
52 #include <GeomToIGES_GeomCurve.hxx>
53
54 #include <Geom2dToIGES_Geom2dCurve.hxx>
55
56 #include <IGESData_HArray1OfIGESEntity.hxx>
57 #include <IGESData_IGESEntity.hxx>
58 #include <IGESData_IGESModel.hxx>
59
60 #include <IGESGeom_CompositeCurve.hxx>
61 #include <IGESGeom_Point.hxx>
62
63 #include <Interface_Macros.hxx>
64
65 #include <Precision.hxx>
66
67 #include <TColStd_HSequenceOfTransient.hxx>
68
69 #include <TopoDS.hxx>
70 #include <TopoDS_Vertex.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Wire.hxx>
73 #include <TopoDS_Shape.hxx>
74
75 #include <TopAbs_ShapeEnum.hxx>
76 #include <TopAbs_Orientation.hxx>
77 #include <TopExp.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <Interface_Static.hxx>
80 #include <ShapeBuild_Edge.hxx>
81 #include <Geom_OffsetSurface.hxx>
82 #include <ShapeExtend_WireData.hxx>
83 #include <ShapeFix_Wire.hxx>
84
85
86 //=============================================================================
87 // BRepToIGES_BRWire
88 //=============================================================================
89
90 BRepToIGES_BRWire::BRepToIGES_BRWire()
91 {
92 }
93
94
95 //=============================================================================
96 // BRepToIGES_BRWire
97 //=============================================================================
98
99 BRepToIGES_BRWire::BRepToIGES_BRWire
100 (const BRepToIGES_BREntity& BR)
101 : BRepToIGES_BREntity(BR)
102 {
103 }
104
105
106 //=============================================================================
107 // TransferWire
108 //=============================================================================
109
110 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
111 (const TopoDS_Shape& start)
112 {
113   Handle(IGESData_IGESEntity) res;
114
115   if (start.IsNull())  return  res;
116
117   if (start.ShapeType() == TopAbs_VERTEX) {
118     TopoDS_Vertex V =  TopoDS::Vertex(start);
119     res = TransferVertex(V);
120   }  
121   else if (start.ShapeType() == TopAbs_EDGE) {
122     TopoDS_Edge E =  TopoDS::Edge(start);
123     res = TransferEdge(E, Standard_False);
124   }  
125   else if (start.ShapeType() == TopAbs_WIRE) {
126     TopoDS_Wire W =  TopoDS::Wire(start);
127     res = TransferWire(W);
128   }  
129   else {
130     // error message
131   }  
132   return res;
133 }
134
135
136 //=============================================================================
137 // TransferVertex
138 // 
139 //=============================================================================
140
141 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
142 (const TopoDS_Vertex& myvertex)
143 {
144   Handle(IGESData_IGESEntity) res;
145   if ( myvertex.IsNull()) return res;
146
147   Handle(Geom_CartesianPoint) Point;
148   Point = new Geom_CartesianPoint(BRep_Tool::Pnt(myvertex));
149   Handle(IGESData_IGESEntity) IVertex;
150   if (!Point.IsNull()) {
151     GeomToIGES_GeomPoint GP;
152     GP.SetModel(GetModel());
153     IVertex = GP.TransferPoint(Point);
154   }
155
156   if (!IVertex.IsNull()) res = IVertex;
157   return res;
158 }
159
160
161 //=============================================================================
162 // TransferVertex
163 // 
164 //=============================================================================
165
166 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
167 (const TopoDS_Vertex& myvertex,
168  const TopoDS_Edge&   myedge,
169  Standard_Real&       parameter)
170 {
171   Handle(IGESData_IGESEntity) res;
172   if ( myvertex.IsNull()) return res;
173
174   Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
175
176   // returns the parameter of myvertex on myedge
177   parameter = BRep_Tool::Parameter(myvertex,myedge);
178
179   if (!IVertex.IsNull()) res = IVertex;
180   return res;
181 }
182
183
184 //=============================================================================
185 // TransferVertex
186 // 
187 //=============================================================================
188
189 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
190 (const TopoDS_Vertex& myvertex,
191  const TopoDS_Edge&   myedge,
192  const TopoDS_Face&   myface,
193  Standard_Real&       parameter)
194 {
195   Handle(IGESData_IGESEntity) res;
196   if ( myvertex.IsNull()) return res;
197
198   Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
199
200   // returns the parameter of myvertex on the pcurve of myedge on myface
201   parameter = BRep_Tool::Parameter(myvertex, myedge, myface);
202
203   if (!IVertex.IsNull()) res = IVertex;
204   return res;
205 }
206
207
208 //=============================================================================
209 // TransferVertex
210 // 
211 //=============================================================================
212
213 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
214 (const TopoDS_Vertex&          myvertex,
215  const TopoDS_Edge&            myedge,
216  const Handle(Geom_Surface)&   mysurface,
217  const TopLoc_Location&        myloc,
218  Standard_Real&                parameter)
219 {
220   Handle(IGESData_IGESEntity) res;
221   if ( myvertex.IsNull()) return res;
222
223   Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
224
225   // returns the parameter of myvertex on the pcurve of myedge on mysurface
226   parameter = BRep_Tool::Parameter(myvertex, myedge, mysurface, myloc);
227
228   if (!IVertex.IsNull()) res = IVertex;
229   return res;
230 }
231
232
233 //=============================================================================
234 // TransferVertex
235 // 
236 //=============================================================================
237
238 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
239 (const TopoDS_Vertex& myvertex,
240  const TopoDS_Face&   myface,
241        gp_Pnt2d&      mypoint)
242 {
243   Handle(IGESData_IGESEntity) res;
244   if ( myvertex.IsNull()) return res;
245
246   Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
247
248   // returns the parameter of myvertex on myface
249   mypoint = BRep_Tool::Parameters(myvertex, myface);
250
251   if (!IVertex.IsNull()) res = IVertex;
252   return res;
253 }
254
255
256 //=============================================================================
257 // TransferEdge
258 //=============================================================================
259
260 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferEdge
261 (const TopoDS_Edge&     myedge,
262  const Standard_Boolean isBRepMode)
263 {
264   Handle(IGESData_IGESEntity) res;
265   if ( myedge.IsNull()) return res;
266
267   // returns the 3d curve of the edge and the parameter range
268   TopLoc_Location L;
269   Standard_Real First, Last, U1, U2;
270   Handle(IGESData_IGESEntity) ICurve;
271   Handle(Geom_Curve) Curve3d = BRep_Tool::Curve(myedge, L, First, Last);
272
273   //#28 rln 19.10.98 UKI60155, etc.
274   //Only Bezier will be converted into B-Spline, not Conic. This conertation
275   //will be done only inside GeomToIGES package for simplifying the code.
276
277   //#29 rln 19.10.98
278   //Unnecessary duplication of curves is removed.
279
280   if (!Curve3d.IsNull()) {
281     gp_Trsf Tr = L.Transformation();
282     if (Tr.Form() != gp_Identity)
283       Curve3d = Handle(Geom_Curve)::DownCast(Curve3d->Transformed (Tr));
284     else
285       Curve3d = Handle(Geom_Curve)::DownCast(Curve3d->Copy()); 
286
287     if (myedge.Orientation() == TopAbs_REVERSED && !isBRepMode) {
288       U1 = Curve3d->ReversedParameter(Last);
289       U2 = Curve3d->ReversedParameter(First);
290       Curve3d->Reverse();
291     }
292     else {
293       U1 = First;
294       U2 = Last;
295     }
296
297     GeomToIGES_GeomCurve GC;
298     GC.SetModel(GetModel());
299     ICurve = GC.TransferCurve(Curve3d, U1, U2);
300   }
301
302   //#31 rln 19.10.98
303   //Vertices are not translated into IGES anymore since they are not put into
304   //the model
305
306   if (!ICurve.IsNull()) res = ICurve;
307
308   SetShapeResult ( myedge, res );
309
310   return res;
311 }
312
313
314 //=============================================================================
315 // TransferEdge
316 //=============================================================================
317
318 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferEdge (const TopoDS_Edge& myedge,
319                                                               const TopoDS_Face& myface,
320                                                               const Standard_Real length,
321                                                               const Standard_Boolean isBRepMode)
322 {
323   Handle(IGESData_IGESEntity) res;
324   if ( myedge.IsNull() || GetPCurveMode() ==0 ||
325        ( ! isBRepMode && BRep_Tool::Degenerated ( myedge ) ) ) return res;
326
327   //S4181 pdn 23.04.99 adjusting length factor according to analytic mode.
328   Standard_Real myLen = length;
329   Standard_Boolean analyticMode = ( GetConvertSurfaceMode() ==0 && isBRepMode );
330   
331   // returns the 2d curve associated to myedge in the parametric space of myface
332   Standard_Real First, Last;
333   Handle(Geom2d_Curve) Curve2d = BRep_Tool::CurveOnSurface(myedge, myface, First, Last);
334   Handle(IGESData_IGESEntity) ICurve2d;
335   //#29 rln 19.10.98
336
337   if (!Curve2d.IsNull()) {
338     // For "revolution" and "LinearExtrusion" surfaces, it is necessary
339     // to apply a translation of 2D curves to agree on the 
340     // origin (U,V) between IGES and BRep (for Cylindrical,
341     // Conical and SurfaceOfLinearExtrusion)
342     // It is necessary to invert (u,v) surfaces of revolution.
343     
344     TopLoc_Location L;
345     Handle(Geom_Surface) st = BRep_Tool::Surface(myface, L);
346     if (st->IsKind(STANDARD_TYPE(Geom_Plane))){
347       return res;
348     }
349     Standard_Real Ufirst, Ulast, Vfirst, Vlast;
350     BRepTools::UVBounds(myface, Ufirst, Ulast, Vfirst, Vlast);
351     Handle(Geom_Surface) Surf;
352
353     if (st->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
354       DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, st);
355       Surf = rectang->BasisSurface();
356     }
357     else 
358       Surf = st;
359
360     //:abv 19.06.02: writing (loopback) on file offseted_sphere.rle in BRep mode
361     if (st->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) { 
362       DeclareAndCast(Geom_OffsetSurface, offset, Surf);
363       Surf = offset->BasisSurface();
364     }
365
366     //S4181 pdn 20.04.99 transformation of pcurves id defined by type of surface 
367     // and analytic mode.
368     // skl 18.07.2005 for OCC9490 : in following if() commented
369     // condition for SurfaceOfLinearExtrusion
370     Standard_Boolean needShift = (!analyticMode&&
371                                   ((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) ||
372                                    (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))/* ||
373                                    (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))*/));
374     //:q4 abv 16 Mar 99: PRO17828 face 555: shift pcurves on SurfaceOfRevolution
375     if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { 
376       Handle(Geom_SurfaceOfRevolution) rev = 
377         Handle(Geom_SurfaceOfRevolution)::DownCast ( Surf );
378       Handle(Geom_Curve) curve = rev->BasisCurve();
379       // skl 31.05.2004 for OCC6004
380       if(curve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
381         Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(curve);
382         curve = tc->BasisCurve();
383       }
384       if ( curve->IsKind(STANDARD_TYPE(Geom_Line)) ) needShift = Standard_True;
385     }
386     if ( needShift ) {
387       gp_Trsf2d TR;
388       TR.SetTranslation(gp_Pnt2d(0.,0.),gp_Pnt2d(0.,-Vfirst)); 
389       Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Transformed(TR));
390     }
391     else Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Copy());
392
393     if (!analyticMode&&((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))  ||
394                         (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))      ||
395                         (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))))) {
396       //#30 rln 19.10.98 transformation of pcurves for IGES Surface of Revolution
397       Curve2d->Mirror (gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
398       Curve2d->Mirror (gp::OX2d());
399       Curve2d->Translate (gp_Vec2d (0, 2 * M_PI));
400     }
401     
402     if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))||
403        (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))){
404       Curve2d->Mirror (gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
405       Curve2d->Mirror (gp::OX2d());
406       Curve2d->Translate (gp_Vec2d (0, 2 * M_PI));
407     }
408     
409     if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
410                        Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))))
411       myLen = M_PI/180.;
412     
413     if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
414                        Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))) {
415       gp_Trsf2d trans;
416       trans.SetScale(gp_Pnt2d(0,0),180./M_PI);
417       Curve2d->Transform(trans);
418       First = Curve2d->TransformedParameter(First,trans);
419       Last  = Curve2d->TransformedParameter(Last, trans);
420     }
421     
422     if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))) {
423       Handle(Geom_ConicalSurface) con = Handle(Geom_ConicalSurface)::DownCast ( Surf );
424       if(con->SemiAngle() < 0) {
425         Standard_Real vApex = 2 * con->RefRadius() / Sin (con->SemiAngle());
426         Curve2d->Translate (gp_Vec2d (0, vApex));
427       }
428     }
429     //S4181 transfer functionality
430     gp_Trsf2d trans;
431     Standard_Real uFact = 1.;
432     if(isBRepMode && Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
433       trans.SetScale(gp_Pnt2d(0,0),1./GetUnit());
434     }
435     if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
436       Standard_Real aDiv = myLen;
437       if(aDiv < gp::Resolution())
438         aDiv = 1.;
439       //emv: changed for bug OCC22126 17.12.2010
440       trans.SetScale(gp_Pnt2d(0,0), 1. / (Vlast - Vfirst));
441       //uFact = myLen; 
442       
443       //added by skl 18.07.2005 for OCC9490
444 //      trans.SetScale(gp_Pnt2d(0,0),1./Vlast);
445
446       Standard_Real du = 1.;
447       Standard_Real us1,us2,vs1,vs2;
448       //scaling parameterization to [0,1]
449       Surf->Bounds(us1,us2,vs1,vs2);
450       du = us2-us1;
451       //emv: changed for bug OCC22126 17.12.2010
452       uFact = (Vlast - Vfirst)/du;
453       //uFact = aDiv/du;
454     }
455     if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
456         Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)) ||
457         Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { //:q4
458       uFact = 1./myLen; 
459     }
460     
461     ShapeBuild_Edge sbe;
462     Curve2d = sbe.TransformPCurve(Curve2d,trans,uFact,First,Last);
463 //      (Curve2d, Surf, First, Last, myLen, isBRepMode);
464     // if the edge is REVERSED, it is necessary to "REVERSE" the curve 2d.
465
466     // added by skl 18.07.2005 for OCC9490
467     if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
468       //emv: changed for bug OCC22126 17.12.2010
469       gp_Trsf2d trans1;
470       Standard_Real us1,us2,vs1,vs2,du;
471       //computing shift of pcurves
472       Surf->Bounds(us1,us2,vs1,vs2);
473       du = us2-us1;
474       trans1.SetTranslation(gp_Vec2d(-us1/du,-Vfirst/(Vlast-Vfirst)));
475       Curve2d = sbe.TransformPCurve(Curve2d,trans1,1.,First,Last);
476     }
477
478     if (myedge.Orientation() == TopAbs_REVERSED) {
479       Standard_Real tmpFirst = Curve2d->ReversedParameter(Last),
480                     tmpLast  = Curve2d->ReversedParameter(First);
481       Curve2d->Reverse();
482       First = tmpFirst;
483       Last  = tmpLast;
484     }
485     Geom2dToIGES_Geom2dCurve GC;
486     GC.SetModel(GetModel());
487     ICurve2d = GC.Transfer2dCurve(Curve2d, First, Last);
488   }
489
490   //#31 rln 19.10.98
491   //Vertices are not translated into IGES anymore since they are not put into
492   //the model
493
494   if (!ICurve2d.IsNull()) res = ICurve2d;
495
496   SetShapeResult ( myedge, res );
497
498   return res;
499 }
500
501
502 //=============================================================================
503 // TransferWire
504 //=============================================================================
505
506 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
507 (const TopoDS_Wire& mywire)
508 {
509   Handle(IGESData_IGESEntity) res;
510   if ( mywire.IsNull()) return res;
511
512   //A composite curve is defined as an ordered list of entities
513   //consisting of a point, connect point and parametrised curve
514   //entities (excluding the CompositeCurve entity).
515
516   Handle(IGESData_IGESEntity) ent ;
517   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
518
519   TopExp_Explorer TE(mywire, TopAbs_VERTEX);
520   if ( TE.More()) {
521     BRepTools_WireExplorer WE;
522     for ( WE.Init(mywire); WE.More(); WE.Next()) {
523       TopoDS_Edge E = WE.Current();
524       if (E.IsNull()) {
525         AddWarning(mywire, "an Edge is a null entity");
526       }
527       else {
528               ent = TransferEdge(E, Standard_False);
529               if (!ent.IsNull()) Seq->Append(ent);
530       }
531     }
532   }
533   else 
534     AddWarning(mywire, " no Vertex associated to the Wire");
535   
536
537   Standard_Integer nbedges = Seq->Length();
538   Handle(IGESData_HArray1OfIGESEntity) Tab;
539   if ( nbedges == 1 ) {
540     res = GetCasted(IGESData_IGESEntity, Seq->Value(1));
541   }
542   else if ( nbedges >= 2) {
543     Tab =  new IGESData_HArray1OfIGESEntity(1,nbedges);
544     for (Standard_Integer itab = 1; itab <= nbedges; itab++) {
545       Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab));
546       Tab->SetValue(itab,item);
547     }
548     Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
549     Comp->Init(Tab);
550     res = Comp;
551   }
552
553   SetShapeResult ( mywire, res );
554
555   return res;
556 }
557
558
559 //=============================================================================
560 // TransferWire
561 //=============================================================================
562
563 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
564 (const TopoDS_Wire &          mywire,
565  const TopoDS_Face &          myface,
566  Handle(IGESData_IGESEntity)& mycurve2d,
567  const Standard_Real          length)
568 {
569   Handle(IGESData_IGESEntity) res;
570   if ( mywire.IsNull()) return res;
571
572   Handle(IGESData_IGESEntity) ent3d ;
573   Handle(IGESData_IGESEntity) ent2d ;
574   Handle(TColStd_HSequenceOfTransient) Seq3d = new TColStd_HSequenceOfTransient();
575   Handle(TColStd_HSequenceOfTransient) Seq2d = new TColStd_HSequenceOfTransient();
576
577
578   // create a 3d CompositeCurve and a 2d CompositeCurve
579   TopExp_Explorer TE(mywire, TopAbs_VERTEX);
580   if ( TE.More()) {
581     // PTV OCC908 workaround for KAS:dev version
582     /*
583     BRepTools_WireExplorer WE;
584     for ( WE.Init(mywire,myface); WE.More(); WE.Next()) { 
585       TopoDS_Edge E = WE.Current();
586       if (E.IsNull()) {
587         AddWarning(mywire, "an Edge is a null entity");
588       }
589       else {
590         ent3d = TransferEdge(E, Standard_False);
591         if (!ent3d.IsNull()) Seq3d->Append(ent3d);
592         ent2d = TransferEdge(E, myface, length, Standard_False);
593         if (!ent2d.IsNull()) Seq2d->Append(ent2d);
594       }
595     }
596     */
597     Handle(ShapeFix_Wire) aSFW = 
598       new ShapeFix_Wire( mywire, myface, Precision::Confusion() );
599     aSFW->FixReorder();
600     Handle(ShapeExtend_WireData) aSEWD = aSFW->WireData();
601     Standard_Integer nbE = aSEWD->NbEdges();
602     for (Standard_Integer windex = 1; windex <= nbE; windex++) {
603       TopoDS_Edge E = aSEWD->Edge( windex );
604       if (E.IsNull()) {
605         AddWarning(mywire, "an Edge is a null entity");
606       }
607       else {
608         ent3d = TransferEdge(E, Standard_False);
609         if (!ent3d.IsNull()) Seq3d->Append(ent3d);
610         ent2d = TransferEdge(E, myface, length, Standard_False);
611         if (!ent2d.IsNull()) Seq2d->Append(ent2d);
612       }
613     }
614     // OCC908 end of workaround
615   }
616   else 
617     AddWarning(mywire, " no Vertex associated to the Wire");
618   
619   // Composite Curve 3D
620   Standard_Integer nb3d = Seq3d->Length();
621   Handle(IGESData_HArray1OfIGESEntity) Tab3d;
622   if ( nb3d == 1 ) {
623     res = ent3d;
624   }
625   else if (nb3d >= 2) {
626     Tab3d =  new IGESData_HArray1OfIGESEntity(1,nb3d);
627     //Standard_Integer tabval = nb3d; //szv#4:S4163:12Mar99 unused
628     for (Standard_Integer itab = 1; itab <= nb3d; itab++) {
629       Handle(IGESData_IGESEntity) item = 
630         GetCasted(IGESData_IGESEntity, Seq3d->Value(itab));
631       Tab3d->SetValue(itab,item);
632     }
633     Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
634     Comp->Init(Tab3d);
635     res = Comp;
636   }
637
638   // Composite Curve 2D
639   Standard_Integer nb2d = Seq2d->Length();
640   Handle(IGESData_HArray1OfIGESEntity) Tab2d;
641   if ( nb2d == 1 ) {
642     mycurve2d = ent2d;
643   }
644   else if (nb2d >= 2) {
645     Tab2d =  new IGESData_HArray1OfIGESEntity(1,nb2d);
646     //Standard_Integer tabval = nb2d; //szv#4:S4163:12Mar99 unused
647     for ( Standard_Integer itab = 1; itab <= nb2d; itab++) {
648       Handle(IGESData_IGESEntity) item = 
649         GetCasted(IGESData_IGESEntity, Seq2d->Value(itab));
650       Tab2d->SetValue(itab,item);
651     }
652     Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
653     Comp->Init(Tab2d);
654     mycurve2d = Comp;
655   }
656   
657   SetShapeResult ( mywire, res );
658
659   return res;
660 }