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