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