0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / GeometryTest / GeometryTest_APICommands.cxx
1 // Created on: 1995-01-17
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-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 #include <Geom_BSplineCurve.hxx>
18 #include <Geom_BSplineSurface.hxx>
19 #include <Draw.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <DrawTrSurf.hxx>
22 #include <Draw_Appli.hxx>
23 #include <GeometryTest.hxx>
24 #include <GeomAPI_ProjectPointOnCurve.hxx>
25 #include <GeomAPI_ProjectPointOnSurf.hxx>
26 #include <Extrema_GenLocateExtPS.hxx>
27 #include <GeomAPI_ExtremaCurveCurve.hxx>
28 #include <GeomAPI_ExtremaCurveSurface.hxx>
29 #include <GeomAPI_ExtremaSurfaceSurface.hxx>
30 #include <GeomAPI_PointsToBSpline.hxx>
31 #include <GeomAPI_PointsToBSplineSurface.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <Draw_Segment3D.hxx>
35 #include <Draw_Marker3D.hxx>
36 #include <Draw_Color.hxx>
37 #include <Draw_MarkerShape.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
39 #include <TColgp_Array2OfPnt.hxx>
40 #include <TColStd_Array2OfReal.hxx>
41 #include <Precision.hxx>
42 #include <stdio.h>
43
44 #ifdef _WIN32
45 Standard_IMPORT Draw_Viewer dout;
46 #endif
47
48 //=======================================================================
49 //function : proj
50 //purpose  : 
51 //=======================================================================
52
53 static void showProjSolution(Draw_Interpretor& di,
54                              const Standard_Integer i,
55                              const gp_Pnt& P, const gp_Pnt& P1,
56                              const Standard_Real U, const Standard_Real V,
57                              const Standard_Boolean isSurface)
58 {
59   char name[100];
60   Sprintf(name, "%s%d", "ext_", i);
61   di << name << " ";
62   char* temp = name; // portage WNT
63   if (P.Distance(P1) > Precision::Confusion())
64   {
65     Handle(Geom_Line) L = new Geom_Line(P, gp_Vec(P, P1));
66     Handle(Geom_TrimmedCurve) CT =
67       new Geom_TrimmedCurve(L, 0., P.Distance(P1));
68     DrawTrSurf::Set(temp, CT);
69   }
70   else
71   {
72     DrawTrSurf::Set(temp, P1);
73     if (isSurface)
74       di << " Point on surface ";
75     else
76       di << " Point on curve ";
77   }
78   if (isSurface)
79     di << " Parameters: " << U << " " << V << "\n";
80   else
81     di << " parameter " << i << " = " << U << "\n";
82 }
83
84 //=======================================================================
85 //function : proj
86 //purpose  : 
87 //=======================================================================
88
89 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
90 {
91   if ( n < 5)
92   {
93     std::cout << " Use proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]" << std::endl;
94     return 1;
95   }
96
97   gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
98
99   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
100   Handle(Geom_Surface) GS;
101   Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
102
103   if (n == 6 && a[5][0] == 't')
104     aProjAlgo = Extrema_ExtAlgo_Tree;
105
106   if (GC.IsNull())
107   {
108     GS = DrawTrSurf::GetSurface(a[1]);
109
110     if (GS.IsNull())
111       return 1;
112
113     if (n <= 6)
114     {
115       Standard_Real U1, U2, V1, V2;
116       GS->Bounds(U1,U2,V1,V2);
117
118       GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
119       if (!proj.IsDone())
120       {
121         di << "projection failed.";
122         return 0;
123       }
124
125       Standard_Real UU,VV;
126       for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
127       {
128         gp_Pnt P1 = proj.Point(i);
129         proj.Parameters(i, UU, VV);
130         showProjSolution(di, i, P, P1, UU, VV, Standard_True);
131       }
132     }
133     else if (n == 7)
134     {
135       const gp_XY aP2d(Draw::Atof(a[5]), Draw::Atof(a[6]));
136       GeomAdaptor_Surface aGAS(GS);
137       Extrema_GenLocateExtPS aProjector(aGAS, Precision::PConfusion(), Precision::PConfusion());
138       aProjector.Perform(P, aP2d.X(), aP2d.Y());
139       if (!aProjector.IsDone())
140       {
141         di << "projection failed.";
142         return 0;
143       }
144
145       const Extrema_POnSurf& aP = aProjector.Point();
146       Standard_Real UU, VV;
147       aP.Parameter(UU, VV);
148       showProjSolution(di, 1, P, aP.Value(), UU, VV, Standard_True);
149     }
150   }
151   else
152   {
153     GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
154       GC->LastParameter());
155
156     if(proj.NbPoints() == 0)
157     {
158       std::cout << "No project point was found." << std::endl;
159       return 0;
160     }
161
162     for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
163     {
164       gp_Pnt P1 = proj.Point(i);
165       Standard_Real UU = proj.Parameter(i);
166       showProjSolution(di, i, P, P1, UU, UU, Standard_False);
167     }
168   }
169
170   return 0;
171 }
172
173 //=======================================================================
174 //function : appro
175 //purpose  : 
176 //=======================================================================
177
178 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
179 {
180   if ( n<3) return 1;
181
182   Handle(Geom_Curve) GC;
183   Standard_Integer Nb = Draw::Atoi(a[2]);
184
185   TColgp_Array1OfPnt Points(1, Nb);
186
187   Handle(Draw_Marker3D) mark;
188
189   if ( n == 4) {
190     GC = DrawTrSurf::GetCurve(a[3]);
191     if ( GC.IsNull()) 
192       return 1;
193
194     Standard_Real U, U1, U2;
195     U1 = GC->FirstParameter();
196     U2 = GC->LastParameter();
197     Standard_Real Delta = ( U2 - U1) / (Nb-1);
198     for ( Standard_Integer i = 1 ; i <= Nb; i++) {
199       U = U1 + (i-1) * Delta;
200       Points(i) = GC->Value(U);
201       mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); 
202       dout << mark;
203     }
204   }
205   else {
206     Standard_Integer id,XX,YY,b;
207     dout.Select(id,XX,YY,b);
208     Standard_Real zoom = dout.Zoom(id);
209
210     Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom, 
211                         ((Standard_Real)YY)/zoom, 
212                         0.);
213     
214     mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert); 
215     
216     dout << mark;
217     
218     for (Standard_Integer i = 2; i<=Nb; i++) {
219       dout.Select(id,XX,YY,b);
220       Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom, 
221                          ((Standard_Real)YY)/zoom, 
222                          0.);
223       mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); 
224       dout << mark;
225     }
226   }    
227   dout.Flush();
228   Standard_Integer Dmin = 3;
229   Standard_Integer Dmax = 8;
230   Standard_Real Tol3d = 1.e-3;
231   
232   Handle(Geom_BSplineCurve) TheCurve;
233   GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d);
234   TheCurve = aPointToBSpline.Curve();
235
236   
237   DrawTrSurf::Set(a[1], TheCurve);
238   di << a[1];
239
240   return 0;
241
242 }
243
244
245 //=======================================================================
246 //function : grilapp
247 //purpose  : 
248 //=======================================================================
249
250 static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
251 {
252   if ( n < 12) return 1;
253
254   Standard_Integer i,j;
255   Standard_Integer Nu = Draw::Atoi(a[2]);
256   Standard_Integer Nv = Draw::Atoi(a[3]);
257   TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv);
258
259   Standard_Real X0 = Draw::Atof(a[4]);
260   Standard_Real dX = Draw::Atof(a[5]);
261   Standard_Real Y0 = Draw::Atof(a[6]);
262   Standard_Real dY = Draw::Atof(a[7]);
263
264   Standard_Integer Count = 8;
265   for ( j = 1; j <= Nv; j++) {
266     for ( i = 1; i <= Nu; i++) {
267       if ( Count > n) return 1;
268       ZPoints(i,j) = Draw::Atof(a[Count]);
269       Count++;
270     }
271   }
272   
273   Handle(Geom_BSplineSurface) S 
274     = GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY);
275   DrawTrSurf::Set(a[1],S);
276
277   di << a[1];
278   
279   return 0;
280 }
281
282 //=======================================================================
283 //function : surfapp
284 //purpose  : 
285 //=======================================================================
286
287 static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
288 {
289   if (n < 5) return 1;
290
291   Standard_Integer i, j;
292   Standard_Integer Nu = Draw::Atoi(a[2]);
293   Standard_Integer Nv = Draw::Atoi(a[3]);
294   TColgp_Array2OfPnt Points(1, Nu, 1, Nv);
295   Standard_Boolean IsPeriodic = Standard_False;
296   Standard_Boolean RemoveLast = Standard_False;
297
298   if (n >= 5 && n <= 6) {
299     Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
300     if (Surf.IsNull()) return 1;
301
302     Standard_Real U, V, U1, V1, U2, V2;
303     Surf->Bounds(U1, U2, V1, V2);
304     for (j = 1; j <= Nv; j++) {
305       V = V1 + (j - 1) * (V2 - V1) / (Nv - 1);
306       for (i = 1; i <= Nu; i++) {
307         U = U1 + (i - 1) * (U2 - U1) / (Nu - 1);
308         Points(i, j) = Surf->Value(U, V);
309       }
310     }
311     if (n == 6)
312     {
313       Standard_Integer ip = Draw::Atoi(a[5]);
314       if (ip > 0) IsPeriodic = Standard_True;
315     }
316     if (IsPeriodic)
317     {
318       for (j = 1; j <= Nv; j++)
319       {
320         Standard_Real d = Points(1, j).Distance(Points(Nu, j));
321         if (d <= Precision::Confusion())
322         {
323           RemoveLast = Standard_True;
324           break;
325         }
326       }
327     }
328   }
329   else if (n >= 16) {
330     Standard_Integer Count = 4;
331     for (j = 1; j <= Nv; j++) {
332       for (i = 1; i <= Nu; i++) {
333         if (Count > n) return 1;
334         Points(i, j) = gp_Pnt(Draw::Atof(a[Count]), Draw::Atof(a[Count + 1]), Draw::Atof(a[Count + 2]));
335         Count += 3;
336       }
337     }
338   }
339   char name[100];
340   Standard_Integer Count = 1;
341   for (j = 1; j <= Nv; j++) {
342     for (i = 1; i <= Nu; i++) {
343       Sprintf(name, "point_%d", Count++);
344       char* temp = name; // portage WNT
345       DrawTrSurf::Set(temp, Points(i, j));
346     }
347   }
348
349   GeomAPI_PointsToBSplineSurface anApprox;
350   if (RemoveLast)
351   {
352     TColgp_Array2OfPnt Points1(1, Nu - 1, 1, Nv);
353     for (j = 1; j <= Nv; j++)
354     {
355       for (i = 1; i <= Nu - 1; i++) {
356         Points1(i, j) = Points(i, j);
357       }
358     }
359     anApprox.Init(Points1, Approx_ChordLength, 3, 8, GeomAbs_C2, 1.e-3, IsPeriodic);
360   }
361   else
362   {
363     anApprox.Init(Points, Approx_ChordLength, 3, 8, GeomAbs_C2, 1.e-3, IsPeriodic);
364   }
365
366   if (anApprox.IsDone())
367   {
368     Handle(Geom_BSplineSurface) S = anApprox.Surface();
369     DrawTrSurf::Set(a[1], S);
370     di << a[1];
371   }
372
373   return 0;
374 }
375
376 //=======================================================================
377 //function : surfint
378 //purpose  : 
379 //=======================================================================
380
381 static Standard_Integer surfint(Draw_Interpretor& di, Standard_Integer n, const char** a)
382 {
383   if (n < 5) return 1;
384
385   Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[2]);
386   if (Surf.IsNull()) return 1;
387   Standard_Integer i, j;
388   Standard_Integer Nu = Draw::Atoi(a[3]);
389   Standard_Integer Nv = Draw::Atoi(a[4]);
390   TColgp_Array2OfPnt Points(1, Nu, 1, Nv);
391
392   Standard_Real U, V, U1, V1, U2, V2;
393   Surf->Bounds(U1, U2, V1, V2);
394   for (j = 1; j <= Nv; j++) {
395     V = V1 + (j - 1) * (V2 - V1) / (Nv - 1);
396     for (i = 1; i <= Nu; i++) {
397       U = U1 + (i - 1) * (U2 - U1) / (Nu - 1);
398       Points(i, j) = Surf->Value(U, V);
399     }
400   }
401
402   char name[100];
403   Standard_Integer Count = 1;
404   for (j = 1; j <= Nv; j++) {
405     for (i = 1; i <= Nu; i++) {
406       Sprintf(name, "point_%d", Count++);
407       char* temp = name; // portage WNT
408       DrawTrSurf::Set(temp, Points(i, j));
409     }
410   }
411
412   Standard_Boolean IsPeriodic = Standard_False;
413   if (n > 5)
414   {
415     Standard_Integer ip = Draw::Atoi(a[5]);
416     if (ip > 0) IsPeriodic = Standard_True;
417   }
418   Standard_Boolean RemoveLast = Standard_False;
419   if (IsPeriodic)
420   {
421     for (j = 1; j <= Nv; j++)
422     {
423       Standard_Real d = Points(1, j).Distance(Points(Nu, j));
424       if (d <= Precision::Confusion())
425       {
426         RemoveLast = Standard_True;
427         break;
428       }
429     }
430   }
431   const Approx_ParametrizationType ParType = Approx_ChordLength;
432   GeomAPI_PointsToBSplineSurface anApprox;
433   if (RemoveLast)
434   {
435     TColgp_Array2OfPnt Points1(1, Nu-1, 1, Nv);
436     for (j = 1; j <= Nv; j++)
437     {
438       for (i = 1; i <= Nu-1; i++) {
439         Points1(i, j) = Points(i, j);
440       }
441     }
442     anApprox.Interpolate(Points1, ParType, IsPeriodic);
443   }
444   else
445   {
446     anApprox.Interpolate(Points, ParType, IsPeriodic);
447   }
448   if (anApprox.IsDone())
449   {
450     Handle(Geom_BSplineSurface) S = anApprox.Surface();
451     DrawTrSurf::Set(a[1], S);
452     di << a[1];
453   }
454   else
455   {
456     di << "Interpolation not done \n";
457   }
458
459
460   return 0;
461 }
462
463
464 //=======================================================================
465 //function : extrema
466 //purpose  : 
467 //=======================================================================
468
469 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
470 {
471   if (n < 3)
472   {
473     return 1;
474   }
475
476   Handle(Geom_Curve) GC1, GC2;
477   Handle(Geom_Surface) GS1, GS2;
478
479   Standard_Boolean isInfinitySolutions = Standard_False;
480   Standard_Real aMinDist = RealLast();
481
482   Standard_Real U1f, U1l, U2f, U2l, V1f = 0., V1l = 0., V2f = 0., V2l = 0.;
483
484   GC1 = DrawTrSurf::GetCurve(a[1]);
485   if ( GC1.IsNull()) {
486     GS1 = DrawTrSurf::GetSurface(a[1]);
487     if ( GS1.IsNull())
488       return 1;
489
490     GS1->Bounds(U1f,U1l,V1f,V1l);
491   }
492   else {
493     U1f = GC1->FirstParameter();
494     U1l = GC1->LastParameter();
495   }
496
497   GC2 = DrawTrSurf::GetCurve(a[2]);
498   if ( GC2.IsNull()) {
499     GS2 = DrawTrSurf::GetSurface(a[2]);
500     if ( GS2.IsNull())
501       return 1;
502     GS2->Bounds(U2f,U2l,V2f,V2l);
503   }
504   else {
505     U2f = GC2->FirstParameter();
506     U2l = GC2->LastParameter();
507   }
508
509   NCollection_Vector<gp_Pnt> aPnts1, aPnts2;
510   NCollection_Vector<Standard_Real> aPrms[4];
511   if (!GC1.IsNull() && !GC2.IsNull())
512   {
513     GeomAPI_ExtremaCurveCurve Ex(GC1, GC2, U1f, U1l, U2f, U2l);
514     
515     // Since GeomAPI cannot provide access to flag directly.
516     isInfinitySolutions = Ex.Extrema().IsParallel();
517     if (isInfinitySolutions)
518     {
519       aMinDist = Ex.LowerDistance();
520     }
521     else
522     {
523       for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
524       {
525         gp_Pnt aP1, aP2;
526         Ex.Points(aJ, aP1, aP2);
527         aPnts1.Append(aP1);
528         aPnts2.Append(aP2);
529
530         Standard_Real aU1, aU2;
531         Ex.Parameters(aJ, aU1, aU2);
532         aPrms[0].Append(aU1);
533         aPrms[2].Append(aU2);
534       }
535     }
536   }
537   else if (!GC1.IsNull() && !GS2.IsNull())
538   {
539     GeomAPI_ExtremaCurveSurface Ex(GC1, GS2, U1f, U1l, U2f, U2l, V2f, V2l);
540
541     isInfinitySolutions = Ex.Extrema().IsParallel();
542     if (isInfinitySolutions)
543     {
544       aMinDist = Ex.LowerDistance();
545     }
546     else
547     {
548       for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
549       {
550         gp_Pnt aP1, aP2;
551         Ex.Points(aJ, aP1, aP2);
552         aPnts1.Append(aP1);
553         aPnts2.Append(aP2);
554
555         Standard_Real aU1, aU2, aV2;
556         Ex.Parameters(aJ, aU1, aU2, aV2);
557         aPrms[0].Append(aU1);
558         aPrms[2].Append(aU2);
559         aPrms[3].Append(aV2);
560       }
561     }
562   }
563   else if (!GS1.IsNull() && !GC2.IsNull())
564   {
565     GeomAPI_ExtremaCurveSurface Ex(GC2, GS1, U2f, U2l, U1f, U1l, V1f, V1l);
566
567     isInfinitySolutions = Ex.Extrema().IsParallel();
568     if (isInfinitySolutions)
569     {
570       aMinDist = Ex.LowerDistance();
571     }
572     else
573     {
574       for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
575       {
576         gp_Pnt aP2, aP1;
577         Ex.Points(aJ, aP2, aP1);
578         aPnts1.Append(aP1);
579         aPnts2.Append(aP2);
580
581         Standard_Real aU1, aV1, aU2;
582         Ex.Parameters(aJ, aU2, aU1, aV1);
583         aPrms[0].Append(aU1);
584         aPrms[1].Append(aV1);
585         aPrms[2].Append(aU2);
586       }
587     }
588   }
589   else if (!GS1.IsNull() && !GS2.IsNull())
590   {
591     GeomAPI_ExtremaSurfaceSurface Ex(GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
592     // Since GeomAPI cannot provide access to flag directly.
593     isInfinitySolutions = Ex.Extrema().IsParallel();
594     if (isInfinitySolutions)
595     {
596       aMinDist = Ex.LowerDistance();
597     }
598     else
599     {
600       for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
601       {
602         gp_Pnt aP1, aP2;
603         Ex.Points(aJ, aP1, aP2);
604         aPnts1.Append(aP1);
605         aPnts2.Append(aP2);
606
607         Standard_Real aU1, aV1, aU2, aV2;
608         Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
609         aPrms[0].Append(aU1);
610         aPrms[1].Append(aV1);
611         aPrms[2].Append(aU2);
612         aPrms[3].Append(aV2);
613       }
614     }
615   }
616
617   char aName[100];
618   char* aName2 = aName; // portage WNT
619
620   // Output points.
621   const Standard_Integer aPntCount = aPnts1.Size();
622   if (aPntCount == 0 || isInfinitySolutions)
623   {
624     // Infinity solutions flag may be set with 0 number of 
625     // solutions in analytic extrema Curve/Curve.
626     if (isInfinitySolutions) 
627       di << "Infinite number of extremas, distance = " << aMinDist << "\n";
628     else
629       di << "No solutions!\n";
630   }
631   for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
632   {
633     gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
634
635     if (aP1.Distance(aP2) < 1.e-16)
636     {
637       di << "Extrema " << aJ << " is point : " <<
638         aP1.X() << " " << aP1.Y() << " " << aP1.Z() << "\n";
639       continue;
640     }
641
642     Handle(Geom_Line) aL = new Geom_Line(aP1, gp_Vec(aP1, aP2));
643     Handle(Geom_TrimmedCurve) aCT = 
644       new Geom_TrimmedCurve(aL, 0., aP1.Distance(aP2));
645     Sprintf(aName, "%s%d", "ext_", aJ);
646     DrawTrSurf::Set(aName2, aCT);
647     di << aName << " ";
648   }
649
650   if (n >= 4)
651   {
652     // Output points.
653     for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
654     {
655       gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
656       Sprintf(aName, "%s%d%s", "ext_", aJ, "_2");
657       DrawTrSurf::Set(aName2, aP1);
658       di << aName << " ";
659       Sprintf(aName, "%s%d%s", "ext_", aJ, "_3");
660       DrawTrSurf::Set(aName2, aP2);
661       di << aName << " ";
662     }
663
664     // Output parameters.
665     for (Standard_Integer aJ = 0; aJ < 4; ++aJ)
666     {
667       for (Standard_Integer aPrmCount = aPrms[aJ].Size(), aK = 0;
668         aK < aPrmCount; ++aK)
669       {
670         Standard_Real aP = aPrms[aJ](aK);
671         Sprintf(aName, "%s%d%s%d", "prm_", aJ + 1, "_", aK + 1);
672         Draw::Set(aName2, aP);
673         di << aName << " ";
674       }
675     }
676   }
677
678   return 0;
679 }
680
681 //=======================================================================
682 //function : totalextcc
683 //purpose  : 
684 //=======================================================================
685
686 static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
687 {
688   if ( n<3) return 1;
689
690   Handle(Geom_Curve)   GC1, GC2;
691
692
693   Standard_Real U1f,U1l,U2f,U2l;
694
695   GC1 = DrawTrSurf::GetCurve(a[1]);
696   if ( GC1.IsNull()) {
697       return 1;
698   }
699   else {
700     U1f = GC1->FirstParameter();
701     U1l = GC1->LastParameter();
702   }
703
704   GC2 = DrawTrSurf::GetCurve(a[2]);
705   if ( GC2.IsNull()) {
706       return 1;
707   }
708   else {
709     U2f = GC2->FirstParameter();
710     U2l = GC2->LastParameter();
711   }
712
713   char name[100];
714     GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
715   gp_Pnt P1,P2;
716   if(Ex.TotalNearestPoints(P1,P2)) {
717     if (P1.Distance(P2) < 1.e-16) {
718       di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
719     }
720     else {
721       di << "Extrema is segment of line\n"; 
722       Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
723       Handle(Geom_TrimmedCurve) CT = 
724         new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
725       Sprintf(name,"%s%d","ext_",1);
726       char* temp = name; // portage WNT
727       DrawTrSurf::Set(temp, CT);
728       di << name << " ";
729     }
730
731     Standard_Real u1, u2;
732     Ex.TotalLowerDistanceParameters(u1, u2);
733
734     di << "Parameters on curves : " << u1 << " " << u2 << "\n";
735
736   }
737   else {
738     di << "Curves are infinite and parallel\n";
739   }
740   
741   di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
742
743   return 0;
744
745 }
746
747
748 void GeometryTest::APICommands(Draw_Interpretor& theCommands)
749 {
750   static Standard_Boolean done = Standard_False;
751   if (done) return;
752
753   done = Standard_True;
754
755   theCommands.Add("proj", "proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]\n"
756                   "\t\tOptional parameters are relevant to surf only.\n"
757                   "\t\tIf initial {u v} are given then local extrema is called",__FILE__, proj);
758
759   theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
760   theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
761                   __FILE__,
762                   surfapp);
763
764   theCommands.Add("surfint", "surfint result surf nbupoint nbvpoint [uperiodic]",
765     __FILE__,
766     surfint);
767
768   theCommands.Add("grilapp",
769        "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu ....  ",
770         __FILE__,grilapp);
771
772   theCommands.Add("extrema", "extrema curve/surface curve/surface [extended_output = 0|1]",__FILE__,extrema);
773   theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);
774 }