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