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