426d8d798100e1f46fc41c1bae112ade16128cc7
[occt.git] / src / GeomliteTest / GeomliteTest_CurveCommands.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 // Modified by xab, Tue Mar 11 18:31:18 1997
18 // Modified by PMN 14/04/97 : Passage a Geomlite
19 // Modified by JPI 01/08/97 : ajout de la commande approxcurve
20
21 #include <GeomliteTest.hxx>
22 #include <Draw_Appli.hxx>
23 #include <DrawTrSurf.hxx>
24 #include <DrawTrSurf_Curve.hxx>
25 #include <DrawTrSurf_Curve2d.hxx>
26 #include <DrawTrSurf_BezierCurve.hxx>
27 #include <DrawTrSurf_BSplineCurve.hxx>
28 #include <DrawTrSurf_BezierCurve2d.hxx>
29 #include <DrawTrSurf_BSplineCurve2d.hxx>
30 #include <Draw_Marker3D.hxx>
31 #include <Draw_Marker2D.hxx>
32 #include <Draw.hxx>
33 #include <Draw_Interpretor.hxx>
34 #include <Draw_Color.hxx>
35 #include <Draw_Display.hxx>
36
37 #include <BSplCLib.hxx>
38
39 #include <gp.hxx>
40 #include <gp_Pln.hxx>
41 #include <gp_Parab2d.hxx>
42 #include <gp_Elips2d.hxx>
43 #include <gp_Hypr2d.hxx>
44
45 #include <Geom_Line.hxx>
46 #include <Geom_Circle.hxx>
47 #include <Geom_Ellipse.hxx>
48 #include <Geom_Parabola.hxx>
49 #include <Geom_Hyperbola.hxx>
50 #include <Geom_BezierCurve.hxx>
51 #include <Geom_BSplineCurve.hxx>
52 #include <GeomAdaptor_Surface.hxx>
53 #include <GeomAdaptor_HSurface.hxx>
54
55 #include <GeomLib.hxx>
56 #include <GeomConvert.hxx>
57 #include <Geom2dConvert.hxx>
58
59 #include <Geom2d_Line.hxx>
60 #include <Geom2d_Circle.hxx>
61 #include <Geom2d_Ellipse.hxx>
62 #include <Geom2d_Parabola.hxx>
63 #include <Geom2d_Hyperbola.hxx>
64 #include <Geom2d_BezierCurve.hxx>
65 #include <Geom2d_BSplineCurve.hxx>
66
67 #include <GeomLProp.hxx>
68 #include <GeomLProp_CLProps.hxx>
69 #include <Geom2dLProp_CLProps2d.hxx>
70 #include <Geom2dLProp_CurAndInf2d.hxx>
71
72 #include <TColgp_Array1OfPnt.hxx>
73 #include <TColgp_Array1OfPnt2d.hxx>
74 #include <TColStd_Array1OfReal.hxx>
75 #include <TColStd_Array1OfInteger.hxx>
76
77 #include <GeomAbs_SurfaceType.hxx>
78 #include <GeomAbs_CurveType.hxx>
79
80 #include <Precision.hxx>
81
82 #include <stdio.h>
83
84 #include <TColStd_HArray1OfReal.hxx>
85 #include <TColStd_HArray2OfReal.hxx>
86 #include <TColStd_HArray1OfInteger.hxx>
87 #include <TColStd_Array1OfReal.hxx>
88 #include <TColStd_Array1OfInteger.hxx>
89
90 #include <TColGeom_HArray1OfBSplineCurve.hxx>
91 #include <TColGeom2d_HArray1OfBSplineCurve.hxx>
92 #include <Convert_CompPolynomialToPoles.hxx>
93 #include <CPnts_AbscissaPoint.hxx>
94 #include <GCPnts_AbscissaPoint.hxx>
95
96 #include <PLib.hxx> 
97 #include <GeomAbs_Shape.hxx>
98 #include <Geom_Curve.hxx>
99 #include <GeomConvert.hxx>
100 #include <GeomConvert_ApproxCurve.hxx>
101 #include <Geom2dConvert_ApproxCurve.hxx>
102 #include <Geom2d_Curve.hxx>
103
104 #include <GeomAdaptor_HCurve.hxx>
105 #include <GeomAdaptor_Curve.hxx>
106 #include <Geom2dAdaptor_HCurve.hxx>
107 #include <GeomAdaptor_HCurve.hxx>
108 #include <Approx_CurvilinearParameter.hxx>
109 #include <Approx_CurveOnSurface.hxx>
110 #include <Geom_BSplineSurface.hxx>
111
112 #include <AppCont_Function.hxx>
113 #include <Adaptor3d_HCurve.hxx>
114 #include <GeomAdaptor_HCurve.hxx>
115 #include <Approx_FitAndDivide.hxx>
116 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
117
118 #ifdef _WIN32
119 Standard_IMPORT Draw_Viewer dout;
120 #endif
121
122 //Class is used in fitcurve
123 class CurveEvaluator : public AppCont_Function
124
125 {
126
127 public:
128   Handle(Adaptor3d_HCurve) myCurve;
129
130   CurveEvaluator(const Handle(Adaptor3d_HCurve)& C)
131     : myCurve(C)
132   {
133     myNbPnt = 1;
134     myNbPnt2d = 0;
135   }
136
137   Standard_Real FirstParameter() const
138   {
139     return myCurve->FirstParameter();
140   }
141
142   Standard_Real LastParameter() const
143   {
144     return myCurve->LastParameter();
145   }
146
147   Standard_Boolean Value(const Standard_Real   theT,
148     NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
149     NCollection_Array1<gp_Pnt>&   thePnt) const
150   {
151     thePnt(1) = myCurve->Value(theT);
152     return Standard_True;
153   }
154
155   Standard_Boolean D1(const Standard_Real   theT,
156     NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
157     NCollection_Array1<gp_Vec>&   theVec) const
158   {
159     gp_Pnt aDummyPnt;
160     myCurve->D1(theT, aDummyPnt, theVec(1));
161     return Standard_True;
162   }
163 };
164
165
166 //=======================================================================
167 //function : anacurve
168 //purpose  : 
169 //=======================================================================
170
171 static Standard_Integer anacurve (Draw_Interpretor& , Standard_Integer n, const char** a)
172 {
173   if (n < 5) return 1;
174
175   Handle(Geom_Geometry) result;
176   Handle(Geom2d_Curve)  result2d;
177
178   if (!strcmp(a[0],"line")) {
179     if (n == 6)
180       result2d = new Geom2d_Line(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
181                                  gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5])));
182     else if (n == 8)
183       result = new Geom_Line(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
184                              gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])));
185     else
186       return 1;
187   }
188
189   else if (!strcmp(a[0],"circle")) {
190     if (n == 5)
191       result2d = 
192         new Geom2d_Circle(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
193                                    gp_Dir2d(1,0)),
194                           Draw::Atof(a[4]));
195     else if (n == 6)
196       result = 
197         new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
198                                gp_Dir(0,0,1)),
199                         Draw::Atof(a[5]));
200     else if (n == 7)
201       result2d =
202         new Geom2d_Circle(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
203                                    gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5]))),
204                           Draw::Atof(a[6]));
205     else if (n == 9)
206       result = 
207         new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
208                                gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7]))),
209                         Draw::Atof(a[8]));
210     else if (n == 12)
211       result = 
212         new Geom_Circle(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
213                                gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
214                                gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10]))),
215                         Draw::Atof(a[11]));
216     else
217       return 1;
218   }
219   
220   else if (!strcmp(a[0],"parabola")) {
221     if (n == 5)
222       result2d = 
223         new Geom2d_Parabola(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
224                                      gp_Dir2d(1,0)),
225                             Draw::Atof(a[4]));
226     else if (n == 6)
227       result = 
228         new Geom_Parabola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
229                                  gp_Dir(0,0,1)),
230                           Draw::Atof(a[5]));
231     else if (n == 7)
232       result2d = 
233         new Geom2d_Parabola(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
234                                      gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5]))),
235                             Draw::Atof(a[6]));
236     else if (n == 9)
237       result = 
238         new Geom_Parabola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
239                                  gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7]))),
240                           Draw::Atof(a[8]));
241     else if (n == 12)
242       result = 
243         new Geom_Parabola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
244                                  gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
245                                  gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10]))),
246                           Draw::Atof(a[11]));
247     else
248       return 1;
249   }
250   
251   else if (!strcmp(a[0],"ellipse")) {
252     if (n == 6)
253       result2d = 
254         new Geom2d_Ellipse(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
255                                     gp_Dir2d(1,0)),
256                            Draw::Atof(a[4]),Draw::Atof(a[5]));
257     else if (n == 7)
258       result = 
259         new Geom_Ellipse(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
260                                 gp_Dir(0,0,1)),
261                          Draw::Atof(a[5]),Draw::Atof(a[6]));
262     else if (n == 8)
263       result2d = 
264         new Geom2d_Ellipse(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
265                                     gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5]))),
266                            Draw::Atof(a[6]), Draw::Atof(a[7]));
267     else if (n == 10)
268       result = 
269         new Geom_Ellipse(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
270                                 gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7]))),
271                          Draw::Atof(a[8]), Draw::Atof(a[9]));
272     else if (n == 13)
273       result = 
274         new Geom_Ellipse(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
275                                 gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
276                                 gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10]))),
277                          Draw::Atof(a[11]), Draw::Atof(a[12]));
278     else
279       return 1;
280   }
281   
282   else if (!strcmp(a[0],"hyperbola")) {
283     if (n == 6)
284       result2d = 
285         new Geom2d_Hyperbola(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
286                                       gp_Dir2d(1,0)),
287                              Draw::Atof(a[4]),Draw::Atof(a[5]));
288     else if (n == 7)
289       result = 
290         new Geom_Hyperbola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
291                                   gp_Dir(0,0,1)),
292                            Draw::Atof(a[5]),Draw::Atof(a[6]));
293     else if (n == 8)
294       result2d = 
295         new Geom2d_Hyperbola(gp_Ax22d(gp_Pnt2d(Draw::Atof(a[2]),Draw::Atof(a[3])),
296                                       gp_Dir2d(Draw::Atof(a[4]),Draw::Atof(a[5]))),
297                              Draw::Atof(a[6]), Draw::Atof(a[7]));
298     else if (n == 10)
299       result = 
300         new Geom_Hyperbola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
301                                   gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7]))),
302                            Draw::Atof(a[8]), Draw::Atof(a[9]));
303     else if (n == 13)
304       result = 
305         new Geom_Hyperbola(gp_Ax2(gp_Pnt(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])),
306                                   gp_Dir(Draw::Atof(a[5]),Draw::Atof(a[6]),Draw::Atof(a[7])),
307                                   gp_Dir(Draw::Atof(a[8]),Draw::Atof(a[9]),Draw::Atof(a[10]))),
308                            Draw::Atof(a[11]), Draw::Atof(a[12]));
309     else
310       return 1;
311   }
312   
313   if (!result.IsNull())
314     DrawTrSurf::Set(a[1],result);
315   else if (!result2d.IsNull())
316     DrawTrSurf::Set(a[1],result2d);
317   else
318     return 1;
319
320   return 0;
321 }
322
323 //=======================================================================
324 //function : polecurve
325 //purpose  : 
326 //=======================================================================
327
328 static Standard_Integer polecurve (Draw_Interpretor& , Standard_Integer n, const char** a)
329 {
330   Standard_Integer k,i;
331
332
333   if (n < 3) return 1;
334
335   if (!strcmp(a[0],"beziercurve")) {
336     
337     Standard_Integer np = Draw::Atoi(a[2]);
338     if (np == 0) return 1;
339     
340     i = (n - 3) / (np);
341     if (i < 3 || i > 4) return 1;
342     Standard_Boolean hasw = i == 4;
343     
344     TColgp_Array1OfPnt poles(1,np);
345     TColStd_Array1OfReal weights(1,np);
346     
347     k = 3;
348     for (i = 1; i <= np; i++) {
349       poles(i).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]),Draw::Atof(a[k+2]));
350       k += 3;
351       if (hasw) {
352         weights(i) = Draw::Atof(a[k]);
353         k++;
354       }
355     }
356     
357     Handle(Geom_BezierCurve) result;
358     if (hasw)
359       result = new Geom_BezierCurve(poles,weights);
360     else
361       result = new Geom_BezierCurve(poles);
362     
363     DrawTrSurf::Set(a[1],result);
364   }
365   
366   else if (!strcmp((*a[0] == 'p') ? a[0]+1 : a[0],"bsplinecurve")) {
367     Standard_Integer deg = Draw::Atoi(a[2]);
368     Standard_Integer nbk = Draw::Atoi(a[3]);
369
370     TColStd_Array1OfReal    knots(1, nbk);
371     TColStd_Array1OfInteger mults(1, nbk);
372     k = 4;
373     Standard_Integer Sigma = 0;
374     for (i = 1; i<=nbk; i++) {
375       knots( i) = Draw::Atof(a[k]);
376       k++;
377       mults( i) = Draw::Atoi(a[k]);
378       Sigma += mults(i);
379       k++;
380     }
381
382     Standard_Boolean periodic = *a[0] == 'p';
383     Standard_Integer np;
384     if (periodic)
385       np = Sigma - mults(nbk);
386     else
387       np = Sigma - deg  -1;
388
389     TColgp_Array1OfPnt   poles  (1, np);
390     TColStd_Array1OfReal weights(1, np);
391     
392     for (i = 1; i <= np; i++) {
393       poles(i).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]),Draw::Atof(a[k+2]));
394       k += 3;
395       weights(i) = Draw::Atof(a[k]);
396       k++;
397     }
398     
399     Handle(Geom_BSplineCurve) result =
400       new Geom_BSplineCurve(poles, weights, knots, mults, deg, periodic);
401     DrawTrSurf::Set(a[1],result);
402   }
403   
404   return 0;
405 }
406
407 //=======================================================================
408 //function : polecurve2d
409 //purpose  : 
410 //=======================================================================
411
412 static Standard_Integer polecurve2d (Draw_Interpretor& , Standard_Integer n, const char** a)
413 {
414   Standard_Integer k,i;
415
416
417   if (n < 3) return 1;
418
419   if (!strcmp(a[0],"2dbeziercurve")) {
420     
421     Standard_Integer np = Draw::Atoi(a[2]);
422     if (np == 0) return 1;
423     
424     i = (n - 2) / (np);
425     if (i < 2 || i > 3) return 1;
426     Standard_Boolean hasw = i == 3;
427     
428     TColgp_Array1OfPnt2d poles(1,np);
429     TColStd_Array1OfReal weights(1,np);
430     
431     k = 3;
432     for (i = 1; i <= np; i++) {
433       poles(i).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]));
434       k += 2;
435       if (hasw) {
436         weights(i) = Draw::Atof(a[k]);
437         k++;
438       }
439     }
440     
441     Handle(Geom2d_BezierCurve) result;
442     if (hasw)
443       result = new Geom2d_BezierCurve(poles,weights);
444     else
445       result = new Geom2d_BezierCurve(poles);
446     
447     DrawTrSurf::Set(a[1],result);
448   }
449   
450   else if (!strcmp((*(a[0]+2) == 'p') ? a[0]+3 : a[0]+2,"bsplinecurve")) {
451     Standard_Integer deg = Draw::Atoi(a[2]);
452     Standard_Integer nbk = Draw::Atoi(a[3]);
453
454     TColStd_Array1OfReal    knots(1, nbk);
455     TColStd_Array1OfInteger mults(1, nbk);
456     k = 4;
457     Standard_Integer Sigma = 0;
458     for (i = 1; i<=nbk; i++) {
459       knots( i) = Draw::Atof(a[k]);
460       k++;
461       mults( i) = Draw::Atoi(a[k]);
462       Sigma += mults(i);
463       k++;
464     }
465
466     Standard_Boolean periodic = *(a[0]+2) == 'p';
467     Standard_Integer np;
468     if (periodic)
469       np = Sigma - mults(nbk);
470     else
471       np = Sigma - deg  -1;
472
473     TColgp_Array1OfPnt2d poles  (1, np);
474     TColStd_Array1OfReal weights(1, np);
475     
476     for (i = 1; i <= np; i++) {
477       poles(i).SetCoord(Draw::Atof(a[k]),Draw::Atof(a[k+1]));
478       k += 2;
479       weights(i) = Draw::Atof(a[k]);
480       k++;
481     }
482     
483     Handle(Geom2d_BSplineCurve) result =
484       new Geom2d_BSplineCurve(poles, weights, knots, mults, deg, periodic);
485     DrawTrSurf::Set(a[1],result);
486   }
487   
488   return 0;
489 }
490
491 //=======================================================================
492 //function : reverse
493 //purpose  : 
494 //=======================================================================
495
496 static Standard_Integer reverse (Draw_Interpretor& , Standard_Integer n, const char** a)
497 {
498   if (n < 2) return 1;
499
500   Standard_Integer i;
501   for (i = 1; i < n; i++) {
502
503     Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[i]);
504     if (!GC.IsNull()) {
505       GC->Reverse();
506       Draw::Repaint();
507     }
508     Handle(Geom2d_Curve) GC2d = DrawTrSurf::GetCurve2d(a[i]);
509     if (!GC2d.IsNull()) {
510       GC2d->Reverse();
511       Draw::Repaint();
512     }
513   }
514   return 0;
515 }
516
517 //=======================================================================
518 //function : cmovepole
519 //purpose  : 
520 //=======================================================================
521
522 static Standard_Integer cmovepole (Draw_Interpretor& , Standard_Integer n, const char** a)
523 {
524   if (n < 5) return 1;
525
526   Standard_Real dx = Draw::Atof(a[3]);
527   Standard_Real dy = Draw::Atof(a[4]);
528   Standard_Real dz=0;
529   if (n >= 6) dz = Draw::Atof(a[5]);
530   Standard_Integer Index = Draw::Atoi(a[2]);
531
532   Handle(Geom_BezierCurve) G1 = DrawTrSurf::GetBezierCurve(a[1]);
533   if (!G1.IsNull()) {
534     gp_Pnt P = G1->Pole(Index);
535     P.SetCoord(P.X()+dx, P.Y()+dy, P.Z()+dz);
536     G1->SetPole(Index,P);
537     Draw::Repaint();
538     return 0;
539   }
540
541
542   Handle(Geom_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve(a[1]);
543   if (!G2.IsNull()) {
544     gp_Pnt P = G2->Pole(Index);
545     P.SetCoord(P.X()+dx, P.Y()+dy, P.Z()+dz);
546     G2->SetPole(Index,P);
547     Draw::Repaint();
548     return 0;
549   }
550
551   Handle(Geom2d_BezierCurve) G3 = DrawTrSurf::GetBezierCurve2d(a[1]);
552   if (!G3.IsNull()) {
553     gp_Pnt2d P = G3->Pole(Index);
554     P.SetCoord(P.X()+dx, P.Y()+dy);
555     G3->SetPole(Index,P);
556     Draw::Repaint();
557     return 0;
558   }
559
560
561   Handle(Geom2d_BSplineCurve) G4 = DrawTrSurf::GetBSplineCurve2d(a[1]);
562   if (!G4.IsNull()) {
563     gp_Pnt2d P = G4->Pole(Index);
564     P.SetCoord(P.X()+dx, P.Y()+dy);
565     G4->SetPole(Index,P);
566     Draw::Repaint();
567     return 0;
568   }
569
570
571
572   return 0;
573 }
574
575 //=======================================================================
576 //function : cmovetangent
577 //purpose  : 
578 //=======================================================================
579
580 static Standard_Integer cmovetangent (Draw_Interpretor& di, Standard_Integer n, const char** a)
581 {
582   Standard_Integer dimension,
583   condition,
584   error_status ;
585   Standard_Real u,
586   x,
587   y,
588   z,
589   tolerance,
590   tx,
591   ty,
592   tz ;
593   u = Draw::Atof(a[2]);
594   x = Draw::Atof(a[3]);
595   y = Draw::Atof(a[4]);
596   z = 0.0e0,
597   tolerance = 1.0e-5 ;
598   dimension = 3 ;
599   if (n <= 8) {
600     dimension = 2 ;
601     if (n < 7) {
602       return 1 ;
603     }
604   }
605   else {
606     dimension = 3 ;
607     if (n < 9) {
608       return 1 ;
609     }
610   }
611   condition = 0 ;
612   error_status  = 0 ;
613   if (dimension == 3) {
614     Handle(Geom_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve(a[1]);
615     if (!G2.IsNull()) {
616       z  = Draw::Atof(a[5]) ;
617       tx = Draw::Atof(a[6]) ;
618       ty = Draw::Atof(a[7]) ;
619       tz = Draw::Atof(a[8]) ;
620       if (n == 10) {
621         condition = Max(Draw::Atoi(a[9]), -1)  ;
622         condition = Min(condition, G2->Degree()-1) ;
623       }
624       gp_Pnt p;
625       gp_Vec tangent ;
626       p.SetCoord(x,y,z);
627       tangent.SetCoord(tx,ty,tz) ;
628       
629       G2->MovePointAndTangent(u, 
630                               p, 
631                               tangent,
632                               tolerance,
633                               condition,
634                               condition,
635                               error_status) ;
636       if (! error_status) {
637         Draw::Repaint();
638         }
639       else {
640         di << "Not enought degree of freedom increase degree please\n";
641       }
642       
643       return 0;
644     }
645   }
646   else {
647     Handle(Geom2d_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve2d(a[1]);
648     if (!G2.IsNull()) {
649       tx = Draw::Atof(a[5]) ;
650       ty = Draw::Atof(a[6]) ;
651       if (n == 8) {
652         condition = Max(Draw::Atoi(a[7]), -1)  ;
653         condition = Min(condition, G2->Degree()-1) ;
654       }
655       gp_Pnt2d p;
656       gp_Vec2d tangent ;
657       p.SetCoord(x,y);
658       tangent.SetCoord(tx,ty) ;
659       
660       G2->MovePointAndTangent(u, 
661                               p, 
662                               tangent,
663                               tolerance,
664                               condition,
665                               condition,
666                               error_status) ;
667       if (! error_status) {
668         Draw::Repaint();
669         }
670       else {
671         di << "Not enought degree of freedom increase degree please\n";
672       }
673       
674       return 0;
675     }
676    } 
677   return 0;
678 }
679
680
681 //=======================================================================
682 //function : cmovepoint
683 //purpose  : 
684 //=======================================================================
685
686 static Standard_Integer cmovepoint (Draw_Interpretor& , Standard_Integer n, const char** a)
687 {
688   if (n < 5) return 1;
689
690   Standard_Real dx = Draw::Atof(a[3]);
691   Standard_Real dy = Draw::Atof(a[4]);
692   Standard_Real dz=0;
693   if (n >= 6 && n != 7) dz = Draw::Atof(a[5]);
694   Standard_Real u = Draw::Atof(a[2]);
695   Standard_Integer index1 = 0;
696   Standard_Integer index2 = 0;
697   Standard_Integer fmodif, lmodif;
698   if (n == 7) {
699     index1 = Draw::Atoi(a[5]);
700     index2 = Draw::Atoi(a[6]);
701   }
702   else if (n == 8) {
703     index1 = Draw::Atoi(a[6]);
704     index2 = Draw::Atoi(a[7]);
705   }
706
707   Handle(Geom_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve(a[1]);
708   if (!G2.IsNull()) {
709     if (index1 == 0) {
710       index1 = 2;
711       index2 = G2->NbPoles()-1;
712     }
713     gp_Pnt p;
714     G2->D0(u, p);
715     p.SetCoord(p.X()+dx, p.Y()+dy, p.Z()+dz);
716     G2->MovePoint(u, p, index1, index2, fmodif, lmodif);
717     Draw::Repaint();
718     return 0;
719   }
720
721   Handle(Geom2d_BSplineCurve) G4 = DrawTrSurf::GetBSplineCurve2d(a[1]);
722   if (!G4.IsNull()) {
723     if (index1 == 0) {
724       index1 = 2;
725       index2 = G4->NbPoles()-1;
726     }
727     gp_Pnt2d p;
728     G4->D0(u, p);
729     p.SetCoord(p.X()+dx, p.Y()+dy);
730     G4->MovePoint(u, p, index1, index2, fmodif, lmodif);
731     Draw::Repaint();
732     return 0;
733   }
734   return 0;
735 }
736
737 //=======================================================================
738 //function : cinsertknot
739 //purpose  : 
740 //=======================================================================
741
742 static Standard_Integer cinsertknot (Draw_Interpretor& , Standard_Integer n, const char** a)
743 {
744   if (n < 4) return 1;
745
746   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
747   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
748
749   if (GBs.IsNull() && GBs2d.IsNull()) return 1;
750
751   if (n <= 4) {
752     Standard_Real    knot = Draw::Atof(a[2]);
753     Standard_Integer mult = 1;
754     if (n == 4) mult = Draw::Atoi(a[3]);
755     if (!GBs.IsNull())
756       GBs->InsertKnot(knot,mult,Precision::PConfusion());
757     else
758       GBs2d->InsertKnot(knot,mult,Precision::PConfusion());
759   }
760
761   else {
762     // multiple insertion
763     if (n % 2 != 0) return 1;
764     Standard_Integer i,nbk = (n-2) / 2;
765     TColStd_Array1OfReal    knots(1,nbk);
766     TColStd_Array1OfInteger mults(1,nbk);
767     for (i = 2; i < n; i += 2) {
768       knots(i/2) = Draw::Atof(a[i]);
769       mults(i/2) = Draw::Atoi(a[i+1]);
770     }
771
772     if (!GBs.IsNull())
773       GBs->InsertKnots(knots,mults,Precision::PConfusion());
774     else
775       GBs2d->InsertKnots(knots,mults,Precision::PConfusion());
776
777   }
778
779   Draw::Repaint();
780   return 0;
781 }
782
783 //=======================================================================
784 //function : csetknot
785 //purpose  : 
786 //=======================================================================
787
788 static Standard_Integer csetknot (Draw_Interpretor& , Standard_Integer n, const char** a)
789 {
790   if (n < 4) return 1;
791
792   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
793   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
794
795   if (GBs.IsNull() && GBs2d.IsNull()) return 1;
796
797   Standard_Integer index = Draw::Atoi(a[2]);
798   Standard_Real    knot  = Draw::Atof(a[3]);
799
800   if ( n == 4) {
801     if (!GBs.IsNull())
802       GBs->SetKnot(index,knot);
803     else
804       GBs2d->SetKnot(index,knot);
805   }
806   else {
807     Standard_Integer mult  = Draw::Atoi(a[4]);
808     if (!GBs.IsNull())
809       GBs->SetKnot(index,knot,mult);
810     else
811       GBs2d->SetKnot(index,knot,mult);
812   }
813
814   Draw::Repaint();
815   return 0;
816 }
817
818 //=======================================================================
819 //function : cremknot
820 //purpose  : 
821 //=======================================================================
822
823 static Standard_Integer cremknot (Draw_Interpretor& di, Standard_Integer n, const char** a)
824 {
825   if (n < 3) return 1;
826
827   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
828   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
829
830   if (GBs.IsNull() && GBs2d.IsNull()) return 1;
831
832   Standard_Integer index = Draw::Atoi(a[2]);
833   Standard_Integer mult  = 0;
834   if (n >= 4) mult = Draw::Atoi(a[3]);
835
836   Standard_Real tol = RealLast();
837   if (n >= 5) tol = Draw::Atof(a[4]);
838
839   if (!GBs.IsNull()) {
840     if (!GBs->RemoveKnot(index,mult,tol))
841       di << "Remove knots failed\n";
842   }
843   else {
844     if (!GBs2d->RemoveKnot(index,mult,tol))
845       di << "Remove knots failed\n";
846   }
847
848   Draw::Repaint();
849   return 0;
850 }
851
852 //=======================================================================
853 //function : increasedegree
854 //purpose  : 
855 //=======================================================================
856
857 static Standard_Integer increasedegree (Draw_Interpretor& , Standard_Integer n, const char** a)
858 {
859   if (n < 3) return 1;
860
861   Standard_Integer Deg = Draw::Atoi(a[2]);
862
863   Handle(Geom_BezierCurve) GBz = DrawTrSurf::GetBezierCurve(a[1]);
864   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
865   Handle(Geom2d_BezierCurve) GBz2d = DrawTrSurf::GetBezierCurve2d(a[1]);
866   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
867
868   if (!GBz.IsNull()) 
869     GBz->Increase(Deg);
870   else if (!GBs.IsNull())
871     GBs->IncreaseDegree(Deg);
872   else if (!GBz2d.IsNull()) 
873     GBz2d->Increase(Deg);
874   else if (!GBs2d.IsNull())
875     GBs2d->IncreaseDegree(Deg);
876   else
877     return 1;
878
879   Draw::Repaint();
880   return 0;
881 }
882
883 //=======================================================================
884 //function : removepole
885 //purpose  : 
886 //=======================================================================
887
888 static Standard_Integer removepole (Draw_Interpretor& di, Standard_Integer n, const char** a)
889 {
890   if (n < 3) return 1;
891
892   Standard_Integer Index = Draw::Atoi(a[2]);
893
894   Handle(Geom_BezierCurve)   GBZ   = DrawTrSurf::GetBezierCurve(a[1]);
895   Handle(Geom2d_BezierCurve) GBZ2d = DrawTrSurf::GetBezierCurve2d(a[1]);
896   if (!GBZ.IsNull()) {
897     GBZ->RemovePole(Index);
898   }
899   else if (!GBZ2d.IsNull()) {
900     GBZ2d->RemovePole(Index);
901   }
902   else {
903     di << "rempole needs a bezier curve";
904     return 1;
905   }
906
907   Draw::Repaint();
908   return 0;
909 }
910
911 //=======================================================================
912 //function : insertpole
913 //purpose  : 
914 //=======================================================================
915
916 static Standard_Integer insertpole (Draw_Interpretor& di, Standard_Integer n, const char** a)
917 {
918   if (n < 6) return 1;
919
920   Standard_Integer Index = Draw::Atoi(a[2]);
921
922   Handle(Geom_BezierCurve)   GBZ   = DrawTrSurf::GetBezierCurve(a[1]);
923   Handle(Geom2d_BezierCurve) GBZ2d = DrawTrSurf::GetBezierCurve2d(a[1]);
924   if (!GBZ.IsNull()) {
925     gp_Pnt P (Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
926     if ( n == 7)
927       GBZ->InsertPoleAfter(Index,P,Draw::Atof(a[6]));
928     else
929       GBZ->InsertPoleAfter(Index,P);
930   }
931   else if (!GBZ2d.IsNull()) {
932     gp_Pnt2d P (Draw::Atof(a[3]),Draw::Atof(a[4]));
933     if ( n == 6)
934       GBZ2d->InsertPoleAfter(Index,P,Draw::Atof(a[5]));
935     else
936       GBZ2d->InsertPoleAfter(Index,P);
937   }
938   else {
939     di << "insertpole needs a bezier curve";
940     return 1;
941   }
942
943   Draw::Repaint();
944   return 0;
945 }
946
947 //=======================================================================
948 //function : cfindp
949 //purpose  : 
950 //=======================================================================
951
952 static Standard_Integer cfindp (Draw_Interpretor& , Standard_Integer n, const char** a)
953 {
954   if (n < 6) return 1;
955
956   Standard_Integer Index = 0;
957   Standard_Integer view = Draw::Atoi(a[2]);
958   Standard_Real x = Draw::Atof(a[3]);
959   Standard_Real y = Draw::Atof(a[4]);
960
961   Draw_Display d = dout.MakeDisplay(view);
962
963   Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
964
965   Handle(DrawTrSurf_BezierCurve) DBz = 
966     Handle(DrawTrSurf_BezierCurve)::DownCast(D);
967   if( !DBz.IsNull())
968     DBz->FindPole( x, y, d, 5, Index);
969   else {
970     Handle(DrawTrSurf_BSplineCurve) DBs = 
971       Handle(DrawTrSurf_BSplineCurve)::DownCast(D);
972     if (!DBs.IsNull())
973       DBs->FindPole( x, y, d, 5, Index);
974     else {
975       Handle(DrawTrSurf_BezierCurve2d) DBz2d = 
976         Handle(DrawTrSurf_BezierCurve2d)::DownCast(D);
977       if( !DBz2d.IsNull())
978         DBz2d->FindPole( x, y, d, 5, Index);
979       else {
980         Handle(DrawTrSurf_BSplineCurve2d) DBs2d = 
981           Handle(DrawTrSurf_BSplineCurve2d)::DownCast(D);
982         if (!DBs2d.IsNull())
983           DBs2d->FindPole( x, y, d, 5, Index);
984         else 
985           return 1;
986       }
987     }
988   }
989   
990   Draw::Set(a[5],Index);
991   
992   return 0;
993 }
994
995
996 //=======================================================================
997 //function : csetperiodic
998 //purpose  : 
999 //=======================================================================
1000
1001 static Standard_Integer csetperiodic (Draw_Interpretor& , Standard_Integer n, const char** a)
1002 {
1003   if (n < 2) return 1;
1004
1005   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
1006   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
1007   
1008   if (GBs.IsNull() && GBs2d.IsNull()) return 1;
1009   
1010   if (!strcmp(a[0],"setperiodic")) {
1011     if (!GBs.IsNull()) 
1012       GBs->SetPeriodic();
1013     else
1014       GBs2d->SetPeriodic();
1015   }
1016   else if (!strcmp(a[0],"setnotperiodic")) {
1017     if (!GBs.IsNull()) 
1018       GBs->SetNotPeriodic();
1019     else
1020       GBs2d->SetNotPeriodic();
1021   }
1022
1023   Draw::Repaint();
1024   return 0;
1025 }
1026
1027 //=======================================================================
1028 //function : value
1029 //purpose  : 
1030 //=======================================================================
1031
1032 static Standard_Integer value (Draw_Interpretor& ,
1033                                Standard_Integer n, const char** a)
1034 {
1035   if (n < 4) return 1;
1036
1037   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
1038   if (GC.IsNull()) return 1;
1039
1040   Standard_Real U = Draw::Atof(a[2]);
1041
1042   Standard_Boolean DrawPoint = ( n%3 == 1);
1043   if ( DrawPoint) n--;
1044
1045   gp_Pnt P;
1046   if (n > 6) {
1047     if (n < 9) return 1;
1048     gp_Vec D1;
1049     if (n > 9) {
1050       if (n < 12) return 1;
1051       gp_Vec D2;
1052       GC->D2(U,P,D1,D2);
1053       Draw::Set(a[9] ,D2.X());
1054       Draw::Set(a[10],D2.Y());
1055       Draw::Set(a[11],D2.Z());
1056     }
1057     else 
1058       GC->D1(U,P,D1);
1059     Draw::Set(a[6],D1.X());
1060     Draw::Set(a[7],D1.Y());
1061     Draw::Set(a[8],D1.Z());
1062   }
1063   else 
1064     GC->D0(U,P);
1065
1066   if ( n > 3) {
1067     Draw::Set(a[3],P.X());
1068     Draw::Set(a[4],P.Y());
1069     Draw::Set(a[5],P.Z());
1070   }
1071   if ( DrawPoint) {
1072     DrawTrSurf::Set(a[n],P);
1073   }
1074   
1075   return 0;
1076 }
1077
1078
1079 //=======================================================================
1080 //function : value2d
1081 //purpose  : 
1082 //=======================================================================
1083
1084 static Standard_Integer value2d (Draw_Interpretor& , 
1085                                  Standard_Integer n, const char** a)
1086 {
1087   if (n < 4) return 1;
1088
1089   Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
1090   if (GC.IsNull()) return 1;
1091
1092   Standard_Real U = Draw::Atof(a[2]);
1093
1094   Standard_Boolean DrawPoint = ( n%2 == 0);
1095   if ( DrawPoint ) n--;
1096
1097   gp_Pnt2d P;
1098   if (n > 5) {
1099     if (n < 7) return 1;
1100     gp_Vec2d D1;
1101     if (n > 7) {
1102       if (n < 9) return 1;
1103       gp_Vec2d D2;
1104       GC->D2(U,P,D1,D2);
1105       Draw::Set(a[7] ,D2.X());
1106       Draw::Set(a[8],D2.Y());
1107     }
1108     else 
1109       GC->D1(U,P,D1);
1110     Draw::Set(a[5],D1.X());
1111     Draw::Set(a[6],D1.Y());
1112   }
1113   else 
1114     GC->D0(U,P);
1115
1116   if ( n > 3 ) {
1117     Draw::Set(a[3],P.X());
1118     Draw::Set(a[4],P.Y());
1119   }
1120   if ( DrawPoint ) {
1121     DrawTrSurf::Set(a[n], P);
1122   }
1123   
1124   return 0;
1125 }
1126
1127 //=======================================================================
1128 //function : segment
1129 //purpose  : 
1130 //=======================================================================
1131
1132 static Standard_Integer segment (Draw_Interpretor& , Standard_Integer n, const char** a)
1133 {
1134   if (n < 4) return 1;
1135
1136   Handle(Geom_BezierCurve) GBz = DrawTrSurf::GetBezierCurve(a[1]);
1137   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
1138   Handle(Geom2d_BezierCurve) GBz2d = DrawTrSurf::GetBezierCurve2d(a[1]);
1139   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
1140
1141   Standard_Real f = Draw::Atof(a[2]), l = Draw::Atof(a[3]);
1142
1143   if (!GBz.IsNull()) 
1144     GBz->Segment(f,l);
1145   else if (!GBs.IsNull())
1146     GBs->Segment(f,l);
1147   else if (!GBz2d.IsNull()) 
1148     GBz2d->Segment(f,l);
1149   else if (!GBs2d.IsNull())
1150     GBs2d->Segment(f,l);
1151   else
1152     return 1;
1153
1154   Draw::Repaint();
1155   return 0;
1156 }
1157
1158
1159 //=======================================================================
1160 //function : setorigin
1161 //purpose  : 
1162 //=======================================================================
1163
1164 static Standard_Integer setorigin (Draw_Interpretor& , Standard_Integer n, const char** a)
1165 {
1166   if (n < 3) return 1;
1167
1168   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
1169   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
1170
1171   if (!GBs.IsNull())
1172     GBs->SetOrigin(Draw::Atoi(a[2])); 
1173   if (!GBs2d.IsNull())
1174     GBs2d->SetOrigin(Draw::Atoi(a[2])); 
1175   else
1176     return 1;
1177
1178   Draw::Repaint();
1179   return 0;
1180 }
1181
1182
1183 //=======================================================================
1184 //function : point
1185 //purpose  : 
1186 //=======================================================================
1187
1188 static Standard_Integer point(Draw_Interpretor& , Standard_Integer n, const char** a)
1189 {
1190   if (n < 4) return 1;
1191   if (n >= 5) {
1192     gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
1193     DrawTrSurf::Set(a[1],P);
1194   }
1195   else {
1196     gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
1197     DrawTrSurf::Set(a[1],P);
1198   }
1199
1200   return 0;
1201 }
1202
1203 //=======================================================================
1204 //function : coord
1205 //purpose  : 
1206 //=======================================================================
1207
1208 static Standard_Integer coord(Draw_Interpretor&,
1209                               Standard_Integer n, const char** a) 
1210 {
1211   if ( n == 4) {
1212     gp_Pnt2d P;
1213     if ( !DrawTrSurf::GetPoint2d(a[1],P)) return 1;
1214     Draw::Set(a[2],P.X());
1215     Draw::Set(a[3],P.Y());
1216   }
1217   else if ( n == 5) {
1218     gp_Pnt  P;
1219     if ( !DrawTrSurf::GetPoint(a[1],P)) return 1;
1220     Draw::Set(a[2],P.X());
1221     Draw::Set(a[3],P.Y());
1222     Draw::Set(a[4],P.Z());
1223   }
1224   else 
1225     return 1;
1226
1227   return 0;
1228 }
1229
1230 //=======================================================================
1231 //function : 
1232 //purpose  : 
1233 //=======================================================================
1234 static Standard_Integer minmaxcurandinf(Draw_Interpretor& di, 
1235                                    Standard_Integer argc, const char** argv)
1236 {
1237   if (argc < 2) return 1;
1238
1239   Handle(Geom2d_Curve)  C1 = DrawTrSurf::GetCurve2d(argv[1]);
1240   if (C1.IsNull()) return 1;
1241
1242   Draw_Color              Couleur;
1243   Geom2dLProp_CurAndInf2d Sommets;  
1244
1245   Sommets.PerformCurExt (C1);
1246   if (Sommets.IsDone() && !Sommets.IsEmpty()) {
1247     for (Standard_Integer i = 1; i <= Sommets.NbPoints(); i++){      
1248       Couleur = Draw_vert;
1249       if (Sommets.Type(i) == LProp_MinCur) {
1250         Couleur = Draw_orange;
1251         di << "  Maximum of curvature at U ="<<Sommets.Parameter(i)<<"\n";
1252       }
1253       else {
1254         di << "  Minimum of curvature at U ="<<Sommets.Parameter(i)<<"\n";
1255       }
1256       gp_Pnt2d P = C1->Value(Sommets.Parameter(i));
1257       Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Couleur); 
1258       dout << dr;
1259     }
1260     dout.Flush();
1261   }
1262    
1263   Geom2dLProp_CurAndInf2d Sommets2;
1264   Sommets2.PerformInf (C1);
1265   
1266   if (Sommets2.IsDone() && !Sommets2.IsEmpty()) {
1267     for (Standard_Integer i = 1; i <= Sommets2.NbPoints(); i++){
1268       gp_Pnt2d P = C1->Value(Sommets2.Parameter(i));
1269       Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_bleu); 
1270       dout << dr;
1271       di << "  Inflexion at U ="<<Sommets2.Parameter(i)<<"\n";
1272     }
1273     dout.Flush();
1274   }
1275   return 0;
1276 }
1277 //=======================================================================
1278 //function :  shcurvature
1279 //purpose  :  affiche le peigne de courbure
1280 //=======================================================================
1281 static Standard_Integer shcurvature(Draw_Interpretor&, 
1282                                    Standard_Integer argc, const char** argv)
1283 {
1284   if (argc < 2) return 1;
1285
1286    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1287                                   ::DownCast(Draw::Get(argv[1]));
1288    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1289                                   ::DownCast(Draw::Get(argv[1]));
1290    
1291   if (C2d.IsNull()) {
1292     if (C3d.IsNull()) return 1;
1293     C3d->ShowCurvature();
1294   }
1295   else {
1296     C2d->ShowCurvature();
1297   }
1298   Draw::Repaint();
1299   return 0;
1300 }
1301
1302 //=======================================================================
1303 //function :  clcurvature
1304 //purpose  :  efface le peigne de courbure
1305 //=======================================================================
1306 static Standard_Integer clcurvature(Draw_Interpretor&, 
1307                                    Standard_Integer argc, const char** argv)
1308 {
1309   if (argc < 2) return 1; 
1310    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1311                                   ::DownCast(Draw::Get(argv[1]));
1312    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1313                                   ::DownCast(Draw::Get(argv[1]));
1314
1315   if (C2d.IsNull()) {
1316     if (C3d.IsNull()) return 1;
1317     C3d->ClearCurvature();
1318   }
1319   else {
1320     C2d->ClearCurvature();
1321   }
1322   Draw::Repaint();
1323   return 0;
1324 }
1325
1326 //=======================================================================
1327 //function :  radiusmax
1328 //purpose  :  definit le rayon de courbure maximum a afficher
1329 //=======================================================================
1330 static Standard_Integer radiusmax(Draw_Interpretor&, 
1331                                   Standard_Integer argc, const char** argv)
1332 {
1333   if (argc < 3) return 1; 
1334   Standard_Real Radius = Draw::Atof(argv[2]);
1335    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1336                                   ::DownCast(Draw::Get(argv[1]));
1337    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1338                                   ::DownCast(Draw::Get(argv[1]));
1339
1340   if (C2d.IsNull()) {
1341     if (C3d.IsNull()) return 1;
1342     C3d->SetRadiusMax(Radius);
1343   }
1344   else {
1345     C2d->SetRadiusMax(Radius);
1346   }
1347   Draw::Repaint();
1348   return 0;
1349 }
1350
1351 //=======================================================================
1352 //function :  radiusratio
1353 //purpose  :  definit le ratio du rayon de courbure a afficher
1354 //=======================================================================
1355 static Standard_Integer radiusratio(Draw_Interpretor&, 
1356                                   Standard_Integer argc, const char** argv)
1357 {
1358   if (argc < 3) return 1;
1359   Standard_Real Ratio = Draw::Atof(argv[2]);
1360   Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1361                                   ::DownCast(Draw::Get(argv[1]));
1362   Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1363                                   ::DownCast(Draw::Get(argv[1]));
1364
1365   if (C2d.IsNull()) { 
1366     if (C3d.IsNull()) return 1;
1367     C3d->SetRadiusRatio(Ratio);
1368   }
1369   else {
1370     C2d->SetRadiusRatio(Ratio);
1371   }
1372   Draw::Repaint();
1373   return 0;
1374 }
1375
1376 //=======================================================================
1377 //function : 
1378 //purpose  : 
1379 //=======================================================================
1380 static Standard_Integer localprop(Draw_Interpretor& di, 
1381                                   Standard_Integer argc, const char** argv)
1382 {
1383   if (argc < 3) return 1;
1384
1385   Standard_Real U =  Draw::Atof(argv[2]);
1386
1387   Handle(Geom2d_Curve)  C2d = DrawTrSurf::GetCurve2d(argv[1]);
1388   Handle(Geom_Curve)    C3d;
1389
1390
1391   if (C2d.IsNull()) {
1392     C3d = DrawTrSurf::GetCurve(argv[1]);
1393     if (C3d.IsNull()) return 1;
1394     GeomLProp_CLProps Prop (C3d,2,Precision::Confusion());
1395     Prop.SetParameter(U);
1396     Handle(Draw_Marker3D)drp = new Draw_Marker3D(Prop.Value(),
1397                                                  Draw_Plus,
1398                                                  Draw_vert );
1399     dout << drp;
1400     if (Prop.IsTangentDefined()) {
1401       Standard_Real K = Prop.Curvature();
1402       di <<" Curvature : "<<K<<"\n";
1403
1404       if (Abs(K) > Precision::Confusion()) {
1405         Standard_Real R = 1/Abs(K);
1406         gp_Pnt        Center;
1407         Prop.CentreOfCurvature(Center);
1408         gp_Dir Tang;
1409         gp_Dir Nor;
1410         Prop.Tangent(Tang);
1411         Prop.Normal(Nor);
1412         gp_Dir AxC = Nor^Tang;
1413         gp_Ax2 Axe(Center,AxC,Nor);
1414         Handle(Geom_Circle) Cir3d = new Geom_Circle(Axe,R);
1415         Handle(DrawTrSurf_Curve) dr;
1416         dr = new DrawTrSurf_Curve(Cir3d);
1417         dout << dr;
1418         dout.Flush();
1419       }
1420     }
1421     else 
1422       di <<"Tangent undefined.\n";  
1423   }
1424   else {
1425     Geom2dLProp_CLProps2d Prop (C2d,2,Precision::Confusion());
1426     Prop.SetParameter(U);
1427     Handle(Draw_Marker2D) drp = new Draw_Marker2D(Prop.Value(),
1428                                                   Draw_Plus,
1429                                                   Draw_vert);
1430     dout << drp;
1431     if (Prop.IsTangentDefined()) {
1432       Standard_Real K = Prop.Curvature();
1433       gp_Pnt2d      Center;
1434
1435       di <<" Curvature : "<<K<<"\n";
1436
1437       if (Abs(K) > Precision::Confusion()) {
1438         Standard_Real R = 1/Abs(K);
1439         Prop.CentreOfCurvature(Center);
1440         gp_Ax2d Axe(Center,gp::DX2d());
1441         Handle(Geom2d_Circle) Cir2d = new Geom2d_Circle(Axe,R);
1442         Handle(DrawTrSurf_Curve2d) dr;
1443         dr = new DrawTrSurf_Curve2d(Cir2d,Draw_rouge,30,Standard_False);
1444         dout << dr;
1445         dout.Flush();
1446       }
1447     }
1448     else 
1449       di <<"Tangent undefined.\n";
1450   }
1451   return 0;
1452 }  
1453 //=======================================================================
1454 //function : rawcont
1455 //purpose  : 
1456 //=======================================================================
1457
1458 static Standard_Integer rawcont(Draw_Interpretor& di, Standard_Integer n, const char** a)
1459 {
1460   if (n < 5) return 1;
1461
1462   Handle(Geom_Curve) GC1;
1463   GC1 = DrawTrSurf::GetCurve(a[1]);
1464   Handle(Geom_Curve) GC2;
1465   GC2 = DrawTrSurf::GetCurve(a[2]);
1466   Standard_Real param1 =
1467     Draw::Atof(a[3]) ;
1468   Standard_Real param2 =
1469     Draw::Atof(a[4]) ;
1470   if (GC1.IsNull() || GC2.IsNull())
1471     return 1;
1472   gp_Pnt a_point1,
1473     a_point2 ;
1474   GC1->D0(param1,
1475           a_point1) ;
1476   GC2->D0(param2,
1477           a_point2) ;
1478   if (a_point2.SquareDistance(a_point1) < Precision::Confusion()) {
1479     GeomAbs_Shape cont =
1480       GeomLProp::Continuity(GC1,
1481                             GC2,
1482                             param1,
1483                             param2,
1484                             Standard_True,
1485                             Standard_True,
1486                             Precision::Confusion(),
1487                             Precision::Angular()) ;
1488     switch (cont) {
1489     case GeomAbs_C0: 
1490       di << " C0 Continuity \n" ;
1491       break ;
1492     case GeomAbs_G1:
1493       di << " G1 Continuity \n" ;
1494       break ;
1495     case GeomAbs_C1 :
1496       di << " C1 Continuity \n" ;
1497       break ;
1498     case GeomAbs_G2 :
1499       di << " G2 Continuity \n" ;
1500       break ; 
1501     case GeomAbs_C2 :
1502       di << " C2 Continuity \n" ;
1503       break ; 
1504     case GeomAbs_C3 :
1505       di << " C3 Continuity \n" ;
1506       break ; 
1507     case GeomAbs_CN :
1508       di << " CN Continuity \n" ;
1509       break ; 
1510     default:
1511       break ; 
1512     }
1513   }
1514   else {
1515     di << " not C0 continuity \n" ;
1516   }
1517   return 0 ;
1518 }
1519 //=======================================================================
1520 //function : approxcurveonsurf
1521 //purpose  : 
1522 //=======================================================================
1523 static Standard_Integer approxcurveonsurf(Draw_Interpretor& di, Standard_Integer n, const char** a)
1524 {
1525   Standard_Real Tol = 1.e-7;              // Tolerance (default 0.1mm) 
1526   GeomAbs_Shape Continuity = GeomAbs_C1;  // Continuity order : 0, 1 or 2 (default 1)
1527   Standard_Integer MaxDeg = 14;           // Maximum degree
1528   Standard_Integer MaxSeg = 16; /*1*/          // Maximum number of segments
1529
1530   if ( n>8 || n<4) return 1;
1531
1532   if (n>4) Tol = Max(Draw::Atof(a[4]),1.e-10);
1533
1534   if (n>5) {
1535     if (Draw::Atoi(a[5]) == 0) Continuity = GeomAbs_C0;
1536     if (Draw::Atoi(a[5]) == 2) Continuity = GeomAbs_C2;
1537   }
1538
1539   if (n>6) {
1540     MaxDeg = Draw::Atoi(a[6]);
1541     if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1542   }
1543
1544   if (n>7) MaxSeg = Draw::Atoi(a[7]);
1545   Handle(Geom2d_Curve) curve2d = DrawTrSurf::GetCurve2d(a[2]);
1546   Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[3]);
1547
1548   Handle(Geom2dAdaptor_HCurve) A2d = new (Geom2dAdaptor_HCurve)(curve2d);
1549   Handle(GeomAdaptor_HSurface) AS = new (GeomAdaptor_HSurface)(Surf);
1550
1551   Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(),
1552                             Tol,  Continuity,  MaxDeg, MaxSeg,
1553                             Standard_True, Standard_False);
1554
1555   if(App.HasResult()) {
1556     Handle(Geom_BSplineCurve) BSCurve = App.Curve3d(); 
1557     DrawTrSurf::Set(a[1], BSCurve);
1558     return 0;
1559   }
1560
1561   di << "Approximation failed !\n";
1562   return 1;
1563                             
1564 }
1565
1566 //=======================================================================
1567 //function : approxcurve
1568 //purpose  : 
1569 //=======================================================================
1570 static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
1571
1572   Standard_Real Tol = 1.e-7;              // Tolerance (default 0.1mm) 
1573   GeomAbs_Shape Continuity = GeomAbs_C1;  // Continuity order : 0, 1 or 2 (default 1)
1574   Standard_Integer MaxDeg = 14;           // Maximum degree
1575   Standard_Integer MaxSeg = 16;           // Maximum number of segments
1576   
1577   Standard_Integer Case, shift;
1578 // Case == 1 : 3d approximation without reparametrization
1579 // Case == 2 : 2d approximation without reparametrization
1580 // Case == 3 : 3d approximation with reparametrization
1581 // Case == 4 : curve_on_surface approximation with reparametrization
1582 // Case == 5 : 2 curves_on_surfaces approximation with reparametrization
1583
1584   Handle(Geom_Curve) curve;
1585   Handle(Geom2d_Curve) curve2d, curve2d2;
1586   Handle(Geom_Surface) surface, surface2;
1587
1588   if(n < 2) return 1;
1589
1590   if (!strcmp(a[1],"-L")) {
1591 // aproximation with curvilinear abscissa reparametrization
1592     if (n > 11 || n < 4) return 1;
1593     Tol = 1.e-4;
1594     curve = DrawTrSurf::GetCurve(a[3]);
1595     if (!curve.IsNull()) {
1596       shift = 4;
1597       Case = 3;
1598     }
1599     else {
1600 // approx curve_on_surface
1601       if (n < 5) return 1;
1602       curve2d = DrawTrSurf::GetCurve2d(a[3]); 
1603       surface = DrawTrSurf::GetSurface(a[4]);
1604       if (curve2d.IsNull() || surface.IsNull()) {
1605         return 1;
1606       }
1607       if (n >= 7) {
1608         curve2d2 = DrawTrSurf::GetCurve2d(a[5]); 
1609         surface2 = DrawTrSurf::GetSurface(a[6]);
1610         if (curve2d2.IsNull() || surface2.IsNull()) {
1611           shift = 5;
1612           Case = 4;
1613         }
1614         else {
1615 // approx 2 curves_on_surfaces
1616           shift = 7;
1617           Case = 5;
1618         }
1619       }
1620       else {
1621         shift = 5;
1622         Case = 4;
1623       }
1624     }
1625   }
1626   else {
1627 // aproximation without reparamitrization
1628     if ( n>7 || n<3) return 1;
1629     shift = 3;
1630     curve = DrawTrSurf::GetCurve(a[2]);
1631     if (curve.IsNull()) {
1632       curve2d = DrawTrSurf::GetCurve2d(a[2]); 
1633       if (curve2d.IsNull()) {
1634         return 1;
1635       }
1636       Case = 2;
1637     }
1638     else
1639       Case = 1;
1640   }
1641   
1642   if (n>shift) Tol = Max(Draw::Atof(a[shift]),1.e-10);
1643   
1644   if (n>shift+1) {
1645     if (Draw::Atoi(a[shift+1]) == 0) Continuity = GeomAbs_C0;
1646     if (Draw::Atoi(a[shift+1]) == 2) Continuity = GeomAbs_C2;
1647   }
1648   
1649   if (n>shift+2) {
1650       MaxDeg = Draw::Atoi(a[shift+2]);
1651       if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1652     }
1653   
1654   if (n>shift+3) MaxSeg = Draw::Atoi(a[shift+3]);
1655     
1656   if (Case == 1) {
1657     GeomConvert_ApproxCurve appr(curve, Tol, Continuity, MaxSeg, MaxDeg);
1658     if(appr.HasResult()) {
1659       //appr.Dump(cout);
1660       Standard_SStream aSStream;
1661       appr.Dump(aSStream);
1662       di << aSStream;
1663       Handle(Geom_BSplineCurve) BSCurve = appr.Curve(); 
1664       DrawTrSurf::Set(a[1], BSCurve);
1665     }
1666  }   
1667
1668   else if (Case == 2) {
1669     Geom2dConvert_ApproxCurve appr(curve2d, Tol, Continuity, MaxSeg, MaxDeg);
1670     if(appr.HasResult()) {
1671       //appr.Dump(cout);
1672       Standard_SStream aSStream;
1673       appr.Dump(aSStream);
1674       di << aSStream;
1675       Handle(Geom2d_BSplineCurve) BSCurve = appr.Curve(); 
1676       DrawTrSurf::Set(a[1], BSCurve);
1677     }
1678   }    
1679
1680   else if (Case == 3) {
1681     Handle(Adaptor3d_HCurve) HACur = new GeomAdaptor_HCurve(curve);
1682     Approx_CurvilinearParameter appr(HACur, Tol, Continuity, MaxDeg, MaxSeg);
1683     if(appr.HasResult()) {
1684       //appr.Dump(cout);
1685       Standard_SStream aSStream;
1686       appr.Dump(aSStream);
1687       di << aSStream;
1688       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1689       DrawTrSurf::Set(a[2], BSCurve);
1690     }
1691 }    
1692   else if (Case == 4) {
1693     Handle(Adaptor2d_HCurve2d) HACur2d = new Geom2dAdaptor_HCurve(curve2d);
1694     Handle(Adaptor3d_HSurface) HASur = new GeomAdaptor_HSurface(surface);
1695     Approx_CurvilinearParameter appr(HACur2d, HASur, Tol, Continuity, MaxDeg, MaxSeg);
1696     if(appr.HasResult()) {
1697       //appr.Dump(cout);
1698       Standard_SStream aSStream;
1699       appr.Dump(aSStream);
1700       di << aSStream;
1701       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1702       DrawTrSurf::Set(a[2], BSCurve);
1703     }
1704   }
1705
1706   else if (Case == 5) {
1707     Handle(Adaptor2d_HCurve2d) HACur2d = new Geom2dAdaptor_HCurve(curve2d);
1708     Handle(Adaptor3d_HSurface) HASur = new GeomAdaptor_HSurface(surface);
1709     Handle(Adaptor2d_HCurve2d) HACur2d2 = new Geom2dAdaptor_HCurve(curve2d2);
1710     Handle(Adaptor3d_HSurface) HASur2 = new GeomAdaptor_HSurface(surface2);
1711     Approx_CurvilinearParameter appr(HACur2d, HASur, HACur2d2, HASur2, Tol, Continuity, MaxDeg, MaxSeg);
1712     if(appr.HasResult()) {
1713       //appr.Dump(cout);
1714       Standard_SStream aSStream;
1715       appr.Dump(aSStream);
1716       di << aSStream;
1717       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1718       DrawTrSurf::Set(a[2], BSCurve);
1719     }
1720   }
1721   
1722
1723   return 0;
1724 }
1725
1726
1727 //=======================================================================
1728 //function : fitcurve
1729 //purpose  : 
1730 //=======================================================================
1731
1732 static Standard_Integer fitcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
1733 {
1734   if (n<3) return 1;
1735
1736   Handle(Geom_Curve) GC;
1737   GC = DrawTrSurf::GetCurve(a[2]);
1738   if (GC.IsNull())
1739     return 1;
1740
1741   Standard_Integer Dmin = 3;
1742   Standard_Integer Dmax = 14;
1743   Standard_Real Tol3d = 1.e-5;
1744   Standard_Boolean inverse = Standard_True;
1745
1746   if (n > 3)
1747   {
1748     Tol3d = Atof(a[3]);
1749   }
1750
1751   if (n > 4)
1752   {
1753     Dmax = atoi(a[4]);
1754   }
1755
1756   if (n > 5)
1757   {
1758     Standard_Integer inv = atoi(a[5]);
1759     if (inv > 0)
1760     {
1761       inverse = Standard_True;
1762     }
1763     else
1764     {
1765       inverse = Standard_False;
1766     }
1767   }
1768
1769   Handle(GeomAdaptor_HCurve) aGAC = new GeomAdaptor_HCurve(GC);
1770
1771   CurveEvaluator aCE(aGAC);
1772
1773   Approx_FitAndDivide anAppro(Dmin, Dmax, Tol3d, 0., Standard_True);
1774   anAppro.SetInvOrder(inverse);
1775   anAppro.Perform(aCE);
1776
1777   if (!anAppro.IsAllApproximated())
1778   {
1779     di << "Approximation failed \n";
1780     return 1;
1781   }
1782   Standard_Integer i;
1783   Standard_Integer NbCurves = anAppro.NbMultiCurves();
1784
1785   Convert_CompBezierCurvesToBSplineCurve Conv;
1786
1787   Standard_Real tol3d, tol2d, tolreached = 0.;
1788   for (i = 1; i <= NbCurves; i++) {
1789     anAppro.Error(i, tol3d, tol2d);
1790     tolreached = Max(tolreached, tol3d);
1791     AppParCurves_MultiCurve MC = anAppro.Value(i);
1792     TColgp_Array1OfPnt Poles(1, MC.Degree() + 1);
1793     MC.Curve(1, Poles);
1794     Conv.AddCurve(Poles);
1795   }
1796   Conv.Perform();
1797   Standard_Integer NbPoles = Conv.NbPoles();
1798   Standard_Integer NbKnots = Conv.NbKnots();
1799
1800   TColgp_Array1OfPnt      NewPoles(1, NbPoles);
1801   TColStd_Array1OfReal    NewKnots(1, NbKnots);
1802   TColStd_Array1OfInteger NewMults(1, NbKnots);
1803
1804   Conv.KnotsAndMults(NewKnots, NewMults);
1805   Conv.Poles(NewPoles);
1806
1807   BSplCLib::Reparametrize(GC->FirstParameter(),
1808     GC->LastParameter(),
1809     NewKnots);
1810   Handle(Geom_BSplineCurve) TheCurve = new Geom_BSplineCurve(NewPoles, NewKnots, NewMults, Conv.Degree());
1811
1812   DrawTrSurf::Set(a[1], TheCurve);
1813   di << a[1] << ": tolreached = " << tolreached << "\n";
1814
1815   return 0;
1816
1817 }
1818
1819 //=======================================================================
1820 //function : newbspline
1821 //purpose  : reduce the multiplicity of the knots to their minimum 
1822 //           compared to the degree of the curve
1823 //=======================================================================
1824
1825 static Standard_Integer splitc1(Draw_Interpretor& di,
1826                                    Standard_Integer n, const char** c)
1827
1828 {Standard_Real      tolerance=1.0e-5,
1829    angular_tolerance = 1.0e-4 ;
1830  Standard_Integer   optiontab,i;
1831  char name[100];
1832
1833  if (n<3) return 1;
1834  optiontab=Draw::Atoi(c[2]);
1835  if (n >= 4 )
1836    tolerance=Draw::Atof(c[3]);
1837  if (n >= 5) {
1838    angular_tolerance = Draw::Atof(c[4]) ;
1839  }
1840  Handle(Geom_Curve) ACurve = Handle(Geom_Curve)::DownCast(DrawTrSurf::Get(c[1])) ;
1841  
1842  Standard_Real f = ACurve->FirstParameter();
1843  Standard_Real l = ACurve->LastParameter();
1844
1845  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
1846    di << " Error: Infinite curves\n";
1847    return 1;
1848  }
1849
1850  Handle(Geom_BSplineCurve) BS = GeomConvert::CurveToBSplineCurve(ACurve);
1851  
1852  if ( BS.IsNull()) return 1;
1853
1854  if (optiontab){
1855    Handle(TColGeom_HArray1OfBSplineCurve)  tabBS;
1856    GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS,
1857                                                  tabBS,
1858                                                  angular_tolerance,
1859                                                  tolerance);
1860    for (i=0;i<=(tabBS->Length()-1);i++){
1861      Sprintf(name,"%s_%d",c[1],i+1);
1862      Standard_CString new_name = name ;
1863      DrawTrSurf::Set(new_name,
1864                      tabBS->Value(i));
1865      di.AppendElement(name);
1866    }
1867  }
1868  else{
1869    GeomConvert::C0BSplineToC1BSplineCurve(BS,
1870                                           tolerance,
1871                                           angular_tolerance) ;
1872
1873    DrawTrSurf::Set(c[1],BS);
1874  }
1875  return 0;
1876 }
1877
1878 //=======================================================================
1879 //function : splitc12d
1880 //purpose  : reduce the multiplicity of the knots to their minimum 
1881 //           compared to the degree of the curve
1882 //=======================================================================
1883
1884 static Standard_Integer splitc12d(Draw_Interpretor& di,
1885                                      Standard_Integer n, const char** c)
1886
1887 {Standard_Real      tolerance=1.0e-5,
1888    angular_tolerance = 1.0e-4 ;
1889  Standard_Integer   optiontab,i;
1890  char name[100];
1891
1892  if (n<3) return 1;
1893  optiontab=Draw::Atoi(c[2]);
1894  if (n==4)
1895    tolerance=Draw::Atof(c[3]);
1896  if (n==5) 
1897    angular_tolerance = Draw::Atof(c[4]) ;
1898  Handle(Geom2d_Curve) ACurve = DrawTrSurf::GetCurve2d(c[1]);
1899  
1900  Standard_Real f = ACurve->FirstParameter();
1901  Standard_Real l = ACurve->LastParameter();
1902
1903  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
1904    di << " Error: Infinite curves\n";
1905    return 1;
1906  }
1907
1908  Handle(Geom2d_BSplineCurve) BS = Geom2dConvert::CurveToBSplineCurve(ACurve);
1909  
1910  if ( BS.IsNull()) return 1;
1911
1912  if (optiontab){
1913    Handle(TColGeom2d_HArray1OfBSplineCurve)  tabBS;
1914    Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(BS,
1915                                                    tabBS,
1916                                                    angular_tolerance,
1917                                                    tolerance);
1918    for (i=0;i<=(tabBS->Length()-1);i++){
1919      Sprintf(name,"%s_%d",c[1],i+1);
1920      Standard_CString new_name = name ;
1921      DrawTrSurf::Set(new_name,
1922                      tabBS->Value(i));
1923      di.AppendElement(name);
1924    }
1925  }
1926  else{
1927    Geom2dConvert::C0BSplineToC1BSplineCurve(BS,tolerance);
1928    DrawTrSurf::Set(c[1],BS);
1929  }
1930  return 0;
1931 }
1932
1933 //=======================================================================
1934 //function : canceldenom
1935 //purpose  : set the value of the denominator cancel its first 
1936 //           derivative on the boundaries of the surface if possible
1937 //=======================================================================
1938
1939 static Standard_Integer canceldenom(Draw_Interpretor& ,
1940                                      Standard_Integer n, const char** c)
1941
1942 {Standard_Integer    uoption,voption;
1943  Standard_Boolean    udirection=Standard_False;
1944  Standard_Boolean    vdirection=Standard_False;
1945  if (n<4) return 1;
1946  uoption=Draw::Atoi(c[2]);
1947  voption=Draw::Atoi(c[3]);
1948  if (uoption)
1949    udirection=Standard_True;
1950  if (voption)
1951    vdirection=Standard_True;
1952  Handle(Geom_BSplineSurface) BSurf = DrawTrSurf::GetBSplineSurface(c[1]);
1953  GeomLib::CancelDenominatorDerivative(BSurf,udirection,vdirection);
1954  DrawTrSurf::Set(c[1],BSurf);
1955  return 0;
1956 }
1957
1958 //=======================================================================
1959 //function : length
1960 //purpose  : eval curve's length
1961 //=======================================================================
1962
1963 static Standard_Integer length(Draw_Interpretor& di,
1964                                Standard_Integer n, const char** a)
1965 {
1966   if (n<2) return 1;
1967   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
1968   Handle(Geom2d_Curve) GC2d = DrawTrSurf::GetCurve2d(a[1]);
1969   Standard_Real Tol = Precision::Confusion(), L;
1970   if (n==3) Tol = Draw::Atof(a[2]);
1971
1972   if (!GC.IsNull()) {
1973     GeomAdaptor_Curve AC(GC);
1974     L = GCPnts_AbscissaPoint::Length(AC, Tol);
1975   }  
1976   else if (!GC2d.IsNull()) {
1977     Geom2dAdaptor_Curve AC(GC2d);
1978     L = GCPnts_AbscissaPoint::Length(AC, Tol);
1979   }
1980   else {
1981     di << a[1] << "is not a curve\n";
1982     return 1;
1983   }
1984
1985   di << "The length " << a[1] << " is " << L << "\n";
1986   return 0;
1987 }
1988
1989
1990
1991 //=======================================================================
1992 //function : CurveCommands
1993 //purpose  : 
1994 //=======================================================================
1995
1996 void  GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
1997 {
1998   
1999   static Standard_Boolean loaded = Standard_False;
2000   if (loaded) return;
2001   loaded = Standard_True;
2002   
2003   DrawTrSurf::BasicCommands(theCommands);
2004   
2005   const char* g;
2006   
2007   
2008   // analytic curves
2009   g = "GEOMETRY curves creation";
2010
2011
2012   theCommands.Add("point",
2013                   "point name x y [z]",
2014                   __FILE__,
2015                   point ,g);
2016   
2017   theCommands.Add("line",
2018                   "line name pos dir",
2019                   __FILE__,
2020                   anacurve,g);
2021   
2022   theCommands.Add("circle",
2023                   "circle name x y [z [dx dy dz]] [ux uy [uz]] radius",
2024                   __FILE__,
2025                   anacurve,g);
2026   
2027   theCommands.Add("ellipse",
2028                   "ellipse name x y [z [dx dy dz]] [ux uy [uz]] major minor",
2029                   __FILE__,
2030                   anacurve,g);
2031   theCommands.Add("parabola",
2032                   "parabola name x y [z [dx dy dz]] [ux uy [uz]] focal",
2033                   __FILE__,
2034                   anacurve,g);
2035   theCommands.Add("hyperbola",
2036                   "hyperbola name x y [z [dx dy dz]] [ux uy [uz]] major minor",
2037                   __FILE__,
2038                   anacurve,g);
2039
2040   theCommands.Add("beziercurve",
2041                   "beziercurve name nbpole pole, [weight]",
2042                   __FILE__,
2043                   polecurve,g);
2044
2045   theCommands.Add("bsplinecurve",
2046                   "bsplinecurve name degree nbknots  knot, umult  pole, weight",
2047                   __FILE__,
2048                   polecurve,g);
2049
2050   theCommands.Add("pbsplinecurve",
2051                   "pbsplinecurve name degree nbknots  knot, umult  pole, weight (periodic)",
2052                   __FILE__,
2053                   polecurve,g);
2054
2055   theCommands.Add("2dbeziercurve",
2056                   "2dbeziercurve name nbpole pole, [weight]",
2057                   __FILE__,
2058                   polecurve2d,g);
2059
2060   theCommands.Add("2dbsplinecurve",
2061                   "2dbsplinecurve name degree nbknots  knot, umult  pole, weight",
2062                   __FILE__,
2063                   polecurve2d,g);
2064
2065   theCommands.Add("2dpbsplinecurve",
2066                   "2dpbsplinecurve name degree nbknots  knot, umult  pole, weight (periodic)",
2067                   __FILE__,
2068                   polecurve2d,g);
2069
2070   g = "GEOMETRY Curves and Surfaces modification";
2071
2072   theCommands.Add("reverse",
2073                   "reverse name ... ",
2074                   __FILE__,
2075                   reverse,g);
2076
2077   theCommands.Add("cmovep",
2078                   "cmovep name index dx dy dz",
2079                   __FILE__,
2080                   cmovepole,g);
2081
2082   theCommands.Add("cmovepoint",
2083                   "cmovepoint name u dx dy [dz index1 index2]",
2084                   __FILE__,
2085                   cmovepoint,g);
2086
2087   theCommands.Add("cmovetangent",
2088                   "cmovetangent name u  x y [z] tx ty [tz constraint = 0]",
2089                   __FILE__,
2090                   cmovetangent,g) ;
2091
2092   theCommands.Add("insertknot",
2093                   "insertknot name knot [mult = 1] [knot mult ...]",
2094                   __FILE__,
2095                   cinsertknot,g);
2096
2097   theCommands.Add("setknot",
2098                   "setknot name index knot [mult]",
2099                   __FILE__,
2100                   csetknot,g);
2101
2102   theCommands.Add("remknot",
2103                   "remknot name index [mult] [tol]",
2104                   __FILE__,
2105                   cremknot,g);
2106
2107   theCommands.Add("incdeg",
2108                   "incdeg name degree",
2109                   __FILE__,
2110                   increasedegree,g);
2111
2112   theCommands.Add("rempole",
2113                   "rempole name index",
2114                   __FILE__,
2115                   removepole,g);
2116
2117   theCommands.Add("insertpole",
2118                   "insertpole name index x y [z] [weight]",
2119                   __FILE__,
2120                   insertpole,g);
2121
2122   theCommands.Add("cfindp",
2123                   "cfindp name view x y index",
2124                   __FILE__,
2125                   cfindp,g);
2126
2127   theCommands.Add("setperiodic",
2128                   "setperiodic name ...",
2129                   __FILE__,
2130                   csetperiodic,g);
2131
2132   theCommands.Add("setnotperiodic",
2133                   "setnotperiodic name",
2134                   __FILE__,
2135                   csetperiodic,g);
2136
2137   theCommands.Add("segment",
2138                   "segment name Ufirst Ulast",
2139                    __FILE__,
2140                   segment , g);
2141
2142   theCommands.Add("setorigin",
2143                   "setorigin name knotindex",
2144                    __FILE__,
2145                   setorigin , g);
2146
2147   g = "GEOMETRY curves and surfaces analysis";
2148
2149   theCommands.Add("cvalue",
2150                   "cvalue curvename U  X Y Z [D1X D1Y D1Z D2X D2Y D2Z]",
2151                   __FILE__,
2152                   value,g);
2153
2154   theCommands.Add("2dcvalue",
2155                   "2dcvalue curvename U  X Y [D1X D1Y D2X D2Y]",
2156                   __FILE__,
2157                   value2d,g);
2158
2159   theCommands.Add("coord",
2160                   "coord P x y [z]: set in x y [z] the coordinates of P",
2161                   __FILE__,
2162                   coord,g);
2163
2164   theCommands.Add("minmaxcurandinf",
2165                   "minmaxcurandinf curve",
2166                   __FILE__,
2167                   minmaxcurandinf,g);
2168   
2169   theCommands.Add("shcurvature",
2170                   "shcurvature curvename",
2171                   __FILE__,
2172                   shcurvature,g);
2173
2174   theCommands.Add("clcurvature",
2175                   "clcurvature curvename",
2176                   __FILE__,
2177                   clcurvature,g);
2178   
2179
2180  theCommands.Add("radiusmax",
2181                   "radiusmax curvename  radius",
2182                   __FILE__,
2183                   radiusmax,g);
2184
2185  theCommands.Add("radiusratio",
2186                   "radiusratio curvename ratio",
2187                   __FILE__,
2188                   radiusratio,g); 
2189   theCommands.Add("localprop",
2190                   "localprop curvename U",
2191                   __FILE__,
2192                   localprop,g);
2193   theCommands.Add("rawcont",
2194                   "rawcont curve1 curve2 u1 u2",
2195                   __FILE__,
2196                   rawcont,g) ;
2197   theCommands.Add("approxcurve",
2198                   "approxcurve [-L] name curve1 [Surf1] [curve2d2 Surf2] [Tol [cont [maxdeg [maxseg]]]] ",
2199                   __FILE__,
2200                   approxcurve,g);
2201
2202   theCommands.Add("approxcurveonsurf",
2203                   "approxcurveonsurf name curve2d surface [Tol [cont [maxdeg [maxseg]]]] ",
2204                   __FILE__,
2205                   approxcurveonsurf,g);
2206
2207  theCommands.Add("fitcurve", "fitcurve result  curve [tol [maxdeg [inverse]]]", __FILE__, fitcurve, g);
2208
2209  theCommands.Add("length", "length curve [Tol]", 
2210                   __FILE__,
2211                   length, g);
2212
2213
2214   theCommands.Add("splitc1",
2215                   "splitc1 bspline resultinarray(0/1) [tol] [angtol] ",
2216                   __FILE__,
2217                   splitc1,g);
2218
2219   theCommands.Add("splitc12d",
2220                   "splitc12d bspline2d resultinarray(0/1) [tol] [angtol] ",
2221                   __FILE__,
2222                   splitc12d,g);
2223   theCommands.Add("canceldenom",
2224                   "canceldenom BSpline-Surface UDirection(0/1) VDirection(0/1)",
2225                   __FILE__,
2226                   canceldenom,g);
2227
2228  
2229
2230 }