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