0022731: Error on attempt to write in IGES 5.3 the attached brep model
[occt.git] / src / BRepToIGESBRep / BRepToIGESBRep_Entity.cxx
1 // Copyright:   Matra-Datavision 1995
2 // File:        BRepToIGESBRep_Entity.cxx
3 // Created:     Tue Apr 25 11:50:05 1995
4 // Author:      Marie Jose MARTZ
5 //              <mjm>
6
7
8 // modif le 25/03/96 mjm
9 // implement ShapeCustom::DirectModification for indirect surfaces (out of norm IGES)
10 //:l4 abv 12 Jan 99: CTS22022-2: correct writing reversed shells
11 //:n3 abv 8 Feb 99: PRO17820: BRepTools::OuterWire() -> ShapeAnalysis::OuterWire
12 //szv#4 S4163
13 //S4181 pdn 20.04.99 implementing of writing IGES elementary surfaces.
14 //      abv 31.01.00 inheriting from BRepToIGES_BREntity to remove code duplication
15 //eap: Tue Aug 29 11:02:56 2000: Shape Processing moved to upper levels
16
17 #include <BRepToIGESBRep_Entity.ixx>
18
19 #include <BRepToIGES_BRWire.hxx>
20
21 #include <BRepLib.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepTools.hxx>
24 #include <BRepTools_WireExplorer.hxx>
25
26 #include <gp.hxx>
27 #include <gp_Circ2d.hxx>
28 #include <gp_Elips2d.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <gp_Trsf.hxx>
32 #include <gp_XYZ.hxx>
33 #include <gp_Trsf2d.hxx>
34
35 #include <Geom_BezierCurve.hxx>
36 #include <Geom_BSplineCurve.hxx>
37 #include <Geom_CartesianPoint.hxx>
38 #include <Geom_ConicalSurface.hxx>
39 #include <Geom_Circle.hxx>
40 #include <Geom_Curve.hxx>
41 #include <Geom_Ellipse.hxx>
42 #include <Geom_Hyperbola.hxx>
43 #include <Geom_Parabola.hxx>
44 #include <Geom_Plane.hxx>
45 #include <Geom_Surface.hxx>
46 #include <Geom_CylindricalSurface.hxx>
47 #include <Geom_RectangularTrimmedSurface.hxx>
48 #include <Geom_SphericalSurface.hxx>
49 #include <Geom_SurfaceOfLinearExtrusion.hxx>
50 #include <Geom_SurfaceOfRevolution.hxx>
51 #include <Geom_ToroidalSurface.hxx>
52 #include <Geom_TrimmedCurve.hxx>
53
54 //#include <GeomConvert.hxx>
55 //#include <Geom2dConvert.hxx>
56
57 #include <Geom2d_Curve.hxx>
58
59 #include <GeomToIGES_GeomCurve.hxx>
60 #include <GeomToIGES_GeomSurface.hxx>
61
62 #include <Geom2dToIGES_Geom2dCurve.hxx>
63
64 #include <IGESBasic_HArray1OfHArray1OfInteger.hxx>
65 #include <IGESBasic_HArray1OfHArray1OfIGESEntity.hxx>
66 #include <IGESBasic_Group.hxx>
67
68 #include <IGESData_IGESEntity.hxx>
69 #include <IGESData_IGESModel.hxx>
70 #include <IGESData_HArray1OfIGESEntity.hxx>
71
72 #include <IGESGeom_CompositeCurve.hxx>
73 #include <IGESGeom_Point.hxx>
74
75 #include <IGESSolid_Face.hxx>
76 #include <IGESSolid_HArray1OfFace.hxx>
77 #include <IGESSolid_Loop.hxx>
78 #include <IGESSolid_HArray1OfLoop.hxx>
79 #include <IGESSolid_Shell.hxx>
80 #include <IGESSolid_HArray1OfShell.hxx>
81 #include <IGESSolid_ManifoldSolid.hxx>
82 #include <IGESSolid_VertexList.hxx>
83 #include <IGESSolid_HArray1OfVertexList.hxx>
84 #include <IGESSolid_EdgeList.hxx>
85
86 #include <Interface_Macros.hxx>
87
88 //#include <ShapeAnalysis.hxx>
89 //#include <ShapeCustom.hxx>
90
91 #include <TColgp_HArray1OfXYZ.hxx>
92
93 #include <TColStd_HSequenceOfTransient.hxx>
94 #include <TColStd_SequenceOfInteger.hxx>
95 #include <TColStd_HArray1OfInteger.hxx>
96
97 #include <TopAbs_ShapeEnum.hxx>
98 #include <TopAbs_Orientation.hxx>
99
100 #include <TopExp.hxx>
101 #include <TopExp_Explorer.hxx>
102
103 #include <TopLoc_Location.hxx>
104
105 #include <TopoDS.hxx>
106 #include <TopoDS_Compound.hxx>
107 #include <TopoDS_CompSolid.hxx>
108 #include <TopoDS_Edge.hxx>
109 #include <TopoDS_Face.hxx>
110 #include <TopoDS_Solid.hxx>
111 #include <TopoDS_Shape.hxx>
112 #include <TopoDS_Shell.hxx>
113 #include <TopoDS_Vertex.hxx>
114 #include <TopoDS_Wire.hxx>
115
116 #include <Transfer_FinderProcess.hxx>
117 #include <TransferBRep_ShapeMapper.hxx>
118 #include <TransferBRep_OrientedShapeMapper.hxx>
119 #include <Transfer_TransientMapper.hxx>
120 #include <Transfer_SimpleBinderOfTransient.hxx>
121 #include <Interface_Static.hxx>
122
123 #include <ShapeAlgo.hxx>
124 #include <ShapeAlgo_AlgoContainer.hxx>
125 #include <Message_ProgressIndicator.hxx>
126
127 //=======================================================================
128 //function : BRepToIGESBRep_Entity
129 //purpose  : 
130 //=======================================================================
131
132 BRepToIGESBRep_Entity::BRepToIGESBRep_Entity()
133 {  
134   Init();
135   if (myEdgeList.IsNull()) 
136     myEdgeList = new IGESSolid_EdgeList;
137   if (myVertexList.IsNull())
138     myVertexList = new IGESSolid_VertexList;
139 }
140
141
142 //=======================================================================
143 //function : Clear
144 //purpose  : 
145 //=======================================================================
146
147 void BRepToIGESBRep_Entity::Clear()
148 {
149   myVertices.Clear();
150   myEdges.Clear();
151   myCurves.Clear();
152 }
153
154
155 //=============================================================================
156 // TransferVertexList
157 // 
158 //=============================================================================
159
160 void BRepToIGESBRep_Entity::TransferVertexList()
161 {
162
163   Standard_Integer nbvertices = myVertices.Extent();
164   if(!nbvertices)
165     return;
166   Handle(TColgp_HArray1OfXYZ) vertices= new TColgp_HArray1OfXYZ(1,nbvertices);
167   Standard_Real Unit = GetUnit();
168   Standard_Real X,Y,Z;
169
170   for (Standard_Integer ivertex = 1; ivertex <= nbvertices; ivertex++) {
171     TopoDS_Shape myshape = myVertices(ivertex);
172     TopoDS_Vertex myvertex = TopoDS::Vertex(myshape);
173     gp_Pnt Point = BRep_Tool::Pnt(myvertex);
174     Point.Coord(X,Y,Z);
175     vertices->SetValue(ivertex, gp_XYZ(X/Unit,Y/Unit,Z/Unit));
176   }
177
178   myVertexList->Init(vertices);
179 }
180
181
182 //=============================================================================
183 // IndexVertex
184 //=============================================================================
185 Standard_Integer BRepToIGESBRep_Entity::IndexVertex(const TopoDS_Vertex& myvertex) const
186 {
187   TopoDS_Shape V = myvertex;
188   return myVertices.FindIndex(V);
189 }
190
191
192 //=============================================================================
193 // AddVertex
194 // 
195 //=============================================================================
196
197 Standard_Integer BRepToIGESBRep_Entity::AddVertex(const TopoDS_Vertex& myvertex) 
198 {
199   if ( myvertex.IsNull()) return 0;
200   
201   TopoDS_Shape V = myvertex;
202   Standard_Integer index = myVertices.FindIndex(V);
203   if (index == 0) {
204     index = myVertices.Add(V);
205   }
206   
207   return index;
208 }
209
210
211 //=============================================================================
212 // TransferEdgeList
213 // 
214 //=============================================================================
215
216 void BRepToIGESBRep_Entity::TransferEdgeList()
217 {
218
219   Handle(IGESSolid_VertexList) TheVertexList = myVertexList;
220
221   Handle(IGESData_IGESEntity) mycurve;
222   Standard_Integer mystartindex, myendindex;
223   Handle(IGESSolid_VertexList) mystartlist;
224   Handle(IGESSolid_VertexList) myendlist;
225
226   Standard_Integer nbedges = myEdges.Extent();
227   if(!nbedges)
228     return;
229   Handle(IGESData_HArray1OfIGESEntity) Curves= 
230     new IGESData_HArray1OfIGESEntity(1,nbedges);
231   Handle(IGESSolid_HArray1OfVertexList) startVertexList = 
232     new IGESSolid_HArray1OfVertexList(1,nbedges);
233   Handle(TColStd_HArray1OfInteger) startVertexIndex = 
234     new TColStd_HArray1OfInteger(1,nbedges);
235   Handle(IGESSolid_HArray1OfVertexList) endVertexList = 
236     new IGESSolid_HArray1OfVertexList(1,nbedges);
237   Handle(TColStd_HArray1OfInteger) endVertexIndex = 
238     new TColStd_HArray1OfInteger(1,nbedges);
239
240   for (Standard_Integer iedge = 1; iedge <= nbedges; iedge++) {
241     TopoDS_Shape myshape = myEdges(iedge);
242     TopoDS_Edge myedge = TopoDS::Edge(myshape);
243     //  the curve 3D
244     DeclareAndCast(IGESData_IGESEntity, amycurve, myCurves(iedge));
245     Curves->SetValue(iedge, amycurve);
246     TopoDS_Vertex V1, V2;
247     TopExp::Vertices(myedge, V1, V2);
248     //  vertices follow the orientation of curve 3d
249     mystartindex = IndexVertex(V1);
250     myendindex = IndexVertex(V2);
251     startVertexIndex->SetValue(iedge, mystartindex);
252     endVertexIndex->SetValue(iedge, myendindex);
253     startVertexList->SetValue(iedge, TheVertexList);
254     endVertexList->SetValue(iedge, TheVertexList);
255   }
256
257   myEdgeList->Init
258     (Curves, startVertexList, startVertexIndex, endVertexList, endVertexIndex);
259 }
260
261
262 //=============================================================================
263 // IndexEdge
264 //=============================================================================
265 Standard_Integer BRepToIGESBRep_Entity::IndexEdge(const TopoDS_Edge& myedge) const
266 {
267   TopoDS_Shape E = myedge;
268   return myEdges.FindIndex(E);
269 }
270
271
272 //=============================================================================
273 // AddEdge
274 // 
275 //=============================================================================
276
277 Standard_Integer BRepToIGESBRep_Entity::AddEdge(const TopoDS_Edge& myedge,
278                                                 const Handle(IGESData_IGESEntity)& mycurve3d)
279 {
280   if ( myedge.IsNull()) return 0;
281   
282   TopoDS_Shape E = myedge;
283   Handle(IGESData_IGESEntity) C = mycurve3d;
284   Standard_Integer index = myEdges.FindIndex(E);
285   if (index == 0) {
286     index = myEdges.Add(E);
287     myCurves.Add(C);
288   }
289   
290   return index;
291 }
292
293
294 //=======================================================================
295 //function : TransferShape
296 //purpose  : 
297 //=======================================================================
298 Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferShape
299 (const TopoDS_Shape& start)
300 {
301   Handle(IGESData_IGESEntity) res;
302   //TopoDS_Shape theShape;
303
304   if (start.IsNull()) return res;
305
306   if (start.ShapeType() == TopAbs_VERTEX) {
307     AddWarning (start, " A Vertex alone is not a IGESBRep Entity");
308     TopoDS_Vertex V = TopoDS::Vertex(start);
309     BRepToIGES_BRWire BW(*this);
310     BW.SetModel(GetModel());
311     res = BW.TransferVertex(V);
312     return res;
313   }  
314   else if (start.ShapeType() == TopAbs_EDGE) {
315     AddWarning (start, " An Edge alone is not a IGESBRep Entity");
316     TopoDS_Edge E =  TopoDS::Edge(start);
317     BRepToIGES_BRWire BW(*this);
318     BW.SetModel(GetModel());
319     res = BW.TransferEdge(E, Standard_False);
320     return res;
321   }  
322   else if (start.ShapeType() == TopAbs_WIRE) {
323     AddWarning (start, " An Wire alone is not a IGESBRep Entity");
324     TopoDS_Wire W =  TopoDS::Wire(start);
325     BRepToIGES_BRWire BW(*this);
326     BW.SetModel(GetModel());
327     res = BW.TransferWire(W);
328     return res;
329   }  
330   else { 
331 //    theShape = ShapeCustom::DirectFaces(start);
332     if (start.ShapeType() == TopAbs_FACE) {
333       TopoDS_Face F =  TopoDS::Face(start);
334       res = TransferFace(F);
335     }  
336     else if (start.ShapeType() == TopAbs_SHELL) {
337       TopoDS_Shell S =  TopoDS::Shell(start);
338       res = TransferShell(S);
339     }  
340     else if (start.ShapeType() == TopAbs_SOLID) {
341       TopoDS_Solid M =  TopoDS::Solid(start);
342       res = TransferSolid(M);
343     }  
344     else if (start.ShapeType() == TopAbs_COMPSOLID) {
345       TopoDS_CompSolid C =  TopoDS::CompSolid(start);
346       res = TransferCompSolid(C);
347     }  
348     else if (start.ShapeType() == TopAbs_COMPOUND) {
349       TopoDS_Compound C =  TopoDS::Compound(start);
350       res = TransferCompound(C);
351     }  
352     else {
353       // error message
354     }  
355   }
356   if(res.IsNull())
357     return res;
358
359   TransferVertexList();
360   TransferEdgeList();
361   return res;
362 }
363
364
365 //=============================================================================
366 // TransferEdge
367 //=============================================================================
368
369 Handle(IGESData_IGESEntity)  BRepToIGESBRep_Entity::TransferEdge (const TopoDS_Edge& myedge)
370 {
371   BRepToIGES_BRWire BR(*this);
372   BR.SetModel(GetModel());
373   return BR.TransferEdge (myedge, Standard_True);
374 }
375
376
377 //=============================================================================
378 // TransferEdge
379 //=============================================================================
380
381 Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferEdge (const TopoDS_Edge& myedge,
382                                                                  const TopoDS_Face& myface,
383                                                                  const Standard_Real Length)
384 {
385   Handle(IGESData_IGESEntity) ICurve3d;
386   Handle(IGESData_IGESEntity) ICurve2d;
387   if ( myedge.IsNull()) return ICurve2d;
388
389   BRepToIGES_BRWire BR(*this);
390   BR.SetModel(GetModel());
391   ICurve2d = BR.TransferEdge (myedge, myface, Length, Standard_True);
392
393   // curve 3d is obligatory. If it does not exist it is created and stored in "myCurves".
394   // If the edge is degenerated, there is no associated 3d. So "edge-tuple" 
395   // will be a Vertex.
396
397   if (!BRep_Tool::Degenerated(myedge)) {
398     ICurve3d = TransferEdge(myedge);
399     if (ICurve3d.IsNull()) {
400       AddFail (myedge, " Transfer Failed : no Curve 3D ");
401     }
402     AddEdge(myedge, ICurve3d);
403   }
404     
405   return ICurve2d;
406 }
407
408
409 //=============================================================================
410 // TransferWire
411 //=============================================================================
412
413 Handle(IGESSolid_Loop) BRepToIGESBRep_Entity::TransferWire (const TopoDS_Wire& mywire,
414                                                             const TopoDS_Face& myface,
415                                                             const Standard_Real Length)
416 {
417   Handle(IGESSolid_Loop) myLoop = new IGESSolid_Loop;
418   if ( mywire.IsNull()) return myLoop;
419   Handle(IGESData_IGESEntity) Pointeur;
420
421   TColStd_SequenceOfInteger Seqindex;
422   TColStd_SequenceOfInteger Seqorient;
423   TColStd_SequenceOfInteger Seqtype;
424   Handle(IGESData_IGESEntity) ent2d ;
425   Handle(IGESData_IGESEntity) ent3d ;
426   Handle(TColStd_HSequenceOfTransient) Seq2d = new TColStd_HSequenceOfTransient();
427
428   BRepTools_WireExplorer WE;
429   //Standard_Integer nbedge = 0; //szv#4:S4163:12Mar99 unused
430   TopExp_Explorer TE(mywire, TopAbs_VERTEX);
431   if ( TE.More()) {
432     for ( WE.Init(mywire,myface); WE.More(); WE.Next()) { 
433       TopoDS_Edge E = WE.Current();
434       if (E.IsNull()) {
435         AddWarning(mywire, "an Edge is a null entity");
436       }
437       else {
438         ent2d = TransferEdge(E, myface, Length);
439         Seq2d->Append(ent2d);
440         Standard_Integer myindex; 
441
442         // add Vertices in the Map "myVertices"
443         TopoDS_Vertex V1, V2;
444         TopExp::Vertices(E, V1, V2);
445         //Standard_Integer Ivertex1, Ivertex2; //szv#4:S4163:12Mar99 not needed
446         if (!BRep_Tool::Degenerated(E)) {
447           if ( !V1.IsNull()) {
448             AddVertex(V1); //szv#4:S4163:12Mar99 `Ivertex1=` not needed
449           }
450           if ( !V2.IsNull()) {
451             AddVertex(V2); //szv#4:S4163:12Mar99 `Ivertex2=` not needed
452           }
453           myindex = IndexEdge(E);
454           Seqtype.Append(0);
455         }
456         else {
457           myindex = AddVertex(V1);
458           Seqtype.Append(1);
459         }
460         Seqindex.Append(myindex);
461         if (E.Orientation() == TopAbs_FORWARD ) Seqorient.Append(1);
462         if (E.Orientation() == TopAbs_REVERSED) Seqorient.Append(0); 
463       }
464     }
465   }
466   else 
467     AddWarning(mywire, " no Vertex associated to the Wire");
468
469   Standard_Integer nbedges = Seq2d->Length();
470   Handle(TColStd_HArray1OfInteger) types = new TColStd_HArray1OfInteger(1,nbedges);
471   Standard_Integer mytype;
472   Handle(IGESData_HArray1OfIGESEntity) edges = new IGESData_HArray1OfIGESEntity(1,nbedges);
473   Handle(IGESData_IGESEntity) myedge;
474   Handle(TColStd_HArray1OfInteger) index = new TColStd_HArray1OfInteger(1,nbedges);
475   Standard_Integer myindex;
476   Handle(TColStd_HArray1OfInteger) orient = new TColStd_HArray1OfInteger(1,nbedges);
477   Standard_Integer myorient;
478   Handle(TColStd_HArray1OfInteger) nbcurves = new TColStd_HArray1OfInteger(1,nbedges);
479   Standard_Integer mynbcurve;
480   Handle(TColStd_HArray1OfInteger) flag;
481   Handle(IGESBasic_HArray1OfHArray1OfInteger) isoflags = 
482     new IGESBasic_HArray1OfHArray1OfInteger(1,nbedges);
483   Standard_Integer myisoflag;
484   Handle(IGESData_HArray1OfIGESEntity) curve;
485   Handle(IGESBasic_HArray1OfHArray1OfIGESEntity) curves = 
486     new IGESBasic_HArray1OfHArray1OfIGESEntity(1,nbedges);
487   Handle(IGESData_IGESEntity) mycurve;
488
489
490   for (Standard_Integer itab = 1; itab <= nbedges; itab++) {
491     mytype = Seqtype.Value(itab);
492     types->SetValue(itab,mytype);
493     if ( mytype == 0) 
494       Pointeur = myEdgeList;
495     else
496       Pointeur = myVertexList;
497     edges->SetValue(itab,Pointeur);
498     myindex = Seqindex.Value(itab);
499     index->SetValue(itab, myindex);
500     myorient = Seqorient.Value(itab);
501     orient->SetValue(itab, myorient);
502     mynbcurve = ( Seq2d->Value(itab).IsNull() ? 0 : 1 ); // abv 31 Jan 00: to be able not to write pcurves: was 1
503     nbcurves->SetValue(itab, mynbcurve);
504     myisoflag = 0;
505     flag = new TColStd_HArray1OfInteger(1,1);  
506     flag->SetValue(1,myisoflag);
507     isoflags->SetValue(itab,flag);
508     mycurve = GetCasted(IGESData_IGESEntity, Seq2d->Value(itab));
509     curve = new IGESData_HArray1OfIGESEntity(1,1);
510     curve->SetValue(1,mycurve);
511     curves->SetValue(itab,curve);
512   }
513   
514   myLoop->Init(types, edges, index, orient, nbcurves, isoflags, curves);
515
516   SetShapeResult ( mywire, myLoop );
517
518   return myLoop;
519 }
520
521
522 //=============================================================================
523 // TransferFace
524 // 
525 //=============================================================================
526
527 Handle(IGESSolid_Face) BRepToIGESBRep_Entity ::TransferFace(const TopoDS_Face& start)
528 {
529   Handle(Message_ProgressIndicator) progress = GetTransferProcess()->GetProgress();
530   if ( ! progress.IsNull() ) {
531     if ( progress->UserBreak() ) return 0;
532     progress->Increment();
533   }
534   
535   Handle(IGESSolid_Face) myent = new IGESSolid_Face;
536   if ( start.IsNull()) return myent;
537   Handle(IGESData_IGESEntity) ISurf;
538   Standard_Real Length = 1.;
539
540   // returns the face surface, the face tolerance, the face natural restriction flag.
541   // --------------------------------------------------------------------------------
542   Handle(Geom_Surface) Surf = BRep_Tool::Surface(start);
543   if (!Surf.IsNull()) {
544     Standard_Real U1, U2, V1, V2;
545     BRepTools::UVBounds(start, U1, U2, V1, V2);  // to limit the base surfaces
546     GeomToIGES_GeomSurface GS;
547     //S4181 pdn 17.04.99 Boolean flags in order to define write of elementary surfaces added.
548     GS.SetBRepMode(Standard_True);
549     GS.SetAnalyticMode ( Interface_Static::IVal("write.convertsurface.mode") ==0 );
550     GS.SetModel(GetModel());
551
552     Handle(Geom_Surface) st;
553     if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
554       DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, Surf);
555       st = rectang->BasisSurface();
556     }
557     else 
558       st= Surf;
559
560     //S4181 pdn 17.04.99 Geom_Plane translated into GeomToIGES_GeomSurface
561     ISurf = GS.TransferSurface(st, U1, U2, V1, V2);
562     if (ISurf.IsNull()) {
563       AddWarning (start, "the basic surface is a null entity");
564       return myent;
565     }
566     Length = GS.Length();
567   }
568
569
570   // returns the wires of start
571   // --------------------------
572
573   // to explore the face , it is required to set it FORWARD.
574   TopoDS_Face myface = start;
575   Standard_Boolean IsReversed = Standard_False;
576   if (start.Orientation() == TopAbs_REVERSED) {
577     myface.Reverse();
578     IsReversed = Standard_True;
579   }
580
581   // outer wire
582 //:n3  TopoDS_Wire Outer = BRepTools::OuterWire(myface);
583   TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(myface); //:n3 
584   Handle(IGESSolid_Loop) OuterLoop = new IGESSolid_Loop;
585   Standard_Boolean OuterLoopFlag = Standard_False;
586   if (!Outer.IsNull()) {
587     OuterLoopFlag = Standard_True;
588     OuterLoop = TransferWire(Outer, myface, Length);
589   }
590
591   // inner wires
592   TopExp_Explorer Ex;
593   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
594
595   for (Ex.Init(myface,TopAbs_WIRE); Ex.More(); Ex.Next()) {
596     TopoDS_Wire W = TopoDS::Wire(Ex.Current());
597     Handle(IGESSolid_Loop) InnerLoop = new IGESSolid_Loop;
598     if (W.IsNull()) {
599       AddWarning(start," a Wire is a null entity");
600     }
601     else if (!W.IsSame(Outer)) {
602       InnerLoop = TransferWire(W, myface, Length);
603       if (!InnerLoop.IsNull()) Seq->Append(InnerLoop);
604     }
605   }
606
607   // all inner edges not in a wire
608   for (Ex.Init(myface,TopAbs_EDGE,TopAbs_WIRE); Ex.More(); Ex.Next()) {
609     TopoDS_Edge E = TopoDS::Edge(Ex.Current());
610     AddWarning ( E, "An edge alone is not transfer as an IGESBRep Entity");
611   }
612
613   Standard_Integer nbent = Seq->Length();
614   Handle(IGESSolid_HArray1OfLoop) TabLoop;
615   TabLoop = new IGESSolid_HArray1OfLoop(1,nbent+1);
616   TabLoop->SetValue(1,OuterLoop);
617   if ( nbent >= 1) {
618     for (Standard_Integer itab = 1; itab <= nbent; itab++) {
619       Handle(IGESSolid_Loop) item = GetCasted(IGESSolid_Loop, Seq->Value(itab));
620       TabLoop->SetValue(itab+1,item);
621     }
622   }
623
624   // returns the Face
625   // ----------------
626   myent-> Init (ISurf, OuterLoopFlag, TabLoop);
627
628   if (IsReversed) myface.Reverse();
629
630   SetShapeResult ( start, myent );
631
632   return myent;
633 }
634
635
636 //=============================================================================
637 // TransferShell
638 //=============================================================================
639
640 Handle(IGESSolid_Shell) BRepToIGESBRep_Entity ::TransferShell(const TopoDS_Shell& start)
641 {
642   Handle(IGESSolid_Shell) myshell = new IGESSolid_Shell;
643   if ( start.IsNull()) return myshell;
644
645   TopExp_Explorer Ex;
646   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
647   TColStd_SequenceOfInteger SeqFlag;
648   Handle(IGESSolid_Face) IFace;
649
650   for (Ex.Init(start,TopAbs_FACE); Ex.More(); Ex.Next()) {
651     TopoDS_Face F = TopoDS::Face(Ex.Current());
652     if ( start.Orientation() == TopAbs_REVERSED ) F.Reverse(); //:l4 abv 12 Jan 99: CTS22022-2: writing reversed shells
653     if (F.IsNull()) {
654       AddWarning(start," a Face is a null entity");
655     }
656     else {
657       IFace = TransferFace(F);
658       if (!IFace.IsNull()) {
659         Seq->Append(IFace);
660         if (F.Orientation() == TopAbs_FORWARD ) SeqFlag.Append(1);
661         if (F.Orientation() == TopAbs_REVERSED) SeqFlag.Append(0); 
662       }
663     }
664   }
665
666
667   Standard_Integer nbfaces = Seq->Length();  
668   Handle(IGESSolid_HArray1OfFace) TabFace = new IGESSolid_HArray1OfFace(1,nbfaces);
669   Handle(TColStd_HArray1OfInteger) TabFlag = new TColStd_HArray1OfInteger(1,nbfaces);
670   for (Standard_Integer itab = 1; itab <= nbfaces; itab++) {
671     Handle(IGESSolid_Face) itemface = GetCasted(IGESSolid_Face, Seq->Value(itab));
672     TabFace->SetValue(itab,itemface);
673     Standard_Integer item = SeqFlag.Value(itab);
674     TabFlag->SetValue(itab, item);
675   }
676
677   myshell->Init(TabFace,TabFlag);
678
679   SetShapeResult ( start, myshell );
680
681   return myshell;
682 }
683
684
685 //=============================================================================
686 // TransferSolid
687 // with a Solid
688 //=============================================================================
689
690 Handle(IGESSolid_ManifoldSolid) BRepToIGESBRep_Entity ::TransferSolid (const TopoDS_Solid& start)
691 {
692   Handle(IGESSolid_ManifoldSolid) mysol = new IGESSolid_ManifoldSolid;
693   if ( start.IsNull()) return mysol;
694
695   TopExp_Explorer Ex;
696   Handle(IGESSolid_Shell) IShell, FirstShell;
697   Standard_Integer ShellFlag = 1;
698   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
699   TColStd_SequenceOfInteger SeqFlag;
700
701   for (Ex.Init(start,TopAbs_SHELL); Ex.More(); Ex.Next()) {
702     TopoDS_Shell S = TopoDS::Shell(Ex.Current());
703     if (S.IsNull()) {
704       AddWarning(start," a Shell is a null entity");
705     }
706     else {
707       IShell = TransferShell(S);
708       if (!IShell.IsNull()) { 
709         Seq->Append(IShell);
710         if (S.Orientation() == TopAbs_FORWARD ) SeqFlag.Append(1);
711         if (S.Orientation() == TopAbs_REVERSED) SeqFlag.Append(0); 
712       }
713     }
714   }
715
716
717   Standard_Integer nbshells = Seq->Length();
718   Handle(IGESSolid_HArray1OfShell) Tab;
719   Handle(TColStd_HArray1OfInteger) TabFlag;
720   if ( nbshells > 1) {
721     Tab     =  new IGESSolid_HArray1OfShell(1,nbshells-1);
722     TabFlag =  new TColStd_HArray1OfInteger(1,nbshells-1);
723     for (Standard_Integer itab = 1; itab <= nbshells; itab++) {
724       Handle(IGESSolid_Shell) itemShell = GetCasted(IGESSolid_Shell, Seq->Value(itab));
725       Standard_Integer item = SeqFlag.Value(itab);
726       if (itab == 1) {
727         FirstShell = itemShell;
728         ShellFlag = item;
729       }
730       else {
731         Tab->SetValue(itab-1,itemShell);
732         TabFlag->SetValue(itab-1, item);
733       }
734     }
735   }
736
737   if (nbshells == 1) {
738     FirstShell = GetCasted(IGESSolid_Shell, Seq->Value(1));
739     ShellFlag = SeqFlag.Value(1);
740     Tab.Nullify();  TabFlag.Nullify();
741     mysol->Init(FirstShell, ShellFlag, Tab, TabFlag);
742   }
743   else if (nbshells >=2 ) {
744     mysol->Init(FirstShell, ShellFlag, Tab, TabFlag);
745   }
746   else
747     AddWarning (start, " no Result ");
748
749   SetShapeResult ( start, mysol );
750
751   return mysol;
752 }
753
754
755 //=============================================================================
756 // TransferCompSolid
757 // with a CompSolid
758 //=============================================================================
759
760 Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferCompSolid (const TopoDS_CompSolid& start)
761 {
762   Handle(IGESData_IGESEntity) myent;
763   if ( start.IsNull()) return myent;
764
765   TopExp_Explorer Ex;
766   Handle(IGESSolid_ManifoldSolid) ISolid = new IGESSolid_ManifoldSolid;
767   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
768
769   for (Ex.Init(start,TopAbs_SOLID); Ex.More(); Ex.Next()) {
770     TopoDS_Solid S = TopoDS::Solid(Ex.Current());
771     if (S.IsNull()) {
772       AddWarning(start," an Solid is a null entity");
773     }
774     else {
775       ISolid = TransferSolid(S);
776       if (!ISolid.IsNull()) Seq->Append(ISolid);
777     }
778   }
779
780
781   Standard_Integer nbsolids = Seq->Length();
782   Handle(IGESData_HArray1OfIGESEntity) Tab;
783   if ( nbsolids > 1) {
784     Tab =  new IGESData_HArray1OfIGESEntity(1,nbsolids);
785     for (Standard_Integer itab = 1; itab <= nbsolids; itab++) {
786       Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab));
787       Tab->SetValue(itab,item);
788     }
789   }
790
791   if (nbsolids == 1) {
792     myent = ISolid;
793   }
794   else if(nbsolids > 1 ){
795     Handle(IGESBasic_Group) IGroup = new IGESBasic_Group;
796     IGroup->Init(Tab);
797     myent = IGroup;
798   }
799
800   SetShapeResult ( start, myent );
801
802   return myent;
803 }
804
805
806 //=============================================================================
807 // TransferCompound
808 // with a Compound
809 //=============================================================================
810
811 Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferCompound (const TopoDS_Compound& start)
812 {
813   Handle(IGESData_IGESEntity) res;
814   if ( start.IsNull()) return res;
815
816
817   TopExp_Explorer Ex;
818   Handle(IGESData_IGESEntity) IShape;
819   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
820
821   // take all Solids
822   for (Ex.Init(start, TopAbs_SOLID); Ex.More(); Ex.Next()) {
823     TopoDS_Solid S = TopoDS::Solid(Ex.Current());
824     if (S.IsNull()) {
825       AddWarning(start," a Solid is a null entity");
826     }
827     else {
828       IShape = TransferSolid(S);
829       if (!IShape.IsNull()) Seq->Append(IShape);
830     }
831   }
832
833   // take all isolated Shells 
834   for (Ex.Init(start, TopAbs_SHELL, TopAbs_SOLID); Ex.More(); Ex.Next()) {
835     TopoDS_Shell S = TopoDS::Shell(Ex.Current());
836     if (S.IsNull()) {
837       AddWarning(start," a Shell is a null entity");
838     }
839     else {
840       IShape = TransferShell(S);
841       if (!IShape.IsNull()) Seq->Append(IShape);
842     }
843   }
844
845
846   // take all isolated Faces
847   for (Ex.Init(start, TopAbs_FACE, TopAbs_SHELL); Ex.More(); Ex.Next()) {
848     TopoDS_Face S = TopoDS::Face(Ex.Current());
849     if (S.IsNull()) {
850       AddWarning(start," a Face is a null entity");
851     }
852     else {
853       IShape = TransferFace(S);
854       if (!IShape.IsNull()) Seq->Append(IShape);
855     }
856   }
857
858
859   // take all isolated Wires 
860   for (Ex.Init(start, TopAbs_WIRE, TopAbs_FACE); Ex.More(); Ex.Next()) {
861     TopoDS_Wire S = TopoDS::Wire(Ex.Current());
862     AddWarning(S," a Wire alone is not an IGESBRep entity : no Transfer");
863   }
864
865
866   // take all isolated Edges 
867   for (Ex.Init(start, TopAbs_EDGE, TopAbs_WIRE); Ex.More(); Ex.Next()) {
868     TopoDS_Edge S = TopoDS::Edge(Ex.Current());
869     AddWarning(S," a Edge alone is not an IGESBRep entity : no Transfer");
870   }
871
872
873   // take all isolated Vertices 
874   for (Ex.Init(start, TopAbs_VERTEX, TopAbs_EDGE); Ex.More(); Ex.Next()) {
875     TopoDS_Vertex S = TopoDS::Vertex(Ex.Current());
876     AddWarning(S," a Vertex alone is not an IGESBRep entity : no Transfer");
877   }
878
879   // construct the group
880   Standard_Integer nbshapes = Seq->Length();
881   Handle(IGESData_HArray1OfIGESEntity) Tab;
882   if (nbshapes > 1) {
883     Tab =  new IGESData_HArray1OfIGESEntity(1,nbshapes);
884     for (Standard_Integer itab = 1; itab <= nbshapes; itab++) {
885       Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab));
886       Tab->SetValue(itab,item);
887     }
888   }
889   
890   if (nbshapes == 1) {
891     res = IShape;
892   }
893   else if(nbshapes > 1) {
894     Handle(IGESBasic_Group) IGroup = new IGESBasic_Group;
895     IGroup->Init(Tab);
896     res = IGroup;
897   }
898
899   SetShapeResult ( start, res );
900
901   return res;
902 }