0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / GeomliteTest / GeomliteTest_ApproxCommands.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 // PMN : Ajout de la commande smooth
18 // PMN : 11/07/97 Passage a GeomliteTest de bsmooth.
19
20 #include <Standard_Stream.hxx>
21
22 #include <GeomliteTest.hxx>
23 #include <DrawTrSurf.hxx>
24 #include <Draw.hxx>
25 #include <Draw_Appli.hxx>
26 #include <Draw_Interpretor.hxx>
27 #include <Draw_Marker3D.hxx>
28 #include <Draw_Marker2D.hxx>
29 #include <TColgp_SequenceOfPnt.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <Geom_BezierCurve.hxx>
32 #include <TColgp_SequenceOfPnt2d.hxx>
33
34 #include <Geom2d_BSplineCurve.hxx>
35 #include <Geom2d_BezierCurve.hxx>
36 #include <DrawTrSurf_BSplineCurve.hxx>
37 #include <DrawTrSurf_BezierCurve.hxx>
38 #include <DrawTrSurf_BSplineCurve2d.hxx>
39 #include <DrawTrSurf_BezierCurve2d.hxx>
40 #include <TColgp_HArray1OfPnt.hxx>
41 #include <TColgp_Array1OfPnt.hxx>
42 #include <TColgp_Array1OfPnt2d.hxx>
43
44 #include <AppDef_Variational.hxx>
45 #include <AppDef_Compute.hxx>
46 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
47 #include <AppParCurves_ConstraintCouple.hxx>
48 #include <AppDef_HArray1OfMultiPointConstraint.hxx>
49 #include <AppDef_Array1OfMultiPointConstraint.hxx>
50
51 #ifdef _WIN32
52 Standard_IMPORT Draw_Viewer dout;
53 #endif
54
55 //Draw_Color DrawTrSurf_CurveColor(const Draw_Color);
56
57 //=======================================================================
58 //function :  NbConstraint
59 //=======================================================================
60 static Standard_Integer  NbConstraint(const AppParCurves_Constraint C1,
61                                       const AppParCurves_Constraint C2)
62 {
63    Standard_Integer N =0;
64    switch (C1) {
65    case  AppParCurves_PassPoint : 
66      {
67        N = 1;
68        break;
69      }
70    case  AppParCurves_TangencyPoint : 
71      {
72        N =2;
73        break;
74      }
75    case  AppParCurves_CurvaturePoint : 
76      {
77        N = 3;
78        break;
79      }     
80    default:
81        break;
82    }
83
84    switch (C2) {
85    case  AppParCurves_PassPoint : 
86      {
87        N++;
88        break;
89      }
90    case  AppParCurves_TangencyPoint : 
91      {
92        N += 2;
93        break;
94      }
95    case  AppParCurves_CurvaturePoint : 
96      {
97        N += 3;
98        break;
99      }     
100    default:
101        break;
102    }
103    return N;
104 }
105 //=======================================================================
106 //function : PointsByPick
107 //=======================================================================
108 static Standard_Integer PointsByPick
109        (Handle(AppDef_HArray1OfMultiPointConstraint)& MPC, Draw_Interpretor& di)
110 {
111  Standard_Integer id,XX,YY,b, i;
112  
113  di << "Pick points \n";
114  dout.Select(id, XX, YY, b);
115  Standard_Real zoom = dout.Zoom(id);
116  if (b != 1) return 0;
117  if (id < 0) return 0;
118  gp_Pnt P;
119  gp_Pnt2d P2d;
120
121  //Standard_Boolean newcurve;
122     
123  if (dout.Is3D(id)) {
124    // Cas du 3D -------
125    Handle(Draw_Marker3D) mark;
126    TColgp_SequenceOfPnt ThePoints;
127    P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
128    ThePoints.Append (P);
129    mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
130    dout << mark;
131    dout.Flush();
132    i = 1;
133       
134    while (b != 3) {
135      dout.Select(id,XX,YY,b, Standard_False);
136      if (b == 1) { 
137        i++;
138        P.SetCoord( (Standard_Real)XX/zoom,
139                   (Standard_Real)YY/zoom, 0.0);
140        ThePoints.Append(P);
141        mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
142        dout << mark;
143        dout.Flush();
144      }
145    }
146
147    MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
148    AppDef_MultiPointConstraint mpc(1,0);
149    MPC->ChangeArray1().Init(mpc);
150    for (i=1; i<=ThePoints.Length(); i++) {
151       AppDef_MultiPointConstraint aLocalMpc(1,0);
152       aLocalMpc.SetPoint(1, ThePoints.Value(i));
153       MPC->SetValue(i, aLocalMpc);
154    }  
155  }
156  
157  else {
158    // Cas du 2D -------
159    Handle(Draw_Marker2D) mark;
160    TColgp_SequenceOfPnt2d ThePoints;
161    P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
162    ThePoints.Append(P2d);
163    mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
164    dout << mark;
165    dout.Flush();
166    i = 1;
167       
168    while (b != 3) {
169      dout.Select(id,XX,YY,b, Standard_False);
170      
171      if (b == 1) { 
172        i++;
173        P2d.SetCoord( (Standard_Real)XX/zoom, (Standard_Real)YY/zoom );
174        ThePoints.Append (P2d);
175        mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
176        dout << mark;
177        dout.Flush();
178      }
179    }
180
181    MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
182    for (i=1; i<=ThePoints.Length(); i++) {
183      AppDef_MultiPointConstraint mpc(0,1);
184      mpc.SetPoint2d(1, ThePoints.Value(i));
185      MPC->SetValue(i,  mpc);
186    }
187  }
188  return id;
189 }
190
191 //=======================================================================
192 //function : PointsByFile
193 //=======================================================================
194 static void PointsByFile(Handle(AppDef_HArray1OfMultiPointConstraint)& MPC,
195                          Handle(AppParCurves_HArray1OfConstraintCouple)& TABofCC,
196                          std::ifstream& iFile,
197                          Draw_Interpretor& di)
198 {
199   Standard_Integer nbp, i, nbc;
200   char c;
201   Standard_Real x, y, z;
202
203   iFile >> nbp;
204   char dimen[3];
205   iFile >> dimen;
206
207   if (!strcmp(dimen,"3d")) {
208     Handle(Draw_Marker3D) mark;
209     MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
210
211     for (i = 1; i <= nbp; i++) {
212       iFile >> x >> y >> z;
213       AppDef_MultiPointConstraint mpc(1,0);
214       mpc.SetPoint(1, gp_Pnt(x, y, z));
215       MPC->SetValue(i,mpc);
216       mark = new Draw_Marker3D(gp_Pnt(x, y, z), Draw_X, Draw_orange);
217       dout << mark;
218     }
219     Standard_Boolean HasConstrainte = Standard_False;
220     if (iFile.get(c)) {
221       if ( IsControl( (Standard_Character)c) ) {   
222         if (iFile.get(c))  HasConstrainte = Standard_True;
223       }
224       else  HasConstrainte = Standard_True;
225     }
226
227     if (HasConstrainte) {
228       Standard_Integer num, ordre;
229       iFile >> nbc;
230       if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
231       AppParCurves_Constraint  Constraint = AppParCurves_NoConstraint;
232       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
233       for(i=1; i<=nbp; i++){
234         AppParCurves_ConstraintCouple ACC(i,Constraint);
235         TABofCC->SetValue(i,ACC);
236       }
237       for(i=1; i<=nbc; i++) {
238         iFile >> num >> ordre;
239         if ((num<1)||(num>nbp)) {
240           di << "Error on point Index in constrainte\n";
241           return;
242         }
243         Constraint = (AppParCurves_Constraint) (ordre+1);
244         TABofCC->ChangeValue(num).SetConstraint(Constraint);
245         if (Constraint >=  AppParCurves_TangencyPoint) {
246           iFile >> x >> y >> z;
247           MPC->ChangeValue(num).SetTang(1, gp_Vec(x,y,z));
248         }
249         if (Constraint >=  AppParCurves_CurvaturePoint) {
250           iFile >> x >> y >> z;
251           MPC->ChangeValue(num).SetCurv(1, gp_Vec(x,y,z));
252         }
253       }
254     }
255     
256   }
257   else if (!strcmp(dimen,"2d")) {
258     Handle(Draw_Marker2D) mark;
259     MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
260
261     for (i = 1; i <= nbp; i++) {
262       iFile >> x >> y;
263       AppDef_MultiPointConstraint mpc(0,1);
264       mpc.SetPoint2d(1, gp_Pnt2d(x, y));
265       MPC->SetValue(i, mpc);
266       mark = new Draw_Marker2D(gp_Pnt2d(x, y), Draw_X, Draw_orange);
267       dout << mark;
268     }
269
270     Standard_Boolean HasConstrainte = Standard_False;
271     if (iFile.get(c)) {
272       if ( IsControl( (Standard_Character)c) )  {
273         if (iFile.get(c))  HasConstrainte = Standard_True;
274       }
275       else  HasConstrainte = Standard_True;
276     }
277
278     if (HasConstrainte) {
279       Standard_Integer num, ordre;
280       iFile >> nbc;
281       if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
282       AppParCurves_Constraint  Constraint = AppParCurves_NoConstraint;
283       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
284       for(i=1; i<=nbp; i++){
285         AppParCurves_ConstraintCouple ACC(i,Constraint);
286         TABofCC->SetValue(i,ACC);
287       }
288       for(i=1; i<=nbc; i++) {
289         iFile >> num >> ordre;
290         if ((num<1)||(num>nbp)) {
291           di << "Error on point Index in constrainte\n";
292           return;
293         }
294         Constraint = (AppParCurves_Constraint) (ordre+1);
295         TABofCC->ChangeValue(num).SetConstraint(Constraint);
296         if (Constraint >=  AppParCurves_TangencyPoint) {
297           iFile >> x >> y;
298           MPC->ChangeValue(num).SetTang2d(1, gp_Vec2d(x,y));
299         }
300         if (Constraint >=  AppParCurves_CurvaturePoint) {
301           iFile >> x >> y;
302           MPC->ChangeValue(num).SetCurv2d(1, gp_Vec2d(x,y));
303         }
304       }
305     }
306   }  
307 }
308
309
310
311 //==================================================================================
312 static Standard_Integer smoothing (Draw_Interpretor& di,Standard_Integer n, const char** a)
313 //==================================================================================
314 //  Tolerance < 0 lissage "filtre"
315 //  Tolerance > 0 lissage avec respect de l'erreur max
316 //  Tolerance = 0 interpolation.
317 //
318 {
319   Standard_Real Tolerance=0;
320
321   AppParCurves_Constraint  Constraint=AppParCurves_NoConstraint;
322
323   Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
324   TABofCC.Nullify();
325   Handle(AppDef_HArray1OfMultiPointConstraint) Points;
326   Standard_Integer id = 0, DegMax = -1;
327
328   if (n == 1) {
329     di <<"give a name to your curve !\n";
330     return 0;
331   }
332   if (n == 2) {
333     di <<"give a tolerance to your curve !\n";
334     return 0;
335   }
336   if (n == 3) {
337     Tolerance = Draw::Atof(a[2]);
338     if (Abs(Tolerance) < Precision::Confusion()*1.e-7)  {
339       Constraint = AppParCurves_PassPoint;
340     }
341     else {
342       Constraint = AppParCurves_NoConstraint;
343     } 
344     // Designation Graphique ------------------------
345     id = PointsByPick(Points, di);
346   }
347   else if (n >= 4) {
348     Standard_Integer ific = 3;
349     Tolerance = Draw::Atof(a[2]);
350     if (Abs(Tolerance) < Precision::Confusion()*1.e-7)  {
351       Constraint = AppParCurves_PassPoint;
352     }
353     else {
354       Constraint = AppParCurves_NoConstraint;
355     }
356
357     if (! strcmp(a[3],"-D")) {
358        DegMax = Draw::Atoi(a[4]);
359        ific = 5;
360     }
361     
362     if (n > ific) {
363       // lecture du fichier.
364     // nbpoints, 2d ou 3d, puis valeurs.
365       const char* nomfic = a[ific];
366       std::ifstream iFile(nomfic, std::ios::in);
367       if (!iFile) { 
368         di << a[ific] <<"do not exist !\n";
369         return 1;
370       }
371       PointsByFile(Points, TABofCC, iFile, di);
372     }
373     else {
374     // Designation Graphique
375     id = PointsByPick(Points, di);
376     }
377   }
378
379   AppDef_MultiLine AML(Points->Array1());
380
381   // Compute --------------
382   Standard_Integer i;
383   if (Points->Value(1).NbPoints()==0){
384     // Cas 2d
385     Handle(TColgp_HArray1OfPnt2d) ThePoints;
386     // Calcul du lissage
387     Standard_Integer NbPoints = Points->Length();
388     if (TABofCC.IsNull()) {
389       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
390       for(i=1; i<=NbPoints; i++){
391         AppParCurves_ConstraintCouple ACC(i,Constraint);
392         TABofCC->SetValue(i,ACC);
393       }
394     }
395
396     AppDef_Variational Variation(AML, 
397                                     1, NbPoints,
398                                     TABofCC);
399     
400     if (DegMax > 0) {
401       if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
402       else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
403       Variation.SetMaxDegree(DegMax);
404     }
405     Variation.SetTolerance( Abs(Tolerance));
406     if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
407     Variation.Approximate();
408
409 #  ifdef GEOMLITETEST_DEB
410     //Variation.Dump(std::cout);
411     Standard_SStream aSStream;
412     Variation.Dump(aSStream);
413     di << aSStream;
414 #   endif
415
416     AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
417
418     TColgp_Array1OfPnt2d ThePoles (1,  AnMuC.NbPoles() ); 
419     AnMuC.Curve(1, ThePoles);    
420     Handle(Geom2d_BSplineCurve) Cvliss = new (Geom2d_BSplineCurve)
421       (ThePoles,
422        AnMuC.Knots(),
423        AnMuC. Multiplicities(),
424        AnMuC.Degree() );
425
426     Handle(DrawTrSurf_BSplineCurve2d) 
427       DC = new DrawTrSurf_BSplineCurve2d(Cvliss);
428     DC->ClearPoles();
429     Draw::Set(a[1], DC);
430     if (id!=0) dout.RepaintView(id); 
431   }
432   else {
433     Standard_Integer NbPoints = Points->Length();
434     if (TABofCC.IsNull()) {
435       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
436       for(i=1; i<=NbPoints; i++){
437         AppParCurves_ConstraintCouple ACC(i,Constraint);
438         TABofCC->SetValue(i,ACC);
439       }
440     } 
441
442     AppDef_Variational Variation(AML, 
443                                     1,  NbPoints,
444                                     TABofCC);
445
446     if (DegMax > 0) {
447       if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
448       else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
449       Variation.SetMaxDegree(DegMax);
450     }
451     Variation.SetTolerance( Abs(Tolerance));
452     if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
453     Variation.Approximate();
454 #     ifdef GEOMLITETEST_DEB
455     //Variation.Dump(std::cout);
456     Standard_SStream aSStream;
457     Variation.Dump(aSStream);
458     di << aSStream;
459 #     endif
460
461     AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
462
463     TColgp_Array1OfPnt ThePoles (1,  AnMuC.NbPoles() ); 
464     AnMuC.Curve(1, ThePoles);    
465     Handle(Geom_BSplineCurve) Cvliss = new (Geom_BSplineCurve)
466       (ThePoles,
467        AnMuC.Knots(),
468        AnMuC. Multiplicities(),
469        AnMuC.Degree() );
470
471     Handle(DrawTrSurf_BSplineCurve) 
472       DC = new DrawTrSurf_BSplineCurve(Cvliss);
473     DC->ClearPoles();
474     Draw::Set(a[1], DC);
475     if (id!=0) dout.RepaintView(id);
476   }
477   return 0;
478 }
479
480 //=============================================================================
481 static Standard_Integer smoothingbybezier (Draw_Interpretor& di,
482                                            Standard_Integer n, 
483                                            const char** a)
484 //============================================================================
485 {
486   Standard_Real Tolerance=0;
487   AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
488   Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
489   Handle(AppDef_HArray1OfMultiPointConstraint) Points;
490
491   Standard_Integer id = 0;
492   Standard_Integer methode=0;
493   Standard_Integer Degree = 8;
494
495   if (n == 1) {
496     di <<"give a name to your curve !\n";
497     return 0;
498   }
499   if (n == 2) {
500     di <<"give a tolerance to your curve !\n";
501     return 0;
502   }
503  if (n == 3) {
504     di <<"give a max degree!\n";
505     return 0;
506   }
507
508   if (n == 4) {
509     di <<"give an option!\n";
510     return 0;
511   }
512   if (n >= 5) {
513     Tolerance = Draw::Atof(a[2]);
514     Degree = Draw::Atoi(a[3]);
515     if (! strcmp(a[4],"-GR")) {
516       methode = 1;
517     }
518     else if (! strcmp(a[4],"-PR")) {
519       methode = 2;
520     }
521     else { methode = 3;}
522     
523     if (Abs(Tolerance) < Precision::Confusion()*1.e-7)  {
524       Constraint = AppParCurves_PassPoint;
525     }
526     else {
527       Constraint = AppParCurves_NoConstraint;
528     } 
529     if (n==5)
530       // Designation Graphique ------------------------
531      id = PointsByPick(Points, di);
532     else {
533       // lecture du fichier.
534       // nbpoints, 2d ou 3d, puis valeurs.
535       const char* nomfic = a[5];
536       std::ifstream iFile(nomfic, std::ios::in);
537       if (!iFile) { 
538         di << a[6] <<"do not exist !\n";
539         return 1;
540       }
541       PointsByFile(Points, TABofCC, iFile, di);
542     }
543   }
544     
545   AppDef_MultiLine AML(Points->Array1());  
546
547   // Compute --------------
548   Standard_Integer i;
549   if (Points->Value(1).NbPoints()==0){
550     // Cas 2d
551     Handle(TColgp_HArray1OfPnt2d) ThePoints;
552     // Calcul du lissage
553     Standard_Integer NbPoints = Points->Length();
554     if (TABofCC.IsNull()) {
555       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
556       for(i=1; i<=NbPoints; i++){
557         AppParCurves_ConstraintCouple ACC(i,Constraint);
558         TABofCC->SetValue(i,ACC);
559       }
560
561       AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
562       if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
563         TABofCC->SetValue(1, AC1);
564     
565       AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
566       if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
567         TABofCC->SetValue(NbPoints, AC2);
568     }
569
570     if (methode < 3) {
571       Standard_Boolean mySquare = (methode == 2);
572       Standard_Integer degmin = 4;
573       Standard_Integer NbIteration = 5;
574       
575       if (Degree < 4) degmin = Max(1, Degree -1);
576       degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),  
577                                         TABofCC->Value(NbPoints).Constraint()) );
578       
579       AppDef_Compute Appr(degmin, Degree,
580                           Abs(Tolerance),  Abs(Tolerance),
581                           NbIteration, Standard_False, 
582                           Approx_ChordLength, mySquare);
583
584      Appr.SetConstraints(TABofCC->Value(1).Constraint(), 
585                           TABofCC->Value(NbPoints).Constraint());
586    
587       Appr.Perform (AML);
588       
589       if (! Appr.IsAllApproximated()) {
590         di << " No result\n";
591       }
592       AppParCurves_MultiCurve AnMuC = Appr.Value();
593       ThePoints = new (TColgp_HArray1OfPnt2d) (1,  AnMuC.NbPoles() );
594       AnMuC.Curve(1, ThePoints->ChangeArray1());
595       Standard_Real err, err2d;
596       Appr.Error(1, err, err2d);
597       di <<" Error2D is : " << err2d << "\n";
598     }
599     else {
600       AppDef_Variational Varia(AML, 
601                                   1,  NbPoints,
602                                   TABofCC,
603                                   Degree, 1);
604       Varia.SetTolerance(Abs(Tolerance));
605       Varia.Approximate();
606
607       if (! Varia.IsDone()) {
608         di << " No result\n";
609       }
610
611       AppParCurves_MultiBSpCurve  AnMuC = Varia.Value();
612       di <<" Error2D is : " << Varia.MaxError() << "\n";
613       ThePoints = new (TColgp_HArray1OfPnt2d) (1,  AnMuC.NbPoles() );
614       AnMuC.Curve(1, ThePoints->ChangeArray1());    
615  }
616     
617     Handle(Geom2d_BezierCurve) Cvliss = 
618       new (Geom2d_BezierCurve)(ThePoints->Array1());
619
620     Handle(DrawTrSurf_BezierCurve2d) DC = 
621       new (DrawTrSurf_BezierCurve2d) (Cvliss);
622     Draw::Set(a[1], DC);
623     if (id!=0) dout.RepaintView(id); 
624   }
625   else {
626     // Cas 3d
627     Handle(TColgp_HArray1OfPnt) ThePoints;
628     Standard_Integer NbPoints = Points->Length();
629     if (TABofCC.IsNull()) {
630       TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
631       for(i=1; i<=NbPoints; i++){
632         AppParCurves_ConstraintCouple ACC(i,Constraint);
633         TABofCC->SetValue(i,ACC);
634       }
635     
636
637       AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
638       if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
639         TABofCC->SetValue(1, AC1);
640     
641       AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
642       if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
643         TABofCC->SetValue(NbPoints, AC2);
644     }
645
646     if (methode < 3) {
647       Standard_Boolean mySquare = (methode == 2);
648       Standard_Integer degmin = 4;
649       Standard_Integer NbIteration = 5;
650       if (Degree < 4) degmin = Max(1, Degree - 1);
651       degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),  
652                                         TABofCC->Value(NbPoints).Constraint()) );
653       
654       AppDef_Compute Appr(degmin, Degree,
655                           Abs(Tolerance),  Abs(Tolerance),
656                           NbIteration, Standard_False, 
657                           Approx_ChordLength, mySquare);
658
659       Appr.SetConstraints(TABofCC->Value(1).Constraint(), 
660                           TABofCC->Value(NbPoints).Constraint());
661    
662       Appr.Perform (AML);
663       
664       if (! Appr.IsAllApproximated()) {
665         di << " No result\n";
666       }
667       AppParCurves_MultiCurve AnMuC = Appr.Value();
668       ThePoints = new (TColgp_HArray1OfPnt) (1,  AnMuC.NbPoles() );
669       AnMuC.Curve(1, ThePoints->ChangeArray1());
670       Standard_Real err, err2d;
671       Appr.Error(1, err, err2d);
672       di <<" Error3D is : " << err << "\n";
673     }
674     else {
675       AppDef_Variational Varia(AML, 
676                                   1,  NbPoints,
677                                   TABofCC,
678                                   Degree, 1);
679
680       Varia.SetTolerance(Abs(Tolerance));
681       Varia.Approximate();
682       if (! Varia.IsDone()) {
683         di << " No result\n";
684       }
685
686       AppParCurves_MultiBSpCurve  AnMuC = Varia.Value();
687       di <<" Error3D is : " << Varia.MaxError() << "\n";
688       ThePoints = new (TColgp_HArray1OfPnt) (1,  AnMuC.NbPoles() );
689       AnMuC.Curve(1, ThePoints->ChangeArray1());    
690     }    
691
692     Handle(Geom_BezierCurve) Cvliss = 
693       new (Geom_BezierCurve)(ThePoints->Array1());
694
695     Handle(DrawTrSurf_BezierCurve) 
696       DC = new DrawTrSurf_BezierCurve(Cvliss);
697     Draw::Set(a[1], DC);
698     if (id!=0) dout.RepaintView(id);
699   }
700   return 0;
701 }
702
703 //=======================================================================
704 //function : ConstraintCommands
705 //purpose  : 
706 //=======================================================================
707
708
709 void  GeomliteTest::ApproxCommands(Draw_Interpretor& theCommands)
710 {
711
712   static Standard_Boolean loaded = Standard_False;
713   if (loaded) return;
714   loaded = Standard_True;
715
716   DrawTrSurf::BasicCommands(theCommands);
717
718   const char* g;
719   // constrained constructs
720   g = "GEOMETRY Constraints";
721
722
723   theCommands.Add("bsmooth",
724                   "bsmooth cname tol [-D degree] [fic]", 
725                   __FILE__,
726                   smoothing, g);
727
728   theCommands.Add("bzsmooth",
729                   "bzsmooth cname tol degree option [fic]", 
730                   __FILE__,
731                   smoothingbybezier, g);
732 }
733