1 // Created on: 2003-03-18
2 // Created by: Oleg FEDYAEV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <GeomLib_Tool.ixx>
18 #include <Geom_Curve.hxx>
19 #include <Geom_Line.hxx>
20 #include <Geom_Circle.hxx>
21 #include <Geom_Ellipse.hxx>
22 #include <Geom_Parabola.hxx>
23 #include <Geom_Hyperbola.hxx>
24 #include <Geom_BSplineCurve.hxx>
25 #include <Geom_BezierCurve.hxx>
26 #include <Geom_TrimmedCurve.hxx>
27 #include <Geom_OffsetCurve.hxx>
28 #include <Geom_Surface.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_ConicalSurface.hxx>
32 #include <Geom_SphericalSurface.hxx>
33 #include <Geom_ToroidalSurface.hxx>
34 #include <Geom_BSplineSurface.hxx>
35 #include <Geom_BezierSurface.hxx>
36 #include <Geom_RectangularTrimmedSurface.hxx>
37 #include <Geom_OffsetSurface.hxx>
38 #include <Geom_SurfaceOfLinearExtrusion.hxx>
39 #include <Geom_SurfaceOfRevolution.hxx>
42 #include <gp_Cylinder.hxx>
43 #include <gp_Cone.hxx>
44 #include <gp_Sphere.hxx>
45 #include <gp_Torus.hxx>
47 #include <gp_Circ.hxx>
48 #include <gp_Elips.hxx>
49 #include <gp_Parab.hxx>
50 #include <gp_Hypr.hxx>
52 #include <GeomAdaptor_Curve.hxx>
53 #include <GeomAdaptor_Surface.hxx>
56 #include <Extrema_ExtPC.hxx>
57 #include <Extrema_ExtPS.hxx>
58 #include <Geom2d_Curve.hxx>
59 #include <Geom2d_Line.hxx>
60 #include <Geom2d_Circle.hxx>
61 #include <Geom2d_Ellipse.hxx>
62 #include <Geom2d_Parabola.hxx>
63 #include <Geom2d_Hyperbola.hxx>
64 #include <Geom2d_BSplineCurve.hxx>
65 #include <Geom2d_BezierCurve.hxx>
66 #include <Geom2d_TrimmedCurve.hxx>
67 #include <Geom2d_OffsetCurve.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <gp_Lin2d.hxx>
70 #include <gp_Circ2d.hxx>
71 #include <gp_Elips2d.hxx>
72 #include <gp_Parab2d.hxx>
73 #include <gp_Hypr2d.hxx>
74 #include <Geom2dAdaptor_Curve.hxx>
76 #include <Extrema_ExtPC2d.hxx>
79 // The functions Parameter(s) are used to compute parameter(s) of point
80 // on curves and surfaces. The main rule is that tested point must lied
81 // on curves or surfaces otherwise the resulted parameter(s) may be wrong.
82 // To make search process more common the tolerance value is used to define
83 // the proximity of point to curve or surface. It is clear that this tolerance
84 // value can't be too high to be not in conflict with previous rule.
85 static const Standard_Real MAXTOLERANCEGEOM = 1.e-4;
86 static const Standard_Real MAXTOLERANCEPARM = 1.e-3;
87 static const Standard_Real UNKNOWNVALUE = 1.e+100;
88 static const Standard_Real PARTOLERANCE = 1.e-9;
90 //=======================================================================
91 //function : Parameter
92 //purpose : Get parameter on curve of given point
93 // return FALSE if point is far from curve than tolerance
94 // or computation fails
95 //=======================================================================
97 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom_Curve)& Curve,
99 const Standard_Real Tolerance,
102 if( Curve.IsNull() ) return Standard_False;
105 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
108 Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
110 // process analitical curves
111 if( KindOfCurve == STANDARD_TYPE (Geom_Line) ||
112 KindOfCurve == STANDARD_TYPE (Geom_Circle) ||
113 KindOfCurve == STANDARD_TYPE (Geom_Ellipse) ||
114 KindOfCurve == STANDARD_TYPE (Geom_Parabola) ||
115 KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
117 Standard_Real D = 0.;
119 if( KindOfCurve == STANDARD_TYPE (Geom_Line) )
121 Handle(Geom_Line) aGL = Handle(Geom_Line)::DownCast(Curve);
122 gp_Lin aLin = aGL->Lin();
123 D = aLin.SquareDistance(Point);
126 return Standard_False;
128 U = ElCLib::Parameter(aLin,Point);
130 else if( KindOfCurve == STANDARD_TYPE (Geom_Circle) )
132 Handle(Geom_Circle) aGC = Handle(Geom_Circle)::DownCast(Curve);
133 gp_Circ aCirc = aGC->Circ();
134 D = aCirc.SquareDistance(Point);
137 return Standard_False;
139 U = ElCLib::Parameter(aCirc,Point);
141 else if( KindOfCurve == STANDARD_TYPE (Geom_Ellipse) )
143 Handle(Geom_Ellipse) aGE = Handle(Geom_Ellipse)::DownCast(Curve);
144 gp_Elips anElips = aGE->Elips();
145 U = ElCLib::Parameter(anElips,Point);
146 D = Point.SquareDistance(aGE->Value(U));
149 return Standard_False;
152 else if( KindOfCurve == STANDARD_TYPE (Geom_Parabola) )
154 Handle(Geom_Parabola) aGP = Handle(Geom_Parabola)::DownCast(Curve);
155 gp_Parab aParab = aGP->Parab();
156 U = ElCLib::Parameter(aParab,Point);
157 D = Point.SquareDistance(aGP->Value(U));
160 return Standard_False;
163 else if( KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
165 Handle(Geom_Hyperbola) aGH = Handle(Geom_Hyperbola)::DownCast(Curve);
166 gp_Hypr aHypr = aGH->Hypr();
167 U = ElCLib::Parameter(aHypr,Point);
168 D = Point.SquareDistance(aGH->Value(U));
171 return Standard_False;
175 // process parametrical curves
176 else if( KindOfCurve == STANDARD_TYPE (Geom_BSplineCurve) ||
177 KindOfCurve == STANDARD_TYPE (Geom_BezierCurve) ||
178 KindOfCurve == STANDARD_TYPE (Geom_TrimmedCurve) ||
179 KindOfCurve == STANDARD_TYPE (Geom_OffsetCurve) )
181 GeomAdaptor_Curve aGAC(Curve);
182 Extrema_ExtPC extrema(Point,aGAC);
183 if( !extrema.IsDone() ) return Standard_False;
184 Standard_Integer n = extrema.NbExt();
185 if( n <= 0 ) return Standard_False;
186 Standard_Integer i = 0, iMin = 0;
187 Standard_Real Dist2Min = 1.e+100;
188 for( i = 1; i <= n; i++ )
190 if (extrema.SquareDistance(i) < Dist2Min)
193 Dist2Min = extrema.SquareDistance(i);
196 if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
198 else { return Standard_False; }
200 return Standard_True;
204 //=======================================================================
205 //function : Parameters
206 //purpose : Get parameters on surface of given point
207 // return FALSE if point is far from surface than tolerance
208 // or computation fails
209 //=======================================================================
211 Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
213 const Standard_Real Tolerance,
217 if( Surface.IsNull() ) return Standard_False;
221 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
224 Handle(Standard_Type) KindOfSurface = Surface->DynamicType();
226 // process analitical surfaces
227 if( KindOfSurface == STANDARD_TYPE (Geom_Plane) ||
228 KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) ||
229 KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) ||
230 KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) ||
231 KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
233 Standard_Real D = 0.;
235 if( KindOfSurface == STANDARD_TYPE (Geom_Plane) )
237 Handle(Geom_Plane) aGP = Handle(Geom_Plane)::DownCast(Surface);
238 gp_Pln aPlane = aGP->Pln();
239 D = aPlane.SquareDistance(Point);
242 return Standard_False;
244 ElSLib::Parameters (aPlane,Point,U,V);
246 else if( KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) )
248 Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(Surface);
249 gp_Cylinder aCylinder = aGC->Cylinder();
250 ElSLib::Parameters(aCylinder,Point,U,V);
251 D = Point.SquareDistance(aGC->Value(U, V));
254 return Standard_False;
257 else if( KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) )
259 Handle(Geom_ConicalSurface) aGC = Handle(Geom_ConicalSurface)::DownCast(Surface);
260 gp_Cone aCone = aGC->Cone();
261 ElSLib::Parameters(aCone,Point,U,V);
262 D = Point.SquareDistance(aGC->Value(U, V));
265 return Standard_False;
268 else if( KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) )
270 Handle(Geom_SphericalSurface) aGS = Handle(Geom_SphericalSurface)::DownCast(Surface);
271 gp_Sphere aSphere = aGS->Sphere();
272 ElSLib::Parameters(aSphere,Point,U,V);
273 D = Point.SquareDistance(aGS->Value(U, V));
276 return Standard_False;
279 else if( KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
281 Handle(Geom_ToroidalSurface) aTS = Handle(Geom_ToroidalSurface)::DownCast(Surface);
282 gp_Torus aTorus = aTS->Torus();
283 ElSLib::Parameters(aTorus,Point,U,V);
284 D = Point.SquareDistance(aTS->Value(U, V));
287 return Standard_False;
290 else return Standard_False;
292 // process parametrical surfaces
293 else if( KindOfSurface == STANDARD_TYPE (Geom_BSplineSurface) ||
294 KindOfSurface == STANDARD_TYPE (Geom_BezierSurface) ||
295 KindOfSurface == STANDARD_TYPE (Geom_RectangularTrimmedSurface) ||
296 KindOfSurface == STANDARD_TYPE (Geom_OffsetSurface) ||
297 KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfLinearExtrusion) ||
298 KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfRevolution) )
300 GeomAdaptor_Surface aGAS(Surface);
301 Standard_Real aTolU = PARTOLERANCE, aTolV = PARTOLERANCE;
302 Extrema_ExtPS extrema(Point,aGAS,aTolU,aTolV);
303 if( !extrema.IsDone() ) return Standard_False;
304 Standard_Integer n = extrema.NbExt();
305 if( n <= 0 ) return Standard_False;
307 Standard_Real Dist2Min = 1.e+100;
308 Standard_Integer i = 0, iMin = 0;
309 for( i = 1; i <= n; i++ )
311 if( extrema.SquareDistance(i) < Dist2Min )
313 Dist2Min = extrema.SquareDistance(i);
317 if( iMin != 0 && Dist2Min <= aTol) extrema.Point(iMin).Parameter(U,V);
318 else return Standard_False;
320 else { return Standard_False; }
322 return Standard_True;
326 //=======================================================================
327 //function : Parameter
328 //purpose : Get parameter on curve of given point
329 // return FALSE if point is far from curve than tolerance
330 // or computation fails
331 //=======================================================================
333 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom2d_Curve)& Curve,
334 const gp_Pnt2d& Point,
335 const Standard_Real Tolerance,
338 if( Curve.IsNull() ) return Standard_False;
341 Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
344 Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
346 // process analytical curves
347 if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) ||
348 KindOfCurve == STANDARD_TYPE (Geom2d_Circle) ||
349 KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) ||
350 KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) ||
351 KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
353 Standard_Real D = 0.;
355 if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) )
357 Handle(Geom2d_Line) aGL = Handle(Geom2d_Line)::DownCast(Curve);
358 gp_Lin2d aLin = aGL->Lin2d();
359 D = aLin.SquareDistance(Point);
362 return Standard_False;
364 U = ElCLib::Parameter(aLin,Point);
366 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Circle) )
368 Handle(Geom2d_Circle) aGC = Handle(Geom2d_Circle)::DownCast(Curve);
369 gp_Circ2d aCirc = aGC->Circ2d();
370 D = aCirc.SquareDistance(Point);
373 return Standard_False;
375 U = ElCLib::Parameter(aCirc,Point);
377 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) )
379 Handle(Geom2d_Ellipse) aGE = Handle(Geom2d_Ellipse)::DownCast(Curve);
380 gp_Elips2d anElips = aGE->Elips2d();
381 U = ElCLib::Parameter(anElips,Point);
382 D = Point.SquareDistance(aGE->Value(U));
385 return Standard_False;
388 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) )
390 Handle(Geom2d_Parabola) aGP = Handle(Geom2d_Parabola)::DownCast(Curve);
391 gp_Parab2d aParab = aGP->Parab2d();
392 U = ElCLib::Parameter(aParab,Point);
393 D = Point.SquareDistance(aGP->Value(U));
396 return Standard_False;
399 else if( KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
401 Handle(Geom2d_Hyperbola) aGH = Handle(Geom2d_Hyperbola)::DownCast(Curve);
402 gp_Hypr2d aHypr = aGH->Hypr2d();
403 U = ElCLib::Parameter(aHypr,Point);
404 D = Point.SquareDistance(aGH->Value(U));
407 return Standard_False;
410 else return Standard_False;
412 // process parametrical curves
413 else if( KindOfCurve == STANDARD_TYPE (Geom2d_BSplineCurve) ||
414 KindOfCurve == STANDARD_TYPE (Geom2d_BezierCurve) ||
415 KindOfCurve == STANDARD_TYPE (Geom2d_TrimmedCurve) ||
416 KindOfCurve == STANDARD_TYPE (Geom2d_OffsetCurve) )
418 Geom2dAdaptor_Curve aGAC(Curve);
419 Extrema_ExtPC2d extrema(Point,aGAC);
420 if( !extrema.IsDone() ) return Standard_False;
421 Standard_Integer n = extrema.NbExt();
422 if( n <= 0 ) return Standard_False;
423 Standard_Integer i = 0, iMin = 0;
424 Standard_Real Dist2Min = 1.e+100;
425 for ( i = 1; i <= n; i++ )
427 if( extrema.SquareDistance(i) < Dist2Min )
429 Dist2Min = extrema.SquareDistance(i);
433 if( iMin != 0 && Dist2Min <= aTol ) U = (extrema.Point(iMin)).Parameter();
434 else return Standard_False;
436 else { return Standard_False; }
438 return Standard_True;