0025748: Parallel version of progress indicator
[occt.git] / src / IGESToBRep / IGESToBRep_BRepEntity.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //=======================================================================
15 //purpose  : Members to transfert any BRepEntity into TopoDS_Shape
16 //=======================================================================
17 // 21.12.98 rln, gka S4054
18 //#62 rln 10.01.99 PRO17015
19 //:q5 abv 19.03.99 unnecessary includes removed
20 //pdn 12.03.99 S4135 Constructing vertex with minimal tolerance
21 //:r1 abv 25.03.99 CTS21655.igs, CTS18545.igs: apply FixOrientation to whole face
22 //S4181 pdn 20.04.99 implementing of reading IGES elementary surfaces.
23 //pdn 20.04.99 CTS22655 avoid of exceptions in case of empty loops
24
25 #include <BRep_Builder.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRepTools.hxx>
28 #include <Geom_Curve.hxx>
29 #include <Geom_TrimmedCurve.hxx>
30 #include <gp.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Trsf2d.hxx>
33 #include <gp_Vec2d.hxx>
34 #include <IGESBasic_SingleParent.hxx>
35 #include <IGESData_HArray1OfIGESEntity.hxx>
36 #include <IGESData_IGESEntity.hxx>
37 #include <IGESData_IGESModel.hxx>
38 #include <IGESData_ToolLocation.hxx>
39 #include <IGESGeom_Boundary.hxx>
40 #include <IGESGeom_BoundedSurface.hxx>
41 #include <IGESGeom_CurveOnSurface.hxx>
42 #include <IGESGeom_Plane.hxx>
43 #include <IGESGeom_TrimmedSurface.hxx>
44 #include <IGESSolid_EdgeList.hxx>
45 #include <IGESSolid_Face.hxx>
46 #include <IGESSolid_Loop.hxx>
47 #include <IGESSolid_ManifoldSolid.hxx>
48 #include <IGESSolid_Shell.hxx>
49 #include <IGESSolid_VertexList.hxx>
50 #include <IGESToBRep.hxx>
51 #include <IGESToBRep_AlgoContainer.hxx>
52 #include <IGESToBRep_BasicCurve.hxx>
53 #include <IGESToBRep_BasicSurface.hxx>
54 #include <IGESToBRep_BRepEntity.hxx>
55 #include <IGESToBRep_CurveAndSurface.hxx>
56 #include <IGESToBRep_IGESBoundary.hxx>
57 #include <IGESToBRep_ToolContainer.hxx>
58 #include <IGESToBRep_TopoCurve.hxx>
59 #include <IGESToBRep_TopoSurface.hxx>
60 #include <Interface_Macros.hxx>
61 #include <Message_Msg.hxx>
62 #include <Message_ProgressScope.hxx>
63 #include <Precision.hxx>
64 #include <ShapeBuild_Edge.hxx>
65 #include <ShapeExtend_WireData.hxx>
66 #include <Standard_ErrorHandler.hxx>
67 #include <TCollection_HAsciiString.hxx>
68 #include <TopAbs_ShapeEnum.hxx>
69 #include <TopExp.hxx>
70 #include <TopLoc_Location.hxx>
71 #include <TopoDS.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
74 #include <TopoDS_Shape.hxx>
75 #include <TopoDS_Shell.hxx>
76 #include <TopoDS_Solid.hxx>
77 #include <TopoDS_Vertex.hxx>
78 #include <TopoDS_Wire.hxx>
79 #include <Transfer_TransientProcess.hxx>
80
81 #include <stdio.h>
82 //rln
83 //#include <ShapeFix_Face.hxx>
84 //=======================================================================
85 //function : IGESToBRep_BRepEntity
86 //purpose  : 
87 //=======================================================================
88 IGESToBRep_BRepEntity::IGESToBRep_BRepEntity()
89      :IGESToBRep_CurveAndSurface()
90 {
91   SetModeTransfer(Standard_False);
92   SetContinuity(0);
93 }
94
95
96 //=======================================================================
97 //function : IGESToBRep_BRepEntity
98 //purpose  : 
99 //=======================================================================
100 IGESToBRep_BRepEntity::IGESToBRep_BRepEntity
101   (const IGESToBRep_CurveAndSurface& CS)
102      :IGESToBRep_CurveAndSurface(CS)
103 {
104   SetContinuity(0);
105 }
106
107
108 //=======================================================================
109 //function : IGESToBRep_BRepEntity
110 //purpose  : 
111 //=======================================================================
112 IGESToBRep_BRepEntity::IGESToBRep_BRepEntity
113   (const Standard_Real    eps,
114    const Standard_Real    epsCoeff,
115    const Standard_Real    epsGeom,
116    const Standard_Boolean mode,
117    const Standard_Boolean modeapprox,
118    const Standard_Boolean optimized)
119      :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, modeapprox,
120                                  optimized)
121 {  
122   SetContinuity(0);
123 }
124
125
126 //=======================================================================
127 //function : TransferBRepEntity
128 //purpose  : 
129 //=======================================================================
130 TopoDS_Shape IGESToBRep_BRepEntity::TransferBRepEntity
131   (const Handle(IGESData_IGESEntity)& start,
132    const Message_ProgressRange& theProgress)
133 {
134   TopoDS_Shape res;
135
136   if (start->IsKind(STANDARD_TYPE(IGESSolid_Face))) {
137     DeclareAndCast(IGESSolid_Face, st510, start);
138     res = TransferFace(st510);
139   }
140   else if (start->IsKind(STANDARD_TYPE(IGESSolid_Shell))) {
141     DeclareAndCast(IGESSolid_Shell, st514, start);
142     res = TransferShell(st514, theProgress);
143   }
144   else if (start->IsKind(STANDARD_TYPE(IGESSolid_ManifoldSolid))) {
145     DeclareAndCast(IGESSolid_ManifoldSolid, st186, start);
146     res = TransferManifoldSolid(st186, theProgress);
147   }
148   else {
149     Message_Msg Msg1005("IGES_1005");
150     SendFail(start,Msg1005);
151   }
152   return res;
153 }
154
155
156 //=======================================================================
157 //function : TransferVertex
158 //purpose  : 
159 //=======================================================================
160 TopoDS_Vertex IGESToBRep_BRepEntity::TransferVertex
161   (const Handle(IGESSolid_VertexList)& start,
162    const Standard_Integer index)
163 {
164   TopoDS_Vertex res;
165
166   Standard_Integer nbshapes = NbShapeResult(start);
167   if (nbshapes == 0 ) {
168     BRep_Builder B;
169     for (Standard_Integer inum = 1; inum <= start->NbVertices(); inum++) {
170       gp_Pnt point = start-> Vertex(inum);
171       point.Scale(gp_Pnt(0,0,0),GetUnitFactor());
172       TopoDS_Vertex V;
173       //pdn 12.03.99 S4135 Constructing vertex with minimal tolerance
174       B.MakeVertex(V, point, Precision::Confusion());
175       AddShapeResult(start,V);
176     }
177   }
178   
179   TopoDS_Shape Sh = GetShapeResult(start,index);
180   if ( Sh.IsNull()) { 
181     Message_Msg Msg1156("IGES_1156"); //"the Vertex number %d is a null object." FAIL!!!
182     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
183     Msg1156.Arg("vertex");
184     Msg1156.Arg(label);
185     SendWarning(start,Msg1156);
186   }
187   res = TopoDS::Vertex(Sh);
188   return res;
189 }
190
191
192 //=======================================================================
193 //function : TransferEdge
194 //purpose  : 
195 //=======================================================================
196 TopoDS_Shape IGESToBRep_BRepEntity::TransferEdge
197   (const Handle(IGESSolid_EdgeList)& start,
198    const Standard_Integer index)
199 {
200   TopoDS_Shape res;
201   BRep_Builder B;
202   
203   Standard_Integer nbshapes = NbShapeResult(start);
204   if (nbshapes == 0) {
205     IGESToBRep_TopoCurve  TC(*this);
206     for (Standard_Integer inum = 1; inum <= start->NbEdges(); inum++) {
207       
208       // Vertices
209       // --------
210       Handle(IGESSolid_VertexList) thestartlist = start->StartVertexList(inum);
211       Standard_Integer thestartindex = start->StartVertexIndex(inum);
212       TopoDS_Vertex V1 = TransferVertex(thestartlist,thestartindex);
213       
214       Handle(IGESSolid_VertexList) theendlist = start->EndVertexList(inum);
215       Standard_Integer theendindex = start->EndVertexIndex(inum);
216       TopoDS_Vertex V2 = TransferVertex(theendlist,theendindex);
217       
218       // Curve
219       // -----
220       
221       Handle(IGESData_IGESEntity)  thecurve = start->Curve(inum);
222       if (thecurve.IsNull() ||
223           !IGESToBRep::IsTopoCurve(thecurve)  || 
224           thecurve->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface)) ||
225           thecurve->IsKind(STANDARD_TYPE(IGESGeom_Boundary))           ) {
226         Message_Msg Msg1306("IGES_1306");//one underlying curve is a Null object.
227         Msg1306.Arg(inum);
228         SendWarning(start,Msg1306);
229         TopoDS_Edge Sh;
230         AddShapeResult(start,Sh); // add null shape to avoid shift of indexing
231       }
232       else {
233         TopoDS_Shape Sh = TC.TransferTopoCurve(thecurve);
234         if (!Sh.IsNull()) {
235           if (Sh.ShapeType() == TopAbs_EDGE) {
236             TopoDS_Edge edge = TopoDS::Edge(Sh);
237             TopoDS_Vertex Vf,Vl;
238             TopExp::Vertices (edge, Vf, Vl);
239             TopoDS_Edge E;
240             B.MakeEdge(E);
241             TopLoc_Location    loc;
242             Standard_Real      first, last;
243             Handle(Geom_Curve) Crv  = BRep_Tool::Curve(edge, loc, first, last);
244             Handle(Geom_Curve) newC3d;
245             // dams le cas d`une conique, il faut reverser
246             // sens de parcours IGES inverse sens de parcours CASCADE.
247             if (Crv->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
248               DeclareAndCast(Geom_TrimmedCurve, acurve, Crv);
249               newC3d = acurve->BasisCurve();
250             }
251             else {
252               newC3d = Crv;
253             }
254             B.UpdateEdge(E,newC3d,loc,0.);//S4054:GetEpsGeom()*GetUnitFactor()
255             gp_Pnt p1 = BRep_Tool::Pnt ( V1 ); 
256             gp_Pnt p2 = BRep_Tool::Pnt ( V2 ); 
257             gp_Pnt pf = BRep_Tool::Pnt ( Vf ); 
258             gp_Pnt pl = BRep_Tool::Pnt ( Vl ); 
259             Standard_Real dist1f = p1.Distance ( pf );
260             Standard_Real dist2f = p2.Distance ( pf );
261             Standard_Real dist1l = p1.Distance ( pl );
262             Standard_Real dist2l = p2.Distance ( pl );
263             if ( V1.IsSame(V2) || dist1f + dist2l <= dist1l + dist2f + Precision::Confusion() ) {
264               //:77 if (BRepTools::Compare(V1, Vf)) //the part 'else' only if, in fact, edge should be reversed
265               V1.Orientation(TopAbs_FORWARD);
266               B.Add(E,V1);
267               V2.Orientation(TopAbs_REVERSED);
268               B.Add(E,V2);
269               B.UpdateVertex(V1, first, E, 0.);//S4054 1.001 * dist1f //:77 GetEpsGeom()*GetUnitFactor();
270               B.UpdateVertex(V2, last,  E, 0.);//S4054 1.001 * dist2l //:77 GetEpsGeom()*GetUnitFactor();
271               B.Range (E, first, last);
272             }
273             // modif mjm du 13/10/97 : Reverse de l`edge ?
274             else {
275               E.Reverse();
276               V1.Orientation(TopAbs_FORWARD);
277               B.Add(E,V1);
278               V2.Orientation(TopAbs_REVERSED);
279               B.Add(E,V2);
280               B.UpdateVertex(V1, last,  E, 0.);//S4054 1.001 * dist1l //:77 GetEpsGeom()*GetUnitFactor();
281               B.UpdateVertex(V2, first, E, 0.);//S4054 1.001 * dist2f //:77 GetEpsGeom()*GetUnitFactor();
282               B.Range (E, first, last);
283             }
284             AddShapeResult(start,E);
285           }
286           else if (Sh.ShapeType() == TopAbs_WIRE) {
287             // pas traite 
288             Message_Msg Msg1325("IGES_1325"); //"Item %d of EdgeList cannot be represented by single edge (non-continuous or composite curve)."
289             Msg1325.Arg(inum);
290             SendWarning(start,Msg1325);
291             AddShapeResult(start,Sh);
292           }
293         }
294         else {
295           Message_Msg Msg1156("IGES_1156");
296           Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(thecurve);
297           Msg1156.Arg("underlying curve");
298           Msg1156.Arg(label);
299           SendWarning(start,Msg1156);       
300           AddShapeResult(start,Sh); // add null shape to avoid shift of indexing
301         }
302       }
303     }
304   }
305   
306   TopoDS_Shape Sh = GetShapeResult(start,index);
307   if ( Sh.IsNull()) {
308     Message_Msg Msg1156("IGES_1156"); 
309     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
310     Msg1156.Arg("edge");
311     Msg1156.Arg(label);
312     SendWarning(start,Msg1156);
313   }
314   return Sh;
315 }
316
317
318 //=======================================================================
319 //function : TransferLoop
320 //purpose  : 
321 //=======================================================================
322 TopoDS_Shape IGESToBRep_BRepEntity::TransferLoop(const Handle(IGESSolid_Loop)& start,
323                                                  const TopoDS_Face& face,
324                                                  const gp_Trsf2d& trans,
325                                                  const Standard_Real uFact) 
326 {
327   TopoDS_Shape res;
328   
329   if (!HasShapeResult(start)) {
330     TopoDS_Wire mywire;
331     Standard_Boolean okCurve = Standard_True, okCurve3d = Standard_True, okCurve2d = Standard_True;
332     Handle(ShapeExtend_WireData) sewd;
333     Standard_Integer filepreference = 3;//3D is preferred by default
334     Standard_Boolean Result = Standard_True;
335
336     Handle(IGESToBRep_IGESBoundary) IB = IGESToBRep::AlgoContainer()->ToolContainer()->IGESBoundary();
337     IB->Init (*this, start, face, trans, uFact, filepreference);
338     BRep_Builder B;
339     ShapeBuild_Edge sbe;
340     
341     for ( Standard_Integer iedge = 1; iedge <= start->NbEdges(); iedge++ ) {
342       Standard_Integer itype = start->EdgeType(iedge);
343       Handle(IGESData_IGESEntity)  theedge = start->Edge(iedge);
344       Standard_Integer indexlist = start->ListIndex(iedge);
345       Standard_Boolean orientation = start->Orientation(iedge);
346       Standard_Integer nbparam = start->NbParameterCurves(iedge);
347       if (theedge.IsNull()) {
348          Message_Msg Msg1365("IGES_1365"); //"Loop : one edge is null" 
349          Msg1365.Arg(iedge);
350          SendWarning(start,Msg1365);
351         //      AddWarning (start,"Loop : one edge is null");
352       }
353       else {
354         //  edge
355         //  ----
356         Handle(ShapeExtend_WireData) curve3d = new ShapeExtend_WireData;
357
358         if (( itype == 1) && (theedge ->IsKind(STANDARD_TYPE(IGESSolid_VertexList)))) {
359           DeclareAndCast(IGESSolid_VertexList,thelist,theedge);
360           TopoDS_Vertex V1 = TransferVertex(thelist,indexlist);
361           TopoDS_Edge  E;
362           B.MakeEdge(E);
363           //szv#4:S4163:12Mar99 SGI warns
364           TopoDS_Shape sh = V1.Oriented(TopAbs_FORWARD);
365           B.Add(E, TopoDS::Vertex(sh));
366           sh = V1.Oriented(TopAbs_REVERSED);
367           B.Add(E, TopoDS::Vertex(sh));
368           B.Degenerated(E, Standard_True);
369           curve3d->Add (E);
370         }
371         else if (( itype == 0) && (theedge ->IsKind(STANDARD_TYPE(IGESSolid_EdgeList)))) {
372           DeclareAndCast(IGESSolid_EdgeList,thelist,theedge);
373           TopoDS_Shape Sh = TransferEdge(thelist,indexlist);
374           if (Sh.IsNull())
375           {
376             continue; // skip non-translated edge hoping for the best; warning is already generated by TransferEdge()
377           }
378           curve3d->Add(Sh);
379         }
380         else { 
381           Message_Msg Msg1365("IGES_1365"); //"Improper type for the edge"
382           Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
383           Msg1365.Arg(iedge);
384           SendWarning(start,Msg1365);
385           continue;
386         }
387         if (!orientation) curve3d->Reverse();
388         
389         //  traitement des courbes 2d.
390         //  -------------------------
391         Handle(IGESData_HArray1OfIGESEntity) Curves2d;
392         
393         //Current limitation:
394         //2D representation is not translated if:
395         //- 3D curve was translated into wire (i.e. if it is 102)
396         //- more than 1 2D curve,
397         //- 2D curve is 102
398         Handle(TColStd_HSequenceOfTransient) seq2d;
399         if (curve3d->NbEdges() == 1 && nbparam == 1 &&
400             IGESToBRep::IGESCurveToSequenceOfIGESCurve (start->ParametricCurve(iedge, 1), seq2d) == 1) {
401           Curves2d = new IGESData_HArray1OfIGESEntity (1, nbparam);
402           for (Standard_Integer i = 1; i <= nbparam; i++)
403             Curves2d->SetValue (i, start->ParametricCurve(iedge,i));
404         }
405         Handle(ShapeExtend_WireData) lsewd;//result of translation of current edge
406         Result = Result & IB->Transfer (okCurve, okCurve3d, okCurve2d,
407                                         curve3d, Curves2d, !orientation,
408                                         iedge, lsewd);
409         if (iedge == 1) sewd = IB->WireData();//initialization
410         if (curve3d->NbEdges() == 1 && lsewd->NbEdges() == 1) {//the condition corresponds to limitation above
411           //to keep sharing of edges all geometric representations should be put
412           //into the edge from EdgeList
413           TopoDS_Edge fromedge = lsewd->Edge(1), toedge = curve3d->Edge(1);
414           if (!fromedge.IsSame (toedge)) {
415             sbe.RemoveCurve3d (toedge);
416             IGESToBRep::TransferPCurve (fromedge, toedge, face);
417             sewd->Set (toedge, sewd->Index (fromedge));
418           }
419         }
420       }
421     }
422     //IB->Check(Result, Standard_True);
423     //pdn 20.04.99 CTS22655 avoid of exceptions in case of empty loops
424     if(!sewd.IsNull()) {
425       //IB.Fix (sewd, Standard_False, Standard_True, Standard_True, Standard_True, Standard_True);
426       mywire = sewd->Wire();
427     }
428     SetShapeResult(start, mywire);
429   }
430   
431   TopoDS_Shape Sh = GetShapeResult(start);
432   if ( Sh.IsNull()) {
433     Message_Msg Msg1156("IGES_1156"); //The Loop is null
434     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
435     Msg1156.Arg("loop");
436     Msg1156.Arg(label);
437     SendWarning(start,Msg1156);
438   }
439   return Sh;
440 }
441
442 //=======================================================================
443 //function : TransferFace
444 //purpose  : 
445 //=======================================================================
446 TopoDS_Shape IGESToBRep_BRepEntity::TransferFace
447   (const Handle(IGESSolid_Face)& start)
448 {
449   TopoDS_Shape res;
450
451   if (!HasShapeResult(start)) {
452     BRep_Builder B;
453     TopoDS_Face F;
454     Handle(IGESData_IGESEntity) surf         = start->Surface();
455     Standard_Integer            nbloops      = start->NbLoops();
456     IGESToBRep_TopoSurface TS(*this);
457
458     // surface
459     // -------
460     if (surf.IsNull() || 
461         !IGESToBRep::IsTopoSurface(surf) ||
462         surf->IsKind(STANDARD_TYPE(IGESGeom_Plane)) ||
463         surf->IsKind(STANDARD_TYPE(IGESGeom_BoundedSurface)) ||
464         surf->IsKind(STANDARD_TYPE(IGESGeom_TrimmedSurface)) ||
465         surf->IsKind(STANDARD_TYPE(IGESBasic_SingleParent)) ){
466       Message_Msg Msg196("XSTEP_196"); //"pas de surface de base pour creer la face"
467       SendWarning(start,Msg196);
468       // AddWarning(start, "pas de surface de base pour creer la face");
469       TopoDS_Shape Sh;
470       SetShapeResult(start,Sh);
471     }
472     else {
473       // si la surface IGES est une surface de revolution , il faudra
474       // inverser les courbes 2d (u,v) pour etre en accord avec le parametrage
475       // BRep.
476       gp_Trsf2d trans;
477       Standard_Real uFact;
478       TopoDS_Shape myshape = TS.ParamSurface(surf, trans, uFact);
479       
480       if (!myshape.IsNull()) {
481         if (myshape.ShapeType() == TopAbs_FACE) {
482           //#62 rln 10.01.99 PRO17015 (reading back IGES written in 'BRep' mode) face #65
483           F = TopoDS::Face (myshape);
484           F.EmptyCopy();
485           if (nbloops == 0) B.NaturalRestriction (F,Standard_True);
486           
487           // Loops
488           // -----
489           for (Standard_Integer iloop = 1; iloop <= nbloops; iloop++){
490             Handle(IGESSolid_Loop) loop = start->Loop(iloop);
491             TopoDS_Shape Shape = TransferLoop (loop, F, trans, uFact);
492             //pdn 20.04.99 CTS22655 avoid of exceptions in case of empty loops
493             if(!Shape.IsNull())
494               B.Add(F,Shape);
495           }
496
497           // update the face
498           BRepTools::Update (F);
499           F.Orientable(Standard_True);
500           SetShapeResult(start,F);
501         }
502       }
503       else {
504         Message_Msg Msg1156("IGES_1156"); //Face : result of TransferTopoSurface is Null
505         Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(surf);
506         Msg1156.Arg("surface");
507         Msg1156.Arg(label);
508         SendFail(start,Msg1156);
509         //  AddWarning(start,"Face : result of TransferTopoSurface is Null");
510         TopoDS_Shape Sh;
511         SetShapeResult(start,Sh);
512       }
513     }
514   }
515   
516   
517   TopoDS_Shape Sh = GetShapeResult(start);
518   if ( Sh.IsNull()) {
519     Message_Msg Msg1156("IGES_1156"); //the Face is a Null object.
520     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
521     Msg1156.Arg("face");
522     Msg1156.Arg(label);
523     SendFail(start,Msg1156);     
524     //    AddWarning (start, "the Face is a Null object.");
525   }
526   return Sh;
527 }
528
529
530 //=======================================================================
531 //function : TransferShell
532 //purpose  : 
533 //=======================================================================
534 TopoDS_Shape IGESToBRep_BRepEntity::TransferShell
535   (const Handle(IGESSolid_Shell)& start,
536    const Message_ProgressRange& theProgress)
537 {
538   TopoDS_Shape res;
539
540   if (!HasShapeResult(start)) {
541     TopoDS_Shell S;
542     BRep_Builder B;
543     B.MakeShell(S);
544     Standard_Integer nbfaces = start->NbFaces();
545     if (nbfaces != 0) {
546       Standard_Boolean closed = Standard_True; //:39
547       Message_ProgressScope aPS(theProgress, "Face", nbfaces);
548       for (Standard_Integer iface = 1; iface <= nbfaces && aPS.More(); iface++, aPS.Next()) {
549         Handle(IGESSolid_Face) face = start->Face(iface);
550         Standard_Boolean orientation = start->Orientation(iface);
551         TopoDS_Shape Sh = TransferFace(face);
552         if ( Sh.IsNull() ) { //:39 by abv 15.12.97
553           
554           closed = Standard_False;
555           continue;
556         }
557         if (!orientation) Sh.Reverse();
558         B.Add(S,Sh);
559       }
560       if ( ! closed ) {
561         Message_Msg Msg1360("IGES_1360");
562         SendFail(start,Msg1360);
563         
564       }
565         //AddWarning ( start, "Shell is not closed" ); //:39
566       S.Closed ( closed ); //:39
567       S.Orientable(Standard_True);
568       SetShapeResult(start,S);
569     }
570     else {
571       Message_Msg Msg200("XSTEP_200"); //Number of Faces = 0
572       SendFail(start,Msg200);
573     }
574   }
575   
576   TopoDS_Shape Sh = GetShapeResult(start);
577   if ( Sh.IsNull()) {
578     Message_Msg Msg1156("IGES_1156"); //the Shell is a null object
579     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
580     Msg1156.Arg("shell");
581     Msg1156.Arg(label);
582     SendFail(start,Msg1156); 
583   }
584     //AddWarning (start, "the Shell is a null object.");
585   res = Sh;
586   return res;
587 }
588
589
590 //=======================================================================
591 //function : TransferManifoldSolid
592 //purpose  : 
593 //=======================================================================
594 TopoDS_Shape IGESToBRep_BRepEntity::TransferManifoldSolid
595   (const Handle(IGESSolid_ManifoldSolid)& start,
596    const Message_ProgressRange& theProgress)
597 {
598   TopoDS_Shape res;
599
600   if (!HasShapeResult(start)) {
601     TopoDS_Solid S;
602     BRep_Builder B;
603     B.MakeSolid(S);
604     Handle(IGESSolid_Shell) shell = start->Shell();
605     Standard_Boolean isoriented   = start->OrientationFlag();
606     Standard_Integer nbshell      = start->NbVoidShells();
607     TopoDS_Shape Sh = TransferShell(shell, theProgress);
608     if (!Sh.IsNull()) {
609       if (Sh.ShapeType() == TopAbs_SHELL) {
610         TopoDS_Shell Shell = TopoDS::Shell(Sh);
611         if (!isoriented) Shell.Reverse();
612         B.Add(S,Shell);
613       }
614
615       if (nbshell != 0) {
616         // progress scope without name, since usually we have single shell in solid
617         Message_ProgressScope aPS (theProgress, NULL, nbshell);
618         for (Standard_Integer ishell=1; ishell<= nbshell && aPS.More(); ishell++) {
619           Handle(IGESSolid_Shell) voidshell= start->VoidShell(ishell);
620 //        Standard_Boolean orientation = start->VoidOrientationFlag(ishell);
621           TopoDS_Shape aSh = TransferShell (voidshell, aPS.Next());
622           if (!aSh.IsNull()) {
623             if (aSh.ShapeType() == TopAbs_SHELL) {
624               TopoDS_Shell Shell = TopoDS::Shell(aSh);
625               if (!isoriented) Shell.Reverse();
626               B.Add(S,Shell);
627             }
628           }
629           else {
630           //  AddWarning(start,"ManifoldSolid : one VoidShell is Null");
631             TopoDS_Shell Shell;
632             B.Add(S,Shell);
633           }
634         }    
635       }
636     }
637     SetShapeResult(start,S);
638   }
639
640   TopoDS_Shape Sh = GetShapeResult(start);
641   if ( Sh.IsNull()) {
642     Message_Msg Msg1156("IGES_1156"); //the ManifoldSolid is a null object.
643     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(start);
644     Msg1156.Arg("solid");
645     Msg1156.Arg(label);
646     SendFail(start,Msg1156);  
647   }
648  //   AddWarning (start, "the ManifoldSolid is a null object.");
649   res = Sh;
650   return res;
651 }