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 //=======================================================================
IGESToBRep_BRepEntity()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 //=======================================================================
IGESToBRep_BRepEntity(const IGESToBRep_CurveAndSurface & CS)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 //=======================================================================
IGESToBRep_BRepEntity(const Standard_Real eps,const Standard_Real epsCoeff,const Standard_Real epsGeom,const Standard_Boolean mode,const Standard_Boolean modeapprox,const Standard_Boolean optimized)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 //=======================================================================
TransferBRepEntity(const Handle (IGESData_IGESEntity)& start,const Message_ProgressRange & theProgress)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 //=======================================================================
TransferVertex(const Handle (IGESSolid_VertexList)& start,const Standard_Integer index)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 //=======================================================================
TransferEdge(const Handle (IGESSolid_EdgeList)& start,const Standard_Integer index)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 //=======================================================================
TransferLoop(const Handle (IGESSolid_Loop)& start,const TopoDS_Face & face,const gp_Trsf2d & trans,const Standard_Real uFact)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 //=======================================================================
TransferFace(const Handle (IGESSolid_Face)& start)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 //=======================================================================
TransferShell(const Handle (IGESSolid_Shell)& start,const Message_ProgressRange & theProgress)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 //=======================================================================
TransferManifoldSolid(const Handle (IGESSolid_ManifoldSolid)& start,const Message_ProgressRange & theProgress)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 }
652