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