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