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