0022627: Change OCCT memory management defaults
[occt.git] / src / GeomLib / GeomLib_Tool.cxx
1 // File:        GeomLib_Tool.cxx
2 // Created:     Tue Mar 18 11:06:16 2003
3 // Author:      Oleg FEDYAEV
4 //              <ofv@merlox>
5 // Copyright:   Open CASCADE 2003
6
7 #include <GeomLib_Tool.ixx>
8
9 #include <Geom_Curve.hxx>
10 #include <Geom_Line.hxx>
11 #include <Geom_Circle.hxx>
12 #include <Geom_Ellipse.hxx>
13 #include <Geom_Parabola.hxx>
14 #include <Geom_Hyperbola.hxx>
15 #include <Geom_BSplineCurve.hxx>
16 #include <Geom_BezierCurve.hxx>
17 #include <Geom_TrimmedCurve.hxx>
18 #include <Geom_OffsetCurve.hxx>
19 #include <Geom_Surface.hxx>
20 #include <Geom_Plane.hxx>
21 #include <Geom_CylindricalSurface.hxx>
22 #include <Geom_ConicalSurface.hxx>
23 #include <Geom_SphericalSurface.hxx>
24 #include <Geom_ToroidalSurface.hxx>
25 #include <Geom_BSplineSurface.hxx>
26 #include <Geom_BezierSurface.hxx>
27 #include <Geom_RectangularTrimmedSurface.hxx>
28 #include <Geom_OffsetSurface.hxx> 
29 #include <Geom_SurfaceOfLinearExtrusion.hxx>
30 #include <Geom_SurfaceOfRevolution.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Pln.hxx>
33 #include <gp_Cylinder.hxx>
34 #include <gp_Cone.hxx>
35 #include <gp_Sphere.hxx>
36 #include <gp_Torus.hxx>
37 #include <gp_Lin.hxx>
38 #include <gp_Circ.hxx>
39 #include <gp_Elips.hxx>
40 #include <gp_Parab.hxx>
41 #include <gp_Hypr.hxx> 
42 #include <gp_Vec.hxx>
43 #include <GeomAdaptor_Curve.hxx>
44 #include <GeomAdaptor_Surface.hxx>
45 #include <ElSLib.hxx>
46 #include <ElCLib.hxx>
47 #include <Extrema_ExtPC.hxx>
48 #include <Extrema_ExtPS.hxx>
49 #include <Geom2d_Curve.hxx>
50 #include <Geom2d_Line.hxx>
51 #include <Geom2d_Circle.hxx>
52 #include <Geom2d_Ellipse.hxx>
53 #include <Geom2d_Parabola.hxx>
54 #include <Geom2d_Hyperbola.hxx>
55 #include <Geom2d_BSplineCurve.hxx>
56 #include <Geom2d_BezierCurve.hxx>
57 #include <Geom2d_TrimmedCurve.hxx>
58 #include <Geom2d_OffsetCurve.hxx>
59 #include <gp_Pnt2d.hxx>
60 #include <gp_Lin2d.hxx>
61 #include <gp_Circ2d.hxx>
62 #include <gp_Elips2d.hxx>
63 #include <gp_Parab2d.hxx>
64 #include <gp_Hypr2d.hxx>
65 #include <Geom2dAdaptor_Curve.hxx>
66 #include <ElCLib.hxx>
67 #include <Extrema_ExtPC2d.hxx>
68
69
70 // The functions Parameter(s) are used to compute parameter(s) of point
71 // on curves and surfaces. The main rule is that tested point must lied
72 // on curves or surfaces otherwise the resulted parameter(s) may be wrong.
73 //
74 // To make search process more common the tolerance value is used to define
75 // the proximity of point to curve or surface. It is clear that this tolerance
76 // value can't be too high to be not in conflict with previous rule.
77 static const Standard_Real MAXTOLERANCEGEOM = 1.e-4;
78 static const Standard_Real MAXTOLERANCEPARM = 1.e-3;
79 static const Standard_Real UNKNOWNVALUE = 1.e+100;
80 static const Standard_Real PARTOLERANCE = 1.e-9;
81
82 //=======================================================================
83 //function : ProcessAnalyticalSurfaces
84 //purpose  : Computes the coefficients of the implicit equation
85 //           of the analytical surfaces in the absolute cartesian
86 //           coordinate system and check given point
87 //=======================================================================
88
89 static Standard_Boolean ProcessAnalyticalSurfaces(const Handle(Geom_Surface)& Surface,
90                                                   const gp_Pnt&               Point,
91                                                   Standard_Real&              Delta)
92 {
93   Delta = UNKNOWNVALUE;
94   Handle(Standard_Type) KindOfSurface = Surface->DynamicType();
95   if( KindOfSurface == STANDARD_TYPE (Geom_Plane) )
96     {
97       Handle(Geom_Plane) aGP = Handle(Geom_Plane)::DownCast(Surface);
98       if( aGP.IsNull() ) return Standard_False;
99       gp_Pln aPlane = aGP->Pln();
100       Delta = aPlane.Distance(Point);
101     }
102   else if( KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) )
103     {
104       Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(Surface);
105       if( aGC.IsNull() ) return Standard_False;
106       gp_Vec aVec(aGC->Cylinder().Location(),Point);
107       Standard_Real X = aVec.Dot(aGC->Cylinder().XAxis().Direction());
108       Standard_Real Y = aVec.Dot(aGC->Cylinder().YAxis().Direction());
109       Delta = X*X + Y*Y - aGC->Cylinder().Radius()*aGC->Cylinder().Radius();
110     }
111   else if( KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) )
112     {
113       Handle(Geom_ConicalSurface) aGC = Handle(Geom_ConicalSurface)::DownCast(Surface);
114       if( aGC.IsNull() ) return Standard_False;
115       gp_Vec aVec(aGC->Cone().Location(),Point);
116       Standard_Real X = aVec.Dot(aGC->Cone().XAxis().Direction());
117       Standard_Real Y = aVec.Dot(aGC->Cone().YAxis().Direction());
118       Standard_Real Z = aVec.Dot(aGC->Cone().Axis().Direction());
119       Standard_Real tZ = aGC->Cone().RefRadius() + Z * Tan(aGC->Cone().SemiAngle());
120       Delta = X*X + Y*Y - tZ*tZ; 
121     }
122   else if( KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) )
123     {
124       Handle(Geom_SphericalSurface) aGS = Handle(Geom_SphericalSurface)::DownCast(Surface);
125       if( aGS.IsNull() ) return Standard_False;
126       gp_Vec aVec(aGS->Sphere().Location(),Point);
127       Standard_Real X = aVec.Dot(aGS->Sphere().XAxis().Direction());
128       Standard_Real Y = aVec.Dot(aGS->Sphere().YAxis().Direction());
129       gp_Dir Zdir = aGS->Sphere().XAxis().Direction().Crossed(aGS->Sphere().YAxis().Direction());
130       Standard_Real Z = aVec.Dot(Zdir);
131       Delta =  X*X + Y*Y + Z*Z - aGS->Sphere().Radius() * aGS->Sphere().Radius();
132     }
133   else if( KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
134     {
135       Handle(Geom_ToroidalSurface) aTS = Handle(Geom_ToroidalSurface)::DownCast(Surface);
136       if( aTS.IsNull() ) return Standard_False;
137       gp_Vec aVec(aTS->Torus().Location(),Point);
138       Standard_Real X = aVec.Dot(aTS->Torus().XAxis().Direction());
139       Standard_Real Y = aVec.Dot(aTS->Torus().YAxis().Direction());
140       Standard_Real Z = aVec.Dot(aTS->Torus().Axis().Direction());
141       Delta = X*X + Y*Y + Z*Z - 2.*aTS->Torus().MajorRadius()*Sqrt( X*X + Y*Y ) -
142             aTS->Torus().MinorRadius()*aTS->Torus().MinorRadius() +
143             aTS->Torus().MajorRadius()*aTS->Torus().MajorRadius();
144     }
145   else
146     {
147       return Standard_False;
148     }
149   return Standard_True;
150 }
151
152 //=======================================================================
153 //function : ProcessAnalyticalCurves
154 //purpose  : Computes the coefficients of the implicit equation
155 //           of the analytical curves and check given point
156 //=======================================================================
157
158 static Standard_Boolean ProcessAnalyticalCurves(const Handle(Geom_Curve)& Curve,
159                                                 const gp_Pnt&             Point,
160                                                 Standard_Real&            Delta)
161 {
162   Delta = UNKNOWNVALUE;
163   Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
164   if( KindOfCurve == STANDARD_TYPE (Geom_Line) )
165     {
166       Handle(Geom_Line) aGL = Handle(Geom_Line)::DownCast(Curve);
167       if( aGL.IsNull() ) return Standard_False;
168       gp_Lin aLin = aGL->Lin();
169       Delta = aLin.Distance(Point);
170     }
171   else if( KindOfCurve == STANDARD_TYPE (Geom_Circle) )
172     {
173       Handle(Geom_Circle) aGC = Handle(Geom_Circle)::DownCast(Curve);
174       if( aGC.IsNull() ) return Standard_False;
175       gp_Circ aCirc = aGC->Circ();
176       Delta = aCirc.Distance(Point);
177     }
178   else if( KindOfCurve == STANDARD_TYPE (Geom_Ellipse) )
179     {
180       Handle(Geom_Ellipse) aGE = Handle(Geom_Ellipse)::DownCast(Curve);
181       if( aGE.IsNull() ) return Standard_False;
182       gp_Elips anElips = aGE->Elips();
183       gp_Vec aVec(anElips.Location(),Point);
184       Standard_Real X = aVec.Dot(anElips.XAxis().Direction());
185       Standard_Real Y = aVec.Dot(anElips.YAxis().Direction());
186       Standard_Real Z = aVec.Dot(anElips.Axis().Direction());
187       Standard_Real AA = anElips.MajorRadius()*anElips.MajorRadius();
188       Standard_Real BB = anElips.MinorRadius()*anElips.MinorRadius();
189       Standard_Real tY = Sqrt( Abs( (1. - X*X/AA)*BB ) );
190       Delta = Max( Abs(Z), Abs( Y - tY ) );
191     }
192   else if( KindOfCurve == STANDARD_TYPE (Geom_Parabola) )
193     { 
194       Handle(Geom_Parabola) aGP = Handle(Geom_Parabola)::DownCast(Curve);
195       if( aGP.IsNull() ) return Standard_False;
196       gp_Parab aParab = aGP->Parab();
197       gp_Vec aVec(aParab.Location(),Point);
198       Standard_Real X = aVec.Dot(aParab.XAxis().Direction());
199       Standard_Real Y = aVec.Dot(aParab.YAxis().Direction());
200       Standard_Real Z = aVec.Dot(aParab.Axis().Direction());
201       Standard_Real tY = Sqrt( Abs(X*2.*aParab.Parameter()) );
202       Delta = Max( Abs(Z), Abs( Y - tY ) );
203     }
204   else if( KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
205     {
206       Handle(Geom_Hyperbola) aGH = Handle(Geom_Hyperbola)::DownCast(Curve);
207       if( aGH.IsNull() ) return Standard_False;
208       gp_Hypr aHypr = aGH->Hypr();
209       gp_Vec aVec(aHypr.Location(),Point);
210       Standard_Real X = aVec.Dot(aHypr.XAxis().Direction());
211       Standard_Real Y = aVec.Dot(aHypr.YAxis().Direction());
212       Standard_Real Z = aVec.Dot(aHypr.Axis().Direction());
213       Standard_Real AA = aHypr.MajorRadius()*aHypr.MajorRadius();
214       Standard_Real BB = aHypr.MinorRadius()*aHypr.MinorRadius();
215       Standard_Real tY1 = Sqrt( Abs( (X*X/AA - 1.)*BB ) );
216       Standard_Real tY2 = Sqrt( (X*X/AA + 1.)*BB );
217       Delta = Max( Abs(Z), Min( Abs( tY1 - Y ), Abs( tY2 - Y ) ) );
218     }
219   else return Standard_False;
220   return Standard_True;
221 }
222
223
224 //=======================================================================
225 //function : Parameter
226 //purpose  : Get parameter on curve of given point
227 //           return FALSE if point is far from curve than tolerance
228 //           or computation fails
229 //=======================================================================
230
231 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom_Curve)& Curve,
232                                          const gp_Pnt&             Point,
233                                          const Standard_Real       Tolerance,
234                                          Standard_Real&            U)
235 {
236   U = 0.;
237   if( Curve.IsNull() ) return Standard_False;
238   Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
239
240   // process analitical curves
241   if( KindOfCurve == STANDARD_TYPE (Geom_Line) ||
242       KindOfCurve == STANDARD_TYPE (Geom_Circle) ||
243       KindOfCurve == STANDARD_TYPE (Geom_Ellipse) ||
244       KindOfCurve == STANDARD_TYPE (Geom_Parabola) ||
245       KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
246     {
247       Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
248       Standard_Real D = 0.;
249       Standard_Boolean isOk = ProcessAnalyticalCurves(Curve,Point,D);
250       if( !isOk ) return Standard_False;
251       if( Abs(D) > aTol ) return Standard_False;
252
253       if( KindOfCurve == STANDARD_TYPE (Geom_Line) )
254         {
255           Handle(Geom_Line) aGL = Handle(Geom_Line)::DownCast(Curve);
256           gp_Lin aLin = aGL->Lin();
257           U = ElCLib::Parameter(aLin,Point);
258         }
259       else if( KindOfCurve == STANDARD_TYPE (Geom_Circle) )
260         {
261           Handle(Geom_Circle) aGC = Handle(Geom_Circle)::DownCast(Curve);
262           gp_Circ aCirc = aGC->Circ();
263           U = ElCLib::Parameter(aCirc,Point);
264         }
265       else if( KindOfCurve == STANDARD_TYPE (Geom_Ellipse) )
266         {
267           Handle(Geom_Ellipse) aGE = Handle(Geom_Ellipse)::DownCast(Curve);
268           gp_Elips anElips = aGE->Elips();
269           U = ElCLib::Parameter(anElips,Point);
270         }
271       else if( KindOfCurve == STANDARD_TYPE (Geom_Parabola) )
272         { 
273           Handle(Geom_Parabola) aGP = Handle(Geom_Parabola)::DownCast(Curve);
274           gp_Parab aParab = aGP->Parab();
275           U = ElCLib::Parameter(aParab,Point);
276         }
277       else if( KindOfCurve == STANDARD_TYPE (Geom_Hyperbola) )
278         {
279           Handle(Geom_Hyperbola) aGH = Handle(Geom_Hyperbola)::DownCast(Curve);
280           gp_Hypr aHypr = aGH->Hypr();
281           U = ElCLib::Parameter(aHypr,Point);
282         }
283     }
284   // process parametrical curves
285   else if( KindOfCurve == STANDARD_TYPE (Geom_BSplineCurve) ||
286            KindOfCurve == STANDARD_TYPE (Geom_BSplineCurve) ||
287            KindOfCurve == STANDARD_TYPE (Geom_TrimmedCurve) ||
288            KindOfCurve == STANDARD_TYPE (Geom_OffsetCurve) )
289     {
290       Standard_Real aTol = (Tolerance < MAXTOLERANCEPARM) ? Tolerance : MAXTOLERANCEPARM;
291       GeomAdaptor_Curve aGAC(Curve);
292       Extrema_ExtPC extrema(Point,aGAC);
293       if( !extrema.IsDone() ) return Standard_False;
294       Standard_Integer n = extrema.NbExt();
295       if( n <= 0 ) return Standard_False;
296       Standard_Integer i = 0, iMin = 0;
297       Standard_Real Dist2Min = 1.e+100;
298       for( i = 1; i <= n; i++ )
299         {
300           if (extrema.SquareDistance(i) < Dist2Min)
301             {
302               iMin = i;
303               Dist2Min = extrema.SquareDistance(i);
304             }
305         }
306       if( iMin != 0 && Dist2Min <= aTol * aTol ) U = (extrema.Point(iMin)).Parameter();
307     }
308   else { return Standard_False; }
309   
310   return Standard_True;
311
312 }
313
314 //=======================================================================
315 //function : Parameters
316 //purpose  : Get parameters on surface of given point
317 //           return FALSE if point is far from surface than tolerance
318 //           or computation fails
319 //=======================================================================
320
321 Standard_Boolean GeomLib_Tool::Parameters(const Handle(Geom_Surface)& Surface,
322                                           const gp_Pnt&               Point,
323                                           const Standard_Real         Tolerance,
324                                           Standard_Real&              U,
325                                           Standard_Real&              V)
326 {
327   U = 0.;
328   V = 0.;
329   if( Surface.IsNull() ) return Standard_False;
330   Handle(Standard_Type) KindOfSurface = Surface->DynamicType();
331
332   // process analitical surfaces
333   if( KindOfSurface == STANDARD_TYPE (Geom_Plane) ||
334       KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) ||
335       KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) ||
336       KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) ||
337       KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
338     {
339       Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
340       Standard_Real D = 0.;
341       Standard_Boolean isOk = ProcessAnalyticalSurfaces(Surface,Point,D);
342       if( !isOk ) return Standard_False;
343       if( Abs(D) > aTol ) return Standard_False;
344
345       if( KindOfSurface == STANDARD_TYPE (Geom_Plane) )
346         {
347           Handle(Geom_Plane) aGP = Handle(Geom_Plane)::DownCast(Surface);
348           gp_Pln aPlane = aGP->Pln(); 
349           ElSLib::Parameters (aPlane,Point,U,V);
350         }
351       else if( KindOfSurface == STANDARD_TYPE (Geom_CylindricalSurface) )
352         {
353           Handle(Geom_CylindricalSurface) aGC = Handle(Geom_CylindricalSurface)::DownCast(Surface);
354           gp_Cylinder aCylinder = aGC->Cylinder();
355           ElSLib::Parameters(aCylinder,Point,U,V);
356         }
357       else if( KindOfSurface == STANDARD_TYPE (Geom_ConicalSurface) )
358         {
359           Handle(Geom_ConicalSurface) aGC = Handle(Geom_ConicalSurface)::DownCast(Surface);
360           gp_Cone aCone = aGC->Cone();
361           ElSLib::Parameters(aCone,Point,U,V);
362         }
363       else if( KindOfSurface == STANDARD_TYPE (Geom_SphericalSurface) )
364         {
365           Handle(Geom_SphericalSurface) aGS = Handle(Geom_SphericalSurface)::DownCast(Surface);
366           gp_Sphere aSphere = aGS->Sphere(); 
367           ElSLib::Parameters(aSphere,Point,U,V);
368         }
369       else if( KindOfSurface == STANDARD_TYPE (Geom_ToroidalSurface) )
370         {
371           Handle(Geom_ToroidalSurface) aTS = Handle(Geom_ToroidalSurface)::DownCast(Surface);
372           gp_Torus aTorus = aTS->Torus();
373           ElSLib::Parameters(aTorus,Point,U,V);
374         }
375       else return Standard_False;
376     }
377   // process parametrical surfaces
378   else if( KindOfSurface == STANDARD_TYPE (Geom_BSplineSurface) ||
379            KindOfSurface == STANDARD_TYPE (Geom_BezierSurface) ||
380            KindOfSurface == STANDARD_TYPE (Geom_RectangularTrimmedSurface) ||
381            KindOfSurface == STANDARD_TYPE (Geom_OffsetSurface) ||
382            KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfLinearExtrusion) ||
383            KindOfSurface == STANDARD_TYPE (Geom_SurfaceOfRevolution) )
384     {
385       Standard_Real aTol = (Tolerance < MAXTOLERANCEPARM) ? Tolerance : MAXTOLERANCEPARM;
386       GeomAdaptor_Surface aGAS(Surface);
387       Standard_Real aTolU = PARTOLERANCE, aTolV = PARTOLERANCE;
388       Extrema_ExtPS extrema(Point,aGAS,aTolU,aTolV);
389       if( !extrema.IsDone() ) return Standard_False;
390       Standard_Integer n = extrema.NbExt();
391       if( n <= 0 ) return Standard_False;
392
393       Standard_Real Dist2Min = 1.e+100;
394       Standard_Integer i = 0, iMin = 0;
395       for( i = 1; i <= n; i++ )
396         {
397           if( extrema.SquareDistance(i) < Dist2Min )
398             {
399               Dist2Min = extrema.SquareDistance(i);
400               iMin = i;
401             }
402         }
403       if( iMin != 0 && Dist2Min <= aTol * aTol ) extrema.Point(iMin).Parameter(U,V);
404       else return Standard_False;
405     }
406   else { return Standard_False; }
407   
408   return Standard_True;
409
410 }
411
412 //=======================================================================
413 //function : ProcessAnalyticalCurves2d
414 //purpose  : Computes the coefficients of the implicit equation
415 //           of the analytical curves and check given point
416 //=======================================================================
417
418 static Standard_Boolean ProcessAnalyticalCurves2d(const Handle(Geom2d_Curve)& Curve,
419                                                   const gp_Pnt2d&             Point,
420                                                   Standard_Real&              Delta)
421 {
422   Delta = UNKNOWNVALUE;
423   Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
424   if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) )
425     {
426       Handle(Geom2d_Line) aGL = Handle(Geom2d_Line)::DownCast(Curve);
427       if( aGL.IsNull() ) return Standard_False;
428       gp_Lin2d aLin = aGL->Lin2d();
429       Delta = aLin.Distance(Point);
430     }
431   else if( KindOfCurve == STANDARD_TYPE (Geom2d_Circle) )
432     {
433       Handle(Geom2d_Circle) aGC = Handle(Geom2d_Circle)::DownCast(Curve);
434       if( aGC.IsNull() ) return Standard_False;
435       gp_Circ2d aCirc = aGC->Circ2d();
436       Delta = aCirc.Distance(Point);
437     }
438   else if( KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) )
439     {
440       Handle(Geom2d_Ellipse) aGE = Handle(Geom2d_Ellipse)::DownCast(Curve);
441       if( aGE.IsNull() ) return Standard_False;
442       gp_Elips2d anElips = aGE->Elips2d();
443       Standard_Real A=0., B=0., C=0., D=0., E=0., F=0.;
444       anElips.Coefficients(A,B,C,D,E,F);
445       Standard_Real X = Point.X(), Y = Point.Y();
446       Delta = A*X*X + B*Y*Y + 2.*C*X*Y + 2.*D*X + 2.*E*Y + F;
447     }
448   else if( KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) )
449     { 
450       Handle(Geom2d_Parabola) aGP = Handle(Geom2d_Parabola)::DownCast(Curve);
451       if( aGP.IsNull() ) return Standard_False;
452       gp_Parab2d aParab = aGP->Parab2d();
453       Standard_Real A=0., B=0., C=0., D=0., E=0., F=0.;
454       aParab.Coefficients(A,B,C,D,E,F);
455       Standard_Real X = Point.X(), Y = Point.Y();
456       Delta = A*X*X + B*Y*Y + 2.*C*X*Y + 2.*D*X + 2.*E*Y + F;
457     }
458   else if( KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
459     {
460       Handle(Geom2d_Hyperbola) aGH = Handle(Geom2d_Hyperbola)::DownCast(Curve);
461       if( aGH.IsNull() ) return Standard_False;
462       gp_Hypr2d aHypr = aGH->Hypr2d();
463       Standard_Real A=0., B=0., C=0., D=0., E=0., F=0.;
464       aHypr.Coefficients(A,B,C,D,E,F);
465       Standard_Real X = Point.X(), Y = Point.Y();
466       Delta = A*X*X + B*Y*Y + 2.*C*X*Y + 2.*D*X + 2.*E*Y + F;
467     }
468   else return Standard_False;
469
470   return Standard_True;
471 }
472
473 //=======================================================================
474 //function : Parameter
475 //purpose  : Get parameter on curve of given point
476 //           return FALSE if point is far from curve than tolerance
477 //           or computation fails
478 //=======================================================================
479
480 Standard_Boolean GeomLib_Tool::Parameter(const Handle(Geom2d_Curve)& Curve,
481                                          const gp_Pnt2d&             Point,
482                                          const Standard_Real         Tolerance,
483                                          Standard_Real&              U)
484 {
485   U = 0.;
486   if( Curve.IsNull() ) return Standard_False;
487   Handle(Standard_Type) KindOfCurve = Curve->DynamicType();
488
489   // process analytical curves
490   if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) ||
491       KindOfCurve == STANDARD_TYPE (Geom2d_Circle) ||
492       KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) ||
493       KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) ||
494       KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
495     {
496       Standard_Real aTol = (Tolerance < MAXTOLERANCEGEOM) ? Tolerance : MAXTOLERANCEGEOM;
497       Standard_Real D = 0.;
498       Standard_Boolean isOk = ProcessAnalyticalCurves2d(Curve,Point,D);
499       if( !isOk ) return Standard_False;
500       if( Abs(D) > aTol ) return Standard_False;
501
502       if( KindOfCurve == STANDARD_TYPE (Geom2d_Line) )
503         {
504           Handle(Geom2d_Line) aGL = Handle(Geom2d_Line)::DownCast(Curve);
505           gp_Lin2d aLin = aGL->Lin2d();
506           U = ElCLib::Parameter(aLin,Point);
507         }
508       else if( KindOfCurve == STANDARD_TYPE (Geom2d_Circle) )
509         {
510           Handle(Geom2d_Circle) aGC = Handle(Geom2d_Circle)::DownCast(Curve);
511           gp_Circ2d aCirc = aGC->Circ2d();
512           U = ElCLib::Parameter(aCirc,Point);
513         }
514       else if( KindOfCurve == STANDARD_TYPE (Geom2d_Ellipse) )
515         {
516           Handle(Geom2d_Ellipse) aGE = Handle(Geom2d_Ellipse)::DownCast(Curve);
517           gp_Elips2d anElips = aGE->Elips2d();
518           U = ElCLib::Parameter(anElips,Point);
519         }
520       else if( KindOfCurve == STANDARD_TYPE (Geom2d_Parabola) )
521         {
522           Handle(Geom2d_Parabola) aGP = Handle(Geom2d_Parabola)::DownCast(Curve);
523           gp_Parab2d aParab = aGP->Parab2d();
524           U = ElCLib::Parameter(aParab,Point);
525         }
526       else if( KindOfCurve == STANDARD_TYPE (Geom2d_Hyperbola) )
527         {
528           Handle(Geom2d_Hyperbola) aGH = Handle(Geom2d_Hyperbola)::DownCast(Curve);
529           gp_Hypr2d aHypr = aGH->Hypr2d();
530           U = ElCLib::Parameter(aHypr,Point);
531         }
532       else return Standard_False;
533     }
534   // process parametrical curves
535   else if( KindOfCurve == STANDARD_TYPE (Geom2d_BSplineCurve) ||
536            KindOfCurve == STANDARD_TYPE (Geom2d_BSplineCurve) ||
537            KindOfCurve == STANDARD_TYPE (Geom2d_TrimmedCurve) ||
538            KindOfCurve == STANDARD_TYPE (Geom2d_OffsetCurve) )
539     {
540       Standard_Real aTol = (Tolerance < MAXTOLERANCEPARM) ? Tolerance : MAXTOLERANCEPARM;
541       Geom2dAdaptor_Curve aGAC(Curve);
542       Extrema_ExtPC2d extrema(Point,aGAC);
543       if( !extrema.IsDone() ) return Standard_False;
544       Standard_Integer n = extrema.NbExt();
545       if( n <= 0 ) return Standard_False;
546       Standard_Integer i = 0, iMin = 0;
547       Standard_Real Dist2Min = 1.e+100;
548       for ( i = 1; i <= n; i++ )
549         {
550          if( extrema.SquareDistance(i) < Dist2Min )
551            {
552              Dist2Min = extrema.SquareDistance(i);
553              iMin = i;
554            }
555         }
556       if( iMin != 0 && Dist2Min <= aTol * aTol ) U = (extrema.Point(iMin)).Parameter();
557       else return Standard_False;
558     }
559   else { return Standard_False; }
560   
561   return Standard_True;
562 }