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