0024428: Implementation of LGPL license
[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
9 // under the terms of the GNU Lesser General Public 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_Curve.hxx>
18 #include <Geom_Surface.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 WNT
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) return 1;
324
325   Handle(Geom_Curve)   GC1, GC2;
326   Handle(Geom_Surface) GS1, GS2;
327
328   Standard_Boolean C1 = Standard_False;
329   Standard_Boolean C2 = Standard_False;
330   Standard_Boolean S1 = Standard_False;
331   Standard_Boolean S2 = Standard_False;
332
333   Standard_Real U1f,U1l,U2f,U2l,V1f = 0.,V1l = 0.,V2f = 0.,V2l = 0.;
334
335   GC1 = DrawTrSurf::GetCurve(a[1]);
336   if ( GC1.IsNull()) {
337     GS1 = DrawTrSurf::GetSurface(a[1]);
338     if ( GS1.IsNull())
339       return 1;
340     S1 = Standard_True;
341     GS1->Bounds(U1f,U1l,V1f,V1l);
342   }
343   else {
344     C1 = Standard_True;
345     U1f = GC1->FirstParameter();
346     U1l = GC1->LastParameter();
347   }
348
349   GC2 = DrawTrSurf::GetCurve(a[2]);
350   if ( GC2.IsNull()) {
351     GS2 = DrawTrSurf::GetSurface(a[2]);
352     if ( GS2.IsNull())
353       return 1;
354     S2 = Standard_True;
355     GS2->Bounds(U2f,U2l,V2f,V2l);
356   }
357   else {
358     C2 = Standard_True;
359     U2f = GC2->FirstParameter();
360     U2l = GC2->LastParameter();
361   }
362
363   char name[100];
364   if ( C1 && C2)
365     {
366     GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
367
368     if(!Ex.Extrema().IsParallel())
369       {
370       const Standard_Integer aNExtr = Ex.NbExtrema();
371       if(aNExtr == 0)
372         {
373         di << "No solutions!\n";
374         }
375       else
376         {
377         for ( Standard_Integer i = 1; i <= aNExtr; i++)
378           {
379           gp_Pnt P1,P2;
380           Ex.Points(i,P1,P2);
381           Standard_Real U1,V1;
382           Ex.Parameters(i,U1,V1);
383           if (P1.Distance(P2) < 1.e-16)
384             {
385             di << "Extrema " << i << " is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
386             continue;
387             }
388
389           Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
390           Handle(Geom_TrimmedCurve) CT = 
391             new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
392           Sprintf(name,"%s%d","ext_",i);
393           char* temp = name; // portage WNT
394           DrawTrSurf::Set(temp, CT);
395 #ifdef DEB          
396           di << name << "(U=" << U1 << ";V=" << V1 << ")" << "\n";
397 #else
398           di << name << " ";
399 #endif
400           }
401         }
402       }
403     else
404       {
405       di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n";
406       }
407     }
408   else if ( C1 & S2)
409     {
410     GeomAPI_ExtremaCurveSurface Ex(GC1,GS2,U1f,U1l,U2f,U2l,V2f,V2l);
411
412     const Standard_Integer aNExtr = Ex.NbExtrema();
413     if(aNExtr == 0)
414       {
415       di << "No solutions!\n";
416       }
417     else
418       {
419       for ( Standard_Integer i = 1; i <= aNExtr; i++)
420         {
421         gp_Pnt P1,P2;
422         Ex.Points(i,P1,P2);
423         if (P1.Distance(P2) < 1.e-16) continue;
424         Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
425         Handle(Geom_TrimmedCurve) CT = 
426           new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
427         Sprintf(name,"%s%d","ext_",i);
428         char* temp = name; // portage WNT
429         DrawTrSurf::Set(temp, CT);
430         di << name << " ";
431         }
432       }
433     }
434   else if ( S1 & C2)
435     {
436     GeomAPI_ExtremaCurveSurface Ex(GC2,GS1,U2f,U2l,U1f,U1l,V1f,V1l);
437
438     const Standard_Integer aNExtr = Ex.NbExtrema();
439     if(aNExtr == 0)
440       {
441       di << "No solutions!\n";
442       }
443     else
444       {
445       for ( Standard_Integer i = 1; i <= aNExtr; i++)
446         {
447         gp_Pnt P1,P2;
448         Ex.Points(i,P1,P2);
449         if (P1.Distance(P2) < 1.e-16) continue;
450         Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
451         Handle(Geom_TrimmedCurve) CT = 
452           new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
453         Sprintf(name,"%s%d","ext_",i);
454         char* temp = name; // portage WNT
455         DrawTrSurf::Set(temp, CT);
456         di << name << " ";
457         }
458       }
459     }
460   else if ( S1 & S2)
461     {
462     GeomAPI_ExtremaSurfaceSurface Ex(GS1,GS2,U1f,U1l,V1f,V1l,U2f,U2l,V2f,V2l);
463
464     const Standard_Integer aNExtr = Ex.NbExtrema();
465     if(aNExtr == 0)
466       {
467       di << "No solutions!\n";
468       }
469     else
470       {
471       for ( Standard_Integer i = 1; i <= aNExtr; i++)
472         {
473         gp_Pnt P1,P2;
474         Ex.Points(i,P1,P2);
475         if (P1.Distance(P2) < 1.e-16)
476           continue;
477
478         Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
479         Handle(Geom_TrimmedCurve) CT = 
480           new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
481         Sprintf(name,"%s%d","ext_",i);
482         char* temp = name; // portage WNT
483         DrawTrSurf::Set(temp, CT);
484         di << name << " ";
485         }
486       }
487     }
488
489   return 0;
490   }
491
492 //=======================================================================
493 //function : totalextcc
494 //purpose  : 
495 //=======================================================================
496
497 static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a)
498 {
499   if ( n<3) return 1;
500
501   Handle(Geom_Curve)   GC1, GC2;
502
503
504   Standard_Real U1f,U1l,U2f,U2l;
505
506   GC1 = DrawTrSurf::GetCurve(a[1]);
507   if ( GC1.IsNull()) {
508       return 1;
509   }
510   else {
511     U1f = GC1->FirstParameter();
512     U1l = GC1->LastParameter();
513   }
514
515   GC2 = DrawTrSurf::GetCurve(a[2]);
516   if ( GC2.IsNull()) {
517       return 1;
518   }
519   else {
520     U2f = GC2->FirstParameter();
521     U2l = GC2->LastParameter();
522   }
523
524   char name[100];
525     GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
526   gp_Pnt P1,P2;
527   if(Ex.TotalNearestPoints(P1,P2)) {
528     if (P1.Distance(P2) < 1.e-16) {
529       di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n";
530     }
531     else {
532       di << "Extrema is segment of line" << "\n"; 
533       Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2));
534       Handle(Geom_TrimmedCurve) CT = 
535         new Geom_TrimmedCurve(L, 0., P1.Distance(P2));
536       Sprintf(name,"%s%d","ext_",1);
537       char* temp = name; // portage WNT
538       DrawTrSurf::Set(temp, CT);
539       di << name << " ";
540     }
541
542     Standard_Real u1, u2;
543     Ex.TotalLowerDistanceParameters(u1, u2);
544
545     di << "Parameters on curves : " << u1 << " " << u2 << "\n";
546
547   }
548   else {
549     di << "Curves are infinite and parallel" << "\n";
550   }
551   
552   di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n";
553
554   return 0;
555
556 }
557
558
559 void GeometryTest::APICommands(Draw_Interpretor& theCommands)
560 {
561   static Standard_Boolean done = Standard_False;
562   if (done) return;
563
564   done = Standard_True;
565   const char* g;
566
567   g = "GEOMETRY curves and surfaces analysis";
568
569   theCommands.Add("proj", "proj curve/surf x y z [extrema algo: g(grad)/t(tree)]",__FILE__, proj);
570
571   g = "GEOMETRY approximations";
572
573   theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro);
574   theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
575                   __FILE__,
576                   surfapp);
577   theCommands.Add("grilapp",
578        "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu ....  ",
579         __FILE__,grilapp);
580
581   g = "GEOMETRY curves and surfaces analysis";
582
583   theCommands.Add("extrema", "extrema curve/surface curve/surface",__FILE__,extrema);
584   theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc);
585 }