0028643: Coding rules - eliminate GCC compiler warnings -Wmisleading-indentation
[occt.git] / src / GeomliteTest / GeomliteTest_SurfaceCommands.cxx
1 // Created on: 1993-08-12
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <GeomliteTest.hxx>
18 #include <DrawTrSurf.hxx>
19 #include <Draw.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <Draw_Appli.hxx>
22 #include <Draw_Display.hxx>
23
24 #include <GeomAbs_SurfaceType.hxx>
25 #include <GeomAbs_IsoType.hxx>
26 #include <GeomAbs_Shape.hxx>
27
28 #include <Geom_Plane.hxx>
29 #include <Geom_CylindricalSurface.hxx>
30 #include <Geom_ConicalSurface.hxx>
31 #include <Geom_SphericalSurface.hxx>
32 #include <Geom_ToroidalSurface.hxx>
33 #include <Geom_BezierSurface.hxx>
34 #include <Geom_BSplineSurface.hxx>
35 #include <Geom_SurfaceOfLinearExtrusion.hxx>
36 #include <Geom_SurfaceOfRevolution.hxx>
37 #include <Geom_RectangularTrimmedSurface.hxx>
38 #include <Geom_OffsetSurface.hxx>
39 #include <Geom_Surface.hxx>
40
41 #include <Geom_TrimmedCurve.hxx>
42 #include <Geom_OffsetCurve.hxx>
43 #include <Geom_BezierCurve.hxx>
44 #include <Geom_BSplineCurve.hxx>
45
46 #include <Geom2d_TrimmedCurve.hxx>
47 #include <Geom2d_OffsetCurve.hxx>
48
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomAdaptor_HSurface.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <Geom2dAdaptor_Curve.hxx>
53
54 #include <TColGeom_Array2OfBezierSurface.hxx>
55 #include <TColgp_Array1OfPnt.hxx>
56 #include <TColgp_Array2OfPnt.hxx>
57 #include <TColStd_Array1OfReal.hxx>
58 #include <TColStd_Array2OfReal.hxx>
59 #include <TColStd_Array1OfInteger.hxx>
60 #include <TColStd_HArray1OfInteger.hxx>
61 #include <TColStd_HArray1OfReal.hxx>
62 #include <TColStd_HArray2OfReal.hxx>
63
64 #include <ElSLib.hxx>
65 #include <ElCLib.hxx>
66 #include <Precision.hxx>
67 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
68 #include <GeomConvert.hxx>
69 #include <GeomConvert_BSplineCurveToBezierCurve.hxx>
70 #include <GeomConvert_BSplineSurfaceToBezierSurface.hxx>
71 #include <GeomConvert_CompBezierSurfacesToBSplineSurface.hxx>
72 #include <Geom2dConvert.hxx>
73 #include <Geom2dConvert_BSplineCurveToBezierCurve.hxx>
74 #include <GeomLProp_SLProps.hxx>
75
76
77 #include <DrawTrSurf_BezierSurface.hxx>
78 #include <DrawTrSurf_BSplineSurface.hxx>
79 #include <GeomConvert_ApproxSurface.hxx>
80 #include <GeomLib_Tool.hxx>
81 #include <TopoDS_Shape.hxx>
82 #include <DBRep.hxx>
83 #include <Geom_Curve.hxx>
84
85 #include <stdio.h>
86 #ifdef _WIN32
87 Standard_IMPORT Draw_Viewer dout;
88 #endif
89
90
91
92
93 //=======================================================================
94 //function : compute min max radius of curvature on a surface
95 //purpose  : 
96 //=======================================================================
97 static Standard_Integer surface_radius (Draw_Interpretor& di,
98                                         Standard_Integer n, 
99                                         const char** a)
100 {
101   Standard_Integer report_curvature = 0 ;
102   Standard_Real UParameter,VParameter,radius,tolerance = 1.0e-7 ;
103
104   if (n <  4) return 1;
105   if (n >= 6) report_curvature = 1 ;
106
107   UParameter = Draw::Atof(a[2]);
108   VParameter = Draw::Atof(a[3]);
109   Handle(Geom_Surface) SurfacePtr = DrawTrSurf::GetSurface(a[1]);
110   if (!SurfacePtr.IsNull()) {
111     GeomLProp_SLProps myProperties(SurfacePtr,
112                                    UParameter,
113                                    VParameter,
114                                    2,
115                                    tolerance);
116     if (myProperties.IsCurvatureDefined()) {
117       radius = myProperties.MinCurvature();
118       
119       if (report_curvature) Draw::Set(a[4],radius);
120       
121       if (Abs(radius) > tolerance) { 
122         radius = 1.0e0/ radius ;
123         di << "Min Radius of Curvature : " << radius  << "\n";
124       }
125       else {
126         di << "Min Radius of Curvature :  infinite\n";
127       }
128     
129       radius = myProperties.MaxCurvature();
130       if (report_curvature) Draw::Set(a[5],radius);
131       if (Abs(radius) > tolerance)  { 
132         radius = 1.0e0/ radius;
133         di << "Max Radius of Curvature : " << radius  << "\n";
134       }
135       else
136         di << "Min Radius of Curvature :  infinite\n";
137     }
138     else {
139       di << "Curvature not defined.\n";
140     }
141   }
142   else {
143     return 1;
144   }
145   return 0;
146 }
147
148
149 //=======================================================================
150 //function : anasurface
151 //purpose  : 
152 //=======================================================================
153
154 static Standard_Integer anasurface (Draw_Interpretor& ,
155                                     Standard_Integer  n, 
156                                     const char** a)
157 {
158   if (n < 2) return 1;
159   gp_Ax3 loc;
160
161   Standard_Integer i;
162
163   if (n < 5) {
164     loc = gp_Ax3(gp_Pnt(0,0,0),gp_Dir(0,0,1),gp_Dir(1,0,0));
165     i = 2;
166   }
167   else if (n < 8) {
168     loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
169                  gp_Dir(0,0,1),gp_Dir(1,0,0));
170     i = 5;
171   }
172   else if (n < 11) {
173     loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
174                  gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])));
175     i = 8;
176   }
177   else if (n < 14) {
178     loc = gp_Ax3(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
179                  gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
180                  gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10])));
181     i = 11;
182   }
183   else
184     return 1;
185
186   Handle(Geom_Geometry) result;
187
188   if (!strcasecmp(a[0],"plane")) {
189     Handle(Geom_Plane) C = new Geom_Plane(loc);
190     result = C;
191   }
192   else {
193     if (i >= n) return 1;
194     Standard_Real par1 = Draw::Atof(a[i]);
195     
196     if (!strcasecmp(a[0],"cylinder")) {
197       Handle(Geom_CylindricalSurface) C = 
198         new Geom_CylindricalSurface(loc,par1);
199       result = C;
200     }
201     
202     else if (!strcasecmp(a[0],"sphere")) {
203       Handle(Geom_SphericalSurface) C = 
204         new Geom_SphericalSurface(loc,par1);
205       result = C;
206     }
207     
208     else {
209       if (i+1 >= n) return 1;
210       Standard_Real par2 = Draw::Atof(a[i+1]);
211       
212       if (!strcasecmp(a[0],"cone")) {
213         par1 *= (M_PI / 180.0);
214         Handle(Geom_ConicalSurface) C =
215           new Geom_ConicalSurface(loc,par1,par2);
216         result = C;
217       }
218     
219       else if (!strcasecmp(a[0],"torus")) {
220         Handle(Geom_ToroidalSurface) C =
221           new Geom_ToroidalSurface(loc,par1,par2);
222         result = C;
223       }
224     }    
225   }
226
227   DrawTrSurf::Set(a[1],result);
228   return 0;
229 }
230
231
232 //=======================================================================
233 //function : polesurface
234 //purpose  : 
235 //=======================================================================
236
237 static Standard_Integer polesurface (Draw_Interpretor& , Standard_Integer n, const char** a)
238 {
239   Standard_Integer k,j,i;
240
241
242   if (n < 4) return 1;
243
244   if (!strcasecmp(a[0],"beziersurf")) {
245     
246     Standard_Integer nup = Draw::Atoi(a[2]);
247     Standard_Integer nvp = Draw::Atoi(a[3]);
248     if (nup * nvp == 0) return 1;
249     
250     i = (n - 4) / (nup * nvp);
251     if (i < 3 || i > 4) return 1;
252     Standard_Boolean hasw = i == 4;
253     
254     TColgp_Array2OfPnt poles(1,nup,1,nvp);
255     TColStd_Array2OfReal weights(1,nup,1,nvp);
256     
257     k = 4;
258     for (j = 1; j <= nvp; j++) {
259       for (i = 1; i <= nup; i++) {
260         poles(i, j).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]),Draw::Atof(a[k+2]));
261         k += 3;
262         if (hasw) {
263           weights(i, j) = Draw::Atof(a[k]);
264           k++;
265         }
266       }
267     }
268     
269     Handle(Geom_BezierSurface) result;
270     if (hasw)
271       result = new Geom_BezierSurface(poles,weights);
272     else
273       result = new Geom_BezierSurface(poles);
274
275     DrawTrSurf::Set(a[1],result);
276   }
277
278   else {
279     Standard_Integer udeg = Draw::Atoi(a[2]);
280     Standard_Integer nbuk = Draw::Atoi(a[3]);
281
282     Standard_Boolean uper = (*a[0] == 'u') || (*(a[0]+1) == 'u');
283     Standard_Boolean vper = (*a[0] == 'v') || (*(a[0]+1) == 'v');
284
285     TColStd_Array1OfReal    uk   (1, nbuk);
286     TColStd_Array1OfInteger umult(1, nbuk);
287     k = 4;
288     Standard_Integer SigmaU = 0;
289     for (i = 1; i<=nbuk; i++) {
290       uk( i) = Draw::Atof(a[k]);
291       k++;
292       umult( i) = Draw::Atoi(a[k]);
293       SigmaU += umult(i);
294       k++;
295     }
296
297     Standard_Integer vdeg = Draw::Atoi(a[k]);
298     k++;
299     Standard_Integer nbvk = Draw::Atoi(a[k]);
300     k++;
301
302     TColStd_Array1OfReal    vk   (1, nbvk);
303     TColStd_Array1OfInteger vmult(1, nbvk);
304     Standard_Integer SigmaV = 0;
305     for (i = 1; i<=nbvk; i++) {
306       vk( i) = Draw::Atof(a[k]);
307       k++;
308       vmult( i) = Draw::Atoi(a[k]);
309       SigmaV += vmult(i);
310       k++;
311     }
312
313     Standard_Integer nup,nvp;
314     if (uper)
315       nup = SigmaU - umult(nbuk);
316     else
317       nup = SigmaU - udeg  -1;
318     if (vper)
319       nvp = SigmaV - vmult(nbvk);
320     else
321       nvp = SigmaV - vdeg  -1;
322     TColgp_Array2OfPnt   poles  (1, nup, 1, nvp);
323     TColStd_Array2OfReal weights(1, nup, 1, nvp);
324     
325     for (j = 1; j <= nvp; j++) {
326       for (i = 1; i <= nup; i++) {
327         poles(i, j).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]),Draw::Atof(a[k+2]));
328         k += 3;
329         weights(i, j) = Draw::Atof(a[k]);
330         k++;
331       }
332     }
333     
334     Handle(Geom_BSplineSurface) result =
335       new Geom_BSplineSurface(poles, weights,
336                               uk   , vk     ,
337                               umult, vmult  ,
338                               udeg , vdeg   ,
339                               uper , vper   );
340
341     DrawTrSurf::Set(a[1],result);
342   }
343   
344   return 0;
345 }
346
347 //=======================================================================
348 //function : algosurface
349 //purpose  : 
350 //=======================================================================
351
352 static Standard_Integer algosurface (Draw_Interpretor& , Standard_Integer n, const char** a)
353 {
354   if (n < 5) return 1;
355
356   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[2]);
357   if (GC.IsNull()) return 1;
358
359   gp_Dir D;
360   gp_Pnt P;
361
362   if (!strcasecmp(a[0],"extsurf")) {
363     D.SetCoord(Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
364     Handle(Geom_SurfaceOfLinearExtrusion) result =
365       new Geom_SurfaceOfLinearExtrusion(GC,D);
366
367     DrawTrSurf::Set(a[1],result);
368
369   }
370   else if (!strcasecmp(a[0],"revsurf")) {
371     if (n<8) return 1;
372     P.SetCoord(Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
373     D.SetCoord(Draw::Atof(a[6]),Draw::Atof(a[7]),Draw::Atof(a[8]));
374     
375     Handle(Geom_SurfaceOfRevolution) result =
376       new Geom_SurfaceOfRevolution(GC,gp_Ax1(P,D));
377
378     DrawTrSurf::Set(a[1],result);
379
380   }
381
382   return 0;
383
384 }
385
386
387
388 //=======================================================================
389 //function : trimming
390 //purpose  : 
391 //=======================================================================
392
393 static Standard_Integer trimming (Draw_Interpretor& , 
394                                   Standard_Integer n, const char** a)
395 {
396   if (n < 3) return 1;
397
398   Handle(Geom_Curve)   GC   = DrawTrSurf::GetCurve(a[2]);
399   Handle(Geom2d_Curve) GC2d = DrawTrSurf::GetCurve2d(a[2]);
400   Handle(Geom_Surface) GS   = DrawTrSurf::GetSurface(a[2]);
401
402   if (n == 3) {
403     if (!GC.IsNull()) {
404       Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(GC);
405       if (!T.IsNull()) GC = T->BasisCurve();
406       DrawTrSurf::Set(a[1],GC);
407     }
408     else if (!GC2d.IsNull()) {
409       Handle(Geom2d_TrimmedCurve) T = Handle(Geom2d_TrimmedCurve)::DownCast(GC2d);
410       if (!T.IsNull()) GC2d = T->BasisCurve();
411       DrawTrSurf::Set(a[1],GC2d);
412     }
413     else if (!GS.IsNull()) {
414       Handle(Geom_RectangularTrimmedSurface) T = Handle(Geom_RectangularTrimmedSurface)::DownCast(GS);
415       if (!T.IsNull()) GS = T->BasisSurface();
416       DrawTrSurf::Set(a[1],GS);
417     }
418     return 0;
419   }
420         
421   if (n < 5) return 1;
422
423   Standard_Real u1 = Draw::Atof(a[3]);
424   Standard_Real u2 = Draw::Atof(a[4]);
425
426   Handle(Geom_Geometry) result;
427   Handle(Geom2d_Curve) result2d;
428
429   if (!strcasecmp(a[0],"trim")) {
430     if (!GS.IsNull()) {
431       if (n<7) return 1;
432       result =
433         new Geom_RectangularTrimmedSurface(GS,u1,u2,Draw::Atof(a[5]),Draw::Atof(a[6]));
434     }
435     else if (!GC.IsNull()) {
436       result = new Geom_TrimmedCurve(GC, u1, u2);
437     }
438     else if (!GC2d.IsNull()) {
439       result2d = new Geom2d_TrimmedCurve(GC2d, u1, u2);
440     }
441     else
442       return 1;
443   }
444   else {
445     if (GS.IsNull()) return 1;
446     result =  new Geom_RectangularTrimmedSurface(GS,u1,u2,
447                                                  !strcasecmp(a[0],"trimu"));
448   }
449
450   if (!result.IsNull())
451     DrawTrSurf::Set(a[1], result);
452   else
453     DrawTrSurf::Set(a[1],result2d);
454   
455   return 0;
456 }
457
458 //=======================================================================
459 //function : converting
460 //purpose  : 
461 //=======================================================================
462
463 static Standard_Integer converting(Draw_Interpretor& , Standard_Integer n, const char ** a)
464 {
465   if ( n < 3) return 1;
466
467   Convert_ParameterisationType 
468     Parameterisation = Convert_TgtThetaOver2 ;
469   if (strcmp(a[n-1], "qa") == 0) {
470     Parameterisation = Convert_QuasiAngular ;
471   }
472   else if (strcmp(a[n-1], "c1") == 0) {
473     Parameterisation = Convert_RationalC1 ;
474   }
475   else if (strcmp (a[n-1], "s1") == 0) {
476     Parameterisation = Convert_TgtThetaOver2_1 ;
477   } 
478   else if (strcmp (a[n-1], "s2") == 0) {
479     Parameterisation = Convert_TgtThetaOver2_2;
480   }
481   else if (strcmp (a[n-1], "s3") == 0) {
482     Parameterisation = Convert_TgtThetaOver2_3 ;
483   }
484   else if (strcmp (a[n-1], "s4") == 0) {
485     Parameterisation = Convert_TgtThetaOver2_4 ;
486   }
487   else if (strcmp (a[n-1], "po") == 0) {
488     Parameterisation = Convert_Polynomial;
489   }
490
491   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[2]);
492   if ( GC.IsNull()) {
493     Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[2]);
494     if ( GS.IsNull()) {
495       Handle(Geom2d_Curve) G2d = DrawTrSurf::GetCurve2d(a[2]);
496       if ( G2d.IsNull()) {
497         return 1;
498       }
499       else {
500         G2d = Geom2dConvert::CurveToBSplineCurve(G2d,
501                                                  Parameterisation);
502         DrawTrSurf::Set(a[1], G2d);
503       }
504     }
505     else {
506       GS = GeomConvert::SurfaceToBSplineSurface( GS);
507       DrawTrSurf::Set(a[1], GS);
508     }
509   }
510   else {
511     GC = GeomConvert::CurveToBSplineCurve( GC,
512                                           Parameterisation);
513     DrawTrSurf::Set(a[1], GC);
514   }
515
516   return 0;
517 }
518
519
520 //=======================================================================
521 //function : tobezier
522 //purpose  : 
523 //=======================================================================
524
525 static Standard_Integer tobezier(Draw_Interpretor& di,
526                                  Standard_Integer n, const char** a)
527 {
528   if ( n < 3) return 1;
529   Standard_Integer i,j,NbU,NbV,NbArc;
530   char* name = new char[100];
531   
532   Handle(Geom2d_BSplineCurve) C2d = 
533     DrawTrSurf::GetBSplineCurve2d(a[2]);
534   if ( C2d.IsNull()) {
535     Handle(Geom_BSplineCurve) C3d = 
536       DrawTrSurf::GetBSplineCurve(a[2]);
537     if ( C3d.IsNull()) {
538       Handle(Geom_BSplineSurface) S = 
539         DrawTrSurf::GetBSplineSurface(a[2]);
540       if ( S.IsNull()) return 1;
541       if (n == 7) {
542         Standard_Real U1, U2, V1, V2;
543         U1 = Draw::Atof(a[3]);
544         U2 = Draw::Atof(a[4]);
545         V1 = Draw::Atof(a[5]);
546         V2 = Draw::Atof(a[6]);
547         GeomConvert_BSplineSurfaceToBezierSurface 
548           Conv(S, U1, U2, V1, V2, Precision::PConfusion());
549         NbU = Conv.NbUPatches();
550         NbV = Conv.NbVPatches();
551         di << NbU << " X " << NbV << " patches in the result\n";
552         for (i = 1; i <= NbU; i++) {
553           for (j = 1; j <= NbV; j++) {
554             Sprintf(name,"%s_%i_%i",a[1],i,j);
555             char *temp = name ;
556             DrawTrSurf::Set(temp,Conv.Patch(i,j));
557           }
558         }
559       }
560       else {
561         GeomConvert_BSplineSurfaceToBezierSurface Conv(S);
562         NbU = Conv.NbUPatches();
563         NbV = Conv.NbVPatches();
564         di << NbU << " X " << NbV << " patches in the result\n";
565         for (i = 1; i <= NbU; i++) {
566           for (j = 1; j <= NbV; j++) {
567             Sprintf(name,"%s_%i_%i",a[1],i,j);
568             char *temp = name ;
569             DrawTrSurf::Set(temp,Conv.Patch(i,j));
570           }
571         }
572       }
573     }
574     else {
575       if (n==5) {
576         Standard_Real U1, U2;
577         U1 = Draw::Atof(a[3]);
578         U2 = Draw::Atof(a[4]);
579         GeomConvert_BSplineCurveToBezierCurve Conv(C3d, U1, U2, 
580                                                    Precision::PConfusion());
581         NbArc = Conv.NbArcs();
582         di << NbArc << " arcs in the result\n";
583         for (i = 1; i <= NbArc; i++) {
584           Sprintf(name,"%s_%i",a[1],i);
585           char *temp = name ;
586           DrawTrSurf::Set(temp,Conv.Arc(i));
587         }
588       }
589       else {
590         GeomConvert_BSplineCurveToBezierCurve Conv(C3d);
591         NbArc = Conv.NbArcs();
592         di << NbArc << " arcs in the result\n";
593         for (i = 1; i <= NbArc; i++) {
594           Sprintf(name,"%s_%i",a[1],i);
595           char *temp = name ;
596           DrawTrSurf::Set(temp,Conv.Arc(i));
597         }
598       }
599     }
600   }
601   else {
602     if (n==5) {
603       Standard_Real U1, U2;
604       U1 = Draw::Atof(a[3]);
605       U2 = Draw::Atof(a[4]);
606       Geom2dConvert_BSplineCurveToBezierCurve Conv(C2d, U1, U2, 
607                                                    Precision::PConfusion());
608       NbArc = Conv.NbArcs();
609       di << NbArc << " arcs in the result\n";
610       for (i = 1; i <= NbArc; i++) {
611         Sprintf(name,"%s_%i",a[1],i);
612         char *temp = name ;
613         DrawTrSurf::Set(temp,Conv.Arc(i));
614       }
615     }
616     else {
617       Geom2dConvert_BSplineCurveToBezierCurve Conv(C2d);
618       NbArc = Conv.NbArcs();
619       di << NbArc << " arcs in the result\n";
620       for (i = 1; i <= NbArc; i++) {
621         Sprintf(name,"%s_%i",a[1],i);
622         char *temp = name ;
623         DrawTrSurf::Set(temp,Conv.Arc(i));
624       }
625     }
626   }
627
628   return 0;
629 }
630
631 //=======================================================================
632 //function : convbz
633 //purpose  : 
634 //=======================================================================
635
636 static Standard_Integer convbz(Draw_Interpretor& di,
637                                  Standard_Integer n, const char** a)
638 {
639   if ( n < 4) return 1;
640
641   Standard_Integer ii, jj, kk=0, NbU, NbV;
642   Standard_Real Tol = Precision::Confusion();
643   
644   NbU = Draw::Atoi(a[2]);
645   Handle(Geom_Curve) aCurve (Handle(Geom_Curve)::DownCast(DrawTrSurf::Get(a[3])));
646   if (aCurve.IsNull()) {
647     // Cas Surfacique
648     NbV = Draw::Atoi(a[3]);
649     if (n<4+NbU*NbV) {
650       di << "The number of bezier surface have to be " << NbU*NbV << "\n";
651       return 1;
652     }
653     TColGeom_Array2OfBezierSurface BZ(1, NbU, 1, NbV);
654     kk = 4;
655     for (jj=1; jj<=NbV; jj++)
656       for(ii=1;ii<=NbU; ii++) {
657         BZ(ii,jj) = 
658           Handle(Geom_BezierSurface)::DownCast(DrawTrSurf::Get(a[kk]));
659         if (BZ(ii,jj).IsNull()) {
660           di << "the Surface " << kk <<"is not a BezierSurface\n";
661           return 1;
662         }
663         kk++;
664       }
665     if (kk<n) Tol = Draw::Atof(a[kk]);
666   
667     GeomConvert_CompBezierSurfacesToBSplineSurface Conv(BZ, Tol);
668     
669     if (! Conv.IsDone()) {
670       di << "Convert Not Done\n";
671       return 1;
672     }
673
674     Handle(Geom_BSplineSurface) BSurf = 
675       new Geom_BSplineSurface(Conv.Poles()->Array2(),
676                               Conv.UKnots()->Array1(),
677                               Conv.VKnots()->Array1(),
678                               Conv.UMultiplicities()->Array1(),
679                               Conv.VMultiplicities()->Array1(),
680                               Conv.UDegree(),
681                               Conv.VDegree());
682
683     DrawTrSurf::Set(a[1], BSurf);
684   }
685   else { // cas de courbes
686     Convert_CompBezierCurvesToBSplineCurve Conv;
687     Handle(Geom_BezierCurve) BZ;
688     for (ii=1, kk=3; ii<=NbU; ii++,kk++) {
689       BZ =  Handle(Geom_BezierCurve)::DownCast(DrawTrSurf::Get(a[kk]));
690       if (BZ.IsNull()) {
691           di << "the curve " << kk <<"is not a BezierCurve\n";
692           return 1;
693         }
694       TColgp_Array1OfPnt Poles(1, BZ->NbPoles());
695       BZ->Poles(Poles);
696       Conv.AddCurve(Poles);
697     }
698
699     Conv.Perform();
700
701     TColgp_Array1OfPnt Poles(1, Conv.NbPoles());
702     Conv.Poles(Poles);
703     TColStd_Array1OfInteger Mults(1, Conv.NbKnots());
704     TColStd_Array1OfReal  Knots(1, Conv.NbKnots());
705     Conv.KnotsAndMults(Knots, Mults);
706     Handle(Geom_BSplineCurve) BS = 
707       new (Geom_BSplineCurve) (Poles, Knots, Mults,
708                                Conv.Degree());
709     DrawTrSurf::Set(a[1], BS);
710   }
711
712     return 0;
713 }
714
715 //=======================================================================
716 //function : approxsurf
717 //purpose  : Approximation d'une Surface par une BSpline non rationnelle
718 //=======================================================================
719
720
721 static Standard_Integer approxsurf(Draw_Interpretor& di, Standard_Integer n, const char** a)
722
723 // " Tolerance (par defaut 0.1mm) " 
724   Standard_Real Tol = 1.e-4;
725 // " Ordres de continuites : 0, 1 ou 2 (par defaut 1)" 
726   GeomAbs_Shape myUCont = GeomAbs_C1, myVCont = GeomAbs_C1;
727 // " Degre maximum des carreaux de Bezier 14 par defaut "
728   Standard_Integer degU = 14, degV = 14;
729 // " Nombre max de carreaux (par defaut 10)" 
730   Standard_Integer nmax = 16;
731 // "Code de precision par defaults"
732   Standard_Integer myPrec = 1;  
733
734   if ( n>10 || n<3) return 1;
735
736   if (n>3) Tol = Max(Draw::Atof(a[3]),1.e-10);
737
738   if (n==5)  return 1;
739   
740   if (n>5) {
741     if (Draw::Atoi(a[4]) == 0) myUCont = GeomAbs_C0;
742     if (Draw::Atoi(a[4]) == 2) myUCont = GeomAbs_C2;
743     if (Draw::Atoi(a[5]) == 0) myVCont = GeomAbs_C0;
744     if (Draw::Atoi(a[5]) == 2) myVCont = GeomAbs_C2;
745   }
746
747   if (n==7)  return 1;
748
749   if (n>7) {
750     ( degU = (Draw::Atoi(a[6])));
751     ( degV = (Draw::Atoi(a[7])));
752     if ((degU<1) || (degU>24)) degU = 14;
753     if ((degV<1) || (degV>24)) degV = 14; 
754   }  
755
756   if (n>8) nmax = Draw::Atoi(a[8]);
757   if (n>9) myPrec =  Draw::Atoi(a[9]);
758
759   Handle(Geom_Surface) surf = DrawTrSurf::GetSurface(a[2]);
760   if (surf.IsNull()) return 1;  
761   GeomConvert_ApproxSurface myApprox(surf,Tol,myUCont,myVCont,degU,degV,nmax,myPrec);
762   if ( myApprox.HasResult()) DrawTrSurf::Set(a[1], myApprox.Surface());
763   di<<a[1]<<"\n";
764   return 0;
765 }
766
767 //=======================================================================
768 //function : offseting
769 //purpose  : 
770 //=======================================================================
771
772 static Standard_Integer offseting (Draw_Interpretor& ,
773                                    Standard_Integer n, const char** a)
774 {
775   if (n < 4) return 1;
776
777   // test the Geom2d curve
778   Handle(Geom2d_Curve) C2d = DrawTrSurf::GetCurve2d(a[2]);
779   if (!C2d.IsNull()) {
780     Handle(Geom2d_OffsetCurve) OC = new Geom2d_OffsetCurve(C2d,Draw::Atof(a[3]));
781     DrawTrSurf::Set(a[1],OC);
782     return 0;
783   }
784
785   Standard_Boolean yasurf = Standard_False;
786
787   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[2]);
788   Handle(Geom_Surface) GS;
789   if (GC.IsNull()) {
790     GS = DrawTrSurf::GetSurface(a[2]);
791     if (GS.IsNull())
792       return 1;
793     yasurf = Standard_True;
794   }
795
796   Standard_Real dist = Draw::Atof(a[3]);
797
798   Handle(Geom_Geometry) result;
799
800   if (yasurf) {
801     Handle(Geom_OffsetSurface) GO = new Geom_OffsetSurface(GS,dist);
802     result = GO;
803   }
804   else {
805     if (n < 7) return 1;
806     gp_Dir D(Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]));
807     Handle(Geom_OffsetCurve) GT = new Geom_OffsetCurve(GC, dist, D);
808     result = GT;
809   }
810
811   DrawTrSurf::Set(a[1], result);
812   return 0;
813 }
814
815 //=======================================================================
816 //function : sreverse
817 //purpose  : 
818 //=======================================================================
819
820 static Standard_Integer sreverse (Draw_Interpretor& , Standard_Integer n, const char** a)
821 {
822   if (n < 2) return 1;
823
824   Standard_Integer i;
825   for (i = 1; i < n; i++) {
826
827     Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[i]);
828     if (!GS.IsNull()) {
829       if (*a[0] == 'u')
830         GS->UReverse();
831       else
832         GS->VReverse();
833       Draw::Repaint();
834     }
835   }
836
837   return 0;
838 }
839
840 //=======================================================================
841 //function : iso
842 //purpose  : 
843 //=======================================================================
844
845 static Standard_Integer iso (Draw_Interpretor& , Standard_Integer n, const char** a)
846 {
847   if (n < 4) return 1;
848
849   Handle(Geom_Curve) C;
850   Standard_Real par = Draw::Atof(a[3]);
851   Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[2]);
852   if (!GS.IsNull()) {
853     if (*a[0] == 'u')
854       C = GS->UIso(par);
855     else
856       C = GS->VIso(par);
857     DrawTrSurf::Set(a[1],C);
858   }
859   
860   return 0;
861 }
862
863
864 //=======================================================================
865 //function : value
866 //purpose  : 
867 //=======================================================================
868
869 static Standard_Integer value (Draw_Interpretor& ,
870                                Standard_Integer n, const char** a)
871 {
872   if (n < 5) return 1;
873
874   Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[1]);
875   if (GS.IsNull()) return 1;
876
877   Standard_Real U = Draw::Atof(a[2]);
878   Standard_Real V = Draw::Atof(a[3]);
879
880   Standard_Boolean DrawPoint = ( n%3 == 2);
881   if ( DrawPoint) n--;
882
883   gp_Pnt P;
884   if (n >= 13) {
885     gp_Vec DU,DV;
886     if (n >= 22) {
887       gp_Vec D2U,D2V,D2UV;
888       GS->D2(U,V,P,DU,DV,D2U,D2V,D2UV);
889       Draw::Set(a[13],D2U.X());
890       Draw::Set(a[14],D2U.Y());
891       Draw::Set(a[15],D2U.Z());
892       Draw::Set(a[16],D2V.X());
893       Draw::Set(a[17],D2V.Y());
894       Draw::Set(a[18],D2V.Z());
895       Draw::Set(a[19],D2UV.X());
896       Draw::Set(a[20],D2UV.Y());
897       Draw::Set(a[21],D2UV.Z());
898     }
899     else
900       GS->D1(U,V,P,DU,DV);
901
902     Draw::Set(a[7],DU.X());
903     Draw::Set(a[8],DU.Y());
904     Draw::Set(a[9],DU.Z());
905     Draw::Set(a[10],DV.X());
906     Draw::Set(a[11],DV.Y());
907     Draw::Set(a[12],DV.Z());
908   }
909   else 
910     GS->D0(U,V,P);
911
912   if ( n > 6) {
913     Draw::Set(a[4],P.X());
914     Draw::Set(a[5],P.Y());
915     Draw::Set(a[6],P.Z());
916   }
917   if ( DrawPoint) {
918     DrawTrSurf::Set(a[n],P);
919   }
920
921   return 0;
922 }
923
924 //=======================================================================
925 //function : movepole
926 //purpose  : 
927 //=======================================================================
928
929 static Standard_Integer movepole (Draw_Interpretor& , Standard_Integer n, const char** a)
930 {
931   if (n < 6) return 1;
932   Standard_Boolean BSpline = Standard_False;
933
934   Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[1]);
935   Handle(Geom_BSplineSurface) GBs;
936   if (GBz.IsNull()) {
937     GBs = DrawTrSurf::GetBSplineSurface(a[1]);
938     if (GBs.IsNull())
939     {
940       return 1;
941     }
942     BSpline = Standard_True;
943   }
944
945   Standard_Real dx = Draw::Atof(a[n-3]);
946   Standard_Real dy = Draw::Atof(a[n-2]);
947   Standard_Real dz = Draw::Atof(a[n-1]);
948   
949   Standard_Integer nup, nvp;
950   if( !BSpline) {
951     nup = GBz->NbUPoles();
952     nvp = GBz->NbVPoles();
953   }
954   else {
955     nup = GBs->NbUPoles();
956     nvp = GBs->NbVPoles();
957   }
958
959   Standard_Integer FirstRow=0, LastRow=0, FirstCol=0, LastCol=0;
960   // Rem : Row = indice ligne.  -> variation en U. 
961   //       Col = indice colonne.-> variation en V.
962
963   if (!strcasecmp(a[0],"movep")) {
964     if (n<7) return 1;
965     FirstRow = Draw::Atoi(a[2]);
966     FirstCol = Draw::Atoi(a[3]);
967     if ( FirstRow < 1  || FirstRow > nup ||
968          FirstCol < 1  || FirstCol > nvp   ) return 1;
969     LastRow = FirstRow;
970     LastCol = FirstCol;
971   }
972   else if (!strcasecmp(a[0],"moverowp")) {
973     FirstRow = Draw::Atoi(a[2]);
974     if ( FirstRow < 1  || FirstRow > nup ) return 1;
975     LastRow = FirstRow;
976     FirstCol = 1;
977     LastCol  = nvp;
978   }
979   else if (!strcasecmp(a[0],"movecolp")) {
980     FirstCol = Draw::Atoi(a[2]);
981     if ( FirstCol < 1  || FirstCol > nvp ) return 1;
982     LastCol = FirstCol;
983     FirstRow = 1;
984     LastRow  = nup;
985   }
986
987   gp_Pnt P;
988
989   for ( Standard_Integer i = FirstRow; i<= LastRow; i++) {
990     for ( Standard_Integer j = FirstCol; j<= LastCol; j++) {
991       if( !BSpline) {
992         P = GBz->Pole(i,j);
993         P.SetCoord(P.X()+dx, P.Y()+dy, P.Z()+dz);
994         GBz->SetPole(i,j,P);
995       }
996       else {
997         P = GBs->Pole(i,j);
998         P.SetCoord(P.X()+dx, P.Y()+dy, P.Z()+dz);
999         GBs->SetPole(i,j,P);
1000       }
1001     }
1002   }
1003
1004   Draw::Repaint();
1005
1006   return 0;
1007 }
1008
1009
1010 //=======================================================================
1011 //function : movepoint
1012 //purpose  : 
1013 //=======================================================================
1014
1015 static Standard_Integer movepoint (Draw_Interpretor& , Standard_Integer n, const char** a)
1016 {
1017   if (n < 7) return 1;
1018
1019   Handle(Geom_BSplineSurface) GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1020   if (GBs.IsNull()) {
1021     return 1;
1022   }
1023
1024   Standard_Real u = Draw::Atof(a[2]);
1025   Standard_Real v = Draw::Atof(a[3]);
1026
1027   Standard_Real dx = Draw::Atof(a[4]);
1028   Standard_Real dy = Draw::Atof(a[5]);
1029   Standard_Real dz = Draw::Atof(a[6]);
1030   
1031   Standard_Integer index1u = 0;
1032   Standard_Integer index2u = 0;
1033   Standard_Integer index1v = 0;
1034   Standard_Integer index2v = 0;
1035
1036   Standard_Integer fmodifu, lmodifu, fmodifv, lmodifv;
1037   if (n == 11) {
1038     index1u = Draw::Atoi(a[7]);
1039     index2u = Draw::Atoi(a[8]);
1040     index1v = Draw::Atoi(a[9]);
1041     index2v = Draw::Atoi(a[10]);
1042   }
1043   else {
1044     index1u = 2;
1045     index2u = GBs->NbUPoles()-1;
1046     index1v = 2;
1047     index2v = GBs->NbVPoles()-1;
1048   }
1049
1050   gp_Pnt p;
1051   GBs->D0(u, v, p);
1052   p.SetCoord(p.X()+dx, p.Y()+dy, p.Z()+dz);
1053   GBs->MovePoint(u, v, p, index1u, index2u, index1v, index2v, fmodifu, lmodifu, fmodifv, lmodifv);
1054   Draw::Repaint();
1055   return 0;
1056 }
1057
1058
1059 //=======================================================================
1060 //function : insertknot
1061 //purpose  : 
1062 //=======================================================================
1063
1064 static Standard_Integer insertknot (Draw_Interpretor& , Standard_Integer n, const char** a)
1065 {
1066   if (n < 3) return 1;
1067
1068   Handle(Geom_BSplineSurface) GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1069
1070   if (GBs.IsNull()) return 1;
1071
1072   Standard_Real    knot=0;
1073   Standard_Integer mult = 0;
1074   Standard_Integer index=0;
1075   if (  !strcasecmp(a[0],"insertuknot") ||
1076         !strcasecmp(a[0],"insertvknot")   ) {
1077     if (n<4) return 1;
1078     knot = Draw::Atof(a[2]);
1079     mult = Draw::Atoi(a[3]);
1080   }
1081   else if (  !strcasecmp(a[0],"remuknot") ||
1082              !strcasecmp(a[0],"remvknot")   ) {
1083     index = Draw::Atoi(a[2]);
1084     if (n>=4) mult  = Draw::Atoi(a[3]);
1085   }
1086
1087   Standard_Real tol = RealLast();
1088
1089   if (!strcasecmp(a[0],"insertuknot")) {
1090     GBs->InsertUKnot(knot,mult,Precision::PConfusion());
1091   }
1092   else if (!strcasecmp(a[0],"insertvknot")) {
1093     GBs->InsertVKnot(knot,mult,Precision::PConfusion());
1094   }
1095   else if (!strcasecmp(a[0],"remuknot")) {
1096     if (n>=5) tol = Draw::Atof(a[4]);
1097     if (!GBs->RemoveUKnot(index,mult,tol)) 
1098       return 1;
1099   }
1100   else if (!strcasecmp(a[0],"remvknot")) {
1101     if (n>=5) tol = Draw::Atof(a[4]);
1102     if (!GBs->RemoveVKnot(index,mult,tol))
1103       return 1;
1104   }
1105
1106   Draw::Repaint();
1107   return 0;
1108 }
1109
1110 //=======================================================================
1111 //function : incdegree
1112 //purpose  : 
1113 //=======================================================================
1114
1115 static Standard_Integer incdegree (Draw_Interpretor& di, Standard_Integer n, const char** a)
1116 {
1117   if (n < 3) return 1;
1118   
1119   Standard_Integer NewDeg = Draw::Atoi(a[2]);
1120   Standard_Boolean BSpline = Standard_False;
1121   
1122   Standard_Integer UDeg=0, VDeg=0;
1123   
1124   Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[1]);
1125   Handle(Geom_BSplineSurface) GBs;
1126   
1127   if (GBz.IsNull()) {
1128     GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1129     if (GBs.IsNull())
1130       return 1;
1131     BSpline = Standard_True;
1132   }
1133   
1134   Standard_Integer Degree=0;
1135   if ( !strcasecmp(a[0],"incudeg")) {
1136     UDeg = NewDeg;
1137     if (BSpline) {
1138       Degree = GBs->UDegree();
1139       VDeg   = GBs->VDegree();
1140     }
1141     else {
1142       Degree = GBz->UDegree();
1143       VDeg   = GBz->VDegree();
1144     }
1145   }  
1146   else if ( !strcasecmp(a[0],"incvdeg")) {
1147     VDeg = NewDeg;
1148     if (BSpline) {
1149       Degree = GBs->VDegree();
1150       UDeg   = GBs->UDegree();
1151     }
1152     else {
1153       Degree = GBz->VDegree();
1154       UDeg   = GBz->UDegree();
1155     }
1156   }
1157   
1158   if (Degree > NewDeg) {
1159     di<<"The Degree must be greater than " << Degree <<"\n";
1160     return 1;
1161   }
1162   
1163   if ( BSpline) {
1164     GBs->IncreaseDegree(UDeg, VDeg);
1165   }
1166   else {
1167     GBz->Increase(UDeg, VDeg);
1168   }
1169
1170   Draw::Repaint();
1171   return 0;
1172 }
1173
1174 //=======================================================================
1175 //function : rempole
1176 //purpose  : 
1177 //=======================================================================
1178
1179 static Standard_Integer rempole (Draw_Interpretor& di, Standard_Integer n, const char** a)
1180 {
1181   if (n < 3) return 1;
1182   
1183   Standard_Integer NewIndex = Draw::Atoi(a[2]);
1184   Standard_Boolean BSpline  = Standard_False;
1185   
1186   Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[1]);
1187   Handle(Geom_BSplineSurface) GBs;
1188   
1189   if (GBz.IsNull()) {
1190     GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1191     if (GBs.IsNull())
1192       return 1;
1193     BSpline = Standard_True;
1194   }
1195   
1196   if ( !strcasecmp(a[0],"remrowpole")) {
1197     if ( BSpline) {
1198       di << " Error : Cannot remove a polerow on a BSplineSurface \n";
1199     }
1200     else {
1201       GBz->RemovePoleRow(NewIndex);
1202     }
1203   }
1204   else if ( !strcasecmp(a[0],"remcolpole")) {
1205     if ( BSpline) {
1206       di << " Error : Cannot remove a polecol on a BSplineSurface \n";
1207     }
1208     else {
1209       GBz->RemovePoleCol(NewIndex);
1210     }
1211   }
1212
1213   Draw::Repaint();
1214   return 0;
1215 }
1216
1217 //=======================================================================
1218 //function : sfindp
1219 //purpose  : 
1220 //=======================================================================
1221
1222 static Standard_Integer sfindp (Draw_Interpretor& , Standard_Integer n, const char** a)
1223 {
1224   if (n < 7) return 1;
1225   Standard_Boolean BSpline = Standard_False;
1226
1227   Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[1]);
1228   Handle(Geom_BSplineSurface) GBs;
1229   if (GBz.IsNull()) {
1230     GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1231     if (GBs.IsNull())
1232     {
1233       return 1;
1234     }
1235     BSpline = Standard_True;
1236   }
1237
1238   Standard_Integer UIndex = 0;
1239   Standard_Integer VIndex = 0;
1240   Standard_Integer view = Draw::Atoi(a[2]);
1241   Standard_Real x = Draw::Atof(a[3]);
1242   Standard_Real y = Draw::Atof(a[4]);
1243
1244   Draw_Display d = dout.MakeDisplay(view);
1245   
1246   if( !BSpline) {
1247     Handle(DrawTrSurf_BezierSurface) DBz = 
1248       new DrawTrSurf_BezierSurface(GBz);
1249     DBz->FindPole( x, y, d, 5, UIndex,VIndex);
1250   }
1251   else {
1252     Handle(DrawTrSurf_BSplineSurface) DBs = 
1253       new DrawTrSurf_BSplineSurface(GBs);
1254     DBs->FindPole( x, y, d, 5, UIndex,VIndex);
1255   }
1256
1257   Draw::Set(a[5],UIndex);
1258   Draw::Set(a[6],VIndex);
1259   
1260   return 0;
1261 }
1262
1263
1264 //=======================================================================
1265 //function : ssetperiodic
1266 //purpose  : 
1267 //=======================================================================
1268
1269 static Standard_Integer ssetperiodic (Draw_Interpretor& , Standard_Integer n, const char** a)
1270 {
1271   if (n < 2) return 1;
1272
1273   Standard_Integer i;
1274
1275   if (!strcasecmp(a[0],"setuperiodic")) {
1276     for (i = 1; i < n; i++) {
1277       Handle(Geom_BSplineSurface) 
1278         GBs = DrawTrSurf::GetBSplineSurface(a[i]);
1279       if (!GBs.IsNull()) {
1280         GBs->SetUPeriodic();
1281         Draw::Repaint();
1282       }
1283     }
1284   }
1285   else if (!strcasecmp(a[0],"setvperiodic")){
1286     for (i = 1; i < n; i++) {
1287       Handle(Geom_BSplineSurface) 
1288         GBs = DrawTrSurf::GetBSplineSurface(a[i]);
1289       if (!GBs.IsNull()) {
1290         GBs->SetVPeriodic();
1291         Draw::Repaint();
1292       }
1293     }
1294   }
1295   else if (!strcasecmp(a[0],"setunotperiodic")){
1296     for (i = 1; i < n; i++) {
1297       Handle(Geom_BSplineSurface) 
1298         GBs = DrawTrSurf::GetBSplineSurface(a[i]);
1299       if (!GBs.IsNull()) {
1300         GBs->SetUNotPeriodic();
1301         Draw::Repaint();
1302       }
1303     }
1304   }
1305   else if (!strcasecmp(a[0],"setvnotperiodic")){
1306     for (i = 1; i < n; i++) {
1307       Handle(Geom_BSplineSurface) 
1308         GBs = DrawTrSurf::GetBSplineSurface(a[i]);
1309       if (!GBs.IsNull()) {
1310         GBs->SetVNotPeriodic();
1311         Draw::Repaint();
1312       }
1313     }
1314   }
1315   return 0;
1316 }
1317
1318 //=======================================================================
1319 //function : exchuv
1320 //purpose  : 
1321 //=======================================================================
1322
1323 static Standard_Integer exchuv (Draw_Interpretor& , Standard_Integer n, const char** a)
1324 {
1325   if (n < 2) return 1;
1326
1327   Standard_Integer i;
1328   for (i = 1; i < n; i++) {
1329
1330     Handle(Geom_BSplineSurface) GBs = DrawTrSurf::GetBSplineSurface(a[i]);
1331     if (!GBs.IsNull()) {
1332       GBs->ExchangeUV();
1333       Draw::Repaint();
1334     }
1335     else {
1336       Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[i]);
1337       if (!GBz.IsNull()) {
1338         GBz->ExchangeUV();
1339         Draw::Repaint();
1340       }
1341     }
1342   }
1343
1344   return 0;
1345 }
1346
1347 //=======================================================================
1348 //function : segsur
1349 //purpose  : 
1350 //=======================================================================
1351
1352 static Standard_Integer segsur (Draw_Interpretor& , Standard_Integer n, const char** a)
1353 {
1354   if (n < 6) return 1;
1355
1356   Handle(Geom_BezierSurface) GBz = DrawTrSurf::GetBezierSurface(a[1]);
1357   Handle(Geom_BSplineSurface) GBs;
1358   if (GBz.IsNull()) {
1359     GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1360     if (GBs.IsNull())
1361       return 1;
1362     GBs->Segment(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5])); 
1363   }
1364   else {
1365     GBz->Segment(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
1366   }
1367
1368   Draw::Repaint();
1369   return 0;
1370 }
1371
1372 static Standard_Integer compBsplSur (Draw_Interpretor& , Standard_Integer n, const char** a)
1373 {
1374   if (n < 2) 
1375   {
1376     cout<<"Invalid number of parameters"<<endl;
1377     return 1;
1378   }
1379
1380   Handle(Geom_BSplineSurface) GBs1 = DrawTrSurf::GetBSplineSurface(a[1]);
1381   Handle(Geom_BSplineSurface) GBs2 = DrawTrSurf::GetBSplineSurface(a[2]);
1382   if (GBs1.IsNull() || GBs2.IsNull()) {
1383     cout<<"Invalid surface"<<endl;
1384     return 1;
1385   }
1386    
1387   Standard_Real aU11,aU12,aV11,aV12;
1388   GBs1->Bounds(aU11,aU12,aV11,aV12);
1389   
1390   Standard_Real aU21,aU22,aV21,aV22;
1391   GBs2->Bounds(aU21,aU22,aV21,aV22);
1392   
1393   Standard_Real aUmin = Max(aU11,aU21);
1394   Standard_Real aUmax = Min(aU12,aU22);
1395   
1396   Standard_Real aVmin = Max(aV11,aV21);
1397   Standard_Real aVmax = Min(aV12,aV22);
1398   
1399   Standard_Integer nbP = 100;
1400   Standard_Real aStepU = (aUmax - aUmin)/nbP;
1401   Standard_Real aStepV = (aVmax - aVmin)/nbP;
1402   Standard_Integer nbErr =0;
1403   Standard_Integer i =1;
1404   for( ; i <= nbP +1; i++)
1405   {
1406     Standard_Real aU = aUmin + aStepU*(i-1);
1407     Standard_Integer j =1;
1408     for( ; j <= nbP +1; j++)
1409     {
1410       Standard_Real aV = aVmin + aStepV*(j-1);
1411       gp_Pnt aP1 = GBs1->Value(aU,aV);
1412       gp_Pnt aP2 = GBs2->Value(aU,aV);
1413       Standard_Real aDist = aP1.SquareDistance(aP2);
1414       if(aDist > Precision::SquareConfusion())
1415       {
1416         nbErr++;
1417         Standard_Real aD = sqrt(aDist);
1418         cout<<"Surfaces differ for U,V,Dist: "<<aU<<" "<<aV<<" "<<aD<<endl;
1419       }
1420     }
1421   }
1422   
1423   
1424   Draw::Repaint();
1425   return 0;
1426 }
1427
1428 //=======================================================================
1429 //function : setuvorigin
1430 //purpose  : 
1431 //=======================================================================
1432
1433 static Standard_Integer setuvorigin (Draw_Interpretor& , Standard_Integer n, const char** a)
1434 {
1435   if (n < 3) return 1;
1436
1437   Handle(Geom_BSplineSurface) GBs = DrawTrSurf::GetBSplineSurface(a[1]);
1438   if (GBs.IsNull())
1439     return 1;
1440   if ( !strcasecmp(a[0],"setuorigin")) {
1441     GBs->SetUOrigin(Draw::Atoi(a[2])); 
1442   }
1443   else if ( !strcasecmp(a[0],"setvorigin")) {
1444     GBs->SetVOrigin(Draw::Atoi(a[2])); 
1445   }
1446   else 
1447     return 1;
1448
1449   Draw::Repaint();
1450   return 0;
1451 }
1452
1453
1454 //=======================================================================
1455 //function : parameters
1456 //purpose  : 
1457 //=======================================================================
1458
1459 static Standard_Integer parameters (Draw_Interpretor& di, Standard_Integer n, const char** a)
1460 {
1461   if(n == 8)
1462     { 
1463       // try to find parameters on a Surface
1464       Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[1]);
1465       if( S.IsNull() ) { di << "Unknown surface\n"; return 1; }
1466       gp_Pnt P(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
1467       Standard_Real Tol = Draw::Atof(a[5]), U = 0., V = 0.;
1468       Standard_Boolean res = GeomLib_Tool::Parameters(S,P,Tol,U,V);
1469
1470       Draw::Set(a[6],U);
1471       Draw::Set(a[7],V);
1472
1473       if( !res ) { di << "Wrong point\n"; return 1; }
1474     }
1475   else if(n == 7)
1476     {
1477       // try to find parameters on a 3d Curve
1478       Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[1]);
1479       if( C.IsNull() ) { di << "Unknown curve\n"; return 1; }
1480       gp_Pnt P(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
1481       Standard_Real Tol = Draw::Atof(a[5]), U = 0.;
1482       Standard_Boolean res = GeomLib_Tool::Parameter(C,P,Tol,U);
1483     
1484       Draw::Set(a[6],U);
1485
1486     if( !res ) { di << "Wrong point\n"; return 1; }
1487     }
1488   else if(n == 6)
1489     {
1490       // try to find parameters on a 2d Curve
1491       Handle(Geom2d_Curve) C = DrawTrSurf::GetCurve2d(a[1]);
1492       if( C.IsNull() ) { di << "Unknown curve 2d\n";  return 1; }
1493       gp_Pnt2d P(Draw::Atof(a[2]), Draw::Atof(a[3]));
1494       Standard_Real Tol = Draw::Atof(a[4]), U = 0.;
1495       Standard_Boolean res = GeomLib_Tool::Parameter(C,P,Tol,U);
1496     
1497       Draw::Set(a[5],U);
1498
1499       if( !res ) { di << "Wrong point\n"; return 1; }
1500     }
1501   else
1502     {
1503       di << "Invalid parameters!\n";
1504       di << "Usage:\n";
1505       di << "parameters Surf X Y Z Tol U V\n";
1506       di << "parameters Curv X Y Z Tol U\n";
1507       di << "parameters Curv2d X Y Tol U\n";
1508       return 1;
1509     }
1510
1511   return 0;
1512 }
1513
1514
1515 //=======================================================================
1516 //function : bounds
1517 //purpose  : 
1518 //=======================================================================
1519
1520 Standard_Integer bounds(Draw_Interpretor&, Standard_Integer n, const char** a)
1521 {
1522   Standard_Real U1, U2, V1, V2;
1523   if ( n == 4) {  // compute on a curve or a 2d curve
1524     Handle(Geom_Curve) C3d = DrawTrSurf::GetCurve(a[1]);
1525     if ( C3d.IsNull()) { // 2dcurve
1526       Handle(Geom2d_Curve) C2d = DrawTrSurf::GetCurve2d(a[1]);
1527       if ( C2d.IsNull()) return 1;
1528       U1 = C2d->FirstParameter();
1529       U2 = C2d->LastParameter();
1530     }
1531     else { // 3dcurve
1532       U1 = C3d->FirstParameter();
1533       U2 = C3d->LastParameter();
1534     }
1535     Draw::Set(a[2],U1);
1536     Draw::Set(a[3],U2);
1537   }
1538   else if ( n == 6) { // compute on a Surface
1539     Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[1]);
1540     if ( S.IsNull()) return 1;
1541     S->Bounds(U1,U2,V1,V2);
1542
1543     Draw::Set(a[2],U1);
1544     Draw::Set(a[3],U2);
1545     Draw::Set(a[4],V1);
1546     Draw::Set(a[5],V2);
1547   }
1548
1549   return 0;
1550 }
1551
1552 //=======================================================================
1553 //function : SurfaceCommands
1554 //purpose  : 
1555 //=======================================================================
1556
1557
1558 void  GeomliteTest::SurfaceCommands(Draw_Interpretor& theCommands)
1559 {
1560   static Standard_Boolean loaded = Standard_False;
1561   if (loaded) return;
1562   loaded = Standard_True;
1563
1564   DrawTrSurf::BasicCommands(theCommands);
1565
1566   const char* g;
1567   // analytic surfaces
1568   g = "GEOMETRY surfaces creation";
1569
1570   theCommands.Add("plane",
1571                   "plane name [x y z [dx dy dz [ux uy uz]]]",
1572                   __FILE__,
1573                   anasurface,g);
1574
1575   theCommands.Add("cone",
1576                   "cone name [x y z [dx dy dz [ux uy uz]]] semi-angle radius",
1577                   __FILE__,
1578                   anasurface,g);
1579
1580   theCommands.Add("cylinder",
1581                   "cylinder name [x y z [dx dy dz [ux uy uz]]]  radius",
1582                   __FILE__,
1583                   anasurface,g);
1584
1585   theCommands.Add("sphere",
1586                   "sphere name [x y z [dx dy dz [ux uy uz]]]  radius",
1587                   __FILE__,
1588                   anasurface,g);
1589
1590   theCommands.Add("torus",
1591                   "torus name [x y z [dx dy dz [ux uy uz]]]  major minor",
1592                   __FILE__,
1593                   anasurface,g);
1594
1595   theCommands.Add("beziersurf",
1596                   "beziersurf name nbupoles nbvpoles pole, [weight]",
1597                   __FILE__,
1598                   polesurface,g);
1599
1600   theCommands.Add("bsplinesurf",
1601                   "bsplinesurf name udegree nbuknots  uknot, umult  vdegree nbvknots vknot, vmult pole, weight",
1602                   __FILE__,
1603                   polesurface,g);
1604
1605   theCommands.Add("upbsplinesurf",
1606                   "bsplinesurf name udegree nbuknots  uknot, umult  vdegree nbvknots vknot, vmult pole, weight",
1607                   __FILE__,
1608                   polesurface,g);
1609
1610   theCommands.Add("vpbsplinesurf",
1611                   "bsplinesurf name udegree nbuknots  uknot, umult  vdegree nbvknots vknot, vmult pole, weight",
1612                   __FILE__,
1613                   polesurface,g);
1614
1615   theCommands.Add("uvpbsplinesurf",
1616                   "bsplinesurf name udegree nbuknots  uknot, umult  vdegree nbvknots vknot, vmult pole, weight",
1617                   __FILE__,
1618                   polesurface,g);
1619
1620   theCommands.Add("extsurf",
1621                   "extsurf name curvename dx dy dz",
1622                   __FILE__,
1623                   algosurface,g);
1624
1625   theCommands.Add("revsurf",
1626                   "revsurf name curvename x y z dx dy dz",
1627                   __FILE__,
1628                   algosurface,g);
1629
1630   theCommands.Add("offset",
1631                   "offset name basename distance [dx dy dz]",
1632                   __FILE__,
1633                   offseting,g);
1634
1635   theCommands.Add("trim",
1636                   "trim newname name [u1 u2 [v1 v2]], no args remove trim",
1637                   __FILE__,
1638                   trimming,g);
1639
1640   theCommands.Add("trimu",
1641                   "trim newname name u1 u2",
1642                   __FILE__,
1643                   trimming,g);
1644
1645   theCommands.Add("trimv",
1646                   "trim newname name v1 v2",
1647                   __FILE__,
1648                   trimming,g);
1649
1650   theCommands.Add("convert",
1651                   "convert result c2d/c3d/surf [qa,c1,s1,s2,s3,s4,po]",
1652                   __FILE__,
1653                   converting,g);
1654
1655   theCommands.Add("tobezier",
1656                   "tobezier result c2d/c3d/surf [ufirst, ulast / ufirst, ulast, vfirst, vlast]",
1657                   __FILE__,
1658                   tobezier,g);
1659
1660   theCommands.Add("convertfrombezier",
1661                   "convertfrombezier result nbu [nbv] bz1 [bz2 .... bzn] [tol]",
1662                   __FILE__,
1663                   convbz,g);
1664
1665   theCommands.Add("approxsurf",
1666                   "approxsurf name surf [Tol [CnU CnV [degU degV [nmax]]]] ",
1667                   __FILE__,
1668                   approxsurf,g);
1669
1670   g = "GEOMETRY Curves and Surfaces modification";
1671
1672   theCommands.Add("ureverse",
1673                   "ureverse name ... ",
1674                   __FILE__,
1675                   sreverse,g);
1676
1677   theCommands.Add("vreverse",
1678                   "vreverse name ... ",
1679                   __FILE__,
1680                   sreverse,g);
1681
1682   theCommands.Add("movep",
1683                   "movep name row col dx dy dz",
1684                   __FILE__,
1685                   movepole,g);
1686
1687   theCommands.Add("moverowp",
1688                   "moverowp name row dx dy dz",
1689                   __FILE__,
1690                   movepole,g);
1691
1692   theCommands.Add("movecolp",
1693                   "movecolp name col dx dy dz",
1694                   __FILE__,
1695                   movepole,g);
1696
1697   theCommands.Add("movepoint",
1698                   "movepoint name u v dx dy dz [index1u index2u index2v index2v",
1699                   __FILE__,
1700                   movepoint,g);
1701
1702   theCommands.Add("insertuknot",
1703                   "insertuknot name knot mult",
1704                   __FILE__,
1705                   insertknot,g);
1706
1707   theCommands.Add("insertvknot",
1708                   "insertvknot name knot mult",
1709                   __FILE__,
1710                   insertknot,g);
1711
1712   theCommands.Add("remuknot",
1713                   "remuknot name index [mult] [tol]",
1714                   __FILE__,
1715                   insertknot,g);
1716   
1717   theCommands.Add("remvknot",
1718                   "remvknot name index [mult] [tol]",
1719                   __FILE__,
1720                   insertknot,g);
1721
1722   theCommands.Add("incudeg",
1723                   "incudeg name degree",
1724                   __FILE__,
1725                   incdegree,g);
1726
1727   theCommands.Add("incvdeg",
1728                   "incvdeg name degree",
1729                   __FILE__,
1730                   incdegree,g);
1731
1732   theCommands.Add("remrowpole",
1733                   "remrowpole name index",
1734                   __FILE__,
1735                   rempole,g);
1736
1737   theCommands.Add("remcolpole",
1738                   "remcolpole name index",
1739                   __FILE__,
1740                   rempole,g);
1741
1742   theCommands.Add("sfindp",
1743                   "sfindp name view x y Uindex Vindex",
1744                   __FILE__,
1745                   sfindp,g);
1746
1747   theCommands.Add("setuperiodic",
1748                   "setuperiodic name ...",
1749                   __FILE__,
1750                   ssetperiodic,g);
1751
1752   theCommands.Add("setvperiodic",
1753                   "setvperiodic name ...",
1754                   __FILE__,
1755                   ssetperiodic,g);
1756
1757   theCommands.Add("setunotperiodic",
1758                   "setunotperiodic name ...",
1759                   __FILE__,
1760                   ssetperiodic,g);
1761
1762   theCommands.Add("setvnotperiodic",
1763                   "setvnotperiodic name ...",
1764                   __FILE__,
1765                   ssetperiodic,g);
1766
1767   theCommands.Add("exchuv",
1768                   "exchuv name ...",
1769                   __FILE__,
1770                   exchuv,g);
1771
1772   theCommands.Add("segsur",
1773                   "segsur name Ufirst Ulast Vfirst Vlast",
1774                   __FILE__,
1775                   segsur , g);
1776
1777   theCommands.Add("setuorigin",
1778                   "setuorigin name knotindex",
1779                   __FILE__,
1780                   setuvorigin , g);
1781
1782   theCommands.Add("setvorigin",
1783                   "setvorigin name knotindex",
1784                   __FILE__,
1785                   setuvorigin , g);
1786
1787   g = "GEOMETRY curves creation";
1788
1789
1790   theCommands.Add("uiso",
1791                   "uiso curvename surfacename u",
1792                   __FILE__,
1793                   iso,g);
1794
1795   theCommands.Add("viso",
1796                   "viso curvename surfacename v",
1797                   __FILE__,
1798                   iso,g);
1799
1800
1801   g = "GEOMETRY curves and surfaces analysis";
1802
1803   theCommands.Add("svalue",
1804                   "svalue surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]",
1805                   __FILE__,
1806                   value,g);
1807
1808   theCommands.Add("parameters",
1809                   "parameters surf/curve X Y [Z] Tol U [V] : {X Y Z} point, {U V} output parameter(s)",
1810                   __FILE__,
1811                   parameters,g);
1812
1813   theCommands.Add("bounds",
1814                   "bounds S/C/C2d U1 U2 [V1 V2]",
1815                   __FILE__,
1816                   bounds,g);
1817
1818   theCommands.Add("surface_radius",
1819                   "surface_radius surface Uvalue <Real> Vvalue <Real> returns min max radius of curvature",
1820                   __FILE__,
1821                   surface_radius,g);
1822   theCommands.Add("compBsplSur","BsplSurf1 BSplSurf2",__FILE__,compBsplSur,g);
1823   
1824   
1825 }