c799e05044ac6ff7531fbc13192933204de3fcbb
[occt.git] / src / IGESToBRep / IGESToBRep_TopoSurface.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 //modified: 
16 // Integration to ensure SCCS base integrity
17 // 21.12.98 rln, gka S4054
18 // 28.12.98 dce S3767 New messaging system
19 //#55,#56 rln 25.12.98 UKI60878
20 //:l1 abv 10.01.99: USA60022 7289: fix missing seam
21 //#63 rln 19.01.99 UKI60878 no offset if C0 surface is converted into the grid of C1 surfaces
22 //%13 pdn 15.02.99 USA60293 entities 792, 8604 .. handling of C0 ruled surfaces, tabulated cylindres,
23 //                 and surfaces of revolution.
24 //:p4 abv, pdn 23.02.99: PRO9234 #15720: call BRepTools::Update() for faces
25 //%14 pdn 24.02.99 implementing of ShapeFix_Face on IGES  
26 //    pdn 17.04.99 S4181: Implementing of reading IGES elementary surfaces.
27 //    pdn 10.05.99 S4137: Using modified ShapeDivide tools
28 //#11 smh 22.12.99 BUC60625 Transform axis.
29 //#12 smh 12.12.99 FRA62468 - Using conversion to B-Spline for Offset surface
30 //=======================================================================
31
32 #include <BRep_Builder.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <BRepBuilderAPI_MakeFace.hxx>
36 #include <BRepFill.hxx>
37 #include <BRepGProp.hxx>
38 #include <BRepLib_MakeFace.hxx>
39 #include <BRepPrimAPI_MakePrism.hxx>
40 #include <BRepPrimAPI_MakeRevol.hxx>
41 #include <BRepTools.hxx>
42 #include <BSplCLib.hxx>
43 #include <ElCLib.hxx>
44 #include <ElSLib.hxx>
45 #include <Geom2d_Curve.hxx>
46 #include <Geom2d_Line.hxx>
47 #include <Geom_BezierCurve.hxx>
48 #include <Geom_BSplineCurve.hxx>
49 #include <Geom_BSplineSurface.hxx>
50 #include <Geom_ConicalSurface.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom_CylindricalSurface.hxx>
53 #include <Geom_Line.hxx>
54 #include <Geom_OffsetSurface.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_RectangularTrimmedSurface.hxx>
57 #include <Geom_SphericalSurface.hxx>
58 #include <Geom_Surface.hxx>
59 #include <Geom_SurfaceOfLinearExtrusion.hxx>
60 #include <Geom_SurfaceOfRevolution.hxx>
61 #include <Geom_ToroidalSurface.hxx>
62 #include <Geom_TrimmedCurve.hxx>
63 #include <GeomAbs_Shape.hxx>
64 #include <GeomConvert.hxx>
65 #include <GeomLib.hxx>
66 #include <gp.hxx>
67 #include <gp_Ax1.hxx>
68 #include <gp_Cone.hxx>
69 #include <gp_Cylinder.hxx>
70 #include <gp_Dir.hxx>
71 #include <gp_Dir2d.hxx>
72 #include <gp_GTrsf.hxx>
73 #include <gp_Pln.hxx>
74 #include <gp_Pnt.hxx>
75 #include <gp_Sphere.hxx>
76 #include <gp_Torus.hxx>
77 #include <gp_Trsf.hxx>
78 #include <gp_Trsf2d.hxx>
79 #include <gp_Vec.hxx>
80 #include <GProp.hxx>
81 #include <GProp_GProps.hxx>
82 #include <IGESBasic_SingleParent.hxx>
83 #include <IGESData_IGESEntity.hxx>
84 #include <IGESData_IGESModel.hxx>
85 #include <IGESData_ToolLocation.hxx>
86 #include <IGESGeom_BoundedSurface.hxx>
87 #include <IGESGeom_BSplineSurface.hxx>
88 #include <IGESGeom_CircularArc.hxx>
89 #include <IGESGeom_CurveOnSurface.hxx>
90 #include <IGESGeom_Direction.hxx>
91 #include <IGESGeom_Line.hxx>
92 #include <IGESGeom_OffsetSurface.hxx>
93 #include <IGESGeom_Plane.hxx>
94 #include <IGESGeom_Point.hxx>
95 #include <IGESGeom_RuledSurface.hxx>
96 #include <IGESGeom_SurfaceOfRevolution.hxx>
97 #include <IGESGeom_TabulatedCylinder.hxx>
98 #include <IGESGeom_TrimmedSurface.hxx>
99 #include <IGESSolid_ConicalSurface.hxx>
100 #include <IGESSolid_CylindricalSurface.hxx>
101 #include <IGESSolid_PlaneSurface.hxx>
102 #include <IGESSolid_SphericalSurface.hxx>
103 #include <IGESSolid_ToroidalSurface.hxx>
104 #include <IGESToBRep.hxx>
105 #include <IGESToBRep_BasicCurve.hxx>
106 #include <IGESToBRep_BasicSurface.hxx>
107 #include <IGESToBRep_CurveAndSurface.hxx>
108 #include <IGESToBRep_TopoCurve.hxx>
109 #include <IGESToBRep_TopoSurface.hxx>
110 #include <Interface_Macros.hxx>
111 #include <Message_Msg.hxx>
112 #include <Precision.hxx>
113 #include <ShapeAlgo.hxx>
114 #include <ShapeAlgo_AlgoContainer.hxx>
115 #include <ShapeAnalysis.hxx>
116 #include <ShapeExtend_WireData.hxx>
117 #include <ShapeFix_Wire.hxx>
118 #include <Standard_ErrorHandler.hxx>
119 #include <TColgp_Array1OfPnt.hxx>
120 #include <TColStd_Array1OfInteger.hxx>
121 #include <TColStd_Array1OfReal.hxx>
122 #include <TopAbs.hxx>
123 #include <TopExp.hxx>
124 #include <TopExp_Explorer.hxx>
125 #include <TopLoc_Location.hxx>
126 #include <TopoDS.hxx>
127 #include <TopoDS_Edge.hxx>
128 #include <TopoDS_Face.hxx>
129 #include <TopoDS_Iterator.hxx>
130 #include <TopoDS_Shape.hxx>
131 #include <TopoDS_Shell.hxx>
132 #include <TopoDS_Vertex.hxx>
133 #include <TopoDS_Wire.hxx>
134
135 #include <stdio.h>
136 //S4054: ShapeTool_MakeWire -> ShapeExtend_WireData //:g8: BRepLib_MakeWire -> ShapeTool_MakeWire
137 //:e3
138 //#16
139 //S4054
140 //S3767
141 //=======================================================================
142 //function : IGESToBRep_TopoSurface
143 //purpose  : 
144 //=======================================================================
145 IGESToBRep_TopoSurface::IGESToBRep_TopoSurface()
146      :IGESToBRep_CurveAndSurface()
147 {  
148 }
149
150
151 //=======================================================================
152 //function : IGESToBRep_TopoSurface
153 //purpose  : 
154 //=======================================================================
155
156 IGESToBRep_TopoSurface::IGESToBRep_TopoSurface
157   (const IGESToBRep_CurveAndSurface& CS)
158      :IGESToBRep_CurveAndSurface(CS)
159 {  
160 }
161
162
163 //=======================================================================
164 //function : IGESToBRep_TopoSurface
165 //purpose  : 
166 //=======================================================================
167
168 IGESToBRep_TopoSurface::IGESToBRep_TopoSurface
169   (const Standard_Real    eps,
170    const Standard_Real    epsCoeff,
171    const Standard_Real    epsGeom,
172    const Standard_Boolean mode,
173    const Standard_Boolean modeapprox,
174    const Standard_Boolean optimized)
175      :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, 
176                                  modeapprox, optimized)
177 {  
178 }
179
180 static Standard_Boolean extractCurve3d (const TopoDS_Shape& theEdges,
181                                         Handle(Geom_Curve)& theCurve)
182 {
183   TopExp_Explorer anExp(theEdges, TopAbs_EDGE);
184   Standard_Integer howMuch = 0;
185   Standard_Real f = 0., l = 0.;
186   for (; anExp.More(); anExp.Next()) {
187     TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
188     if (anEdge.IsNull())
189       continue;
190     howMuch++;
191     theCurve = BRep_Tool::Curve(anEdge, f, l);
192   }
193   if ( howMuch != 1 || theCurve.IsNull() )
194     return Standard_False;
195   
196   if ( f != theCurve->FirstParameter() || l != theCurve->LastParameter() )
197     theCurve = new Geom_TrimmedCurve ( theCurve, f, l );
198   return Standard_True;
199 }
200
201
202 //=======================================================================
203 //function : TransferTopoSurface
204 //purpose  : 
205 //=======================================================================
206
207 TopoDS_Shape IGESToBRep_TopoSurface::TransferTopoSurface
208        (const Handle(IGESData_IGESEntity)& st)
209 { // Declaration of messages// 
210   // DCE 22/12/98
211   //Message_Msg msg1005("IGES_1005");
212   ////////////////////////////
213
214   TopoDS_Shape res;
215   TheULength = 1.;
216   //S4054
217   if (st.IsNull()) {
218     Message_Msg msg1005("IGES_1005");
219     SendFail(st, msg1005);
220   }
221   ////modified by jgv, 20.11.2009 for OCC21487///
222   else if (HasShapeResult(st))
223     {
224       res = GetShapeResult(st);
225       return res;
226     }
227   ///////////////////////////////////////////////
228   else if (IGESToBRep::IsBasicSurface(st)) {
229     res = TransferTopoBasicSurface(st);
230   }
231   else if (st->IsKind(STANDARD_TYPE(IGESGeom_TrimmedSurface))) {
232     DeclareAndCast(IGESGeom_TrimmedSurface, st144, st);
233     res = TransferTrimmedSurface(st144);
234   }
235   else if (st->IsKind(STANDARD_TYPE(IGESGeom_SurfaceOfRevolution))) {
236     DeclareAndCast(IGESGeom_SurfaceOfRevolution, st120, st);
237     res = TransferSurfaceOfRevolution(st120);
238   }
239   else if (st->IsKind(STANDARD_TYPE(IGESGeom_TabulatedCylinder))) {
240     DeclareAndCast(IGESGeom_TabulatedCylinder, st122, st);
241     res = TransferTabulatedCylinder(st122);
242   }
243   else if (st->IsKind(STANDARD_TYPE(IGESGeom_RuledSurface))) {
244     DeclareAndCast(IGESGeom_RuledSurface, st118, st);
245     res = TransferRuledSurface(st118);
246   }
247   else if (st->IsKind(STANDARD_TYPE(IGESGeom_Plane))) {
248     DeclareAndCast(IGESGeom_Plane, st108, st);
249     res = TransferPlane(st108);
250   }
251   else if (st->IsKind(STANDARD_TYPE(IGESGeom_BoundedSurface))) {
252     DeclareAndCast(IGESGeom_BoundedSurface, st143, st);
253     res = TransferBoundedSurface(st143);
254   }
255   else if (st->IsKind(STANDARD_TYPE(IGESGeom_OffsetSurface))) {
256     DeclareAndCast(IGESGeom_OffsetSurface, st140, st);
257     res = TransferOffsetSurface(st140);
258   }
259   //S4181 pdn IGESSolid_PlaneSurface recognized as basic surface
260   else if (st->IsKind(STANDARD_TYPE(IGESBasic_SingleParent)))  {
261     DeclareAndCast(IGESBasic_SingleParent,st402_9,st);
262     res = TransferPerforate(st402_9);    // limite : Planes seulement
263   }
264   else {
265    //  AddFail(st, "The IGESEntity is not a Topologic Surface.");
266   }
267   SetShapeResult (st, res);
268   return res;
269 }
270
271 //=======================================================================
272 //function : TransferTopoBasicSurface
273 //purpose  : 
274 //=======================================================================
275
276 TopoDS_Shape IGESToBRep_TopoSurface::TransferTopoBasicSurface
277        (const Handle(IGESData_IGESEntity)& st)
278 { // Declaration of messages// 
279   // DCE 22/12/98
280   //Message_Msg msg1005("IGES_1005");
281   ////////////////////////////
282
283   TopoDS_Shape  res;
284
285   if (st.IsNull()) {
286     Message_Msg msg1005("IGES_1005");
287     SendFail(st, msg1005);
288     return res;
289   }
290   if (!IGESToBRep::IsBasicSurface(st)) {
291   //  AddFail(st, "BasicSurface Transfer Error : Not Allowed IGESEntity");  This message can not occur.
292     return res;
293   }
294
295   IGESToBRep_BasicSurface BS(*this);
296
297   Handle(Geom_Surface) surf = BS.TransferBasicSurface(st);
298   if (surf.IsNull()) {
299     // AddFail(st, "Surface Conversion Error"); Messages have ever been Added in the called function.
300     return res;
301   }
302
303   //#9 rln 26/02/98 UKI60106
304   if (surf->Continuity() < GeomAbs_C1) {
305     Message_Msg msg1250("IGES_1250");
306     SendWarning(st, msg1250);
307   }
308   if(surf->IsKind(STANDARD_TYPE(Geom_Plane))){
309     BRep_Builder B;
310     TopoDS_Face plane;
311     B.MakeFace(plane);
312     B.UpdateFace(plane, surf, TopLoc_Location(), Precision::Confusion());
313     res = plane; 
314   }
315   else {
316     BRepLib_MakeFace makeFace(surf, Precision::Confusion());
317     res = makeFace.Face();
318   }
319
320   if (st->HasTransf()) {
321     gp_Trsf trsf;
322     SetEpsilon(1.E-04);
323     if (IGESData_ToolLocation::ConvertLocation
324         (GetEpsilon(),st->CompoundLocation(),trsf,GetUnitFactor())) { 
325       TopLoc_Location locFace(trsf);
326       res.Move(locFace);
327     }
328     else {
329       Message_Msg msg1035("IGES_1035");
330       SendWarning(st, msg1035);
331     } 
332   }
333   return res;
334 }
335
336
337 //=======================================================================
338 //function : TransferRuledSurface
339 //purpose  : 
340 //=======================================================================
341 static void reparamBSpline(Handle(Geom_Curve)& curve,
342                            const Standard_Real First,
343                            const Standard_Real Last)
344 {
345   Handle (Geom_BSplineCurve) bscurve;
346   if (!curve->IsKind (STANDARD_TYPE (Geom_BSplineCurve))) {
347     if (curve->FirstParameter() < First || curve->LastParameter() > Last)
348       curve = new Geom_TrimmedCurve (curve, First, Last);
349     bscurve = GeomConvert::CurveToBSplineCurve (curve, Convert_RationalC1);
350   }
351   else {
352     bscurve = Handle (Geom_BSplineCurve)::DownCast (curve);
353     bscurve->Segment (First, Last);
354   }
355   
356   if (bscurve.IsNull())
357     return;
358   
359   TColStd_Array1OfReal Knots(1, bscurve->NbKnots());
360   bscurve->Knots(Knots);
361   BSplCLib::Reparametrize (0., 1., Knots);
362   bscurve->SetKnots(Knots);
363   curve = bscurve;
364 }
365
366 static void ReparamCurve(TopoDS_Edge& edge)
367 {
368   TopLoc_Location L;
369   Standard_Real First, Last;
370   
371   Handle (Geom_Curve) curve = Handle (Geom_Curve)::DownCast (BRep_Tool::Curve ( edge, L, First, Last )->Copy());
372   //if ( Abs (First) <= Precision::PConfusion() && Abs (Last - 1.) <= Precision::PConfusion() ) return;
373   if(!curve->IsKind(STANDARD_TYPE(Geom_Line))) return;
374   
375   reparamBSpline( curve, First, Last );
376   
377   BRep_Builder B;
378   B.UpdateEdge ( edge, curve, L, Precision::Confusion() );
379   B.Range ( edge, 0., 1 );
380 }
381
382
383 //=======================================================================
384 //function : TransferRuledSurface
385 //purpose  : 
386 //=======================================================================
387
388 TopoDS_Shape IGESToBRep_TopoSurface::TransferRuledSurface
389   (const Handle(IGESGeom_RuledSurface)& st)
390 { // Declaration of messages// 
391   // DCE 22/12/98
392   //Message_Msg msg1005("IGES_1005");
393   ////////////////////////////////
394   TopoDS_Shape res;
395
396   if (st.IsNull()) {
397     Message_Msg msg1005("IGES_1005");
398     SendFail(st, msg1005);
399     return res;
400   }
401
402   IGESToBRep_TopoCurve TC(*this);
403   //%13 pdn 12.02.99 
404   TC.SetContinuity (0);
405   Handle(IGESData_IGESEntity) igesCurve1 = st->FirstCurve();
406   Handle(IGESData_IGESEntity) igesCurve2 = st->SecondCurve();
407
408   if (igesCurve1.IsNull()) {
409     Message_Msg msg148("XSTEP_148");
410     SendFail(st, msg148); // Curve Reading Error : Null IGESEntity
411     return res;
412   }
413   if (igesCurve2.IsNull()) {
414     Message_Msg msg149("XSTEP_149");
415     SendFail(st, msg149); // Curve Reading Error : Null IGESEntity
416     return res;
417   }
418
419   Standard_Integer nbEdges1,   nbEdges2;
420   TopoDS_Shape     shape1,     shape2;
421   TopoDS_Wire      wire1,      wire2;
422   TopoDS_Wire      newWire1,   newWire2;
423   //TopoDS_Edge      edge1,      edge2; // skl
424
425   if (IGESToBRep::IsTopoCurve(igesCurve1)) { 
426     shape1 = TC.TransferTopoCurve(igesCurve1);
427     if (shape1.IsNull()) {
428       Message_Msg msg1156("IGES_1156");
429       const Standard_CString typeName(igesCurve1->DynamicType()->Name());
430       Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesCurve1);
431       msg1156.Arg(typeName);
432       msg1156.Arg(label);
433       SendFail(st, msg1156);
434       return res;
435     }
436
437     //%13 pdn 15.02.99
438     //added by rln on 03/12/97
439     //if shape1 is a wire it means that the curve1 in file was of continuity C0
440     //in order to get a face instead of shell when to BRepFill shape1
441     //should be retransfered with contionuity C0 (to get an edge). Once shape1
442     //has been built with C0, it is useless to require C1 from shape2 because
443     //anyway resulting surface was of continuity C0. Thus shape2 is built with C0
444 //    if (shape1.ShapeType() != TopAbs_EDGE) {
445 //      TC.SetContinuity (0);
446 //      shape1  = TC.TransferTopoCurve(igesCurve1);
447 //      if (shape1.IsNull()) {
448 //      Message_Msg msg1156("IGES_1156");
449 //      const Standard_CString typeName(igesCurve1->DynamicType()->Name());
450 //      Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesCurve1);
451 //      msg1156.Arg(typeName);
452 //      msg1156.Arg(label);
453 //      SendFail(st, msg1156);  
454 //      return res;
455 //      }
456 //      else {  
457 //        Message_Msg msg1250("IGES_1250");
458 //        SendWarning (st, msg1250); // RuledSurface was built with continuity C0
459 //      }
460 //    }
461     
462     TopAbs_ShapeEnum shapeEnum1 = shape1.ShapeType();
463     switch (shapeEnum1) {
464     case TopAbs_EDGE :
465       {
466         TopoDS_Edge edge1 = TopoDS::Edge(shape1);
467         ReparamCurve(edge1);
468         nbEdges1 = 1;
469       }
470       break;
471     case TopAbs_WIRE : 
472       {
473         wire1    = TopoDS::Wire(shape1);
474         nbEdges1 = 0;
475         for (TopoDS_Iterator hulot(wire1); hulot.More(); hulot.Next()) {
476          TopoDS_Edge edge1 = TopoDS::Edge(hulot.Value());
477          ReparamCurve(edge1);
478          nbEdges1++;
479         }
480       }
481       break;
482     default: 
483       {
484         // AddFail(st, "Curve Conversion Error."); This message can not occur.
485         return res;
486       }
487       //break; //szv#4:S4163:12Mar99 unreachable
488     }
489   }
490   else { 
491     Message_Msg msg148("XSTEP_148");
492     SendFail(st, msg148);
493     // Curve Type not Allowed.
494     return res;
495   }
496     
497   if (IGESToBRep::IsTopoCurve(igesCurve2)) { 
498     shape2 = TC.TransferTopoCurve(igesCurve2);
499     // dirflg = 0 join first to first, last to last
500     // dirflg = 1 join first to last, last to first
501     
502     if (shape2.IsNull()) {
503       Message_Msg msg1156("IGES_1156");
504       const Standard_CString typeName(igesCurve2->DynamicType()->Name());
505       Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesCurve2);
506       msg1156.Arg(typeName);
507       msg1156.Arg(label);
508       SendFail(st, msg1156);
509       // Curve Conversion Error.
510       return res;
511     }
512    Standard_Integer dirflag = st->DirectionFlag ();
513    // if (dirflag == 1){ // gka BUC60685
514       
515     //  shape2.Reverse();
516     //}
517
518     TopAbs_ShapeEnum shapeEnum2 = shape2.ShapeType();
519     switch (shapeEnum2) {
520     case TopAbs_EDGE : 
521       {
522         TopoDS_Edge edge2 = TopoDS::Edge(shape2);
523         ReparamCurve(edge2);
524         if (dirflag == 1)
525           shape2.Reverse();
526         nbEdges2 = 1;
527       }
528       break;
529     case TopAbs_WIRE :
530       {
531         wire2 = TopoDS::Wire(shape2);
532         nbEdges2 = 0;
533         for (TopoDS_Iterator cousto(wire2); cousto.More(); cousto.Next())  {
534           TopoDS_Edge edge2 = TopoDS::Edge(cousto.Value());
535           ReparamCurve(edge2);
536           nbEdges2++;
537         }
538         if (dirflag == 1) {   //gka BUC60685
539           Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData;
540           sewd2->Add(shape2);
541           sewd2->Reverse();
542           wire2 = sewd2->Wire();
543         }
544       }
545       break;
546     default:
547       { 
548         // AddFail(st, "Curve Conversion Error.");
549         return res;
550       }
551       //break; //szv#4:S4163:12Mar99 unreachable
552     }
553   }
554   else { 
555     Message_Msg msg149("XSTEP_149");
556     SendFail(st, msg149);
557     // Curve Type not Allowed
558     return res;
559   }
560   
561
562   if (nbEdges1 != nbEdges2) {
563     if (nbEdges1 == 1) {
564       Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData;
565       sewd1->Add(shape1);
566       wire1  = sewd1->Wire();
567     }
568     else if (nbEdges2 == 1) {
569       Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData;
570       sewd2->Add(shape2);
571       wire2  = sewd2->Wire();
572     }
573
574     if (!st->IsRuledByParameter()) {
575       // AddWarning (st,"Compute by parametric constant ratio");
576     }
577     if (!ShapeAlgo::AlgoContainer()->HomoWires
578         (wire1, wire2, newWire1, newWire2, st->IsRuledByParameter())) {
579       Message_Msg msg1255("IGES_1255");// "Ruled Surface Construction Error");
580       SendFail(st, msg1255);
581       return res;
582     }
583     nbEdges1 = 2;           // a number > 1
584   }
585
586   else if (nbEdges1 != 1) {
587     newWire1 = wire1;
588     newWire2 = wire2;
589   }
590
591
592   if (nbEdges1 == 1) {
593     
594     //:e3 abv 31 Mar 98: UK4.igs 3170: ruled surface with directixes - line
595     // In IGES, line is parametrised [0;1] - this should have been kept !
596     // Let us detect the case and remake curve as bspline [0;1]
597     for ( Standard_Integer i=1; i <=2; i++ ) {
598       //#43 rln 20.11.98 S4054 BUC50047 entity D463 (circles as generatrices [0, 2*PI])
599       //reparameterisation should be for all curves not with range [0, 1] (see IGES)
600       TopoDS_Edge edge = TopoDS::Edge ( i==1 ? shape1 : shape2 );
601       //ReparamCurve(edge);
602       TopLoc_Location L;
603       Standard_Real First, Last;
604       Handle (Geom_Curve) curve = Handle (Geom_Curve)::DownCast (BRep_Tool::Curve ( edge, L, First, Last )->Copy());
605       if ( Abs (First) <= Precision::PConfusion() && Abs (Last - 1.) <= Precision::PConfusion() ) continue;
606       
607       Handle (Geom_BSplineCurve) bscurve;
608       if (!curve->IsKind (STANDARD_TYPE (Geom_BSplineCurve))) {
609         if (curve->FirstParameter() < First || curve->LastParameter() > Last)
610           curve = new Geom_TrimmedCurve (curve, First, Last);
611         bscurve = GeomConvert::CurveToBSplineCurve (curve, Convert_RationalC1);
612       }
613       else {
614         bscurve = Handle (Geom_BSplineCurve)::DownCast (curve);
615         bscurve->Segment (First, Last);
616       }
617       TColStd_Array1OfReal Knots(1, bscurve->NbKnots());
618       bscurve->Knots(Knots);
619       BSplCLib::Reparametrize (0., 1., Knots);
620       bscurve->SetKnots(Knots);
621       
622       BRep_Builder B;
623       B.UpdateEdge ( edge, bscurve, L, Precision::Confusion() );
624       B.Range ( edge, 0., 1 );
625       if ( i ==1 ) shape1 = edge;
626       else shape2 = edge;
627     }
628     
629     res = BRepFill::Face(TopoDS::Edge(shape1), TopoDS::Edge(shape2));
630     Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(res));
631     if(surf->Continuity()==GeomAbs_C0) {
632       Message_Msg msg1250("IGES_1250");
633       SendWarning (st, msg1250);
634     }
635   }
636   else {
637     res = BRepFill::Shell(newWire1, newWire2);
638   }
639   if (res.IsNull()) {
640     Message_Msg msg1255("IGES_1255");// "Ruled Surface Construction Error");
641     SendFail(st, msg1255);
642     return res;
643   }
644
645
646   if (st->HasTransf()) {
647     gp_Trsf trsf;
648     SetEpsilon(1.E-04);
649     if (IGESData_ToolLocation::ConvertLocation
650         (GetEpsilon(),st->CompoundLocation(), trsf,GetUnitFactor())) { 
651       TopLoc_Location shapeLoc(trsf);
652       res.Move(shapeLoc);
653     }
654     else {
655       Message_Msg msg1035("IGES_1035");
656       SendWarning(st,msg1035); // Transformation : not a similarity
657     }
658   }
659   return res;
660 }
661
662
663 //=======================================================================
664 //function : TransferSurfaceOfRevolution
665 //purpose  : 
666 //=======================================================================
667
668 TopoDS_Shape IGESToBRep_TopoSurface::TransferSurfaceOfRevolution
669   (const Handle(IGESGeom_SurfaceOfRevolution)& st)
670 { // Declaration of messages// 
671   // DCE 22/12/98
672   //Message_Msg msg1005("IGES_1005");
673   ////////////////////////////////
674   TopoDS_Shape res;
675   if (st.IsNull()) {
676     Message_Msg msg1005("IGES_1005");
677     SendFail(st, msg1005);
678     return res;
679   }
680
681   IGESToBRep_TopoCurve  TC(*this);
682   IGESToBRep_BasicCurve BC(*this);
683   Handle(IGESData_IGESEntity) igesGeneratrix = st->Generatrix();
684   Handle(IGESGeom_Line)       igesAxis       = st->AxisOfRevolution();
685
686   if (igesGeneratrix.IsNull() || !IGESToBRep::IsTopoCurve(igesGeneratrix) ) {
687     Message_Msg msg153("XSTEP_153");
688     SendFail(st, msg153);
689     // Generatrix Reading Error : Null IGESEntity
690     // Generatrix : Not Allowed IGESEntity.
691     return res;
692   }
693   
694   DeclareAndCast(IGESGeom_Line,srgen,st->Generatrix());
695   if (!srgen.IsNull()) {
696     gp_Pnt gen1 = srgen->StartPoint();
697     gp_Pnt gen2 = srgen->EndPoint();
698     TheULength = gen1.Distance(gen2)*GetUnitFactor();
699   }
700
701   if (igesAxis.IsNull()) {
702     Message_Msg msg152("XSTEP_152");
703     SendFail(st, msg152);
704     return res;
705   }
706
707   //%13 pdn 15.02.99 
708   TC.SetContinuity(0);
709   TopoDS_Shape generatrix  = TC.TransferTopoCurve(igesGeneratrix);
710   if (generatrix.IsNull()) {
711     Message_Msg msg1156("IGES_1156");
712     const Standard_CString typeName("generatrix");
713     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesGeneratrix);
714     msg1156.Arg(typeName);
715     msg1156.Arg(label);
716     SendFail(st, msg1156);
717     // Generatrix Conversion Error.
718     return res;
719   }
720
721   gp_Trsf startLoc;
722   gp_Pnt pt1 = igesAxis->TransformedStartPoint(); //smh#11
723   gp_Pnt pt2 = igesAxis->TransformedEndPoint(); //smh#11
724   pt1.Scale(gp_Pnt(0,0,0),GetUnitFactor());
725   pt2.Scale(gp_Pnt(0,0,0),GetUnitFactor());
726   //#30 rln 19.10.98 To keep IGES surface normal CAS.CADE axis = reversed IGES axis
727   //CAS.CADE SA = 2*PI - IGES TA
728   //CAS.CADE TA = 2*PI - IGES SA
729   //gp_Ax1 revolAxis(pt1, gp_Dir(gp_Vec(pt1, pt2)));
730   //Standard_Real startAngle = st->StartAngle();
731   //Standard_Real endAngle = st->EndAngle();
732   gp_Ax1 revolAxis(pt1, gp_Dir( gp_Vec (pt2, pt1)));
733   Standard_Real startAngle = 2 * M_PI - st->EndAngle();
734   Standard_Real endAngle = 2 * M_PI - st->StartAngle();
735   Standard_Real deltaAngle = endAngle - startAngle;
736   Standard_Boolean IsFullAngle = ( deltaAngle > 2.*M_PI-Precision::PConfusion() );
737   if (IsFullAngle) deltaAngle = 2.*M_PI;  // ** CKY 18-SEP-1996
738   // il faudra translater les courbes 2d de startAngle pour 
739   // etre en phase IGES et BRep
740   startLoc.SetRotation(revolAxis, startAngle);
741   generatrix.Move(startLoc);
742   
743   // PTV file D44-11325-6.igs OCC660 depends on OCC450
744   // PTV 29.05.2002 OCC450 create Surface of Revolution by native API
745   // file NIC_file5.igs 
746   // (BRepPrimAPI_MakeRevol replace surface of revolution by plane then 3D and 2D curves are inconsistent;
747   // and 3D is ignored. As result shape is rectangle instead circle shape.
748   Handle(Geom_Curve) aBasisCurve;
749   
750   {
751     try
752     {
753       OCC_CATCH_SIGNALS
754       if (extractCurve3d(generatrix, aBasisCurve))
755       {
756         BRepBuilderAPI_MakeFace aMakeF;
757         Handle(Geom_Surface) aResultSurf = 
758                 new Geom_SurfaceOfRevolution(aBasisCurve, revolAxis);
759
760         if ( !aResultSurf.IsNull())
761         {
762           if (!IsFullAngle)
763           {
764             const Standard_Real VF = aBasisCurve->FirstParameter();
765             const Standard_Real VL = aBasisCurve->LastParameter();
766             
767             // PTV 29.08.2002  begin of OCC663 Trim surface by correct parameters
768             const Standard_Real UF = 0;
769             const Standard_Real UL = endAngle - startAngle;
770             // PTV 29.08.2002  end of OCC663
771
772             aMakeF.Init(aResultSurf, UF, UL, VF, VL, Precision::Confusion());
773           }//if (!IsFullAngle)
774           else
775           {
776             aMakeF.Init(aResultSurf, Standard_True, Precision::Confusion());
777           }
778
779           if (aMakeF.IsDone())
780             res = aMakeF.Face();
781         }//if ( !aResultSurf.IsNull())
782       }//if (extractCurve3d(generatrix, aBasisCurve))
783     }
784     catch (Standard_Failure const& anException) {
785 #ifdef OCCT_DEBUG
786       cout << "Warning: IgesToBRep_TopoSurface::"
787                     "TransferSurfaceOfRevolution(): exception by Geom: ";
788       anException.Print ( cout ); cout << endl;
789 #endif
790       (void)anException;
791     }//catch (Standard_Failure)
792   }
793   
794   if ( res.IsNull() ) {
795     // do as usual.
796   
797     BRepPrimAPI_MakeRevol revol(generatrix, revolAxis, deltaAngle);
798 //mjm: si debug IsDone()est fait : 
799 //  if (!revol.IsDone()) {
800 //    AddFail(st, "Revol Construction Error.");
801 //    return res;
802 //  }
803     res = revol.Shape();
804   }
805   //%13 pdn 15.02.99
806   if (res.ShapeType() == TopAbs_FACE) {
807     Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(res));
808     if(surf->Continuity()==GeomAbs_C0) {
809       Message_Msg msg1250("IGES_1250");
810       SendWarning (st, msg1250);
811     } 
812   }
813
814   if (st->HasTransf()) {
815     gp_Trsf trsf;
816     SetEpsilon(1.E-04);
817     if (IGESData_ToolLocation::ConvertLocation
818         (GetEpsilon(), st->CompoundLocation(), trsf, GetUnitFactor())) { 
819       TopLoc_Location shapeLoc(trsf);
820       res.Move(shapeLoc);
821     }
822     else {
823       Message_Msg msg1035("IGES_1035");
824       SendWarning(st,msg1035); // Transformation : not a similarity
825     }
826   }
827     
828   return res;
829 }
830
831
832 //=======================================================================
833 //function : TransferTabulatedCylinder
834 //purpose  : 
835 //=======================================================================
836
837 TopoDS_Shape IGESToBRep_TopoSurface::TransferTabulatedCylinder
838        (const Handle(IGESGeom_TabulatedCylinder)& st)
839 { // Declaration of messages// 
840   // DCE 22/12/98
841   //Message_Msg msg1005("IGES_1005");
842   ////////////////////////////////
843   TopoDS_Shape res;
844   if (st.IsNull()) {
845     Message_Msg msg1005("IGES_1005");
846     SendFail(st, msg1005);
847     return res;
848   }
849
850   IGESToBRep_TopoCurve TC(*this);
851 //  TopoDS_Edge  firstEdge;//commented by rln on 02/12/97
852
853   Handle(IGESData_IGESEntity) igesDirectrix = st->Directrix();
854   if (igesDirectrix.IsNull() || !IGESToBRep::IsTopoCurve(igesDirectrix) ) {
855     Message_Msg msg153("XSTEP_153");
856     SendFail(st, msg153); 
857     // Directrix Reading Error : Null IGESEntity
858     //Directrix, not allowed IGESEntity
859     return res;
860   }
861
862   //%13 pdn 15.02.99
863   TC.SetContinuity(0);
864   TopoDS_Shape directrix = TC.TransferTopoCurve(igesDirectrix);
865   if (directrix.IsNull()) {
866     Message_Msg msg1156("IGES_1156");
867     const Standard_CString typeName("directrix");
868     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesDirectrix);
869     msg1156.Arg(typeName);
870     msg1156.Arg(label);
871     SendFail(st, msg1156);
872     // Directrix Conversion Error.
873     return res;
874   }
875
876   //modified by rln on 03/12/97
877   //TopoDS_Vertex firstVertex = TopExp::FirstVertex(firstEdge);
878   TopoDS_Vertex firstVertex, lastVertex;
879   ShapeAnalysis::FindBounds (directrix, firstVertex, lastVertex);
880   gp_Pnt pt1  = BRep_Tool::Pnt(firstVertex);
881   gp_Pnt pt2  = st->EndPoint();
882   pt2.Scale(gp_Pnt(0,0,0),GetUnitFactor());
883
884   TheULength = pt1.Distance(pt2);
885   if(TheULength < Precision::Confusion()) {
886     Message_Msg msg("Tabulated cylinder with zero length");
887     SendFail (st, msg); // TabulatedCylinder was built with continuity C0
888     return res;
889   }
890
891   // PTV file D44-11325-6.igs OCC660 depends on OCC450
892   // PTV 29.05.2002 OCC450 create Surface of LinearExtrusion by native API
893   // see description about problem in Surface of Revolution
894   Handle(Geom_Curve) aBasisCurve;
895   {
896   try {
897     OCC_CATCH_SIGNALS
898     if (extractCurve3d(directrix, aBasisCurve)) {
899       gp_Vec dir (pt1, pt2);
900       Handle(Geom_Surface) aResultSurf = 
901         new Geom_SurfaceOfLinearExtrusion(aBasisCurve, dir);
902       if (!aResultSurf.IsNull()) {
903         //aResultSurf = 
904         //  new Geom_RectangularTrimmedSurface(aResultSurf, 
905         //                                     aBasisCurve->FirstParameter(),
906         //                                     aBasisCurve->LastParameter(),
907         //                                     0., dir.Magnitude() );
908         BRepBuilderAPI_MakeFace aMakeF(aResultSurf, aBasisCurve->FirstParameter(),
909                                              aBasisCurve->LastParameter(),
910                                              0., dir.Magnitude(),
911                                              Precision::Confusion());
912         if (aMakeF.IsDone())
913           res = aMakeF.Face();
914       }
915     }
916   }
917   catch (Standard_Failure const& anException) {
918 #ifdef OCCT_DEBUG
919     cout << "Warning: IgesToBRep_TopoSurface::TransferTabulatedCylinder(): exception by Geom: ";
920     anException.Print ( cout ); cout << endl;
921 #endif
922     (void)anException;
923   }
924   }
925   
926   if ( res.IsNull() ) {
927     // do as usual.
928     BRepPrimAPI_MakePrism prism(directrix, gp_Vec(pt1, pt2));
929 //mjm: si debug IsDone() est fait
930 //  if (!prism.IsDone()) {
931 //    AddFail(st, "Prism Construction Error.");
932 //    return res;
933 //  }
934     res = prism.Shape();
935   }
936   //#16 rln 08/04/98 coq-inf-support.igs entity 2105
937   //CAS.CADE can parametrize SurfaceOfLinearExtrusion with generatrix opposite to Vec(pt1, pt2)
938   //and with parametrization V > 0, while in IGES TabulatedCylinder is parametrized with positive V
939   //direction exactly in the direction Vec(pt1, pt2)
940   if (res.ShapeType() == TopAbs_FACE) {
941     Standard_Real UMin, UMax, VMin, VMax;
942     BRepTools::UVBounds (TopoDS::Face (res), UMin, UMax, VMin, VMax);
943     if (VMax <= Precision::PConfusion() && VMin < -Precision::PConfusion()) {
944       TheULength *= -1;
945       res.Reverse();
946     }
947     Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(res));
948     if(surf->Continuity()==GeomAbs_C0) {
949       Message_Msg msg1250("IGES_1250");
950       SendWarning (st, msg1250);
951     }
952   }
953     
954   if (st->HasTransf()) {
955     gp_Trsf trsf;
956     SetEpsilon(1.E-04);
957     if (IGESData_ToolLocation::ConvertLocation
958         (GetEpsilon(),st->CompoundLocation(), trsf, GetUnitFactor())) { 
959       TopLoc_Location shapeLoc(trsf);
960       res.Move(shapeLoc);
961     }
962     else {
963       Message_Msg msg1035("IGES_1035");
964       SendWarning(st,msg1035); // Transformation : not a similarity
965     }
966   }
967   return res;
968 }
969
970
971 //=======================================================================
972 //function : TransferOffsetSurface
973 //purpose  : 
974 //=======================================================================
975
976 TopoDS_Shape IGESToBRep_TopoSurface::TransferOffsetSurface
977   (const Handle(IGESGeom_OffsetSurface)& st)
978 { // Declaration of messages// 
979   // DCE 22/12/98
980   //Message_Msg msg1005("IGES_1005");
981   ////////////////////////////////
982   TopoDS_Shape    res;
983   if (st.IsNull()) {
984     Message_Msg msg1005("IGES_1005");
985     SendFail(st, msg1005);
986     return res;
987   }
988
989   TopoDS_Shape    igesShape;
990   TopoDS_Face     face;
991   TopLoc_Location basisLoc;
992
993   Handle (IGESData_IGESEntity) igesSrf = st->Surface();
994   if (igesSrf.IsNull() || !IGESToBRep::IsTopoSurface(igesSrf) ) {
995     Message_Msg msg164("XSTEP_164");
996     SendFail(st, msg164); 
997     // Basis Surface Reading Error : Null IGESEntity
998     // Basis Surface Transfer Error : Not Allowed IGESEntity 
999     return res;
1000   }
1001
1002   igesShape = TransferTopoSurface(igesSrf);
1003   if (igesShape.IsNull()) {
1004     Message_Msg msg1156("IGES_1156");
1005     const Standard_CString typeName("basis surface");
1006     Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSrf);
1007     msg1156.Arg(typeName);
1008     msg1156.Arg(label);
1009     SendFail(st, msg1156);  // Basis Surface Conversion Error.
1010     return res;
1011   }
1012   
1013   TopAbs_ShapeEnum shapeEnum = igesShape.ShapeType();
1014   switch (shapeEnum) {
1015   case TopAbs_FACE :
1016     {
1017       face = TopoDS::Face(igesShape);
1018       break;
1019     }
1020   case TopAbs_SHELL :
1021     {
1022       TopoDS_Iterator dabovil(igesShape);
1023       if (dabovil.More()) {
1024         SendWarning(st, "The First Surface only will be transfered.");
1025         face = TopoDS::Face(dabovil.Value());
1026         break;
1027       }
1028       /* else  AddF("... */
1029     }
1030     Standard_FALLTHROUGH
1031   default:
1032     {
1033       Message_Msg msg1156("IGES_1156");
1034       const Standard_CString typeName("basis surface");
1035       Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSrf);
1036       msg1156.Arg(typeName);
1037       msg1156.Arg(label);
1038       SendFail(st, msg1156);  // Basis Surface Conversion Error.
1039       return res;
1040     }
1041   }
1042   
1043   
1044   //Handle(Geom_Surface) geomSupport = BRep_Tool::Surface(face, basisLoc);
1045   // attention on ne peut construire une Geom_OffsetSurface que
1046   // si la surface de base est au moins C1, sinon on plante !
1047   //#56 rln 25.12.98 UKI60878 entity D593 (Offset surface on C0 B-Spline)
1048   //Trying to eliminate previous limitation on processing only C1 surfaces
1049   Handle(Geom_Surface) geomSupport = BRep_Tool::Surface(face);
1050   Handle(Geom_OffsetSurface) basisSrf;
1051   
1052   if (geomSupport->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1053     DeclareAndCast(Geom_OffsetSurface, geom140, geomSupport);
1054     geom140->SetOffsetValue(basisSrf->Offset() + 
1055                             st->Distance()*GetUnitFactor());
1056     basisSrf = geom140;
1057   }
1058   else {
1059     if (geomSupport->Continuity() == GeomAbs_C0) {
1060       res = ShapeAlgo::AlgoContainer()->C0ShapeToC1Shape (face, Abs (st->Distance()) * GetUnitFactor());
1061       if(res.ShapeType()!=TopAbs_FACE) {
1062         Message_Msg msg1266("IGES_1266");
1063         SendFail(st, msg1266);//Basis surface is C0-continuous and cannot be corrected to C1-continuous.
1064         return res;
1065       }
1066       else {
1067         geomSupport = BRep_Tool::Surface (TopoDS::Face(res));
1068         if (geomSupport->Continuity() == GeomAbs_C0) {
1069           Message_Msg msg1266("IGES_1266");
1070           SendFail(st, msg1266);//Basis surface is C0-continuous and cannot be corrected to C1-continuous.
1071           res.Nullify();
1072           return res;
1073         }
1074       }
1075       Message_Msg msg1267("IGES_1267");
1076       SendWarning(st, msg1267);//Basis surface is C0-continuous but was corrected to C1-continuous
1077     }
1078     //smh#12
1079     if (res.IsNull()) res = face;
1080     geomSupport = BRep_Tool::Surface (TopoDS::Face(res));
1081     Standard_Real umin, umax, vmin, vmax;
1082     geomSupport->Bounds (umin, umax, vmin, vmax);
1083     if (Precision::IsInfinite (umin) || Precision::IsInfinite (umax) ||
1084         Precision::IsInfinite (vmin) || Precision::IsInfinite (vmax)) {
1085       // convert to C1 B-Spline
1086       BRepTools::UVBounds (face, umin, umax, vmin, vmax);
1087       Handle(Geom_RectangularTrimmedSurface) TS = new Geom_RectangularTrimmedSurface (geomSupport, umin, umax, vmin, vmax);
1088       Handle (Geom_BSplineSurface) BS = ShapeAlgo::AlgoContainer()->ConvertSurfaceToBSpline(TS, umin, umax, vmin, vmax);
1089       if (BS.IsNull() || BS->Continuity() == GeomAbs_C0) {
1090         Message_Msg msg1265("IGES_1265");
1091         SendFail(st, msg1265); // OffsetSurface Construction Error.
1092         return res;
1093       }
1094       else {
1095         geomSupport = BS;
1096       }
1097     }
1098     basisSrf = new Geom_OffsetSurface(geomSupport, st->Distance()*GetUnitFactor());
1099   }
1100   
1101   BRepLib_MakeFace MF(basisSrf, Precision::Confusion());
1102   if(!MF.IsDone()) {
1103     Message_Msg msg1265("IGES_1265");
1104     SendFail(st, msg1265); // OffsetSurface Construction Error.
1105     return res;
1106   }
1107
1108   res = MF.Face();
1109   
1110   if (st->HasTransf()) {
1111     gp_Trsf trsf;
1112     SetEpsilon(1.E-04);
1113     if (IGESData_ToolLocation::ConvertLocation
1114         (GetEpsilon(),st->CompoundLocation(),trsf, GetUnitFactor())) { 
1115       TopLoc_Location loc2(trsf);
1116       res.Move(loc2);
1117     }
1118     else {
1119       Message_Msg msg1035("IGES_1035");
1120       SendWarning(st,msg1035); // Transformation : not a similarity
1121     }
1122   }
1123   return res;
1124 }
1125
1126
1127 //=======================================================================
1128 //function : TransferTrimmedSurface
1129 //purpose  : 
1130 //=======================================================================
1131
1132 TopoDS_Shape IGESToBRep_TopoSurface::TransferTrimmedSurface
1133        (const Handle(IGESGeom_TrimmedSurface)& st)
1134 { // Declaration of messages// 
1135   // DCE 22/12/98
1136   //Message_Msg msg1005("IGES_1005");
1137   ////////////////////////////////
1138   TopoDS_Shape res;
1139   if (st.IsNull()) {
1140     Message_Msg msg1005("IGES_1005");
1141     SendFail(st, msg1005);
1142     return res;
1143   }
1144   
1145   TopAbs_ShapeEnum shapeEnum;
1146   IGESToBRep_TopoCurve TC(*this);
1147
1148   Handle (IGESData_IGESEntity) igesSurface = st->Surface();
1149   if (igesSurface.IsNull() || !IGESToBRep::IsTopoSurface(igesSurface) ) {
1150     Message_Msg msg169("XSTEP_169");   
1151     SendFail(st, msg169);
1152     // BasicSurface Transfer Error : Null IGESEntity
1153     // Basis Surface, not Allowed IGESEntity.
1154     return res;
1155   }
1156   gp_Trsf2d trans;
1157   Standard_Real uFact;
1158   TopoDS_Face  face, faceres;
1159   
1160   TopoDS_Shape myshape = ParamSurface(igesSurface, trans, uFact);
1161
1162   if (!myshape.IsNull()) {
1163     shapeEnum = myshape.ShapeType();
1164     switch (shapeEnum) {
1165     case TopAbs_FACE :
1166       {
1167         face = TopoDS::Face(myshape);
1168         faceres = face;
1169         break;
1170       }
1171     case TopAbs_SHELL :
1172       {
1173         TopoDS_Iterator IT(myshape);
1174         Standard_Integer nbfaces = 0;
1175         for (; IT.More(); IT.Next()) {
1176           nbfaces++;
1177           face = TopoDS::Face(IT.Value());
1178           faceres = face;
1179         }
1180         //szv#4:S4163:12Mar99 optimized
1181         if (nbfaces != 1) {
1182           Message_Msg msg1156("IGES_1156");
1183           const Standard_CString typeName("basis surface");
1184           Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSurface);
1185           msg1156.Arg(typeName);
1186           msg1156.Arg(label);
1187           SendFail(st, msg1156);  // Not Implemented Trimmed Composite Surface.
1188           return myshape;
1189         }
1190       }
1191       break;
1192     default:
1193       {
1194         Message_Msg msg1156("IGES_1156");
1195         const Standard_CString typeName("basis surface");
1196         Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSurface);
1197         msg1156.Arg(typeName);
1198         msg1156.Arg(label);
1199         SendFail(st, msg1156);  // Basis Surface Conversion Error.
1200         return res;
1201       }
1202     }
1203   }
1204   else {
1205     return res;
1206   }
1207   
1208   //obtaining a surface
1209   TopLoc_Location L;
1210   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(face, L);
1211   TC.SetSurface(aSurf);
1212   
1213   if (st->HasOuterContour()) {
1214     face.EmptyCopy();
1215     TopoDS_Shape myshape1 = TC.TransferCurveOnFace (face, st->OuterContour(), trans, uFact, Standard_False);
1216     // si ca se passe mal , on recupere au moins la face avec NaturalRestriction
1217     if (myshape1 .IsNull()) {
1218       face = faceres;
1219       BRep_Builder B;
1220       B.NaturalRestriction(face,Standard_False);
1221     }
1222   }
1223   for (Standard_Integer i = 1; i <= st->NbInnerContours(); i++) {
1224     TopoDS_Shape myshape2 = TC.TransferCurveOnFace (face, st->InnerContour(i), trans, uFact, Standard_False);
1225   }
1226   BRepTools::Update ( face ); //:p4
1227   //%16 pdn 08.04.99
1228   return face;
1229 }
1230
1231
1232 //=======================================================================
1233 //function : TransferBoundedSurface
1234 //purpose  : 
1235 //=======================================================================
1236
1237 TopoDS_Shape  IGESToBRep_TopoSurface::TransferBoundedSurface
1238   (const Handle(IGESGeom_BoundedSurface)&  st)
1239 { // Declaration of messages// 
1240   // DCE 22/12/98
1241   //Message_Msg msg1005("IGES_1005");
1242   ////////////////////////////////
1243   TopoDS_Shape res;
1244   if (st.IsNull()) {
1245     Message_Msg msg1005("IGES_1005");
1246     SendFail(st, msg1005);
1247     return res;
1248   }
1249
1250   if (st->RepresentationType()==0) {
1251     Message_Msg msg1275("IGES_1275");
1252     SendWarning(st, msg1275);
1253     // Model Space Representation Not Implemented : the result will be the basis surface
1254   }
1255   
1256   TopAbs_ShapeEnum shapeEnum;
1257   IGESToBRep_TopoCurve TC(*this);
1258   Handle (IGESData_IGESEntity) igesSrf = st->Surface();
1259   if (igesSrf.IsNull() || !IGESToBRep::IsTopoSurface(igesSrf) ) {
1260     Message_Msg msg166("XSTEP_166");
1261     SendFail( st, msg166);
1262     // Basis Surface Transfer Error : Null IGESEntity.
1263     // Basis Surface Transfer Error : Not Allowed IGESEntity.
1264     return res;
1265   }
1266   gp_Trsf2d trans;
1267   Standard_Real uFact;
1268   TopoDS_Face  face;
1269
1270   TopoDS_Shape myshape = ParamSurface(igesSrf, trans, uFact);
1271
1272   if (myshape.IsNull()) {
1273     //#55 rln 24.12.98 UKI60878 entity D593
1274 #ifdef OCCT_DEBUG
1275     cout << "Fail: IGESToBRep_TopoSurface::TransferBoundedSurface  UntrimmedSurface is translated into Null" << endl;
1276 #endif
1277     return res;
1278   }
1279   else {
1280     shapeEnum = myshape.ShapeType();
1281     switch (shapeEnum) {
1282     case TopAbs_FACE :
1283       {
1284         face = TopoDS::Face(myshape);
1285       }
1286       break;
1287     case TopAbs_SHELL :
1288       {
1289         TopoDS_Iterator IT(myshape);
1290         Standard_Integer nbfaces = 0;
1291         for (; IT.More(); IT.Next()) {
1292           nbfaces++;
1293           face = TopoDS::Face(IT.Value());
1294         }
1295         //szv#4:S4163:12Mar99 optimized
1296         if (nbfaces != 1) {
1297           Message_Msg msg1156("IGES_1156");
1298           const Standard_CString typeName("basis surface");
1299           Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSrf);
1300           msg1156.Arg(typeName);
1301           msg1156.Arg(label);
1302           SendFail(st, msg1156);
1303           // Not Implemented Trimmed Composite Surface.
1304           return myshape;
1305         }
1306       }
1307       break;
1308     default:
1309       { 
1310         Message_Msg msg1156("IGES_1156");
1311         const Standard_CString typeName("basis surface");
1312         Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(igesSrf);
1313         msg1156.Arg(typeName);
1314         msg1156.Arg(label);
1315         SendFail(st, msg1156);
1316         return res;
1317       }
1318     }
1319   }
1320   
1321   face.EmptyCopy();
1322   for (Standard_Integer i = 1; i <= st->NbBoundaries(); i++) 
1323     TC.TransferBoundaryOnFace(face, st->Boundary(i), trans, uFact);
1324   
1325   BRepTools::Update ( face ); //:p4
1326   //#22 rln 01.06.98 UK3.igs entity 1279
1327 //  ShapeFix_Face sff ( face );
1328 //  sff.FixMissingSeam(); //:l1 abv 10 Jan 99: USA60022 7289: fix missing seam
1329 //  if(sff.FixSmallAreaWire()) { //%14 pdn 24.02,99: USA60293: fix small area wires.
1330 //    AddFail(st, "Small area wire detected, dropped"); 
1331 //  }
1332 //  sff.FixOrientation();
1333 //  face = sff.Face();
1334   //%16 pdn 08.04.99
1335   return face;
1336 }
1337
1338
1339 //=======================================================================
1340 //function : TransferPlane
1341 //purpose  : 
1342 //=======================================================================
1343
1344 TopoDS_Shape IGESToBRep_TopoSurface::TransferPlane
1345   (const Handle(IGESGeom_Plane)& st)
1346 { // Declaration of messages// 
1347   // DCE 22/12/98
1348   //Message_Msg msg1005("IGES_1005");
1349   ////////////////////////////////
1350   TopoDS_Shape     res;
1351   if (st.IsNull()) {
1352     Message_Msg msg1005("IGES_1005");
1353     SendFail(st, msg1005);
1354     return res;
1355   }
1356
1357   gp_Pln  pln;
1358   gp_Trsf trsf;
1359   res = TransferPlaneParts (st, pln,trsf,Standard_True);
1360 //   res contient (en principe ...) une Face avec eventuellement un Wire
1361 //   il reste a la mettre en position
1362   if (trsf.Form() != gp_Identity) {
1363     TopLoc_Location loc(trsf);
1364     res.Location(loc);
1365   }
1366   return res;
1367 }
1368
1369
1370 //=======================================================================
1371 //function : TransferPlaneSurface
1372 //purpose  : this function transferred into IGESToBRep_BasicSurface
1373 //=======================================================================
1374
1375
1376 //=======================================================================
1377 //function : TransferPerforate
1378 //purpose  : 
1379 //=======================================================================
1380
1381 TopoDS_Shape  IGESToBRep_TopoSurface::TransferPerforate
1382   (const Handle(IGESBasic_SingleParent)& st)
1383 { // Declaration of messages// 
1384   // DCE 22/12/98
1385   //Message_Msg msg1005("IGES_1005");
1386   ////////////////////////////////
1387   TopoDS_Shape     res;
1388   if (st.IsNull()) {
1389     Message_Msg msg1005("IGES_1005");
1390     SendFail(st, msg1005);
1391     return res;
1392   }
1393
1394   //char mess[100];
1395   gp_Pln  pln;
1396   gp_Trsf trsf;
1397   DeclareAndCast(IGESGeom_Plane,p0,st->SingleParent());
1398   BRep_Builder B;
1399   if (p0.IsNull()) {
1400     Message_Msg msg206("XSTEP_206");   
1401     SendFail(st, msg206);
1402     // SingleParent does not describe a holed face
1403     return res;
1404   }
1405   res = TransferPlaneParts (p0,pln,trsf,Standard_True);
1406 //res demarre avec la face et son contour externe
1407   Standard_Integer nb = st->NbChildren();
1408   for (Standard_Integer i = 1; i <= nb; i ++) {
1409     DeclareAndCast(IGESGeom_Plane,pi,st->Child(i));
1410     if (pi.IsNull()) {
1411       Message_Msg msg1285("IGES_1285");
1412       msg1285.Arg(i);
1413       // A child is not a Plane, skipped, n0 %d
1414       SendWarning(st,msg1285);
1415       continue;
1416     }
1417     gp_Pln  pli;
1418     gp_Trsf trsi;
1419     TopoDS_Shape wire = TransferPlaneParts (pi,pli,trsi,Standard_False);
1420 //    si ce n est pas un Wire, sauter
1421     if (wire.ShapeType() != TopAbs_WIRE) {
1422       Message_Msg msg1156("IGES_1156");
1423       const Standard_CString typeName("hole");
1424       Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(pi);
1425       msg1156.Arg(typeName);
1426       msg1156.Arg(label);
1427       SendWarning(st, msg1156);
1428       // A hole could not be transferred, skipped, n0 %d
1429       continue;
1430     }
1431 //    coplanaires ? verifier
1432     if (!pln.Position().IsCoplanar(pli.Position(),GetEpsGeom(),GetEpsilon())) {
1433       Message_Msg msg1295("IGES_1295");
1434       msg1295.Arg(i);
1435       SendWarning(st,msg1295);
1436       // "A hole is not well coplanar to the face, n0 %d",i);
1437     }
1438 //    Ne pas oublier de composer la transformation locale a ce Wire
1439     if (trsi.Form() != gp_Identity) {
1440       TopLoc_Location locw(trsi);
1441       wire.Location(locw);
1442     }
1443     B.Add (res,wire);
1444   }
1445 //    Enfin, appliquer la trsf globale
1446   if (trsf.Form() != gp_Identity) {
1447     TopLoc_Location loc(trsf);
1448     res.Location(loc);
1449   }
1450   return res;
1451 }
1452
1453
1454 //=======================================================================
1455 //function : TransferPlaneParts
1456 //purpose  : 
1457 //=======================================================================
1458 TopoDS_Shape IGESToBRep_TopoSurface::TransferPlaneParts(const Handle(IGESGeom_Plane)& st,
1459                                                         gp_Pln&  pln,  
1460                                                         gp_Trsf&  trsf,
1461                                                         const Standard_Boolean first)
1462 { // Declaration of messages// 
1463   // DCE 22/12/98
1464   //Message_Msg msg1005("IGES_1005");
1465   ////////////////////////////////
1466   TopoDS_Shape res;
1467   if (st.IsNull()) {
1468     Message_Msg msg1005("IGES_1005");
1469     SendFail(st, msg1005);
1470     return res;
1471   }
1472
1473   Standard_Real a, b, c, d;
1474   // equation de Geom : ax + by + cz + d = 0.0;
1475   // equation de IGES : ax + by + cz = d;
1476   st->Equation(a, b, c, d);
1477   pln = gp_Pln(a, b, c, -d);
1478   
1479   TopoDS_Face plane;
1480   TopoDS_Wire wire;
1481   BRep_Builder B;
1482   if (first) {
1483     B.MakeFace(plane);         // Just to create a empty Plane with a Tshape.
1484     Handle (Geom_Plane) geomPln = new Geom_Plane(pln);
1485     geomPln->Scale(gp_Pnt(0,0,0),GetUnitFactor());
1486 //   ATTENTION, ici on CALCULE la trsf, on ne l`applique pas ...
1487     //S4054: B.UpdateFace (plane, geomPln, TopLoc_Location(), 
1488                            //GetEpsGeom()*GetUnitFactor());
1489     B.UpdateFace (plane, geomPln, TopLoc_Location(), Precision::Confusion());
1490     //:3 by ABV 5 Nov 97: set Infinite() flag (see below for unsetting)
1491     plane.Infinite ( Standard_True );  //:3
1492   }
1493
1494 //   ATTENTION, ici on CALCULE la trsf, on ne l'appliquera qu'a la fin !
1495   if (st->HasTransf()) {
1496     SetEpsilon(1.E-04);
1497     if (!IGESData_ToolLocation::ConvertLocation
1498         (GetEpsilon(), st->CompoundLocation(),trsf,GetUnitFactor())) { 
1499       Message_Msg msg1035("IGES_1035");
1500       SendWarning(st,msg1035); // Transformation : not a similarity
1501     }
1502   }
1503
1504   if (st->HasBoundingCurve()) {
1505     IGESToBRep_TopoCurve TC(*this);
1506     Handle(IGESData_IGESEntity) crv = st->BoundingCurve();
1507
1508     if (crv.IsNull()) {
1509       Message_Msg msg1300("IGES_1300");
1510       SendWarning(st,msg1300);
1511       //:4 by ABV 5 Nov 97: plane cannot be trimmed - let it be infinite
1512       //:4 NOTE: NB "else"
1513       //:4      return res;
1514     }
1515     else //:4
1516       
1517       if (IGESToBRep::IsTopoCurve(crv)) {
1518         gp_Trsf trans;
1519         if (crv->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface))) {
1520           DeclareAndCast(IGESGeom_CurveOnSurface, crv142, crv);
1521           TopoDS_Shape myshape = TC.TransferCurveOnFace (plane, crv142, trans, TheULength, Standard_False);
1522           
1523           //:3 by ABV 5 Nov 97: set plane to be finite
1524           if ( first ) {
1525             TopExp_Explorer ws ( plane, TopAbs_WIRE ); 
1526             if ( ws.More() ) plane.Infinite ( Standard_False ); 
1527           }
1528         }
1529         else {
1530           TopoDS_Shape     shape = TC.TransferTopoCurve(crv);
1531           TopAbs_ShapeEnum shapeEnum = shape.ShapeType();
1532           switch (shapeEnum) {
1533           case TopAbs_EDGE :
1534             {
1535               TopoDS_Edge edge = TopoDS::Edge(shape);
1536               Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
1537               sewd->Add(edge);
1538               wire = sewd->Wire();
1539             }
1540             break;
1541           case TopAbs_WIRE :
1542             {
1543               wire = TopoDS::Wire(shape);           
1544             }
1545           break;
1546           default:
1547             { 
1548               Message_Msg msg1156("IGES_1156");
1549               const Standard_CString typeName("Bounding curve");
1550               Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(crv);
1551               msg1156.Arg(typeName);
1552               msg1156.Arg(label);
1553               SendWarning(st, msg1156);
1554               if (first) res = plane;
1555               else       res = wire;
1556               return res;
1557             }
1558           }
1559           //S4054 CTS18953 entity 14
1560           Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
1561           sfw->Load (wire);
1562           sfw->FixConnected (GetMaxTol());
1563           wire = sfw->Wire();
1564           BRepLib_MakeFace MF(pln, wire, Standard_False);
1565           if (!MF.IsDone()) {
1566             // AddFail(st, "Plane Construction Error.");
1567             return res;
1568           }
1569           
1570           TopoDS_Face F = MF.Face();
1571           GProp_GProps G;
1572           BRepGProp::SurfaceProperties(F,G);
1573           if (G.Mass() < 0) {
1574             if(!st->HasBoundingCurveHole())    
1575               wire.Reverse();
1576           }
1577           else
1578             if( st->HasBoundingCurveHole())
1579               wire.Reverse();
1580           //:3 by ABV 5 Nov 97: set plane to be finite
1581           //:3        if (first) B.Add (plane,wire);
1582           if ( first ) { 
1583             B.Add ( plane, wire ); 
1584             plane.Infinite ( Standard_False ); 
1585           } 
1586           //BRepLib_MakeFace MP(pln, wire);
1587           //plane = MP.Face();
1588         }
1589       }
1590       else {
1591         Message_Msg msg1156("IGES_1156");
1592         const Standard_CString typeName("Bounding curve");
1593         Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(crv);
1594         msg1156.Arg(typeName);
1595         msg1156.Arg(label);
1596         SendWarning(st, msg1156);
1597         // Plane Cannot Be Trimmed.
1598       }
1599   }
1600   
1601   if (first) res = plane;
1602   else       res = wire;
1603   return res;
1604 }
1605
1606
1607 //=======================================================================
1608 //function : ParamSurface
1609 //purpose  : 
1610 //=======================================================================
1611 TopoDS_Shape IGESToBRep_TopoSurface::ParamSurface(const Handle(IGESData_IGESEntity)& st,
1612                                                   gp_Trsf2d& trans,
1613                                                   Standard_Real& uFact) 
1614 { // Declaration of messages// 
1615   // DCE 22/12/98
1616   //Message_Msg msg1005("IGES_1005");
1617   ////////////////////////////////
1618
1619   TopoDS_Shape res;
1620
1621   TopoDS_Shape basisSurface = TransferTopoSurface(st);
1622   Standard_Real uscale = 1.;
1623   Standard_Real cscale = TheULength;
1624   if (basisSurface.IsNull()) {
1625     Message_Msg msg1005("IGES_1005");
1626     SendFail(st, msg1005);
1627     return res;
1628   }
1629
1630   TopAbs_ShapeEnum shapeEnum;
1631   shapeEnum = basisSurface.ShapeType();
1632   TopoDS_Face  face;
1633   switch (shapeEnum) {
1634   case TopAbs_FACE :
1635     {
1636       face = TopoDS::Face(basisSurface);
1637       break;
1638     }
1639   case TopAbs_SHELL :
1640     {
1641       TopoDS_Iterator IT(basisSurface);
1642       Standard_Integer nbfaces = 0;
1643       for (; IT.More(); IT.Next()) {
1644         nbfaces++;
1645         face = TopoDS::Face(IT.Value());
1646       }
1647       //szv#4:S4163:12Mar99 optimized
1648       if (nbfaces != 1) {
1649          Message_Msg msg1156("IGES_1156");
1650          const Standard_CString typeName("basis surface");
1651          Handle(TCollection_HAsciiString) label = GetModel()->StringLabel(st);
1652          msg1156.Arg(typeName);
1653          msg1156.Arg(label);
1654          SendWarning(st, msg1156);
1655          return basisSurface;
1656       }
1657     }
1658     break;
1659   default:
1660     {
1661       //AddFail(st, "Basis Surface Transfer Error.");
1662       return res;
1663     }
1664   }
1665   
1666   //S4181 pdn 19.04.99 defining shift of parametric space on base 
1667   // of CAS.CADE type of surface  
1668   Standard_Real paramu = 0., paramv = 0.;
1669   TopLoc_Location L;
1670   TopoDS_Edge theedge;
1671   Handle(Geom_Surface) Surf = BRep_Tool::Surface(face);
1672
1673   if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
1674     DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, Surf);
1675     Surf = rectang->BasisSurface();
1676   }
1677
1678   if ((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) ||
1679       (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))     ||
1680       (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))    ||
1681       (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)))) {
1682     TopExp_Explorer TE;
1683     for ( TE.Init(face,TopAbs_EDGE); TE.More(); TE.Next()){
1684       TopoDS_Edge myedge = TopoDS::Edge(TE.Current());
1685       Standard_Real First, Last;
1686       Handle(Geom2d_Curve) Curve2d = BRep_Tool::CurveOnSurface
1687         (myedge, face, First, Last);
1688       if ( Curve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
1689         DeclareAndCast(Geom2d_Line, Line2d, Curve2d);   
1690         if (Line2d->Direction().IsParallel(gp::DY2d(),Precision::Angular())){
1691           theedge = myedge;
1692           break;
1693         }
1694       }
1695     }
1696
1697     Standard_Real First, Last;
1698     Handle(Geom_Curve) Curve3d = BRep_Tool::Curve(theedge, First, Last); 
1699     if (Precision::IsNegativeInfinite(First)) First = 0.;  
1700     
1701     if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))){
1702       DeclareAndCast(Geom_CylindricalSurface, Cyl, Surf);
1703       gp_Cylinder TheCyl = Cyl->Cylinder();
1704       ElSLib::CylinderParameters(TheCyl.Position(), 
1705                                  TheCyl.Radius(), 
1706                                  Curve3d->Value(First), paramu , paramv );
1707     }
1708
1709     else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))){
1710       DeclareAndCast(Geom_ConicalSurface, Cone, Surf);
1711       gp_Cone TheCone = Cone->Cone();
1712       ElSLib::ConeParameters(TheCone.Position(), 
1713                              TheCone.RefRadius(), 
1714                              TheCone.SemiAngle(), 
1715                              Curve3d->Value(First), paramu , paramv );
1716     }
1717
1718     else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))){
1719       DeclareAndCast(Geom_ToroidalSurface, Tore, Surf);
1720       gp_Torus TheTore = Tore->Torus();
1721       ElSLib::TorusParameters(TheTore.Position(), 
1722                               TheTore.MajorRadius(), 
1723                               TheTore.MinorRadius(), 
1724                               Curve3d->Value(First), paramu , paramv );
1725     }
1726     else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) &&
1727              //: abv 18.06.02: loopback on s1.brep BRep mode, face 32 - the spherical surface (192)
1728              //: in IGES is from [-90,90] by V, i.e. similar to OCC, thus only scaling is enough
1729              ! st->IsKind (STANDARD_TYPE(IGESSolid_SphericalSurface)) ) {
1730       DeclareAndCast(Geom_SphericalSurface, Sphere, Surf);
1731       gp_Sphere TheSphere = Sphere->Sphere();
1732       ElSLib::SphereParameters(TheSphere.Position(), 
1733                                TheSphere.Radius(), 
1734                                Curve3d->Value(First), paramu , paramv );
1735     }
1736         
1737     //#88 rln 06.04.99 CTS60168, BLEND.IGS entity 68
1738     //Generatrix is Transformed Circular Arc. When creating CAS.CADE surface parameterization
1739     //has changed.
1740     if (st->IsKind (STANDARD_TYPE (IGESGeom_SurfaceOfRevolution))) {
1741       DeclareAndCast (IGESGeom_SurfaceOfRevolution, revol, st);
1742       Handle(IGESData_IGESEntity) generatrix = revol->Generatrix();
1743       if (generatrix->IsKind (STANDARD_TYPE (IGESGeom_CircularArc))) {
1744         DeclareAndCast (IGESGeom_CircularArc, circ, generatrix);
1745         gp_Pnt2d startpoint = circ->StartPoint();
1746         paramv -= ElCLib::Parameter (gp_Circ2d (gp_Ax2d (circ->Center(), gp_Dir2d(1,0)), circ->Radius()), startpoint);
1747         if (Surf->IsKind (STANDARD_TYPE(Geom_SphericalSurface)))
1748           paramv += ShapeAnalysis::AdjustToPeriod(paramv, - M_PI, M_PI);
1749         else if (Surf->IsKind (STANDARD_TYPE(Geom_ToroidalSurface)))
1750           paramv += ShapeAnalysis::AdjustToPeriod(paramv, 0, M_PI * 2);
1751       }
1752     }
1753     else if (st->IsKind (STANDARD_TYPE (IGESGeom_TabulatedCylinder))) {
1754       DeclareAndCast (IGESGeom_TabulatedCylinder, cylinder, st);
1755       Handle(IGESData_IGESEntity) directrix = cylinder->Directrix();
1756       if (directrix->IsKind (STANDARD_TYPE (IGESGeom_CircularArc))) {
1757         DeclareAndCast (IGESGeom_CircularArc, circ, directrix);
1758         gp_Pnt2d startpoint = circ->StartPoint();
1759         paramu -= ElCLib::Parameter (gp_Circ2d (gp_Ax2d (circ->Center(), gp_Dir2d(1,0)), circ->Radius()), startpoint);
1760         paramu += ShapeAnalysis::AdjustToPeriod(paramu, 0, M_PI * 2);
1761       }
1762     }
1763
1764   }
1765
1766   if ( Abs(paramu) <= Precision::Confusion()) paramu = 0.;
1767   if ( Abs(paramv) <= Precision::Confusion()) paramv = 0.;
1768   
1769   //S4181 pdn 16.04.99 computation of transformation depending on 
1770   //IGES Type of surface
1771   Handle(IGESData_IGESEntity) isrf = st;
1772   if (isrf->IsKind(STANDARD_TYPE(IGESGeom_OffsetSurface))){
1773     DeclareAndCast(IGESGeom_OffsetSurface, offsurf, isrf);
1774     isrf = offsurf->Surface();
1775   }
1776   if (isrf->IsKind(STANDARD_TYPE(IGESGeom_SurfaceOfRevolution))) {
1777     DeclareAndCast(IGESGeom_SurfaceOfRevolution, st120, isrf);
1778     //S4181 pdn 19.04.99 defining transformation matrix
1779     gp_Trsf2d tmp;
1780     tmp.SetTranslation(gp_Vec2d (0, -2 * M_PI));
1781     trans.PreMultiply(tmp);
1782     tmp.SetMirror(gp::OX2d());
1783     trans.PreMultiply(tmp);
1784     tmp.SetMirror(gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
1785     trans.PreMultiply(tmp);
1786     uscale = 1./cscale;
1787     //#30 rln 19.10.98
1788     //CAS.CADE SA = 2*PI - IGES TA
1789     //paramu = st120->StartAngle();
1790     paramu = -(2 * M_PI - st120->EndAngle());
1791   }
1792   else
1793     paramu = 0.;
1794   
1795   if (isrf->IsKind(STANDARD_TYPE(IGESGeom_RuledSurface))) {
1796     uscale = 1./cscale;
1797   }
1798   
1799   // corrected skl 13.11.2001 for BUC61054
1800   if (isrf->IsKind(STANDARD_TYPE(IGESGeom_TabulatedCylinder))) {
1801     Handle(IGESGeom_TabulatedCylinder) igtc = Handle(IGESGeom_TabulatedCylinder)::DownCast(isrf);
1802     Handle(IGESData_IGESEntity) idie = igtc->Directrix();
1803     Standard_Real uln=1;
1804     Standard_Real Umin,Umax,Vmin,Vmax;
1805     //scaling parameterization from [0,1]
1806     Surf->Bounds(Umin,Umax,Vmin,Vmax);
1807     uln = Abs(Umax-Umin);
1808     //computing shift of pcurves
1809     uscale = uln/cscale;
1810     paramu = Umin/uln;
1811   }
1812   
1813   if (isrf->IsKind(STANDARD_TYPE(IGESSolid_CylindricalSurface))||
1814       isrf->IsKind(STANDARD_TYPE(IGESSolid_ConicalSurface))) {
1815     uscale = M_PI/180.;
1816   }
1817   
1818   if (isrf->IsKind(STANDARD_TYPE(IGESSolid_SphericalSurface))) {
1819     cscale = M_PI/180.;
1820     uscale = 1.;
1821   }
1822       
1823   if (isrf->IsKind(STANDARD_TYPE(IGESSolid_ToroidalSurface))) {
1824     gp_Trsf2d tmp;
1825     tmp.SetTranslation(gp_Vec2d (0, -360.)); // in IGES terms
1826     trans.PreMultiply(tmp);
1827     tmp.SetMirror(gp::OX2d());
1828     trans.PreMultiply(tmp);
1829     tmp.SetMirror(gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
1830     trans.PreMultiply(tmp);
1831     if(paramv > 0)
1832       paramv = paramv*180./M_PI;
1833     cscale = M_PI/180.;
1834     uscale = 1.;
1835   } 
1836     
1837   gp_Trsf2d tmp;
1838   tmp.SetTranslation(gp_Pnt2d(0.,0.), gp_Pnt2d(paramu,paramv));
1839   trans.PreMultiply(tmp);
1840   
1841   tmp.SetScale(gp_Pnt2d(0,0),cscale);
1842   trans.PreMultiply(tmp);
1843   uFact = uscale;
1844   return face;
1845 }
1846