0026138: Problems with writing periodic BSplines into IGES
[occt.git] / src / GeomToIGES / GeomToIGES_GeomSurface.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 // modif du 22/10/96 mjm
15 // ajout du champ TheLength
16 //:l6 abv 15.01.99: CTS22022: writing full tori
17 //szv#4:S4163:12Mar99
18 //S4181 pdn 20.04.99 implementing of writing IGES elementary surfaces.
19 //szv#10:PRO19566:05Oct99 workaround against weights array loss
20
21 #include <GeomToIGES_GeomSurface.ixx>
22 #include <GeomToIGES_GeomCurve.hxx>
23 #include <GeomToIGES_GeomPoint.hxx>
24 #include <GeomToIGES_GeomVector.hxx>
25
26 #include <Geom_BSplineSurface.hxx>
27 #include <Geom_BezierSurface.hxx>
28 #include <Geom_BoundedSurface.hxx>
29 #include <Geom_CartesianPoint.hxx>
30 #include <Geom_ConicalSurface.hxx>
31 #include <Geom_Circle.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_CylindricalSurface.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Direction.hxx>
36 #include <Geom_Geometry.hxx>
37 #include <Geom_Line.hxx>
38 #include <Geom_OffsetSurface.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Geom_Point.hxx>
41 #include <Geom_RectangularTrimmedSurface.hxx>
42 #include <Geom_SphericalSurface.hxx>
43 #include <Geom_Surface.hxx>
44 #include <Geom_SurfaceOfLinearExtrusion.hxx>
45 #include <Geom_SurfaceOfRevolution.hxx>
46 #include <Geom_SweptSurface.hxx>
47 #include <Geom_ToroidalSurface.hxx>
48
49 #include <GeomConvert.hxx>
50
51 #include <GeomLProp_SLProps.hxx>
52
53 #include <IGESConvGeom_GeomBuilder.hxx>
54
55 #include <IGESData_IGESEntity.hxx>
56
57 #include <IGESGeom_BoundedSurface.hxx>
58 #include <IGESGeom_BSplineSurface.hxx>
59 #include <IGESGeom_CircularArc.hxx>
60 #include <IGESGeom_CurveOnSurface.hxx>
61 #include <IGESGeom_Direction.hxx>
62 #include <IGESGeom_Line.hxx>
63 #include <IGESGeom_OffsetSurface.hxx>
64 #include <IGESGeom_Plane.hxx>
65 #include <IGESGeom_Point.hxx>
66 #include <IGESGeom_RuledSurface.hxx>
67 #include <IGESGeom_SurfaceOfRevolution.hxx>
68 #include <IGESGeom_TabulatedCylinder.hxx>
69 #include <IGESGeom_TransformationMatrix.hxx>
70
71 #include <IGESSolid_PlaneSurface.hxx>
72 #include <Interface_Macros.hxx>
73 #include <Interface_Static.hxx>
74
75 #include <gce_MakeLin.hxx>
76
77 #include <gp.hxx>
78 #include <gp_Ax1.hxx>
79 #include <gp_Ax3.hxx>
80 #include <gp_Cone.hxx>
81 #include <gp_Cylinder.hxx>
82 #include <gp_Dir.hxx>
83 #include <gp_Pln.hxx>
84 #include <gp_Pnt.hxx>
85 #include <gp_Sphere.hxx>
86 #include <gp_Torus.hxx>
87 #include <gp_Trsf.hxx>
88 #include <gp_Vec.hxx>
89 #include <gp_XYZ.hxx>
90
91 #include <Precision.hxx>
92
93 #include <ShapeAnalysis.hxx>
94 #include <Standard_Failure.hxx>
95 #include <Standard_ErrorHandler.hxx>
96
97 #include <TColgp_HArray2OfXYZ.hxx>
98 #include <TColStd_HArray1OfReal.hxx>
99 #include <TColStd_HArray2OfReal.hxx>
100 #include <IGESSolid_CylindricalSurface.hxx>
101 #include <IGESSolid_ConicalSurface.hxx>
102 #include <IGESSolid_SphericalSurface.hxx>
103 #include <IGESSolid_ToroidalSurface.hxx>
104 #include <Geom_TrimmedCurve.hxx>
105
106
107 //=============================================================================
108 // GeomToIGES_GeomSurface
109 //=============================================================================
110
111 GeomToIGES_GeomSurface::GeomToIGES_GeomSurface()
112 :GeomToIGES_GeomEntity()
113 {
114   myBRepMode = Standard_False;
115   myAnalytic = Standard_False;
116 }
117
118
119 //=============================================================================
120 // GeomToIGES_GeomSurface
121 //=============================================================================
122
123 GeomToIGES_GeomSurface::GeomToIGES_GeomSurface(const GeomToIGES_GeomEntity& GE)
124      :GeomToIGES_GeomEntity(GE)
125 {
126   myBRepMode = Standard_False;
127   myAnalytic = Standard_False;
128 }
129
130
131 //=============================================================================
132 // Transfer des Entites Surface de Geom vers IGES
133 // TransferSurface
134 //=============================================================================
135
136 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_Surface)& start, 
137                                                                     const Standard_Real Udeb,
138                                                                     const Standard_Real Ufin, 
139                                                                     const Standard_Real Vdeb, 
140                                                                     const Standard_Real Vfin)
141 {
142   Handle(IGESData_IGESEntity) res;
143   if (start.IsNull()) {
144     return res;
145   }
146
147   if (start->IsKind(STANDARD_TYPE(Geom_BoundedSurface))) {
148     DeclareAndCast(Geom_BoundedSurface, Bounded, start);
149     res = TransferSurface(Bounded, Udeb, Ufin, Vdeb, Vfin);
150   }
151   else if (start->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) {
152     DeclareAndCast(Geom_ElementarySurface, Elementary, start);
153     res = TransferSurface(Elementary, Udeb, Ufin, Vdeb, Vfin);
154   }
155   else if ( start->IsKind(STANDARD_TYPE(Geom_SweptSurface))) {
156     DeclareAndCast(Geom_SweptSurface, Swept, start);
157     res = TransferSurface(Swept, Udeb, Ufin, Vdeb, Vfin);
158   }
159   else if ( start->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
160     DeclareAndCast(Geom_OffsetSurface, OffsetS, start);
161     res = TransferSurface(OffsetS, Udeb, Ufin, Vdeb, Vfin);
162   }
163   
164   return res;
165 }
166  
167
168 //=============================================================================
169 // Transfer des Entites BoundedSurface de Geom vers IGES
170 // TransferSurface
171 //=============================================================================
172
173 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_BoundedSurface)& start, 
174                                                                     const Standard_Real Udeb,
175                                                                     const Standard_Real Ufin,
176                                                                     const Standard_Real Vdeb, 
177                                                                     const Standard_Real Vfin)
178 {
179   Handle(IGESData_IGESEntity) res;
180   if (start.IsNull()) {
181     return res;
182   }
183
184   if (start->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
185     DeclareAndCast(Geom_BSplineSurface, BSpline, start);
186     res = TransferSurface(BSpline, Udeb, Ufin, Vdeb, Vfin);
187   }
188   else if (start->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
189     DeclareAndCast(Geom_BezierSurface, Bezier, start);
190     res = TransferSurface(Bezier, Udeb, Ufin, Vdeb, Vfin);
191   }
192   else if ( start->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
193     DeclareAndCast(Geom_RectangularTrimmedSurface, Trimmed, start);
194     res = TransferSurface(Trimmed,Udeb, Ufin, Vdeb, Vfin);
195   }
196
197   return res;
198 }
199
200
201 //=============================================================================
202 // Transfer des Entites BSplineSurface de Geom vers IGES
203 // TransferSurface
204 //=============================================================================
205
206 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_BSplineSurface)& start,
207                                                                     const Standard_Real Udeb,
208                                                                     const Standard_Real Ufin,
209                                                                     const Standard_Real Vdeb,
210                                                                     const Standard_Real Vfin)
211 {
212   //  a b-spline surface is defined by :
213   //         The U and V Degree (up to 25)
214   //         The Poles  (and the weights if it is rational)
215   //         The U and V Knots and Multiplicities
216   //         
217   //  The knot vector   is an  increasing  sequence  of reals without  repetition. 
218   //  The multiplicities are the repetition of the knots.
219   //           
220   //  If the knots are regularly spaced (the difference of two consecutive knots  
221   //  is a constant),
222   //  the knots repartition (in U or V) is :
223   //              - Uniform if all multiplicities are 1.
224   //              -  Quasi-uniform if  all multiplicities are  1
225   //              but the first and the last which are Degree+1.
226   //              -   PiecewiseBezier if  all multiplicites  are
227   //              Degree but the   first and the  last which are
228   //              Degree+1. 
229   //              
230   //         The surface may be periodic in U and in V. 
231   //              On a U periodic surface if there are k U knots
232   //              and the poles table  has p rows.  the U period
233   //              is uknot(k) - uknot(1)
234   //              
235   //              the poles and knots are infinite vectors with :
236   //                uknot(i+k) = uknot(i) + period
237   //                pole(i+p,j) = pole(i,j)
238
239
240   Handle(IGESData_IGESEntity) res;
241   TheLength = 1;
242   if (start.IsNull()) {
243     return res;
244   }
245
246   Handle(IGESGeom_BSplineSurface) BSpline = new IGESGeom_BSplineSurface;
247   Handle(Geom_BSplineSurface) mysurface;
248   
249   Standard_Boolean PeriodU = start->IsUPeriodic();
250   Standard_Boolean PeriodV = start->IsVPeriodic();
251   mysurface = Handle(Geom_BSplineSurface)::DownCast(start->Copy());
252
253   Standard_Real Umin = Udeb, Umax = Ufin, Vmin = Vdeb, Vmax = Vfin;
254   Standard_Real U0,U1,V0,V1;
255   Standard_Real uShift = 0, vShift = 0;
256   mysurface->Bounds(U0,U1,V0,V1);
257
258   // cut segment from periodic surfaces for syncronization of pcurves ranges
259   // and surface bounds (issue 26138)
260   if (!PeriodU) {
261     if (Umin < U0)
262       Umin = U0;
263     if (U1 < Umax)
264       Umax = U1;
265   }
266   else {
267     if (Abs(Umin - U0) < Precision::PConfusion())
268       Umin = U0;
269     if (Abs(Umax - U1) < Precision::PConfusion())
270       Umax = U1;
271     uShift = ShapeAnalysis::AdjustToPeriod(Umin, U0, U1);
272     Umin += uShift;
273     Umax += uShift;
274   }
275   if (!PeriodV) {
276     if (Vmin < V0)
277       Vmin = V0;
278     if (V1 < Vmax)
279       Vmax = V1;
280   }
281   else {
282     if (Abs(Vmin - V0) < Precision::PConfusion())
283       Vmin = V0;
284     if (Abs(Vmax - V1) < Precision::PConfusion())
285       Vmax = V1;
286     vShift = ShapeAnalysis::AdjustToPeriod(Vmin, V0, V1);
287     Vmin += vShift;
288     Vmax += vShift;
289   }
290   if ( Abs(uShift) > Precision::PConfusion() || Abs(vShift) > Precision::PConfusion()) {
291     Standard_Boolean isNeedSegment = Standard_True;
292     isNeedSegment = Abs(Umax-Umin) > Precision::PConfusion() && 
293                     Abs(Vmax-Vmin) > Precision::PConfusion();
294     Standard_Real uMaxShift = 0, vMaxShift = 0;
295     uMaxShift = ShapeAnalysis::AdjustToPeriod(Ufin, U0, U1);
296     vMaxShift = ShapeAnalysis::AdjustToPeriod(Vfin, V0, V1);
297     isNeedSegment &= 
298       (PeriodU && Abs(uShift - uMaxShift) > Precision::PConfusion()) ||
299       (PeriodV && Abs(vShift - vMaxShift) > Precision::PConfusion());           
300     if (isNeedSegment) {
301       try {
302         OCC_CATCH_SIGNALS
303         Handle(Geom_BSplineSurface) bspl = Handle(Geom_BSplineSurface)::DownCast ( start->Copy() );
304         if ( ! bspl.IsNull() ) {
305           bspl->CheckAndSegment(Umin, Umax, Vmin, Vmax);
306           if ((U1 - U0) - (Umax - Umin) > Precision::PConfusion())
307             PeriodU = Standard_False;
308           if ((V1 - V0) - (Vmax - Vmin) > Precision::PConfusion())
309             PeriodV = Standard_False;
310                 mysurface = bspl;
311         }
312       }
313       catch ( Standard_Failure ) {
314         #ifdef DEB
315         cout << "Warning: GeomToIGES_GeomSurface: can't trim bspline" << endl;
316         cout << "Warning: Exception in Segment(): " ;
317         Standard_Failure::Caught()->Print(cout);
318         #endif
319     }
320     }
321   }
322
323   //unperiodize surface to get neccessary for IGES standard number of knots and mults
324   if ( mysurface->IsUPeriodic() ) {
325     mysurface->SetUNotPeriodic();
326   }
327   if ( mysurface->IsVPeriodic() ) {
328     mysurface->SetVNotPeriodic();
329   }
330  
331   Standard_Integer DegU = mysurface->UDegree();
332   Standard_Integer DegV = mysurface->VDegree();
333   Standard_Boolean CloseU = mysurface->IsUClosed();
334   Standard_Boolean CloseV = mysurface->IsVClosed();
335   Standard_Boolean RationU = mysurface->IsURational();
336   Standard_Boolean RationV = mysurface->IsVRational();
337   Standard_Integer NbUPoles = mysurface->NbUPoles();
338   Standard_Integer NbVPoles = mysurface->NbVPoles();
339   Standard_Integer IndexU = NbUPoles -1;
340   Standard_Integer IndexV = NbVPoles -1;
341   Standard_Boolean Polynom = !(RationU || RationV); //szv#10:PRO19566:05Oct99 && was wrong
342
343   // filling knots array for U :
344   // Sequence des Knots de [-DegU, IndexU+1] dans IGESGeom.
345   Standard_Integer Knotindex;
346   Standard_Real rtampon;
347   Standard_Integer itampon;
348   TColStd_Array1OfReal KU(1, NbUPoles+ DegU+ 1);
349   mysurface->UKnotSequence(KU);
350   itampon = -DegU;
351   Handle(TColStd_HArray1OfReal) KnotsU = 
352     new TColStd_HArray1OfReal(-DegU,IndexU+1 );
353   for ( Knotindex=KU.Lower(); Knotindex<=KU.Upper(); Knotindex++) { 
354     rtampon = KU.Value(Knotindex);
355     KnotsU->SetValue(itampon, rtampon);
356     itampon++;
357   }
358
359   // filling knots array for V :
360   // Sequence des Knots de [-DegV, IndexV+1] dans IGESGeom.
361   TColStd_Array1OfReal KV(1, NbVPoles+ DegV+ 1);
362   mysurface->VKnotSequence(KV);
363   itampon = -DegV;
364   Handle(TColStd_HArray1OfReal) KnotsV = 
365     new TColStd_HArray1OfReal(-DegV, IndexV+1);
366   for ( Knotindex=KV.Lower(); Knotindex<=KV.Upper(); Knotindex++) { 
367     rtampon = KV.Value(Knotindex);
368     KnotsV->SetValue(itampon, rtampon);
369     itampon++;
370   }
371
372   // filling Weights array de [0, IndexU, 0, IndexV]
373   // ----------------------------------------------
374   Handle(TColStd_HArray2OfReal) Weights = 
375     new TColStd_HArray2OfReal(0 , IndexU, 0, IndexV);
376   Standard_Integer WeightRow = Weights->LowerRow();
377   Standard_Integer WeightCol = Weights->LowerCol();
378   Standard_Integer iw, jw;
379
380   if(RationU || RationV) {
381     for ( iw = 1; iw<= IndexU+1; iw++) {
382       for ( jw = 1; jw<= IndexV+1; jw++)
383         Weights->SetValue(WeightRow, WeightCol++, mysurface->Weight(iw,jw));
384       WeightRow++;
385       WeightCol = Weights->LowerCol();
386     }
387   } else {
388     for ( iw = 1; iw<= IndexU+1; iw++) {
389       for ( jw = 1; jw<= IndexV+1; jw++) 
390         Weights->SetValue(WeightRow, WeightCol++, 1.0);
391       WeightRow++;
392       WeightCol = Weights->LowerCol();
393     }
394
395   }
396       
397   // filling Poles array de [0, IndexU, 0, IndexV]
398   // ---------------------------------------------
399   Handle(TColgp_HArray2OfXYZ) Poles = 
400     new TColgp_HArray2OfXYZ(0, IndexU, 0, IndexV);
401   Standard_Integer UIndex = Poles->LowerRow();
402   Standard_Integer VIndex = Poles->LowerCol();
403   Standard_Integer ipole, jpole;
404   Standard_Real Xd, Yd, Zd;
405
406   for ( ipole = 1; ipole<= IndexU+1; ipole++) {
407     for ( jpole = 1; jpole<= IndexV+1; jpole++) {
408       gp_Pnt tempPnt = mysurface-> Pole(ipole, jpole);
409       tempPnt.Coord(Xd, Yd, Zd);
410       gp_XYZ PXYZ = gp_XYZ( Xd/GetUnit(), Yd/GetUnit(), Zd/GetUnit());
411       Poles->SetValue(UIndex, VIndex++, PXYZ);
412     }     
413     UIndex++;
414     VIndex = Poles->LowerCol();
415   }
416
417   BSpline-> Init (IndexU, IndexV, DegU, DegV, CloseU, CloseV, Polynom, PeriodU, 
418                   PeriodV, KnotsU, KnotsV, Weights, Poles, Umin, Umax, Vmin, Vmax);
419   res = BSpline;
420   return res;
421 }
422
423
424 //=============================================================================
425 // Transfer des Entites BezierSurface de Geom vers IGES
426 // TransferSurface
427 //=============================================================================
428
429 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_BezierSurface)& start,
430                                                                     const Standard_Real /*Udeb*/,
431                                                                     const Standard_Real /*Ufin*/,
432                                                                     const Standard_Real /*Vdeb*/,
433                                                                     const Standard_Real /*Vfin*/)
434 {
435   Handle(IGESData_IGESEntity) res;
436   if (start.IsNull()) {
437     return res;
438   }
439
440   Handle(Geom_BSplineSurface) Bspline = 
441     GeomConvert::SurfaceToBSplineSurface(start);
442   Standard_Real U1,U2,V1,V2;
443   Bspline->Bounds(U1,U2,V1,V2);
444   res = TransferSurface(Bspline, U1, U2, V1, V2);
445   return res;
446 }
447
448
449 //=============================================================================
450 // Transfer des Entites RectangularTrimmedSurface de Geom vers IGES
451 // TransferSurface
452 //=============================================================================
453
454 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_RectangularTrimmedSurface)& start,
455                                                                     const Standard_Real Udeb,
456                                                                     const Standard_Real Ufin,
457                                                                     const Standard_Real Vdeb,
458                                                                     const Standard_Real Vfin)
459 {
460   Handle(IGESData_IGESEntity) res;
461   if (start.IsNull()) {
462     return res;
463   }
464
465   Handle(Geom_Surface) st = start->BasisSurface();
466   if (st->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
467     //message d'erreur pas de trimmed a partir d'une trimmed , 
468     //on peut eventuellement ecrire la surface de base : st.
469     return res;
470   }
471
472   res = TransferSurface(st, Udeb, Ufin, Vdeb, Vfin);
473   return res;
474
475 }
476
477
478 //=============================================================================
479 // Transfer des Entites ElementarySurface de Geom vers IGES
480 // TransferSurface
481 //=============================================================================
482
483 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_ElementarySurface)& start, 
484                                                                     const Standard_Real Udeb,
485                                                                     const Standard_Real Ufin,
486                                                                     const Standard_Real Vdeb,
487                                                                     const Standard_Real Vfin)
488 {
489   Handle(IGESData_IGESEntity) res;
490   //  All these entities are located in 3D space with an axis
491   //  placement (Location point, XAxis, YAxis, ZAxis). It is 
492   //  their local coordinate system.
493
494   //S4181 pdn 16.04.99 Hereunder, the implementation of translation of CAS.CADE
495   // elementary surfaces into different types of IGES surfaces according to boolean flags
496   if (start.IsNull()) {
497     return res;
498   }
499   if (start->IsKind(STANDARD_TYPE(Geom_Plane))) {
500     DeclareAndCast(Geom_Plane, Plane, start);
501     if(myBRepMode)
502       res = TransferPlaneSurface(Plane, Udeb, Ufin, Vdeb, Vfin);
503     else
504       res = TransferSurface(Plane, Udeb, Ufin, Vdeb, Vfin);
505   }
506   else if (start->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
507     DeclareAndCast(Geom_CylindricalSurface, Cylindrical, start);
508     if(myBRepMode&&myAnalytic)
509       res = TransferCylindricalSurface(Cylindrical, Udeb, Ufin, Vdeb, Vfin);
510     else
511       res = TransferSurface(Cylindrical, Udeb, Ufin, Vdeb, Vfin);
512   }
513   else if ( start->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
514     DeclareAndCast(Geom_ConicalSurface, Conical, start);
515     if(myBRepMode&&myAnalytic)
516       res = TransferConicalSurface(Conical, Udeb, Ufin, Vdeb, Vfin);
517     else
518       res = TransferSurface(Conical, Udeb, Ufin, Vdeb, Vfin);
519   }
520   else if (start->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
521     DeclareAndCast(Geom_SphericalSurface, Spherical, start);
522     if(myBRepMode&&myAnalytic)
523       res = TransferSphericalSurface(Spherical, Udeb, Ufin, Vdeb, Vfin);
524     else
525       res = TransferSurface(Spherical, Udeb, Ufin, Vdeb, Vfin);
526   }
527   else if ( start->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
528     DeclareAndCast(Geom_ToroidalSurface, Toroidal, start);
529     if(myBRepMode&&myAnalytic)
530       res = TransferToroidalSurface(Toroidal, Udeb, Ufin, Vdeb, Vfin);
531        else
532          res = TransferSurface(Toroidal, Udeb, Ufin, Vdeb, Vfin);
533   }
534   
535   return res;
536
537 }
538
539
540 //=============================================================================
541 // Transfer des Entites Plane de Geom vers IGES
542 // TransferSurface
543 //=============================================================================
544
545 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle(Geom_Plane)& start,
546                                                                     const Standard_Real Udeb,
547                                                                     const Standard_Real Ufin,
548                                                                     const Standard_Real Vdeb,
549                                                                     const Standard_Real Vfin)
550 {
551   // on va ecrire une BSplineSurface pour pouvoir etre coherent avec les courbes 2d
552   Handle(IGESData_IGESEntity) res;
553   TheLength = 1;
554   if (start.IsNull()) {
555     return res;
556   }
557   if (Interface_Static::IVal("write.iges.plane.mode") == 0){
558     Handle(IGESGeom_Plane) aPlane = new IGESGeom_Plane;
559     Standard_Real A,B,C,D;
560     start->Coefficients(A,B,C,D);
561     D = -D;// because of difference in Geom_Plane class and Type 108
562     gp_XYZ anAttach = start->Location().XYZ().Divided( GetUnit() );
563     aPlane->Init (A, B, C, D / GetUnit(), 0, anAttach, 0);
564     res = aPlane;
565     return res;
566   }
567   else{
568     Handle(IGESGeom_BSplineSurface) BSpline = new IGESGeom_BSplineSurface;
569     gp_Pnt P1 ,P2, P3, P4;
570     start->D0(Udeb, Vdeb, P1);
571     start->D0(Udeb, Vfin, P2);
572     start->D0(Ufin, Vdeb, P3);
573     start->D0(Ufin, Vfin, P4);
574     Handle(TColgp_HArray2OfXYZ) Poles = new TColgp_HArray2OfXYZ(0, 1, 0, 1);
575     Standard_Real X,Y,Z;
576     P1.Coord(X,Y,Z);
577     Poles->SetValue (0, 0, gp_XYZ(X/GetUnit(),Y/GetUnit(),Z/GetUnit()));
578     P2.Coord(X,Y,Z);
579     Poles->SetValue (0, 1, gp_XYZ(X/GetUnit(),Y/GetUnit(),Z/GetUnit()));
580     P3.Coord(X,Y,Z);
581     Poles->SetValue (1, 0, gp_XYZ(X/GetUnit(),Y/GetUnit(),Z/GetUnit()));
582     P4.Coord(X,Y,Z);
583     Poles->SetValue (1, 1, gp_XYZ(X/GetUnit(),Y/GetUnit(),Z/GetUnit()));
584
585     Handle(TColStd_HArray1OfReal) KnotsU = new TColStd_HArray1OfReal(-1,2);
586     KnotsU->SetValue(-1, Udeb);
587     KnotsU->SetValue(0, Udeb);
588     KnotsU->SetValue(1, Ufin);
589     KnotsU->SetValue(2, Ufin);
590
591     Handle(TColStd_HArray1OfReal) KnotsV = new TColStd_HArray1OfReal(-1,2);
592     KnotsV->SetValue(-1, Vdeb);
593     KnotsV->SetValue(0, Vdeb);
594     KnotsV->SetValue(1, Vfin);
595     KnotsV->SetValue(2, Vfin);
596
597     Handle(TColStd_HArray2OfReal) Weights = 
598       new TColStd_HArray2OfReal(0, 1, 0, 1, 1.);
599
600     //#32 rln 19.10.98
601     BSpline-> Init ( 1, 1, 1, 1, Standard_False , Standard_False, Standard_True, 
602                     Standard_False, Standard_False,
603                     KnotsU, KnotsV, Weights, Poles, Udeb, Ufin, Vdeb, Vfin);
604     res = BSpline;
605     return res;
606   }
607
608 }
609
610
611 //=============================================================================
612 // Transfer des Entites CylindricalSurface de Geom vers IGES
613 // TransferSurface
614 //=============================================================================
615
616 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
617 ( const Handle(Geom_CylindricalSurface)& start, const Standard_Real Udeb, 
618  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
619 {
620   //  The "ZAxis" is the symmetry axis of the CylindricalSurface, 
621   //  it gives the direction of increasing parametric value V.
622   //  The parametrization range is :
623   //       U [0, 2*PI],  V ]- infinite, + infinite[
624   //  The "XAxis" and the "YAxis" define the placement plane of the 
625   //  surface (Z = 0, and parametric value V = 0)  perpendicular to 
626   //  the symmetry axis. The "XAxis" defines the origin of the 
627   //  parameter U = 0.  The trigonometric sense gives the positive 
628   //  orientation for the parameter U.
629
630   Handle(IGESData_IGESEntity) res;
631   TheLength = 1;
632   if (start.IsNull()) {
633     return res;
634   }
635
636   Handle(IGESGeom_SurfaceOfRevolution) Surf = new IGESGeom_SurfaceOfRevolution;
637   Standard_Real U1 = Udeb;
638   Standard_Real U2 = Ufin;
639   Standard_Real V1 = Vdeb;
640   Standard_Real V2 = Vfin;
641   if (Precision::IsNegativeInfinite(Vdeb)) V1 = -Precision::Infinite();
642   if (Precision::IsPositiveInfinite(Vfin)) V2 = Precision::Infinite();
643
644   // creation de la generatrice : Generatrix 
645   Handle(Geom_Line) Ligne = 
646     new Geom_Line (gp_Pnt(start->Cylinder().Radius(), 0.0, 0.0), 
647                    gp_Dir(0.0, 0.0, 1.0));
648   GeomToIGES_GeomCurve GC(*this);
649   Handle(IGESData_IGESEntity) Generatrix = GC.TransferCurve( Ligne, V1, V2);
650   gp_Pnt gen1 = Ligne->Value(V1);
651   gp_Pnt gen2 = Ligne->Value(V2);
652   TheLength = gen1.Distance(gen2);
653   
654
655   // creation de l`axe : Axis .
656   Handle(IGESGeom_Line) Axis = new IGESGeom_Line;
657   //#30 rln 19.10.98 IGES axis = reversed CAS.CADE axis
658   //Axis->Init(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(0.0, 0.0, 1.0/GetUnit()));
659   //Surf->Init (Axis, Generatrix, U1, U2);
660   Axis->Init(gp_XYZ (0, 0, 1.), gp_XYZ (0, 0, 0));  
661   Surf->Init (Axis, Generatrix, 2 * M_PI - U2, 2 * M_PI - U1);
662
663
664   // creation de la Trsf (#124)
665   // il faut tenir compte de l`unite pour la matrice de transformation
666   // (partie translation).
667   IGESConvGeom_GeomBuilder Build;
668   Standard_Real xloc,yloc,zloc;
669   start->Cylinder().Location().Coord(xloc,yloc,zloc);
670   gp_Pnt Loc;
671   Loc.SetCoord(xloc, yloc, zloc);
672   gp_Ax3 Pos = start->Cylinder().Position();
673   Pos.SetLocation(Loc);
674   Build.SetPosition(Pos);
675   if (!Build.IsIdentity()){
676     Handle(IGESGeom_TransformationMatrix) TMat = 
677       new IGESGeom_TransformationMatrix;
678     TMat = Build.MakeTransformation(GetUnit());
679     Surf->InitTransf(TMat);
680   }
681   res = Surf;
682   return res;
683
684 }
685
686
687 //=============================================================================
688 // Transfer des Entites ConicalSurface de Geom vers IGES
689 // TransferSurface
690 //=============================================================================
691
692 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
693 ( const Handle(Geom_ConicalSurface)& start, const Standard_Real Udeb, 
694  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
695 {
696   //  The "ZAxis" is the symmetry axis of the ConicalSurface, 
697   //  it gives the direction of increasing parametric value V.
698   //  The apex of the surface is on the negative side of this axis.
699   //  The parametrization range is  :
700   //     U [0, 2*PI],  V ]-infinite, + infinite[
701   //  The "XAxis" and the "YAxis" define the placement plane of the 
702   //  surface (Z = 0, and parametric value V = 0)  perpendicular to 
703   //  the symmetry axis. The "XAxis" defines the origin of the 
704   //  parameter U = 0.  The trigonometric sense gives the positive 
705   //  orientation for the parameter U.
706
707
708   Handle(IGESData_IGESEntity) res;
709   TheLength = 1;
710   if (start.IsNull()) {
711     return res;
712   }
713   Handle(IGESGeom_SurfaceOfRevolution) Surf = new IGESGeom_SurfaceOfRevolution;
714   Standard_Real U1 = Udeb;
715   Standard_Real U2 = Ufin;
716   Standard_Real V1 = Vdeb;
717   Standard_Real V2 = Vfin;
718   if (Precision::IsNegativeInfinite(Vdeb)) V1 = -Precision::Infinite();
719   if (Precision::IsPositiveInfinite(Vfin)) V2 = Precision::Infinite();
720
721   // creation de la generatrice : Generatrix
722   Handle(Geom_Line) Ligne = 
723     new Geom_Line( gp_Pnt(start->Cone().RefRadius(), 0.0, 0.0), 
724                    gp_Dir(sin(start->Cone().SemiAngle()), 0.,
725                           cos(start->Cone().SemiAngle())));
726   GeomToIGES_GeomCurve GC(*this);
727   Handle(IGESData_IGESEntity) Generatrix = GC.TransferCurve( Ligne, V1, V2);
728   gp_Pnt gen1 = Ligne->Value(V1);
729   gp_Pnt gen2 = Ligne->Value(V2);
730 //  TheLength = gen1.Distance(gen2)*Cos(start->Cone().SemiAngle());
731   TheLength = gen1.Distance(gen2);
732
733   // creation de l`axe : Axis .
734   Handle(IGESGeom_Line) Axis = new IGESGeom_Line;
735   //#30 rln 19.10.98 IGES axis = reversed CAS.CADE axis
736   //Axis->Init(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(0.0, 0.0, 1.0/GetUnit()));
737   //Surf->Init (Axis, Generatrix, U1, U2);
738   Axis->Init(gp_XYZ (0, 0, 1.), gp_XYZ (0, 0, 0));  
739   Surf->Init (Axis, Generatrix, 2 * M_PI - U2, 2 * M_PI - U1);
740
741
742   // creation de la Trsf (#124)
743   // il faut tenir compte de l`unite pour la matrice de transformation
744   // (partie translation).
745   IGESConvGeom_GeomBuilder Build;
746   Standard_Real xloc,yloc,zloc;
747   start->Cone().Location().Coord(xloc,yloc,zloc);
748   gp_Pnt Loc;
749   Loc.SetCoord(xloc, yloc, zloc);
750   gp_Ax3 Pos = start->Cone().Position();
751   Pos.SetLocation(Loc);
752   Build.SetPosition(Pos);
753   if (!Build.IsIdentity()){
754     Handle(IGESGeom_TransformationMatrix) TMat = 
755       new IGESGeom_TransformationMatrix;
756     TMat = Build.MakeTransformation(GetUnit());
757     Surf->InitTransf(TMat);
758   }
759   res = Surf;
760   return res;
761
762 }
763
764
765 //=============================================================================
766 // Transfer des Entites SphericalSurface de Geom vers IGES
767 // TransferSurface
768 //=============================================================================
769
770 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
771 ( const Handle(Geom_SphericalSurface)& start, const Standard_Real Udeb, 
772  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
773 {
774   //  The center of the sphere is the "Location" point of the local
775   //  coordinate system.
776   //  The V isoparametric curves of the surface  are defined by 
777   //  the section of the spherical surface with plane parallel to the
778   //  plane (Location, XAxis, YAxis). This plane defines the origin of
779   //  parametrization V.
780   //  The U isoparametric curves of the surface are defined by the 
781   //  section of the spherical surface with plane obtained by rotation
782   //  of the plane (Location, XAxis, ZAxis) around ZAxis. This plane
783   //  defines the origin of parametrization u.
784   //  The parametrization range is  U [0, 2*PI],  V [- PI/2, + PI/2]
785
786   Handle(IGESData_IGESEntity) res;
787   TheLength = 1;
788   if (start.IsNull()) {
789     return res;
790   }
791
792   Handle(IGESGeom_SurfaceOfRevolution) Surf = new IGESGeom_SurfaceOfRevolution;
793
794   Standard_Real U1 = Udeb;
795   Standard_Real U2 = Ufin;
796   Standard_Real V1 = Vdeb;
797   Standard_Real V2 = Vfin;
798
799   // creation de la generatrice : Generatrix (1/2 cercle)
800   gp_Ax2 Axe(gp::Origin(), -gp::DY(), gp::DX());
801   Handle(Geom_Circle) Cercle = 
802     new Geom_Circle(Axe, start->Sphere().Radius());
803   GeomToIGES_GeomCurve GC(*this);
804   Handle(IGESData_IGESEntity) Gen = GC.TransferCurve( Cercle, V1, V2);
805
806   // creation de l`axe : Axis .
807   Handle(IGESGeom_Line) Axis = new IGESGeom_Line;
808   //#30 rln 19.10.98 IGES axis = reversed CAS.CADE axis
809   //Axis->Init(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(0.0, 0.0, 1.0/GetUnit()));
810   Axis->Init(gp_XYZ (0, 0, 1.), gp_XYZ (0, 0, 0));  
811
812   if ( Gen->IsKind(STANDARD_TYPE(IGESGeom_CircularArc))) {
813     //#30 rln 19.10.98 Surf->Init (Axis, Gen, U1, U2);
814     Surf->Init (Axis, Gen, 2 * M_PI - U2, 2 * M_PI - U1);
815     IGESConvGeom_GeomBuilder Build;
816     Standard_Real xloc,yloc,zloc;
817     start->Sphere().Location().Coord(xloc,yloc,zloc);
818     gp_Pnt Loc;
819     Loc.SetCoord(xloc, yloc, zloc);
820     gp_Ax3 Pos = start->Sphere().Position();
821     Pos.SetLocation(Loc);
822     Build.SetPosition(Pos);
823     if (!Build.IsIdentity()){    
824       Handle(IGESGeom_TransformationMatrix) TMat = 
825         new IGESGeom_TransformationMatrix;
826       TMat = Build.MakeTransformation(GetUnit());
827       Surf->InitTransf(TMat);
828     }
829   }
830   res = Surf;
831   return res;
832 }
833
834
835 //=============================================================================
836 // Transfer des Entites ToroidalSurface de Geom vers IGES
837 // TransferSurface
838 //=============================================================================
839
840 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
841 ( const Handle(Geom_ToroidalSurface)& start, const Standard_Real Udeb, 
842  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
843 {
844   //  The "Location point" of the axis placement is the center 
845   //  of the surface.
846   //  The plane (Location, XAxis, ZAxis) defines the origin of the
847   //  parametrization U. The plane (Location, XAxis, YAxis)
848   //  defines the origin of the parametrization V.
849   //  The parametrization range is  U [0, 2*PI],  V [0, 2*PI]
850
851
852   Handle(IGESData_IGESEntity) res;
853   TheLength = 1;
854   if (start.IsNull()) {
855     return res;
856   }
857
858   Handle(IGESGeom_SurfaceOfRevolution) Surf = new IGESGeom_SurfaceOfRevolution;
859   Standard_Real U1 = Udeb;
860   Standard_Real U2 = Ufin;
861   Standard_Real V1 = Vdeb;
862   Standard_Real V2 = Vfin;
863
864   // creation de la generatrice : Generatrix (cercle)
865   gp_Ax2 Axe = gp_Ax2(gp_Pnt((start->Torus().MajorRadius()), 0., 0.),
866                       -gp::DY(), gp::DX());
867   Handle(Geom_Circle) Cercle = 
868     new Geom_Circle(Axe, start->Torus().MinorRadius());
869   GeomToIGES_GeomCurve GC(*this);
870   Handle(IGESData_IGESEntity) Gen = GC.TransferCurve( Cercle, V1, V2);
871   
872   // creation de l`axe : Axis .
873   Handle(IGESGeom_Line) Axis = new IGESGeom_Line;
874   //#30 rln 19.10.98 IGES axis = reversed CAS.CADE axis
875   //Axis->Init(gp_XYZ(0.0, 0.0, 0.0), gp_XYZ(0.0, 0.0, 1.0/GetUnit()));
876   Axis->Init(gp_XYZ (0, 0, 1.), gp_XYZ (0, 0, 0));  
877
878 //:l6 abv: CTS22022: writing full tori:  if ( Gen->IsKind(STANDARD_TYPE(IGESGeom_CircularArc))) {
879     //#30 rln 19.10.98 Surf->Init (Axis, Gen, U1, U2);
880     Surf->Init (Axis, Gen, 2 * M_PI - U2, 2 * M_PI - U1);
881     IGESConvGeom_GeomBuilder Build;
882 /* //:l6: useless
883     Standard_Real xloc,yloc,zloc;
884     start->Torus().Location().Coord(xloc,yloc,zloc);
885     gp_Pnt Loc;
886     Loc.SetCoord(xloc, yloc, zloc);
887 */
888     gp_Ax3 Pos = start->Torus().Position();
889 //:l6    Pos.SetLocation(Loc);
890     Build.SetPosition(Pos);
891     if (!Build.IsIdentity()){
892       Handle(IGESGeom_TransformationMatrix) TMat = 
893         new IGESGeom_TransformationMatrix;
894       TMat = Build.MakeTransformation(GetUnit());
895       Surf->InitTransf(TMat);
896     }
897 //:l6  }
898   res = Surf;
899   return res;
900
901 }
902
903 //=============================================================================
904 // Transfer des Entites SweptSurface de Geom vers IGES
905 // TransferSurface
906 //=============================================================================
907
908 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
909 ( const Handle(Geom_SweptSurface)& start, const Standard_Real Udeb, 
910  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
911 {
912   Handle(IGESData_IGESEntity) res;
913   if (start.IsNull()) {
914     return res;
915   }
916
917   if (start->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
918     DeclareAndCast(Geom_SurfaceOfLinearExtrusion, Extrusion, start);
919     res = TransferSurface(Extrusion, Udeb, Ufin, Vdeb, Vfin);
920   }
921   else if (start->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
922     DeclareAndCast(Geom_SurfaceOfRevolution, Revolution, start);
923     res = TransferSurface(Revolution, Udeb, Ufin, Vdeb, Vfin);
924   }
925
926   return res;
927
928 }
929
930 //=============================================================================
931 // Transfer des Entites SurfaceOfLinearExtrusion de Geom vers IGES
932 // TransferSurface
933 //=============================================================================
934
935 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
936 ( const Handle(Geom_SurfaceOfLinearExtrusion)& start, const Standard_Real Udeb, 
937  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
938 {
939   //  This surface is obtained by sweeping a curve in a given direction.
940   //  The parametrization range for the parameter U is defined with the
941   //  referenced curve.
942   //  The parametrization range for the parameter V is 
943   //  ]-infinite, + infinite[
944   //  The position of the curve gives the origin for the parameter V.
945
946
947   Handle(IGESData_IGESEntity) res;
948   TheLength = 1;
949   if (start.IsNull()) {
950     return res;
951   }
952
953   Handle(IGESGeom_TabulatedCylinder) Surf = new IGESGeom_TabulatedCylinder;
954   Standard_Real U1 = Udeb;
955   Standard_Real U2 = Ufin;
956   Standard_Real V1 = Vdeb;
957   Standard_Real V2 = Vfin;
958   if (Precision::IsNegativeInfinite(Vdeb)) V1 = -Precision::Infinite();
959   if (Precision::IsPositiveInfinite(Vfin)) V2 = Precision::Infinite();
960
961   // added by skl 18.07.2005 for OCC9490
962   Standard_Real UF,UL,VF,VL;
963   start->Bounds(UF,UL,VF,VL);
964   U1=UF;
965   U2=UL;
966
967   Handle(Geom_Curve) TheCurve = start->BasisCurve();
968
969   //dans IGES l'origine de la generatrice est identique a l'origine 
970   //de la directrice , il faut translater la courbe si les deux 
971   //points ne sont pas confondus dans Geom et donc la copier !!!!!!!
972   gp_Pnt TheEnd = start->Value(U1,V2);
973   Standard_Real Xe, Ye, Ze;
974   TheEnd.Coord(Xe, Ye, Ze);
975   gp_XYZ End = gp_XYZ (Xe/GetUnit(), Ye/GetUnit(), Ze/GetUnit());
976
977   GeomToIGES_GeomCurve GC(*this);
978 // commented by skl 18.07.2005 for OCC9490
979   Handle(Geom_Curve) CopyCurve;
980   if ( Abs(V1) > Precision::Confusion()) {
981    CopyCurve = Handle(Geom_Curve)::DownCast
982      (TheCurve->Translated (start->Value(U1,0.), start->Value(U1,V1)));
983   }
984   else {
985     CopyCurve = TheCurve;
986   }
987   //Handle(IGESData_IGESEntity) Directrix = GC.TransferCurve( CopyCurve, V1, V2);
988   Handle(IGESData_IGESEntity) Directrix = GC.TransferCurve( CopyCurve, U1, U2);
989   //Handle(IGESData_IGESEntity) Directrix = GC.TransferCurve( TheCurve, U1, U2);
990   //gp_Pnt gen1 = start->Value(U1,V1);
991   //TheLength = gen1.Distance(TheEnd);
992
993   Surf->Init (Directrix, End);
994   res = Surf;
995   return res;
996
997 }
998
999 //=============================================================================
1000 // Transfer des Entites SurfaceOfRevolution de Geom vers IGES
1001 // TransferSurface
1002 //=============================================================================
1003
1004 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
1005 ( const Handle(Geom_SurfaceOfRevolution)& start, const Standard_Real Udeb, 
1006  const Standard_Real Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
1007 {
1008   //  The surface is obtained by rotating a curve a complete revolution
1009   //  about an axis. The curve and the axis must be in the same plane.
1010   //  For a complete surface of revolution the parametric range is
1011   //  0 <= U <= 2*PI.
1012   //  The parametric range for V is defined with the revolved curve.
1013   //  The origin of the U parametrization is given by the position
1014   //  of the revolved curve (reference). The direction of the revolution
1015   //  axis defines the positive sense of rotation (trigonometric sense)
1016   //  corresponding to the increasing of the parametric value U.
1017   //  The derivatives are always defined for the u direction.
1018   //  For the v direction the definition of the derivatives depends on
1019   //  the degree of continuity of the referenced curve.
1020
1021   Handle(IGESData_IGESEntity) res;
1022   TheLength = 1;
1023   if (start.IsNull()) {
1024     return res;
1025   }
1026
1027   Handle(IGESGeom_SurfaceOfRevolution) Surf = new IGESGeom_SurfaceOfRevolution;
1028   Standard_Real U1 = Udeb;
1029   Standard_Real U2 = Ufin;
1030   Standard_Real V1 = Vdeb;
1031   Standard_Real V2 = Vfin;
1032   if (Precision::IsNegativeInfinite(Vdeb)) V1 = -Precision::Infinite();
1033   if (Precision::IsPositiveInfinite(Vfin)) V2 = Precision::Infinite();
1034
1035   // creation de la generatrice : Generatrix 
1036   Handle(Geom_Curve) Curve = start->BasisCurve();
1037   GeomToIGES_GeomCurve GC(*this);
1038   Handle(IGESData_IGESEntity) Generatrix = GC.TransferCurve( Curve, V1, V2);
1039   //pdn BUC184: decoding a trimmed curve
1040   while( Curve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
1041     Handle(Geom_TrimmedCurve) aTrCurve = Handle(Geom_TrimmedCurve)::
1042       DownCast(Curve);
1043     Curve = aTrCurve->BasisCurve();
1044   }
1045   
1046   if ( Curve->IsKind(STANDARD_TYPE(Geom_Line))) {
1047     DeclareAndCast(Geom_Line, Line, Curve);
1048     gp_Pnt gen1 = Line->Value(V1);
1049     gp_Pnt gen2 = Line->Value(V2);
1050     TheLength = gen1.Distance(gen2);
1051   }
1052
1053   // creation de l`axe : Axis .
1054   Handle(IGESGeom_Line) Axis = new IGESGeom_Line;
1055   gp_Ax1 Axe = start->Axis();
1056   Standard_Real X1,Y1,Z1,X2,Y2,Z2;
1057   Axe.Location().Coord(X1,Y1,Z1);
1058   Axe.Direction().Coord(X2,Y2,Z2);
1059
1060   //#30 rln 19.10.98 IGES axis = reversed CAS.CADE axis
1061   //Axis->Init(gp_XYZ(X1/GetUnit(),Y1/GetUnit(),Z1/GetUnit()),
1062   //         gp_XYZ(X2/GetUnit(),Y2/GetUnit(),Z2/GetUnit()));
1063   //#36 rln 27.10.98 BUC60328 face 7
1064   Axis->Init(gp_XYZ(X1/GetUnit(),Y1/GetUnit(),Z1/GetUnit()),
1065              gp_XYZ( (X1 - X2) / GetUnit(), (Y1 - Y2) / GetUnit(), (Z1 - Z2) / GetUnit()));
1066
1067   Surf->Init (Axis, Generatrix, 2 * M_PI - U2, 2 * M_PI - U1);
1068   res = Surf;
1069   return res;
1070
1071 }
1072
1073
1074 //=============================================================================
1075 // Transfer des Entites OffsetSurface de Geom vers IGES
1076 // TransferSurface
1077 //=============================================================================
1078
1079 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface
1080 ( const Handle(Geom_OffsetSurface)& start, const Standard_Real Udeb, const Standard_Real 
1081  Ufin, const Standard_Real Vdeb, const Standard_Real Vfin)
1082 {
1083   //  An offset surface is a surface at constant distance
1084   //  (Offset) from a basis surface. The distance may be positive
1085   //  or negative to the preferred side of the surface.
1086   //  The positive side is defined by the cross product D1u ^ D1v
1087   //  where D1u and D1v are the tangent vectors of the basis
1088   //  surface in the U and V parametric directions. The previous 
1089   //  cross product defines the normal direction to the basis
1090   //  surface.
1091
1092   Handle(IGESData_IGESEntity) res;
1093   if (start.IsNull()) {
1094     return res;
1095   }
1096
1097   Handle(IGESGeom_OffsetSurface) Surf = new IGESGeom_OffsetSurface;
1098   Handle(Geom_Surface) TheSurf = start->BasisSurface();
1099   Standard_Real U1, U2, V1, V2 , Um, Vm;
1100   start->Bounds (U1, U2, V1, V2);
1101   Um = (U1 + U2 ) /2.;
1102   Vm = (V1 + V2 ) /2.;
1103   Handle(IGESData_IGESEntity) Surface = TransferSurface
1104     (TheSurf, Udeb, Ufin, Vdeb, Vfin);
1105   Standard_Real Distance = start->Offset()/GetUnit();
1106   GeomLProp_SLProps Prop = GeomLProp_SLProps 
1107     (TheSurf, Um, Vm, 1, Precision::Confusion());
1108   gp_Dir Dir = Prop.Normal();
1109   Standard_Real Xd, Yd, Zd;
1110   Dir.Coord(Xd, Yd, Zd);
1111   gp_XYZ Indicator = gp_XYZ(Xd/GetUnit(), Yd/GetUnit(), Zd/GetUnit());
1112
1113   Surf-> Init (Indicator, Distance, Surface);
1114   res = Surf;
1115   return res;
1116
1117 }
1118
1119
1120 //=============================================================================
1121 // Transfer des Entites Plane de Geom vers IGESSolid
1122 // TransferPlaneSurface
1123 //=============================================================================
1124
1125 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferPlaneSurface(const Handle(Geom_Plane)& start,
1126                                                                          const Standard_Real /*Udeb*/,
1127                                                                          const Standard_Real /*Ufin*/,
1128                                                                          const Standard_Real /*Vdeb*/,
1129                                                                          const Standard_Real /*Vfin*/)
1130 {
1131   //  The parametrization range is  U, V  ]- infinite, + infinite[
1132   //  The local coordinate system of the plane is defined with
1133   //  an axis placement two axis.
1134
1135   Handle(IGESData_IGESEntity) res;
1136   TheLength = 1;
1137   if (start.IsNull()) {
1138     return res;
1139   }
1140
1141   Handle(IGESSolid_PlaneSurface) Plsurf = new IGESSolid_PlaneSurface;
1142   GeomToIGES_GeomPoint GP(*this);
1143
1144   gp_Pln aPln = start->Pln();
1145
1146   Handle(Geom_CartesianPoint) mypoint = new Geom_CartesianPoint (aPln.Location()); 
1147   Handle(IGESGeom_Point) aLocation = GP.TransferPoint(mypoint);
1148
1149   Handle(IGESGeom_Direction) aNormal = new IGESGeom_Direction;
1150   aNormal->Init (aPln.Axis().Direction().XYZ());
1151
1152   Handle(IGESGeom_Direction) aRefDir = new IGESGeom_Direction;
1153   aRefDir->Init (aPln.XAxis().Direction().XYZ());
1154
1155   Plsurf->Init (aLocation, aNormal, aRefDir);
1156   res = Plsurf;
1157   return res;
1158
1159 }
1160
1161 //=======================================================================
1162 //function : TransferCylindricaSurface
1163 //purpose  : 
1164 //=======================================================================
1165
1166 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferCylindricalSurface(const Handle(Geom_CylindricalSurface)& start,
1167                                                                                const Standard_Real /*Udeb*/,
1168                                                                                const Standard_Real /*Ufin*/,
1169                                                                                const Standard_Real /*Vdeb*/,
1170                                                                                const Standard_Real /*Vfin*/)
1171 {
1172
1173   Handle(IGESData_IGESEntity) res;
1174   TheLength = 1;
1175   if (start.IsNull()) {
1176     return res;
1177   }
1178
1179   Handle(IGESSolid_CylindricalSurface) CylSurf = new IGESSolid_CylindricalSurface;
1180   GeomToIGES_GeomPoint GP(*this);
1181
1182   gp_Cylinder aCyl = start->Cylinder();
1183
1184   Handle(Geom_CartesianPoint) mypoint = new Geom_CartesianPoint (aCyl.Location()); 
1185   Handle(IGESGeom_Point) aLocation = GP.TransferPoint(mypoint);
1186
1187   Handle(IGESGeom_Direction) anAxis = new IGESGeom_Direction;
1188   anAxis->Init (aCyl.Axis().Direction().XYZ());
1189
1190   Handle(IGESGeom_Direction) aRefDir = new IGESGeom_Direction;
1191   aRefDir->Init (aCyl.XAxis().Direction().XYZ());
1192
1193   Standard_Real aRadius = aCyl.Radius() / GetUnit();
1194
1195   CylSurf->Init (aLocation, anAxis, aRadius, aRefDir);
1196   res = CylSurf;
1197   return res;
1198 }
1199
1200
1201 //=======================================================================
1202 //function : TransferConicalSurface
1203 //purpose  : 
1204 //=======================================================================
1205
1206 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferConicalSurface(const Handle(Geom_ConicalSurface)& start,
1207                                                                            const Standard_Real /*Udeb*/,
1208                                                                            const Standard_Real /*Ufin*/,
1209                                                                            const Standard_Real /*Vdeb*/,
1210                                                                            const Standard_Real /*Vfin*/)
1211 {
1212
1213   Handle(IGESData_IGESEntity) res;
1214   TheLength = 1;
1215   if (start.IsNull()) {
1216     return res;
1217   }
1218
1219   Handle(IGESSolid_ConicalSurface) ConSurf = new IGESSolid_ConicalSurface;
1220   GeomToIGES_GeomPoint GP(*this);
1221
1222   gp_Cone Con = start->Cone();
1223   Standard_Real aRadius = Con.RefRadius() / GetUnit();
1224   Standard_Real angle  = Con.SemiAngle();
1225   gp_Ax1 Axe = Con.Axis();
1226   gp_Ax1 XAxe = Con.XAxis();
1227   gp_Dir XDir = XAxe.Direction();
1228
1229   Handle(Geom_CartesianPoint) mypoint = new Geom_CartesianPoint(Con.Location());
1230   if(angle < 0.) {
1231     gp_Pnt pnt = mypoint->Pnt();
1232     mypoint->SetPnt(Con.Apex().XYZ()*2-pnt.XYZ());
1233     angle = -angle;
1234     XDir.Reverse();
1235   }
1236   Handle(IGESGeom_Point) aLocation = GP.TransferPoint(mypoint);
1237
1238   Handle(IGESGeom_Direction) anAxis = new IGESGeom_Direction;
1239   anAxis->Init (Axe.Direction().XYZ());
1240
1241   Handle(IGESGeom_Direction) aRefDir = new IGESGeom_Direction;
1242   aRefDir->Init (XDir.XYZ());
1243
1244   ConSurf->Init (aLocation, anAxis, aRadius, angle*180./M_PI, aRefDir);
1245   res = ConSurf;
1246   return res;
1247 }
1248
1249
1250 //=======================================================================
1251 //function : TransferSphericalSurface
1252 //purpose  : 
1253 //=======================================================================
1254
1255 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSphericalSurface(const Handle(Geom_SphericalSurface)& start,
1256                                                                              const Standard_Real /*Udeb*/,
1257                                                                              const Standard_Real /*Ufin*/,
1258                                                                              const Standard_Real /*Vdeb*/,
1259                                                                              const Standard_Real /*Vfin*/)
1260 {
1261
1262   Handle(IGESData_IGESEntity) res;
1263   TheLength = 1;
1264   if (start.IsNull()) {
1265     return res;
1266   }
1267
1268   Handle(IGESSolid_SphericalSurface) SphSurf = new IGESSolid_SphericalSurface;
1269   GeomToIGES_GeomPoint GP(*this);
1270
1271   gp_Sphere aSph = start->Sphere();
1272
1273   Handle(Geom_CartesianPoint) mypoint = new Geom_CartesianPoint(aSph.Location()); 
1274   Handle(IGESGeom_Point) aLocation = GP.TransferPoint(mypoint);
1275
1276   Handle(IGESGeom_Direction) anAxis = new IGESGeom_Direction;
1277   anAxis->Init (aSph.Position().Axis().Direction().XYZ());
1278
1279   Handle(IGESGeom_Direction) aRefDir = new IGESGeom_Direction;
1280   aRefDir->Init (aSph.XAxis().Direction().XYZ());
1281
1282   Standard_Real aRadius = aSph.Radius() / GetUnit();
1283   
1284   SphSurf->Init (aLocation, aRadius, anAxis, aRefDir);
1285   res = SphSurf;
1286   return res;
1287 }
1288
1289 Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferToroidalSurface(const Handle(Geom_ToroidalSurface)& start,
1290                                                                             const Standard_Real /*Udeb*/,
1291                                                                             const Standard_Real /*Ufin*/,
1292                                                                             const Standard_Real /*Vdeb*/,
1293                                                                             const Standard_Real /*Vfin*/)
1294 {
1295
1296   Handle(IGESData_IGESEntity) res;
1297   TheLength = 1;
1298   if (start.IsNull()) {
1299     return res;
1300   }
1301
1302   Handle(IGESSolid_ToroidalSurface) TorSurf = new IGESSolid_ToroidalSurface;
1303   GeomToIGES_GeomPoint GP(*this);
1304
1305   gp_Torus aTor = start->Torus();
1306
1307   Handle(Geom_CartesianPoint) mypoint = new Geom_CartesianPoint (aTor.Location()); 
1308   Handle(IGESGeom_Point) aLocation = GP.TransferPoint(mypoint);
1309
1310   Handle(IGESGeom_Direction) anAxis = new IGESGeom_Direction;
1311   anAxis->Init (aTor.Axis().Direction().XYZ());
1312
1313   Handle(IGESGeom_Direction) aRefDir = new IGESGeom_Direction;
1314   aRefDir->Init (aTor.XAxis().Direction().XYZ());
1315
1316   Standard_Real aMajor = aTor.MajorRadius() / GetUnit();
1317   Standard_Real aMinor = aTor.MinorRadius() / GetUnit();
1318   
1319   TorSurf->Init (aLocation, anAxis, aMajor, aMinor, aRefDir);
1320   res = TorSurf;
1321   return res;
1322 }
1323
1324
1325 //=======================================================================
1326 //function : Length
1327 //purpose  : 
1328 //=======================================================================
1329 Standard_Real GeomToIGES_GeomSurface::Length() const
1330 {  return TheLength;  }
1331
1332 //=======================================================================
1333 //function : GetBRepMode
1334 //purpose  : 
1335 //=======================================================================
1336
1337 Standard_Boolean GeomToIGES_GeomSurface::GetBRepMode() const
1338 {
1339   return myBRepMode;
1340 }
1341
1342 //=======================================================================
1343 //function : SetBRepMode
1344 //purpose  : 
1345 //=======================================================================
1346
1347 void GeomToIGES_GeomSurface::SetBRepMode(const Standard_Boolean flag)
1348 {
1349   myBRepMode = flag;
1350 }
1351
1352 //=======================================================================
1353 //function : GetAnalyticMode
1354 //purpose  : 
1355 //=======================================================================
1356
1357 Standard_Boolean GeomToIGES_GeomSurface::GetAnalyticMode() const
1358 {
1359   return myAnalytic;
1360 }
1361
1362 void GeomToIGES_GeomSurface::SetAnalyticMode(const Standard_Boolean flag)
1363 {
1364   myAnalytic = flag;
1365 }
1366