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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // modified : pmn 11/04/97 : mis dans GeomliteTest
20 #include <GeomliteTest.hxx>
21 #include <Geom2d_BSplineCurve.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>
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 <IntAna2d_Conic.hxx>
45 #include <IntRes2d_IntersectionPoint.hxx>
46 #include <Geom2dAdaptor_GHCurve.hxx>
51 Standard_IMPORT Draw_Viewer dout;
54 //=======================================================================
57 //=======================================================================
59 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
63 gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
67 Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
72 Geom2dAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
75 for (Standard_Integer i = 1; i <= proj.NbPoints(); i++)
77 gp_Pnt2d aP1 = proj.Point(i);
78 const Standard_Real aDist = P.Distance(aP1);
79 Sprintf(name, "%s%d", "ext_", i);
81 if (aDist > Precision::PConfusion())
83 Handle(Geom2d_Line) L = new Geom2d_Line(P, gp_Dir2d(aP1.XY() - P.XY()));
84 Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., aDist);
85 DrawTrSurf::Set(name, CT);
89 DrawTrSurf::Set(name, aP1);
98 //=======================================================================
101 //=======================================================================
103 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
105 // Approximation et interpolation 2d
108 // - affiche la tolerance
110 // - change la tolerance
111 // 2dappro result nbpoint
112 // - saisie interactive
113 // 2dappro result nbpoint curve
114 // - calcule des points sur la courbe
115 // 2dappro result nbpoint x1 y1 x2 y2 ..
116 // - tableau de points
117 // 2dappro result nbpoint x1 dx y1 y2 ..
118 // - tableau de points (x1,y1) (x1+dx,y2) ... avec x = t
121 static Standard_Real Tol2d = 1.e-6;
125 Tol2d = Draw::Atof(a[1]);
127 di << "Tolerance for 2d approx : "<< Tol2d << "\n";
132 Standard_Integer i, Nb = Draw::Atoi(a[2]);
134 Standard_Boolean hasPoints = Standard_True;
135 TColgp_Array1OfPnt2d Points(1, Nb);
136 TColStd_Array1OfReal YValues(1,Nb);
137 Standard_Real X0=0,DX=0;
139 Handle(Draw_Marker2D) mark;
142 // saisie interactive
143 Standard_Integer id,XX,YY,b;
144 dout.Select(id,XX,YY,b);
145 Standard_Real zoom = dout.Zoom(id);
147 Points(1) = gp_Pnt2d( ((Standard_Real)XX)/zoom,
148 ((Standard_Real)YY)/zoom );
150 mark = new Draw_Marker2D( Points(1), Draw_X, Draw_vert);
154 for (i = 2; i<=Nb; i++) {
155 dout.Select(id,XX,YY,b);
156 Points(i) = gp_Pnt2d( ((Standard_Real)XX)/zoom,
157 ((Standard_Real)YY)/zoom );
158 mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert);
165 Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[3]);
169 Standard_Real U, U1, U2;
170 U1 = GC->FirstParameter();
171 U2 = GC->LastParameter();
172 Standard_Real Delta = ( U2 - U1) / (Nb-1);
173 for ( i = 1 ; i <= Nb; i++) {
174 U = U1 + (i-1) * Delta;
175 Points(i) = GC->Value(U);
180 // test points ou ordonnees
181 hasPoints = Standard_False;
182 Standard_Integer nc = n - 3;
186 for (i = 1; i <= Nb; i++) {
187 Points(i).SetCoord(Draw::Atof(a[nc]),Draw::Atof(a[nc+1]));
191 else if (nc - 2 == Nb) {
194 X0 = Draw::Atof(a[3]);
195 DX = Draw::Atof(a[4]);
196 for (i = 1; i <= Nb; i++) {
197 YValues(i) = Draw::Atof(a[nc]);
198 Points(i).SetCoord(X0+(i-1)*DX,YValues(i));
205 // display the points
206 for ( i = 1 ; i <= Nb; i++) {
207 mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert);
212 Standard_Integer Dmin = 3;
213 Standard_Integer Dmax = 8;
215 Handle(Geom2d_BSplineCurve) TheCurve;
217 TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
219 TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
221 DrawTrSurf::Set(a[1], TheCurve);
228 //=======================================================================
231 //=======================================================================
233 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
237 Handle(Geom2d_Curve) GC1, GC2;
239 Standard_Real U1f,U1l,U2f,U2l;
241 GC1 = DrawTrSurf::GetCurve2d(a[1]);
244 U1f = GC1->FirstParameter();
245 U1l = GC1->LastParameter();
247 GC2 = DrawTrSurf::GetCurve2d(a[2]);
250 U2f = GC2->FirstParameter();
251 U2l = GC2->LastParameter();
255 Geom2dAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
256 Standard_Boolean isInfinitySolutions = Ex.Extrema().IsParallel();
257 const Standard_Integer aNExtr = Ex.NbExtrema();
259 if (aNExtr == 0 || isInfinitySolutions)
261 // Infinity solutions flag may be set with 0 number of
262 // solutions in analytic extrema Curve/Curve.
263 if (isInfinitySolutions)
264 di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n";
266 di << "No solutions!\n";
269 for (Standard_Integer i = 1; i <= aNExtr; i++)
273 di << "dist " << i << ": " << Ex.Distance(i) << " ";
274 if (Ex.Distance(i) <= Precision::PConfusion())
276 Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert);
279 Sprintf(name,"%s%d","ext_",i);
281 DrawTrSurf::Set(temp, P1);
286 Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
287 Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
288 Sprintf(name,"%s%d","ext_",i);
289 char* temp = name; // portage WNT
290 DrawTrSurf::Set(temp, CT);
298 //=======================================================================
299 //function : intersect
301 //=======================================================================
302 static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
310 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
313 di << "Curve " << a[1] << " is null\n";
317 Handle(Geom2d_Curve) C2;
318 Standard_Real Tol = 0.001;
319 Standard_Boolean bPrintState = Standard_False;
321 // Retrieve other parameters if any
322 for (Standard_Integer i = 2; i < n; ++i)
324 if (!strcmp(a[i], "-tol"))
326 Tol = Draw::Atof(a[++i]);
328 else if (!strcmp(a[i], "-state"))
330 bPrintState = Standard_True;
334 C2 = DrawTrSurf::GetCurve2d(a[i]);
337 di << "Curve " << a[i] << " is null\n";
343 Geom2dAPI_InterCurveCurve Intersector;
346 // Curves intersection
347 Intersector.Init(C1, C2, Tol);
349 // Self-intersection of the curve
350 Intersector.Init(C1, Tol);
352 const Geom2dInt_GInter& anIntTool = Intersector.Intersector();
353 if (!anIntTool.IsDone())
355 di << "Intersection failed\n";
359 if (anIntTool.IsEmpty())
362 Standard_Integer aNbPoints = Intersector.NbPoints();
363 for (Standard_Integer i = 1; i <= aNbPoints; i++)
365 // API simplified result
366 gp_Pnt2d P = Intersector.Point(i);
367 di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
368 // Intersection extended results from intersection tool
369 const IntRes2d_IntersectionPoint& aPInt = anIntTool.Point(i);
370 di << "parameter on the fist: " << aPInt.ParamOnFirst();
371 di << " parameter on the second: " << aPInt.ParamOnSecond() << "\n";
374 di << "Intersection type: " <<
375 (aPInt.TransitionOfFirst().IsTangent() ? "TOUCH" : "INTERSECTION") << "\n";
377 Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
382 Handle(Geom2d_Curve) S1, S2;
383 Handle(DrawTrSurf_Curve2d) CD;
384 Standard_Integer aNbSegments = Intersector.NbSegments();
385 for (Standard_Integer i = 1; i <= aNbSegments; i++)
387 di << "Segment #" << i << " found.\n";
388 Intersector.Segment(i,S1,S2);
389 CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
391 CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
400 //=======================================================================
401 //function : intersect_ana
403 //=======================================================================
405 static Standard_Integer intersect_ana(Draw_Interpretor& di, Standard_Integer n, const char** a)
409 cout << "2dintana circle circle " << endl;
413 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
414 if (C1.IsNull() && !C1->IsKind(STANDARD_TYPE(Geom2d_Circle)))
417 Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
418 if (C2.IsNull() && !C2->IsKind(STANDARD_TYPE(Geom2d_Circle)))
421 Handle(Geom2d_Circle) aCir1 = Handle(Geom2d_Circle)::DownCast(C1);
422 Handle(Geom2d_Circle) aCir2 = Handle(Geom2d_Circle)::DownCast(C2);
424 IntAna2d_AnaIntersection Intersector(aCir1->Circ2d(), aCir2->Circ2d());
428 for (i = 1; i <= Intersector.NbPoints(); i++) {
429 gp_Pnt2d P = Intersector.Point(i).Value();
430 di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
431 di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
432 di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
433 Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
441 //=======================================================================
442 //function : intconcon
444 //=======================================================================
446 static Standard_Integer intconcon(Draw_Interpretor& di, Standard_Integer n, const char** a)
450 cout<< "intconcon con1 con2 "<<endl;
454 Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
457 cout << a[1] << " is Null " << endl;
461 Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
464 cout << a[2] << " is Null " << endl;
468 Geom2dAdaptor_Curve AC1(C1), AC2(C2);
469 GeomAbs_CurveType T1 = AC1.GetType(), T2 = AC2.GetType();
470 #if (defined(_MSC_VER) && (_MSC_VER < 1600))
471 std::auto_ptr<IntAna2d_Conic> pCon;
473 std::unique_ptr<IntAna2d_Conic> pCon;
479 pCon.reset(new IntAna2d_Conic(AC2.Line()));
484 pCon.reset(new IntAna2d_Conic(AC2.Circle()));
487 case GeomAbs_Ellipse:
489 pCon.reset(new IntAna2d_Conic(AC2.Ellipse()));
492 case GeomAbs_Hyperbola:
494 pCon.reset(new IntAna2d_Conic(AC2.Hyperbola()));
497 case GeomAbs_Parabola:
499 pCon.reset(new IntAna2d_Conic(AC2.Parabola()));
503 cout << a[2] << " is not conic " << endl;
507 IntAna2d_AnaIntersection Intersector;
511 Intersector.Perform(AC1.Line(), *pCon);
514 Intersector.Perform(AC1.Circle(), *pCon);
516 case GeomAbs_Ellipse:
517 Intersector.Perform(AC1.Ellipse(), *pCon);
519 case GeomAbs_Hyperbola:
520 Intersector.Perform(AC1.Hyperbola(), *pCon);
522 case GeomAbs_Parabola:
523 Intersector.Perform(AC1.Parabola(), *pCon);
526 cout << a[1] << " is not conic " << endl;
531 for ( i = 1; i <= Intersector.NbPoints(); i++) {
532 gp_Pnt2d P = Intersector.Point(i).Value();
533 di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
534 di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
535 if (!Intersector.Point(i).SecondIsImplicit())
537 di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
543 Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert);
553 void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
555 static Standard_Boolean done = Standard_False;
560 done = Standard_True;
561 g = "GEOMETRY curves and surfaces analysis";
563 theCommands.Add("2dproj", "proj curve x y",__FILE__, proj,g);
565 g = "GEOMETRY approximations";
567 theCommands.Add("2dapprox", "2dapprox result nbpoint [curve] [[x] y [x] y...]",__FILE__,
569 theCommands.Add("2dinterpole", "2dinterpole result nbpoint [curve] [[x] y [x] y ...]",__FILE__,
572 g = "GEOMETRY curves and surfaces analysis";
574 theCommands.Add("2dextrema", "extrema curve curve",__FILE__,
577 g = "GEOMETRY intersections";
579 theCommands.Add("2dintersect", "2dintersect curve1 [curve2] [-tol tol] [-state]\n"
580 "Intersects the given 2d curve(s)."
581 "If only one curve is given, it will be checked on self-intersection.\n"
583 " -tol - allows changing the intersection tolerance (default value is 1.e-3);\n"
584 " -state - allows printing the intersection state for each point.",
585 __FILE__, intersect, g);
587 theCommands.Add("2dintanalytical", "intersect circle1 and circle2 using IntAna",__FILE__,
589 theCommands.Add("intconcon", "intersect conic curve1 and conic curve2 using IntAna", __FILE__,