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