0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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 || n > 5) 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   Standard_Real aTolerance = Precision::PConfusion();
1144   if (n == 5)
1145     aTolerance = Draw::Atof(a[4]);
1146
1147   if (!GBz.IsNull()) 
1148     GBz->Segment(f,l);
1149   else if (!GBs.IsNull())
1150     GBs->Segment(f, l, aTolerance);
1151   else if (!GBz2d.IsNull()) 
1152     GBz2d->Segment(f,l);
1153   else if (!GBs2d.IsNull())
1154     GBs2d->Segment(f, l, aTolerance);
1155   else
1156     return 1;
1157
1158   Draw::Repaint();
1159   return 0;
1160 }
1161
1162
1163 //=======================================================================
1164 //function : setorigin
1165 //purpose  : 
1166 //=======================================================================
1167
1168 static Standard_Integer setorigin (Draw_Interpretor& , Standard_Integer n, const char** a)
1169 {
1170   if (n < 3) return 1;
1171
1172   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
1173   Handle(Geom2d_BSplineCurve) GBs2d = DrawTrSurf::GetBSplineCurve2d(a[1]);
1174
1175   if (!GBs.IsNull())
1176     GBs->SetOrigin(Draw::Atoi(a[2])); 
1177   if (!GBs2d.IsNull())
1178     GBs2d->SetOrigin(Draw::Atoi(a[2])); 
1179   else
1180     return 1;
1181
1182   Draw::Repaint();
1183   return 0;
1184 }
1185
1186
1187 //=======================================================================
1188 //function : point
1189 //purpose  : 
1190 //=======================================================================
1191
1192 static Standard_Integer point(Draw_Interpretor& , Standard_Integer n, const char** a)
1193 {
1194   if (n < 4) return 1;
1195   if (n >= 5) {
1196     gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
1197     DrawTrSurf::Set(a[1],P);
1198   }
1199   else {
1200     gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
1201     DrawTrSurf::Set(a[1],P);
1202   }
1203
1204   return 0;
1205 }
1206
1207 //=======================================================================
1208 //function : coord
1209 //purpose  : 
1210 //=======================================================================
1211
1212 static Standard_Integer coord(Draw_Interpretor&,
1213                               Standard_Integer n, const char** a) 
1214 {
1215   if ( n == 4) {
1216     gp_Pnt2d P;
1217     if ( !DrawTrSurf::GetPoint2d(a[1],P)) return 1;
1218     Draw::Set(a[2],P.X());
1219     Draw::Set(a[3],P.Y());
1220   }
1221   else if ( n == 5) {
1222     gp_Pnt  P;
1223     if ( !DrawTrSurf::GetPoint(a[1],P)) return 1;
1224     Draw::Set(a[2],P.X());
1225     Draw::Set(a[3],P.Y());
1226     Draw::Set(a[4],P.Z());
1227   }
1228   else 
1229     return 1;
1230
1231   return 0;
1232 }
1233
1234 //=======================================================================
1235 //function : 
1236 //purpose  : 
1237 //=======================================================================
1238 static Standard_Integer minmaxcurandinf(Draw_Interpretor& di, 
1239                                    Standard_Integer argc, const char** argv)
1240 {
1241   if (argc < 2) return 1;
1242
1243   Handle(Geom2d_Curve)  C1 = DrawTrSurf::GetCurve2d(argv[1]);
1244   if (C1.IsNull()) return 1;
1245
1246   Draw_Color              Couleur;
1247   Geom2dLProp_CurAndInf2d Sommets;  
1248
1249   Sommets.PerformCurExt (C1);
1250   if (Sommets.IsDone() && !Sommets.IsEmpty()) {
1251     for (Standard_Integer i = 1; i <= Sommets.NbPoints(); i++){      
1252       Couleur = Draw_vert;
1253       if (Sommets.Type(i) == LProp_MinCur) {
1254         Couleur = Draw_orange;
1255         di << "  Maximum of curvature at U ="<<Sommets.Parameter(i)<<"\n";
1256       }
1257       else {
1258         di << "  Minimum of curvature at U ="<<Sommets.Parameter(i)<<"\n";
1259       }
1260       gp_Pnt2d P = C1->Value(Sommets.Parameter(i));
1261       Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Couleur); 
1262       dout << dr;
1263     }
1264     dout.Flush();
1265   }
1266    
1267   Geom2dLProp_CurAndInf2d Sommets2;
1268   Sommets2.PerformInf (C1);
1269   
1270   if (Sommets2.IsDone() && !Sommets2.IsEmpty()) {
1271     for (Standard_Integer i = 1; i <= Sommets2.NbPoints(); i++){
1272       gp_Pnt2d P = C1->Value(Sommets2.Parameter(i));
1273       Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_bleu); 
1274       dout << dr;
1275       di << "  Inflexion at U ="<<Sommets2.Parameter(i)<<"\n";
1276     }
1277     dout.Flush();
1278   }
1279   return 0;
1280 }
1281 //=======================================================================
1282 //function :  shcurvature
1283 //purpose  :  affiche le peigne de courbure
1284 //=======================================================================
1285 static Standard_Integer shcurvature(Draw_Interpretor&, 
1286                                    Standard_Integer argc, const char** argv)
1287 {
1288   if (argc < 2) return 1;
1289
1290    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1291                                   ::DownCast(Draw::Get(argv[1]));
1292    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1293                                   ::DownCast(Draw::Get(argv[1]));
1294    
1295   if (C2d.IsNull()) {
1296     if (C3d.IsNull()) return 1;
1297     C3d->ShowCurvature();
1298   }
1299   else {
1300     C2d->ShowCurvature();
1301   }
1302   Draw::Repaint();
1303   return 0;
1304 }
1305
1306 //=======================================================================
1307 //function :  clcurvature
1308 //purpose  :  efface le peigne de courbure
1309 //=======================================================================
1310 static Standard_Integer clcurvature(Draw_Interpretor&, 
1311                                    Standard_Integer argc, const char** argv)
1312 {
1313   if (argc < 2) return 1; 
1314    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1315                                   ::DownCast(Draw::Get(argv[1]));
1316    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1317                                   ::DownCast(Draw::Get(argv[1]));
1318
1319   if (C2d.IsNull()) {
1320     if (C3d.IsNull()) return 1;
1321     C3d->ClearCurvature();
1322   }
1323   else {
1324     C2d->ClearCurvature();
1325   }
1326   Draw::Repaint();
1327   return 0;
1328 }
1329
1330 //=======================================================================
1331 //function :  radiusmax
1332 //purpose  :  definit le rayon de courbure maximum a afficher
1333 //=======================================================================
1334 static Standard_Integer radiusmax(Draw_Interpretor&, 
1335                                   Standard_Integer argc, const char** argv)
1336 {
1337   if (argc < 3) return 1; 
1338   Standard_Real Radius = Draw::Atof(argv[2]);
1339    Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1340                                   ::DownCast(Draw::Get(argv[1]));
1341    Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1342                                   ::DownCast(Draw::Get(argv[1]));
1343
1344   if (C2d.IsNull()) {
1345     if (C3d.IsNull()) return 1;
1346     C3d->SetRadiusMax(Radius);
1347   }
1348   else {
1349     C2d->SetRadiusMax(Radius);
1350   }
1351   Draw::Repaint();
1352   return 0;
1353 }
1354
1355 //=======================================================================
1356 //function :  radiusratio
1357 //purpose  :  definit le ratio du rayon de courbure a afficher
1358 //=======================================================================
1359 static Standard_Integer radiusratio(Draw_Interpretor&, 
1360                                   Standard_Integer argc, const char** argv)
1361 {
1362   if (argc < 3) return 1;
1363   Standard_Real Ratio = Draw::Atof(argv[2]);
1364   Handle(DrawTrSurf_Curve2d) C2d =  Handle(DrawTrSurf_Curve2d)
1365                                   ::DownCast(Draw::Get(argv[1]));
1366   Handle(DrawTrSurf_Curve) C3d =  Handle(DrawTrSurf_Curve)
1367                                   ::DownCast(Draw::Get(argv[1]));
1368
1369   if (C2d.IsNull()) { 
1370     if (C3d.IsNull()) return 1;
1371     C3d->SetRadiusRatio(Ratio);
1372   }
1373   else {
1374     C2d->SetRadiusRatio(Ratio);
1375   }
1376   Draw::Repaint();
1377   return 0;
1378 }
1379
1380 //=======================================================================
1381 //function : 
1382 //purpose  : 
1383 //=======================================================================
1384 static Standard_Integer localprop(Draw_Interpretor& di, 
1385                                   Standard_Integer argc, const char** argv)
1386 {
1387   if (argc < 3) return 1;
1388
1389   Standard_Real U =  Draw::Atof(argv[2]);
1390
1391   Handle(Geom2d_Curve)  C2d = DrawTrSurf::GetCurve2d(argv[1]);
1392   Handle(Geom_Curve)    C3d;
1393
1394
1395   if (C2d.IsNull()) {
1396     C3d = DrawTrSurf::GetCurve(argv[1]);
1397     if (C3d.IsNull()) return 1;
1398     GeomLProp_CLProps Prop (C3d,2,Precision::Confusion());
1399     Prop.SetParameter(U);
1400     Handle(Draw_Marker3D)drp = new Draw_Marker3D(Prop.Value(),
1401                                                  Draw_Plus,
1402                                                  Draw_vert );
1403     dout << drp;
1404     if (Prop.IsTangentDefined()) {
1405       Standard_Real K = Prop.Curvature();
1406       di <<" Curvature : "<<K<<"\n";
1407
1408       if (Abs(K) > Precision::Confusion()) {
1409         Standard_Real R = 1/Abs(K);
1410         gp_Pnt        Center;
1411         Prop.CentreOfCurvature(Center);
1412         gp_Dir Tang;
1413         gp_Dir Nor;
1414         Prop.Tangent(Tang);
1415         Prop.Normal(Nor);
1416         gp_Dir AxC = Nor^Tang;
1417         gp_Ax2 Axe(Center,AxC,Nor);
1418         Handle(Geom_Circle) Cir3d = new Geom_Circle(Axe,R);
1419         Handle(DrawTrSurf_Curve) dr;
1420         dr = new DrawTrSurf_Curve(Cir3d);
1421         dout << dr;
1422         dout.Flush();
1423       }
1424     }
1425     else 
1426       di <<"Tangent undefined.\n";  
1427   }
1428   else {
1429     Geom2dLProp_CLProps2d Prop (C2d,2,Precision::Confusion());
1430     Prop.SetParameter(U);
1431     Handle(Draw_Marker2D) drp = new Draw_Marker2D(Prop.Value(),
1432                                                   Draw_Plus,
1433                                                   Draw_vert);
1434     dout << drp;
1435     if (Prop.IsTangentDefined()) {
1436       Standard_Real K = Prop.Curvature();
1437       gp_Pnt2d      Center;
1438
1439       di <<" Curvature : "<<K<<"\n";
1440
1441       if (Abs(K) > Precision::Confusion()) {
1442         Standard_Real R = 1/Abs(K);
1443         Prop.CentreOfCurvature(Center);
1444         gp_Ax2d Axe(Center,gp::DX2d());
1445         Handle(Geom2d_Circle) Cir2d = new Geom2d_Circle(Axe,R);
1446         Handle(DrawTrSurf_Curve2d) dr;
1447         dr = new DrawTrSurf_Curve2d(Cir2d,Draw_rouge,30,Standard_False);
1448         dout << dr;
1449         dout.Flush();
1450       }
1451     }
1452     else 
1453       di <<"Tangent undefined.\n";
1454   }
1455   return 0;
1456 }  
1457 //=======================================================================
1458 //function : rawcont
1459 //purpose  : 
1460 //=======================================================================
1461
1462 static Standard_Integer rawcont(Draw_Interpretor& di, Standard_Integer n, const char** a)
1463 {
1464   if (n < 5) return 1;
1465
1466   Handle(Geom_Curve) GC1;
1467   GC1 = DrawTrSurf::GetCurve(a[1]);
1468   Handle(Geom_Curve) GC2;
1469   GC2 = DrawTrSurf::GetCurve(a[2]);
1470   Standard_Real param1 =
1471     Draw::Atof(a[3]) ;
1472   Standard_Real param2 =
1473     Draw::Atof(a[4]) ;
1474   if (GC1.IsNull() || GC2.IsNull())
1475     return 1;
1476   gp_Pnt a_point1,
1477     a_point2 ;
1478   GC1->D0(param1,
1479           a_point1) ;
1480   GC2->D0(param2,
1481           a_point2) ;
1482   if (a_point2.SquareDistance(a_point1) < Precision::Confusion()) {
1483     GeomAbs_Shape cont =
1484       GeomLProp::Continuity(GC1,
1485                             GC2,
1486                             param1,
1487                             param2,
1488                             Standard_True,
1489                             Standard_True,
1490                             Precision::Confusion(),
1491                             Precision::Angular()) ;
1492     switch (cont) {
1493     case GeomAbs_C0: 
1494       di << " C0 Continuity \n" ;
1495       break ;
1496     case GeomAbs_G1:
1497       di << " G1 Continuity \n" ;
1498       break ;
1499     case GeomAbs_C1 :
1500       di << " C1 Continuity \n" ;
1501       break ;
1502     case GeomAbs_G2 :
1503       di << " G2 Continuity \n" ;
1504       break ; 
1505     case GeomAbs_C2 :
1506       di << " C2 Continuity \n" ;
1507       break ; 
1508     case GeomAbs_C3 :
1509       di << " C3 Continuity \n" ;
1510       break ; 
1511     case GeomAbs_CN :
1512       di << " CN Continuity \n" ;
1513       break ; 
1514     default:
1515       break ; 
1516     }
1517   }
1518   else {
1519     di << " not C0 continuity \n" ;
1520   }
1521   return 0 ;
1522 }
1523 //=======================================================================
1524 //function : approxcurveonsurf
1525 //purpose  : 
1526 //=======================================================================
1527 static Standard_Integer approxcurveonsurf(Draw_Interpretor& di, Standard_Integer n, const char** a)
1528 {
1529   Standard_Real Tol = 1.e-7;              // Tolerance (default 0.1mm) 
1530   GeomAbs_Shape Continuity = GeomAbs_C1;  // Continuity order : 0, 1 or 2 (default 1)
1531   Standard_Integer MaxDeg = 14;           // Maximum degree
1532   Standard_Integer MaxSeg = 16; /*1*/          // Maximum number of segments
1533
1534   if ( n>8 || n<4) return 1;
1535
1536   if (n>4) Tol = Max(Draw::Atof(a[4]),1.e-10);
1537
1538   if (n>5) {
1539     if (Draw::Atoi(a[5]) == 0) Continuity = GeomAbs_C0;
1540     if (Draw::Atoi(a[5]) == 2) Continuity = GeomAbs_C2;
1541   }
1542
1543   if (n>6) {
1544     MaxDeg = Draw::Atoi(a[6]);
1545     if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1546   }
1547
1548   if (n>7) MaxSeg = Draw::Atoi(a[7]);
1549   Handle(Geom2d_Curve) curve2d = DrawTrSurf::GetCurve2d(a[2]);
1550   Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[3]);
1551
1552   Handle(Geom2dAdaptor_HCurve) A2d = new (Geom2dAdaptor_HCurve)(curve2d);
1553   Handle(GeomAdaptor_HSurface) AS = new (GeomAdaptor_HSurface)(Surf);
1554
1555   Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(), Tol);
1556   App.Perform(MaxSeg, MaxDeg, Continuity, Standard_True, Standard_False);
1557
1558   if(App.HasResult()) {
1559     Handle(Geom_BSplineCurve) BSCurve = App.Curve3d(); 
1560     DrawTrSurf::Set(a[1], BSCurve);
1561     return 0;
1562   }
1563
1564   di << "Approximation failed !\n";
1565   return 1;
1566                             
1567 }
1568
1569 //=======================================================================
1570 //function : approxcurve
1571 //purpose  : 
1572 //=======================================================================
1573 static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
1574
1575   Standard_Real Tol = 1.e-7;              // Tolerance (default 0.1mm) 
1576   GeomAbs_Shape Continuity = GeomAbs_C1;  // Continuity order : 0, 1 or 2 (default 1)
1577   Standard_Integer MaxDeg = 14;           // Maximum degree
1578   Standard_Integer MaxSeg = 16;           // Maximum number of segments
1579   
1580   Standard_Integer Case, shift;
1581 // Case == 1 : 3d approximation without reparametrization
1582 // Case == 2 : 2d approximation without reparametrization
1583 // Case == 3 : 3d approximation with reparametrization
1584 // Case == 4 : curve_on_surface approximation with reparametrization
1585 // Case == 5 : 2 curves_on_surfaces approximation with reparametrization
1586
1587   Handle(Geom_Curve) curve;
1588   Handle(Geom2d_Curve) curve2d, curve2d2;
1589   Handle(Geom_Surface) surface, surface2;
1590
1591   if(n < 2) return 1;
1592
1593   if (!strcmp(a[1],"-L")) {
1594 // aproximation with curvilinear abscissa reparametrization
1595     if (n > 11 || n < 4) return 1;
1596     Tol = 1.e-4;
1597     curve = DrawTrSurf::GetCurve(a[3]);
1598     if (!curve.IsNull()) {
1599       shift = 4;
1600       Case = 3;
1601     }
1602     else {
1603 // approx curve_on_surface
1604       if (n < 5) return 1;
1605       curve2d = DrawTrSurf::GetCurve2d(a[3]); 
1606       surface = DrawTrSurf::GetSurface(a[4]);
1607       if (curve2d.IsNull() || surface.IsNull()) {
1608         return 1;
1609       }
1610       if (n >= 7) {
1611         curve2d2 = DrawTrSurf::GetCurve2d(a[5]); 
1612         surface2 = DrawTrSurf::GetSurface(a[6]);
1613         if (curve2d2.IsNull() || surface2.IsNull()) {
1614           shift = 5;
1615           Case = 4;
1616         }
1617         else {
1618 // approx 2 curves_on_surfaces
1619           shift = 7;
1620           Case = 5;
1621         }
1622       }
1623       else {
1624         shift = 5;
1625         Case = 4;
1626       }
1627     }
1628   }
1629   else {
1630 // aproximation without reparamitrization
1631     if ( n>7 || n<3) return 1;
1632     shift = 3;
1633     curve = DrawTrSurf::GetCurve(a[2]);
1634     if (curve.IsNull()) {
1635       curve2d = DrawTrSurf::GetCurve2d(a[2]); 
1636       if (curve2d.IsNull()) {
1637         return 1;
1638       }
1639       Case = 2;
1640     }
1641     else
1642       Case = 1;
1643   }
1644   
1645   if (n>shift) Tol = Max(Draw::Atof(a[shift]),1.e-10);
1646   
1647   if (n>shift+1) {
1648     if (Draw::Atoi(a[shift+1]) == 0) Continuity = GeomAbs_C0;
1649     if (Draw::Atoi(a[shift+1]) == 2) Continuity = GeomAbs_C2;
1650   }
1651   
1652   if (n>shift+2) {
1653       MaxDeg = Draw::Atoi(a[shift+2]);
1654       if (MaxDeg<1 || MaxDeg>14) MaxDeg = 14;
1655     }
1656   
1657   if (n>shift+3) MaxSeg = Draw::Atoi(a[shift+3]);
1658     
1659   if (Case == 1) {
1660     GeomConvert_ApproxCurve appr(curve, Tol, Continuity, MaxSeg, MaxDeg);
1661     if(appr.HasResult()) {
1662       //appr.Dump(std::cout);
1663       Standard_SStream aSStream;
1664       appr.Dump(aSStream);
1665       di << aSStream;
1666       Handle(Geom_BSplineCurve) BSCurve = appr.Curve(); 
1667       DrawTrSurf::Set(a[1], BSCurve);
1668     }
1669  }   
1670
1671   else if (Case == 2) {
1672     Geom2dConvert_ApproxCurve appr(curve2d, Tol, Continuity, MaxSeg, MaxDeg);
1673     if(appr.HasResult()) {
1674       //appr.Dump(std::cout);
1675       Standard_SStream aSStream;
1676       appr.Dump(aSStream);
1677       di << aSStream;
1678       Handle(Geom2d_BSplineCurve) BSCurve = appr.Curve(); 
1679       DrawTrSurf::Set(a[1], BSCurve);
1680     }
1681   }    
1682
1683   else if (Case == 3) {
1684     Handle(Adaptor3d_HCurve) HACur = new GeomAdaptor_HCurve(curve);
1685     Approx_CurvilinearParameter appr(HACur, Tol, Continuity, MaxDeg, MaxSeg);
1686     if(appr.HasResult()) {
1687       //appr.Dump(std::cout);
1688       Standard_SStream aSStream;
1689       appr.Dump(aSStream);
1690       di << aSStream;
1691       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1692       DrawTrSurf::Set(a[2], BSCurve);
1693     }
1694 }    
1695   else if (Case == 4) {
1696     Handle(Adaptor2d_HCurve2d) HACur2d = new Geom2dAdaptor_HCurve(curve2d);
1697     Handle(Adaptor3d_HSurface) HASur = new GeomAdaptor_HSurface(surface);
1698     Approx_CurvilinearParameter appr(HACur2d, HASur, Tol, Continuity, MaxDeg, MaxSeg);
1699     if(appr.HasResult()) {
1700       //appr.Dump(std::cout);
1701       Standard_SStream aSStream;
1702       appr.Dump(aSStream);
1703       di << aSStream;
1704       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1705       DrawTrSurf::Set(a[2], BSCurve);
1706     }
1707   }
1708
1709   else if (Case == 5) {
1710     Handle(Adaptor2d_HCurve2d) HACur2d = new Geom2dAdaptor_HCurve(curve2d);
1711     Handle(Adaptor3d_HSurface) HASur = new GeomAdaptor_HSurface(surface);
1712     Handle(Adaptor2d_HCurve2d) HACur2d2 = new Geom2dAdaptor_HCurve(curve2d2);
1713     Handle(Adaptor3d_HSurface) HASur2 = new GeomAdaptor_HSurface(surface2);
1714     Approx_CurvilinearParameter appr(HACur2d, HASur, HACur2d2, HASur2, Tol, Continuity, MaxDeg, MaxSeg);
1715     if(appr.HasResult()) {
1716       //appr.Dump(std::cout);
1717       Standard_SStream aSStream;
1718       appr.Dump(aSStream);
1719       di << aSStream;
1720       Handle(Geom_BSplineCurve) BSCurve = appr.Curve3d(); 
1721       DrawTrSurf::Set(a[2], BSCurve);
1722     }
1723   }
1724   
1725
1726   return 0;
1727 }
1728
1729
1730 //=======================================================================
1731 //function : fitcurve
1732 //purpose  : 
1733 //=======================================================================
1734
1735 static Standard_Integer fitcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
1736 {
1737   if (n<3) return 1;
1738
1739   Handle(Geom_Curve) GC;
1740   GC = DrawTrSurf::GetCurve(a[2]);
1741   if (GC.IsNull())
1742     return 1;
1743
1744   Standard_Integer Dmin = 3;
1745   Standard_Integer Dmax = 14;
1746   Standard_Real Tol3d = 1.e-5;
1747   Standard_Boolean inverse = Standard_True;
1748
1749   if (n > 3)
1750   {
1751     Tol3d = Atof(a[3]);
1752   }
1753
1754   if (n > 4)
1755   {
1756     Dmax = atoi(a[4]);
1757   }
1758
1759   if (n > 5)
1760   {
1761     Standard_Integer inv = atoi(a[5]);
1762     if (inv > 0)
1763     {
1764       inverse = Standard_True;
1765     }
1766     else
1767     {
1768       inverse = Standard_False;
1769     }
1770   }
1771
1772   Handle(GeomAdaptor_HCurve) aGAC = new GeomAdaptor_HCurve(GC);
1773
1774   CurveEvaluator aCE(aGAC);
1775
1776   Approx_FitAndDivide anAppro(Dmin, Dmax, Tol3d, 0., Standard_True);
1777   anAppro.SetInvOrder(inverse);
1778   anAppro.Perform(aCE);
1779
1780   if (!anAppro.IsAllApproximated())
1781   {
1782     di << "Approximation failed \n";
1783     return 1;
1784   }
1785   Standard_Integer i;
1786   Standard_Integer NbCurves = anAppro.NbMultiCurves();
1787
1788   Convert_CompBezierCurvesToBSplineCurve Conv;
1789
1790   Standard_Real tol3d, tol2d, tolreached = 0.;
1791   for (i = 1; i <= NbCurves; i++) {
1792     anAppro.Error(i, tol3d, tol2d);
1793     tolreached = Max(tolreached, tol3d);
1794     AppParCurves_MultiCurve MC = anAppro.Value(i);
1795     TColgp_Array1OfPnt Poles(1, MC.Degree() + 1);
1796     MC.Curve(1, Poles);
1797     Conv.AddCurve(Poles);
1798   }
1799   Conv.Perform();
1800   Standard_Integer NbPoles = Conv.NbPoles();
1801   Standard_Integer NbKnots = Conv.NbKnots();
1802
1803   TColgp_Array1OfPnt      NewPoles(1, NbPoles);
1804   TColStd_Array1OfReal    NewKnots(1, NbKnots);
1805   TColStd_Array1OfInteger NewMults(1, NbKnots);
1806
1807   Conv.KnotsAndMults(NewKnots, NewMults);
1808   Conv.Poles(NewPoles);
1809
1810   BSplCLib::Reparametrize(GC->FirstParameter(),
1811     GC->LastParameter(),
1812     NewKnots);
1813   Handle(Geom_BSplineCurve) TheCurve = new Geom_BSplineCurve(NewPoles, NewKnots, NewMults, Conv.Degree());
1814
1815   DrawTrSurf::Set(a[1], TheCurve);
1816   di << a[1] << ": tolreached = " << tolreached << "\n";
1817
1818   return 0;
1819
1820 }
1821
1822 //=======================================================================
1823 //function : newbspline
1824 //purpose  : reduce the multiplicity of the knots to their minimum 
1825 //           compared to the degree of the curve
1826 //=======================================================================
1827
1828 static Standard_Integer splitc1(Draw_Interpretor& di,
1829                                    Standard_Integer n, const char** c)
1830
1831 {Standard_Real      tolerance=1.0e-5,
1832    angular_tolerance = 1.0e-4 ;
1833  Standard_Integer   optiontab,i;
1834  char name[100];
1835
1836  if (n<3) return 1;
1837  optiontab=Draw::Atoi(c[2]);
1838  if (n >= 4 )
1839    tolerance=Draw::Atof(c[3]);
1840  if (n >= 5) {
1841    angular_tolerance = Draw::Atof(c[4]) ;
1842  }
1843  Handle(Geom_Curve) ACurve = Handle(Geom_Curve)::DownCast(DrawTrSurf::Get(c[1])) ;
1844  
1845  Standard_Real f = ACurve->FirstParameter();
1846  Standard_Real l = ACurve->LastParameter();
1847
1848  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
1849    di << " Error: Infinite curves\n";
1850    return 1;
1851  }
1852
1853  Handle(Geom_BSplineCurve) BS = GeomConvert::CurveToBSplineCurve(ACurve);
1854  
1855  if ( BS.IsNull()) return 1;
1856
1857  if (optiontab){
1858    Handle(TColGeom_HArray1OfBSplineCurve)  tabBS;
1859    GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS,
1860                                                  tabBS,
1861                                                  angular_tolerance,
1862                                                  tolerance);
1863    for (i=0;i<=(tabBS->Length()-1);i++){
1864      Sprintf(name,"%s_%d",c[1],i+1);
1865      Standard_CString new_name = name ;
1866      DrawTrSurf::Set(new_name,
1867                      tabBS->Value(i));
1868      di.AppendElement(name);
1869    }
1870  }
1871  else{
1872    GeomConvert::C0BSplineToC1BSplineCurve(BS,
1873                                           tolerance,
1874                                           angular_tolerance) ;
1875
1876    DrawTrSurf::Set(c[1],BS);
1877  }
1878  return 0;
1879 }
1880
1881 //=======================================================================
1882 //function : splitc12d
1883 //purpose  : reduce the multiplicity of the knots to their minimum 
1884 //           compared to the degree of the curve
1885 //=======================================================================
1886
1887 static Standard_Integer splitc12d(Draw_Interpretor& di,
1888                                      Standard_Integer n, const char** c)
1889
1890 {Standard_Real      tolerance=1.0e-5,
1891    angular_tolerance = 1.0e-4 ;
1892  Standard_Integer   optiontab,i;
1893  char name[100];
1894
1895  if (n<3) return 1;
1896  optiontab=Draw::Atoi(c[2]);
1897  if (n==4)
1898    tolerance=Draw::Atof(c[3]);
1899  if (n==5) 
1900    angular_tolerance = Draw::Atof(c[4]) ;
1901  Handle(Geom2d_Curve) ACurve = DrawTrSurf::GetCurve2d(c[1]);
1902  
1903  Standard_Real f = ACurve->FirstParameter();
1904  Standard_Real l = ACurve->LastParameter();
1905
1906  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
1907    di << " Error: Infinite curves\n";
1908    return 1;
1909  }
1910
1911  Handle(Geom2d_BSplineCurve) BS = Geom2dConvert::CurveToBSplineCurve(ACurve);
1912  
1913  if ( BS.IsNull()) return 1;
1914
1915  if (optiontab){
1916    Handle(TColGeom2d_HArray1OfBSplineCurve)  tabBS;
1917    Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(BS,
1918                                                    tabBS,
1919                                                    angular_tolerance,
1920                                                    tolerance);
1921    for (i=0;i<=(tabBS->Length()-1);i++){
1922      Sprintf(name,"%s_%d",c[1],i+1);
1923      Standard_CString new_name = name ;
1924      DrawTrSurf::Set(new_name,
1925                      tabBS->Value(i));
1926      di.AppendElement(name);
1927    }
1928  }
1929  else{
1930    Geom2dConvert::C0BSplineToC1BSplineCurve(BS,tolerance);
1931    DrawTrSurf::Set(c[1],BS);
1932  }
1933  return 0;
1934 }
1935
1936 //=======================================================================
1937 //function : canceldenom
1938 //purpose  : set the value of the denominator cancel its first 
1939 //           derivative on the boundaries of the surface if possible
1940 //=======================================================================
1941
1942 static Standard_Integer canceldenom(Draw_Interpretor& ,
1943                                      Standard_Integer n, const char** c)
1944
1945 {Standard_Integer    uoption,voption;
1946  Standard_Boolean    udirection=Standard_False;
1947  Standard_Boolean    vdirection=Standard_False;
1948  if (n<4) return 1;
1949  uoption=Draw::Atoi(c[2]);
1950  voption=Draw::Atoi(c[3]);
1951  if (uoption)
1952    udirection=Standard_True;
1953  if (voption)
1954    vdirection=Standard_True;
1955  Handle(Geom_BSplineSurface) BSurf = DrawTrSurf::GetBSplineSurface(c[1]);
1956  GeomLib::CancelDenominatorDerivative(BSurf,udirection,vdirection);
1957  DrawTrSurf::Set(c[1],BSurf);
1958  return 0;
1959 }
1960
1961 //=======================================================================
1962 //function : length
1963 //purpose  : eval curve's length
1964 //=======================================================================
1965
1966 static Standard_Integer length(Draw_Interpretor& di,
1967                                Standard_Integer n, const char** a)
1968 {
1969   if (n<2) return 1;
1970   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
1971   Handle(Geom2d_Curve) GC2d = DrawTrSurf::GetCurve2d(a[1]);
1972   Standard_Real Tol = Precision::Confusion(), L;
1973   if (n==3) Tol = Draw::Atof(a[2]);
1974
1975   if (!GC.IsNull()) {
1976     GeomAdaptor_Curve AC(GC);
1977     L = GCPnts_AbscissaPoint::Length(AC, Tol);
1978   }  
1979   else if (!GC2d.IsNull()) {
1980     Geom2dAdaptor_Curve AC(GC2d);
1981     L = GCPnts_AbscissaPoint::Length(AC, Tol);
1982   }
1983   else {
1984     di << a[1] << "is not a curve\n";
1985     return 1;
1986   }
1987
1988   di << "The length " << a[1] << " is " << L << "\n";
1989   return 0;
1990 }
1991
1992
1993
1994 //=======================================================================
1995 //function : CurveCommands
1996 //purpose  : 
1997 //=======================================================================
1998
1999 void  GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
2000 {
2001   
2002   static Standard_Boolean loaded = Standard_False;
2003   if (loaded) return;
2004   loaded = Standard_True;
2005   
2006   DrawTrSurf::BasicCommands(theCommands);
2007   
2008   const char* g;
2009   
2010   
2011   // analytic curves
2012   g = "GEOMETRY curves creation";
2013
2014
2015   theCommands.Add("point",
2016                   "point name x y [z]",
2017                   __FILE__,
2018                   point ,g);
2019   
2020   theCommands.Add("line",
2021                   "line name pos dir",
2022                   __FILE__,
2023                   anacurve,g);
2024   
2025   theCommands.Add("circle",
2026                   "circle name x y [z [dx dy dz]] [ux uy [uz]] radius",
2027                   __FILE__,
2028                   anacurve,g);
2029   
2030   theCommands.Add("ellipse",
2031                   "ellipse name x y [z [dx dy dz]] [ux uy [uz]] major minor",
2032                   __FILE__,
2033                   anacurve,g);
2034   theCommands.Add("parabola",
2035                   "parabola name x y [z [dx dy dz]] [ux uy [uz]] focal",
2036                   __FILE__,
2037                   anacurve,g);
2038   theCommands.Add("hyperbola",
2039                   "hyperbola name x y [z [dx dy dz]] [ux uy [uz]] major minor",
2040                   __FILE__,
2041                   anacurve,g);
2042
2043   theCommands.Add("beziercurve",
2044                   "beziercurve name nbpole pole, [weight]",
2045                   __FILE__,
2046                   polecurve,g);
2047
2048   theCommands.Add("bsplinecurve",
2049                   "bsplinecurve name degree nbknots  knot, umult  pole, weight",
2050                   __FILE__,
2051                   polecurve,g);
2052
2053   theCommands.Add("pbsplinecurve",
2054                   "pbsplinecurve name degree nbknots  knot, umult  pole, weight (periodic)",
2055                   __FILE__,
2056                   polecurve,g);
2057
2058   theCommands.Add("2dbeziercurve",
2059                   "2dbeziercurve name nbpole pole, [weight]",
2060                   __FILE__,
2061                   polecurve2d,g);
2062
2063   theCommands.Add("2dbsplinecurve",
2064                   "2dbsplinecurve name degree nbknots  knot, umult  pole, weight",
2065                   __FILE__,
2066                   polecurve2d,g);
2067
2068   theCommands.Add("2dpbsplinecurve",
2069                   "2dpbsplinecurve name degree nbknots  knot, umult  pole, weight (periodic)",
2070                   __FILE__,
2071                   polecurve2d,g);
2072
2073   g = "GEOMETRY Curves and Surfaces modification";
2074
2075   theCommands.Add("reverse",
2076                   "reverse name ... ",
2077                   __FILE__,
2078                   reverse,g);
2079
2080   theCommands.Add("cmovep",
2081                   "cmovep name index dx dy dz",
2082                   __FILE__,
2083                   cmovepole,g);
2084
2085   theCommands.Add("cmovepoint",
2086                   "cmovepoint name u dx dy [dz index1 index2]",
2087                   __FILE__,
2088                   cmovepoint,g);
2089
2090   theCommands.Add("cmovetangent",
2091                   "cmovetangent name u  x y [z] tx ty [tz constraint = 0]",
2092                   __FILE__,
2093                   cmovetangent,g) ;
2094
2095   theCommands.Add("insertknot",
2096                   "insertknot name knot [mult = 1] [knot mult ...]",
2097                   __FILE__,
2098                   cinsertknot,g);
2099
2100   theCommands.Add("setknot",
2101                   "setknot name index knot [mult]",
2102                   __FILE__,
2103                   csetknot,g);
2104
2105   theCommands.Add("remknot",
2106                   "remknot name index [mult] [tol]",
2107                   __FILE__,
2108                   cremknot,g);
2109
2110   theCommands.Add("incdeg",
2111                   "incdeg name degree",
2112                   __FILE__,
2113                   increasedegree,g);
2114
2115   theCommands.Add("rempole",
2116                   "rempole name index",
2117                   __FILE__,
2118                   removepole,g);
2119
2120   theCommands.Add("insertpole",
2121                   "insertpole name index x y [z] [weight]",
2122                   __FILE__,
2123                   insertpole,g);
2124
2125   theCommands.Add("cfindp",
2126                   "cfindp name view x y index",
2127                   __FILE__,
2128                   cfindp,g);
2129
2130   theCommands.Add("setperiodic",
2131                   "setperiodic name ...",
2132                   __FILE__,
2133                   csetperiodic,g);
2134
2135   theCommands.Add("setnotperiodic",
2136                   "setnotperiodic name",
2137                   __FILE__,
2138                   csetperiodic,g);
2139
2140   theCommands.Add("segment",
2141                   "segment name Ufirst Ulast [tol]",
2142                    __FILE__,
2143                   segment , g);
2144
2145   theCommands.Add("setorigin",
2146                   "setorigin name knotindex",
2147                    __FILE__,
2148                   setorigin , g);
2149
2150   g = "GEOMETRY curves and surfaces analysis";
2151
2152   theCommands.Add("cvalue",
2153                   "cvalue curvename U  X Y Z [D1X D1Y D1Z D2X D2Y D2Z]",
2154                   __FILE__,
2155                   value,g);
2156
2157   theCommands.Add("2dcvalue",
2158                   "2dcvalue curvename U  X Y [D1X D1Y D2X D2Y]",
2159                   __FILE__,
2160                   value2d,g);
2161
2162   theCommands.Add("coord",
2163                   "coord P x y [z]: set in x y [z] the coordinates of P",
2164                   __FILE__,
2165                   coord,g);
2166
2167   theCommands.Add("minmaxcurandinf",
2168                   "minmaxcurandinf curve",
2169                   __FILE__,
2170                   minmaxcurandinf,g);
2171   
2172   theCommands.Add("shcurvature",
2173                   "shcurvature curvename",
2174                   __FILE__,
2175                   shcurvature,g);
2176
2177   theCommands.Add("clcurvature",
2178                   "clcurvature curvename",
2179                   __FILE__,
2180                   clcurvature,g);
2181   
2182
2183  theCommands.Add("radiusmax",
2184                   "radiusmax curvename  radius",
2185                   __FILE__,
2186                   radiusmax,g);
2187
2188  theCommands.Add("radiusratio",
2189                   "radiusratio curvename ratio",
2190                   __FILE__,
2191                   radiusratio,g); 
2192   theCommands.Add("localprop",
2193                   "localprop curvename U",
2194                   __FILE__,
2195                   localprop,g);
2196   theCommands.Add("rawcont",
2197                   "rawcont curve1 curve2 u1 u2",
2198                   __FILE__,
2199                   rawcont,g) ;
2200   theCommands.Add("approxcurve",
2201                   "approxcurve [-L] name curve1 [Surf1] [curve2d2 Surf2] [Tol [cont [maxdeg [maxseg]]]] ",
2202                   __FILE__,
2203                   approxcurve,g);
2204
2205   theCommands.Add("approxcurveonsurf",
2206                   "approxcurveonsurf name curve2d surface [Tol [cont [maxdeg [maxseg]]]] ",
2207                   __FILE__,
2208                   approxcurveonsurf,g);
2209
2210  theCommands.Add("fitcurve", "fitcurve result  curve [tol [maxdeg [inverse]]]", __FILE__, fitcurve, g);
2211
2212  theCommands.Add("length", "length curve [Tol]", 
2213                   __FILE__,
2214                   length, g);
2215
2216
2217   theCommands.Add("splitc1",
2218                   "splitc1 bspline resultinarray(0/1) [tol] [angtol] ",
2219                   __FILE__,
2220                   splitc1,g);
2221
2222   theCommands.Add("splitc12d",
2223                   "splitc12d bspline2d resultinarray(0/1) [tol] [angtol] ",
2224                   __FILE__,
2225                   splitc12d,g);
2226   theCommands.Add("canceldenom",
2227                   "canceldenom BSpline-Surface UDirection(0/1) VDirection(0/1)",
2228                   __FILE__,
2229                   canceldenom,g);
2230
2231  
2232
2233 }