0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / GeomliteTest / GeomliteTest_API2dCommands.cxx
CommitLineData
b311480e 1// Created on: 1995-01-11
2// Created by: Remi LEQUETTE
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// modified : pmn 11/04/97 : mis dans GeomliteTest
18
19
20#include <GeomliteTest.hxx>
543a9964 21#include <Geom2d_BSplineCurve.hxx>
7fd59977 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>
64a44752 29#include <Geom2dAPI_Interpolate.hxx>
7fd59977 30#include <Geom2dAPI_PointsToBSpline.hxx>
31#include <Geom2dAPI_InterCurveCurve.hxx>
32#include <Geom2d_Line.hxx>
33#include <Geom2d_TrimmedCurve.hxx>
34#include <TColgp_Array1OfPnt2d.hxx>
35#include <gp_Pnt.hxx>
36#include <Draw_Marker2D.hxx>
37#include <Draw_Color.hxx>
38#include <Draw_MarkerShape.hxx>
39#include <TColStd_Array1OfReal.hxx>
40#include <GeomAbs_Shape.hxx>
41#include <Precision.hxx>
3f16d970 42#include <Geom2d_Circle.hxx>
43#include <IntAna2d_AnaIntersection.hxx>
44#include <IntAna2d_IntPoint.hxx>
18d8e3e7 45#include <IntAna2d_Conic.hxx>
1d19db8d 46#include <IntRes2d_IntersectionPoint.hxx>
18d8e3e7 47#include <Geom2dAdaptor_GHCurve.hxx>
48#include <memory>
7fd59977 49
50#include <stdio.h>
57c28b61 51#ifdef _WIN32
7fd59977 52Standard_IMPORT Draw_Viewer dout;
53#endif
54
55//=======================================================================
56//function : proj
57//purpose :
58//=======================================================================
59
60static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
61{
62 if ( n < 4) return 1;
63
91322f44 64 gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
7fd59977 65
66 char name[100];
67
68 Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
69
70 if (GC.IsNull())
71 return 1;
72
73 Geom2dAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
74 GC->LastParameter());
75
23e8067c 76 for (Standard_Integer i = 1; i <= proj.NbPoints(); i++)
77 {
78 gp_Pnt2d aP1 = proj.Point(i);
79 const Standard_Real aDist = P.Distance(aP1);
80 Sprintf(name, "%s%d", "ext_", i);
81
82 if (aDist > Precision::PConfusion())
83 {
84 Handle(Geom2d_Line) L = new Geom2d_Line(P, gp_Dir2d(aP1.XY() - P.XY()));
85 Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., aDist);
86 DrawTrSurf::Set(name, CT);
87 }
88 else
89 {
90 DrawTrSurf::Set(name, aP1);
91 }
92
7fd59977 93 di << name << " ";
94 }
95
96 return 0;
97}
98
99//=======================================================================
100//function : appro
101//purpose :
102//=======================================================================
103
104static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
105{
106 // Approximation et interpolation 2d
107
108 // 2dappro
109 // - affiche la tolerance
110 // 2dappro tol
111 // - change la tolerance
112 // 2dappro result nbpoint
113 // - saisie interactive
114 // 2dappro result nbpoint curve
115 // - calcule des points sur la courbe
116 // 2dappro result nbpoint x1 y1 x2 y2 ..
117 // - tableau de points
118 // 2dappro result nbpoint x1 dx y1 y2 ..
119 // - tableau de points (x1,y1) (x1+dx,y2) ... avec x = t
120
121
122 static Standard_Real Tol2d = 1.e-6;
123
124 if (n < 3) {
125 if (n == 2)
91322f44 126 Tol2d = Draw::Atof(a[1]);
7fd59977 127
128 di << "Tolerance for 2d approx : "<< Tol2d << "\n";
129 return 0;
130 }
131
132
91322f44 133 Standard_Integer i, Nb = Draw::Atoi(a[2]);
7fd59977 134
135 Standard_Boolean hasPoints = Standard_True;
136 TColgp_Array1OfPnt2d Points(1, Nb);
137 TColStd_Array1OfReal YValues(1,Nb);
138 Standard_Real X0=0,DX=0;
139
140 Handle(Draw_Marker2D) mark;
141
142 if (n == 3) {
143 // saisie interactive
144 Standard_Integer id,XX,YY,b;
145 dout.Select(id,XX,YY,b);
146 Standard_Real zoom = dout.Zoom(id);
147
148 Points(1) = gp_Pnt2d( ((Standard_Real)XX)/zoom,
149 ((Standard_Real)YY)/zoom );
150
151 mark = new Draw_Marker2D( Points(1), Draw_X, Draw_vert);
152
153 dout << mark;
154
155 for (i = 2; i<=Nb; i++) {
156 dout.Select(id,XX,YY,b);
157 Points(i) = gp_Pnt2d( ((Standard_Real)XX)/zoom,
158 ((Standard_Real)YY)/zoom );
159 mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert);
160 dout << mark;
161 }
162 }
163 else {
164 if ( n == 4) {
165 // points sur courbe
166 Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[3]);
167 if ( GC.IsNull())
168 return 1;
169
170 Standard_Real U, U1, U2;
171 U1 = GC->FirstParameter();
172 U2 = GC->LastParameter();
173 Standard_Real Delta = ( U2 - U1) / (Nb-1);
174 for ( i = 1 ; i <= Nb; i++) {
175 U = U1 + (i-1) * Delta;
176 Points(i) = GC->Value(U);
177 }
178 }
179
180 else {
181 // test points ou ordonnees
7fd59977 182 Standard_Integer nc = n - 3;
183 if (nc == 2 * Nb) {
184 // points
185 nc = 3;
186 for (i = 1; i <= Nb; i++) {
91322f44 187 Points(i).SetCoord(Draw::Atof(a[nc]),Draw::Atof(a[nc+1]));
7fd59977 188 nc += 2;
189 }
190 }
191 else if (nc - 2 == Nb) {
192 // YValues
64a44752 193 hasPoints = Standard_False;
7fd59977 194 nc = 5;
91322f44 195 X0 = Draw::Atof(a[3]);
196 DX = Draw::Atof(a[4]);
7fd59977 197 for (i = 1; i <= Nb; i++) {
91322f44 198 YValues(i) = Draw::Atof(a[nc]);
7fd59977 199 Points(i).SetCoord(X0+(i-1)*DX,YValues(i));
200 nc++;
201 }
202 }
203 else
204 return 1;
205 }
206 // display the points
207 for ( i = 1 ; i <= Nb; i++) {
208 mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert);
209 dout << mark;
210 }
211 }
212 dout.Flush();
213 Standard_Integer Dmin = 3;
214 Standard_Integer Dmax = 8;
215
216 Handle(Geom2d_BSplineCurve) TheCurve;
217 if (hasPoints)
64a44752 218 {
219 if (!strcmp (a[0], "2dinterpole"))
220 {
221 Geom2dAPI_Interpolate anInterpol (new TColgp_HArray1OfPnt2d(Points), Standard_False, Tol2d);
222 anInterpol.Perform();
223 if (!anInterpol.IsDone())
224 {
225 di << "not done";
226 return 1;
227 }
228 TheCurve = anInterpol.Curve();
229 }
230 else
231 {
232 Geom2dAPI_PointsToBSpline anApprox (Points, Dmin, Dmax, GeomAbs_C2, Tol2d);
233 if (!anApprox.IsDone())
234 {
235 di << "not done";
236 return 1;
237 }
238 TheCurve = anApprox.Curve();
239 }
240 }
7fd59977 241 else
64a44752 242 {
243 if (!strcmp (a[0], "2dinterpole"))
244 {
245 di << "incorrect usage";
246 return 1;
247 }
248 Geom2dAPI_PointsToBSpline anApprox (YValues, X0, DX, Dmin, Dmax, GeomAbs_C2, Tol2d);
249 if (!anApprox.IsDone())
250 {
251 di << "not done";
252 return 1;
253 }
254 TheCurve = anApprox.Curve();
255 }
7fd59977 256
257 DrawTrSurf::Set(a[1], TheCurve);
258 di << a[1];
259
260 return 0;
261
262}
263
264//=======================================================================
265//function : extrema
266//purpose :
267//=======================================================================
268
269static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
270{
271 if ( n<3) return 1;
272
273 Handle(Geom2d_Curve) GC1, GC2;
274
275 Standard_Real U1f,U1l,U2f,U2l;
276
277 GC1 = DrawTrSurf::GetCurve2d(a[1]);
278 if ( GC1.IsNull())
279 return 1;
280 U1f = GC1->FirstParameter();
281 U1l = GC1->LastParameter();
282
283 GC2 = DrawTrSurf::GetCurve2d(a[2]);
284 if ( GC2.IsNull())
285 return 1;
286 U2f = GC2->FirstParameter();
287 U2l = GC2->LastParameter();
288
289 char name[100];
290
291 Geom2dAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
92a206a3 292 Standard_Boolean isInfinitySolutions = Ex.Extrema().IsParallel();
32ca7a51 293 const Standard_Integer aNExtr = Ex.NbExtrema();
7fd59977 294
92a206a3 295 if (aNExtr == 0 || isInfinitySolutions)
296 {
297 // Infinity solutions flag may be set with 0 number of
298 // solutions in analytic extrema Curve/Curve.
299 if (isInfinitySolutions)
300 di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n";
301 else
302 di << "No solutions!\n";
303 }
304
305 for (Standard_Integer i = 1; i <= aNExtr; i++)
306 {
7fd59977 307 gp_Pnt2d P1,P2;
308 Ex.Points(i,P1,P2);
e8746a26 309 di << "dist " << i << ": " << Ex.Distance(i) << " ";
92a206a3 310 if (Ex.Distance(i) <= Precision::PConfusion())
311 {
7fd59977 312 Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert);
313 dout << mark;
314 dout.Flush();
e8746a26 315 Sprintf(name,"%s%d","ext_",i);
316 char* temp = name;
317 DrawTrSurf::Set(temp, P1);
318 di << name << "\n";
7fd59977 319 }
92a206a3 320 else
321 {
7fd59977 322 Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
e8746a26 323 Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
91322f44 324 Sprintf(name,"%s%d","ext_",i);
7fd59977 325 char* temp = name; // portage WNT
326 DrawTrSurf::Set(temp, CT);
e8746a26 327 di << name << "\n";
7fd59977 328 }
329 }
7fd59977 330
331 return 0;
332}
333
7fd59977 334//=======================================================================
335//function : intersect
336//purpose :
337//=======================================================================
305cc3f8 338static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
7fd59977 339{
4bc805bf 340 if (n < 2)
305cc3f8 341 {
4bc805bf 342 di.PrintHelp(a[0]);
7fd59977 343 return 1;
305cc3f8 344 }
4e14c88f 345
4bc805bf 346 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
347 if (C1.IsNull())
348 {
349 di << "Curve " << a[1] << " is null\n";
7fd59977 350 return 1;
4bc805bf 351 }
7fd59977 352
353 Handle(Geom2d_Curve) C2;
4bc805bf 354 Standard_Real Tol = 0.001;
355 Standard_Boolean bPrintState = Standard_False;
305cc3f8 356
4bc805bf 357 // Retrieve other parameters if any
358 for (Standard_Integer i = 2; i < n; ++i)
305cc3f8 359 {
4bc805bf 360 if (!strcmp(a[i], "-tol"))
361 {
362 Tol = Draw::Atof(a[++i]);
363 }
364 else if (!strcmp(a[i], "-state"))
365 {
366 bPrintState = Standard_True;
367 }
368 else
369 {
370 C2 = DrawTrSurf::GetCurve2d(a[i]);
371 if (C2.IsNull())
372 {
373 di << "Curve " << a[i] << " is null\n";
374 return 1;
375 }
376 }
7fd59977 377 }
4bc805bf 378
379 Geom2dAPI_InterCurveCurve Intersector;
380
381 if (!C2.IsNull())
382 // Curves intersection
383 Intersector.Init(C1, C2, Tol);
384 else
385 // Self-intersection of the curve
7fd59977 386 Intersector.Init(C1, Tol);
4bc805bf 387
388 const Geom2dInt_GInter& anIntTool = Intersector.Intersector();
389 if (!anIntTool.IsDone())
390 {
391 di << "Intersection failed\n";
392 return 0;
7fd59977 393 }
394
4bc805bf 395 if (anIntTool.IsEmpty())
396 return 0;
7fd59977 397
4bc805bf 398 Standard_Integer aNbPoints = Intersector.NbPoints();
399 for (Standard_Integer i = 1; i <= aNbPoints; i++)
400 {
401 // API simplified result
7fd59977 402 gp_Pnt2d P = Intersector.Point(i);
4bc805bf 403 di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
404 // Intersection extended results from intersection tool
405 const IntRes2d_IntersectionPoint& aPInt = anIntTool.Point(i);
406 di << "parameter on the fist: " << aPInt.ParamOnFirst();
407 di << " parameter on the second: " << aPInt.ParamOnSecond() << "\n";
408 if (bPrintState)
409 {
410 di << "Intersection type: " <<
411 (aPInt.TransitionOfFirst().IsTangent() ? "TOUCH" : "INTERSECTION") << "\n";
412 }
413 Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
7fd59977 414 dout << mark;
415 }
416 dout.Flush();
417
4bc805bf 418 Handle(Geom2d_Curve) S1, S2;
7fd59977 419 Handle(DrawTrSurf_Curve2d) CD;
4bc805bf 420 Standard_Integer aNbSegments = Intersector.NbSegments();
421 for (Standard_Integer i = 1; i <= aNbSegments; i++)
422 {
4e14c88f 423 di << "Segment #" << i << " found.\n";
305cc3f8 424 Intersector.Segment(i,S1,S2);
425 CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
426 dout << CD;
427 CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
428 dout << CD;
7fd59977 429 }
305cc3f8 430
7fd59977 431 dout.Flush();
432
433 return 0;
434}
435
3f16d970 436//=======================================================================
18d8e3e7 437//function : intersect_ana
3f16d970 438//purpose :
439//=======================================================================
440
441static Standard_Integer intersect_ana(Draw_Interpretor& di, Standard_Integer n, const char** a)
442{
18d8e3e7 443 if (n < 2)
3f16d970 444 {
04232180 445 std::cout << "2dintana circle circle " << std::endl;
3f16d970 446 return 1;
447 }
18d8e3e7 448
3f16d970 449 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
18d8e3e7 450 if (C1.IsNull() && !C1->IsKind(STANDARD_TYPE(Geom2d_Circle)))
3f16d970 451 return 1;
452
453 Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
18d8e3e7 454 if (C2.IsNull() && !C2->IsKind(STANDARD_TYPE(Geom2d_Circle)))
3f16d970 455 return 1;
456
457 Handle(Geom2d_Circle) aCir1 = Handle(Geom2d_Circle)::DownCast(C1);
458 Handle(Geom2d_Circle) aCir2 = Handle(Geom2d_Circle)::DownCast(C2);
459
460 IntAna2d_AnaIntersection Intersector(aCir1->Circ2d(), aCir2->Circ2d());
461
462 Standard_Integer i;
463
18d8e3e7 464 for (i = 1; i <= Intersector.NbPoints(); i++) {
465 gp_Pnt2d P = Intersector.Point(i).Value();
466 di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
467 di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
468 di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
469 Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
470 dout << mark;
471 }
472 dout.Flush();
473
474 return 0;
475}
476
477//=======================================================================
478//function : intconcon
479//purpose :
480//=======================================================================
481
482static Standard_Integer intconcon(Draw_Interpretor& di, Standard_Integer n, const char** a)
483{
484 if( n < 2)
485 {
04232180 486 std::cout<< "intconcon con1 con2 "<<std::endl;
18d8e3e7 487 return 1;
488 }
489
490 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
491 if (C1.IsNull())
492 {
04232180 493 std::cout << a[1] << " is Null " << std::endl;
18d8e3e7 494 return 1;
495 }
496
497 Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
498 if (C2.IsNull())
499 {
04232180 500 std::cout << a[2] << " is Null " << std::endl;
18d8e3e7 501 return 1;
502 }
503
504 Geom2dAdaptor_Curve AC1(C1), AC2(C2);
505 GeomAbs_CurveType T1 = AC1.GetType(), T2 = AC2.GetType();
506#if (defined(_MSC_VER) && (_MSC_VER < 1600))
507 std::auto_ptr<IntAna2d_Conic> pCon;
508#else
509 std::unique_ptr<IntAna2d_Conic> pCon;
510#endif
511 switch (T2)
512 {
513 case GeomAbs_Line:
514 {
515 pCon.reset(new IntAna2d_Conic(AC2.Line()));
516 break;
517 }
518 case GeomAbs_Circle:
519 {
520 pCon.reset(new IntAna2d_Conic(AC2.Circle()));
521 break;
522 }
523 case GeomAbs_Ellipse:
524 {
525 pCon.reset(new IntAna2d_Conic(AC2.Ellipse()));
526 break;
527 }
528 case GeomAbs_Hyperbola:
529 {
530 pCon.reset(new IntAna2d_Conic(AC2.Hyperbola()));
531 break;
532 }
533 case GeomAbs_Parabola:
534 {
535 pCon.reset(new IntAna2d_Conic(AC2.Parabola()));
536 break;
537 }
538 default:
04232180 539 std::cout << a[2] << " is not conic " << std::endl;
18d8e3e7 540 return 1;
541 }
542
543 IntAna2d_AnaIntersection Intersector;
544 switch (T1)
545 {
546 case GeomAbs_Line:
547 Intersector.Perform(AC1.Line(), *pCon);
548 break;
549 case GeomAbs_Circle:
550 Intersector.Perform(AC1.Circle(), *pCon);
551 break;
552 case GeomAbs_Ellipse:
553 Intersector.Perform(AC1.Ellipse(), *pCon);
554 break;
555 case GeomAbs_Hyperbola:
556 Intersector.Perform(AC1.Hyperbola(), *pCon);
557 break;
558 case GeomAbs_Parabola:
559 Intersector.Perform(AC1.Parabola(), *pCon);
560 break;
561 default:
04232180 562 std::cout << a[1] << " is not conic " << std::endl;
18d8e3e7 563 return 1;
564 }
565
566 Standard_Integer i;
3f16d970 567 for ( i = 1; i <= Intersector.NbPoints(); i++) {
568 gp_Pnt2d P = Intersector.Point(i).Value();
569 di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
18d8e3e7 570 di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
571 if (!Intersector.Point(i).SecondIsImplicit())
572 {
573 di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
574 }
575 else
576 {
577 di << "\n";
578 }
3f16d970 579 Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert);
580 dout << mark;
581 }
582 dout.Flush();
583
584 return 0;
585}
586
587
7fd59977 588
589void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
590{
591 static Standard_Boolean done = Standard_False;
592 if (done) return;
593
594 const char *g;
595
596 done = Standard_True;
597 g = "GEOMETRY curves and surfaces analysis";
598
599 theCommands.Add("2dproj", "proj curve x y",__FILE__, proj,g);
600
601 g = "GEOMETRY approximations";
602
603 theCommands.Add("2dapprox", "2dapprox result nbpoint [curve] [[x] y [x] y...]",__FILE__,
604 appro,g);
605 theCommands.Add("2dinterpole", "2dinterpole result nbpoint [curve] [[x] y [x] y ...]",__FILE__,
606 appro,g);
607
608 g = "GEOMETRY curves and surfaces analysis";
609
610 theCommands.Add("2dextrema", "extrema curve curve",__FILE__,
611 extrema,g);
612
613 g = "GEOMETRY intersections";
614
4bc805bf 615 theCommands.Add("2dintersect", "2dintersect curve1 [curve2] [-tol tol] [-state]\n"
616 "Intersects the given 2d curve(s)."
617 "If only one curve is given, it will be checked on self-intersection.\n"
618 "Options:\n"
619 " -tol - allows changing the intersection tolerance (default value is 1.e-3);\n"
620 " -state - allows printing the intersection state for each point.",
621 __FILE__, intersect, g);
3f16d970 622
18d8e3e7 623 theCommands.Add("2dintanalytical", "intersect circle1 and circle2 using IntAna",__FILE__,
3f16d970 624 intersect_ana,g);
18d8e3e7 625 theCommands.Add("intconcon", "intersect conic curve1 and conic curve2 using IntAna", __FILE__,
626 intconcon, g);
7fd59977 627}