084c495e975837968caa1a543d71bf88bdc455d1
[occt.git] / src / GeomliteTest / GeomliteTest_API2dCommands.cxx
1 // Created on: 1995-01-11
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 // modified : pmn 11/04/97 : mis dans GeomliteTest
18
19
20 #include <GeomliteTest.hxx>
21 #include <Geom2d_BSplineCurve.hxx>
22 #include <Draw.hxx>
23 #include <Draw_Interpretor.hxx>
24 #include <DrawTrSurf.hxx>
25 #include <Draw_Appli.hxx>
26 #include <DrawTrSurf_Curve2d.hxx>
27 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
28 #include <Geom2dAPI_ExtremaCurveCurve.hxx>
29 #include <Geom2dAPI_PointsToBSpline.hxx>
30 #include <Geom2dAPI_InterCurveCurve.hxx>
31 #include <Geom2d_Line.hxx>
32 #include <Geom2d_TrimmedCurve.hxx>
33 #include <TColgp_Array1OfPnt2d.hxx>
34 #include <gp_Pnt.hxx>
35 #include <Draw_Marker2D.hxx>
36 #include <Draw_Color.hxx>
37 #include <Draw_MarkerShape.hxx>
38 #include <TColStd_Array1OfReal.hxx>
39 #include <GeomAbs_Shape.hxx>
40 #include <Precision.hxx>
41 #include <Geom2d_Circle.hxx>
42 #include <IntAna2d_AnaIntersection.hxx>
43 #include <IntAna2d_IntPoint.hxx>
44 #include <IntRes2d_IntersectionPoint.hxx>
45
46 #include <stdio.h>
47 #ifdef _WIN32
48 Standard_IMPORT Draw_Viewer dout;
49 #endif
50
51 //=======================================================================
52 //function : proj
53 //purpose  : 
54 //=======================================================================
55
56 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
57 {
58   if ( n < 4) return 1;
59
60   gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
61
62   char name[100];
63
64   Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
65
66   if (GC.IsNull())
67     return 1;
68
69   Geom2dAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
70                                           GC->LastParameter());
71   
72   for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++) {
73     gp_Pnt2d P1 = proj.Point(i);
74     Handle(Geom2d_Line) L = new Geom2d_Line(P,gp_Vec2d(P,P1));
75     Handle(Geom2d_TrimmedCurve) CT = 
76       new Geom2d_TrimmedCurve(L, 0., P.Distance(P1));
77     Sprintf(name,"%s%d","ext_",i);
78     char* temp = name; // portage WNT
79     DrawTrSurf::Set(temp, CT);
80     di << name << " ";
81   }
82
83   return 0;
84 }
85
86 //=======================================================================
87 //function : appro
88 //purpose  : 
89 //=======================================================================
90
91 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
92 {
93   // Approximation et interpolation 2d
94
95   // 2dappro
96   //     - affiche la tolerance
97   // 2dappro tol
98   //     - change la tolerance
99   // 2dappro result nbpoint 
100   //     - saisie interactive
101   // 2dappro result nbpoint curve 
102   //     - calcule des points sur la courbe
103   // 2dappro result nbpoint x1 y1 x2 y2 .. 
104   //     - tableau de points
105   // 2dappro result nbpoint x1 dx y1 y2 ..
106   //     - tableau de points (x1,y1) (x1+dx,y2) ... avec x = t
107   
108
109   static Standard_Real Tol2d = 1.e-6;
110
111   if (n < 3) {
112     if (n == 2) 
113       Tol2d = Draw::Atof(a[1]);
114     
115     di << "Tolerance for 2d approx : "<< Tol2d << "\n";
116     return 0;
117   }
118
119
120   Standard_Integer i, Nb = Draw::Atoi(a[2]);
121   
122   Standard_Boolean hasPoints = Standard_True;
123   TColgp_Array1OfPnt2d Points(1, Nb);
124   TColStd_Array1OfReal YValues(1,Nb);
125   Standard_Real X0=0,DX=0;
126   
127   Handle(Draw_Marker2D) mark;
128   
129   if (n == 3)  {
130     // saisie interactive
131     Standard_Integer id,XX,YY,b;
132     dout.Select(id,XX,YY,b);
133     Standard_Real zoom = dout.Zoom(id);
134
135     Points(1) = gp_Pnt2d( ((Standard_Real)XX)/zoom, 
136                           ((Standard_Real)YY)/zoom );
137     
138     mark = new Draw_Marker2D( Points(1), Draw_X, Draw_vert); 
139     
140     dout << mark;
141     
142     for (i = 2; i<=Nb; i++) {
143       dout.Select(id,XX,YY,b);
144       Points(i) = gp_Pnt2d( ((Standard_Real)XX)/zoom, 
145                             ((Standard_Real)YY)/zoom );
146       mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert); 
147       dout << mark;
148     }
149   }    
150   else {
151     if ( n == 4) {
152     // points sur courbe
153       Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[3]);
154       if ( GC.IsNull()) 
155         return 1;
156
157       Standard_Real U, U1, U2;
158       U1 = GC->FirstParameter();
159       U2 = GC->LastParameter();
160       Standard_Real Delta = ( U2 - U1) / (Nb-1);
161       for ( i = 1 ; i <= Nb; i++) {
162         U = U1 + (i-1) * Delta;
163         Points(i) = GC->Value(U);
164       }
165     }
166
167     else {
168       // test points ou ordonnees
169       hasPoints = Standard_False;
170       Standard_Integer nc = n - 3;
171       if (nc == 2 * Nb) {
172         // points
173         nc = 3;
174         for (i = 1; i <= Nb; i++) {
175           Points(i).SetCoord(Draw::Atof(a[nc]),Draw::Atof(a[nc+1]));
176           nc += 2;
177         }
178       }
179       else if (nc - 2 == Nb) {
180         // YValues
181         nc = 5;
182         X0 = Draw::Atof(a[3]);
183         DX = Draw::Atof(a[4]);
184         for (i = 1; i <= Nb; i++) {
185           YValues(i) = Draw::Atof(a[nc]);
186           Points(i).SetCoord(X0+(i-1)*DX,YValues(i));
187           nc++;
188         }
189       }
190       else
191         return 1;
192     }
193     // display the points
194     for ( i = 1 ; i <= Nb; i++) {
195       mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert); 
196       dout << mark;
197     }
198   }
199   dout.Flush();
200   Standard_Integer Dmin = 3;
201   Standard_Integer Dmax = 8;
202   
203   Handle(Geom2d_BSplineCurve) TheCurve;
204   if (hasPoints)
205     TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
206   else
207     TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
208   
209   DrawTrSurf::Set(a[1], TheCurve);
210   di << a[1];
211
212   return 0;
213
214 }
215
216 //=======================================================================
217 //function : extrema
218 //purpose  : 
219 //=======================================================================
220
221 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
222 {
223   if ( n<3) return 1;
224
225   Handle(Geom2d_Curve)   GC1, GC2;
226
227   Standard_Real U1f,U1l,U2f,U2l;
228
229   GC1 = DrawTrSurf::GetCurve2d(a[1]);
230   if ( GC1.IsNull())
231     return 1;
232   U1f = GC1->FirstParameter();
233   U1l = GC1->LastParameter();
234
235   GC2 = DrawTrSurf::GetCurve2d(a[2]);
236   if ( GC2.IsNull())
237     return 1;
238   U2f = GC2->FirstParameter();
239   U2l = GC2->LastParameter();
240
241   char name[100];
242
243   Geom2dAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
244
245 // modified by APV (compilation error - LINUX)
246 //  for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) {
247   Standard_Integer i;
248   const Standard_Integer aNExtr = Ex.NbExtrema();
249   for ( i = 1; i <= aNExtr; i++) {
250 // modified by APV (compilation error - LINUX)
251
252     gp_Pnt2d P1,P2;
253     Ex.Points(i,P1,P2);
254     di << "dist " << i << ": " << Ex.Distance(i) << "  ";
255     if (Ex.Distance(i) <= Precision::PConfusion()) {
256       Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert); 
257       dout << mark;
258       dout.Flush();
259       Sprintf(name,"%s%d","ext_",i);
260       char* temp = name;
261       DrawTrSurf::Set(temp, P1);
262       di << name << "\n";
263     }
264     else {
265       Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
266       Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
267       Sprintf(name,"%s%d","ext_",i);
268       char* temp = name; // portage WNT
269       DrawTrSurf::Set(temp, CT);
270       di << name << "\n";
271     }
272   }
273   if (i==1)
274     di << "No solutions!\n";
275
276   return 0;
277 }
278
279 //=======================================================================
280 //function : intersect
281 //purpose  : 
282 //=======================================================================
283
284 static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
285 {
286   if( n < 2) 
287   {
288 #ifdef OCCT_DEBUG
289     cout<< "2dintersect curve curve [Tol]"<<endl;
290 #endif
291     return 1;
292   }
293   Standard_Integer k = 1;
294   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[k++]);
295   if ( C1.IsNull()) 
296     return 1;
297
298   Standard_Real Tol = 0.001;
299   Geom2dAPI_InterCurveCurve Intersector;
300
301   Handle(Geom2d_Curve) C2;
302   if ( k < n ) {
303     C2 = DrawTrSurf::GetCurve2d(a[k++]);
304     if ( C2.IsNull())
305       return 1;
306   }
307   if(k < n)
308     Tol = Draw::Atof(a[k]);
309
310   if(!C2.IsNull())
311   {
312     Intersector.Init(C1,C2,Tol);
313   }
314   else {
315     Intersector.Init(C1, Tol);
316   }
317
318   Standard_Integer i;
319
320   for ( i = 1; i <= Intersector.NbPoints(); i++) {
321     gp_Pnt2d P = Intersector.Point(i);
322
323     di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
324     di<<"parameter on the fist: "<<Intersector.Intersector().Point(i).ParamOnFirst();
325     di<<" parameter on the second: "<<Intersector.Intersector().Point(i).ParamOnSecond()<<"\n";
326     Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert); 
327     dout << mark;
328   }
329   dout.Flush();
330
331   Handle(Geom2d_Curve) S1,S2;
332   Handle(DrawTrSurf_Curve2d) CD;
333   for ( i = 1; i <= Intersector.NbSegments(); i++) {
334     Intersector.Segment(i,S1,S2);
335     CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
336     dout << CD;
337     CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
338     dout << CD;
339   }
340   
341   dout.Flush();
342
343   return 0;
344 }
345
346 //=======================================================================
347 //function : intersect
348 //purpose  : 
349 //=======================================================================
350
351 static Standard_Integer intersect_ana(Draw_Interpretor& di, Standard_Integer n, const char** a)
352 {
353   if( n < 2) 
354   {
355     cout<< "2dintana circle circle "<<endl;
356     return 1;
357   }
358   
359   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
360   if ( C1.IsNull() && !C1->IsKind(STANDARD_TYPE(Geom2d_Circle))) 
361     return 1;
362
363   Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
364   if ( C2.IsNull() && !C2->IsKind(STANDARD_TYPE(Geom2d_Circle)))
365     return 1;
366
367   Handle(Geom2d_Circle) aCir1 = Handle(Geom2d_Circle)::DownCast(C1);
368   Handle(Geom2d_Circle) aCir2 = Handle(Geom2d_Circle)::DownCast(C2);
369
370   IntAna2d_AnaIntersection Intersector(aCir1->Circ2d(), aCir2->Circ2d());
371
372   Standard_Integer i;
373
374   for ( i = 1; i <= Intersector.NbPoints(); i++) {
375     gp_Pnt2d P = Intersector.Point(i).Value();
376     di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
377         di<<"parameter on the fist: "<<Intersector.Point(i).ParamOnFirst();
378         di<<" parameter on the second: "<<Intersector.Point(i).ParamOnSecond()<<"\n";
379     Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert); 
380     dout << mark;
381   }
382   dout.Flush();
383
384   return 0;
385 }
386
387
388
389 void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
390 {
391   static Standard_Boolean done = Standard_False;
392   if (done) return;
393
394   const char *g;
395
396   done = Standard_True;
397   g = "GEOMETRY curves and surfaces analysis";
398
399   theCommands.Add("2dproj", "proj curve x y",__FILE__, proj,g);
400
401   g = "GEOMETRY approximations";
402
403   theCommands.Add("2dapprox", "2dapprox result nbpoint [curve] [[x] y [x] y...]",__FILE__, 
404                   appro,g);
405   theCommands.Add("2dinterpole", "2dinterpole result nbpoint [curve] [[x] y [x] y ...]",__FILE__, 
406                   appro,g);
407
408   g = "GEOMETRY curves and surfaces analysis";
409
410   theCommands.Add("2dextrema", "extrema curve curve",__FILE__,
411                   extrema,g);
412
413   g = "GEOMETRY intersections";
414
415   theCommands.Add("2dintersect", "intersect curve curve [Tol]",__FILE__,
416                   intersect,g);
417
418   theCommands.Add("2dintanalytical", "intersect curve curve using IntAna",__FILE__,
419                   intersect_ana,g);
420 }