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