0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / GeomConvert / GeomConvert_1.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //Jean-Claude Vauthier Novembre 1991
16 //Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline
17 //Modif JCV correction bug le 02/08/1993
18
19 #include <BSplCLib.hxx>
20 #include <Convert_ConeToBSplineSurface.hxx>
21 #include <Convert_CylinderToBSplineSurface.hxx>
22 #include <Convert_ElementarySurfaceToBSplineSurface.hxx>
23 #include <Convert_SphereToBSplineSurface.hxx>
24 #include <Convert_TorusToBSplineSurface.hxx>
25 #include <Geom_BezierSurface.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #include <Geom_BSplineSurface.hxx>
28 #include <Geom_ConicalSurface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_Geometry.hxx>
32 #include <Geom_OffsetSurface.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35 #include <Geom_SphericalSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_SurfaceOfLinearExtrusion.hxx>
38 #include <Geom_SurfaceOfRevolution.hxx>
39 #include <Geom_ToroidalSurface.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <GeomAdaptor_Surface.hxx>
42 #include <GeomConvert.hxx>
43 #include <GeomConvert_ApproxSurface.hxx>
44 #include <gp_Cone.hxx>
45 #include <gp_Cylinder.hxx>
46 #include <gp_GTrsf.hxx>
47 #include <gp_Pln.hxx>
48 #include <gp_Sphere.hxx>
49 #include <gp_Torus.hxx>
50 #include <gp_Trsf.hxx>
51 #include <gp_Vec.hxx>
52 #include <Precision.hxx>
53 #include <Standard_DomainError.hxx>
54 #include <Standard_NotImplemented.hxx>
55 #include <TColgp_Array1OfPnt.hxx>
56 #include <TColgp_Array2OfPnt.hxx>
57 #include <TColStd_Array1OfInteger.hxx>
58 #include <TColStd_Array1OfReal.hxx>
59 #include <TColStd_Array2OfInteger.hxx>
60 #include <TColStd_Array2OfReal.hxx>
61 #include <TColStd_HArray1OfInteger.hxx>
62 #include <TColStd_HArray1OfReal.hxx>
63
64 typedef Geom_Surface                          Surface;
65 typedef Geom_BSplineSurface                   BSplineSurface;
66 typedef TColStd_Array1OfReal                 Array1OfReal;
67 typedef TColStd_Array2OfReal                 Array2OfReal;
68 typedef TColStd_Array1OfInteger              Array1OfInteger;
69 typedef TColStd_Array2OfInteger              Array2OfInteger;
70 typedef TColgp_Array2OfPnt                          Array2OfPnt;
71 typedef TColgp_Array1OfPnt                          Array1OfPnt;
72 typedef gp_Pnt Pnt;
73
74 //=======================================================================
75 //function : BSplineSurfaceBuilder
76 //purpose  : 
77 //=======================================================================
78
79 Handle(Geom_BSplineSurface) BSplineSurfaceBuilder 
80   (const Convert_ElementarySurfaceToBSplineSurface& Convert) 
81 {
82   Handle(Geom_BSplineSurface) TheSurface;
83   Standard_Integer UDegree  = Convert.UDegree ();
84   Standard_Integer VDegree  = Convert.VDegree ();
85   Standard_Integer NbUPoles = Convert.NbUPoles();
86   Standard_Integer NbVPoles = Convert.NbVPoles();
87   Standard_Integer NbUKnots = Convert.NbUKnots();
88   Standard_Integer NbVKnots = Convert.NbVKnots();
89   Array2OfPnt     Poles   (1, NbUPoles, 1, NbVPoles);
90   Array2OfReal    Weights (1, NbUPoles, 1, NbVPoles);
91   Array1OfReal    UKnots  (1, NbUKnots);
92   Array1OfReal    VKnots  (1, NbVKnots);
93   Array1OfInteger UMults  (1, NbUKnots);
94   Array1OfInteger VMults  (1, NbVKnots);
95   Standard_Integer i, j;
96   for (j = 1; j <= NbVPoles; j++) {
97     for (i = 1; i <= NbUPoles; i++) {
98       Poles   (i, j) = Convert.Pole   (i, j);
99       Weights (i, j) = Convert.Weight (i, j);         
100     }
101   }
102   for (i = 1; i <= NbUKnots; i++) {
103     UKnots (i) = Convert.UKnot (i);
104     UMults (i) = Convert.UMultiplicity (i);
105   }
106   for (i = 1; i <= NbVKnots; i++) {
107     VKnots (i) = Convert.VKnot (i);
108     VMults (i) = Convert.VMultiplicity (i);
109   }
110   TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots, 
111     UMults, VMults, UDegree, VDegree,
112     Convert.IsUPeriodic(),
113     Convert.IsVPeriodic());
114   return TheSurface;
115 }
116
117 //=======================================================================
118 //function : SplitBSplineSurface
119 //purpose  : 
120 //=======================================================================
121
122 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface 
123   (const Handle(Geom_BSplineSurface)& S,
124   const Standard_Integer FromUK1, 
125   const Standard_Integer ToUK2,
126   const Standard_Integer FromVK1, 
127   const Standard_Integer ToVK2,
128   const Standard_Boolean SameUOrientation, 
129   const Standard_Boolean SameVOrientation ) 
130 {
131   Standard_Integer FirstU = S->FirstUKnotIndex ();
132   Standard_Integer FirstV = S->FirstVKnotIndex ();
133   Standard_Integer LastU  = S->LastUKnotIndex  ();
134   Standard_Integer LastV  = S->LastVKnotIndex  ();
135   if (FromUK1 == ToUK2 || FromVK1 == ToVK2)   Standard_DomainError::Raise();
136   Standard_Integer FirstUK = Min (FromUK1, ToUK2);
137   Standard_Integer LastUK  = Max (FromUK1, ToUK2);
138   Standard_Integer FirstVK = Min (FromVK1, ToVK2);
139   Standard_Integer LastVK  = Max (FromVK1, ToVK2);
140   if (FirstUK < FirstU || LastUK > LastU || 
141     FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
142
143   Handle(Geom_BSplineSurface) S1= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
144
145   S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
146     S1->VKnot(FirstVK),S1->VKnot(LastVK));
147
148   if (S->IsUPeriodic()) {
149     if (!SameUOrientation) S1->UReverse();
150   }
151   else {
152     if (FromUK1 > ToUK2)   S1->UReverse();
153   }
154   if (S->IsVPeriodic()) {
155     if (!SameVOrientation) S1->VReverse();
156   }
157   else {
158     if (FromVK1 > ToVK2)   S1->VReverse();
159   }
160   return S1;
161 }
162
163
164 //=======================================================================
165 //function : SplitBSplineSurface
166 //purpose  : 
167 //=======================================================================
168
169 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface 
170   (const Handle(Geom_BSplineSurface)& S,
171   const Standard_Integer FromK1,
172   const Standard_Integer ToK2,
173   const Standard_Boolean USplit, 
174   const Standard_Boolean SameOrientation )
175 {
176   if (FromK1 == ToK2)   Standard_DomainError::Raise();
177
178
179   Handle(Geom_BSplineSurface) S1 = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
180
181   if (USplit) {
182
183     Standard_Integer FirstU = S->FirstUKnotIndex ();
184     Standard_Integer LastU  = S->LastUKnotIndex  ();
185     Standard_Integer FirstUK = Min (FromK1, ToK2);
186     Standard_Integer LastUK  = Max (FromK1, ToK2);
187     if (FirstUK < FirstU || LastUK > LastU)  Standard_DomainError::Raise();
188
189     S1->Segment( S1->UKnot(FirstUK), 
190       S1->UKnot(LastUK),
191       S1->VKnot(S1->FirstVKnotIndex()),
192       S1->VKnot(S1->LastVKnotIndex()));
193
194     if (S->IsUPeriodic()) {
195       if (!SameOrientation) S1->UReverse();
196     }
197     else {
198       if (FromK1 > ToK2)    S1->UReverse();
199     }
200
201   }
202   else {
203
204     Standard_Integer FirstV = S->FirstVKnotIndex ();
205     Standard_Integer LastV  = S->LastVKnotIndex  ();
206     Standard_Integer FirstVK = Min (FromK1, ToK2);
207     Standard_Integer LastVK  = Max (FromK1, ToK2);
208     if (FirstVK < FirstV || LastVK > LastV)  Standard_DomainError::Raise();
209
210     S1->Segment( S1->UKnot(S1->FirstUKnotIndex()), 
211       S1->UKnot(S1->LastUKnotIndex()),
212       S1->VKnot(FirstVK),
213       S1->VKnot(LastVK));
214
215
216     if (S->IsVPeriodic()) {
217       if (!SameOrientation) S1->VReverse();
218     }
219     else {
220       if (FromK1 > ToK2)    S1->VReverse();
221     }
222   }
223   return S1;
224 }
225
226
227 //=======================================================================
228 //function : SplitBSplineSurface
229 //purpose  : 
230 //=======================================================================
231
232 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface 
233   (const Handle(Geom_BSplineSurface)& S, 
234   const Standard_Real FromU1, 
235   const Standard_Real ToU2,
236   const Standard_Real FromV1, 
237   const Standard_Real ToV2,
238   //   const Standard_Real ParametricTolerance,
239   const Standard_Real ,
240   const Standard_Boolean SameUOrientation, 
241   const Standard_Boolean SameVOrientation )
242 {
243   Standard_Real FirstU = Min( FromU1, ToU2);
244   Standard_Real LastU  = Max( FromU1, ToU2);
245   Standard_Real FirstV = Min( FromV1, ToV2);
246   Standard_Real LastV  = Max( FromV1, ToV2);
247
248   Handle (Geom_BSplineSurface) NewSurface 
249     = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
250
251   NewSurface->Segment(FirstU, LastU, FirstV, LastV);
252
253   if (S->IsUPeriodic()) { 
254     if (!SameUOrientation)  NewSurface->UReverse(); 
255   }
256   else { 
257     if (FromU1 > ToU2)    NewSurface->UReverse(); 
258   }
259   if (S->IsVPeriodic()) {
260     if (!SameVOrientation)  NewSurface->VReverse();
261   }
262   else {
263     if (FromV1 > ToV2)     NewSurface->VReverse();
264   }
265   return NewSurface;
266 }
267
268
269 //=======================================================================
270 //function : SplitBSplineSurface
271 //purpose  : 
272 //=======================================================================
273
274 Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface 
275   (const Handle(Geom_BSplineSurface)& S, 
276   const Standard_Real                    FromParam1, 
277   const Standard_Real                    ToParam2,
278   const Standard_Boolean                 USplit, 
279   const Standard_Real                    ParametricTolerance, 
280   const Standard_Boolean                 SameOrientation  )
281 {
282   if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
283     Standard_DomainError::Raise();
284   }
285   Handle(Geom_BSplineSurface) NewSurface
286     = Handle(Geom_BSplineSurface)::DownCast(S->Copy());
287
288   if (USplit) {
289     Standard_Real FirstU = Min( FromParam1, ToParam2);
290     Standard_Real LastU  = Max( FromParam1, ToParam2);
291     Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
292     Standard_Real LastV  = S->VKnot(S->LastVKnotIndex());
293
294     NewSurface->Segment(FirstU, LastU, FirstV, LastV);
295
296     if (S->IsUPeriodic()) { 
297       if (!SameOrientation)  NewSurface->UReverse(); 
298     }
299     else { 
300       if (FromParam1 > ToParam2)    NewSurface->UReverse(); 
301     }
302
303   }
304   else {
305     Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
306     Standard_Real LastU  = S->UKnot(S->LastUKnotIndex());
307     Standard_Real FirstV = Min( FromParam1, ToParam2);
308     Standard_Real LastV  = Max( FromParam1, ToParam2);
309
310     NewSurface->Segment(FirstU, LastU, FirstV, LastV);
311
312     if (S->IsUPeriodic()) { 
313       if (!SameOrientation)  NewSurface->UReverse(); 
314     }
315     else { 
316       if (FromParam1 > ToParam2)    NewSurface->UReverse(); 
317     }
318
319   }
320   return NewSurface;
321 }
322
323
324 //=======================================================================
325 //function : SurfaceToBSplineSurface
326 //purpose  : 
327 //=======================================================================
328
329 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
330   (const Handle(Geom_Surface)& Sr) 
331 {
332   Standard_Real U1, U2, V1, V2;
333   Sr->Bounds (U1, U2, V1, V2);
334   Standard_Real UFirst = Min (U1, U2);
335   Standard_Real ULast  = Max (U1, U2);
336   Standard_Real VFirst = Min (V1, V2);
337   Standard_Real VLast  = Max (V1, V2);
338
339   //If the surface Sr is infinite stop the computation
340   if (Precision::IsNegativeInfinite(UFirst) || 
341     Precision::IsPositiveInfinite(ULast)  || 
342     Precision::IsNegativeInfinite(VFirst) || 
343     Precision::IsPositiveInfinite(VLast) )   {
344       Standard_DomainError::Raise("");
345   }
346
347   Handle(Geom_BSplineSurface) TheSurface;
348   Handle(Geom_Surface) S; 
349   Handle(Geom_OffsetSurface) OffsetSur;
350   if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
351     OffsetSur = Handle(Geom_OffsetSurface)::DownCast (Sr);
352     S = OffsetSur->Surface();
353     if (!S.IsNull()) { // Convert the equivalent surface.
354       return SurfaceToBSplineSurface(S);
355     }
356   }
357   S = Sr;
358
359   if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
360     Handle(Geom_RectangularTrimmedSurface) Strim = 
361       Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
362
363     Handle(Geom_Surface) Surf = Strim->BasisSurface();
364     UFirst = U1;  ULast = U2; VFirst = V1; VLast = V2;
365     if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
366       Handle(Geom_OffsetSurface) OffsetSurBasis =
367         Handle(Geom_OffsetSurface)::DownCast(Surf);
368
369       S = OffsetSurBasis->Surface();
370       if (!S.IsNull()) {
371         Surf = S;
372       } 
373       else S = Surf;
374     }
375
376     if  (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
377       Handle(Geom_RectangularTrimmedSurface) aStrim = new 
378         (Geom_RectangularTrimmedSurface) (Surf, 
379         UFirst, ULast, 
380         VFirst, VLast);
381       return SurfaceToBSplineSurface(aStrim);
382     }
383
384     if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
385       TColgp_Array2OfPnt Poles (1, 2, 1, 2);
386       Poles (1, 1) = Strim->Value (U1, V1);
387       Poles (1, 2) = Strim->Value (U1, V2);
388       Poles (2, 1) = Strim->Value (U2, V1);
389       Poles (2, 2) = Strim->Value (U2, V2);
390       TColStd_Array1OfReal UKnots (1, 2);
391       TColStd_Array1OfReal VKnots (1, 2);
392       TColStd_Array1OfInteger UMults (1, 2);
393       TColStd_Array1OfInteger VMults (1, 2);
394       UKnots (1) = U1;
395       UKnots (2) = U2;
396       VKnots (1) = V1;
397       VKnots (2) = V2;
398       UMults (1) = 2;
399       UMults (2) = 2;
400       VMults (1) = 2;
401       VMults (2) = 2;
402       Standard_Integer UDegree = 1;
403       Standard_Integer VDegree = 1;
404       TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
405         VMults, UDegree, VDegree);
406     }
407     else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
408       Handle(Geom_CylindricalSurface) TheElSurf= 
409         Handle(Geom_CylindricalSurface)::DownCast(Surf);
410
411       gp_Cylinder Cyl = TheElSurf->Cylinder();
412       if (Strim->IsUClosed()) {
413         Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
414         TheSurface = BSplineSurfaceBuilder (Convert);
415       }
416       else {
417         Convert_CylinderToBSplineSurface 
418           Conv (Cyl, UFirst, ULast, VFirst, VLast);
419         TheSurface = BSplineSurfaceBuilder (Conv);
420       }
421     }
422
423
424     else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
425       Handle(Geom_ConicalSurface) TheElSurf = 
426         Handle(Geom_ConicalSurface)::DownCast(Surf);
427       gp_Cone Co = TheElSurf->Cone();
428       if (Strim->IsUClosed()) {
429         Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
430         TheSurface = BSplineSurfaceBuilder (Convert);
431       }
432       else {
433         Convert_ConeToBSplineSurface 
434           Convert (Co, UFirst, ULast, VFirst, VLast);
435         TheSurface = BSplineSurfaceBuilder (Convert);
436       }
437     }
438
439
440     else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
441       Handle(Geom_SphericalSurface) TheElSurf = 
442         Handle(Geom_SphericalSurface)::DownCast(Surf);
443       gp_Sphere Sph = TheElSurf->Sphere();
444       //OCC217
445       if (Strim->IsUClosed()) {
446         //if (Strim->IsVClosed()) {
447         //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
448         Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
449         TheSurface = BSplineSurfaceBuilder (Convert);
450       }
451       else {
452         Convert_SphereToBSplineSurface 
453           Convert (Sph, UFirst, ULast, VFirst, VLast);
454         TheSurface = BSplineSurfaceBuilder (Convert);
455       }
456     }
457
458
459     else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
460       Handle(Geom_ToroidalSurface) TheElSurf = 
461         Handle(Geom_ToroidalSurface)::DownCast(Surf);
462
463       gp_Torus Tr = TheElSurf->Torus();
464       if (Strim->IsUClosed()) { 
465         Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast, 
466           Standard_False);
467         TheSurface = BSplineSurfaceBuilder (Convert);
468       }
469       else if (Strim->IsVClosed()) {
470         Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
471         TheSurface = BSplineSurfaceBuilder (Convert);
472       }
473       else {
474         Convert_TorusToBSplineSurface 
475           Convert (Tr, UFirst, ULast, VFirst, VLast);
476         TheSurface = BSplineSurfaceBuilder (Convert);
477       }
478     }
479
480
481     else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
482       Handle(Geom_SurfaceOfRevolution) Revol = 
483         Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
484
485       Handle(Geom_Curve) Meridian = Revol->BasisCurve();
486       Handle(Geom_BSplineCurve) C; 
487       if (Strim->IsVClosed()) {
488         C =  GeomConvert::CurveToBSplineCurve (Meridian);
489       }
490       else {
491         Handle(Geom_TrimmedCurve) CT = 
492           new Geom_TrimmedCurve( Meridian, VFirst, VLast);
493         C =  GeomConvert::CurveToBSplineCurve (CT);
494       }
495       Standard_Integer NbUPoles, NbUKnots;
496       Standard_Integer NbVPoles, NbVKnots;
497       Standard_Boolean periodic = Standard_False;
498
499       // Poles of meridian = Vpoles
500       NbVPoles = C->NbPoles();
501       TColgp_Array1OfPnt Poles(1, NbVPoles);
502       C->Poles(Poles);
503       TColStd_Array1OfReal Weights( 1, NbVPoles);
504       Weights.Init(1.);
505       if ( C->IsRational()) C->Weights(Weights);
506
507       Standard_Integer nbUSpans;
508       Standard_Real AlfaU;
509       if (Strim->IsUPeriodic()) {
510         NbUKnots = 4;
511         nbUSpans = 3;
512         AlfaU    = M_PI / 3.;
513         NbUPoles = 6;
514         periodic = Standard_True;
515       }
516       else {
517         // Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
518         nbUSpans = 
519           (Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / M_PI) + 1;
520         AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
521         NbUPoles = 2 * nbUSpans + 1;
522         NbUKnots = nbUSpans + 1;
523       }
524       // Compute Knots and Mults
525       TColStd_Array1OfReal    UKnots(1, NbUKnots);
526       TColStd_Array1OfInteger UMults( 1, NbUKnots);
527       Standard_Integer i,j;
528       for ( i = 1; i <= NbUKnots; i++) {
529         UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
530         UMults(i) = 2;
531       }
532       if (!periodic) {
533         UMults(1)++; UMults(NbUKnots)++;
534       }
535       NbVKnots = C->NbKnots();
536       TColStd_Array1OfReal    VKnots(1, NbVKnots);
537       TColStd_Array1OfInteger VMults(1, NbVKnots);
538       C->Knots(VKnots);
539       C->Multiplicities(VMults);
540
541       // Compute the poles.
542       TColgp_Array2OfPnt   NewPoles  ( 1, NbUPoles, 1, NbVPoles);
543       TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
544       gp_Trsf Trsf;
545
546       for ( i = 1; i<= NbUPoles; i+=2) {
547         Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
548         for ( j = 1; j <= NbVPoles; j++) {
549           NewPoles(i,j) = Poles(j).Transformed(Trsf);
550           NewWeights(i,j) = Weights(j);
551         }
552       }
553       gp_GTrsf Aff;
554       Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
555       gp_XYZ coord;
556       for ( j= 1; j<= NbVPoles; j++) {
557         coord = Poles(j).XYZ();
558         Aff.Transforms(coord);
559         Poles(j).SetXYZ(coord);
560       }
561       for ( i = 2; i<= NbUPoles; i+=2) {
562         Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
563         for ( j = 1; j <= NbVPoles; j++) {
564           NewPoles(i,j) = Poles(j).Transformed(Trsf);
565           NewWeights(i,j) = Weights(j) * Cos(AlfaU);
566         }
567       }
568
569       TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights, 
570         UKnots, VKnots, 
571         UMults, VMults,
572         2 , C->Degree(),
573         periodic, C->IsPeriodic());
574
575
576     }
577
578
579     else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
580       Handle(Geom_SurfaceOfLinearExtrusion) Extru = 
581         Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
582
583       Handle(Geom_Curve) Meridian = Extru->BasisCurve();
584       Handle(Geom_BSplineCurve) C; 
585       if (Strim->IsUClosed()) {
586         C =  GeomConvert::CurveToBSplineCurve (Meridian);
587       }
588       else {
589         Handle(Geom_TrimmedCurve) CT = 
590           new Geom_TrimmedCurve( Meridian, UFirst, ULast);
591         C =  GeomConvert::CurveToBSplineCurve (CT);
592       }
593       TColgp_Array2OfPnt      Poles  ( 1, C->NbPoles(), 1, 2);
594       TColStd_Array2OfReal    Weights( 1, C->NbPoles(), 1, 2);
595       TColStd_Array1OfReal    UKnots ( 1, C->NbKnots());
596       C->Knots(UKnots);
597       TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
598       C->Multiplicities(UMults);
599       TColStd_Array1OfReal    VKnots ( 1, 2);
600       VKnots(1) = VFirst; 
601       VKnots(2) = VLast;
602       TColStd_Array1OfInteger VMults ( 1, 2);
603       VMults.Init(2);
604
605       gp_Vec D( Extru->Direction());
606       gp_Vec DV1 = VFirst * D;
607       gp_Vec DV2 = VLast  * D;
608       for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
609         Poles(i,1) = C->Pole(i).Translated(DV1);
610         Poles(i,2) = C->Pole(i).Translated(DV2);
611         Weights(i,1) = Weights(i,2) = C->Weight(i);
612       } 
613       TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots, 
614         UMults, VMults,
615         C->Degree(), 1,
616         C->IsPeriodic(), Standard_False);
617     }
618
619
620     else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
621
622       Handle(Geom_BezierSurface) SBez = 
623         Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
624
625       SBez->Segment (U1, U2, V1, V2);
626       Standard_Integer NbUPoles = SBez->NbUPoles();
627       Standard_Integer NbVPoles = SBez->NbVPoles();
628       Standard_Integer UDegree  = SBez->UDegree();
629       Standard_Integer VDegree  = SBez->VDegree();
630       TColgp_Array2OfPnt      Poles    (1, NbUPoles, 1, NbVPoles);
631       TColStd_Array1OfReal    UKnots   (1, 2);
632       TColStd_Array1OfInteger UMults   (1, 2);
633       TColStd_Array1OfReal    VKnots   (1, 2);
634       TColStd_Array1OfInteger VMults   (1, 2);
635       UKnots (1) = 0.0;
636       UKnots (2) = 1.0;
637       UMults (1) = UDegree + 1;
638       UMults (2) = UDegree + 1;
639       VKnots (1) = 0.0;
640       VKnots (2) = 1.0;
641       VMults (1) = VDegree + 1;
642       VMults (2) = VDegree + 1;
643       SBez->Poles (Poles);
644       if (SBez->IsURational() || SBez->IsVRational()) {    
645         TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
646         SBez->Weights (Weights);
647         TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
648           UMults, VMults,
649           UDegree, VDegree);
650       }
651       else {
652         TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, 
653           UMults, VMults,
654           UDegree, VDegree);
655       }
656     }
657
658     else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
659       Handle(Geom_BSplineSurface) BS = 
660         Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
661       Standard_Real umin, umax, vmin, vmax;
662       BS->Bounds(umin, umax, vmin, vmax);
663       if (!BS->IsUPeriodic()) {
664         if (U1 < umin)
665           U1 = umin;
666         if (U2 > umax) 
667           U2 = umax;
668       }
669
670       if (!BS->IsVPeriodic()) {
671         if (V1 < vmin)
672           V1 = vmin;
673         if (V2 > vmax)
674           V2 = vmax;
675       }
676       if (BS->IsUPeriodic() || BS->IsVPeriodic())
677         BS->CheckAndSegment (U1, U2, V1, V2);
678       else
679         BS->Segment (U1, U2, V1, V2);
680       TheSurface = BS;
681     }
682
683     else {
684       Standard_Real Tol3d=1.e-4;
685       Standard_Integer MaxDegree =14, MaxSeg;
686       GeomAbs_Shape cont;
687       GeomAdaptor_Surface AS(Sr);
688       if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 ) 
689         cont=GeomAbs_C1;
690       else
691         cont=GeomAbs_C2;
692       MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1); 
693       GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
694         MaxDegree, MaxDegree, MaxSeg, 1);
695       TheSurface = BSpS.Surface();
696     }
697   } // Fin du cas Rectangular::TrimmedSurface
698
699   else { 
700
701     if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
702       Handle(Geom_SphericalSurface) TheElSurf = 
703         Handle(Geom_SphericalSurface)::DownCast(S);
704
705       gp_Sphere Sph = TheElSurf->Sphere();
706       Convert_SphereToBSplineSurface Convert(Sph);
707       TheSurface = BSplineSurfaceBuilder(Convert);
708     }
709
710
711     else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
712       Handle(Geom_ToroidalSurface) TheElSurf = 
713         Handle(Geom_ToroidalSurface)::DownCast(S);
714
715       gp_Torus Tr = TheElSurf->Torus();
716       Convert_TorusToBSplineSurface Convert(Tr);
717       TheSurface = BSplineSurfaceBuilder(Convert);
718     }
719
720
721     else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
722
723       Handle(Geom_SurfaceOfRevolution) Revol = 
724         Handle(Geom_SurfaceOfRevolution)::DownCast(S);
725
726       Handle(Geom_Curve) Meridian = Revol->BasisCurve();
727       Handle(Geom_BSplineCurve) C 
728         = GeomConvert::CurveToBSplineCurve (Meridian);
729
730       Standard_Integer NbUPoles, NbUKnots;
731       Standard_Integer NbVPoles, NbVKnots;
732       Standard_Boolean periodic = Standard_True;
733
734       // Poles of meridian = Vpoles
735       NbVPoles = C->NbPoles();
736       TColgp_Array1OfPnt Poles(1, NbVPoles);
737       C->Poles(Poles);
738       TColStd_Array1OfReal Weights( 1, NbVPoles);
739       Weights.Init(1.);
740       if ( C->IsRational()) C->Weights(Weights);
741
742       Standard_Real AlfaU;
743       NbUKnots = 4;
744       AlfaU    = M_PI / 3.;
745       NbUPoles = 6;
746
747       // Compute Knots and Mults
748       TColStd_Array1OfReal    UKnots(1, NbUKnots);
749       TColStd_Array1OfInteger UMults( 1, NbUKnots);
750       Standard_Integer i,j;
751       for ( i = 1; i <= NbUKnots; i++) {
752         UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
753         UMults(i) = 2;
754       }
755       NbVKnots = C->NbKnots();
756       TColStd_Array1OfReal    VKnots(1, NbVKnots);
757       TColStd_Array1OfInteger VMults(1, NbVKnots);
758       C->Knots(VKnots);
759       C->Multiplicities(VMults);
760
761       // Compute the poles.
762       TColgp_Array2OfPnt   NewPoles  ( 1, NbUPoles, 1, NbVPoles);
763       TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
764       gp_Trsf Trsf;
765
766       for ( i = 1; i<= NbUPoles; i+=2) {
767         Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
768         for ( j = 1; j <= NbVPoles; j++) {
769           NewPoles(i,j) = Poles(j).Transformed(Trsf);
770           NewWeights(i,j) = Weights(j);
771         }
772       }
773       gp_GTrsf Aff;
774       Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
775       gp_XYZ coord;
776       for ( j= 1; j<= NbVPoles; j++) {
777         coord = Poles(j).XYZ();
778         Aff.Transforms(coord);
779         Poles(j).SetXYZ(coord);
780       }
781       for ( i = 2; i<= NbUPoles; i+=2) {
782         Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
783         for ( j = 1; j <= NbVPoles; j++) {
784           NewPoles(i,j) = Poles(j).Transformed(Trsf);
785           NewWeights(i,j) = Weights(j) * Cos(AlfaU);
786         }
787       }
788
789       TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights, 
790         UKnots, VKnots, 
791         UMults, VMults,
792         2 , C->Degree(),
793         periodic, C->IsPeriodic());
794     }
795
796
797     else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
798
799       Handle(Geom_BezierSurface) SBez = 
800         Handle(Geom_BezierSurface)::DownCast(S);
801
802       Standard_Integer NbUPoles = SBez->NbUPoles();
803       Standard_Integer NbVPoles = SBez->NbVPoles();
804       Standard_Integer UDegree  = SBez->UDegree();
805       Standard_Integer VDegree  = SBez->VDegree();
806       TColgp_Array2OfPnt      Poles (1, NbUPoles, 1, NbVPoles);
807       TColStd_Array1OfReal    UKnots(1, 2);
808       TColStd_Array1OfInteger UMults(1, 2);
809       TColStd_Array1OfReal    VKnots(1, 2);
810       TColStd_Array1OfInteger VMults(1, 2);
811       UKnots (1) = 0.0;
812       UKnots (2) = 1.0;
813       UMults (1) = UDegree + 1;
814       UMults (2) = UDegree + 1;
815       VKnots (1) = 0.0;
816       VKnots (2) = 1.0;
817       VMults (1) = VDegree + 1;
818       VMults (2) = VDegree + 1;
819       SBez->Poles (Poles);
820       if (SBez->IsURational() || SBez->IsVRational()) {    
821         TColStd_Array2OfReal    Weights (1, NbUPoles, 1, NbVPoles);
822         SBez->Weights (Weights);
823         TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
824           UMults, VMults,
825           UDegree, VDegree);
826       }
827       else {
828         TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, 
829           UMults, VMults,
830           UDegree, VDegree);
831       }
832     }
833
834     else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
835       TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
836     }
837
838     else { // In other cases => Approx
839       Standard_Real Tol3d=1.e-4;
840       Standard_Integer MaxDegree = 14, MaxSeg;
841       GeomAbs_Shape ucont = GeomAbs_C0, vcont = GeomAbs_C0;
842       GeomAdaptor_Surface AS(Sr);
843       //
844       if (Sr->IsCNu(2)) 
845       {
846         ucont=GeomAbs_C2;
847       }
848       else if(Sr->IsCNu(1)) 
849       {
850         ucont=GeomAbs_C1;
851       }
852       //
853       if (Sr->IsCNv(2)) 
854       {
855         vcont=GeomAbs_C2;
856       }
857       else if(Sr->IsCNv(1)) 
858       {
859         vcont=GeomAbs_C1;
860       }
861       //
862       MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);      
863       GeomConvert_ApproxSurface BSpS(Sr, Tol3d, ucont, vcont,
864                                      MaxDegree, MaxDegree, MaxSeg, 1);
865       TheSurface = BSpS.Surface();
866     }
867   } // Fin du cas direct
868   return TheSurface;
869 }
870
871
872