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