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