0bf179cc23f3b00053444daee7368617292393d8
[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 <GeomAPI_ExtremaCurveCurve.hxx>
27 #include <GeomAPI_ExtremaCurveSurface.hxx>
28 #include <GeomAPI_ExtremaSurfaceSurface.hxx>
29 #include <GeomAPI_PointsToBSpline.hxx>
30 #include <GeomAPI_PointsToBSplineSurface.hxx>
31 #include <Geom_Line.hxx>
32 #include <Geom_TrimmedCurve.hxx>
33 #include <Draw_Segment3D.hxx>
34 #include <Draw_Marker3D.hxx>
35 #include <Draw_Color.hxx>
36 #include <Draw_MarkerShape.hxx>
37 #include <TColgp_Array1OfPnt.hxx>
38 #include <TColgp_Array2OfPnt.hxx>
39 #include <TColStd_Array2OfReal.hxx>
40 #include <Precision.hxx>
41 #include <stdio.h>
42 #ifdef _WIN32
43 Standard_IMPORT Draw_Viewer dout;
44 #endif
45
46 //=======================================================================
47 //function : proj
48 //purpose  : 
49 //=======================================================================
50
51 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
52 {
53   if ( n < 5)
54   {
55     cout << " Use proj curve/surf x y z [extrema algo: g(grad)/t(tree)]" << endl;
56     return 1;
57   }
58
59   gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4]));
60
61   char name[100];
62
63   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
64   Handle(Geom_Surface) GS;
65   Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
66
67   if (n == 6 && a[5][0] == 't')
68     aProjAlgo = Extrema_ExtAlgo_Tree;
69
70   if (GC.IsNull())
71   {
72     GS = DrawTrSurf::GetSurface(a[1]);
73
74     if (GS.IsNull())
75       return 1;
76
77     Standard_Real U1, U2, V1, V2;
78     GS->Bounds(U1,U2,V1,V2);
79
80     GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
81
82     Standard_Real UU,VV;
83     for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
84     {
85       gp_Pnt P1 = proj.Point(i);
86       if ( P.Distance(P1) > Precision::Confusion())
87       {
88         Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1));
89         Handle(Geom_TrimmedCurve) CT = 
90           new Geom_TrimmedCurve(L, 0., P.Distance(P1));
91         Sprintf(name,"%s%d","ext_",i);
92         char* temp = name; // portage WNT
93         DrawTrSurf::Set(temp, CT);
94         di << name << " ";
95       }
96       else
97       {
98         Sprintf(name,"%s%d","ext_",i);
99         di << name << " ";
100         char* temp = name; // portage WNT
101         DrawTrSurf::Set(temp, P1);
102         proj.Parameters(i,UU,VV);
103         di << " Le point est sur la surface.\n";
104         di << " Ses parametres sont:  UU = " << UU << "\n";
105         di << "                       VV = " << VV << "\n";
106       }
107     }
108   }
109   else
110   {
111     GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
112       GC->LastParameter());
113
114     if(proj.NbPoints() == 0)
115     {
116       cout << "No project point was found." << endl;
117       return 0;
118     }
119
120     for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++)
121     {
122       gp_Pnt P1 = proj.Point(i);
123       Standard_Real UU = proj.Parameter(i);
124       di << " parameter " << i << " = " << UU << "\n";
125       if ( P.Distance(P1) > Precision::Confusion())
126       {
127         Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1));
128         Handle(Geom_TrimmedCurve) CT = 
129           new Geom_TrimmedCurve(L, 0., P.Distance(P1));
130         Sprintf(name,"%s%d","ext_",i);
131         char* temp = name; // portage WNT
132         DrawTrSurf::Set(temp, CT);
133         di << name << " ";
134       }
135       else
136       {
137         Sprintf(name,"%s%d","ext_",i);
138         char* temp = name; // portage WNT
139         DrawTrSurf::Set(temp, P1);
140         di << name << " ";
141         UU = proj.Parameter(i);
142         di << " Le point est sur la courbe.\n";
143         di << " Son parametre est U = " << UU << "\n";
144       }
145     }
146   }
147
148   return 0;
149 }
150
151 //=======================================================================
152 //function : appro
153 //purpose  : 
154 //=======================================================================
155
156 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
157 {
158   if ( n<3) return 1;
159
160   Handle(Geom_Curve) GC;
161   Standard_Integer Nb = Draw::Atoi(a[2]);
162
163   TColgp_Array1OfPnt Points(1, Nb);
164
165   Handle(Draw_Marker3D) mark;
166
167   if ( n == 4) {
168     GC = DrawTrSurf::GetCurve(a[3]);
169     if ( GC.IsNull()) 
170       return 1;
171
172     Standard_Real U, U1, U2;
173     U1 = GC->FirstParameter();
174     U2 = GC->LastParameter();
175     Standard_Real Delta = ( U2 - U1) / (Nb-1);
176     for ( Standard_Integer i = 1 ; i <= Nb; i++) {
177       U = U1 + (i-1) * Delta;
178       Points(i) = GC->Value(U);
179       mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); 
180       dout << mark;
181     }
182   }
183   else {
184     Standard_Integer id,XX,YY,b;
185     dout.Select(id,XX,YY,b);
186     Standard_Real zoom = dout.Zoom(id);
187
188     Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom, 
189                         ((Standard_Real)YY)/zoom, 
190                         0.);
191     
192     mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert); 
193     
194     dout << mark;
195     
196     for (Standard_Integer i = 2; i<=Nb; i++) {
197       dout.Select(id,XX,YY,b);
198       Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom, 
199                          ((Standard_Real)YY)/zoom, 
200                          0.);
201       mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); 
202       dout << mark;
203     }
204   }    
205   dout.Flush();
206   Standard_Integer Dmin = 3;
207   Standard_Integer Dmax = 8;
208   Standard_Real Tol3d = 1.e-3;
209   
210   Handle(Geom_BSplineCurve) TheCurve;
211   GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d);
212   TheCurve = aPointToBSpline.Curve();
213
214   
215   DrawTrSurf::Set(a[1], TheCurve);
216   di << a[1];
217
218   return 0;
219
220 }
221
222
223 //=======================================================================
224 //function : grilapp
225 //purpose  : 
226 //=======================================================================
227
228 static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
229 {
230   if ( n < 12) return 1;
231
232   Standard_Integer i,j;
233   Standard_Integer Nu = Draw::Atoi(a[2]);
234   Standard_Integer Nv = Draw::Atoi(a[3]);
235   TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv);
236
237   Standard_Real X0 = Draw::Atof(a[4]);
238   Standard_Real dX = Draw::Atof(a[5]);
239   Standard_Real Y0 = Draw::Atof(a[6]);
240   Standard_Real dY = Draw::Atof(a[7]);
241
242   Standard_Integer Count = 8;
243   for ( j = 1; j <= Nv; j++) {
244     for ( i = 1; i <= Nu; i++) {
245       if ( Count > n) return 1;
246       ZPoints(i,j) = Draw::Atof(a[Count]);
247       Count++;
248     }
249   }
250   
251   Handle(Geom_BSplineSurface) S 
252     = GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY);
253   DrawTrSurf::Set(a[1],S);
254
255   di << a[1];
256   
257   return 0;
258 }
259
260 //=======================================================================
261 //function : surfapp
262 //purpose  : 
263 //=======================================================================
264
265 static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
266 {
267   if ( n < 5 ) return 1;
268
269   Standard_Integer i,j;
270   Standard_Integer Nu = Draw::Atoi(a[2]);
271   Standard_Integer Nv = Draw::Atoi(a[3]);
272   TColgp_Array2OfPnt Points (1, Nu, 1, Nv);
273
274   if ( n == 5) {
275     Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
276     if ( Surf.IsNull()) return 1;
277
278     Standard_Real U, V, U1, V1, U2, V2;
279     Surf->Bounds( U1, U2, V1, V2);
280     for ( j = 1; j <= Nv; j++) {
281       V = V1 + (j-1) * (V2-V1) / (Nv-1);
282       for ( i = 1; i <= Nu; i++) {
283         U = U1 + (i-1) * (U2-U1) / (Nu-1);
284         Points(i,j) = Surf->Value(U,V);
285       }
286     } 
287   }
288   else if ( n >= 16) {
289     Standard_Integer Count = 4;
290     for ( j = 1; j <= Nv; j++) {
291       for ( i = 1; i <= Nu; i++) {
292         if ( Count > n) return 1;
293         Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2]));
294         Count += 3;
295       }
296     }
297   }
298   char name[100];
299   Standard_Integer Count = 1;
300   for ( j = 1; j <= Nv; j++) {
301     for ( i = 1; i <= Nu; i++) {
302       Sprintf(name,"point_%d",Count++);
303       char* temp = name; // portage WNT
304       DrawTrSurf::Set(temp,Points(i,j));
305     }
306   } 
307
308   Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points);
309   DrawTrSurf::Set(a[1],S);
310   di << a[1];
311
312   return 0;
313 }
314
315
316 //=======================================================================
317 //function : extrema
318 //purpose  : 
319 //=======================================================================
320
321 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
322 {
323   if (n < 3)
324   {
325     return 1;
326   }
327
328   Handle(Geom_Curve)   GC1, GC2;
329   Handle(Geom_Surface) GS1, GS2;
330
331   Standard_Boolean C1 = Standard_False;
332   Standard_Boolean C2 = Standard_False;
333   Standard_Boolean S1 = Standard_False;
334   Standard_Boolean S2 = Standard_False;
335   Standard_Boolean isInfinitySolutions = Standard_False;
336   Standard_Real aMinDist = RealLast();
337
338   Standard_Real U1f, U1l, U2f, U2l, V1f = 0., V1l = 0., V2f = 0., V2l = 0.;
339
340   GC1 = DrawTrSurf::GetCurve(a[1]);
341   if ( GC1.IsNull()) {
342     GS1 = DrawTrSurf::GetSurface(a[1]);
343     if ( GS1.IsNull())
344       return 1;
345     S1 = Standard_True;
346     GS1->Bounds(U1f,U1l,V1f,V1l);
347   }
348   else {
349     C1 = Standard_True;
350     U1f = GC1->FirstParameter();
351     U1l = GC1->LastParameter();
352   }
353
354   GC2 = DrawTrSurf::GetCurve(a[2]);
355   if ( GC2.IsNull()) {
356     GS2 = DrawTrSurf::GetSurface(a[2]);
357     if ( GS2.IsNull())
358       return 1;
359     S2 = Standard_True;
360     GS2->Bounds(U2f,U2l,V2f,V2l);
361   }
362   else {
363     C2 = Standard_True;
364     U2f = GC2->FirstParameter();
365     U2l = GC2->LastParameter();
366   }
367
368   NCollection_Vector<gp_Pnt> aPnts1, aPnts2;
369   NCollection_Vector<Standard_Real> aPrms[4];
370   if (C1 && C2)
371   {
372     GeomAPI_ExtremaCurveCurve Ex(GC1, GC2, U1f, U1l, U2f, U2l);
373
374     for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
375     {
376         gp_Pnt aP1, aP2;
377         Ex.Points(aJ, aP1, aP2);
378         aPnts1.Append(aP1);
379         aPnts2.Append(aP2);
380
381         Standard_Real aU1, aU2;
382         Ex.Parameters(aJ, aU1, aU2);
383         aPrms[0].Append(aU1);
384         aPrms[2].Append(aU2);
385     }
386     // Since GeomAPI cannot provide access to flag directly.
387     isInfinitySolutions = Ex.Extrema().IsParallel();
388     aMinDist = Ex.LowerDistance();
389   }
390   else if (C1 && S2)
391   {
392     GeomAPI_ExtremaCurveSurface Ex(GC1, GS2, U1f, U1l, U2f, U2l, V2f, V2l);
393     for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
394     {
395       gp_Pnt aP1, aP2;
396       Ex.Points(aJ, aP1, aP2);
397       aPnts1.Append(aP1);
398       aPnts2.Append(aP2);
399
400       Standard_Real aU1, aU2, aV2;
401       Ex.Parameters(aJ, aU1, aU2, aV2);
402       aPrms[0].Append(aU1);
403       aPrms[2].Append(aU2);
404       aPrms[3].Append(aV2);
405     }
406   }
407   else if (S1 && C2)
408   {
409     GeomAPI_ExtremaCurveSurface Ex(GC2, GS1, U2f, U2l, U1f, U1l, V1f, V1l);
410     for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
411     {
412       gp_Pnt aP2, aP1;
413       Ex.Points(aJ, aP2, aP1);
414       aPnts1.Append(aP1);
415       aPnts2.Append(aP2);
416
417       Standard_Real aU1, aV1, aU2;
418       Ex.Parameters(aJ, aU2, aU1, aV1);
419       aPrms[0].Append(aU1);
420       aPrms[1].Append(aV1);
421       aPrms[2].Append(aU2);
422     }
423   }
424   else if (S1 && S2)
425   {
426     GeomAPI_ExtremaSurfaceSurface Ex(
427       GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
428     for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
429     {
430       gp_Pnt aP1, aP2;
431       Ex.Points(aJ, aP1, aP2);
432       aPnts1.Append(aP1);
433       aPnts2.Append(aP2);
434
435       Standard_Real aU1, aV1, aU2, aV2;
436       Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
437       aPrms[0].Append(aU1);
438       aPrms[1].Append(aV1);
439       aPrms[2].Append(aU2);
440       aPrms[3].Append(aV2);
441     }
442   }
443
444   char aName[100];
445   char* aName2 = aName; // portage WNT
446
447   // Output points.
448   const Standard_Integer aPntCount = aPnts1.Size();
449   if (aPntCount == 0 || isInfinitySolutions)
450   {
451     // Infinity solutions flag may be set with 0 number of 
452     // solutions in analytic extrema Curve/Curve.
453     if (isInfinitySolutions) 
454       di << "Infinite number of extremas, distance = " << aMinDist << "\n";
455     else
456       di << "No solutions!\n";
457   }
458   for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
459   {
460     gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
461
462     if (aP1.Distance(aP2) < 1.e-16)
463     {
464       di << "Extrema " << aJ << " is point : " <<
465         aP1.X() << " " << aP1.Y() << " " << aP1.Z() << "\n";
466       continue;
467     }
468
469     Handle(Geom_Line) aL = new Geom_Line(aP1, gp_Vec(aP1, aP2));
470     Handle(Geom_TrimmedCurve) aCT = 
471       new Geom_TrimmedCurve(aL, 0., aP1.Distance(aP2));
472     Sprintf(aName, "%s%d", "ext_", aJ);
473     DrawTrSurf::Set(aName2, aCT);
474     di << aName << " ";
475   }
476
477   if (n >= 4)
478   {
479     // Output points.
480     for (Standard_Integer aJ = 1; aJ <= aPntCount; aJ++)
481     {
482       gp_Pnt aP1 = aPnts1(aJ - 1), aP2 = aPnts2(aJ - 1);
483       Sprintf(aName, "%s%d%s", "ext_", aJ, "_2");
484       DrawTrSurf::Set(aName2, aP1);
485       di << aName << " ";
486       Sprintf(aName, "%s%d%s", "ext_", aJ, "_3");
487       DrawTrSurf::Set(aName2, aP2);
488       di << aName << " ";
489     }
490
491     // Output parameters.
492     for (Standard_Integer aJ = 0; aJ < 4; ++aJ)
493     {
494       for (Standard_Integer aPrmCount = aPrms[aJ].Size(), aK = 0;
495         aK < aPrmCount; ++aK)
496       {
497         Standard_Real aP = aPrms[aJ](aK);
498         Sprintf(aName, "%s%d%s%d", "prm_", aJ + 1, "_", aK + 1);
499         Draw::Set(aName2, aP);
500         di << aName << " ";
501       }
502     }
503   }
504
505   return 0;
506 }
507
508 //=======================================================================
509 //function : totalextcc
510 //purpose  : 
511 //=======================================================================
512
513 static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
514 {
515   if ( n<3) return 1;
516
517   Handle(Geom_Curve)   GC1, GC2;
518
519
520   Standard_Real U1f,U1l,U2f,U2l;
521
522   GC1 = DrawTrSurf::GetCurve(a[1]);
523   if ( GC1.IsNull()) {
524       return 1;
525   }
526   else {
527     U1f = GC1->FirstParameter();
528     U1l = GC1->LastParameter();
529   }
530
531   GC2 = DrawTrSurf::GetCurve(a[2]);
532   if ( GC2.IsNull()) {
533       return 1;
534   }
535   else {
536     U2f = GC2->FirstParameter();
537     U2l = GC2->LastParameter();
538   }
539
540   char name[100];
541     GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
542   gp_Pnt P1,P2;
543   if(Ex.TotalNearestPoints(P1,P2)) {
544     if (P1.Distance(P2) < 1.e-16) {
545       di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
546     }
547     else {
548       di << "Extrema is segment of line\n"; 
549       Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
550       Handle(Geom_TrimmedCurve) CT = 
551         new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
552       Sprintf(name,"%s%d","ext_",1);
553       char* temp = name; // portage WNT
554       DrawTrSurf::Set(temp, CT);
555       di << name << " ";
556     }
557
558     Standard_Real u1, u2;
559     Ex.TotalLowerDistanceParameters(u1, u2);
560
561     di << "Parameters on curves : " << u1 << " " << u2 << "\n";
562
563   }
564   else {
565     di << "Curves are infinite and parallel\n";
566   }
567   
568   di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
569
570   return 0;
571
572 }
573
574
575 void GeometryTest::APICommands(Draw_Interpretor& theCommands)
576 {
577   static Standard_Boolean done = Standard_False;
578   if (done) return;
579
580   done = Standard_True;
581
582   theCommands.Add("proj", "proj curve/surf x y z [extrema algo: g(grad)/t(tree)]",__FILE__, proj);
583
584   theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
585   theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
586                   __FILE__,
587                   surfapp);
588   theCommands.Add("grilapp",
589        "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu ....  ",
590         __FILE__,grilapp);
591
592   theCommands.Add("extrema", "extrema curve/surface curve/surface [extended_output = 0|1]",__FILE__,extrema);
593   theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);
594 }