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