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