-// File: GeometryTest_API2dCommands.cxx
-// Created: Wed Jan 11 10:33:13 1995
-// Author: Remi LEQUETTE
-// <rle@bravox>
+// Created on: 1995-01-11
+// Created by: Remi LEQUETTE
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
// modified : pmn 11/04/97 : mis dans GeomliteTest
#include <GeomliteTest.hxx>
-#include <Geom2d_Curve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
#include <Draw.hxx>
#include <Draw_Interpretor.hxx>
#include <DrawTrSurf.hxx>
#include <DrawTrSurf_Curve2d.hxx>
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
#include <Geom2dAPI_ExtremaCurveCurve.hxx>
+#include <Geom2dAPI_Interpolate.hxx>
#include <Geom2dAPI_PointsToBSpline.hxx>
#include <Geom2dAPI_InterCurveCurve.hxx>
#include <Geom2d_Line.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GeomAbs_Shape.hxx>
#include <Precision.hxx>
+#include <Geom2d_Circle.hxx>
+#include <IntAna2d_AnaIntersection.hxx>
+#include <IntAna2d_IntPoint.hxx>
+#include <IntAna2d_Conic.hxx>
+#include <IntRes2d_IntersectionPoint.hxx>
+#include <Geom2dAdaptor_GHCurve.hxx>
+#include <memory>
#include <stdio.h>
-#ifdef WNT
+#ifdef _WIN32
Standard_IMPORT Draw_Viewer dout;
#endif
{
if ( n < 4) return 1;
- gp_Pnt2d P(atof(a[2]),atof(a[3]));
+ gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
char name[100];
Geom2dAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
GC->LastParameter());
- for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++) {
- gp_Pnt2d P1 = proj.Point(i);
- Handle(Geom2d_Line) L = new Geom2d_Line(P,gp_Vec2d(P,P1));
- Handle(Geom2d_TrimmedCurve) CT =
- new Geom2d_TrimmedCurve(L, 0., P.Distance(P1));
- sprintf(name,"%s%d","ext_",i);
- char* temp = name; // portage WNT
- DrawTrSurf::Set(temp, CT);
+ for (Standard_Integer i = 1; i <= proj.NbPoints(); i++)
+ {
+ gp_Pnt2d aP1 = proj.Point(i);
+ const Standard_Real aDist = P.Distance(aP1);
+ Sprintf(name, "%s%d", "ext_", i);
+
+ if (aDist > Precision::PConfusion())
+ {
+ Handle(Geom2d_Line) L = new Geom2d_Line(P, gp_Dir2d(aP1.XY() - P.XY()));
+ Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., aDist);
+ DrawTrSurf::Set(name, CT);
+ }
+ else
+ {
+ DrawTrSurf::Set(name, aP1);
+ }
+
di << name << " ";
}
if (n < 3) {
if (n == 2)
- Tol2d = atof(a[1]);
+ Tol2d = Draw::Atof(a[1]);
di << "Tolerance for 2d approx : "<< Tol2d << "\n";
return 0;
}
- Standard_Integer i, Nb = atoi(a[2]);
+ Standard_Integer i, Nb = Draw::Atoi(a[2]);
Standard_Boolean hasPoints = Standard_True;
TColgp_Array1OfPnt2d Points(1, Nb);
else {
// test points ou ordonnees
- hasPoints = Standard_False;
Standard_Integer nc = n - 3;
if (nc == 2 * Nb) {
// points
nc = 3;
for (i = 1; i <= Nb; i++) {
- Points(i).SetCoord(atof(a[nc]),atof(a[nc+1]));
+ Points(i).SetCoord(Draw::Atof(a[nc]),Draw::Atof(a[nc+1]));
nc += 2;
}
}
else if (nc - 2 == Nb) {
// YValues
+ hasPoints = Standard_False;
nc = 5;
- X0 = atof(a[3]);
- DX = atof(a[4]);
+ X0 = Draw::Atof(a[3]);
+ DX = Draw::Atof(a[4]);
for (i = 1; i <= Nb; i++) {
- YValues(i) = atof(a[nc]);
+ YValues(i) = Draw::Atof(a[nc]);
Points(i).SetCoord(X0+(i-1)*DX,YValues(i));
nc++;
}
Handle(Geom2d_BSplineCurve) TheCurve;
if (hasPoints)
- TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
+ {
+ if (!strcmp (a[0], "2dinterpole"))
+ {
+ Geom2dAPI_Interpolate anInterpol (new TColgp_HArray1OfPnt2d(Points), Standard_False, Tol2d);
+ anInterpol.Perform();
+ if (!anInterpol.IsDone())
+ {
+ di << "not done";
+ return 1;
+ }
+ TheCurve = anInterpol.Curve();
+ }
+ else
+ {
+ Geom2dAPI_PointsToBSpline anApprox (Points, Dmin, Dmax, GeomAbs_C2, Tol2d);
+ if (!anApprox.IsDone())
+ {
+ di << "not done";
+ return 1;
+ }
+ TheCurve = anApprox.Curve();
+ }
+ }
else
- TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
+ {
+ if (!strcmp (a[0], "2dinterpole"))
+ {
+ di << "incorrect usage";
+ return 1;
+ }
+ Geom2dAPI_PointsToBSpline anApprox (YValues, X0, DX, Dmin, Dmax, GeomAbs_C2, Tol2d);
+ if (!anApprox.IsDone())
+ {
+ di << "not done";
+ return 1;
+ }
+ TheCurve = anApprox.Curve();
+ }
DrawTrSurf::Set(a[1], TheCurve);
di << a[1];
char name[100];
Geom2dAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
+ Standard_Boolean isInfinitySolutions = Ex.Extrema().IsParallel();
+ const Standard_Integer aNExtr = Ex.NbExtrema();
+
+ if (aNExtr == 0 || isInfinitySolutions)
+ {
+ // Infinity solutions flag may be set with 0 number of
+ // solutions in analytic extrema Curve/Curve.
+ if (isInfinitySolutions)
+ di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n";
+ else
+ di << "No solutions!\n";
+ }
-// modified by APV (compilation error - LINUX)
-// for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) {
- Standard_Integer i;
- for ( i = 1; i <= Ex.NbExtrema(); i++) {
-// modified by APV (compilation error - LINUX)
-
+ for (Standard_Integer i = 1; i <= aNExtr; i++)
+ {
gp_Pnt2d P1,P2;
Ex.Points(i,P1,P2);
- di << "dist " << i << ": " << Ex.Distance(i) << " \n";
- if (Ex.Distance(i) <= Precision::PConfusion()) {
+ di << "dist " << i << ": " << Ex.Distance(i) << " ";
+ if (Ex.Distance(i) <= Precision::PConfusion())
+ {
Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert);
dout << mark;
dout.Flush();
+ Sprintf(name,"%s%d","ext_",i);
+ char* temp = name;
+ DrawTrSurf::Set(temp, P1);
+ di << name << "\n";
}
- else {
+ else
+ {
Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
- Handle(Geom2d_TrimmedCurve) CT =
- new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
- sprintf(name,"%s%d","ext_",i);
+ Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
+ Sprintf(name,"%s%d","ext_",i);
char* temp = name; // portage WNT
DrawTrSurf::Set(temp, CT);
- di << name << " ";
+ di << name << "\n";
}
}
- if (i==1)
- di << "No decisions ";
return 0;
}
-
//=======================================================================
//function : intersect
//purpose :
//=======================================================================
-
-static Standard_Integer intersect(Draw_Interpretor& /*di*/, Standard_Integer n, const char** a)
+static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
- if( n < 2)
+ if (n < 2)
+ {
+ di.PrintHelp(a[0]);
return 1;
+ }
Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
- if ( C1.IsNull())
+ if (C1.IsNull())
+ {
+ di << "Curve " << a[1] << " is null\n";
return 1;
+ }
+ Handle(Geom2d_Curve) C2;
Standard_Real Tol = 0.001;
+ Standard_Boolean bPrintState = Standard_False;
+
+ // Retrieve other parameters if any
+ for (Standard_Integer i = 2; i < n; ++i)
+ {
+ if (!strcmp(a[i], "-tol"))
+ {
+ Tol = Draw::Atof(a[++i]);
+ }
+ else if (!strcmp(a[i], "-state"))
+ {
+ bPrintState = Standard_True;
+ }
+ else
+ {
+ C2 = DrawTrSurf::GetCurve2d(a[i]);
+ if (C2.IsNull())
+ {
+ di << "Curve " << a[i] << " is null\n";
+ return 1;
+ }
+ }
+ }
+
Geom2dAPI_InterCurveCurve Intersector;
- Handle(Geom2d_Curve) C2;
- if ( n == 3) {
- C2 = DrawTrSurf::GetCurve2d(a[2]);
- if ( C2.IsNull())
- return 1;
- Intersector.Init(C1,C2,Tol);
- }
- else {
+ if (!C2.IsNull())
+ // Curves intersection
+ Intersector.Init(C1, C2, Tol);
+ else
+ // Self-intersection of the curve
Intersector.Init(C1, Tol);
+
+ const Geom2dInt_GInter& anIntTool = Intersector.Intersector();
+ if (!anIntTool.IsDone())
+ {
+ di << "Intersection failed\n";
+ return 0;
}
- Standard_Integer i;
+ if (anIntTool.IsEmpty())
+ return 0;
- for ( i = 1; i <= Intersector.NbPoints(); i++) {
+ Standard_Integer aNbPoints = Intersector.NbPoints();
+ for (Standard_Integer i = 1; i <= aNbPoints; i++)
+ {
+ // API simplified result
gp_Pnt2d P = Intersector.Point(i);
- Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert);
+ di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
+ // Intersection extended results from intersection tool
+ const IntRes2d_IntersectionPoint& aPInt = anIntTool.Point(i);
+ di << "parameter on the fist: " << aPInt.ParamOnFirst();
+ di << " parameter on the second: " << aPInt.ParamOnSecond() << "\n";
+ if (bPrintState)
+ {
+ di << "Intersection type: " <<
+ (aPInt.TransitionOfFirst().IsTangent() ? "TOUCH" : "INTERSECTION") << "\n";
+ }
+ Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
dout << mark;
}
dout.Flush();
- Handle(Geom2d_Curve) S1,S2;
+ Handle(Geom2d_Curve) S1, S2;
Handle(DrawTrSurf_Curve2d) CD;
- if ( n == 3) {
- for ( i = 1; i <= Intersector.NbSegments(); i++) {
- Intersector.Segment(i,S1,S2);
- CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
- dout << CD;
- CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
- dout << CD;
+ Standard_Integer aNbSegments = Intersector.NbSegments();
+ for (Standard_Integer i = 1; i <= aNbSegments; i++)
+ {
+ di << "Segment #" << i << " found.\n";
+ Intersector.Segment(i,S1,S2);
+ CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
+ dout << CD;
+ CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
+ dout << CD;
+ }
+
+ dout.Flush();
+
+ return 0;
+}
+
+//=======================================================================
+//function : intersect_ana
+//purpose :
+//=======================================================================
+
+static Standard_Integer intersect_ana(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+ if (n < 2)
+ {
+ std::cout << "2dintana circle circle " << std::endl;
+ return 1;
+ }
+
+ Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
+ if (C1.IsNull() && !C1->IsKind(STANDARD_TYPE(Geom2d_Circle)))
+ return 1;
+
+ Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
+ if (C2.IsNull() && !C2->IsKind(STANDARD_TYPE(Geom2d_Circle)))
+ return 1;
+
+ Handle(Geom2d_Circle) aCir1 = Handle(Geom2d_Circle)::DownCast(C1);
+ Handle(Geom2d_Circle) aCir2 = Handle(Geom2d_Circle)::DownCast(C2);
+
+ IntAna2d_AnaIntersection Intersector(aCir1->Circ2d(), aCir2->Circ2d());
+
+ Standard_Integer i;
+
+ for (i = 1; i <= Intersector.NbPoints(); i++) {
+ gp_Pnt2d P = Intersector.Point(i).Value();
+ di << "Intersection point " << i << " : " << P.X() << " " << P.Y() << "\n";
+ di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
+ di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
+ Handle(Draw_Marker2D) mark = new Draw_Marker2D(P, Draw_X, Draw_vert);
+ dout << mark;
+ }
+ dout.Flush();
+
+ return 0;
+}
+
+//=======================================================================
+//function : intconcon
+//purpose :
+//=======================================================================
+
+static Standard_Integer intconcon(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+ if( n < 2)
+ {
+ std::cout<< "intconcon con1 con2 "<<std::endl;
+ return 1;
+ }
+
+ Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
+ if (C1.IsNull())
+ {
+ std::cout << a[1] << " is Null " << std::endl;
+ return 1;
+ }
+
+ Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
+ if (C2.IsNull())
+ {
+ std::cout << a[2] << " is Null " << std::endl;
+ return 1;
+ }
+
+ Geom2dAdaptor_Curve AC1(C1), AC2(C2);
+ GeomAbs_CurveType T1 = AC1.GetType(), T2 = AC2.GetType();
+#if (defined(_MSC_VER) && (_MSC_VER < 1600))
+ std::auto_ptr<IntAna2d_Conic> pCon;
+#else
+ std::unique_ptr<IntAna2d_Conic> pCon;
+#endif
+ switch (T2)
+ {
+ case GeomAbs_Line:
+ {
+ pCon.reset(new IntAna2d_Conic(AC2.Line()));
+ break;
+ }
+ case GeomAbs_Circle:
+ {
+ pCon.reset(new IntAna2d_Conic(AC2.Circle()));
+ break;
+ }
+ case GeomAbs_Ellipse:
+ {
+ pCon.reset(new IntAna2d_Conic(AC2.Ellipse()));
+ break;
+ }
+ case GeomAbs_Hyperbola:
+ {
+ pCon.reset(new IntAna2d_Conic(AC2.Hyperbola()));
+ break;
+ }
+ case GeomAbs_Parabola:
+ {
+ pCon.reset(new IntAna2d_Conic(AC2.Parabola()));
+ break;
+ }
+ default:
+ std::cout << a[2] << " is not conic " << std::endl;
+ return 1;
+ }
+
+ IntAna2d_AnaIntersection Intersector;
+ switch (T1)
+ {
+ case GeomAbs_Line:
+ Intersector.Perform(AC1.Line(), *pCon);
+ break;
+ case GeomAbs_Circle:
+ Intersector.Perform(AC1.Circle(), *pCon);
+ break;
+ case GeomAbs_Ellipse:
+ Intersector.Perform(AC1.Ellipse(), *pCon);
+ break;
+ case GeomAbs_Hyperbola:
+ Intersector.Perform(AC1.Hyperbola(), *pCon);
+ break;
+ case GeomAbs_Parabola:
+ Intersector.Perform(AC1.Parabola(), *pCon);
+ break;
+ default:
+ std::cout << a[1] << " is not conic " << std::endl;
+ return 1;
+ }
+
+ Standard_Integer i;
+ for ( i = 1; i <= Intersector.NbPoints(); i++) {
+ gp_Pnt2d P = Intersector.Point(i).Value();
+ di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
+ di << "parameter on the fist: " << Intersector.Point(i).ParamOnFirst();
+ if (!Intersector.Point(i).SecondIsImplicit())
+ {
+ di << " parameter on the second: " << Intersector.Point(i).ParamOnSecond() << "\n";
+ }
+ else
+ {
+ di << "\n";
}
+ Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert);
+ dout << mark;
}
dout.Flush();
}
+
void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean done = Standard_False;
g = "GEOMETRY intersections";
- theCommands.Add("2dintersect", "intersect curve curve",__FILE__,
- intersect,g);
+ theCommands.Add("2dintersect", "2dintersect curve1 [curve2] [-tol tol] [-state]\n"
+ "Intersects the given 2d curve(s)."
+ "If only one curve is given, it will be checked on self-intersection.\n"
+ "Options:\n"
+ " -tol - allows changing the intersection tolerance (default value is 1.e-3);\n"
+ " -state - allows printing the intersection state for each point.",
+ __FILE__, intersect, g);
+
+ theCommands.Add("2dintanalytical", "intersect circle1 and circle2 using IntAna",__FILE__,
+ intersect_ana,g);
+ theCommands.Add("intconcon", "intersect conic curve1 and conic curve2 using IntAna", __FILE__,
+ intconcon, g);
}