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