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