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